你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 07:24:19 +08:00
Added memory measure for GPU.
这个提交包含在:
@@ -200,7 +200,7 @@ def check_cmd_names(processedlines, checkessential=True):
|
|||||||
singlecmds = dict.fromkeys(['#domain', '#dx_dy_dz', '#time_window', '#title', '#messages', '#num_threads', '#time_step_stability_factor', '#pml_formulation', '#pml_cells', '#excitation_file', '#src_steps', '#rx_steps', '#output_dir'], None)
|
singlecmds = dict.fromkeys(['#domain', '#dx_dy_dz', '#time_window', '#title', '#messages', '#num_threads', '#time_step_stability_factor', '#pml_formulation', '#pml_cells', '#excitation_file', '#src_steps', '#rx_steps', '#output_dir'], None)
|
||||||
|
|
||||||
# Commands that there can be multiple instances of in a model - these will be lists within the dictionary
|
# Commands that there can be multiple instances of in a model - these will be lists within the dictionary
|
||||||
multiplecmds = {key: [] for key in ['#geometry_view', '#geometry_objects_write', '#material', '#soil_peplinski', '#add_dispersion_debye', '#add_dispersion_lorentz', '#add_dispersion_drude', '#waveform', '#voltage_source', '#hertzian_dipole', '#magnetic_dipole', '#transmission_line', '#rx', '#rx_array', '#snapshot', '#pml_cfs', '#include_file']}
|
multiplecmds = {key: [] for key in ['#geometry_view', '#geometry_objects_write', '#material', '#soil_peplinski', '#add_dispersion_debye', '#add_dispersion_lorentz', '#add_dispersion_drude', '#waveform', '#voltage_source', '#hertzian_dipole', '#magnetic_dipole', '#transmission_line', '#rx', '#rx_array', '#snapshot', '#include_file']}
|
||||||
|
|
||||||
# Geometry object building commands that there can be multiple instances
|
# Geometry object building commands that there can be multiple instances
|
||||||
# of in a model - these will be lists within the dictionary
|
# of in a model - these will be lists within the dictionary
|
||||||
|
@@ -280,28 +280,4 @@ def process_multicmds(multicmds):
|
|||||||
gow = GeometryObjectsWrite(p1=p1, p2=p2, filename=tmp[6])
|
gow = GeometryObjectsWrite(p1=p1, p2=p2, filename=tmp[6])
|
||||||
scene_objects.append(gow)
|
scene_objects.append(gow)
|
||||||
|
|
||||||
cmdname = '#pml_cfs'
|
|
||||||
if multicmds[cmdname] is not None:
|
|
||||||
if len(multicmds[cmdname]) > 2:
|
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' can only be used up to two times, for up to a 2nd order PML')
|
|
||||||
for cmdinstance in multicmds[cmdname]:
|
|
||||||
tmp = cmdinstance.split()
|
|
||||||
if len(tmp) != 12:
|
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires exactly twelve parameters')
|
|
||||||
|
|
||||||
pml_cfs = PMLCFS(alphascalingprofile=tmp[0],
|
|
||||||
alphascalingdirection=tmp[1],
|
|
||||||
alphamin=tmp[2],
|
|
||||||
alphamax=tmp[3],
|
|
||||||
kappascalingprofile=tmp[4],
|
|
||||||
kappascalingdirection=tmp[5],
|
|
||||||
kappamin=tmp[6],
|
|
||||||
kappamax=tmp[7],
|
|
||||||
sigmascalingprofile=tmp[8],
|
|
||||||
sigmascalingdirection=tmp[9],
|
|
||||||
sigmamin=tmp[10],
|
|
||||||
sigmamax=tmp[11])
|
|
||||||
|
|
||||||
scene_objects.append(pml_cfs)
|
|
||||||
|
|
||||||
return scene_objects
|
return scene_objects
|
||||||
|
@@ -103,7 +103,7 @@ class ModelBuildRun:
|
|||||||
# Normal model reading/building process; bypassed if geometry information to be reused
|
# Normal model reading/building process; bypassed if geometry information to be reused
|
||||||
self.reuse_geometry() if config.model_configs[G.model_num].reuse_geometry else self.build_geometry()
|
self.reuse_geometry() if config.model_configs[G.model_num].reuse_geometry else self.build_geometry()
|
||||||
|
|
||||||
log.info(f'\nOutput path: {config.model_configs[G.model_num].output_file_path.parent}')
|
log.info(f'\nOutput directory: {config.model_configs[G.model_num].output_file_path.parent.resolve()}')
|
||||||
|
|
||||||
# Adjust position of simple sources and receivers if required
|
# Adjust position of simple sources and receivers if required
|
||||||
if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
|
if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
|
||||||
@@ -268,19 +268,19 @@ class ModelBuildRun:
|
|||||||
pbar.close()
|
pbar.close()
|
||||||
log.info('')
|
log.info('')
|
||||||
|
|
||||||
def print_resource_info(self, tsolve):
|
def print_resource_info(self, tsolve, memsolve):
|
||||||
"""Print resource information on runtime and memory usage.
|
"""Print resource information on runtime and memory usage.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tsolve (float): time taken to execute solving (seconds).
|
tsolve (float): Time taken to execute solving (seconds).
|
||||||
|
memsolve (float): Memory (RAM) used on GPU.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
mem_GPU = ''
|
memGPU_str = ''
|
||||||
if config.sim_config.general['cuda']:
|
if config.sim_config.general['cuda']:
|
||||||
log.debug('Fix memory used calc for GPU')
|
memGPU_str = f' host + ~{human_size(memsolve)} GPU'
|
||||||
# mem_GPU = f' host + ~{human_size(self.solver.get_memsolve())} GPU'
|
|
||||||
|
|
||||||
log.info(f'\nMemory (RAM) used: ~{human_size(self.p.memory_full_info().uss)}{mem_GPU}')
|
log.info(f'\nMemory (RAM) used: ~{human_size(self.p.memory_full_info().uss)}{memGPU_str}')
|
||||||
log.info(f'Solving time [HH:MM:SS]: {datetime.timedelta(seconds=tsolve)}')
|
log.info(f'Solving time [HH:MM:SS]: {datetime.timedelta(seconds=tsolve)}')
|
||||||
|
|
||||||
def solve(self, solver):
|
def solve(self, solver):
|
||||||
@@ -293,7 +293,7 @@ class ModelBuildRun:
|
|||||||
tsolve (float): time taken to execute solving (seconds).
|
tsolve (float): time taken to execute solving (seconds).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.info(f'\nOutput file: {config.model_configs[self.G.model_num].output_file_path_ext}')
|
log.info(f'\nOutput file: {config.model_configs[self.G.model_num].output_file_path_ext.name}')
|
||||||
|
|
||||||
# Check number of OpenMP threads
|
# Check number of OpenMP threads
|
||||||
if config.sim_config.general['cpu']:
|
if config.sim_config.general['cpu']:
|
||||||
@@ -311,13 +311,13 @@ class ModelBuildRun:
|
|||||||
iterator = range(self.G.iterations)
|
iterator = range(self.G.iterations)
|
||||||
|
|
||||||
# Run solver
|
# Run solver
|
||||||
tsolve = solver.solve(iterator)
|
tsolve, memsolve = solver.solve(iterator)
|
||||||
|
|
||||||
# Write output data, i.e. field data for receivers and snapshots to file(s)
|
# Write output data, i.e. field data for receivers and snapshots to file(s)
|
||||||
self.write_output_data()
|
self.write_output_data()
|
||||||
|
|
||||||
# Print resource information on runtime and memory usage
|
# Print resource information on runtime and memory usage
|
||||||
self.print_resource_info(tsolve)
|
self.print_resource_info(tsolve, memsolve)
|
||||||
|
|
||||||
return tsolve
|
return tsolve
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import sys
|
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from .grid import FDTDGrid
|
from .grid import FDTDGrid
|
||||||
from .grid import CUDAGrid
|
from .grid import CUDAGrid
|
||||||
@@ -92,6 +92,10 @@ class Solver:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
iterator (iterator): can be range() or tqdm()
|
iterator (iterator): can be range() or tqdm()
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tsolve (float): Time taken to execute solving (seconds).
|
||||||
|
memsolve (float): Memory (RAM) used.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.updates.time_start()
|
self.updates.time_start()
|
||||||
@@ -110,9 +114,10 @@ class Solver:
|
|||||||
if self.hsg:
|
if self.hsg:
|
||||||
self.updates.hsg_1()
|
self.updates.hsg_1()
|
||||||
self.updates.update_electric_b()
|
self.updates.update_electric_b()
|
||||||
|
memsolve = self.updates.calculate_memsolve(iteration) if config.sim_config.general['cuda'] else None
|
||||||
|
|
||||||
self.updates.finalise()
|
self.updates.finalise()
|
||||||
tsolve = self.updates.calculate_tsolve()
|
tsolve = self.updates.calculate_tsolve()
|
||||||
self.updates.cleanup()
|
self.updates.cleanup()
|
||||||
|
|
||||||
return tsolve
|
return tsolve, memsolve
|
||||||
|
@@ -61,7 +61,7 @@ class CPUUpdates:
|
|||||||
"""Store any snapshots.
|
"""Store any snapshots.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
iteration (int): iteration number.
|
iteration (int): Iteration number.
|
||||||
"""
|
"""
|
||||||
for snap in self.grid.snapshots:
|
for snap in self.grid.snapshots:
|
||||||
if snap.time == iteration + 1:
|
if snap.time == iteration + 1:
|
||||||
@@ -225,9 +225,11 @@ class CPUUpdates:
|
|||||||
self.dispersive_update_b = disp_b_f
|
self.dispersive_update_b = disp_b_f
|
||||||
|
|
||||||
def time_start(self):
|
def time_start(self):
|
||||||
|
"""Start timer used to calculate solving time for model."""
|
||||||
self.timestart = timer()
|
self.timestart = timer()
|
||||||
|
|
||||||
def calculate_tsolve(self):
|
def calculate_tsolve(self):
|
||||||
|
"""Calculate solving time for model."""
|
||||||
return timer() - self.timestart
|
return timer() - self.timestart
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
@@ -243,7 +245,7 @@ class CUDAUpdates:
|
|||||||
def __init__(self, G):
|
def __init__(self, G):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
G (FDTDGrid): Holds essential parameters describing the model.
|
G (FDTDGrid): Parameters describing a grid in a model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.grid = G
|
self.grid = G
|
||||||
@@ -465,7 +467,7 @@ class CUDAUpdates:
|
|||||||
|
|
||||||
for i, snap in enumerate(self.grid.snapshots):
|
for i, snap in enumerate(self.grid.snapshots):
|
||||||
if snap.time == iteration + 1:
|
if snap.time == iteration + 1:
|
||||||
snapno = 0 if self.grid.snapsgpu2cpu else i
|
snapno = 0 if config.model_configs[self.grid.model_num].cuda['snapsgpu2cpu'] else i
|
||||||
self.store_snapshot_gpu(np.int32(snapno),
|
self.store_snapshot_gpu(np.int32(snapno),
|
||||||
np.int32(snap.xs),
|
np.int32(snap.xs),
|
||||||
np.int32(snap.xf),
|
np.int32(snap.xf),
|
||||||
@@ -490,7 +492,7 @@ class CUDAUpdates:
|
|||||||
self.snapHz_gpu.gpudata,
|
self.snapHz_gpu.gpudata,
|
||||||
block=Snapshot.tpb,
|
block=Snapshot.tpb,
|
||||||
grid=Snapshot.bpg)
|
grid=Snapshot.bpg)
|
||||||
if self.grid.snapsgpu2cpu:
|
if config.model_configs[self.grid.model_num].cuda['snapsgpu2cpu']:
|
||||||
gpu_get_snapshot_array(self.grid.snapEx_gpu.get(),
|
gpu_get_snapshot_array(self.grid.snapEx_gpu.get(),
|
||||||
self.grid.snapEy_gpu.get(),
|
self.grid.snapEy_gpu.get(),
|
||||||
self.grid.snapEz_gpu.get(),
|
self.grid.snapEz_gpu.get(),
|
||||||
@@ -649,6 +651,18 @@ class CUDAUpdates:
|
|||||||
self.iterstart.record()
|
self.iterstart.record()
|
||||||
self.iterstart.synchronize()
|
self.iterstart.synchronize()
|
||||||
|
|
||||||
|
def calculate_memsolve(iteration):
|
||||||
|
"""Calculate memory used on last iteration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
iteration (int): Iteration number.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Memory (RAM) used on GPU.
|
||||||
|
"""
|
||||||
|
if iteration == self.grid.iterations - 1:
|
||||||
|
return self.drv.mem_get_info()[1] - self.drv.mem_get_info()[0]
|
||||||
|
|
||||||
def calculate_tsolve(self):
|
def calculate_tsolve(self):
|
||||||
"""Calculate solving time for model."""
|
"""Calculate solving time for model."""
|
||||||
self.iterend.record()
|
self.iterend.record()
|
||||||
@@ -666,7 +680,7 @@ class CUDAUpdates:
|
|||||||
self.grid)
|
self.grid)
|
||||||
|
|
||||||
# Copy data from any snapshots back to correct snapshot objects
|
# Copy data from any snapshots back to correct snapshot objects
|
||||||
if self.grid.snapshots and not self.grid.snapsgpu2cpu:
|
if self.grid.snapshots and not config.model_configs[self.grid.model_num].cuda['snapsgpu2cpu']:
|
||||||
for i, snap in enumerate(self.grid.snapshots):
|
for i, snap in enumerate(self.grid.snapshots):
|
||||||
get_snapshot_array_gpu(self.snapEx_gpu.get(),
|
get_snapshot_array_gpu(self.snapEx_gpu.get(),
|
||||||
self.snapEy_gpu.get(),
|
self.snapEy_gpu.get(),
|
||||||
|
在新工单中引用
屏蔽一个用户