Exemple #1
0
def impl_extend(l, iterable):
    if not isinstance(l, types.ListType):
        return
    if not isinstance(iterable, types.IterableType):
        raise TypingError("extend argument must be iterable")

    _check_for_none_typed(l, 'insert')

    def select_impl():
        if isinstance(iterable, types.ListType):

            def impl(l, iterable):
                # guard against l.extend(l)
                if l is iterable:
                    iterable = iterable.copy()
                for i in iterable:
                    l.append(i)

            return impl
        else:

            def impl(l, iterable):
                for i in iterable:
                    l.append(i)

            return impl

    if l.is_precise():
        # Handle the precise case.
        return select_impl()
    else:
        # Handle the imprecise case, try to 'guess' the underlying type of the
        # values in the iterable.
        if hasattr(iterable, "dtype"):  # tuples and arrays
            ty = iterable.dtype
        elif hasattr(iterable, "item_type"):  # lists
            ty = iterable.item_type
        elif hasattr(iterable, "yield_type"):  # iterators and generators
            ty = iterable.yield_type
        else:
            raise TypingError("unable to extend list, iterable is missing "
                              "either *dtype*, *item_type* or *yield_type*.")
        l = l.refine(ty)
        # Create the signature that we wanted this impl to have
        sig = typing.signature(types.void, l, iterable)
        return sig, select_impl()
Exemple #2
0
def declare_device_function(name, restype, argtypes):
    from .descriptor import CUDATargetDesc

    typingctx = CUDATargetDesc.typingctx
    targetctx = CUDATargetDesc.targetctx
    sig = typing.signature(restype, *argtypes)
    extfn = ExternFunction(name, sig)

    class device_function_template(ConcreteTemplate):
        key = extfn
        cases = [sig]

    fndesc = funcdesc.ExternalFunctionDescriptor(
        name=name, restype=restype, argtypes=argtypes)
    typingctx.insert_user_function(extfn, device_function_template)
    targetctx.insert_user_function(extfn, fndesc)
    return extfn
Exemple #3
0
    def _context_builder_sig_args(self):
        typing_context = typing.Context()
        context = cpu.CPUContext(typing_context)
        lib = context.codegen().create_library('testing')
        with context.push_code_library(lib):
            module = lc.Module("test_module")

            sig = typing.signature(types.int32, types.int32)
            llvm_fnty = context.call_conv.get_function_type(sig.return_type,
                                                            sig.args)
            function = module.get_or_insert_function(llvm_fnty, name='test_fn')
            args = context.call_conv.get_arguments(function)
            assert function.is_declaration
            entry_block = function.append_basic_block('entry')
            builder = lc.Builder(entry_block)

            yield context, builder, sig, args
Exemple #4
0
    def _do_work_getattr(self, state, work_list, block, i, expr):
        recv_type = state.type_annotation.typemap[expr.value.name]
        recv_type = types.unliteral(recv_type)
        matched = state.typingctx.find_matching_getattr_template(
            recv_type,
            expr.attr,
        )
        if not matched:
            return False
        template = matched['template']
        if getattr(template, 'is_method', False):
            # The attribute template is representing a method.
            # Don't inline the getattr.
            return False

        inline_type = getattr(template, '_inline', None)
        if inline_type is None:
            # inline not defined
            return False
        sig = typing.signature(matched['return_type'], recv_type)
        arg_typs = sig.args

        if not inline_type.is_never_inline:
            try:
                impl = template._overload_func(recv_type)
                if impl is None:
                    raise Exception  # abort for this template
            except Exception:
                return False
        else:
            return False

        is_method = False
        return self._run_inliner(
            state,
            inline_type,
            sig,
            template,
            arg_typs,
            expr,
            i,
            impl,
            block,
            work_list,
            is_method,
        )
