Я хочу рассчитать статистику по всем попарным комбинациям столбцов очень большой матрицы. У меня есть сценарий python, называемый jaccard.py
, который принимает пару столбцов и вычисляет эту статистику по матрице.Параллельная обработка с использованием подпроцесса в python2.4
На моей рабочей машине каждый расчет занимает около 10 секунд, и у меня есть около 95000 из этих вычислений. Однако все эти вычисления независимы друг от друга, и я ищу использовать кластер, который использует систему очередей Torque и python2.4. Каков наилучший способ распараллеливать этот расчет, чтобы он совместим с Torque?
Я сам сделал расчеты совместимыми с python2.4, но я не понимаю, как распараллелить эти вычисления, используя subprocess
, или могу ли я сделать это из-за GIL.
Основная идея, которую я имею, - сохранить постоянный пул подпроцессов; когда заканчивается, читайте вывод и начинайте новый со следующей пары столбцов. Мне нужен результат только после завершения вычисления, после чего процесс можно перезапустить при новом расчете.
Моя идея состояла в том, чтобы представить эту работу таким образом
qsub -l nodes=4:ppn=8 myjob.sh > outfile
myjob.sh
будет ссылаться основной файл питона, который выглядит следующим образом:
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 вычислений. Это по сути то же самое.