From 4777cad4edd2047860da5dff265ffb9eff511d64 Mon Sep 17 00:00:00 2001 From: ianchb Date: Mon, 9 Feb 2026 15:13:18 +0800 Subject: [PATCH] [1/2] Implement multiprocessing-based parallel plotting --- AMSS_NCKU_Program.py | 19 ++++++++++++------- parallel_plot_helper.py | 29 +++++++++++++++++++++++++++++ plot_GW_strain_amplitude_xiaoqu.py | 2 ++ plot_binary_data.py | 2 ++ plot_xiaoqu.py | 2 ++ 5 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 parallel_plot_helper.py diff --git a/AMSS_NCKU_Program.py b/AMSS_NCKU_Program.py index 46d15f1..214f800 100755 --- a/AMSS_NCKU_Program.py +++ b/AMSS_NCKU_Program.py @@ -424,26 +424,31 @@ print( import plot_xiaoqu import plot_GW_strain_amplitude_xiaoqu +from parallel_plot_helper import run_plot_tasks_parallel + +plot_tasks = [] ## Plot black hole trajectory -plot_xiaoqu.generate_puncture_orbit_plot( binary_results_directory, figure_directory ) -plot_xiaoqu.generate_puncture_orbit_plot3D( binary_results_directory, figure_directory ) +plot_tasks.append( ( plot_xiaoqu.generate_puncture_orbit_plot, (binary_results_directory, figure_directory) ) ) +plot_tasks.append( ( plot_xiaoqu.generate_puncture_orbit_plot3D, (binary_results_directory, figure_directory) ) ) ## Plot black hole separation vs. time -plot_xiaoqu.generate_puncture_distence_plot( binary_results_directory, figure_directory ) +plot_tasks.append( ( plot_xiaoqu.generate_puncture_distence_plot, (binary_results_directory, figure_directory) ) ) ## Plot gravitational waveforms (psi4 and strain amplitude) for i in range(input_data.Detector_Number): - plot_xiaoqu.generate_gravitational_wave_psi4_plot( binary_results_directory, figure_directory, i ) - plot_GW_strain_amplitude_xiaoqu.generate_gravitational_wave_amplitude_plot( binary_results_directory, figure_directory, i ) + plot_tasks.append( ( plot_xiaoqu.generate_gravitational_wave_psi4_plot, (binary_results_directory, figure_directory, i) ) ) + plot_tasks.append( ( plot_GW_strain_amplitude_xiaoqu.generate_gravitational_wave_amplitude_plot, (binary_results_directory, figure_directory, i) ) ) ## Plot ADM mass evolution for i in range(input_data.Detector_Number): - plot_xiaoqu.generate_ADMmass_plot( binary_results_directory, figure_directory, i ) + plot_tasks.append( ( plot_xiaoqu.generate_ADMmass_plot, (binary_results_directory, figure_directory, i) ) ) ## Plot Hamiltonian constraint violation over time for i in range(input_data.grid_level): - plot_xiaoqu.generate_constraint_check_plot( binary_results_directory, figure_directory, i ) + plot_tasks.append( ( plot_xiaoqu.generate_constraint_check_plot, (binary_results_directory, figure_directory, i) ) ) + +run_plot_tasks_parallel(plot_tasks) ## Plot stored binary data plot_xiaoqu.generate_binary_data_plot( binary_results_directory, figure_directory ) diff --git a/parallel_plot_helper.py b/parallel_plot_helper.py new file mode 100644 index 0000000..c1168fa --- /dev/null +++ b/parallel_plot_helper.py @@ -0,0 +1,29 @@ +import multiprocessing + +def run_plot_task(task): + """Execute a single plotting task. + + Parameters + ---------- + task : tuple + A tuple of (function, args_tuple) where function is a callable + plotting function and args_tuple contains its arguments. + """ + func, args = task + return func(*args) + + +def run_plot_tasks_parallel(plot_tasks): + """Execute a list of independent plotting tasks in parallel. + + Uses the 'fork' context to create worker processes so that the main + script is NOT re-imported/re-executed in child processes. + + Parameters + ---------- + plot_tasks : list of tuples + Each element is (function, args_tuple). + """ + ctx = multiprocessing.get_context('fork') + with ctx.Pool() as pool: + pool.map(run_plot_task, plot_tasks) diff --git a/plot_GW_strain_amplitude_xiaoqu.py b/plot_GW_strain_amplitude_xiaoqu.py index 739f3d4..cf7b098 100755 --- a/plot_GW_strain_amplitude_xiaoqu.py +++ b/plot_GW_strain_amplitude_xiaoqu.py @@ -11,6 +11,8 @@ import numpy ## numpy for array operations import scipy ## scipy for interpolation and signal processing import math +import matplotlib +matplotlib.use('Agg') ## use non-interactive backend for multiprocessing safety import matplotlib.pyplot as plt ## matplotlib for plotting import os ## os for system/file operations diff --git a/plot_binary_data.py b/plot_binary_data.py index 0694f4f..3ed947d 100755 --- a/plot_binary_data.py +++ b/plot_binary_data.py @@ -10,6 +10,8 @@ import numpy import scipy +import matplotlib +matplotlib.use('Agg') ## use non-interactive backend for multiprocessing safety import matplotlib.pyplot as plt from matplotlib.colors import LogNorm from mpl_toolkits.mplot3d import Axes3D diff --git a/plot_xiaoqu.py b/plot_xiaoqu.py index 7711d5a..7969a4f 100755 --- a/plot_xiaoqu.py +++ b/plot_xiaoqu.py @@ -8,6 +8,8 @@ ################################################# import numpy ## numpy for array operations +import matplotlib +matplotlib.use('Agg') ## use non-interactive backend for multiprocessing safety import matplotlib.pyplot as plt ## matplotlib for plotting from mpl_toolkits.mplot3d import Axes3D ## needed for 3D plots import glob