From 3ab16a1ac79e0781563c7564cd678a8c87474486 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sun, 30 Jun 2019 19:13:36 +0200 Subject: Move OpenCL buffers into Memory class --- simulation.py | 115 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 55 deletions(-) (limited to 'simulation.py') diff --git a/simulation.py b/simulation.py index d3b8641..039486c 100644 --- a/simulation.py +++ b/simulation.py @@ -11,7 +11,6 @@ from pyopencl.tools import get_gl_sharing_context_properties import OpenGL.GL as gl from OpenGL.arrays import vbo - class Geometry: def __init__(self, size_x, size_y, size_z = 1): self.size_x = size_x @@ -36,6 +35,9 @@ class Geometry: return (self.size_x-2, self.size_y-2, self.size_z-2) +def pad(n, m): + return (n // m + min(1,n % m)) * m + class Grid: def __init__(self, geometry, padding = None): if padding == None: @@ -43,9 +45,12 @@ class Grid: self.size_y = geometry.size_y self.size_z = geometry.size_z else: - self.size_x = (geometry.size_x // padding[0] + min(1,geometry.size_x % padding[0])) * padding[0] - self.size_y = (geometry.size_y // padding[1] + min(1,geometry.size_y % padding[1])) * padding[1] - self.size_z = (geometry.size_z // padding[2] + min(1,geometry.size_z % padding[2])) * padding[2] + self.size_x = pad(geometry.size_x, padding[0]) + self.size_y = pad(geometry.size_y, padding[1]) + if geometry.size_z == 1: + self.size_z = geometry.size_z + else: + self.size_z = pad(geometry.size_z, padding[2]) self.volume = self.size_x * self.size_y * self.size_z @@ -55,11 +60,14 @@ class Grid: else: return (self.size_x, self.size_y, self.size_z) - class Memory: - def __init__(self, grid, align = True): + def __init__(self, descriptor, grid, context, float_type, align, opengl): + self.descriptor = descriptor + self.context = context + self.float_type = float_type + if align: - self.size_x = (grid.size_x // 32 + min(1,grid.size_x % 32)) * 32 + self.size_x = pad(grid.size_x, 32) else: self.size_x = grid.size_x @@ -68,6 +76,25 @@ class Memory: self.volume = self.size_x * self.size_y * self.size_z + self.pop_size = descriptor.q * self.volume * self.float_type(0).nbytes + self.moments_size = (descriptor.d+1) * self.volume * self.float_type(0).nbytes + + self.cl_pop_a = cl.Buffer(self.context, mf.READ_WRITE, size=self.pop_size) + self.cl_pop_b = cl.Buffer(self.context, mf.READ_WRITE, size=self.pop_size) + + if opengl: + self.np_moments = numpy.ndarray(shape=(self.volume, 4), dtype=self.float_type) + self.gl_moments = vbo.VBO(data=self.np_moments, usage=gl.GL_DYNAMIC_DRAW, target=gl.GL_ARRAY_BUFFER) + self.gl_moments.bind() + self.cl_gl_moments = cl.GLBuffer(self.context, mf.READ_WRITE, int(self.gl_moments)) + else: + self.cl_moments = cl.Buffer(self.context, mf.WRITE_ONLY, size=self.moments_size) + + self.cl_material = cl.Buffer(self.context, mf.READ_ONLY, size=self.volume * numpy.int32(0).nbytes) + + def gid(self, x, y, z = 0): + return z * (self.size_x*self.size_y) + y * self.size_x + x; + class Lattice: def __init__(self, @@ -77,28 +104,13 @@ class Lattice: ): self.descriptor = descriptor self.geometry = geometry - - self.grid = Grid(self.geometry, padding) - self.memory = Memory(self.grid, align) - - self.moments = moments - self.collide = collide - - self.pop_eq_src = pop_eq_src - self.boundary_src = boundary_src + self.grid = Grid(self.geometry, padding) self.float_type = { 'single': (numpy.float32, 'float'), 'double': (numpy.float64, 'double'), }.get(precision, None) - self.layout = layout - - self.compiler_args = { - 'single': '-cl-single-precision-constant -cl-fast-relaxed-math', - 'double': '-cl-fast-relaxed-math' - }.get(precision, None) - self.platform = cl.get_platforms()[platform] if opengl: @@ -110,45 +122,40 @@ class Lattice: self.queue = cl.CommandQueue(self.context) - self.pop_size = descriptor.q * self.memory.volume * self.float_type[0](0).nbytes - self.moments_size = (descriptor.d+1) * self.memory.volume * self.float_type[0](0).nbytes + self.memory = Memory(self.descriptor, self.grid, self.context, self.float_type[0], align, opengl) + self.tick = False - self.tick = True - self.cl_pop_a = cl.Buffer(self.context, mf.READ_WRITE, size=self.pop_size) - self.cl_pop_b = cl.Buffer(self.context, mf.READ_WRITE, size=self.pop_size) + self.moments = moments + self.collide = collide - if opengl: - self.np_moments = numpy.ndarray(shape=(self.memory.volume, 4), dtype=self.float_type[0]) - self.gl_moments = vbo.VBO(data=self.np_moments, usage=gl.GL_DYNAMIC_DRAW, target=gl.GL_ARRAY_BUFFER) - self.gl_moments.bind() - self.cl_gl_moments = cl.GLBuffer(self.context, mf.READ_WRITE, int(self.gl_moments)) - else: - self.cl_moments = cl.Buffer(self.context, mf.WRITE_ONLY, size=self.moments_size) + self.pop_eq_src = pop_eq_src + self.boundary_src = boundary_src - self.cl_material = cl.Buffer(self.context, mf.READ_ONLY, size=self.memory.volume * numpy.int32(0).nbytes) + self.layout = layout + + self.compiler_args = { + 'single': '-cl-single-precision-constant -cl-fast-relaxed-math', + 'double': '-cl-fast-relaxed-math' + }.get(precision, None) self.build_kernel() self.program.equilibrilize( - self.queue, self.grid.size(), self.layout, self.cl_pop_a, self.cl_pop_b).wait() - - def gid(self, x, y, z = 0): - return z * (self.memory.size_x*self.memory.size_y) + y * self.memory.size_x + x; + self.queue, self.grid.size(), self.layout, self.memory.cl_pop_a, self.memory.cl_pop_b).wait() def setup_geometry(self, material_at): material = numpy.ndarray(shape=(self.memory.volume, 1), dtype=numpy.int32) material[:,:] = 0 for idx in self.geometry.inner_cells(): - material[self.gid(*idx)] = material_at(self.geometry, *idx) + material[self.memory.gid(*idx)] = material_at(self.geometry, *idx) - cl.enqueue_copy(self.queue, self.cl_material, material).wait(); + cl.enqueue_copy(self.queue, self.memory.cl_material, material).wait(); def build_kernel(self): program_src = Template(filename = str(Path(__file__).parent/'template/kernel.mako')).render( descriptor = self.descriptor, geometry = self.geometry, - grid = self.grid, memory = self.memory, moments_subexpr = self.moments[0], @@ -161,16 +168,14 @@ class Lattice: pop_eq_src = Template(self.pop_eq_src).render( descriptor = self.descriptor, geometry = self.geometry, - grid = self.grid, memory = self.memory, - float_type = self.float_type[1] + float_type = self.float_type[1], ), boundary_src = Template(self.boundary_src).render( descriptor = self.descriptor, geometry = self.geometry, - grid = self.grid, memory = self.memory, - float_type = self.float_type[1] + float_type = self.float_type[1], ), ccode = sympy.ccode @@ -181,11 +186,11 @@ class Lattice: if self.tick: self.tick = False self.program.collide_and_stream( - self.queue, self.grid.size(), self.layout, self.cl_pop_a, self.cl_pop_b, self.cl_material) + self.queue, self.grid.size(), self.layout, self.memory.cl_pop_a, self.memory.cl_pop_b, self.memory.cl_material) else: self.tick = True self.program.collide_and_stream( - self.queue, self.grid.size(), self.layout, self.cl_pop_b, self.cl_pop_a, self.cl_material) + self.queue, self.grid.size(), self.layout, self.memory.cl_pop_b, self.memory.cl_pop_a, self.memory.cl_material) def sync(self): self.queue.finish() @@ -195,24 +200,24 @@ class Lattice: if self.tick: self.program.collect_moments( - self.queue, self.grid.size(), self.layout, self.cl_pop_b, self.cl_moments) + self.queue, self.grid.size(), self.layout, self.memory.cl_pop_b, self.memory.cl_moments) else: self.program.collect_moments( - self.queue, self.grid.size(), self.layout, self.cl_pop_a, self.cl_moments) + self.queue, self.grid.size(), self.layout, self.memory.cl_pop_a, self.memory.cl_moments) - cl.enqueue_copy(self.queue, moments, self.cl_moments).wait(); + cl.enqueue_copy(self.queue, moments, self.memory.cl_moments).wait(); return moments def sync_gl_moments(self): - cl.enqueue_acquire_gl_objects(self.queue, [self.cl_gl_moments]) + cl.enqueue_acquire_gl_objects(self.queue, [self.memory.cl_gl_moments]) if self.tick: self.program.collect_gl_moments( - self.queue, self.grid.size(), self.layout, self.cl_pop_b, self.cl_gl_moments) + self.queue, self.grid.size(), self.layout, self.memory.cl_pop_b, self.memory.cl_gl_moments) else: self.program.collect_gl_moments( - self.queue, self.grid.size(), self.layout, self.cl_pop_a, self.cl_gl_moments) + self.queue, self.grid.size(), self.layout, self.memory.cl_pop_a, self.memory.cl_gl_moments) #cl.enqueue_release_gl_objects(self.queue, [self.cl_gl_moments]) self.sync() -- cgit v1.2.3