def __init__(self, data_area_size = DEFAULT_DATA_AREA_SIZE, code_area_size = DEFAULT_CODE_AREA_SIZE, max_threads = DEFAULT_MAX_THREADS ): self.mailbox = MailBox() self.mailbox.enable_qpu(1) self.memory = None try: self.data_area_size = data_area_size self.code_area_size = code_area_size self.max_threads = max_threads self.code_area_base = 0 self.data_area_base = self.code_area_base + self.code_area_size self.msg_area_base = self.data_area_base + self.data_area_size self.code_pos = self.code_area_base self.data_pos = self.data_area_base total = data_area_size + code_area_size + max_threads * 64 self.memory = Memory(self.mailbox, total) self.message = Array( address = self.memory.baseaddr + self.msg_area_base, buffer = self.memory.base, offset = self.msg_area_base, shape = (self.max_threads, 2), dtype = np.uint32) except: if self.memory: self.memory.close() self.mailbox.enable_qpu(0) self.mailbox.close() raise
def __init__(self, data_area_size = DEFAULT_DATA_AREA_SIZE, code_area_size = DEFAULT_CODE_AREA_SIZE, max_threads = DEFAULT_MAX_THREADS, cache_mode = rpi_vcsm.CACHE_NONE ): self.mailbox = MailBox() self.mailbox.enable_qpu(1) self.vcsm = rpi_vcsm.VCSM.VCSM() if cache_mode in [rpi_vcsm.CACHE_HOST, rpi_vcsm.CACHE_BOTH]: self.is_cacheop_needed = True else: self.is_cacheop_needed = False self.max_threads = max_threads message_area_size = max_threads * 2 * 4 try: # Non-cached memory area for code and message. self.ctlmem = Mempool({'message': message_area_size, 'code': code_area_size}, vcsm = self.vcsm, cache_mode = rpi_vcsm.CACHE_NONE) # Memory area for uniforms and data with cache mode cache_mode. self.datmem = Mempool({'data': data_area_size}, vcsm = self.vcsm, cache_mode = cache_mode) self.message = self.ctlmem.alloc('message', shape = (self.max_threads, 2), dtype = np.uint32) except: self.close() raise
class Driver(object): def __init__(self, data_area_size=DEFAULT_DATA_AREA_SIZE, code_area_size=DEFAULT_CODE_AREA_SIZE, max_threads=DEFAULT_MAX_THREADS, cache_mode=rpi_vcsm.CACHE_NONE): self.mailbox = MailBox() self.mailbox.enable_qpu(1) self.vcsm = rpi_vcsm.VCSM.VCSM() if cache_mode in [rpi_vcsm.CACHE_HOST, rpi_vcsm.CACHE_BOTH]: self.is_cacheop_needed = True else: self.is_cacheop_needed = False self.max_threads = max_threads message_area_size = max_threads * 2 * 4 try: # Non-cached memory area for code and message. self.ctlmem = Mempool( { 'message': message_area_size, 'code': code_area_size }, vcsm=self.vcsm, cache_mode=rpi_vcsm.CACHE_NONE) # Memory area for uniforms and data with cache mode cache_mode. self.datmem = Mempool({'data': data_area_size}, vcsm=self.vcsm, cache_mode=cache_mode) self.message = self.ctlmem.alloc('message', shape=(self.max_threads, 2), dtype=np.uint32) except: self.close() raise def close(self): if self.ctlmem: self.ctlmem.close() self.ctlmem = None if self.datmem: self.datmem.close() self.datmem = None self.mailbox.enable_qpu(0) self.mailbox.close() self.mailbox = None def __enter__(self): return self def __exit__(self, exc_type, value, traceback): self.close() return exc_type is None def copy(self, arr): new_arr = self.alloc(shape=arr.shape, dtype=arr.dtype) new_arr[:] = arr return new_arr def alloc(self, *args, **kwargs): return self.datmem.alloc('data', *args, **kwargs) def array(self, *args, **kwargs): arr = np.array(*args, copy=False, **kwargs) new_arr = self.alloc(arr.shape, arr.dtype) new_arr[:] = arr return new_arr def program(self, program, *args, **kwargs): if hasattr(program, '__call__'): program = assemble(program, *args, **kwargs) code = memoryview(program).tobytes() arr = self.ctlmem.alloc('code', shape=int(ceil(len(code) / 8.0)), dtype=np.uint64) arr.buffer[arr.offset:arr.offset + len(code)] = code return Program(arr.address, arr.usraddr, code, len(code)) def execute(self, n_threads, program, uniforms=None, timeout=10000): if not (1 <= n_threads and n_threads <= self.max_threads): raise DriverError('n_threads exceeds max_threads') message = self.message if uniforms is not None: if not isinstance(uniforms, Array): uniforms = self.array(uniforms, dtype='u4') message[:n_threads, 0] = uniforms.addresses().reshape(n_threads, -1)[:, 0] else: message[:n_threads, 0] = 0 message[:n_threads, 1] = program.address if self.is_cacheop_needed: uniforms.clean() r = self.mailbox.execute_qpu(n_threads, message.address, 0, timeout) if self.is_cacheop_needed: uniforms.invalidate() if r > 0: raise DriverError('QPU execution timeout') def load_bin(self, file, *args, **kwargs): with open(file, 'rb') as f: code = f.read() arr = self.ctlmem.alloc('code', shape=int(ceil(len(code) / 8.0)), dtype=np.uint64) arr.buffer[arr.offset:arr.offset + len(code)] = code return Program(arr.address, arr.usraddr, code, len(code))
class Driver(object): def __init__(self, data_area_size = DEFAULT_DATA_AREA_SIZE, code_area_size = DEFAULT_CODE_AREA_SIZE, max_threads = DEFAULT_MAX_THREADS ): self.mailbox = MailBox() self.mailbox.enable_qpu(1) self.memory = None try: self.data_area_size = data_area_size self.code_area_size = code_area_size self.max_threads = max_threads self.code_area_base = 0 self.data_area_base = self.code_area_base + self.code_area_size self.msg_area_base = self.data_area_base + self.data_area_size self.code_pos = self.code_area_base self.data_pos = self.data_area_base total = data_area_size + code_area_size + max_threads * 64 self.memory = Memory(self.mailbox, total) self.message = Array( address = self.memory.baseaddr + self.msg_area_base, buffer = self.memory.base, offset = self.msg_area_base, shape = (self.max_threads, 2), dtype = np.uint32) except: if self.memory: self.memory.close() self.mailbox.enable_qpu(0) self.mailbox.close() raise def close(self): self.memory.close() self.mailbox.enable_qpu(0) self.mailbox.close() def __enter__(self): return self def __exit__(self, exc_type, value, traceback): self.close() return exc_type is None def copy(self, arr): new_arr = Array( shape = arr.shape, dtype = arr.dtype, address = self.memory.baseaddr + self.data_pos, buffer = self.memory.base, offset = self.data_pos ) if self.data_pos + new_arr.nbytes > self.msg_area_base: raise DriverError('Array too large') self.data_pos += new_arr.nbytes new_arr[:] = arr return new_arr def alloc(self, *args, **kwargs): arr = Array( *args, address = self.memory.baseaddr + self.data_pos, buffer = self.memory.base, offset = self.data_pos, **kwargs) if self.data_pos + arr.nbytes > self.msg_area_base: raise DriverError('Array too large') self.data_pos += arr.nbytes return arr def array(self, *args, **kwargs): arr = np.array(*args, copy = False, **kwargs) new_arr = self.alloc(arr.shape, arr.dtype) new_arr[:] = arr return new_arr def program(self, program, *args, **kwargs): if hasattr(program, '__call__'): program = assemble(program, *args, **kwargs) code = memoryview(program).tobytes() if self.code_pos + len(code) > self.data_area_base: raise DriverError('Program too long') code_addr = self.memory.baseaddr + self.code_pos self.memory.base[self.code_pos:self.code_pos+len(code)] = code self.code_pos += len(code) return Program(code_addr, code) def execute(self, n_threads, program, uniforms = None, timeout = 10000): if not (1 <= n_threads and n_threads <= self.max_threads): raise DriverError('n_threads exceeds max_threads') if uniforms is not None: if not isinstance(uniforms, Array): uniforms = self.array(uniforms, dtype = 'u4') self.message[:n_threads, 0] = uniforms.addresses().reshape(n_threads, -1)[:, 0] else: self.message[:n_threads, 0] = 0 self.message[:n_threads, 1] = program.address r = self.mailbox.execute_qpu(n_threads, self.message.address, 0, timeout) if r > 0: raise DriverError('QPU execution timeout')
from videocore.mailbox import MailBox with MailBox() as mb: print('firmware revision: %x' % mb.get_firmware_revision()) print('board model: %x' % mb.get_board_model()) print('board revision: %x' % mb.get_board_revision()) print('board serial: %016x' % mb.get_board_serial())