def test_parsing_context(): def func(a): if dace.in_program(): a[:] = 1 else: a[:] = 2 first = np.random.rand(10) second = np.random.rand(10) func(first) dace.program(func)(second) assert np.allclose(first, 2) assert np.allclose(second, 1)
def mutator(func): dp = dace.program(func) @dace.program def mmm(A: dace.float64[20]): res = dp(A, a) return res sdfg = mmm.to_sdfg() return sdfg
def test_nested_convertible_parse_fail(raise_error, nested_decorator): raised_exception = None class AConvertible(SDFGConvertible): def __call__(self, arr): nonlocal raised_exception raised_exception = FileNotFoundError('Expected') raise raised_exception def __sdfg__(self, arr): raise RuntimeError('Expected') def __sdfg_signature__(self): return (['arr'], []) def __sdfg_closure__(self, reevaluate=None): return {} convertible = AConvertible() def program2(arr): convertible(arr) if nested_decorator: program2 = dace.program(program2) @dace.program def program(arr: dace.float64[10]): program2(arr) A = np.ones((10, )) if raise_error: with dace.config.set_temporary('frontend', 'raise_nested_parsing_errors', value=True): with pytest.raises(RuntimeError): program(A) else: if nested_decorator: with pytest.raises(RuntimeError): program(A) else: with pytest.raises(FileNotFoundError): program(A) if raised_exception is not None: raise raised_exception
def test(): dp = dace.program(func) def get_rand_arr(ddesc): if type(ddesc) is dace.dtypes.typeclass: # we have a scalar ddesc = dace.data.Scalar(ddesc) if ddesc.dtype in [dace.float16, dace.float32, dace.float64]: res = np.random.rand(*ddesc.shape).astype( getattr(np, ddesc.dtype.to_string())) b = 0 if positive else -10 a = 10 res = (b - a) * res + a if non_zero: res[res == 0] = 1 elif ddesc.dtype in [ dace.int8, dace.int16, dace.int32, dace.int64, dace.bool ]: res = np.random.randint(0 if positive else -3, 3, size=ddesc.shape) res = res.astype(getattr(np, ddesc.dtype.to_string())) if non_zero: res[res == 0] = 1 else: raise ValueError("unsupported dtype {}".format( ddesc.dtype)) if type(ddesc) is dace.data.Scalar: return res[0] else: return res signature = inspect.signature(func) inputs = OrderedDict( (name, get_rand_arr(param.annotation)) for name, param in signature.parameters.items()) dace_input = dc(inputs) reference_input = dc(inputs) # save exceptions dace_thrown, numpy_thrown = None, None try: reference_result = func(**reference_input) except Exception as e: numpy_thrown = e try: dace_result = dp(**dace_input) except Exception as e: dace_thrown = e if dace_thrown is not None or numpy_thrown is not None: assert dace_thrown is not None and numpy_thrown is not None, "dace threw:\n{}: {}\nBut numpy threw:\n{}: {}\n".format( type(dace_thrown), dace_thrown, type(numpy_thrown), numpy_thrown) else: assert np.allclose(reference_result, dace_result)
def test(): dp = dace.program(func) def get_rand_arr(ddesc): if type(ddesc) is dace.dtypes.typeclass: # we have a scalar ddesc = dace.data.Scalar(ddesc) if ddesc.dtype in [dace.float16, dace.float32, dace.float64]: res = rng.random(ddesc.shape, dtype=getattr(np, ddesc.dtype.to_string())) b = 0 if positive else -max_value a = max_value res = (b - a) * res + a if non_zero: res[res == 0] = 1 elif ddesc.dtype in [dace.complex64, dace.complex128]: res = (rng.random(ddesc.shape).astype( getattr(np, ddesc.dtype.to_string())) + 1j * rng.random(ddesc.shape).astype( getattr(np, ddesc.dtype.to_string()))) b = 0 if positive else -max_value a = max_value res = (b - a) * res + a if non_zero: res[res == 0] = 1 elif ddesc.dtype in [ dace.int8, dace.int16, dace.int32, dace.int64, dace.bool ]: res = rng.integers(0 if positive else -max_value, max_value, size=ddesc.shape) res = res.astype(getattr(np, ddesc.dtype.to_string())) if non_zero: res[res == 0] = 1 elif ddesc.dtype in [ dace.uint8, dace.uint16, dace.uint32, dace.uint64 ]: res = rng.integers(0, max_value, size=ddesc.shape) res = res.astype(getattr(np, ddesc.dtype.to_string())) if non_zero: res[res == 0] = 1 elif ddesc.dtype in [dace.complex64, dace.complex128]: res = (rng.random(ddesc.shape).astype( getattr(np, ddesc.dtype.to_string())) + 1j * rng.random(ddesc.shape).astype( getattr(np, ddesc.dtype.to_string()))) b = 0 if positive else -10 - 10j a = 10 + 10j res = (b - a) * res + a if non_zero: res[res == 0] = 1 + 1j else: raise ValueError("unsupported dtype {}".format( ddesc.dtype)) if type(ddesc) is dace.data.Scalar: return res[0] else: return res signature = inspect.signature(func) inputs = OrderedDict( (name, get_rand_arr(param.annotation)) for name, param in signature.parameters.items()) dace_input = dc(inputs) if casting: reference_input = OrderedDict( (name, casting(desc)) for name, desc in inputs.items()) else: reference_input = dc(inputs) # save exceptions dace_thrown, numpy_thrown = None, None try: if validation_func: # Works only with 1D inputs of the same size! reference_result = [] reference_input = [arr.tolist() for arr in inputs.values()] for inp_args in zip(*reference_input): reference_result.append(validation_func(*inp_args)) else: reference_result = func(**reference_input) except Exception as e: numpy_thrown = e try: dace_result = dp(**dace_input) except Exception as e: dace_thrown = e if dace_thrown is not None or numpy_thrown is not None: assert dace_thrown is not None and numpy_thrown is not None, "dace threw:\n{}: {}\nBut numpy threw:\n{}: {}\n".format( type(dace_thrown), dace_thrown, type(numpy_thrown), numpy_thrown) else: if not isinstance(reference_result, (tuple, list)): reference_result = [reference_result] dace_result = [dace_result] for ref, val in zip(reference_result, dace_result): if ref.dtype == np.float32: assert np.allclose(ref, val, equal_nan=True, rtol=1e-3, atol=1e-5) else: assert np.allclose(ref, val, equal_nan=True) if check_dtype and not validation_func: assert (ref.dtype == val.dtype)
# Define transient (temporary) array tmp = np.zeros_like(A) # This loop will remain a loop for _ in range(T): # This loop will become a parallel map for i in dace.map[1:N - 1]: tmp[i] = A[i - 1] - 2 * A[i] + A[i + 1] # Alternatively, a "NumPy way" to write the kernel also works # tmp[i] = np.sum(A[i - 1:i + 2] * np.array([1, -2, 1])) for i in dace.map[1:N - 1]: A[i] = tmp[i - 1] - 2 * tmp[i] + tmp[i + 1] if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("N", type=int, nargs="?", default=1024) parser.add_argument("iterations", type=int, nargs="?", default=100) args = parser.parse_args() # Create a data-centric version of the program dace_laplace = dace.program(laplace) # Set initial values A = np.random.rand(args.N) # Time the result by enabling profiling with dace.config.set_temporary('profiling', value=True): dace_laplace(A, args.iterations)