- Enable -qopenmp in makefile.inc - Add OpenMP directives to 4th order derivatives in diff_new.f90 - Update makefile_and_run.py to dynamic calculate OMP_NUM_THREADS based on 96 cores and remove hardcoded CPU binding
195 lines
7.5 KiB
Python
Executable File
195 lines
7.5 KiB
Python
Executable File
|
|
##################################################################
|
|
##
|
|
## This file defines the commands used to build and run AMSS-NCKU
|
|
## Author: Xiaoqu
|
|
## 2025/01/24
|
|
##
|
|
##################################################################
|
|
|
|
|
|
import AMSS_NCKU_Input as input_data
|
|
import subprocess
|
|
|
|
## CPU core binding configuration
|
|
## Removed hardcoded taskset to allow full utilization of 96 cores via MPI+OpenMP
|
|
NUMACTL_CPU_BIND = ""
|
|
|
|
## Build parallelism configuration
|
|
## Use nohz_full cores (4-55, 60-111) for compilation: 52 + 52 = 104 cores
|
|
## Set make -j to utilize available cores for faster builds
|
|
BUILD_JOBS = 96
|
|
|
|
|
|
##################################################################
|
|
|
|
|
|
|
|
##################################################################
|
|
|
|
## Compile the AMSS-NCKU main program ABE
|
|
|
|
def makefile_ABE():
|
|
|
|
print( )
|
|
print( " Compiling the AMSS-NCKU executable file ABE/ABEGPU " )
|
|
print( )
|
|
|
|
## Build command
|
|
if (input_data.GPU_Calculation == "no"):
|
|
makefile_command = f"{NUMACTL_CPU_BIND} make -j{BUILD_JOBS} ABE"
|
|
elif (input_data.GPU_Calculation == "yes"):
|
|
makefile_command = f"{NUMACTL_CPU_BIND} make -j{BUILD_JOBS} ABEGPU"
|
|
else:
|
|
print( " CPU/GPU numerical calculation setting is wrong " )
|
|
print( )
|
|
|
|
## Execute the command with subprocess.Popen and stream output
|
|
makefile_process = subprocess.Popen(makefile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
|
|
## Read and print output lines as they arrive
|
|
for line in makefile_process.stdout:
|
|
print(line, end='') # stream output in real time
|
|
|
|
## Wait for the process to finish
|
|
makefile_return_code = makefile_process.wait()
|
|
if makefile_return_code != 0:
|
|
raise subprocess.CalledProcessError(makefile_return_code, makefile_command)
|
|
|
|
print( )
|
|
print( " Compilation of the AMSS-NCKU executable file ABE is finished " )
|
|
print( )
|
|
|
|
return
|
|
|
|
##################################################################
|
|
|
|
|
|
|
|
##################################################################
|
|
|
|
## Compile the AMSS-NCKU TwoPuncture program TwoPunctureABE
|
|
|
|
def makefile_TwoPunctureABE():
|
|
|
|
print( )
|
|
print( " Compiling the AMSS-NCKU executable file TwoPunctureABE " )
|
|
print( )
|
|
|
|
## Build command
|
|
makefile_command = f"{NUMACTL_CPU_BIND} make -j{BUILD_JOBS} TwoPunctureABE"
|
|
|
|
## Execute the command with subprocess.Popen and stream output
|
|
makefile_process = subprocess.Popen(makefile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
|
|
## Read and print output lines as they arrive
|
|
for line in makefile_process.stdout:
|
|
print(line, end='') # stream output in real time
|
|
|
|
## Wait for the process to finish
|
|
makefile_return_code = makefile_process.wait()
|
|
if makefile_return_code != 0:
|
|
raise subprocess.CalledProcessError(makefile_return_code, makefile_command)
|
|
|
|
print( )
|
|
print( " Compilation of the AMSS-NCKU executable file TwoPunctureABE is finished " )
|
|
print( )
|
|
|
|
return
|
|
|
|
##################################################################
|
|
|
|
|
|
|
|
##################################################################
|
|
|
|
## Run the AMSS-NCKU main program ABE
|
|
|
|
def run_ABE():
|
|
|
|
print( )
|
|
print( " Running the AMSS-NCKU executable file ABE/ABEGPU " )
|
|
print( )
|
|
|
|
## Calculate OMP_NUM_THREADS
|
|
## User has 96 cores. Calculate threads per MPI process.
|
|
total_physical_cores = 96
|
|
omp_num_threads = total_physical_cores // input_data.MPI_processes
|
|
if omp_num_threads < 1:
|
|
omp_num_threads = 1
|
|
|
|
print( f" Configuration: {input_data.MPI_processes} MPI processes, {omp_num_threads} OpenMP threads per process." )
|
|
print( f" Total cores utilized: {input_data.MPI_processes * omp_num_threads}" )
|
|
|
|
## Define the command to run; cast other values to strings as needed
|
|
|
|
if (input_data.GPU_Calculation == "no"):
|
|
mpi_command = f"{NUMACTL_CPU_BIND} mpirun -genv OMP_NUM_THREADS {omp_num_threads} -np {input_data.MPI_processes} ./ABE"
|
|
mpi_command_outfile = "ABE_out.log"
|
|
elif (input_data.GPU_Calculation == "yes"):
|
|
mpi_command = f"{NUMACTL_CPU_BIND} mpirun -genv OMP_NUM_THREADS {omp_num_threads} -np {input_data.MPI_processes} ./ABEGPU"
|
|
mpi_command_outfile = "ABEGPU_out.log"
|
|
|
|
## Execute the MPI command and stream output
|
|
mpi_process = subprocess.Popen(mpi_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
|
|
## Write ABE run output to file while printing to stdout
|
|
with open(mpi_command_outfile, 'w') as file0:
|
|
## Read and print output lines; also write each line to file
|
|
for line in mpi_process.stdout:
|
|
print(line, end='') # stream output in real time
|
|
file0.write(line) # write the line to file
|
|
file0.flush() # flush to ensure each line is written immediately (optional)
|
|
file0.close()
|
|
|
|
## Wait for the process to finish
|
|
mpi_return_code = mpi_process.wait()
|
|
|
|
print( )
|
|
print( " The ABE/ABEGPU simulation is finished " )
|
|
print( )
|
|
|
|
return
|
|
|
|
##################################################################
|
|
|
|
|
|
|
|
##################################################################
|
|
|
|
## Run the AMSS-NCKU TwoPuncture program TwoPunctureABE
|
|
|
|
def run_TwoPunctureABE():
|
|
|
|
print( )
|
|
print( " Running the AMSS-NCKU executable file TwoPunctureABE " )
|
|
print( )
|
|
|
|
## Define the command to run
|
|
TwoPuncture_command = NUMACTL_CPU_BIND + " ./TwoPunctureABE"
|
|
TwoPuncture_command_outfile = "TwoPunctureABE_out.log"
|
|
|
|
## Execute the command with subprocess.Popen and stream output
|
|
TwoPuncture_process = subprocess.Popen(TwoPuncture_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
|
|
## Write TwoPunctureABE run output to file while printing to stdout
|
|
with open(TwoPuncture_command_outfile, 'w') as file0:
|
|
## Read and print output lines; also write each line to file
|
|
for line in TwoPuncture_process.stdout:
|
|
print(line, end='') # stream output in real time
|
|
file0.write(line) # write the line to file
|
|
file0.flush() # flush to ensure each line is written immediately (optional)
|
|
file0.close()
|
|
|
|
## Wait for the process to finish
|
|
TwoPuncture_command_return_code = TwoPuncture_process.wait()
|
|
|
|
print( )
|
|
print( " The TwoPunctureABE simulation is finished " )
|
|
print( )
|
|
|
|
return
|
|
|
|
##################################################################
|
|
|