Added memory measure for GPU.

这个提交包含在:
Craig Warren
2019-10-23 16:52:24 +01:00
父节点 471ee916ea
当前提交 67482810b6
共有 5 个文件被更改,包括 37 次插入42 次删除

查看文件

@@ -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)
# 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
# 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])
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

查看文件

@@ -103,7 +103,7 @@ class ModelBuildRun:
# 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()
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
if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
@@ -268,19 +268,19 @@ class ModelBuildRun:
pbar.close()
log.info('')
def print_resource_info(self, tsolve):
def print_resource_info(self, tsolve, memsolve):
"""Print resource information on runtime and memory usage.
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']:
log.debug('Fix memory used calc for GPU')
# mem_GPU = f' host + ~{human_size(self.solver.get_memsolve())} GPU'
memGPU_str = f' host + ~{human_size(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)}')
def solve(self, solver):
@@ -293,7 +293,7 @@ class ModelBuildRun:
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
if config.sim_config.general['cpu']:
@@ -311,13 +311,13 @@ class ModelBuildRun:
iterator = range(self.G.iterations)
# 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)
self.write_output_data()
# Print resource information on runtime and memory usage
self.print_resource_info(tsolve)
self.print_resource_info(tsolve, memsolve)
return tsolve

查看文件

@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
import sys
import gprMax.config as config
from .grid import FDTDGrid
from .grid import CUDAGrid
@@ -92,6 +92,10 @@ class Solver:
Args:
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()
@@ -110,9 +114,10 @@ class Solver:
if self.hsg:
self.updates.hsg_1()
self.updates.update_electric_b()
memsolve = self.updates.calculate_memsolve(iteration) if config.sim_config.general['cuda'] else None
self.updates.finalise()
tsolve = self.updates.calculate_tsolve()
self.updates.cleanup()
return tsolve
return tsolve, memsolve

查看文件

@@ -61,7 +61,7 @@ class CPUUpdates:
"""Store any snapshots.
Args:
iteration (int): iteration number.
iteration (int): Iteration number.
"""
for snap in self.grid.snapshots:
if snap.time == iteration + 1:
@@ -225,9 +225,11 @@ class CPUUpdates:
self.dispersive_update_b = disp_b_f
def time_start(self):
"""Start timer used to calculate solving time for model."""
self.timestart = timer()
def calculate_tsolve(self):
"""Calculate solving time for model."""
return timer() - self.timestart
def finalise(self):
@@ -243,7 +245,7 @@ class CUDAUpdates:
def __init__(self, G):
"""
Args:
G (FDTDGrid): Holds essential parameters describing the model.
G (FDTDGrid): Parameters describing a grid in a model.
"""
self.grid = G
@@ -465,7 +467,7 @@ class CUDAUpdates:
for i, snap in enumerate(self.grid.snapshots):
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),
np.int32(snap.xs),
np.int32(snap.xf),
@@ -490,7 +492,7 @@ class CUDAUpdates:
self.snapHz_gpu.gpudata,
block=Snapshot.tpb,
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(),
self.grid.snapEy_gpu.get(),
self.grid.snapEz_gpu.get(),
@@ -649,6 +651,18 @@ class CUDAUpdates:
self.iterstart.record()
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):
"""Calculate solving time for model."""
self.iterend.record()
@@ -666,7 +680,7 @@ class CUDAUpdates:
self.grid)
# 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):
get_snapshot_array_gpu(self.snapEx_gpu.get(),
self.snapEy_gpu.get(),