def _construct_args(self, kwargs) -> Tuple[Tuple[Any], Tuple[Any]]: """ Main function that controls argument construction for calling the C prototype of the SDFG. Organizes arguments first by `sdfg.arglist`, then data descriptors by alphabetical order, then symbols by alphabetical order. """ # Return value initialization (for values that have not been given) self._initialize_return_values(kwargs) if self._return_arrays is not None: if len(self._retarray_shapes) == 1: kwargs[self._retarray_shapes[0][0]] = self._return_arrays else: for desc, arr in zip(self._retarray_shapes, self._return_arrays): kwargs[desc[0]] = arr # Argument construction sig = self._sig typedict = self._typedict if len(kwargs) > 0: # Construct mapping from arguments to signature arglist = [] argtypes = [] argnames = [] for a in sig: try: arglist.append(kwargs[a]) argtypes.append(typedict[a]) argnames.append(a) except KeyError: raise KeyError("Missing program argument \"{}\"".format(a)) else: arglist = [] argtypes = [] argnames = [] sig = [] # Type checking for i, (a, arg, atype) in enumerate(zip(argnames, arglist, argtypes)): if not dtypes.is_array(arg) and isinstance(atype, dt.Array): if isinstance(arg, list): print('WARNING: Casting list argument "%s" to ndarray' % a) elif arg is None: # None values are passed as null pointers pass else: raise TypeError( 'Passing an object (type %s) to an array in argument "%s"' % (type(arg).__name__, a)) elif dtypes.is_array(arg) and not isinstance(atype, dt.Array): # GPU scalars are pointers, so this is fine if atype.storage != dtypes.StorageType.GPU_Global: raise TypeError( 'Passing an array to a scalar (type %s) in argument "%s"' % (atype.dtype.ctype, a)) elif not isinstance(atype, dt.Array) and not isinstance( atype.dtype, dtypes.callback) and not isinstance( arg, (atype.dtype.type, sp.Basic)) and not (isinstance(arg, symbolic.symbol) and arg.dtype == atype.dtype): if isinstance(arg, int) and atype.dtype.type == np.int64: pass elif isinstance(arg, float) and atype.dtype.type == np.float64: pass elif (isinstance(arg, int) and atype.dtype.type == np.int32 and abs(arg) <= (1 << 31) - 1): pass elif (isinstance(arg, int) and atype.dtype.type == np.uint32 and arg >= 0 and arg <= (1 << 32) - 1): pass else: warnings.warn( f'Casting scalar argument "{a}" from {type(arg).__name__} to {atype.dtype.type}' ) arglist[i] = atype.dtype.type(arg) elif (isinstance(atype, dt.Array) and isinstance(arg, np.ndarray) and atype.dtype.as_numpy_dtype() != arg.dtype): # Make exception for vector types if (isinstance(atype.dtype, dtypes.vector) and atype.dtype.vtype.as_numpy_dtype() == arg.dtype): pass else: print( 'WARNING: Passing %s array argument "%s" to a %s array' % (arg.dtype, a, atype.dtype.type.__name__)) elif (isinstance(atype, dt.Array) and isinstance(arg, np.ndarray) and arg.base is not None and not '__return' in a and not Config.get_bool('compiler', 'allow_view_arguments')): raise TypeError( f'Passing a numpy view (e.g., sub-array or "A.T") "{a}" to DaCe ' 'programs is not allowed in order to retain analyzability. ' 'Please make a copy with "numpy.copy(...)". If you know what ' 'you are doing, you can override this error in the ' 'configuration by setting compiler.allow_view_arguments ' 'to True.') # Explicit casting for index, (arg, argtype) in enumerate(zip(arglist, argtypes)): # Call a wrapper function to make NumPy arrays from pointers. if isinstance(argtype.dtype, dtypes.callback): arglist[index] = argtype.dtype.get_trampoline(arg, kwargs) # List to array elif isinstance(arg, list) and isinstance(argtype, dt.Array): arglist[index] = np.array(arg, dtype=argtype.dtype.type) # Null pointer elif arg is None and isinstance(argtype, dt.Array): arglist[index] = ctypes.c_void_p(0) # Retain only the element datatype for upcoming checks and casts arg_ctypes = [t.dtype.as_ctypes() for t in argtypes] sdfg = self._sdfg # Obtain SDFG constants constants = sdfg.constants # Remove symbolic constants from arguments callparams = tuple( (arg, actype, atype, aname) for arg, actype, atype, aname in zip( arglist, arg_ctypes, argtypes, argnames) if not symbolic.issymbolic(arg) or ( hasattr(arg, 'name') and arg.name not in constants)) # Replace symbols with their values callparams = tuple( (actype(arg.get()) if isinstance(arg, symbolic.symbol) else arg, actype, atype, aname) for arg, actype, atype, aname in callparams) # Construct init args, which only consist of the symbols symbols = self._free_symbols initargs = tuple( actype(arg) if (not isinstance(arg, ctypes._SimpleCData)) else arg for arg, actype, atype, aname in callparams if aname in symbols) # Replace arrays with their base host/device pointers newargs = tuple( (ctypes.c_void_p(_array_interface_ptr(arg, atype)), actype, atype) if dtypes.is_array(arg) else (arg, actype, atype) for arg, actype, atype, _ in callparams) try: newargs = tuple( actype(arg) if ( not isinstance(arg, ctypes._SimpleCData)) else arg for arg, actype, atype in newargs) except TypeError: # Pinpoint bad argument for i, (arg, actype, _) in enumerate(newargs): try: if not isinstance(arg, ctypes._SimpleCData): actype(arg) except TypeError as ex: raise TypeError( f'Invalid type for scalar argument "{callparams[i][3]}": {ex}' ) self._lastargs = newargs, initargs return self._lastargs
def _construct_args(self, kwargs) -> Tuple[Tuple[Any], Tuple[Any]]: """ Main function that controls argument construction for calling the C prototype of the SDFG. Organizes arguments first by `sdfg.arglist`, then data descriptors by alphabetical order, then symbols by alphabetical order. """ # Return value initialization (for values that have not been given) self._initialize_return_values(kwargs) if self._return_arrays is not None: if len(self._retarray_shapes) == 1: kwargs[self._retarray_shapes[0][0]] = self._return_arrays else: for desc, arr in zip(self._retarray_shapes, self._return_arrays): kwargs[desc[0]] = arr # Argument construction sig = self._sig typedict = self._typedict if len(kwargs) > 0: # Construct mapping from arguments to signature arglist = [] argtypes = [] argnames = [] for a in sig: try: arglist.append(kwargs[a]) argtypes.append(typedict[a]) argnames.append(a) except KeyError: raise KeyError("Missing program argument \"{}\"".format(a)) else: arglist = [] argtypes = [] argnames = [] sig = [] # Type checking for a, arg, atype in zip(argnames, arglist, argtypes): if not dtypes.is_array(arg) and isinstance(atype, dt.Array): if isinstance(arg, list): print('WARNING: Casting list argument "%s" to ndarray' % a) else: raise TypeError( 'Passing an object (type %s) to an array in argument "%s"' % (type(arg).__name__, a)) elif dtypes.is_array(arg) and not isinstance(atype, dt.Array): # GPU scalars are pointers, so this is fine if atype.storage != dtypes.StorageType.GPU_Global: raise TypeError( 'Passing an array to a scalar (type %s) in argument "%s"' % (atype.dtype.ctype, a)) elif not isinstance(atype, dt.Array) and not isinstance( atype.dtype, dtypes.callback) and not isinstance( arg, (atype.dtype.type, sp.Basic)) and not (isinstance(arg, symbolic.symbol) and arg.dtype == atype.dtype): if isinstance(arg, int) and atype.dtype.type == np.int64: pass elif isinstance(arg, float) and atype.dtype.type == np.float64: pass elif (isinstance(arg, int) and atype.dtype.type == np.int32 and abs(arg) <= (1 << 31) - 1): pass elif (isinstance(arg, int) and atype.dtype.type == np.uint32 and arg >= 0 and arg <= (1 << 32) - 1): pass else: print( 'WARNING: Casting scalar argument "%s" from %s to %s' % (a, type(arg).__name__, atype.dtype.type)) elif (isinstance(atype, dt.Array) and isinstance(arg, np.ndarray) and atype.dtype.as_numpy_dtype() != arg.dtype): # Make exception for vector types if (isinstance(atype.dtype, dtypes.vector) and atype.dtype.vtype.as_numpy_dtype() == arg.dtype): pass else: print( 'WARNING: Passing %s array argument "%s" to a %s array' % (arg.dtype, a, atype.dtype.type.__name__)) # Explicit casting for index, (arg, argtype) in enumerate(zip(arglist, argtypes)): # Call a wrapper function to make NumPy arrays from pointers. if isinstance(argtype.dtype, dtypes.callback): arglist[index] = argtype.dtype.get_trampoline(arg, kwargs) # List to array elif isinstance(arg, list) and isinstance(argtype, dt.Array): arglist[index] = np.array(arg, dtype=argtype.dtype.type) # Retain only the element datatype for upcoming checks and casts arg_ctypes = [t.dtype.as_ctypes() for t in argtypes] sdfg = self._sdfg # Obtain SDFG constants constants = sdfg.constants # Remove symbolic constants from arguments callparams = tuple( (arg, actype, atype) for arg, actype, atype in zip(arglist, arg_ctypes, argtypes) if not symbolic.issymbolic(arg) or ( hasattr(arg, 'name') and arg.name not in constants)) # Replace symbols with their values callparams = tuple( (actype(arg.get()), actype, atype) if isinstance(arg, symbolic.symbol) else (arg, actype, atype) for arg, actype, atype in callparams) # Replace arrays with their base host/device pointers newargs = tuple( (ctypes.c_void_p(_array_interface_ptr(arg, atype)), actype, atype) if dtypes.is_array(arg) else (arg, actype, atype) for arg, actype, atype in callparams) initargs = tuple(atup for atup in callparams if not dtypes.is_array(atup[0])) newargs = tuple( actype(arg) if (not isinstance(arg, ctypes._SimpleCData)) else arg for arg, actype, atype in newargs) initargs = tuple( actype(arg) if (not isinstance(arg, ctypes._SimpleCData)) else arg for arg, actype, atype in initargs) self._lastargs = newargs, initargs return self._lastargs
def _construct_args(self, **kwargs): """ Main function that controls argument construction for calling the C prototype of the SDFG. Organizes arguments first by `sdfg.arglist`, then data descriptors by alphabetical order, then symbols by alphabetical order. """ # Return value initialization (for values that have not been given) kwargs.update({ k: v for k, v in self._initialize_return_values(kwargs).items() if k not in kwargs }) # Argument construction sig = self._sdfg.signature_arglist(with_types=False) typedict = self._sdfg.arglist() if len(kwargs) > 0: # Construct mapping from arguments to signature arglist = [] argtypes = [] argnames = [] for a in sig: try: arglist.append(kwargs[a]) argtypes.append(typedict[a]) argnames.append(a) except KeyError: raise KeyError("Missing program argument \"{}\"".format(a)) else: arglist = [] argtypes = [] argnames = [] sig = [] # Type checking for a, arg, atype in zip(argnames, arglist, argtypes): if not dtypes.is_array(arg) and isinstance(atype, dt.Array): raise TypeError( 'Passing an object (type %s) to an array in argument "%s"' % (type(arg).__name__, a)) elif dtypes.is_array(arg) and not isinstance(atype, dt.Array): raise TypeError( 'Passing an array to a scalar (type %s) in argument "%s"' % (atype.dtype.ctype, a)) elif not isinstance(atype, dt.Array) and not isinstance( atype.dtype, dace.callback) and not isinstance( arg, (atype.dtype.type, sp.Basic)) and not (isinstance(arg, symbolic.symbol) and arg.dtype == atype.dtype): if isinstance(arg, int) and atype.dtype.type == np.int64: pass elif isinstance(arg, float) and atype.dtype.type == np.float64: pass else: print( 'WARNING: Casting scalar argument "%s" from %s to %s' % (a, type(arg).__name__, atype.dtype.type)) elif (isinstance(atype, dt.Array) and isinstance(arg, np.ndarray) and atype.dtype.as_numpy_dtype() != arg.dtype): # Make exception for vector types if (isinstance(atype.dtype, dtypes.vector) and atype.dtype.vtype.as_numpy_dtype() != arg.dtype): print( 'WARNING: Passing %s array argument "%s" to a %s array' % (arg.dtype, a, atype.dtype.type.__name__)) # Call a wrapper function to make NumPy arrays from pointers. for index, (arg, argtype) in enumerate(zip(arglist, argtypes)): if isinstance(argtype.dtype, dace.callback): arglist[index] = argtype.dtype.get_trampoline(arg, kwargs) # Retain only the element datatype for upcoming checks and casts arg_ctypes = [t.dtype.as_ctypes() for t in argtypes] sdfg = self._sdfg # Obtain SDFG constants constants = sdfg.constants # Remove symbolic constants from arguments callparams = tuple( (arg, actype, atype) for arg, actype, atype in zip(arglist, arg_ctypes, argtypes) if not symbolic.issymbolic(arg) or ( hasattr(arg, 'name') and arg.name not in constants)) # Replace symbols with their values callparams = tuple( (actype(arg.get()), actype, atype) if isinstance(arg, symbolic.symbol) else (arg, actype, atype) for arg, actype, atype in callparams) # Replace arrays with their base host/device pointers newargs = tuple( (ctypes.c_void_p(_array_interface_ptr(arg, atype)), actype, atype) if dtypes.is_array(arg) else (arg, actype, atype) for arg, actype, atype in callparams) newargs = tuple( actype(arg) if (not isinstance(arg, ctypes._SimpleCData)) else arg for arg, actype, atype in newargs) self._lastargs = newargs return self._lastargs