Exemple #5
0
def impl_insert(l, index, item):
    if not isinstance(l, types.ListType):
        return

    _check_for_none_typed(l, 'insert')
    # insert can refine
    if isinstance(item, NoneType):
        raise TypingError("method support for List[None] is limited")

    if index in index_types:

        def impl(l, index, item):
            # If the index is larger than the size of the list or if the list is
            # empty, just append.
            if index >= len(l) or len(l) == 0:
                l.append(item)
            # Else, do the insert dance
            else:
                # convert negative indices
                if index < 0:
                    # if the index is still negative after conversion, use 0
                    index = max(len(l) + index, 0)
                # grow the list by one, make room for item to insert
                l.append(l[0])
                # reverse iterate over the list and shift all elements
                i = len(l) - 1
                while (i > index):
                    l[i] = l[i - 1]
                    i -= 1
                # finally, insert the item
                l[index] = item

        if l.is_precise():
            # Handle the precise case.
            return impl
        else:
            # Handle the imprecise case
            l = l.refine(item)
            # Re-bind the item type to match the arguments.
            itemty = l.item_type
            # Create the signature that we wanted this impl to have.
            sig = typing.signature(types.void, l, INDEXTY, itemty)
            return sig, impl
    else:
        raise TypingError("list insert indices must be integers")
    def __init__(self, pyfunc, sig, locals, options, pipeline_class=compiler.Compiler):
        args, return_type = sig
        if return_type is None:
            raise TypeError("C callback needs an explicit return type")
        self.__name__ = pyfunc.__name__
        self.__qualname__ = getattr(pyfunc, "__qualname__", self.__name__)
        self.__wrapped__ = pyfunc

        self._pyfunc = pyfunc
        self._sig = signature(return_type, *args)
        self._compiler = _CFuncCompiler(
            pyfunc, self._targetdescr, options, locals, pipeline_class=pipeline_class
        )

        self._wrapper_name = None
        self._wrapper_address = None
        self._cache = NullCache()
        self._cache_hits = 0
def triangular_impl_2(context, builder, sig, args):
    fltty = sig.return_type
    low, high = args
    state_ptr = get_state_ptr(context, builder, "py")
    randval = get_next_double(context, builder, state_ptr)

    def triangular_impl_2(randval, low, high):
        u = randval
        c = 0.5
        if u > c:
            u = 1.0 - u
            low, high = high, low
        return low + (high - low) * math.sqrt(u * c)

    res = context.compile_internal(builder, triangular_impl_2,
                                   signature(*(fltty, ) * 4),
                                   (randval, low, high))
    return impl_ret_untracked(context, builder, sig.return_type, res)
    def _context_builder_sig_args(self):
        typing_context = cpu_target.typing_context
        context = cpu_target.target_context
        lib = context.codegen().create_library('testing')
        with context.push_code_library(lib):
            module = ir.Module("test_module")

            sig = typing.signature(types.int32, types.int32)
            llvm_fnty = context.call_conv.get_function_type(
                sig.return_type, sig.args)
            function = cgutils.get_or_insert_function(module, llvm_fnty,
                                                      'test_fn')
            args = context.call_conv.get_arguments(function)
            assert function.is_declaration
            entry_block = function.append_basic_block('entry')
            builder = ir.IRBuilder(entry_block)

            yield context, builder, sig, args
Exemple #9
0
    def run_pass(self, state):
        """
        Back-end: Packages lowering output in a compile result
        """
        lowered = state['cr']
        signature = typing.signature(state.return_type, *state.args)

        state.cr = cuda_compile_result(
            typing_context=state.typingctx,
            target_context=state.targetctx,
            typing_error=state.status.fail_reason,
            type_annotation=state.type_annotation,
            library=state.library,
            call_helper=lowered.call_helper,
            signature=signature,
            fndesc=lowered.fndesc,
        )
        return True
Exemple #10
0
def print_varargs_impl(context, builder, sig, args):
    """
    A entire print() call.
    """
    pyapi = context.get_python_api(builder)
    gil = pyapi.gil_ensure()

    for i, (argtype, argval) in enumerate(zip(sig.args, args)):
        signature = typing.signature(types.none, argtype)
        imp = context.get_function("print_item", signature)
        imp(builder, [argval])
        if i < len(args) - 1:
            pyapi.print_string(' ')
    pyapi.print_string('\n')

    pyapi.gil_release(gil)
    res = context.get_dummy_value()
    return impl_ret_untracked(context, builder, sig.return_type, res)
Exemple #11
0
 def generic(self, args, kws):
     assert not kws
     assert len(args) == 1
     column = types.unliteral(args[0])
     ret_typ = column
     if (isinstance(column, types.List)
             and (isinstance(column.dtype, types.Number)
                  or column.dtype == types.boolean)):
         ret_typ = types.Array(column.dtype, 1, 'C')
     if (isinstance(column, types.List)
             and (column.dtype == string_type
                  or isinstance(column.dtype, types.Optional)
                  and column.dtype.type == string_type)):
         ret_typ = string_array_type
     if isinstance(column, SeriesType):
         ret_typ = column.data
     # TODO: add other types
     return signature(ret_typ, column)
        def intrin_alloc(typingctx, allocsize, align):
            """Intrinsic to call into the allocator for Array
            """
            def codegen(context, builder, signature, args):
                [allocsize, align] = args

                # XXX: error are being eaten.
                #      example: replace the next line with `align_u32 = align`
                align_u32 = cast_integer(context, builder, align,
                                         signature.args[1], types.uint32)
                meminfo = context.nrt.meminfo_alloc_aligned(
                    builder, allocsize, align_u32)
                return meminfo

            from numba.core.typing import signature
            mip = types.MemInfoPointer(types.voidptr)  # return untyped pointer
            sig = signature(mip, allocsize, align)
            return sig, codegen
Exemple #13
0
    def test_cache(self):
        def times2(i):
            return 2 * i

        def times3(i):
            return i * 3

        with self._context_builder_sig_args() as (
                context,
                builder,
                sig,
                args,
        ):
            # Ensure the cache is empty to begin with
            self.assertEqual(0, len(context.cached_internal_func))

            # After one compile, it should contain one entry
            context.compile_internal(builder, times2, sig, args)
            self.assertEqual(1, len(context.cached_internal_func))

            # After a second compilation of the same thing, it should still contain
            # one entry
            context.compile_internal(builder, times2, sig, args)
            self.assertEqual(1, len(context.cached_internal_func))

            # After compilation of another function, the cache should have grown by
            # one more.
            context.compile_internal(builder, times3, sig, args)
            self.assertEqual(2, len(context.cached_internal_func))

            sig2 = typing.signature(types.float64, types.float64)
            llvm_fnty2 = context.call_conv.get_function_type(
                sig2.return_type, sig2.args)
            function2 = cgutils.get_or_insert_function(builder.module,
                                                       llvm_fnty2, 'test_fn_2')
            args2 = context.call_conv.get_arguments(function2)
            assert function2.is_declaration
            entry_block2 = function2.append_basic_block('entry')
            builder2 = ir.IRBuilder(entry_block2)

            # Ensure that the same function with a different signature does not
            # reuse an entry from the cache in error
            context.compile_internal(builder2, times3, sig2, args2)
            self.assertEqual(3, len(context.cached_internal_func))
def _triangular_impl_3(context, builder, sig, low, high, mode, state):
    fltty = sig.return_type
    state_ptr = get_state_ptr(context, builder, state)
    randval = get_next_double(context, builder, state_ptr)

    def triangular_impl_3(randval, low, high, mode):
        if high == low:
            return low
        u = randval
        c = (mode - low) / (high - low)
        if u > c:
            u = 1.0 - u
            c = 1.0 - c
            low, high = high, low
        return low + (high - low) * math.sqrt(u * c)

    return context.compile_internal(builder, triangular_impl_3,
                                    signature(*(fltty, ) * 5),
                                    (randval, low, high, mode))
