Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] CPU dispatch fails with arguments that can't be coerced to an array-like object by existing utilities #5218

Closed
beckernick opened this issue Feb 8, 2023 · 0 comments · Fixed by #5236
Assignees
Labels
bug Something isn't working Cython / Python Cython or Python issue

Comments

@beckernick
Copy link
Member

beckernick commented Feb 8, 2023

CPU dispatching fails when passing arguments that can't be processed by the existing dispatch and input_utils machinery (such as scalars or Booleans)

from cuml.neighbors import NearestNeighbors
from cuml.common.device_selection import using_device_type, set_global_device_type
from sklearn.datasets import make_classification, make_regression, make_blobs

N = 10000
K = 20
C = 2

X, y = make_classification(
    n_samples=N,
    n_features=K,
    n_redundant=0,
    n_classes=C
)

with using_device_type("CPU"):
    nn = NearestNeighbors(n_neighbors=5)
    nn.fit(X,y)
    nn.kneighbors(X[:5], return_distance=True) # irrelevant whether return_distance is True (default) or False
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:227, in CumlArray.__init__(self, data, index, owner, dtype, shape, order, strides, mem_type, validate)
    226 try:
--> 227     self._array_interface = data.__cuda_array_interface__
    228     if mem_type in (None, MemoryType.mirror):

AttributeError: 'bool' object has no attribute '__cuda_array_interface__'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:233, in CumlArray.__init__(self, data, index, owner, dtype, shape, order, strides, mem_type, validate)
    232 try:
--> 233     self._array_interface = data.__array_interface__
    234     self._mem_type = MemoryType.host

AttributeError: 'bool' object has no attribute '__array_interface__'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:239, in CumlArray.__init__(self, data, index, owner, dtype, shape, order, strides, mem_type, validate)
    238 try:
--> 239     dtype = data.dtype
    240 except AttributeError:

AttributeError: 'bool' object has no attribute 'dtype'

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
Cell In[4], line 24
     22 nn = NearestNeighbors(n_neighbors=5)
     23 nn.fit(X,y)
---> 24 nn.kneighbors(X[:5], return_distance=True)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/api_decorators.py:192, in _make_decorator_function.<locals>.decorator_function.<locals>.decorator_closure.<locals>.wrapper(*args, **kwargs)
    190         ret = func(*args, **kwargs)
    191     else:
--> 192         return func(*args, **kwargs)
    194 return cm.process_return(ret)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/api_decorators.py:388, in enable_device_interop.<locals>.dispatch(self, *args, **kwargs)
    386 if hasattr(self, 'dispatch_func'):
    387     func_name = gpu_func.__name__
--> 388     return self.dispatch_func(func_name, gpu_func, *args, **kwargs)
    389 else:
    390     return gpu_func(self, *args, **kwargs)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/api_decorators.py:192, in _make_decorator_function.<locals>.decorator_function.<locals>.decorator_closure.<locals>.wrapper(*args, **kwargs)
    190         ret = func(*args, **kwargs)
    191     else:
--> 192         return func(*args, **kwargs)
    194 return cm.process_return(ret)

File base.pyx:673, in cuml.internals.base.UniversalBase.dispatch_func()

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/api_decorators.py:192, in _make_decorator_function.<locals>.decorator_function.<locals>.decorator_closure.<locals>.wrapper(*args, **kwargs)
    190         ret = func(*args, **kwargs)
    191     else:
--> 192         return func(*args, **kwargs)
    194 return cm.process_return(ret)

File base.pyx:629, in cuml.internals.base.UniversalBase.args_to_cpu()

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/contextlib.py:75, in ContextDecorator.__call__.<locals>.inner(*args, **kwds)
     72 @wraps(func)
     73 def inner(*args, **kwds):
     74     with self._recreate_cm():
---> 75         return func(*args, **kwds)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/input_utils.py:461, in input_to_host_array(X, order, deepcopy, check_dtype, convert_to_dtype, check_cols, check_rows, fail_on_order, force_contiguous, fail_on_null)
    458         X.fillna(cp.nan, inplace=True)
    459         X = X.values
