Многопроцессорный цикл, который пишет в распределенный файл в Python 3 - PullRequest
0 голосов
/ 09 января 2019

Я конвертирую (в 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 был рекомендован как идеальный для параллельных приложений, и выполнение ряда заданий с отдельными данными, локальными для каждого работника, кажется элементарным приложением, но в Интернете практически нет дискуссий или примеров того, как этого добиться. Мне нужна помощь, прежде чем я потрачу больше времени на изучение тупиков.

...