def dpnp_sum_impl(a):
    name = "sum"
    dpnp_lowering.ensure_dpnp(name)

    ret_type = types.void
    """
    dpnp source:
    https://github.com/IntelPython/dpnp/blob/0.6.1dev/dpnp/backend/kernels/dpnp_krnl_reduction.cpp#L59

    Function declaration:
    void dpnp_sum_c(void* result_out,
                    const void* input_in,
                    const size_t* input_shape,
                    const size_t input_shape_ndim,
                    const long* axes,
                    const size_t axes_ndim,
                    const void* initial,
                    const long* where)

    """
    sig = signature(
        ret_type,
        types.voidptr,  # void* result_out,
        types.voidptr,  # const void* input_in,
        types.voidptr,  # const size_t* input_shape,
        types.intp,  # const size_t input_shape_ndim,
        types.voidptr,  # const long* axes,
        types.intp,  # const size_t axes_ndim,
        types.voidptr,  # const void* initial,
        types.voidptr,  # const long* where)
    )
    dpnp_func = dpnp_ext.dpnp_func("dpnp_" + name, [a.dtype.name, "NONE"], sig)

    PRINT_DEBUG = dpnp_lowering.DEBUG

    def dpnp_impl(a):
        out = np.empty(1, dtype=a.dtype)
        common_impl(a, out, dpnp_func, PRINT_DEBUG)

        return out[0]

    return dpnp_impl
def dpnp_random_impl(mean=0.0, sigma=1.0, size=None):
    name = "lognormal"
    dpnp_lowering.ensure_dpnp(name)

    ret_type = types.void
    """
    dpnp source:
    https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_random.cpp#L199

    Function declaration:
    void custom_rng_lognormal_c(void* result, _DataType mean, _DataType stddev, size_t size)
    """
    sig = signature(ret_type, types.voidptr, types.float64, types.float64,
                    types.intp)
    dpnp_func = dpnp_ext.dpnp_func("dpnp_" + name, ["float64", "NONE"], sig)
    res_dtype = np.float64
    PRINT_DEBUG = dpnp_lowering.DEBUG

    if not isinstance(mean, float):
        if not (isinstance(mean, types.Float)):
            raise ValueError("We only support scalar for input: loc")

    if not isinstance(sigma, float):
        if not (isinstance(sigma, types.Float)):
            raise ValueError("We only support scalar for input: scale")

    if size in (None, types.none):

        def dpnp_impl(mean=0.0, sigma=1.0, size=None):
            res = np.empty(1, dtype=res_dtype)
            common_impl_2_arg(mean, sigma, res, dpnp_func, PRINT_DEBUG)
            return res[0]

    else:

        def dpnp_impl(mean=0.0, sigma=1.0, size=None):
            res = np.empty(size, dtype=res_dtype)
            if res.size != 0:
                common_impl_2_arg(mean, sigma, res, dpnp_func, PRINT_DEBUG)
            return res

    return dpnp_impl
Exemple #17
0
 def run_pass(self, state):
     """
     Just create a compile result for interpreter mode
     """
     args = [types.pyobject] * len(state.args)
     signature = typing.signature(types.pyobject, *args)
     from numba.core.compiler import compile_result
     state.cr = compile_result(
         typing_context=state.typingctx,
         target_context=state.targetctx,
         entry_point=state.func_id.func,
         typing_error=state.status.fail_reason,
         type_annotation="<Interpreter mode function>",
         signature=signature,
         objectmode=False,
         interpmode=True,
         lifted=(),
         fndesc=None,
     )
     return True
Exemple #18
0
def init_series_groupby(typingctx, parent, by_data, data, sort):
    def codegen(context, builder, signature, args):
        parent_val, _, data_val, sort_val = args
        # create series struct and store values
        groupby_obj = cgutils.create_struct_proxy(signature.return_type)(
            context, builder)
        groupby_obj.parent = parent_val
        groupby_obj.data = data_val
        groupby_obj.sort = sort_val

        # increase refcount of stored values
        if context.enable_nrt:
            context.nrt.incref(builder, signature.args[0], parent_val)
            context.nrt.incref(builder, signature.args[2], data_val)

        return groupby_obj._getvalue()

    ret_typ = SeriesGroupByType(parent, by_data)
    sig = signature(ret_typ, parent, by_data, data, sort)
    return sig, codegen
