通常のグリッドで周期的なパーリン ノイズを生成したいと考えています。複数のマップを生成する必要があり、グリッドは非常に大きいため、マルチプロセッシングを使用してコアごとに 1 つのマップを生成したいと考えました。
マップは図にプロットされ、1 つのバイナリ dat ファイルに次々と配置されます。マップは、マップ数 * ノード数のサイズの単一の numpy 配列に格納されるため、スライスはマップになり、配列の異なるゾーンに同時にアクセスすることができます。
プールを使用するこのスレッドと、マルチプロセッシングでいくつかのプロットを行うためにキューを使用したこのスレッドを参照しました。
私は 2 つのコードを思いつきました.1 つは自分のコンピューターでは問題なく動作しますが、ラボのワークステーションやプロのラップトップでは機能しません.エラー メッセージは表示されず、ある時点でフリーズするだけです. 2 番目の例は問題なく動作し、numpy 配列に直接書き込むだけなので、最初の例よりも簡単だと思います。(最初のリンクの非同期ケースのすべての関数と init の必要性がよくわかりませんでした。)
私の質問は: なぜ私の最初のコードに問題があるのですか? 関連すると思われるコードのみを下に置きます。
ご協力いただきありがとうございます。
最初の試み:
def generate_irradiation_maps(rad_v):
while tasks_queue.empty() == False:
print("fetching work ...")
map_index = tasks_queue.get() # get some work to do from the queue
print("----> working on map: %s" % map_index)
perm = range(permsize)
random.shuffle(perm)
perm += perm
for i in range(nb_nodes):
# call the perlin function: fBm
rad_v[map_index, i] = fBm(perm, x[i] * freq, y[i] * freq, int(sizex * freq), int(sizey * freq), octs, persistance)
rad_v[map_index, :] = rad_v[map_index, :] + abs(min(rad_v[map_index, :]))
rad_v[map_index, :] = rad_v[map_index, :] / max(rad_v[map_index, :])
figure = plt.figure(figsize=(20, 7))
plt.tricontourf(x, y, rad_v[map_index, :])
plt.axis('image')
plt.colorbar(shrink=.5)
figure.savefig('diff_gb_and_pf_irrad_c_map_' + str(map_index) + '.png')
plt.clf()
plt.close()
tasks_queue.task_done() # work for this item finished
start_time = time.time()
nb_maps = 10
nb_proc = 1 # number of processes
print("generating %d irradiation maps" % nb_maps)
irrad_c_base_array = mp.Array(ctypes.c_double, nb_maps * nb_nodes)
irrad_c = np.frombuffer(irrad_c_base_array.get_obj())
irrad_c = irrad_c.reshape(nb_maps, nb_nodes)
tasks_queue = mp.JoinableQueue() # a queue to pile up the work to do
jobs = list(range(nb_maps)) # each job is composed of a map
print("inserting jobs in the queue...")
for job in jobs:
tasks_queue.put(job)
print("done")
# launch the processes
for i in range(nb_proc):
current_process = mp.Process(target=generate_irradiation_maps, args=(irrad_c, ))
current_process.start()
# wait for all tasks to be treated
tasks_queue.join()
2 回目の試行:
def generate_irradiation_maps(arg_list):
map_index = arg_list[0]
print('working on map %i ' % map_index)
perm = range(permsize)
random.shuffle(perm)
perm += perm
for i in range(nb_nodes):
arg_list[1][i] = fBm(perm, x[i] * freq, y[i] * freq, int(sizex * freq), int(sizey * freq), octs, persistance)
arg_list[1][:] = arg_list[1][:] + abs(min(arg_list[1][:]))
arg_list[1][:] = arg_list[1][:] / max(arg_list[1][:])
# plot
figure = plt.figure(figsize=(20, 7))
#plt.tricontourf(x, y, rad_v[map_index, :])
plt.tricontourf(x, y, arg_list[1][:])
plt.axis('image')
plt.colorbar(shrink=.5)
figure.savefig('diff_gb_and_pf_irrad_c_map_' + str(map_index) + '.png')
plt.clf()
plt.close()
start_time = time.time()
nb_maps = 2
nb_proc = 2 # number of processes
print("generating %d irradiation maps" % nb_maps)
irrad_c_base_array = mp.Array(ctypes.c_double, nb_maps * nb_nodes) # we build shared array, accessible from all process. we don't access the same zones.
irrad_c = np.frombuffer(irrad_c_base_array.get_obj())
irrad_c = irrad_c.reshape(nb_maps, nb_nodes)
args = [[i,irrad_c[i,:]] for i in range(nb_maps)]
with closing(mp.Pool(processes=nb_proc)) as jobs_pool:
jobs_pool.map_async(generate_irradiation_maps,args)
jobs_pool.join()