Параллельная обработка с использованием подпроцесса в python2.4

Я хочу рассчитать статистику по всем попарным комбинациям столбцов очень большой матрицы. У меня есть скрипт на Python под названием jaccard.py, который принимает пару столбцов и вычисляет эту статистику по матрице.

На моей рабочей машине каждый расчет занимает около 10 секунд, и мне нужно выполнить около 95000 таких расчетов. Однако все эти вычисления независимы друг от друга, и я собираюсь использовать имеющийся у нас кластер, в котором используется система очередей Torque и python2.4. Как лучше распараллелить этот расчет, чтобы он был совместим с Torque?

Я сделал сами вычисления совместимыми с python2.4, но я в недоумении, как распараллелить эти вычисления с помощью subprocess, и смогу ли я вообще это сделать из-за GIL.

Моя основная идея состоит в том, чтобы поддерживать постоянный пул подпроцессов; когда вы закончите, прочитайте вывод и начните новый со следующей парой столбцов. Мне нужен вывод только после завершения расчета, затем процесс можно перезапустить с новым расчетом.

Моя идея состояла в том, чтобы представить работу таким образом

qsub -l nodes=4:ppn=8 myjob.sh > outfile

myjob.sh вызовет основной файл Python, который выглядит следующим образом:

import os, sys
from subprocess import Popen, PIPE
from select import select

def combinations(iterable, r):
    #backport of itertools combinations
    pass

col_pairs = combinations(range(598, 2))

processes = [Popen(['./jaccard.py'] + map(str, col_pairs.next()), 
                   stdout=PIPE)
             for _ in range(8)]

try:
    while 1:
        for p in processes:
            # If process has completed the calculation, print it out
            # **How do I do this part?**

            # Delete the process and add a new one
            p.stdout.close()
            processes.remove(p)
            process.append(Popen(['./jaccard.py'] + map(str, col_pairs.next()),
                                 stdout=Pipe))

# When there are no more column pairs, end the job.
except StopIteration:
    pass

Любой совет, как лучше всего это сделать? Я никогда не использовал Torque и не знаком с такой подпроцессорной обработкой. Я попытался использовать multiprocessing.Pool на своей рабочей станции, и он работал безупречно с Pool.map, но, поскольку в кластере используется python2.4, я не уверен, что делать дальше.

EDIT: На самом деле, если подумать, я мог бы просто написать несколько скриптов qsub, каждый из которых работал бы только с одним фрагментом из 95000 вычислений. Я мог отправить около 16 различных заданий, каждое из которых выполняло 7125 вычислений. Это по сути то же самое.


person wflynny    schedule 01.08.2013    source источник


Ответы (1)


На самом деле, если подумать, я мог бы просто написать несколько сценариев qsub, каждый из которых работал бы только с одним фрагментом из 95000 вычислений. Я мог отправить около 16 различных заданий, каждое из которых выполняло 7125 вычислений. Это по сути то же самое. Это не решение, но подходящий обходной путь с учетом ограничений времени и усилий.

person wflynny    schedule 02.08.2013