def __init__(self, session, block_definition, block_usage, sync_mode=BufferInterface.SYNC_DEFAULT): super(BufferCPU, self).__init__(session, block_definition, block_usage, Buffer.LOCATION_CPU) self.cache = ByteCache(self.block_definition) self.sync_mode = sync_mode self.fresh_bytez = False
def test_pass_through_array_of_matrices(self): glsl_template = """ #version 450 #extension GL_ARB_separate_shader_objects : enable layout(local_size_x=1, local_size_y=1, local_size_z=1) in; layout({layout_in}, {order_in}, binding = 0) buffer BufferA {{ {dtype}[32][48] dataIn; }}; layout({layout_out}, {order_out}, binding = 1) buffer BufferB {{ {dtype}[32][48] dataOut; }}; void main() {{ vec3 pixel = gl_GlobalInvocationID; int h = int(pixel.x); int w = int(pixel.y); dataOut[h][w] = dataIn[h][w]; }} """ rng = np.random.RandomState(123) w = 48 h = 32 matrix_combinations = itertools.product(range(2, 5), range(2, 5), [DataType.FLOAT, DataType.DOUBLE]) layout_order_combinations = itertools.product(self.LAYOUTS, self.LAYOUTS, self.ORDERS, self.ORDERS) for combos1, combos2 in itertools.product(layout_order_combinations, matrix_combinations): layout_in, layout_out, order_in, order_out = combos1 matrix_in = Matrix(*combos2, layout=layout_in, order=order_in) shape = [h, w] + list(matrix_in.shape()) mat = rng.randint(0, 255, size=shape).astype(matrix_in.vector.scalar.numpy_dtype()) glsl = glsl_template.format(**{ "layout_in": self.LAYOUT_MAP[layout_in], "layout_out": self.LAYOUT_MAP[layout_out], "order_in": self.ORDERS_MAP[order_in], "order_out": self.ORDERS_MAP[order_out], "dtype": matrix_in.glsl_dtype() }) shader = self.shader_from_txt(glsl, verbose=False) shader.inspect() cache_in = ByteCache(shader.get_block_definition(0)) cache_in["dataIn"] = mat bytez_in = cache_in.definition.to_bytes(cache_in.get_as_dict()) cache_out = ByteCache(shader.get_block_definition(1)) bytez_out_count = cache_out.definition.size() bytez_out = self.run_compiled_program(shader, bytez_in, bytez_out_count, groups=(h, w, 1)) cache_out.set_from_dict(cache_out.definition.from_bytes(bytez_out)) self.assertTrue((cache_out["dataOut"] == mat).all())
def test_pass_through_array_of_vectors(self): glsl_template = """ #version 450 #extension GL_ARB_separate_shader_objects : enable layout(local_size_x=1, local_size_y=1, local_size_z=1) in; layout({layout_in}, binding = 0) buffer BufferA {{ {dtype}[720][1280] imageIn; }}; layout({layout_out}, binding = 1) buffer BufferB {{ {dtype}[720][1280] imageOut; }}; void main() {{ vec3 pixel = gl_GlobalInvocationID; int h = int(pixel.x); int w = int(pixel.y); imageOut[h][w] = imageIn[h][w]; }} """ rng = np.random.RandomState(123) w = 1280 h = 720 for layout_in, layout_out, n, dtype in itertools.product( self.LAYOUTS, self.LAYOUTS, range(2, 5), DataType.ALL): vector = Vector(n, dtype) im = rng.randint(0, 255, size=(h, w, n)).astype(vector.scalar.numpy_dtype()) glsl = glsl_template.format( **{ "layout_in": self.LAYOUT_MAP[layout_in], "layout_out": self.LAYOUT_MAP[layout_out], "dtype": vector.glsl_dtype() }) shader = self.shader_from_txt(glsl, verbose=False) shader.inspect() cache_in = ByteCache(shader.code.get_block_definition(0)) cache_in["imageIn"] = im bytez_in = cache_in.definition.to_bytes(cache_in.get_as_dict()) cache_out = ByteCache(shader.code.get_block_definition(1)) bytez_out_count = cache_out.definition.size() bytez_out = self.run_compiled_program(shader, bytez_in, bytez_out_count, groups=(h, w, 1)) cache_out.set_from_dict(cache_out.definition.from_bytes(bytez_out)) self.assertTrue((cache_out["imageOut"] == im).all())
def test_manually(self): # byte cache test buffer_usage = BufferUsage.STORAGE_BUFFER buffer_layout = Layout.STD430 buffer_order = Order.ROW_MAJOR struct1 = Struct([Vector.vec3(), Vector.ivec2()], buffer_layout, member_names=["a", "b"], type_name="structB") struct2 = Struct( [Scalar.double(), Scalar.double(), struct1], buffer_layout, type_name="structC") structs = [struct1, struct2] variables = [ Scalar.uint(), Array(Vector.vec2(), (5, 2, 3), buffer_layout), Array(Scalar.float(), 5, buffer_layout), struct2, # this struct needs padding at the end Scalar.uint(), Array(struct1, (2, 3), buffer_layout) ] container = Struct(variables, buffer_layout, type_name="block") cache = ByteCache(container) print("") print("") pprint.pprint(cache.values) print(cache[-1][0][0]["a"]) print("") print("") pprint.pprint(cache) print(cache[-1][0][0]) print("") print("") pprint.pprint(cache.get_as_dict())
class BufferCPU(Buffer): def __init__(self, session, block_definition, block_usage, sync_mode=BufferInterface.SYNC_DEFAULT): super(BufferCPU, self).__init__(session, block_definition, block_usage, Buffer.LOCATION_CPU) self.cache = ByteCache(self.block_definition) self.sync_mode = sync_mode self.fresh_bytez = False @classmethod def from_shader(cls, session, shader, binding, sync_mode=BufferInterface.SYNC_DEFAULT): block_definition = shader.get_block_definition(binding) block_usage = shader.get_block_usage(binding) return cls(session, block_definition, block_usage, sync_mode) def before_stage(self, stage, binding, access_modifier): if access_modifier in [Access.READ_ONLY, Access.READ_WRITE]: if self.sync_mode is self.SYNC_LAZY and self.cache.is_dirty(): self.flush() def after_stage(self, stage, binding, access_modifier): if access_modifier in [Access.WRITE_ONLY, Access.READ_WRITE]: self.fresh_bytez = True if self.sync_mode is self.SYNC_EAGER: self.fetch() def __getitem__(self, key): if self.fresh_bytez and self.sync_mode is self.SYNC_LAZY: self.fetch() return self.cache[key] def __setitem__(self, key, value): self.cache[key] = value if self.sync_mode is self.SYNC_EAGER: self.flush() def is_synced(self): return not self.fresh_bytez and not self.cache.is_dirty() def flush(self): if self.fresh_bytez: warnings.warn( "Buffer contains (probably) data which is not in the cache, it will be overwritten", RuntimeWarning) data = self.cache.get_as_dict() bytez = self.block_definition.to_bytes(data) self.vulkan_buffer.map(bytez) self.cache.set_dirty(False) self.fresh_bytez = False def fetch(self): if self.cache.is_dirty(): warnings.warn( "Cache contains data which is not in the buffer, it will by overwritten", RuntimeWarning) with self.vulkan_buffer.mapped() as bytebuffer: bytez = bytebuffer[:] data = self.block_definition.from_bytes(bytez) self.cache.set_from_dict(data) self.cache.set_dirty(False) self.fresh_bytez = False
def test_pass_through_bools(self): glsl_template = """ #version 450 #extension GL_ARB_separate_shader_objects : enable layout(local_size_x=1, local_size_y=1, local_size_z=1) in; layout({layout_in}, binding = 0) buffer BufferA {{ {dtype} dataIn; {dtype}[{array_size}] dataArrayIn; }}; layout({layout_out}, binding = 1) buffer BufferB {{ {dtype} dataOut; {dtype}[{array_size}] dataArrayOut; }}; void main() {{ dataOut = dataIn; dataArrayOut = dataArrayIn; }} """ dtypes = ["bool", "bvec2", "bvec3", "bvec4"] array_size = 5 for dtype, layout_in, layout_out in itertools.product( dtypes, self.LAYOUTS, self.LAYOUTS): glsl = glsl_template.format( **{ "layout_in": self.LAYOUT_MAP[layout_in], "layout_out": self.LAYOUT_MAP[layout_out], "dtype": dtype, "array_size": array_size }) shader = self.shader_from_txt(glsl, verbose=False) shader.inspect() cache_in = ByteCache(shader.code.get_block_definition(0)) m = 1 if dtype == "bool" else cache_in.definition.definitions[ 0].length() if m == 1: data_in = True data_array_in = (np.arange(array_size) % 2).astype(bool) else: data_in = np.array([True] * m) data_array_in = (np.arange(array_size * m).reshape( (array_size, m)) % 2).astype(bool) cache_in["dataIn"] = data_in cache_in["dataArrayIn"] = data_array_in bytez_in = cache_in.definition.to_bytes(cache_in.get_as_dict()) cache_out = ByteCache(shader.code.get_block_definition(1)) bytez_out_count = cache_out.definition.size() bytez_out = self.run_compiled_program(shader, bytez_in, bytez_out_count) cache_out.set_from_dict(cache_out.definition.from_bytes(bytez_out)) if m == 1: self.assertEqual(cache_out["dataOut"], data_in) else: self.assertTrue((cache_out["dataOut"] == data_in).all()) self.assertTrue((cache_out["dataArrayOut"] == data_array_in).all())
def test_pass_through_struct(self): glsl_template = """ #version 450 #extension GL_ARB_separate_shader_objects : enable layout(local_size_x=1, local_size_y=1, local_size_z=1) in; {struct_glsl} layout({layout_in}, binding = 0) buffer BufferA {{ {dtype} structIn; }}; layout({layout_out}, binding = 1) buffer BufferB {{ {dtype} structOut; }}; void main() {{ structOut = structIn; }} """ rng = np.random.RandomState(123) scalars = [Scalar.of(dtype) for dtype in DataType.ALL] vectors = [ Vector(n, dtype) for n, dtype in itertools.product(range(2, 5), DataType.ALL) ] type_name = "SomeStruct" for layout_in, layout_out in itertools.product(self.LAYOUTS, self.LAYOUTS): members = rng.permutation(scalars + scalars + vectors + vectors) glsl_struct = ["struct {} {{".format(type_name)] for i, member in enumerate(members): glsl_struct.append("{} member{};".format( member.glsl_dtype(), i)) glsl_struct.append("};") glsl = glsl_template.format( **{ "layout_in": self.LAYOUT_MAP[layout_in], "layout_out": self.LAYOUT_MAP[layout_out], "struct_glsl": "\n".join(glsl_struct), "dtype": type_name }) shader = self.shader_from_txt(glsl, verbose=False) shader.inspect() cache_in = ByteCache(shader.code.get_block_definition(0)) for i, member in enumerate(members): if isinstance(member, Scalar): value = member.numpy_dtype()(1.) elif isinstance(member, Vector): value = np.ones(member.length(), member.scalar.numpy_dtype()) else: value = None cache_in["structIn"][i] = value bytez_in = cache_in.definition.to_bytes(cache_in.get_as_dict()) cache_out = ByteCache(shader.code.get_block_definition(1)) bytez_out_count = cache_out.definition.size() bytez_out = self.run_compiled_program(shader, bytez_in, bytez_out_count) cache_out.set_from_dict(cache_out.definition.from_bytes(bytez_out)) for i, member in enumerate(members): a = cache_in["structIn"][i] b = cache_out["structOut"][i] if isinstance(member, Vector): a = a.tolist() b = b.tolist() self.assertEqual(a, b)