--> 461 out_data = input_to_cuml_array(X,
    462                                order=order,
    463                                deepcopy=deepcopy,
    464                                check_dtype=check_dtype,
    465                                convert_to_dtype=convert_to_dtype,
    466                                check_cols=check_cols,
    467                                check_rows=check_rows,
    468                                fail_on_order=fail_on_order,
    469                                force_contiguous=force_contiguous,
    470                                convert_to_mem_type=MemoryType.host)
    472 return out_data._replace(array=out_data.array.to_output("numpy"))

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/contextlib.py:75, in ContextDecorator.__call__.<locals>.inner(*args, **kwds)
     72 @wraps(func)
     73 def inner(*args, **kwds):
     74     with self._recreate_cm():
---> 75         return func(*args, **kwds)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/input_utils.py:366, in input_to_cuml_array(X, order, deepcopy, check_dtype, convert_to_dtype, check_mem_type, convert_to_mem_type, safe_dtype_conversion, check_cols, check_rows, fail_on_order, force_contiguous)
    283 @nvtx_annotate(message="common.input_utils.input_to_cuml_array",
    284                category="utils", domain="cuml_python")
    285 def input_to_cuml_array(X,
   (...)
    295                         fail_on_order=False,
    296                         force_contiguous=True):
    297     """
    298     Convert input X to CumlArray.
    299 
   (...)
    364 
    365     """
--> 366     arr = CumlArray.from_input(
    367         X,
    368         order=order,
    369         deepcopy=deepcopy,
    370         check_dtype=check_dtype,
    371         convert_to_dtype=convert_to_dtype,
    372         check_mem_type=check_mem_type,
    373         convert_to_mem_type=convert_to_mem_type,
    374         safe_dtype_conversion=safe_dtype_conversion,
    375         check_cols=check_cols,
    376         check_rows=check_rows,
    377         fail_on_order=fail_on_order,
    378         force_contiguous=force_contiguous
    379     )
    380     try:
    381         shape = arr.__cuda_array_interface__['shape']

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/memory_utils.py:85, in with_cupy_rmm.<locals>.cupy_rmm_wrapper(*args, **kwargs)
     83 if GPU_ENABLED:
     84     with cupy_using_allocator(rmm_cupy_allocator):
---> 85         return func(*args, **kwargs)
     86 return func(*args, **kwargs)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/contextlib.py:75, in ContextDecorator.__call__.<locals>.inner(*args, **kwds)
     72 @wraps(func)
     73 def inner(*args, **kwds):
     74     with self._recreate_cm():
---> 75         return func(*args, **kwds)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:1070, in CumlArray.from_input(cls, X, order, deepcopy, check_dtype, convert_to_dtype, check_mem_type, convert_to_mem_type, safe_dtype_conversion, check_cols, check_rows, fail_on_order, force_contiguous)
   1067     X = X.to_cupy(copy=False)
   1069 requested_order = (order, None)[fail_on_order]
-> 1070 arr = cls(
   1071     X, index=index, order=requested_order, validate=False
   1072 )
   1073 if deepcopy:
   1074     arr = copy.deepcopy(arr)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/memory_utils.py:85, in with_cupy_rmm.<locals>.cupy_rmm_wrapper(*args, **kwargs)
     83 if GPU_ENABLED:
     84     with cupy_using_allocator(rmm_cupy_allocator):
---> 85         return func(*args, **kwargs)
     86 return func(*args, **kwargs)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/contextlib.py:75, in ContextDecorator.__call__.<locals>.inner(*args, **kwds)
     72 @wraps(func)
     73 def inner(*args, **kwds):
     74     with self._recreate_cm():
---> 75         return func(*args, **kwds)

File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:241, in CumlArray.__init__(self, data, index, owner, dtype, shape, order, strides, mem_type, validate)
    239         dtype = data.dtype
    240     except AttributeError:
--> 241         raise ValueError(
    242             'Must specify dtype when data is passed as a'
    243             ' {}'.format(type(data))
    244         )
    245 if isinstance(data, (CudfBuffer, DeviceBuffer)):
    246     self._mem_type = MemoryType.device

