Repository: nv-legate/cunumeric

Issue:
num.bincount() run aborted when input array is not 1-dimensional

```
size = (2,) * 3
arr = num.random.randint(0, high=9, size=size)
num.bincount(arr)
```

Numpy raises :
ValueError: object too deep for desired array

cuNumeric run ：
` tests/integration/test_bincount.py::test_array_ndim legion_python: /opt/conda/envs/legate/include/legion/legion_domain.inl:942: Legion::Rect<DIM, T> Legion::Domain::bounds() const [with int DIM = 1; T = long long int; Legion::Rect<DIM, T> = Realm::Rect<1, long long int>]: Assertion `DIM == dim' failed.
   Fatal Python error: Aborted
   
   Thread 0x00007fbd52732000 (most recent call first):
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/runner.py", line 349 in from_call
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/runner.py", line 259 in call_runtest_hook
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/runner.py", line 221 in call_and_report
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/runner.py", line 131 in runtestprotocol
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/runner.py", line 112 in pytest_runtest_protocol
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/main.py", line 349 in pytest_runtestloop
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/main.py", line 324 in _main
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/main.py", line 270 in wrap_session
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/main.py", line 317 in pytest_cmdline_main
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/_pytest/config/__init__.py", line 167 in main
     File "/legate/test/tests/integration/test_bincount.py", line 108 in <module>
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/legion_top.py", line 255 in run_path
     File "/opt/conda/envs/legate/lib/python3.9/site-packages/legion_top.py", line 446 in legion_python_main
   [0 - 7fbd62ef1000]    0.000099 {4}{threads}: reservation ('Python-1 proc 1d00000000000003') cannot be satisfied
   Signal 6 received by node 0, process 501 (thread 7fbd52740000) - obtaining backtrace
   Signal 6 received by process 501 (thread 7fbd52740000) at: stack trace: 15 frames
     [0] = /usr/lib/x86_64-linux-gnu/libc.so.6(+0x43090) [0x7fbd64b4c090]
     [1] = /usr/lib/x86_64-linux-gnu/libc.so.6(gsignal+0xcb) [0x7fbd64b4c00b]
     [2] = /usr/lib/x86_64-linux-gnu/libc.so.6(+0x43090) [0x7fbd64b4c090]
     [3] = /usr/lib/x86_64-linux-gnu/libc.so.6(gsignal+0xcb) [0x7fbd64b4c00b]
     [4] = /usr/lib/x86_64-linux-gnu/libc.so.6(abort+0x12b) [0x7fbd64b2b859]
     [5] = /usr/lib/x86_64-linux-gnu/libc.so.6(+0x22729) [0x7fbd64b2b729]
     [6] = /usr/lib/x86_64-linux-gnu/libc.so.6(+0x33fd6) [0x7fbd64b3cfd6]
     [7] = /opt/conda/envs/legate/lib/libcunumeric.so(+0x26b74e) [0x7fbbfa1e974e]
     [8] = /opt/conda/envs/legate/lib/libcunumeric.so(cunumeric::BincountTask::cpu_variant(legate::TaskContext&)+0x158) [0x7fbbfaa48028]
     [9] = /opt/conda/envs/legate/lib/libcunumeric.so(void legate::LegateTask<cunumeric::BincountTask>::legate_task_wrapper<&cunumeric::BincountTask::cpu_variant>(void const*, unsigned long, void const*, unsigned long, Realm::Processor)+0xab) [0x7fbbfaa4a20b]
     [10] = /opt/conda/envs/legate/bin/../lib/librealm.so.1(+0x4c9f61) [0x7fbd65394f61]
     [11] = /opt/conda/envs/legate/bin/../lib/librealm.so.1(+0x4c9ff6) [0x7fbd65394ff6]
     [12] = /opt/conda/envs/legate/bin/../lib/librealm.so.1(+0x4ccbda) [0x7fbd65397bda]
     [13] = /opt/conda/envs/legate/bin/../lib/librealm.so.1(+0x4d1857) [0x7fbd6539c857]
     [14] = /usr/lib/x86_64-linux-gnu/libc.so.6(+0x5b4e0) [0x7fbd64b644e0]
   FAILED               [ 18%]
   tests/integration/test_bincount.py::test_bincount_basic[0-int64] 
`


Discussion:

Resolving patch:
diff --git a/cunumeric/module.py b/cunumeric/module.py
--- a/cunumeric/module.py
+++ b/cunumeric/module.py
@@ -6246,6 +6246,8 @@ def bincount(
     --------
     Multiple GPUs, Multiple CPUs
     """
+    if x.ndim != 1:
+        raise ValueError("the input array must be 1-dimensional")
     if weights is not None:
         if weights.shape != x.shape:
             raise ValueError("weights array must be same shape for bincount")
@@ -6253,11 +6255,16 @@ def bincount(
             raise ValueError("weights must be convertible to float64")
         # Make sure the weights are float64
         weights = weights.astype(np.float64)
-    if x.dtype.kind != "i" and x.dtype.kind != "u":
+    if x.dtype.kind != "i":
         raise TypeError("input array for bincount must be integer type")
     if minlength < 0:
         raise ValueError("'minlength' must not be negative")
-    minlength = _builtin_max(minlength, int(amax(x)) + 1)
+    # Note that the following are non-blocking operations,
+    # though passing their results to `int` is blocking
+    max_val, min_val = amax(x), amin(x)
+    if int(min_val) < 0:
+        raise ValueError("the input array must have no negative elements")
+    minlength = _builtin_max(minlength, int(max_val) + 1)
     if x.size == 1:
         # Handle the special case of 0-D array
         if weights is None:


Test patch: