Я конвертирую (в Python 3) скрипт Matlab, который запускает параллельный цикл для выполнения скомпилированной программы на рабочих AWS. Чтобы передать данные в программу, цикл должен записать в текстовый файл. У меня это успешно работает на ядрах моего локального компьютера с использованием метода joblib Parallel, однако возвращаемые ответы неверны, если я не использую только одну итерацию цикла (то есть одно ядро). В Matlab я раздавал копии нескольких файлов данных, включая один текстовый ввод, каждому работнику в параллельном пуле, чтобы между ними не было конфликта. Я подозреваю, что, поскольку я не сделал явно то же самое в Python, каждый работник пишет в один и тот же файл. Что я не смог выяснить, так это то, должен ли joblib автоматически делать копии всех данных, которые используются в цикле, или мне нужно использовать что-то отдельное, например multiprocessing.pool, чтобы выполнить работу. Вот схема того, что у меня есть для локального пула: -
import subprocess as sp
from joblib import Parallel,delayed
ntest=4
tout=500
def test_loop(n):
rc=-1
#open the external parameter
fileID=open('file.txt','w') #data input text file
#.....data written to file depending on the value of n
fileID.close() #close external parameter file
try: #try running test
rc=sp.call('test.run',timeout=tout,stdout=sp.DEVNULL,\
stderr=sp.DEVNULL,shell=True)
ans= #.....result read from test output file
except: #if test fails to execute
ans=deferr #use failure default
if (ans<=0) or (ans>deferr) or (rc!=0):
ans=deferr #catch other types of failure
return ans
errs=Parallel(n_jobs=ntest)(delayed(test_loop)(i) for i in range(0,ntest))
Обновление (16.01.2009): я проверил идею передачи имени файла в качестве аргумента test_loop, но результат был таким же.
Далее я переключился с joblib. Параллельно на многопроцессорную обработку.Pool.map:-
if __name__=='__main__':
p=multiprocessing.Pool(processes=4)
errs=p.map(test_loop, range(0,ntest))
p.close()
p.join()
Опять же, даже если предполагается, что это определенно многопроцессный процесс, по умолчанию используется общая память, а конфликт нескольких процессов, записывающих в один файл, создает беспорядок.
Затем я прочитал, что mpi4py рекомендуется для ввода-вывода в тех случаях, когда требуются распределенные данные, поэтому я заменил открытие и запись файла эквивалентами MPI (используя буфероподобные объекты для строк в каждой записи): -
import mpi4py.MPI as MPI
comm=MPI.COMM_WORLD
amode=MPI.MODE_RDWR|MPI.MODE_CREATE
def test_loop(n):
rc=-1
#create the external parameter
fileID=MPI.File.Open(comm,'file.txt',amode) #data input text file
fileID.Write(bytes('string varying with n','utf-8'))
fileID.Close() #close external parameter file
Все еще не повезло! Я явно упускаю что-то очевидное здесь. Python был рекомендован как идеальный для параллельных приложений, и выполнение ряда заданий с отдельными данными, локальными для каждого работника, кажется элементарным приложением, но в Интернете практически нет дискуссий или примеров того, как этого добиться. Мне нужна помощь, прежде чем я потрачу больше времени на изучение тупиков.