Changed from print to logging

This commit is contained in:
André R. Brodtkorb 2018-08-13 16:04:46 +02:00
parent 9592a09d36
commit 8bda93e565
5 changed files with 594 additions and 357 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -39,9 +39,10 @@ import pycuda.driver as cuda
Class which keeps track of time spent for a section of code Class which keeps track of time spent for a section of code
""" """
class Timer(object): class Timer(object):
def __init__(self, tag): def __init__(self, tag, log_level=logging.DEBUG):
self.tag = tag self.tag = tag
self.logger = logging.getLogger(__name__) self.log_level = log_level
self.logger = logging.getLogger(__name__)
def __enter__(self): def __enter__(self):
self.start = time.time() self.start = time.time()
@ -51,7 +52,7 @@ class Timer(object):
self.end = time.time() self.end = time.time()
self.secs = self.end - self.start self.secs = self.end - self.start
self.msecs = self.secs * 1000 # millisecs self.msecs = self.secs * 1000 # millisecs
self.logger.info("%s: %f ms", self.tag, self.msecs) self.logger.log(self.log_level, "%s: %f ms", self.tag, self.msecs)
@ -276,12 +277,14 @@ class CUDAArray2D:
Uploads initial data to the CL device Uploads initial data to the CL device
""" """
def __init__(self, stream, nx, ny, halo_x, halo_y, data): def __init__(self, stream, nx, ny, halo_x, halo_y, data):
self.logger = logging.getLogger(__name__)
self.nx = nx self.nx = nx
self.ny = ny self.ny = ny
self.nx_halo = nx + 2*halo_x self.nx_halo = nx + 2*halo_x
self.ny_halo = ny + 2*halo_y self.ny_halo = ny + 2*halo_y
self.logger.debug("Allocating [%dx%d] buffer", self.nx, self.ny)
#Make sure data is in proper format #Make sure data is in proper format
assert np.issubdtype(data.dtype, np.float32), "Wrong datatype: %s" % str(data.dtype) assert np.issubdtype(data.dtype, np.float32), "Wrong datatype: %s" % str(data.dtype)
assert not np.isfortran(data), "Wrong datatype (Fortran, expected C)" assert not np.isfortran(data), "Wrong datatype (Fortran, expected C)"
@ -293,17 +296,26 @@ class CUDAArray2D:
self.bytes_per_float = data.itemsize self.bytes_per_float = data.itemsize
assert(self.bytes_per_float == 4) assert(self.bytes_per_float == 4)
self.pitch = np.int32((self.nx_halo)*self.bytes_per_float) self.pitch = np.int32((self.nx_halo)*self.bytes_per_float)
self.logger.debug("Buffer <%s> [%dx%d]: Allocated ", int(self.data.gpudata), self.nx, self.ny)
def __del__(self, *args):
self.logger.debug("Buffer <%s> [%dx%d]: Releasing ", int(self.data.gpudata), self.nx, self.ny)
self.data.gpudata.free()
self.data = None
""" """
Enables downloading data from CL device to Python Enables downloading data from CL device to Python
""" """
def download(self, stream, async=False): def download(self, stream, async=False):
#Copy data from device to host #Copy data from device to host
if (async): if (async):
self.logger.debug("Buffer <%s> [%dx%d]: Downloading async ", int(self.data.gpudata), self.nx, self.ny)
host_data = self.data.get_async(stream=stream) host_data = self.data.get_async(stream=stream)
return host_data return host_data
else: else:
self.logger.debug("Buffer <%s> [%dx%d]: Downloading synchronously", int(self.data.gpudata), self.nx, self.ny)
host_data = self.data.get(stream=stream)#, pagelocked=True) # pagelocked causes crash on windows at least host_data = self.data.get(stream=stream)#, pagelocked=True) # pagelocked causes crash on windows at least
return host_data return host_data

View File

@ -48,7 +48,6 @@ class KP07 (Simulator.BaseSimulator):
dy: Grid cell spacing along y-axis (20 000 m) dy: Grid cell spacing along y-axis (20 000 m)
dt: Size of each timestep (90 s) dt: Size of each timestep (90 s)
g: Gravitational accelleration (9.81 m/s^2) g: Gravitational accelleration (9.81 m/s^2)
r: Bottom friction coefficient (2.4e-3 m/s)
""" """
def __init__(self, \ def __init__(self, \
context, \ context, \
@ -56,7 +55,7 @@ class KP07 (Simulator.BaseSimulator):
nx, ny, \ nx, ny, \
dx, dy, dt, \ dx, dy, dt, \
g, \ g, \
theta=1.3, r=0.0, \ theta=1.3, \
block_width=16, block_height=16): block_width=16, block_height=16):
# Call super constructor # Call super constructor
@ -69,11 +68,10 @@ class KP07 (Simulator.BaseSimulator):
block_width, block_height); block_width, block_height);
self.theta = np.float32(theta) self.theta = np.float32(theta)
self.r = np.float32(r)
#Get kernels #Get kernels
self.kernel = context.get_prepared_kernel("KP07_kernel.cu", "KP07Kernel", \ self.kernel = context.get_prepared_kernel("KP07_kernel.cu", "KP07Kernel", \
"iiffffffiPiPiPiPiPiPi", \ "iifffffiPiPiPiPiPiPi", \
BLOCK_WIDTH=block_width, \ BLOCK_WIDTH=block_width, \
BLOCK_HEIGHT=block_height) BLOCK_HEIGHT=block_height)
@ -89,7 +87,6 @@ class KP07 (Simulator.BaseSimulator):
self.dx, self.dy, dt, \ self.dx, self.dy, dt, \
self.g, \ self.g, \
self.theta, \ self.theta, \
self.r, \
np.int32(substep), \ np.int32(substep), \
self.data.h0.data.gpudata, self.data.h0.pitch, \ self.data.h0.data.gpudata, self.data.h0.pitch, \
self.data.hu0.data.gpudata, self.data.hu0.pitch, \ self.data.hu0.data.gpudata, self.data.hu0.pitch, \

