See Calling the mpi binary as a subprocess of the mpi application : the safest way is to use MPI_Comm_spawn() . Check out this example manager-manager .
A quick fix will be to use subprocess.Popen as pointed out by @EdSmith. However, note that the default behavior of subprocess.Popen uses the parent environment. I assume it is the same for os.system() . Unfortunately, some environment variables are added by mpirun, depending on the MPI implementation, for example, OMPI_COMM_WORLD_RANK or OMPI_MCA_orte_ess_num_procs . To see these environment variables, enter import os ; print os.environ import os ; print os.environ to import os ; print os.environ code and to the python base shell. These environment variables can cause the subprocess to crash. So I had to add a line to get rid of them ... which is pretty dirty ... It comes down to:
args = shlex.split(RunCprogram) env=os.environ # to remove all environment variables with "MPI" in it...rather dirty... new_env = {k: v for k, v in env.iteritems() if "MPI" not in k} #print new_env # shell=True : watch for security issues... p = subprocess.Popen(RunCprogram,shell=True, env=new_env,stdout=subprocess.PIPE, stdin=subprocess.PIPE) p.wait() result="process myrank "+str(myrank)+" got "+p.stdout.read() print result
Complete the test code, mpirun -np 2 python opti.py :
#!/usr/bin/env python # Standard Python modules import os, sys, time, math import subprocess import shlex # External Python modules try: from mpi4py import MPI comm = MPI.COMM_WORLD myrank = comm.Get_rank() except: raise ImportError('mpi4py is required for parallelization') # Predefine the BashCommand RunCprogram = "mpirun -np 2 main" # Parallel C++ program ######################### def objfunc(x): f = -(((math.sin(2*math.pi*x[0])**3)*math.sin(2*math.pi*x[1]))/((x[0]**3)*(x[0]+x[1]))) # Run CProgram #os.system(RunCprogram) #where the mpirun call occurs args = shlex.split(RunCprogram) env=os.environ new_env = {k: v for k, v in env.iteritems() if "MPI" not in k} #print new_env p = subprocess.Popen(RunCprogram,shell=True, env=new_env,stdout=subprocess.PIPE, stdin=subprocess.PIPE) p.wait() result="process myrank "+str(myrank)+" got "+p.stdout.read() print result g = [0.0]*2 g[0] = x[0]**2 - x[1] + 1 g[1] = 1 - x[0] + (x[1]-4)**2 time.sleep(0.01) fail = 0 return f,g, fail print objfunc([1.0,0.0])
The main working compiled mpiCC main.cpp -o main :
#include "mpi.h" int main(int argc, char* argv[]) { int rank, size; MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &rank); MPI_Comm_size (MPI_COMM_WORLD, &size); if(rank==0){ std::cout<<" size "<<size<<std::endl; } MPI_Finalize(); return 0; }
francis
source share