dpctl icon indicating copy to clipboard operation
dpctl copied to clipboard

tensor.clip throws ValueError on input generated by array API test

Open oleksandr-pavlyk opened this issue 1 year ago • 2 comments

The input is

import dpctl.tensor as dpt
val = dpt.zeros(2, dtype="u1")
max = dpt.zeros(tuple(), dtype="i1")
dpt.clip(val, min=None, max=max)

Raises ValueError: function 'clip' does not support input types (uint8, int8), and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''..

This causes failure in array_api_tests/test_operators_and_elementwise_functions.py::test_clip.

The issue is to investigate the failure and either fix or file an issue with array_api_tests

oleksandr-pavlyk avatar Jul 19 '24 02:07 oleksandr-pavlyk

It is tough to say what the correct behavior should be with this edge case.

The array API demands output array has the same dtype as input. It could be possible to implement something like comparisons for unsigned and signed integer.

But Numpy does not permit this case either (when restricting out dtype to input dtype).

Numpy also has an open issue on the topic of not permitting promotion in the output like array API encourages https://github.com/numpy/numpy/issues/24976

Whatever decision dpctl makes, I feel that this test should be filed as an issue with array_api_tests regardless. Per the spec:

If x and either min or max have different data type kinds (e.g., integer versus floating-point), behavior is unspecified and thus implementation-dependent.

uint and int are different kinds, and therefore, this is an unspecified case.

ndgrigorian avatar Jul 19 '24 08:07 ndgrigorian

It seems the issue is also present when inputs are of the same kind:

dpctl.__version__
# Out: '0.19.0dev0+428.g94b8f841fd'

x = dpt.asarray(0, dtype=numpy.uint8)
dpt.clip(x, min=1, max=dpt.asarray([], dtype=numpy.uint16))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[9], line 1
----> 1 dpt.clip(x, min=1, max=dpt.asarray([], dtype=numpy.uint16))

File /localdisk/work/antonvol/soft/miniforge3/envs/dpnp_dev/lib/python3.11/site-packages/dpctl/tensor/_clip.py:463, in clip(x, min, max, out, order)
    455 buf1_dt, buf2_dt, res_dt = _check_clip_dtypes(
    456     x_dtype,
    457     min_dtype,
    458     max_dtype,
    459     sycl_dev,
    460 )
    462 if res_dt is None:
--> 463     raise ValueError(
    464         f"function '{clip}' does not support input types "
    465         f"({x_dtype}, {min_dtype}, {max_dtype}), "
    466         "and the inputs could not be safely coerced to any "
    467         "supported types according to the casting rule ''safe''."
    468     )
    470 orig_out = out
    471 if out is not None:

ValueError: function '<function clip at 0x7f434a032ac0>' does not support input types (uint8, uint16, uint16), and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''.

While the above example works in numpy:

numpy.__version__
# Out: '2.2.1'

x = numpy.asarray(0, dtype=numpy.uint8)
numpy.clip(x, min=1, max=numpy.asarray([], dtype=numpy.uint16))
# Out: array([], dtype=uint16)

antonwolfy avatar Jan 14 '25 20:01 antonwolfy

Issue related to previous comment open with array API https://github.com/data-apis/array-api-tests/issues/359

ndgrigorian avatar Apr 08 '25 06:04 ndgrigorian

PR in array API tests is open that will resolve this issue https://github.com/data-apis/array-api-tests/pull/360

ndgrigorian avatar Apr 10 '25 01:04 ndgrigorian

Array API tests PR is merged, closing as completed

ndgrigorian avatar Apr 15 '25 21:04 ndgrigorian