你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 07:24:19 +08:00
Work to add detection and setting of GPUs.
这个提交包含在:
@@ -29,6 +29,7 @@ from scipy.constants import c
|
|||||||
from scipy.constants import epsilon_0 as e0
|
from scipy.constants import epsilon_0 as e0
|
||||||
from scipy.constants import mu_0 as m0
|
from scipy.constants import mu_0 as m0
|
||||||
|
|
||||||
|
from .utilities import detect_check_gpus
|
||||||
from .utilities import get_host_info
|
from .utilities import get_host_info
|
||||||
from .utilities import get_terminal_width
|
from .utilities import get_terminal_width
|
||||||
|
|
||||||
@@ -53,15 +54,17 @@ class ModelConfig:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self.i = model_num # Indexed from 0
|
self.i = model_num # Indexed from 0
|
||||||
|
self.mode = '3D'
|
||||||
self.grids = []
|
self.grids = []
|
||||||
self.ompthreads = None # Number of OpenMP threads
|
self.ompthreads = None # Number of OpenMP threads
|
||||||
|
|
||||||
# Store information for CUDA solver type
|
# Store information for CUDA solver
|
||||||
# gpu: GPU object
|
# gpu: GPU object
|
||||||
# snapsgpu2cpu: copy snapshot data from GPU to CPU during simulation
|
# snapsgpu2cpu: copy snapshot data from GPU to CPU during simulation
|
||||||
# N.B. This will happen if the requested snapshots are too large to fit
|
# N.B. This will happen if the requested snapshots are too large to fit
|
||||||
# on the memory of the GPU. If True this will slow performance significantly
|
# on the memory of the GPU. If True this will slow performance significantly
|
||||||
self.cuda = {'gpu': None, 'snapsgpu2cpu': False}
|
if sim_config.general['cuda']:
|
||||||
|
self.cuda = {'gpu': sim_config.cuda['gpus'], 'snapsgpu2cpu': False}
|
||||||
|
|
||||||
# Total memory usage for all grids in the model. Starts with 50MB overhead.
|
# Total memory usage for all grids in the model. Starts with 50MB overhead.
|
||||||
self.mem_use = 50e6
|
self.mem_use = 50e6
|
||||||
@@ -144,7 +147,6 @@ class SimulationConfig:
|
|||||||
# outputfilepath: path to outputfile location
|
# outputfilepath: path to outputfile location
|
||||||
# messages: whether to print all messages as output to stdout or not
|
# messages: whether to print all messages as output to stdout or not
|
||||||
# progressbars: whether to show progress bars on stdoout or not
|
# progressbars: whether to show progress bars on stdoout or not
|
||||||
# mode: 2D TMx, 2D TMy, 2D TMz, or 3D
|
|
||||||
# cpu, cuda, opencl: solver type
|
# cpu, cuda, opencl: solver type
|
||||||
# precision: data type for electromagnetic field output (single/double)
|
# precision: data type for electromagnetic field output (single/double)
|
||||||
# autotranslate: auto translate objects with main grid coordinates
|
# autotranslate: auto translate objects with main grid coordinates
|
||||||
@@ -153,12 +155,12 @@ class SimulationConfig:
|
|||||||
# within the global subgrid space.
|
# within the global subgrid space.
|
||||||
self.general = {'messages': True,
|
self.general = {'messages': True,
|
||||||
'progressbars': True,
|
'progressbars': True,
|
||||||
'mode': '3D',
|
|
||||||
'cpu': True,
|
'cpu': True,
|
||||||
'cuda': False,
|
'cuda': False,
|
||||||
'opencl': False,
|
'opencl': False,
|
||||||
'precision': 'single',
|
'precision': 'single',
|
||||||
'autotranslate': False}
|
'autotranslate': False}
|
||||||
|
log.debug('Should autotranslate be a ModelConfig parameter?')
|
||||||
|
|
||||||
self.em_consts = {'c': c, # Speed of light in free space (m/s)
|
self.em_consts = {'c': c, # Speed of light in free space (m/s)
|
||||||
'e0': e0, # Permittivity of free space (F/m)
|
'e0': e0, # Permittivity of free space (F/m)
|
||||||
@@ -168,8 +170,17 @@ class SimulationConfig:
|
|||||||
# Store information about host machine
|
# Store information about host machine
|
||||||
self.hostinfo = get_host_info()
|
self.hostinfo = get_host_info()
|
||||||
|
|
||||||
# Information about any GPUs as a list of GPU objects
|
# Information about any Nvidia GPUs
|
||||||
self.cuda_gpus = []
|
if self.args.gpu is not None:
|
||||||
|
self.general['cuda'] = True
|
||||||
|
self.general['cpu'] = False
|
||||||
|
self.general['opencl'] = False
|
||||||
|
# gpus: list of GPU objects
|
||||||
|
# gpus_str: list of strings describing GPU(s)
|
||||||
|
self.cuda = {'gpus': [],
|
||||||
|
'gpus_str': []}
|
||||||
|
self.get_gpus()
|
||||||
|
self.set_gpus()
|
||||||
|
|
||||||
# Subgrid parameter may not exist if user enters via CLI
|
# Subgrid parameter may not exist if user enters via CLI
|
||||||
try:
|
try:
|
||||||
@@ -193,6 +204,19 @@ class SimulationConfig:
|
|||||||
def is_messages(self):
|
def is_messages(self):
|
||||||
return self.general['messages']
|
return self.general['messages']
|
||||||
|
|
||||||
|
def get_gpus(self):
|
||||||
|
"""Get information and setup any Nvidia GPU(s)."""
|
||||||
|
# Flatten a list of lists
|
||||||
|
if any(isinstance(element, list) for element in self.args.gpu):
|
||||||
|
self.cuda['gpus'] = [val for sublist in self.args.gpu for val in sublist]
|
||||||
|
|
||||||
|
self.cuda['gpus'], self.cuda['gpus_str'] = detect_check_gpus(self.cuda['gpus'])
|
||||||
|
|
||||||
|
def set_gpus(self):
|
||||||
|
"""Adjust list of GPU object(s) to specify single GPU."""
|
||||||
|
self.cuda['gpus'] = self.cuda['gpus'][0]
|
||||||
|
self.cuda['gpus_str'] = self.cuda['gpus_str'][0]
|
||||||
|
|
||||||
def set_precision(self):
|
def set_precision(self):
|
||||||
"""Data type (precision) for electromagnetic field output.
|
"""Data type (precision) for electromagnetic field output.
|
||||||
|
|
||||||
@@ -268,3 +292,7 @@ class SimulationConfigMPI(SimulationConfig):
|
|||||||
# Set range for number of models to run
|
# Set range for number of models to run
|
||||||
self.model_start = self.args.restart if self.args.restart else 1
|
self.model_start = self.args.restart if self.args.restart else 1
|
||||||
self.model_end = self.modelstart + self.args.n
|
self.model_end = self.modelstart + self.args.n
|
||||||
|
|
||||||
|
def set_gpus(self):
|
||||||
|
"""Leave list of GPU object(s) as multi-object list."""
|
||||||
|
pass
|
||||||
|
@@ -421,9 +421,9 @@ def dispersion_analysis(G):
|
|||||||
minwavelength = minvelocity / results['maxfreq']
|
minwavelength = minvelocity / results['maxfreq']
|
||||||
|
|
||||||
# Maximum spatial step
|
# Maximum spatial step
|
||||||
if '3D' in config.sim_config.general['mode']:
|
if '3D' in config.model_configs[G.model_num].mode:
|
||||||
delta = max(G.dx, G.dy, G.dz)
|
delta = max(G.dx, G.dy, G.dz)
|
||||||
elif '2D' in config.sim_config.general['mode']:
|
elif '2D' in config.model_configs[G.model_num].mode:
|
||||||
if G.nx == 1:
|
if G.nx == 1:
|
||||||
delta = max(G.dy, G.dz)
|
delta = max(G.dy, G.dz)
|
||||||
elif G.ny == 1:
|
elif G.ny == 1:
|
||||||
|
@@ -362,11 +362,11 @@ class GridBuilder:
|
|||||||
pbar.close()
|
pbar.close()
|
||||||
|
|
||||||
def tm_grid_update(self):
|
def tm_grid_update(self):
|
||||||
if '2D TMx' == config.sim_config.general['mode']:
|
if '2D TMx' == config.model_configs[self.grid.model_num].mode:
|
||||||
self.grid.tmx()
|
self.grid.tmx()
|
||||||
elif '2D TMy' == config.sim_config.general['mode']:
|
elif '2D TMy' == config.model_configs[self.grid.model_num].mode:
|
||||||
self.grid.tmy()
|
self.grid.tmy()
|
||||||
elif '2D TMz' == config.sim_config.general['mode']:
|
elif '2D TMz' == config.model_configs[self.grid.model_num].mode:
|
||||||
self.grid.tmz()
|
self.grid.tmz()
|
||||||
|
|
||||||
def update_voltage_source_materials(self):
|
def update_voltage_source_materials(self):
|
||||||
|
@@ -447,6 +447,7 @@ def detect_check_gpus(deviceIDs):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
gpus (list): Detected GPU(s) object(s).
|
gpus (list): Detected GPU(s) object(s).
|
||||||
|
gpus_str (list): Printable strings of information on GPU(s).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -475,15 +476,15 @@ def detect_check_gpus(deviceIDs):
|
|||||||
|
|
||||||
# Gather information about selected/detected GPUs
|
# Gather information about selected/detected GPUs
|
||||||
gpus = []
|
gpus = []
|
||||||
allgpustext = []
|
gpus_str = []
|
||||||
for ID in deviceIDsavail:
|
for ID in deviceIDsavail:
|
||||||
gpu = GPU(deviceID=ID)
|
gpu = GPU(deviceID=ID)
|
||||||
gpu.get_gpu_info(drv)
|
gpu.get_gpu_info(drv)
|
||||||
if ID in deviceIDs:
|
if ID in deviceIDs:
|
||||||
gpus.append(gpu)
|
gpus.append(gpu)
|
||||||
allgpustext.append(f'{gpu.deviceID} - {gpu.name}, {human_size(gpu.totalmem, a_kilobyte_is_1024_bytes=True)}')
|
gpus_str.append(f'{gpu.deviceID} - {gpu.name}, {human_size(gpu.totalmem, a_kilobyte_is_1024_bytes=True)}')
|
||||||
|
|
||||||
return gpus, allgpustext
|
return gpus, gpus_str
|
||||||
|
|
||||||
|
|
||||||
def timer():
|
def timer():
|
||||||
|
在新工单中引用
屏蔽一个用户