def decorator(func): fused_func = cupy.fuse(func) @functools.wraps(func) def wrapper(self, fusion_mode): if fusion_mode == 'enabled': fused_func(*args) elif fusion_mode == 'disabled': func(*args) elif fusion_mode == 'compile': fused_func.clear_cache() dtypes = [_.dtype for _ in args] fused_func._compile_from_dtypes(*dtypes) else: raise ValueError('Invalid parameter') uniform = cupy.random.uniform args = [] if shape_args: assert len(shapes_dict) == 0 for name in inspect.getargspec(func).args: args.append(uniform(0, 200, shape_args, cupy.float32)) else: for name in inspect.getargspec(func).args: shape = shapes_dict[name] args.append(uniform(0, 200, shape, cupy.float32)) # TODO (imanishi) # fused_func.compile(*args) fused_func(*args) return wrapper
def fuse(*args, **kwargs): """Function fusing decorator. It calls :func:`cupy.fuse` when CuPy is available to make fused function and does nothing otherwise. .. seealso:: :func:`cupy.fuse` """ if available: return cupy.fuse(*args, **kwargs) else: return lambda f: f
def _check(self, func, n, gen, args, error_types=None): assert n == len(args), (n, args) if error_types is None: error_types = () f = cupy.fuse(func) # Prepare input arrays if not isinstance(gen, tuple): gen = (gen,) * n data0 = tuple([g(*a) for g, a in zip(gen, args)]) data1 = tuple([_.copy() for _ in data0]) # Invoke non-fused function try: ret0 = func(*data0) # Non-fused err0 = None except Exception as e: if type(e) not in error_types: raise ret0 = None err0 = e # Invoke fused function try: ret1 = f(*data1) # Fused err1 = None except Exception as e: if type(e) not in error_types: raise ret1 = None err1 = e self.assertEqual(err0 is None, err1 is None) if err0 is not None: # Error self.assertEqual(type(err0), type(err1)) self.assertEqual(str(err0), str(err1)) arrs0 = None arrs1 = None else: # Success self.assertEqual(ret0 is None, ret1 is None) if ret0 is None: # Both return values are None ret0 = () ret1 = () else: # Return values must have the same type self.assertEqual(type(ret0), type(ret1)) if not isinstance(ret0, tuple): # Single arrays are returned ret0 = (ret0,) ret1 = (ret1,) else: # Tuples are returned self.assertEqual(len(ret0), len(ret1)) # Concatenate return values and input arrays arrs0 = ret0 + data0 arrs1 = ret1 + data1 # Test they have same values for nf, f in zip(arrs0, arrs1): numpy.testing.assert_array_almost_equal(nf.get(), f.get()) return err0 is not None, (arrs0, arrs1)
def res(xxx, name, xp, dtype): f = getattr(cupy, name) val = func(xxx, name, xp, dtype) return cupy.fuse(f)(*val)