Exemple #19
0
def cuda_quaternion_psi(context, builder, sig, arg):
    # Computes math.atan(2 * (a * d + b * c) / (a * a + b * b - c * c - d * d))
    a = builder.extract_value(arg, 0)
    b = builder.extract_value(arg, 1)
    c = builder.extract_value(arg, 2)
    d = builder.extract_value(arg, 3)

    a2 = builder.fmul(a, a)
    b2 = builder.fmul(b, b)
    c2 = builder.fmul(c, c)
    d2 = builder.fmul(d, d)

    numerator = builder.fadd(builder.fmul(a, d), builder.fmul(b, c))
    denominator = builder.fsub(builder.fsub(builder.fadd(a2, b2), c2), d2)

    atan_sig = signature(types.float64, types.float64)
    atan_impl = context.get_function(math.atan, atan_sig)
    atan_arg = builder.fmul(context.get_constant(types.float64, 2),
                            builder.fdiv(numerator, denominator))
    return atan_impl(builder, [atan_arg])
    def test_error_model(self):
        """
        Caching must not mix up different error models.
        """
        def inv(x):
            return 1.0 / x

        inv_sig = typing.signature(types.float64, types.float64)

        def compile_inv(context):
            return context.compile_subroutine(builder, inv, inv_sig)

        with self._context_builder_sig_args() as (
                context,
                builder,
                sig,
                args,
        ):
            py_error_model = callconv.create_error_model('python', context)
            np_error_model = callconv.create_error_model('numpy', context)

            py_context1 = context.subtarget(error_model=py_error_model)
            py_context2 = context.subtarget(error_model=py_error_model)
            np_context = context.subtarget(error_model=np_error_model)

            initial_cache_size = len(context.cached_internal_func)

            # Note the parent context's cache is shared by subtargets
            self.assertEqual(initial_cache_size + 0,
                             len(context.cached_internal_func))
            # Compiling with the same error model reuses the same cache slot
            compile_inv(py_context1)
            self.assertEqual(initial_cache_size + 1,
                             len(context.cached_internal_func))
            compile_inv(py_context2)
            self.assertEqual(initial_cache_size + 1,
                             len(context.cached_internal_func))
            # Compiling with another error model creates a new cache slot
            compile_inv(np_context)
            self.assertEqual(initial_cache_size + 2,
                             len(context.cached_internal_func))
def dpnp_random_impl(n, p, size=None):
    name = "binomial"
    dpnp_lowering.ensure_dpnp(name)

    ret_type = types.void
    """
    dpnp source:
    https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_random.cpp#L56

    Function declaration:
    void custom_rng_binomial_c(void* result, int ntrial, double p, size_t size)

    """
    sig = signature(ret_type, types.voidptr, types.int32, types.float64,
                    types.intp)
    dpnp_func = dpnp_ext.dpnp_func("dpnp_" + name, ["int32", "NONE"], sig)
    res_dtype = np.int32
    PRINT_DEBUG = dpnp_lowering.DEBUG

    if not (isinstance(n, types.Integer)):
        raise ValueError("We only support scalar for input: n")

    if not (isinstance(p, types.Float)):
        raise ValueError("We only support scalar for input: p")

    if size in (None, types.none):

        def dpnp_impl(n, p, size=None):
            res = np.empty(1, dtype=res_dtype)
            common_impl_2_arg(n, p, res, dpnp_func, PRINT_DEBUG)
            return res[0]

    else:

        def dpnp_impl(n, p, size=None):
            res = np.empty(size, dtype=res_dtype)
            if res.size != 0:
                common_impl_2_arg(n, p, res, dpnp_func, PRINT_DEBUG)
            return res

    return dpnp_impl