ValueError: Must specify dtype when data is passed as a <class 'bool'>

We fail here due essentially due to:

def args_to_cpu(self, *args, **kwargs):
# put all the args on host
new_args = tuple(input_to_host_array(arg)[0] for arg in args)
# put all the kwargs on host
new_kwargs = dict()
for kw, arg in kwargs.items():
new_kwargs[kw] = input_to_host_array(arg)[0]
return new_args, new_kwargs

from cuml.internals.input_utils import input_to_host_array # or input_to_cuml_array
input_to_host_array(True)
----------------
AttributeError                            Traceback (most recent call last)
File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:227, in CumlArray.__init__(self, data, index, owner, dtype, shape, order, strides, mem_type, validate)
    226 try:
--> 227     self._array_interface = data.__cuda_array_interface__
    228     if mem_type in (None, MemoryType.mirror):

AttributeError: 'bool' object has no attribute '__cuda_array_interface__'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:233, in CumlArray.__init__(self, data, index, owner, dtype, shape, order, strides, mem_type, validate)
    232 try:
--> 233     self._array_interface = data.__array_interface__
    234     self._mem_type = MemoryType.host

AttributeError: 'bool' object has no attribute '__array_interface__'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
File /raid/nicholasb/miniconda3/envs/rapids-23.02/lib/python3.8/site-packages/cuml/internals/array.py:239, in CumlArray.__init__(self, data, index, owner, dtype, shape, order, strides, mem_type, validate)
    238 try:
--> 239     dtype = data.dtype
    240 except AttributeError:

AttributeError: 'bool' object has no attribute 'dtype'

... same error ...

Environment: Nightly 23.02

conda list | grep "cuml\|scikit-learn\|raft"
cuml                      23.02.00a230207 cuda11_py38_gd44409910_115    rapidsai-nightly
libcuml                   23.02.00a230207 cuda11_gd44409910_115    rapidsai-nightly
libcumlprims              23.02.00a230126 cuda11_ge28945f_11    rapidsai-nightly
libraft-distance          23.02.00a230206 cuda11_gbd0d86b0_128    rapidsai-nightly
libraft-headers           23.02.00a230206 cuda11_gbd0d86b0_128    rapidsai-nightly
libraft-nn                23.02.00a230206 cuda11_gbd0d86b0_128    rapidsai-nightly
pylibraft                 23.02.00a230206 cuda11_py38_gbd0d86b0_128    rapidsai-nightly
raft-dask                 23.02.00a230206 cuda11_py38_gbd0d86b0_128    rapidsai-nightly
scikit-learn              1.2.1            py38h1e1a916_0    conda-forge
@beckernick beckernick added bug Something isn't working Cython / Python Cython or Python issue labels Feb 8, 2023
@beckernick beckernick changed the title [BUG] CPU dispatch fails with keyword arguments that can't be coerced to an array-like object by existing utilities [BUG] CPU dispatch fails with arguments that can't be coerced to an array-like object by existing utilities Feb 8, 2023
@beckernick beckernick self-assigned this Feb 9, 2023
@rapids-bot rapids-bot bot closed this as completed in #5236 Apr 3, 2023
rapids-bot bot pushed a commit that referenced this issue Apr 3, 2023
…ds during CPU dispatching (#5236)

This PR:
- Updates the CPU dispatching logic to support keyword arguments that are numeric, boolean, and strings (i.e., things that can't be coerced to cuml arrays). It doesn't support passing sequences, as I believe this use case isn't necessary
- Makes a minor update to the tests to test this dispatching in principle. We may want to expand the testing of keyword arguments in general, but as this is likely worth a broader discussion/test expansion I thought it might be out of scope for this small PR


Closes #5218

This is a replacement for #5223

Authors:
  - Nick Becker (https://github.com/beckernick)
  - Dante Gama Dessavre (https://github.com/dantegd)

Approvers:
  - Dante Gama Dessavre (https://github.com/dantegd)

URL: #5236
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Cython / Python Cython or Python issue
Projects
None yet
1 participant