如何使计算循环易于拆分和恢复?
How to make a computation loop easily splittable and resumable?
我想为给定的计算问题在 0..99 中找到最优参数 i, j, k
,我需要 运行:
for i in range(100):
for j in range(100):
for k in range(100):
dothejob(i, j, k) # 1 second per computation
这总共需要 10^6 秒,即 11.5 天。
我开始时将工作分成 4 个进程(使用我的 4 核 CPU 计算机的 100% 计算能力):
for i in range(100):
if i % 4 != 0: # replace != 0 by 1, 2, or 3 for the parallel scripts #2, #3, #4
continue
for j in range(100):
for k in range(100):
dothejob(i, j, k)
with open('done.log', 'a+') as f: # log what has been done
f.write("%i %i\n" % (i, j))
但我对这种方法有疑问:
我必须 运行 python script.py
,然后打开 script.py
,将第 2 行替换为 if i % 4 != 1
,然后 运行 python script.py
,然后打开 script.py
,将第 2 行替换为 if i % 4 != 2
,然后 运行 python script.py
,然后打开 script.py
,将第 2 行替换为 if i % 4 != 3
],然后 运行 python script.py
。
假设循环中断(需要重新启动计算机、崩溃或其他任何情况等)。至少我们知道 done.log
中已经完成的所有 (i, j)(因此我们不需要再次从 0 开始),但是没有简单的方法可以恢复工作。 (好的,我们可以打开 done.log
,解析它,在重新启动循环时丢弃已经完成的 (i, j)
我正在为此寻找更好的解决方案(但是例如 map/reduce 对于这个小任务来说可能有点矫枉过正,而且在 Python 的几行代码中使用起来并不容易)。
问题:如何在 Python 中进行计算 for i in range(100): for j in range(100): for k in range(100): dothejob(i, j, k)
在多个进程之间轻松拆分并轻松恢复(例如重启后)?
只需使用进程池映射产品,示例:
import itertools as it
from multiprocessing import Pool
the_args = it.product(range(100), range(100), range(100))
pool = Pool(4)
def jobWrapper(args): #we need this to unpack the (i, j, k) tuple
return dothejob(*args)
res = pool.map(jobWrapper, the_args)
如果你想恢复它,从日志中知道 las (i, j, k)
,只需跳过所有以前从 the_args
:
计算的
the_args = it.product(range(100), range(100), range(100))
#skip previously computed
while True:
if next(the_args) == (i, j, k):
break
...
作为 (i, j, k)
具有 las 计算值的元组。
我想为给定的计算问题在 0..99 中找到最优参数 i, j, k
,我需要 运行:
for i in range(100):
for j in range(100):
for k in range(100):
dothejob(i, j, k) # 1 second per computation
这总共需要 10^6 秒,即 11.5 天。
我开始时将工作分成 4 个进程(使用我的 4 核 CPU 计算机的 100% 计算能力):
for i in range(100):
if i % 4 != 0: # replace != 0 by 1, 2, or 3 for the parallel scripts #2, #3, #4
continue
for j in range(100):
for k in range(100):
dothejob(i, j, k)
with open('done.log', 'a+') as f: # log what has been done
f.write("%i %i\n" % (i, j))
但我对这种方法有疑问:
我必须 运行
python script.py
,然后打开script.py
,将第 2 行替换为if i % 4 != 1
,然后 运行python script.py
,然后打开script.py
,将第 2 行替换为if i % 4 != 2
,然后 运行python script.py
,然后打开script.py
,将第 2 行替换为if i % 4 != 3
],然后 运行python script.py
。假设循环中断(需要重新启动计算机、崩溃或其他任何情况等)。至少我们知道
done.log
中已经完成的所有 (i, j)(因此我们不需要再次从 0 开始),但是没有简单的方法可以恢复工作。 (好的,我们可以打开done.log
,解析它,在重新启动循环时丢弃已经完成的 (i, j)
我正在为此寻找更好的解决方案(但是例如 map/reduce 对于这个小任务来说可能有点矫枉过正,而且在 Python 的几行代码中使用起来并不容易)。
问题:如何在 Python 中进行计算 for i in range(100): for j in range(100): for k in range(100): dothejob(i, j, k)
在多个进程之间轻松拆分并轻松恢复(例如重启后)?
只需使用进程池映射产品,示例:
import itertools as it
from multiprocessing import Pool
the_args = it.product(range(100), range(100), range(100))
pool = Pool(4)
def jobWrapper(args): #we need this to unpack the (i, j, k) tuple
return dothejob(*args)
res = pool.map(jobWrapper, the_args)
如果你想恢复它,从日志中知道 las (i, j, k)
,只需跳过所有以前从 the_args
:
the_args = it.product(range(100), range(100), range(100))
#skip previously computed
while True:
if next(the_args) == (i, j, k):
break
...
作为 (i, j, k)
具有 las 计算值的元组。