Exemple #22
0
def init_series(typingctx, data, index=None, name=None):
    """Create a Series with provided data, index and name values.
    Used as a single constructor for Series and assigning its data, so that
    optimization passes can look for init_series() to see if underlying
    data has changed, and get the array variables from init_series() args if
    not changed.
    """

    index = types.none if index is None else index
    name = types.none if name is None else name
    is_named = False if name is types.none else True

    def codegen(context, builder, signature, args):
        data_val, index_val, name_val = args
        # create series struct and store values
        series = cgutils.create_struct_proxy(
            signature.return_type)(context, builder)
        series.data = data_val
        series.index = index_val
        if is_named:
            if isinstance(name, types.StringLiteral):
                series.name = numba.cpython.unicode.make_string_from_constant(
                    context, builder, string_type, name.literal_value)
            else:
                series.name = name_val

        # increase refcount of stored values
        if context.enable_nrt:
            context.nrt.incref(builder, signature.args[0], data_val)
            context.nrt.incref(builder, signature.args[1], index_val)
            if is_named:
                context.nrt.incref(builder, signature.args[2], name_val)

        return series._getvalue()

    dtype = data.dtype
    # XXX pd.DataFrame() calls init_series for even Series since it's untyped
    data = if_series_to_array_type(data)
    ret_typ = SeriesType(dtype, data, index, is_named)
    sig = signature(ret_typ, data, index, name)
    return sig, codegen
    def random_arr(context, builder, sig, args, typing_key=typing_key):

        arrty = sig.return_type
        dtype = arrty.dtype
        scalar_sig = signature(dtype, *sig.args[:-1])
        scalar_args = args[:-1]

        # Allocate array...
        shapes = arrayobj._parse_shape(context, builder, sig.args[-1],
                                       args[-1])
        arr = arrayobj._empty_nd_impl(context, builder, arrty, shapes)

        # ... and populate it in natural order
        scalar_impl = context.get_function(typing_key, scalar_sig)
        with cgutils.for_range(builder, arr.nitems) as loop:
            val = scalar_impl(builder, scalar_args)
            ptr = cgutils.gep(builder, arr.data, loop.index)
            arrayobj.store_item(context, builder, arrty, val, ptr)

        return impl_ret_new_ref(context, builder, sig.return_type,
                                arr._getvalue())
Exemple #24
0
    def _get_attr_info(self, state, expr):
        recv_type = state.type_annotation.typemap[expr.value.name]
        recv_type = types.unliteral(recv_type)
        matched = state.typingctx.find_matching_getattr_template(
            recv_type, expr.attr,
        )
        if not matched:
            return None

        template = matched['template']
        if getattr(template, 'is_method', False):
            # The attribute template is representing a method.
            # Don't inline the getattr.
            return None

        templates = [template]
        sig = typing.signature(matched['return_type'], recv_type)
        arg_typs = sig.args
        is_method = False

        return templates, sig, arg_typs, is_method
Exemple #25
0
    def getitem(self, obj, index, typ) -> ir.Expr:
        """Makes a getitem call

        Parameters
        ----------
        obj : ir.Var
            the object being indexed
        index : ir.Var
            the index
        val : ir.Var
            the ty

        Returns
        -------
        res : ir.Expr
            the retrieved value
        """
        tm = self._typemap
        getitem = ir.Expr.getitem(obj, index, loc=self._loc)
        self._lowerer.fndesc.calltypes[getitem] = signature(
            typ, tm[obj.name], tm[index.name],
        )
        return getitem
