From 5da25f109d0f57a85a40e87644e4b1da03bfec12 Mon Sep 17 00:00:00 2001 From: khaled Date: Thu, 6 Apr 2023 13:31:20 -0500 Subject: [PATCH] dpnp.full() complete and test case added Remove 'like' from dpnp.empty() overload ty_x --> ty_x1 --- numba_dpex/core/runtime/_dpexrt_python.c | 83 ++++++++-- numba_dpex/core/runtime/context.py | 35 +++- numba_dpex/core/types/usm_ndarray_type.py | 2 +- numba_dpex/dpnp_iface/_intrinsic.py | 104 ++++++++++-- numba_dpex/dpnp_iface/arrayobj.py | 150 +++++++++++++++--- .../tests/dpjit_tests/dpnp/test_dpnp_empty.py | 20 +-- .../tests/dpjit_tests/dpnp/test_dpnp_full.py | 60 +++++++ .../tests/dpjit_tests/dpnp/test_dpnp_ones.py | 6 +- .../dpjit_tests/dpnp/test_dpnp_ones_like.py | 8 +- .../tests/dpjit_tests/dpnp/test_dpnp_zeros.py | 10 +- .../dpjit_tests/dpnp/test_dpnp_zeros_like.py | 10 +- 11 files changed, 401 insertions(+), 87 deletions(-) create mode 100644 numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_full.py diff --git a/numba_dpex/core/runtime/_dpexrt_python.c b/numba_dpex/core/runtime/_dpexrt_python.c index 4ca1993e9f..815a7a1c59 100644 --- a/numba_dpex/core/runtime/_dpexrt_python.c +++ b/numba_dpex/core/runtime/_dpexrt_python.c @@ -23,6 +23,28 @@ #include "_queuestruct.h" #include "numba/_arraystruct.h" +/* Debugging facilities - enabled at compile-time */ +/* #undef NDEBUG */ +#if 0 +#include +#define DPEXRT_DEBUG(X) \ + { \ + X; \ + fflush(stdout); \ + } +#else +#define DPEXRT_DEBUG(X) \ + if (0) { \ + X; \ + } +#endif + +typedef union +{ + float f_; + uint32_t i_; +} float32bits; + // forward declarations static struct PyUSMArrayObject *PyUSMNdArray_ARRAYOBJ(PyObject *obj); static npy_intp product_of_shape(npy_intp *shape, npy_intp ndim); @@ -34,6 +56,12 @@ static NRT_ExternalAllocator * NRT_ExternalAllocator_new_for_usm(DPCTLSyclQueueRef qref, size_t usm_type); static void *DPEXRTQueue_CreateFromFilterString(const char *device); static MemInfoDtorInfo *MemInfoDtorInfo_new(NRT_MemInfo *mi, PyObject *owner); +static NRT_MemInfo *DPEXRT_MemInfo_fill(NRT_MemInfo *mi, + size_t itemsize, + bool dest_is_float, + bool value_is_float, + int64_t value, + const char *device); static NRT_MemInfo *NRT_MemInfo_new_from_usmndarray(PyObject *ndarrobj, void *data, npy_intp nitems, @@ -521,8 +549,9 @@ DPEXRT_MemInfo_alloc(npy_intp size, size_t usm_type, const char *device) */ static NRT_MemInfo *DPEXRT_MemInfo_fill(NRT_MemInfo *mi, size_t itemsize, - bool is_float, - uint8_t value, + bool dest_is_float, + bool value_is_float, + int64_t value, const char *device) { DPCTLSyclQueueRef qref = NULL; @@ -553,12 +582,16 @@ static NRT_MemInfo *DPEXRT_MemInfo_fill(NRT_MemInfo *mi, case 3: { uint64_t value_assign = (uint64_t)value; - if (is_float) { - double const_val = (double)value; + if (dest_is_float && !value_is_float) { + double const_val = value; // To stop warning: dereferencing type-punned pointer // will break strict-aliasing rules [-Wstrict-aliasing] - double *p = &const_val; - value_assign = *((uint64_t *)(p)); + double *p = (double *)&const_val; + value_assign = *((int64_t *)(p)); + } + else if (!dest_is_float && value_is_float) { + double *p = (double *)&value; + value_assign = *p; } if (!(eref = DPCTLQueue_Fill64(qref, mi->data, value_assign, count))) goto error; @@ -567,25 +600,53 @@ static NRT_MemInfo *DPEXRT_MemInfo_fill(NRT_MemInfo *mi, case 2: { uint32_t value_assign = (uint32_t)value; - if (is_float) { + if (dest_is_float && value_is_float) { + float32bits fb; + double *p = (double *)(&value); + fb.f_ = *p; + value_assign = fb.i_; + } + else if (dest_is_float && !value_is_float) { float const_val = (float)value; // To stop warning: dereferencing type-punned pointer // will break strict-aliasing rules [-Wstrict-aliasing] - float *p = &const_val; - value_assign = *((uint32_t *)(p)); + float *p = (float *)&const_val; + value_assign = *((int32_t *)(p)); + } + else if (!dest_is_float && value_is_float) { + double *p = (double *)&value; + value_assign = *p; } if (!(eref = DPCTLQueue_Fill32(qref, mi->data, value_assign, count))) goto error; break; } case 1: - if (!(eref = DPCTLQueue_Fill16(qref, mi->data, value, count))) + { + if (dest_is_float) + goto error; + uint16_t value_assign = (uint16_t)value; + if (value_is_float) { + double *p = (double *)&value; + value_assign = *p; + } + if (!(eref = DPCTLQueue_Fill16(qref, mi->data, value_assign, count))) goto error; break; + } case 0: - if (!(eref = DPCTLQueue_Fill8(qref, mi->data, value, count))) + { + if (dest_is_float) + goto error; + uint8_t value_assign = (uint8_t)value; + if (value_is_float) { + double *p = (double *)&value; + value_assign = *p; + } + if (!(eref = DPCTLQueue_Fill8(qref, mi->data, value_assign, count))) goto error; break; + } default: goto error; } diff --git a/numba_dpex/core/runtime/context.py b/numba_dpex/core/runtime/context.py index 49d41f906d..26dd6f1bc0 100644 --- a/numba_dpex/core/runtime/context.py +++ b/numba_dpex/core/runtime/context.py @@ -33,10 +33,25 @@ def meminfo_alloc(self, builder, size, usm_type, device): return self.meminfo_alloc_unchecked(builder, size, usm_type, device) @_check_null_result - def meminfo_fill(self, builder, meminfo, itemsize, is_float, value, device): + def meminfo_fill( + self, + builder, + meminfo, + itemsize, + dest_is_float, + value_is_float, + value, + device, + ): """A wrapped caller for meminfo_fill_unchecked() with null check.""" return self.meminfo_fill_unchecked( - builder, meminfo, itemsize, is_float, value, device + builder, + meminfo, + itemsize, + dest_is_float, + value_is_float, + value, + device, ) def meminfo_alloc_unchecked(self, builder, size, usm_type, device): @@ -71,7 +86,14 @@ def meminfo_alloc_unchecked(self, builder, size, usm_type, device): return ret def meminfo_fill_unchecked( - self, builder, meminfo, itemsize, is_float, value, device + self, + builder, + meminfo, + itemsize, + dest_is_float, + value_is_float, + value, + device, ): """Fills an allocated `MemInfo` with the value specified. @@ -96,12 +118,15 @@ def meminfo_fill_unchecked( b = llvmir.IntType(1) fnty = llvmir.FunctionType( cgutils.voidptr_t, - [cgutils.voidptr_t, u64, b, cgutils.int8_t, cgutils.voidptr_t], + [cgutils.voidptr_t, u64, b, b, cgutils.intp_t, cgutils.voidptr_t], ) fn = cgutils.get_or_insert_function(mod, fnty, "DPEXRT_MemInfo_fill") fn.return_value.add_attribute("noalias") - ret = builder.call(fn, [meminfo, itemsize, is_float, value, device]) + ret = builder.call( + fn, + [meminfo, itemsize, dest_is_float, value_is_float, value, device], + ) return ret diff --git a/numba_dpex/core/types/usm_ndarray_type.py b/numba_dpex/core/types/usm_ndarray_type.py index bd4d12eaf3..e3d1101633 100644 --- a/numba_dpex/core/types/usm_ndarray_type.py +++ b/numba_dpex/core/types/usm_ndarray_type.py @@ -74,7 +74,7 @@ def __init__( if not dtype: dummy_tensor = dpctl.tensor.empty( - shape=1, order=layout, usm_type=usm_type, sycl_queue=self.queue + 1, order=layout, usm_type=usm_type, sycl_queue=self.queue ) # convert dpnp type to numba/numpy type _dtype = dummy_tensor.dtype diff --git a/numba_dpex/dpnp_iface/_intrinsic.py b/numba_dpex/dpnp_iface/_intrinsic.py index 3c2ad0ac98..5778627adb 100644 --- a/numba_dpex/dpnp_iface/_intrinsic.py +++ b/numba_dpex/dpnp_iface/_intrinsic.py @@ -2,6 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 +from llvmlite import ir as llvmir from numba import types from numba.core.typing import signature from numba.extending import intrinsic @@ -76,14 +77,25 @@ def fill_arrayobj(context, builder, sig, llargs, value, is_like=False): types.intp, get_itemsize(context, arrtype[0]) ) device = context.insert_const_string(builder.module, arrtype[0].device) - value = context.get_constant(types.int8, value) + + value_is_float = context.get_constant(types.boolean, 0) + if isinstance(sig.args[1], types.scalars.Float): + value = builder.bitcast(value, llvmir.IntType(64)) + value_is_float = context.get_constant(types.boolean, 1) + + dest_is_float = context.get_constant(types.boolean, 0) if isinstance(arrtype[0].dtype, types.scalars.Float): - is_float = context.get_constant(types.boolean, 1) - else: - is_float = context.get_constant(types.boolean, 0) + dest_is_float = context.get_constant(types.boolean, 1) + dpexrtCtx = dpexrt.DpexRTContext(context) dpexrtCtx.meminfo_fill( - builder, ary.meminfo, itemsize, is_float, value, device + builder, + ary.meminfo, + itemsize, + dest_is_float, + value_is_float, + value, + device, ) return ary, arrtype @@ -109,6 +121,7 @@ def impl_dpnp_empty( ty_shape, ty_dtype, ty_order, + # ty_like, ty_device, ty_usm_type, ty_sycl_queue, @@ -144,6 +157,7 @@ def impl_dpnp_empty( ty_shape, ty_dtype, ty_order, + # ty_like, ty_device, ty_usm_type, ty_sycl_queue, @@ -163,6 +177,7 @@ def impl_dpnp_zeros( ty_shape, ty_dtype, ty_order, + ty_like, ty_device, ty_usm_type, ty_sycl_queue, @@ -198,6 +213,7 @@ def impl_dpnp_zeros( ty_shape, ty_dtype, ty_order, + ty_like, ty_device, ty_usm_type, ty_sycl_queue, @@ -205,7 +221,8 @@ def impl_dpnp_zeros( ) def codegen(context, builder, sig, llargs): - ary, _ = fill_arrayobj(context, builder, sig, llargs, 0) + fill_value = context.get_constant(types.intp, 0) + ary, _ = fill_arrayobj(context, builder, sig, llargs, fill_value) return ary._getvalue() return sig, codegen @@ -217,6 +234,7 @@ def impl_dpnp_ones( ty_shape, ty_dtype, ty_order, + ty_like, ty_device, ty_usm_type, ty_sycl_queue, @@ -252,6 +270,7 @@ def impl_dpnp_ones( ty_shape, ty_dtype, ty_order, + ty_like, ty_device, ty_usm_type, ty_sycl_queue, @@ -259,7 +278,8 @@ def impl_dpnp_ones( ) def codegen(context, builder, sig, llargs): - ary, _ = fill_arrayobj(context, builder, sig, llargs, 1) + fill_value = context.get_constant(types.intp, 1) + ary, _ = fill_arrayobj(context, builder, sig, llargs, fill_value) return ary._getvalue() return sig, codegen @@ -268,9 +288,11 @@ def codegen(context, builder, sig, llargs): @intrinsic def impl_dpnp_empty_like( ty_context, - ty_x, + ty_x1, ty_dtype, ty_order, + ty_subok, + ty_shape, ty_device, ty_usm_type, ty_sycl_queue, @@ -302,9 +324,11 @@ def impl_dpnp_empty_like( ty_retty = ty_retty_ref.instance_type sig = ty_retty( - ty_x, + ty_x1, ty_dtype, ty_order, + ty_subok, + ty_shape, ty_device, ty_usm_type, ty_sycl_queue, @@ -323,9 +347,11 @@ def codegen(context, builder, sig, llargs): @intrinsic def impl_dpnp_zeros_like( ty_context, - ty_x, + ty_x1, ty_dtype, ty_order, + ty_subok, + ty_shape, ty_device, ty_usm_type, ty_sycl_queue, @@ -357,9 +383,11 @@ def impl_dpnp_zeros_like( ty_retty = ty_retty_ref.instance_type sig = ty_retty( - ty_x, + ty_x1, ty_dtype, ty_order, + ty_subok, + ty_shape, ty_device, ty_usm_type, ty_sycl_queue, @@ -367,7 +395,10 @@ def impl_dpnp_zeros_like( ) def codegen(context, builder, sig, llargs): - ary, _ = fill_arrayobj(context, builder, sig, llargs, 0, is_like=True) + fill_value = context.get_constant(types.intp, 0) + ary, _ = fill_arrayobj( + context, builder, sig, llargs, fill_value, is_like=True + ) return ary._getvalue() return sig, codegen @@ -376,9 +407,11 @@ def codegen(context, builder, sig, llargs): @intrinsic def impl_dpnp_ones_like( ty_context, - ty_x, + ty_x1, ty_dtype, ty_order, + ty_subok, + ty_shape, ty_device, ty_usm_type, ty_sycl_queue, @@ -410,9 +443,11 @@ def impl_dpnp_ones_like( ty_retty = ty_retty_ref.instance_type sig = ty_retty( - ty_x, + ty_x1, ty_dtype, ty_order, + ty_subok, + ty_shape, ty_device, ty_usm_type, ty_sycl_queue, @@ -420,7 +455,46 @@ def impl_dpnp_ones_like( ) def codegen(context, builder, sig, llargs): - ary, _ = fill_arrayobj(context, builder, sig, llargs, 1, is_like=True) + fill_value = context.get_constant(types.intp, 1) + ary, _ = fill_arrayobj( + context, builder, sig, llargs, fill_value, is_like=True + ) return ary._getvalue() return sig, codegen + + +@intrinsic +def impl_dpnp_full( + ty_context, + ty_shape, + ty_fill_value, + ty_dtype, + ty_order, + ty_like, + ty_device, + ty_usm_type, + ty_sycl_queue, + ty_retty_ref, +): + ty_retty = ty_retty_ref.instance_type + signature = ty_retty( + ty_shape, + ty_fill_value, + ty_dtype, + ty_order, + ty_like, + ty_device, + ty_usm_type, + ty_sycl_queue, + ty_retty_ref, + ) + + def codegen(context, builder, sig, args): + fill_value = context.get_argument_value(builder, sig.args[1], args[1]) + ary, _ = fill_arrayobj( + context, builder, sig, args, fill_value, is_like=False + ) + return ary._getvalue() + + return signature, codegen diff --git a/numba_dpex/dpnp_iface/arrayobj.py b/numba_dpex/dpnp_iface/arrayobj.py index 694ac37db5..1971595176 100644 --- a/numba_dpex/dpnp_iface/arrayobj.py +++ b/numba_dpex/dpnp_iface/arrayobj.py @@ -14,6 +14,7 @@ from ._intrinsic import ( impl_dpnp_empty, impl_dpnp_empty_like, + impl_dpnp_full, impl_dpnp_ones, impl_dpnp_ones_like, impl_dpnp_zeros, @@ -208,6 +209,7 @@ def ol_dpnp_empty( shape, dtype=None, order="C", + # like=None, # this gets lost when dpnp.empty() is called outside dpjit device=None, usm_type="device", sycl_queue=None, @@ -266,12 +268,20 @@ def impl( shape, dtype=None, order="C", + # like=None, device=None, usm_type="device", sycl_queue=None, ): return impl_dpnp_empty( - shape, _dtype, order, _device, _usm_type, sycl_queue, ret_ty + shape, + _dtype, + order, + # like, + _device, + _usm_type, + sycl_queue, + ret_ty, ) return impl @@ -289,6 +299,7 @@ def ol_dpnp_zeros( shape, dtype=None, order="C", + like=None, device=None, usm_type="device", sycl_queue=None, @@ -347,12 +358,20 @@ def impl( shape, dtype=None, order="C", + like=None, device=None, usm_type="device", sycl_queue=None, ): return impl_dpnp_zeros( - shape, _dtype, order, _device, _usm_type, sycl_queue, ret_ty + shape, + _dtype, + order, + like, + _device, + _usm_type, + sycl_queue, + ret_ty, ) return impl @@ -370,6 +389,7 @@ def ol_dpnp_ones( shape, dtype=None, order="C", + like=None, device=None, usm_type="device", sycl_queue=None, @@ -428,12 +448,20 @@ def impl( shape, dtype=None, order="C", + like=None, device=None, usm_type="device", sycl_queue=None, ): return impl_dpnp_ones( - shape, _dtype, order, _device, _usm_type, sycl_queue, ret_ty + shape, + _dtype, + order, + like, + _device, + _usm_type, + sycl_queue, + ret_ty, ) return impl @@ -448,9 +476,10 @@ def impl( @overload(dpnp.empty_like, prefer_literal=True) def ol_dpnp_empty_like( - x, + x1, dtype=None, order="C", + subok=False, shape=None, device=None, usm_type=None, @@ -498,9 +527,9 @@ def ol_dpnp_empty_like( "The parameter shape is not supported " + "inside overloaded dpnp.empty_like() function." ) - _ndim = x.ndim if hasattr(x, "ndim") and x.ndim is not None else 0 - _dtype = _parse_dtype(dtype, data=x) - _order = x.layout if order is None else order + _ndim = x1.ndim if hasattr(x1, "ndim") and x1.ndim is not None else 0 + _dtype = _parse_dtype(dtype, data=x1) + _order = x1.layout if order is None else order _usm_type = _parse_usm_type(usm_type) if usm_type is not None else "device" _device = ( _parse_device_filter_string(device) if device is not None else "unknown" @@ -516,18 +545,21 @@ def ol_dpnp_empty_like( if ret_ty: def impl( - x, + x1, dtype=None, order="C", + subok=False, shape=None, device=None, usm_type=None, sycl_queue=None, ): return impl_dpnp_empty_like( - x, + x1, _dtype, _order, + subok, + shape, _device, _usm_type, sycl_queue, @@ -538,15 +570,16 @@ def impl( else: raise errors.TypingError( "Cannot parse input types to " - + f"function dpnp.empty_like({x}, {dtype}, ...)." + + f"function dpnp.empty_like({x1}, {dtype}, ...)." ) @overload(dpnp.zeros_like, prefer_literal=True) def ol_dpnp_zeros_like( - x, + x1, dtype=None, order="C", + subok=None, shape=None, device=None, usm_type=None, @@ -594,9 +627,9 @@ def ol_dpnp_zeros_like( "The parameter shape is not supported " + "inside overloaded dpnp.zeros_like() function." ) - _ndim = x.ndim if hasattr(x, "ndim") and x.ndim is not None else 0 - _dtype = _parse_dtype(dtype, data=x) - _order = x.layout if order is None else order + _ndim = x1.ndim if hasattr(x1, "ndim") and x1.ndim is not None else 0 + _dtype = _parse_dtype(dtype, data=x1) + _order = x1.layout if order is None else order _usm_type = _parse_usm_type(usm_type) if usm_type is not None else "device" _device = ( _parse_device_filter_string(device) if device is not None else "unknown" @@ -612,18 +645,21 @@ def ol_dpnp_zeros_like( if ret_ty: def impl( - x, + x1, dtype=None, order="C", + subok=None, shape=None, device=None, usm_type=None, sycl_queue=None, ): return impl_dpnp_zeros_like( - x, + x1, _dtype, _order, + subok, + shape, _device, _usm_type, sycl_queue, @@ -634,15 +670,16 @@ def impl( else: raise errors.TypingError( "Cannot parse input types to " - + f"function dpnp.empty_like({x}, {dtype}, ...)." + + f"function dpnp.empty_like({x1}, {dtype}, ...)." ) @overload(dpnp.ones_like, prefer_literal=True) def ol_dpnp_ones_like( - x, + x1, dtype=None, order="C", + subok=None, shape=None, device=None, usm_type=None, @@ -690,9 +727,9 @@ def ol_dpnp_ones_like( "The parameter shape is not supported " + "inside overloaded dpnp.ones_like() function." ) - _ndim = x.ndim if hasattr(x, "ndim") and x.ndim is not None else 0 - _dtype = _parse_dtype(dtype, data=x) - _order = x.layout if order is None else order + _ndim = x1.ndim if hasattr(x1, "ndim") and x1.ndim is not None else 0 + _dtype = _parse_dtype(dtype, data=x1) + _order = x1.layout if order is None else order _usm_type = _parse_usm_type(usm_type) if usm_type is not None else "device" _device = ( _parse_device_filter_string(device) if device is not None else "unknown" @@ -708,17 +745,21 @@ def ol_dpnp_ones_like( if ret_ty: def impl( - x, + x1, dtype=None, order="C", + subok=None, + shape=None, device=None, usm_type=None, sycl_queue=None, ): return impl_dpnp_ones_like( - x, + x1, _dtype, _order, + subok, + shape, _device, _usm_type, sycl_queue, @@ -729,5 +770,66 @@ def impl( else: raise errors.TypingError( "Cannot parse input types to " - + f"function dpnp.empty_like({x}, {dtype}, ...)." + + f"function dpnp.empty_like({x1}, {dtype}, ...)." ) + + +@overload(dpnp.full, prefer_literal=True) +def ov_dpnp_full( + shape, + fill_value, + dtype=None, + order="C", + like=None, + device=None, + usm_type=None, + sycl_queue=None, +): + _ndim = _ty_parse_shape(shape) + _dtype = _parse_dtype(dtype) + _layout = _parse_layout(order) + _usm_type = _parse_usm_type(usm_type) if usm_type is not None else "device" + _device = ( + _parse_device_filter_string(device) if device is not None else "unknown" + ) + if _ndim: + ret_ty = build_dpnp_ndarray( + _ndim, + layout=_layout, + dtype=_dtype, + usm_type=_usm_type, + device=_device, + queue=sycl_queue, + ) + if ret_ty: + + def impl( + shape, + fill_value, + dtype=None, + order="C", + like=None, + device=None, + usm_type=None, + sycl_queue=None, + ): + return impl_dpnp_full( + shape, + fill_value, + _dtype, + order, + like, + _device, + _usm_type, + sycl_queue, + ret_ty, + ) + + return impl + else: + raise errors.TypingError( + "Cannot parse input types to " + + f"function dpnp.full({shape}, {fill_value}, {dtype}, ...)." + ) + else: + raise errors.TypingError("Could not infer the rank of the ndarray.") diff --git a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_empty.py b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_empty.py index 798f03b7d8..775b337109 100644 --- a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_empty.py +++ b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_empty.py @@ -10,7 +10,7 @@ from numba_dpex import dpjit -shapes = [10, (2, 5)] +shapes = [11, (2, 5)] dtypes = [dpnp.int32, dpnp.int64, dpnp.float32, dpnp.float64] usm_types = ["device", "shared", "host"] devices = ["cpu", "unknown"] @@ -22,14 +22,12 @@ @pytest.mark.parametrize("device", devices) def test_dpnp_empty(shape, dtype, usm_type, device): @dpjit - def func1(shape): - c = dpnp.empty( - shape=shape, dtype=dtype, usm_type=usm_type, device=device - ) + def func(shape): + c = dpnp.empty(shape, dtype=dtype, usm_type=usm_type, device=device) return c try: - c = func1(shape) + c = func(shape) except Exception: pytest.fail("Calling dpnp.empty inside dpjit failed") @@ -52,12 +50,12 @@ def func1(shape): @pytest.mark.parametrize("shape", shapes) def test_dpnp_empty_default_dtype(shape): @dpjit - def func1(shape): - c = dpnp.empty(shape=shape) + def func(shape): + c = dpnp.empty(shape) return c try: - c = func1(shape) + c = func(shape) except Exception: pytest.fail("Calling dpnp.empty inside dpjit failed") @@ -66,10 +64,6 @@ def func1(shape): else: assert c.shape == shape - dummy_tensor = dpctl.tensor.empty(shape=1) - - assert c.dtype == dummy_tensor.dtype - dummy_tensor = dpctl.tensor.empty(shape) assert c.dtype == dummy_tensor.dtype diff --git a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_full.py b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_full.py new file mode 100644 index 0000000000..9a238d44e4 --- /dev/null +++ b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_full.py @@ -0,0 +1,60 @@ +# SPDX-FileCopyrightText: 2020 - 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +"""Tests for dpnp ndarray constructors.""" + +import math + +import dpctl +import dpctl.tensor as dpt +import dpnp +import numpy +import pytest + +from numba_dpex import dpjit + +shapes = [11, (3, 7)] +dtypes = [dpnp.int32, dpnp.int64, dpnp.float32, dpnp.float64] +usm_types = ["device", "shared", "host"] +devices = ["cpu", "unknown"] +# TODO: test with 3.4028237e38, 4294967295 etc. +fill_values = [7, -7, 7.1, -7.1, math.pi, math.e] + + +@pytest.mark.parametrize("shape", shapes) +@pytest.mark.parametrize("fill_value", fill_values) +@pytest.mark.parametrize("dtype", dtypes) +@pytest.mark.parametrize("usm_type", usm_types) +@pytest.mark.parametrize("device", devices) +def test_dpnp_full(shape, fill_value, dtype, usm_type, device): + @dpjit + def func(shape, fill_value): + c = dpnp.full( + shape, fill_value, dtype=dtype, usm_type=usm_type, device=device + ) + return c + + a = numpy.full(shape, fill_value, dtype=dtype) + + try: + c = func(shape, fill_value) + except Exception: + pytest.fail("Calling dpnp.full inside dpjit failed") + + if len(c.shape) == 1: + assert c.shape[0] == shape + else: + assert c.shape == shape + + assert c.dtype == dtype + assert c.usm_type == usm_type + if device != "unknown": + assert ( + c.sycl_device.filter_string + == dpctl.SyclDevice(device).filter_string + ) + else: + c.sycl_device.filter_string == dpctl.SyclDevice().filter_string + + assert numpy.array_equal(dpt.asnumpy(c._array_obj), a) diff --git a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones.py b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones.py index fd69038728..34dbcaf457 100644 --- a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones.py +++ b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones.py @@ -24,7 +24,7 @@ @pytest.mark.parametrize("device", devices) def test_dpnp_ones(shape, dtype, usm_type, device): @dpjit - def func1(shape): + def func(shape): c = dpnp.ones( shape=shape, dtype=dtype, usm_type=usm_type, device=device ) @@ -33,9 +33,9 @@ def func1(shape): a = numpy.ones(shape, dtype=dtype) try: - c = func1(shape) + c = func(shape) except Exception: - pytest.fail("Calling dpnp.empty inside dpjit failed") + pytest.fail("Calling dpnp.ones inside dpjit failed") if len(c.shape) == 1: assert c.shape[0] == shape diff --git a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones_like.py b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones_like.py index 64d1accba6..d360a65ffe 100644 --- a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones_like.py +++ b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_ones_like.py @@ -23,10 +23,10 @@ @pytest.mark.parametrize("dtype", dtypes) @pytest.mark.parametrize("usm_type", usm_types) @pytest.mark.parametrize("device", devices) -def test_dpnp_ones(shape, dtype, usm_type, device): +def test_dpnp_ones_like(shape, dtype, usm_type, device): @dpjit def func1(a): - c = dpnp.ones(a, dtype=dtype, usm_type=usm_type, device=device) + c = dpnp.ones_like(a, dtype=dtype, usm_type=usm_type, device=device) return c if isinstance(shape, int): @@ -35,9 +35,9 @@ def func1(a): NZ = numpy.random.rand(*shape) try: - c = func1(shape) + c = func1(NZ) except Exception: - pytest.fail("Calling dpnp.empty inside dpjit failed") + pytest.fail("Calling dpnp.ones_like inside dpjit failed") if len(c.shape) == 1: assert c.shape[0] == NZ.shape[0] diff --git a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros.py b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros.py index 854cceb9bc..e63fee390d 100644 --- a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros.py +++ b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros.py @@ -24,18 +24,16 @@ @pytest.mark.parametrize("device", devices) def test_dpnp_zeros(shape, dtype, usm_type, device): @dpjit - def func1(shape): - c = dpnp.zeros( - shape=shape, dtype=dtype, usm_type=usm_type, device=device - ) + def func(shape): + c = dpnp.zeros(shape, dtype=dtype, usm_type=usm_type, device=device) return c a = numpy.zeros(shape, dtype=dtype) try: - c = func1(shape) + c = func(shape) except Exception: - pytest.fail("Calling dpnp.empty inside dpjit failed") + pytest.fail("Calling dpnp.zeros inside dpjit failed") if len(c.shape) == 1: assert c.shape[0] == shape diff --git a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros_like.py b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros_like.py index 2f8cdd89d6..a1fe81e611 100644 --- a/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros_like.py +++ b/numba_dpex/tests/dpjit_tests/dpnp/test_dpnp_zeros_like.py @@ -23,10 +23,10 @@ @pytest.mark.parametrize("dtype", dtypes) @pytest.mark.parametrize("usm_type", usm_types) @pytest.mark.parametrize("device", devices) -def test_dpnp_zeros(shape, dtype, usm_type, device): +def test_dpnp_zeros_like(shape, dtype, usm_type, device): @dpjit - def func1(a): - c = dpnp.zeros(a, dtype=dtype, usm_type=usm_type, device=device) + def func(a): + c = dpnp.zeros_like(a, dtype=dtype, usm_type=usm_type, device=device) return c if isinstance(shape, int): @@ -35,9 +35,9 @@ def func1(a): NZ = numpy.random.rand(*shape) try: - c = func1(shape) + c = func(NZ) except Exception: - pytest.fail("Calling dpnp.empty inside dpjit failed") + pytest.fail("Calling dpnp.zeros_like inside dpjit failed") if len(c.shape) == 1: assert c.shape[0] == NZ.shape[0]