2015-05-21 12 views
7

Tôi đang cố chạy một số tối ưu hóa song song bằng PyOpt. Phần khó khăn là trong hàm mục tiêu của tôi, tôi cũng muốn chạy một mã C++ bằng cách sử dụng mpi.Python với cuộc gọi được nhúng tới mpirun

script python của tôi là như sau:

#!/usr/bin/env python  
# Standard Python modules 
import os, sys, time, math 
import subprocess 


# External Python modules 
try: 
    from mpi4py import MPI 
    comm = MPI.COMM_WORLD 
    myrank = comm.Get_rank() 
except: 
    raise ImportError('mpi4py is required for parallelization') 

# Extension modules 
from pyOpt import Optimization 
from pyOpt import ALPSO 

# Predefine the BashCommand 
RunCprogram = "mpirun -np 2 CProgram" # 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 

    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 

# Instantiate Optimization Problem 
opt_prob = Optimization('Thermal Conductivity Optimization',objfunc) 
opt_prob.addVar('x1','c',lower=5.0,upper=1e-6,value=10.0) 
opt_prob.addVar('x2','c',lower=5.0,upper=1e-6,value=10.0) 
opt_prob.addObj('f') 
opt_prob.addCon('g1','i') 
opt_prob.addCon('g2','i') 

# Solve Problem (DPM-Parallelization) 
alpso_dpm = ALPSO(pll_type='DPM') 
alpso_dpm.setOption('fileout',0) 
alpso_dpm(opt_prob) 
print opt_prob.solution(0) 

tôi chạy mã sử dụng:

mpirun -np 20 python Script.py 

Tuy nhiên, tôi nhận được lỗi sau:

[user:28323] *** Process received signal *** 
[user:28323] Signal: Segmentation fault (11) 
[user:28323] Signal code: Address not mapped (1) 
[user:28323] Failing at address: (nil) 
[user:28323] [ 0] /lib64/libpthread.so.0() [0x3ccfc0f500] 
[user:28323] *** End of error message *** 

Tôi hình dung rằng 2 cuộc gọi mpirun khác nhau (một cuộc gọi đến tập lệnh python và lệnh gọi bên trong script) đang xung đột với nhau. Bất kỳ khách hàng tiềm năng nào về cách giải quyết điều đó?

Cảm ơn bạn !!

+0

bạn có trao đổi dữ liệu giữa các quá trình python sử dụng thông tin liên lạc Bộ KH & ĐT hoặc là bạn chỉ cần sử dụng 'mpi4py' để chạy nhiều trường hợp cá biệt. Trong trường hợp này, bạn có thể xem xét sử dụng mô đun 'subprocess' trong python để sinh ra nhiều luồng, mỗi thread có thể gọi một cá thể' mpirun' (sử dụng 'subprocess.Popen'). Tôi làm điều này thường xuyên và không có vấn đề gì. Nếu bạn đang chạy 'Script.py' trên nhiều máy, điều này có thể không thực hiện được ... –

Trả lời

1

Xem Calling mpi binary in serial as subprocess of mpi application: cách an toàn nhất để đi là sử dụng MPI_Comm_spawn(). Hãy xem ví dụ this manager-worker example.

Khắc phục nhanh sẽ là sử dụng subprocess.Popen như được báo hiệu bởi @EdSmith. Tuy nhiên, lưu ý rằng hành vi mặc định của subprocess.Popen sử dụng môi trường của cha mẹ. Tôi đoán là nó giống nhau cho os.system(). Thật không may, một số biến môi trường được thêm vào bởi mpirun, tùy thuộc vào việc thực hiện MPI, chẳng hạn như OMPI_COMM_WORLD_RANK hoặc OMPI_MCA_orte_ess_num_procs. Để xem các biến môi trường này, hãy nhập import os ; print os.environ vào mã mpi4py và trong một trình bao python cơ bản. Các biến môi trường này có thể dẫn đến sự thất bại của tiến trình con. Vì vậy, tôi đã phải thêm một dòng để thoát khỏi họ ... đó là khá bẩn ... Nó nắm tới:

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 

Toàn bộ mã kiểm tra, chạy bằng 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]) 

cơ bản người lao động, biên soạn bởi 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; 

} 
Các vấn đề liên quan