Exemple #26
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This enables the resolving of the return type.

        A (template, pysig, args, kws) tuple is returned.
        """
        assert not kws
        self._legalize_arg_types(args)
        # Coerce to object mode
        args = [types.ffi_forced_object] * len(args)

        if self._can_compile:
            self.compile(tuple(args))

        signatures = [typing.signature(self.output_types, *args)]
        pysig = None
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=signatures)

        return call_template, pysig, args, kws
    def setitem(self, obj, index, val) -> ir.SetItem:
        """Makes a setitem call

        Parameters
        ----------
        obj : ir.Var
            the object being indexed
        index : ir.Var
            the index
        val : ir.Var
            the value to be stored

        Returns
        -------
        res : ir.SetItem
        """
        loc = self._loc
        tm = self._typemap
        setitem = ir.SetItem(obj, index, val, loc=loc)
        self._lowerer.fndesc.calltypes[setitem] = signature(
            types.none, tm[obj.name], tm[index.name], tm[val.name])
        self._lowerer.lower_inst(setitem)
        return setitem
def dpnp_cumsum_impl(a):
    name = "cumsum"
    dpnp_lowering.ensure_dpnp(name)

    res_type = types.void
    """
    dpnp source:
    https://github.com/IntelPython/dpnp/blob/0.5.1/dpnp/backend/kernels/dpnp_krnl_mathematical.cpp#L135
    Function declaration:
    void dpnp_cumsum_c(void* array1_in, void* result1, size_t size)
    """
    sig = signature(res_type, types.voidptr, types.voidptr, types.intp)
    dpnp_func = dpnp_ext.dpnp_func("dpnp_" + name, [a.dtype.name, "NONE"], sig)

    PRINT_DEBUG = dpnp_lowering.DEBUG

    def dpnp_impl(a):
        out = np.arange(0, a.size, 1, a.dtype)
        common_impl(a, out, dpnp_func, PRINT_DEBUG)

        return out

    return dpnp_impl
def dpnp_random_impl(low=0.0, high=1.0, size=None):
    name = "uniform"
    dpnp_lowering.ensure_dpnp(name)

    ret_type = types.void
    """
    dpnp source:
    https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_random.cpp#L391

    Function declaration:
    void custom_rng_uniform_c(void* result, long low, long high, size_t size)
    """
    sig = signature(ret_type, types.voidptr, types.int64, types.int64,
                    types.intp)
    dpnp_func = dpnp_ext.dpnp_func("dpnp_" + name, ["float64", "NONE"], sig)

    res_dtype = np.float64

    PRINT_DEBUG = dpnp_lowering.DEBUG

    if size in (None, types.none):

        def dpnp_impl(low=0.0, high=1.0, size=None):
            res = np.empty(1, dtype=res_dtype)
            common_impl(low, high, res, dpnp_func, PRINT_DEBUG)
            return res

    else:

        def dpnp_impl(low=0.0, high=1.0, size=None):
            res = np.empty(size, dtype=res_dtype)
            if res.size != 0:
                common_impl(low, high, res, dpnp_func, PRINT_DEBUG)
            return res

    return dpnp_impl
def dpnp_random_impl(df, size=None):
    name = "chisquare"
    dpnp_lowering.ensure_dpnp(name)

    ret_type = types.void
    """
    dpnp source:
    https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_random.cpp#L71

    Function declaration:
    void custom_rng_chi_square_c(void* result, int df, size_t size)
    """
    sig = signature(ret_type, types.voidptr, types.int32, types.intp)
    dpnp_func = dpnp_ext.dpnp_func("dpnp_" + name, ["float64", "NONE"], sig)
    res_dtype = np.float64
    PRINT_DEBUG = dpnp_lowering.DEBUG

    if not (isinstance(df, types.Integer)):
        raise ValueError("We only support scalar for input: df")

    if size in (None, types.none):

        def dpnp_impl(df, size=None):
            res = np.empty(1, dtype=res_dtype)
            common_impl_1_arg(df, res, dpnp_func, PRINT_DEBUG)
            return res[0]

    else:

        def dpnp_impl(df, size=None):
            res = np.empty(size, dtype=res_dtype)
            if res.size != 0:
                common_impl_1_arg(df, res, dpnp_func, PRINT_DEBUG)
            return res

    return dpnp_impl