Я хочу рассчитать статистику по всем попарным комбинациям столбцов очень большой матрицы. У меня есть скрипт на 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 вычислений. Это по сути то же самое.