def test_consuming_strides(self): hostarray = np.arange(10).reshape(2, 5) face = cuda.to_device(hostarray).__cuda_array_interface__ self.assertIsNone(face['strides']) got = cuda.from_cuda_array_interface(face).copy_to_host() np.testing.assert_array_equal(got, hostarray) self.assertTrue(got.flags['C_CONTIGUOUS']) # Try non-NULL strides face['strides'] = hostarray.strides self.assertIsNotNone(face['strides']) got = cuda.from_cuda_array_interface(face).copy_to_host() np.testing.assert_array_equal(got, hostarray) self.assertTrue(got.flags['C_CONTIGUOUS'])
def test_masked_array(self): h_arr = np.random.random(10) h_mask = np.random.randint(2, size=10, dtype='bool') c_arr = cuda.to_device(h_arr) c_mask = cuda.to_device(h_mask) # Manually create a masked CUDA Array Interface dictionary masked_cuda_array_interface = c_arr.__cuda_array_interface__.copy() masked_cuda_array_interface['mask'] = c_mask with self.assertRaises(NotImplementedError) as raises: cuda.from_cuda_array_interface(masked_cuda_array_interface) expected_msg = 'Masked arrays are not supported' self.assertIn(expected_msg, str(raises.exception))
def get_data(self, memtype=MEM_HOST): """Get read/write access to a QFunction Context via the specified memory type. Args: **memtype: memory type of the array being passed, default CEED_MEM_HOST Returns: *data: Numpy or Numba array""" # Retrieve the length of the array size_pointer = ffi.new("size_t *") err_code = lib.CeedQFunctionContextGetContextSize( self._pointer[0], size_pointer) self._ceed._check_error(err_code) # Setup the pointer's pointer data_pointer = ffi.new("CeedScalar **") # libCEED call err_code = lib.CeedQFunctionContextGetData(self._pointer[0], memtype, data_pointer) self._ceed._check_error(err_code) # Return array created from buffer if memtype == MEM_HOST: # Create buffer object from returned pointer buff = ffi.buffer(data_pointer[0], size_pointer[0]) # return Numpy array return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) else: # CUDA array interface # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html import numba.cuda as nbcuda if lib.CEED_SCALAR_TYPE == lib.CEED_SCALAR_FP32: scalar_type_str = '>f4' else: scalar_type_str = '>f8' desc = { 'shape': (size_pointer[0] / ffi.sizeof("CeedScalar")), 'typestr': scalar_type_str, 'data': (int(ffi.cast("intptr_t", data_pointer[0])), False), 'version': 2 } # return Numba array return nbcuda.from_cuda_array_interface(desc)
def get_array_read(self, memtype=MEM_HOST): """Get read-only access to a Vector via the specified memory type. Args: **memtype: memory type of the array being passed, default CEED_MEM_HOST Returns: *array: Numpy or Numba array""" # Retrieve the length of the array length_pointer = ffi.new("CeedInt *") err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) self._ceed._check_error(err_code) # Setup the pointer's pointer array_pointer = ffi.new("CeedScalar **") # libCEED call err_code = lib.CeedVectorGetArrayRead(self._pointer[0], memtype, array_pointer) self._ceed._check_error(err_code) # Return array created from buffer if memtype == MEM_HOST: # Create buffer object from returned pointer buff = ffi.buffer(array_pointer[0], ffi.sizeof("CeedScalar") * length_pointer[0]) # return read only Numpy array ret = np.frombuffer(buff, dtype="float64") ret.flags['WRITEABLE'] = False return ret else: # CUDA array interface # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html import numba.cuda as nbcuda desc = { 'shape': (length_pointer[0]), 'typestr': '>f8', 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False), 'version': 2 } # return read only Numba array return nbcuda.from_cuda_array_interface(desc)
def get_array_write(self, memtype=MEM_HOST): """Get write-only access to a Vector via the specified memory type. All old values should be considered invalid. Args: **memtype: memory type of the array being passed, default CEED_MEM_HOST Returns: *array: Numpy or Numba array""" # Retrieve the length of the array length_pointer = ffi.new("CeedSize *") err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) self._ceed._check_error(err_code) # Setup the pointer's pointer array_pointer = ffi.new("CeedScalar **") # libCEED call err_code = lib.CeedVectorGetArrayWrite(self._pointer[0], memtype, array_pointer) self._ceed._check_error(err_code) # Return array created from buffer if memtype == MEM_HOST: # Create buffer object from returned pointer buff = ffi.buffer(array_pointer[0], ffi.sizeof("CeedScalar") * length_pointer[0]) # return Numpy array return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) else: # CUDA array interface # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html import numba.cuda as nbcuda desc = { 'shape': (length_pointer[0]), 'typestr': '>f8', 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False), 'version': 2 } # return Numba array return nbcuda.from_cuda_array_interface(desc)