def __init__(self, computation, name, type_): """__init__()""" # hide the signature from Sphinx Type.__init__( self, type_.dtype, shape=type_.shape, strides=type_.strides, offset=type_.offset) self._computation = weakref.ref(computation) self._name = name
def __init__(self, name, type_): """__init__()""" # hide the signature from Sphinx Type.__init__(self, type_.dtype, shape=type_.shape, strides=type_.strides) self.name = name
def __init__(self, trf, name, type_): Type.__init__(self, type_.dtype, shape=type_.shape, strides=type_.strides, offset=type_.offset) self._trf = weakref.ref(trf) self._name = name
def __init__(self, computation, name, type_): """__init__()""" # hide the signature from Sphinx Type.__init__(self, type_.dtype, shape=type_.shape, strides=type_.strides) self._computation = weakref.ref(computation) self._name = name
def test_type_mismatch(): """Check that the error is thrown if the connection is made to an wrong type.""" N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) identity = tr_identity(Type(numpy.complex64, (N, N + 1))) with pytest.raises(ValueError): d.connect('A', identity, identity.o1, A_prime=identity.i1)
def _process_kernel_arguments(self, args): """ Scan through kernel arguments passed by the user, check types, and wrap ad hoc values if necessary. Does not change the plan state. """ processed_args = [] adhoc_idgen = IdGen('_adhoc') adhoc_values = {} for arg in args: if not isinstance(arg, KernelArgument): if hasattr(arg, 'shape') and hasattr(arg, 'dtype'): if len(arg.shape) > 0: raise ValueError( "Arrays are not allowed as ad hoc arguments") # Not creating a new persistent scalar with _scalar(), # because the kernel compilation may fail, # in which case we would have to roll back the plan state. # These arguments are local to this kernel anyway, # so there's no need in registering them in the plan. name = self._translator(adhoc_idgen()) adhoc_values[name] = arg annotation = Annotation(Type(arg.dtype)) arg = KernelArgument(name, annotation.type) else: raise TypeError("Unknown argument type: " + str(type(arg))) else: annotation = self._get_annotation(arg.name) processed_args.append(Parameter(arg.name, annotation)) return processed_args, adhoc_values
def __init__(self, arr_t): assert len(arr_t.shape) == 2 # reset strides/offset of the input and return a contiguous array res_t = Type(arr_t.dtype, arr_t.shape) Computation.__init__(self, [ Parameter('output', Annotation(res_t, 'o')), Parameter('input', Annotation(arr_t, 'i')) ])
def test_nested_same_shape(thr): N = 2000 coeff = 2 second_coeff = 7 B_param = 3 D_param = 4 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = DummyNested(arr_type, arr_type, coeff_dtype, second_coeff, same_A_B=True) identity = tr_identity(d.parameter.A) join = tr_2_to_1(d.parameter.A, d.parameter.coeff) split = tr_1_to_2(d.parameter.A) scale = tr_scale(d.parameter.A, d.parameter.coeff.dtype) d.parameter.A.connect(identity, identity.o1, A_prime=identity.i1) d.parameter.B.connect(join, join.o1, A_prime=join.i1, B_prime=join.i2, B_param=join.s1) d.parameter.B_prime.connect(identity, identity.o1, B_new_prime=identity.i1) d.parameter.C.connect(split, split.i1, C_half1=split.o1, C_half2=split.o2) d.parameter.C_half1.connect(identity, identity.i1, C_new_half1=identity.o1) d.parameter.D.connect(scale, scale.i1, D_prime=scale.o1, D_param=scale.s1) dc = d.compile(thr) A_prime = get_test_array_like(d.parameter.A_prime) B_new_prime = get_test_array_like(d.parameter.B_new_prime) A_prime_dev = thr.to_device(A_prime) B_new_prime_dev = thr.to_device(B_new_prime) C_new_half1_dev = thr.empty_like(d.parameter.A_prime) C_half2_dev = thr.empty_like(d.parameter.A_prime) D_prime_dev = thr.empty_like(d.parameter.A_prime) dc(C_new_half1_dev, C_half2_dev, D_prime_dev, D_param, A_prime_dev, B_new_prime_dev, B_param, coeff) A = A_prime B = A_prime * B_param + B_new_prime C, D = mock_dummy_nested(A, B, coeff, second_coeff) C_new_half1 = C / 2 C_half2 = C / 2 D_prime = D * D_param assert diff_is_negligible(C_new_half1_dev.get(), C_new_half1) assert diff_is_negligible(C_half2_dev.get(), C_half2) assert diff_is_negligible(D_prime_dev.get(), D_prime)
def test_connector_repetition(): """Check that the connector id cannot be repeated in the connections list.""" N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) identity = tr_identity(d.parameter.A) with pytest.raises(ValueError): d.parameter.A.connect(identity, identity.o1, A=identity.o1, A_prime=identity.i1)
def temp_array(self, shape, dtype, strides=None): """ Adds a temporary GPU array to the plan, and returns the corresponding :py:class:`KernelArgument`. Temporary arrays can share physical memory, but in such a way that their contents is guaranteed to persist between the first and the last use in a kernel during the execution of the plan. """ name = self._translator(self._temp_array_idgen()) ann = Annotation(Type(dtype, shape=shape, strides=strides), 'io') self._internal_annotations[name] = ann self._temp_arrays.add(name) return KernelArgument(name, ann.type)
def test_wrong_data_path(): """ Check that the error is thrown if the connector is a part of the signature, but this particular data path (input or output) is already hidden by a previously connected transformation. """ N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = DummyAdvanced(arr_type, coeff_dtype) identity = tr_identity(d.parameter.C) d.parameter.C.connect(identity, identity.o1, C_in=identity.i1) d.parameter.D.connect(identity, identity.i1, D_out=identity.o1) assert list(d.signature.parameters.values()) == [ Parameter('C', Annotation(arr_type, 'o')), Parameter('C_in', Annotation(arr_type, 'i')), Parameter('D_out', Annotation(arr_type, 'o')), Parameter('D', Annotation(arr_type, 'i')), Parameter('coeff1', Annotation(coeff_dtype)), Parameter('coeff2', Annotation(coeff_dtype)) ] # Now input to C is hidden by the previously connected transformation with pytest.raises(ValueError): d.parameter.C.connect(identity, identity.o1, C_in_prime=identity.i1) # Same goes for D with pytest.raises(ValueError): d.parameter.D.connect(identity, identity.i1, D_out_prime=identity.o1) # Also we cannot make one of the transformation outputs an existing output parameter with pytest.raises(ValueError): d.parameter.C.connect(identity, identity.i1, D_out=identity.o1) # Output of C is still available though d.parameter.C.connect(identity, identity.i1, C_out=identity.o1) assert list(d.signature.parameters.values()) == [ Parameter('C_out', Annotation(arr_type, 'o')), Parameter('C_in', Annotation(arr_type, 'i')), Parameter('D_out', Annotation(arr_type, 'o')), Parameter('D', Annotation(arr_type, 'i')), Parameter('coeff1', Annotation(coeff_dtype)), Parameter('coeff2', Annotation(coeff_dtype)) ]
def test_io_merge(some_thr): """ Check that one can end input and output transformation in the same node thus making its role 'io'. """ N = 200 coeff1 = 3 coeff2 = 4 scale_in = 0.5 scale_out = 0.3 arr_type = Type(numpy.complex64, (N, N)) coeff_dtype = numpy.float32 C = get_test_array_like(arr_type) D = get_test_array_like(arr_type) C_dev = some_thr.to_device(C) D_dev = some_thr.to_device(D) d = DummyAdvanced(C, coeff_dtype) scale = tr_scale(d.parameter.C, d.parameter.coeff1.dtype) d.parameter.C.connect(scale, scale.o1, C_prime=scale.i1, scale_in=scale.s1) d.parameter.C.connect(scale, scale.i1, C_prime=scale.o1, scale_out=scale.s1) assert list(d.signature.parameters.values()) == [ Parameter('C_prime', Annotation(arr_type, 'io')), Parameter('scale_out', Annotation(coeff_dtype)), Parameter('scale_in', Annotation(coeff_dtype)), Parameter('D', Annotation(arr_type, 'io')), Parameter('coeff1', Annotation(coeff_dtype)), Parameter('coeff2', Annotation(coeff_dtype)) ] dc = d.compile(some_thr) dc(C_dev, scale_out, scale_in, D_dev, coeff1, coeff2) C_ref, D_ref = mock_dummy_advanced(C * scale_in, D, coeff1, coeff2) C_ref *= scale_out C = C_dev.get() D = D_dev.get() assert diff_is_negligible(C, C_ref) assert diff_is_negligible(D, D_ref)
def test_signature_correctness(): N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) # Root signature assert list(d.signature.parameters.values()) == [ Parameter('C', Annotation(arr_type, 'o')), Parameter('D', Annotation(arr_type, 'o')), Parameter('A', Annotation(arr_type, 'i')), Parameter('B', Annotation(arr_type, 'i')), Parameter('coeff', Annotation(coeff_dtype)) ] identity = tr_identity(d.parameter.A) join = tr_2_to_1(d.parameter.A, d.parameter.coeff) split = tr_1_to_2(d.parameter.A) scale = tr_scale(d.parameter.A, d.parameter.coeff.dtype) # Connect some transformations d.parameter.A.connect(identity, identity.o1, A_prime=identity.i1) d.parameter.B.connect(join, join.o1, A_prime=join.i1, B_prime=join.i2, B_param=join.s1) d.parameter.B_prime.connect(identity, identity.o1, B_new_prime=identity.i1) d.parameter.C.connect(split, split.i1, C_half1=split.o1, C_half2=split.o2) d.parameter.C_half1.connect(identity, identity.i1, C_new_half1=identity.o1) d.parameter.D.connect(scale, scale.i1, D_prime=scale.o1, D_param=scale.s1) assert list(d.signature.parameters.values()) == [ Parameter('C_new_half1', Annotation(arr_type, 'o')), Parameter('C_half2', Annotation(arr_type, 'o')), Parameter('D_prime', Annotation(arr_type, 'o')), Parameter('D_param', Annotation(coeff_dtype)), Parameter('A_prime', Annotation(arr_type, 'i')), Parameter('B_new_prime', Annotation(arr_type, 'i')), Parameter('B_param', Annotation(coeff_dtype)), Parameter('coeff', Annotation(coeff_dtype)) ]
def test_wrong_transformation_parameters(): """ Check that the error is thrown if the list of transformation parameter names does not coincide with actual names. """ N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) identity = tr_identity(d.parameter.A) # ``identity`` does not have ``input`` parameter with pytest.raises(ValueError): d.parameter.A.connect(identity, identity.o1, A_prime='input') # ``identity`` does not have ``i2`` parameter with pytest.raises(ValueError): d.parameter.A.connect(identity, identity.o1, A_prime=identity.i1, A2='i2')
def test_wrong_connector(): """Check that the error is thrown if the connector is unknown or is not in the signature.""" N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) identity = tr_identity(d.parameter.A) d.parameter.A.connect(identity, identity.o1, A_prime=identity.i1) # Connector is missing with pytest.raises(ValueError): d.connect('AA', identity, identity.o1, A_pp=identity.i1) # Node 'A' exists, but it is not a part of the signature # (hidden by previously connected transformation). with pytest.raises(ValueError): d.connect('B', identity, identity.o1, A=identity.i1)
def randint(self, array, minval, maxval, seed=None): kernel_cache, thread = self.kernel_cache, self.thread key = (self.randint, array.shape, array.dtype, minval, maxval, thread) if key not in kernel_cache.keys(): log.info("compiling " + str(key)) rng = CBRNG.uniform_integer( Type(array.dtype, shape=array.shape), len(array.shape), # @UndefinedVariable sampler_kwds=dict(low=numpy.int32(minval), high=numpy.int32(maxval)), seed=seed) counters = thread.to_device(rng.create_counters()) kernel_cache[key] = (rng.compile(thread), counters) (rng, counters) = kernel_cache[key] rng(counters, array)
def test_strings_as_parameters(): """ Check that one can connect transformations using strings as identifiers for computation and transformation parameters. """ N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) identity = tr_identity(d.parameter.A) d.connect('A', identity, 'o1', A_prime='i1') assert list(d.signature.parameters.values()) == [ Parameter('C', Annotation(arr_type, 'o')), Parameter('D', Annotation(arr_type, 'o')), Parameter('A_prime', Annotation(arr_type, 'i')), Parameter('B', Annotation(arr_type, 'i')), Parameter('coeff', Annotation(coeff_dtype))]
def test_connection_to_base(thr): N = 200 coeff = 2 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) identity = tr_identity(d.parameter.A) scale = tr_scale(d.parameter.A, d.parameter.coeff.dtype) # connect to the base array argument (effectively making B the same as A) d.parameter.A.connect(identity, identity.o1, B=identity.i1) # connect to the base scalar argument d.parameter.C.connect(scale, scale.i1, C_prime=scale.o1, coeff=scale.s1) assert list(d.signature.parameters.values()) == [ Parameter('C_prime', Annotation(arr_type, 'o')), Parameter('D', Annotation(arr_type, 'o')), Parameter('B', Annotation(arr_type, 'i')), Parameter('coeff', Annotation(coeff_dtype)) ] dc = d.compile(thr) B = get_test_array_like(d.parameter.B) B_dev = thr.to_device(B) C_prime_dev = thr.empty_like(d.parameter.B) D_dev = thr.empty_like(d.parameter.B) dc(C_prime_dev, D_dev, B_dev, coeff) C, D = mock_dummy(B, B, coeff) C_prime = C * coeff assert diff_is_negligible(C_prime_dev.get(), C_prime) assert diff_is_negligible(D_dev.get(), D)
def test_alien_parameters(): """ Check that one cannot connect transformations using parameter objects from other transformation/computation. """ N = 200 coeff_dtype = numpy.float32 arr_type = Type(numpy.complex64, (N, N)) d = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) d2 = Dummy(arr_type, arr_type, coeff_dtype, same_A_B=True) identity = tr_identity(d.parameter.A) identity2 = tr_identity(d.parameter.A) with pytest.raises(ValueError): d.connect(d2.parameter.A, identity, 'o1', A_prime='i1') with pytest.raises(ValueError): d.connect(d.parameter.A, identity, identity2.o1, A_prime='i1') with pytest.raises(ValueError): d.parameter.A.connect(identity, identity.o1, A_prime=identity2.i1)
def normal(self, array, mean, std, seed=None): kernel_cache, thread = self.kernel_cache, self.thread key = (self.normal, array.shape, array.dtype, mean, std, thread) if key not in kernel_cache.keys(): log.info("compiling " + str(key)) rng = CBRNG.normal_bm( Type(array.dtype, shape=array.shape), len(array.shape), # @UndefinedVariable sampler_kwds=dict(mean=numpy.float32(mean), std=numpy.float32(std)), seed=seed) counters = thread.to_device(rng.create_counters()) kernel_cache[key] = (rng.compile(thread), counters) (rng, counters) = kernel_cache[key] rng(counters, array) return array
def test_io_parameter_in_transformation(): with pytest.raises(ValueError): tr = Transformation( [Parameter('o1', Annotation(Type(numpy.float32, shape=100), 'io'))], "${o1.store_same}(${o1.load_same});")
def __init__(self, trf, name, type_): Type.__init__( self, type_.dtype, shape=type_.shape, strides=type_.strides, offset=type_.offset) self._trf = weakref.ref(trf) self._name = name