Repository navigation
Migrate random glue_lowering to overload where easy - #8061
Conversation
|
gpuci run tests |
|
This is not ready for review. |
Convert all the `glue_lowering` to `overload_method` that is using `compile_internal` to do basically exactly that.
glue_lowering to overload_method where easyglue_lowering to overload where easy
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Add missing functions for handling random distributions in arrays
sklam
left a comment
There was a problem hiding this comment.
The type checking is a bit too restrictive. See comment below.
| if (isinstance(ngood, types.Integer) and isinstance(nbad, types.Integer) | ||
| and isinstance(nsamples, types.Integer)): |
There was a problem hiding this comment.
This is overly restrictive because numpy is casting ngood and nbad to integers. In the old-style, the compiler auto emits the cast. You can replicate that behavior by returning 2-tuple of (sig, impl). See example at https://github.com/numba/numba/blob/main/numba/typed/dictobject.py#L728.
There was a problem hiding this comment.
example:
import numpy as np
from numba import njit
args = [
(1, 2, 3),
(10., 30., 4),
]
@njit
def foo(good, bad, sample):
return np.random.hypergeometric(good, bad, sample)
for good, bad, sample in args:
print(foo(good, bad, sample))
print(foo.py_func(good, bad, sample))Allow floating point types in hypergeometric distribution
sklam
left a comment
There was a problem hiding this comment.
For most of these three argument version, the first two argument typing doesn't match the two argument version (usually requires just types.Number). I also think you can let the two-arg version do the check by not checking in the three-arg version.
| for idx in range(out.size): | ||
| out_flat[idx] = np.random.vonmises(mu, kappa) | ||
| return out | ||
| return _impl |
Add checks for all random distributions array creation. Remove type checks for arguments in array creation functions that will be checked by the scalar versions. Also fixes bugs in several distributions.
| return out | ||
|
|
||
| elif isinstance(size, (types.UniTuple)) and isinstance(size.dtype, types.Integer): | ||
| elif isinstance(size, (types.UniTuple)) and isinstance(size.dtype, |
There was a problem hiding this comment.
| elif isinstance(size, (types.UniTuple)) and isinstance(size.dtype, | |
| elif isinstance(size, types.UniTuple) and isinstance(size.dtype, |
| @overload(np.random.triangular) | ||
| def triangular_impl(low, high, mode, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda low, high, mode, _size: np.random.triangular(low, high, |
There was a problem hiding this comment.
| return lambda low, high, mode, _size: np.random.triangular(low, high, | |
| return lambda low, high, mode, size: np.random.triangular(low, high, |
@overload requires the parameters to match exactly for the returned impl and the decorated func; otherwise you get error like:
Rejected as the implementation raised a specific error:
InternalError: Typing and implementation arguments differ in argument names.
Typing signature: (low, high, mode, size)
Implementation signature: (low, high, mode, _size)
Difference: {<Parameter "_size">, <Parameter "size">}There was a problem hiding this comment.
Also, the func(..., size=None) path is not exercised by the tests.
| @overload(np.random.gamma) | ||
| def gamma_impl(alpha, beta, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda alpha, beta, _size: np.random.gamma(alpha, beta) |
There was a problem hiding this comment.
| return lambda alpha, beta, _size: np.random.gamma(alpha, beta) | |
| return lambda alpha, beta, size: np.random.gamma(alpha, beta) |
| @overload(np.random.standard_gamma) | ||
| def standard_gamma_impl(alpha, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda alpha, _size: np.random.standard_gamma(alpha) |
There was a problem hiding this comment.
| return lambda alpha, _size: np.random.standard_gamma(alpha) | |
| return lambda alpha, size: np.random.standard_gamma(alpha) |
| @overload(np.random.beta) | ||
| def beta_impl(alpha, beta, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda alpha, beta, _size: np.random.beta(alpha, beta) |
There was a problem hiding this comment.
| return lambda alpha, beta, _size: np.random.beta(alpha, beta) | |
| return lambda alpha, beta, size: np.random.beta(alpha, beta) |
| @overload(np.random.rayleigh) | ||
| def rayleigh_impl2(mode, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda mode, _size: np.random.rayleigh(mode) |
There was a problem hiding this comment.
| return lambda mode, _size: np.random.rayleigh(mode) | |
| return lambda mode, size: np.random.rayleigh(mode) |
| @overload(np.random.standard_cauchy) | ||
| def standard_cauchy_impl(size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda p, _size: np.random.standard_cauchy(p) |
There was a problem hiding this comment.
| return lambda p, _size: np.random.standard_cauchy(p) | |
| return lambda p, size: np.random.standard_cauchy(p) |
| @overload(np.random.standard_t) | ||
| def standard_t_impl2(df, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda p, _size: np.random.standard_t(p) |
There was a problem hiding this comment.
| return lambda p, _size: np.random.standard_t(p) | |
| return lambda p, size: np.random.standard_t(p) |
| @overload(np.random.wald) | ||
| def wald_impl2(mean, scale, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda mean, scale, _size: np.random.wald(mean, scale) |
There was a problem hiding this comment.
| return lambda mean, scale, _size: np.random.wald(mean, scale) | |
| return lambda mean, scale, size: np.random.wald(mean, scale) |
| @overload(np.random.zipf) | ||
| def zipf_impl(a, size): | ||
| if isinstance(size, types.NoneType): | ||
| return lambda a, _size: np.random.zipf(a) |
There was a problem hiding this comment.
| return lambda a, _size: np.random.zipf(a) | |
| return lambda a, size: np.random.zipf(a) |
Correct parameters names to match main function's parameter names. Add checks for `size=None` to get a scalar value from random distributions (except for unmigrated ones).
The gamma distribution matches the CPython implementation, not the NumPy one, so create a special test that compares them appropriately when generating an array.
Make the logseries result be 64-bit rather than pointersized
sklam
left a comment
There was a problem hiding this comment.
these impl need to be exercised
This adds test for the remaining array implementations and also a new harness for ones that use the gamma distribution that won't match the Python NumPy version.
| np_prod = n * p | ||
| bound = min(n, np_prod + 10.0 * math.sqrt(np_prod * q + 1)) | ||
|
|
||
| finished = False |
There was a problem hiding this comment.
this variable is dead even in the old code
Include test for vonmises random array. This is another one where the CPython algorithm is used instead of the NumPy one.
Convert all the
glue_loweringtooverload_methodthat is usingcompile_internalto do basically exactly that.