First running version.

This commit is contained in:
Martin Lilleeng Sætra 2021-05-13 14:47:06 +00:00
parent 5b6c4f682d
commit b6424b84fb
3 changed files with 88 additions and 60 deletions

View File

@ -26,6 +26,7 @@ import numpy as np
import pycuda.driver as cuda import pycuda.driver as cuda
import time
class SHMEMGrid(object): class SHMEMGrid(object):
""" """
@ -160,16 +161,12 @@ class SHMEMSimulatorGroup(Simulator.BaseSimulator):
Class which handles communication and synchronization between simulators in different Class which handles communication and synchronization between simulators in different
contexts (presumably on different GPUs) contexts (presumably on different GPUs)
""" """
def __init__(self, grid, **kwargs): def __init__(self, sims, grid):
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
sims = []
assert(grid.ngpus > 0) assert(len(sims) > 1)
for i in range(grid.ngpus): self.sims = sims
kwargs['context'] = grid.cuda_contexts[i]
sims.append(EE2D_KP07_dimsplit.EE2D_KP07_dimsplit(**kwargs))
#sims[i] = SHMEMSimulator(i, local_sim, grid) # 1st attempt: no wrapper (per sim)
autotuner = sims[0].context.autotuner autotuner = sims[0].context.autotuner
sims[0].context.autotuner = None sims[0].context.autotuner = None
@ -187,34 +184,34 @@ class SHMEMSimulatorGroup(Simulator.BaseSimulator):
self.sims = sims self.sims = sims
self.grid = grid self.grid = grid
self.east = [] self.east = [None] * len(self.sims)
self.west = [] self.west = [None] * len(self.sims)
self.north = [] self.north = [None] * len(self.sims)
self.south = [] self.south = [None] * len(self.sims)
self.nvars = [] self.nvars = [None] * len(self.sims)
self.read_e = [] self.read_e = [None] * len(self.sims)
self.read_w = [] self.read_w = [None] * len(self.sims)
self.read_n = [] self.read_n = [None] * len(self.sims)
self.read_s = [] self.read_s = [None] * len(self.sims)
self.write_e = [] self.write_e = [None] * len(self.sims)
self.write_w = [] self.write_w = [None] * len(self.sims)
self.write_n = [] self.write_n = [None] * len(self.sims)
self.write_s = [] self.write_s = [None] * len(self.sims)
self.e = [] self.e = [None] * len(self.sims)
self.w = [] self.w = [None] * len(self.sims)
self.n = [] self.n = [None] * len(self.sims)
self.s = [] self.s = [None] * len(self.sims)
for i, sim in enumerate(self.sims): for i, sim in enumerate(self.sims):
#Get neighbor subdomain ids #Get neighbor subdomain ids
self.east[i] = grid.getEast(self.index) self.east[i] = grid.getEast(i)
self.west[i] = grid.getWest(self.index) self.west[i] = grid.getWest(i)
self.north[i] = grid.getNorth(self.index) self.north[i] = grid.getNorth(i)
self.south[i] = grid.getSouth(self.index) self.south[i] = grid.getSouth(i)
#Get coordinate of this subdomain #Get coordinate of this subdomain
#and handle global boundary conditions #and handle global boundary conditions
@ -250,32 +247,33 @@ class SHMEMSimulatorGroup(Simulator.BaseSimulator):
#Set regions for ghost cells to read from #Set regions for ghost cells to read from
#These have the format [x0, y0, width, height] #These have the format [x0, y0, width, height]
self.read_e.append(np.array([ nx, 0, gc_x, ny + 2*gc_y])) self.read_e[i] = np.array([ nx, 0, gc_x, ny + 2*gc_y])
self.read_w.append(np.array([gc_x, 0, gc_x, ny + 2*gc_y])) self.read_w[i] = np.array([gc_x, 0, gc_x, ny + 2*gc_y])
self.read_n.append(np.array([gc_x, ny, nx, gc_y])) self.read_n[i] = np.array([gc_x, ny, nx, gc_y])
self.read_s.append(np.array([gc_x, gc_y, nx, gc_y])) self.read_s[i] = np.array([gc_x, gc_y, nx, gc_y])
#Set regions for ghost cells to write to #Set regions for ghost cells to write to
self.write_e.append(self.read_e + np.array([gc_x, 0, 0, 0])) self.write_e[i] = self.read_e[i] + np.array([gc_x, 0, 0, 0])
self.write_w.append(self.read_w - np.array([gc_x, 0, 0, 0])) self.write_w[i] = self.read_w[i] - np.array([gc_x, 0, 0, 0])
self.write_n.append(self.read_n + np.array([0, gc_y, 0, 0])) self.write_n[i] = self.read_n[i] + np.array([0, gc_y, 0, 0])
self.write_s.append(self.read_s - np.array([0, gc_y, 0, 0])) self.write_s[i] = self.read_s[i] - np.array([0, gc_y, 0, 0])
#Allocate host data #Allocate host data
#Note that east and west also transfer ghost cells #Note that east and west also transfer ghost cells
#whilst north/south only transfer internal cells #whilst north/south only transfer internal cells
#Reuses the width/height defined in the read-extets above #Reuses the width/height defined in the read-extets above
self.e.append(np.empty((self.nvars, self.read_e[3], self.read_e[2]), dtype=np.float32)) self.e[i] = np.empty((self.nvars[i], self.read_e[i][3], self.read_e[i][2]), dtype=np.float32)
self.w.append(np.empty((self.nvars, self.read_w[3], self.read_w[2]), dtype=np.float32)) self.w[i] = np.empty((self.nvars[i], self.read_w[i][3], self.read_w[i][2]), dtype=np.float32)
self.n.append(np.empty((self.nvars, self.read_n[3], self.read_n[2]), dtype=np.float32)) self.n[i] = np.empty((self.nvars[i], self.read_n[i][3], self.read_n[i][2]), dtype=np.float32)
self.s.append(np.empty((self.nvars, self.read_s[3], self.read_s[2]), dtype=np.float32)) self.s[i] = np.empty((self.nvars[i], self.read_s[i][3], self.read_s[i][2]), dtype=np.float32)
self.logger.debug("Initialized {:d} subdomains".format(len(self.sims))) self.logger.debug("Initialized {:d} subdomains".format(len(self.sims)))
def substep(self, dt, step_number): def substep(self, dt, step_number):
self.exchange()
for i, sim in enumerate(self.sims): for i, sim in enumerate(self.sims):
self.exchange(i)
sim.substep(dt, step_number) sim.substep(dt, step_number)
def getOutput(self): def getOutput(self):
@ -293,6 +291,8 @@ class SHMEMSimulatorGroup(Simulator.BaseSimulator):
def computeDt(self): def computeDt(self):
global_dt = float("inf") global_dt = float("inf")
# XXX: Global sync is needed here
for sim in self.sims: for sim in self.sims:
local_dt = sim.computeDt() local_dt = sim.computeDt()
if local_dt < global_dt: if local_dt < global_dt:
@ -302,7 +302,7 @@ class SHMEMSimulatorGroup(Simulator.BaseSimulator):
self.logger.debug("Global dt: {:f}".format(global_dt)) self.logger.debug("Global dt: {:f}".format(global_dt))
return global_dt return global_dt
def getExtent(self, index): def getExtent(self, index=0):
""" """
Function which returns the extent of the subdomain with index Function which returns the extent of the subdomain with index
index in the grid index in the grid
@ -316,17 +316,27 @@ class SHMEMSimulatorGroup(Simulator.BaseSimulator):
y1 = y0 + height y1 = y0 + height
return [x0, x1, y0, y1] return [x0, x1, y0, y1]
def exchange(self, i): def exchange(self):
#### ####
# First transfer internal cells north-south # First transfer internal cells north-south
#### ####
for i in range(len(self.sims)):
self.ns_download(i) self.ns_download(i)
# XXX: Global sync is needed here
for i in range(len(self.sims)):
self.ns_upload(i) self.ns_upload(i)
#### ####
# Then transfer east-west including ghost cells that have been filled in by north-south transfer above # Then transfer east-west including ghost cells that have been filled in by north-south transfer above
#### ####
for i in range(len(self.sims)):
self.ew_download(i) self.ew_download(i)
# XXX: Global sync is needed here
for i in range(len(self.sims)):
self.ew_upload(i) self.ew_upload(i)
def ns_download(self, i): def ns_download(self, i):
@ -363,6 +373,10 @@ class SHMEMSimulatorGroup(Simulator.BaseSimulator):
if self.east[i] is not None: if self.east[i] is not None:
for k in range(self.nvars[i]): for k in range(self.nvars[i]):
self.sims[i].u0[k].upload(self.sims[i].stream, self.w[self.east[i]][k,:,:], extent=self.write_e[i]) self.sims[i].u0[k].upload(self.sims[i].stream, self.w[self.east[i]][k,:,:], extent=self.write_e[i])
#test_east = np.ones_like(self.e[self.east[i]][k,:,:])
#self.sims[i].u0[k].upload(self.sims[i].stream, test_east, extent=self.write_e[i])
if self.west[i] is not None: if self.west[i] is not None:
for k in range(self.nvars[i]): for k in range(self.nvars[i]):
self.sims[i].u0[k].upload(self.sims[i].stream, self.e[self.west[i]][k,:,:], extent=self.write_w[i]) self.sims[i].u0[k].upload(self.sims[i].stream, self.e[self.west[i]][k,:,:], extent=self.write_w[i])
#test_west = np.ones_like(self.e[self.west[i]][k,:,:])
#self.sims[i].u0[k].upload(self.sims[i].stream, test_west, extent=self.write_w[i])