View File

@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#Import packages we need #Import packages we need
import numpy as np import numpy as np
import logging
import pycuda.compiler as cuda_compiler import pycuda.compiler as cuda_compiler
import pycuda.gpuarray import pycuda.gpuarray
@ -53,6 +54,9 @@ class BaseSimulator:
dx, dy, dt, \ dx, dy, dt, \
g, \ g, \
block_width, block_height): block_width, block_height):
#Get logger
self.logger = logging.getLogger(__name__ + "." + self.__class__.__name__)
#Create a CUDA stream #Create a CUDA stream
self.stream = cuda.Stream() self.stream = cuda.Stream()
@ -93,20 +97,22 @@ class BaseSimulator:
Requires that the stepEuler functionality is implemented in the subclasses Requires that the stepEuler functionality is implemented in the subclasses
""" """
def simulateEuler(self, t_end): def simulateEuler(self, t_end):
# Compute number of timesteps to perform with Common.Timer(self.__class__.__name__ + ".simulateEuler") as t:
n = int(t_end / self.dt + 1) # Compute number of timesteps to perform
n = int(t_end / self.dt + 1)
for i in range(0, n): for i in range(0, n):
# Compute timestep for "this" iteration # Compute timestep for "this" iteration
local_dt = np.float32(min(self.dt, t_end-i*self.dt)) local_dt = np.float32(min(self.dt, t_end-i*self.dt))
# Stop if end reached (should not happen) # Stop if end reached (should not happen)
if (local_dt <= 0.0): if (local_dt <= 0.0):
break break
# Step with forward Euler # Step with forward Euler
self.stepEuler(local_dt) self.stepEuler(local_dt)
self.logger.info("%s simulated %f seconds to %f with %d steps in %f seconds", self.__class__.__name__, t_end, self.t, n, t.secs)
return self.t, n return self.t, n
""" """
@ -114,21 +120,22 @@ class BaseSimulator:
Requires that the stepRK functionality is implemented in the subclasses Requires that the stepRK functionality is implemented in the subclasses
""" """
def simulateRK(self, t_end, order): def simulateRK(self, t_end, order):
with Common.Timer(self.__class__.__name__ + ".simulateRK") as t:
# Compute number of timesteps to perform
n = int(t_end / self.dt + 1)
# Compute number of timesteps to perform for i in range(0, n):
n = int(t_end / self.dt + 1) # Compute timestep for "this" iteration
local_dt = np.float32(min(self.dt, t_end-i*self.dt))
for i in range(0, n): # Stop if end reached (should not happen)
# Compute timestep for "this" iteration if (local_dt <= 0.0):
local_dt = np.float32(min(self.dt, t_end-i*self.dt)) break
# Stop if end reached (should not happen) # Perform all the Runge-Kutta substeps
if (local_dt <= 0.0): self.stepRK(local_dt, order)
break
# Perform all the Runge-Kutta substeps
self.stepRK(local_dt, order)
self.logger.info("%s simulated %f seconds to %f with %d steps in %f seconds", self.__class__.__name__, t_end, self.t, n, t.secs)
return self.t, n return self.t, n
""" """
@ -136,23 +143,23 @@ class BaseSimulator:
Requires that the stepDimsplitX and stepDimsplitY functionality is implemented in the subclasses Requires that the stepDimsplitX and stepDimsplitY functionality is implemented in the subclasses
""" """
def simulateDimsplit(self, t_end): def simulateDimsplit(self, t_end):
with Common.Timer(self.__class__.__name__ + ".simulateDimsplit") as t:
# Compute number of timesteps to perform
n = int(t_end / (2.0*self.dt) + 1)
# Compute number of timesteps to perform for i in range(0, n):
n = int(t_end / (2.0*self.dt) + 1) # Compute timestep for "this" iteration
local_dt = np.float32(0.5*min(2*self.dt, t_end-2*i*self.dt))
for i in range(0, n): # Stop if end reached (should not happen)
# Compute timestep for "this" iteration if (local_dt <= 0.0):
local_dt = np.float32(0.5*min(2*self.dt, t_end-2*i*self.dt)) break
# Stop if end reached (should not happen)
if (local_dt <= 0.0):
break
# Perform the dimensional split substeps
self.stepDimsplitXY(local_dt)
self.stepDimsplitYX(local_dt)
# Perform the dimensional split substeps
self.stepDimsplitXY(local_dt)
self.stepDimsplitYX(local_dt)
self.logger.info("%s simulated %f seconds to %f with %d steps in %f seconds", self.__class__.__name__, t_end, self.t, 2*n, t.secs)
return self.t, 2*n return self.t, 2*n