View File

@ -25,10 +25,13 @@ import numpy as np
import gc import gc
def getExtent(width, height, nx, ny, grid): def getExtent(width, height, nx, ny, grid, index=None):
if grid is not None: if grid is not None:
gx = grid.grid[0] gx = grid.grid[0]
gy = grid.grid[1] gy = grid.grid[1]
if index is not None:
i, j = grid.getCoordinate(index)
else:
i, j = grid.getCoordinate() i, j = grid.getCoordinate()
dx = (width / gx) / nx dx = (width / gx) / nx
@ -192,7 +195,7 @@ def genShockBubble(nx, ny, gamma, grid=None):
def genKelvinHelmholtz(nx, ny, gamma, roughness=0.125, grid=None): def genKelvinHelmholtz(nx, ny, gamma, roughness=0.125, grid=None, index=None):
""" """
Roughness parameter in (0, 1.0] determines how "squiggly" Roughness parameter in (0, 1.0] determines how "squiggly"
the interface betweeen the zones is the interface betweeen the zones is
@ -234,7 +237,7 @@ def genKelvinHelmholtz(nx, ny, gamma, roughness=0.125, grid=None):
x0, x1, y0, y1, _, dy = getExtent(1.0, 1.0, nx, ny, grid) x0, x1, y0, y1, _, dy = getExtent(1.0, 1.0, nx, ny, grid, index)
x = np.linspace(x0, x1, nx) x = np.linspace(x0, x1, nx)
y = np.linspace(y0, y1, ny) y = np.linspace(y0, y1, ny)
_, y = np.meshgrid(x, y) _, y = np.meshgrid(x, y)
@ -274,7 +277,7 @@ def genKelvinHelmholtz(nx, ny, gamma, roughness=0.125, grid=None):
E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0) E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0)
_, _, _, _, dx, dy = getExtent(width, height, nx, ny, grid) _, _, _, _, dx, dy = getExtent(width, height, nx, ny, grid, index)
bc = BoundaryCondition({ bc = BoundaryCondition({

View File

@ -74,7 +74,7 @@ logger.info("Generating initial conditions")
nx = 128 nx = 128
ny = 128 ny = 128
gamma = 1.4 gamma = 1.4
save_times = np.linspace(0, 5.0, 10) save_times = np.linspace(0, 0.01, 10)
save_var_names = ['rho', 'rho_u', 'rho_v', 'E'] save_var_names = ['rho', 'rho_u', 'rho_v', 'E']
outfile = "shmem_out.nc" outfile = "shmem_out.nc"
@ -84,18 +84,29 @@ outfile = "shmem_out.nc"
#local_sim = [] #local_sim = []
#sim = [] #sim = []
arguments = IC.genKelvinHelmholtz(nx, ny, gamma, grid=grid)
arguments['context'] = grid.cuda_contexts[0]
arguments['theta'] = 1.2
arguments['grid'] = grid
#### ####
# Run simulation # Run simulation
#### ####
logger.info("Running simulation") logger.info("Running simulation")
sims = []
for i in range(grid.ngpus):
arguments = IC.genKelvinHelmholtz(nx, ny, gamma, grid=grid, index=i)
arguments['context'] = grid.cuda_contexts[i]
arguments['theta'] = 1.2
sims.append(EE2D_KP07_dimsplit.EE2D_KP07_dimsplit(**arguments))
#sims[i] = SHMEMSimulator(i, local_sim, grid) # 1st attempt: no wrapper (per sim)
arguments['sims'] = sims
arguments['grid'] = grid
#Helper function to create SHMEM simulator #Helper function to create SHMEM simulator
def genSim(grid, **kwargs): def genSim(sims, grid, **kwargs):
sim = SHMEMSimulatorGroup.SHMEMSimulatorGroup(grid, **kwargs) # XXX: kwargs not used, since the simulators are already instantiated in the for-loop above
sim = SHMEMSimulatorGroup.SHMEMSimulatorGroup(sims, grid)
return sim return sim
outfile = Common.runSimulation(genSim, arguments, outfile, save_times, save_var_names) outfile = Common.runSimulation(genSim, arguments, outfile, save_times, save_var_names)