Generate 64 bit randint from 32 bit rng
@@ -604,11 +604,7 @@ class RandomState(object):
If ``int``, 1-D array of length size is returned.
If ``tuple``, multi-dimensional array with shape
``size`` is returned.
- Currently, only 32 bit integers can be sampled.
- If 0 :math:`\\leq` ``mx`` :math:`\\leq` 0x7fffffff,
- a ``numpy.int32`` array is returned.
- If 0x80000000 :math:`\\leq` ``mx`` :math:`\\leq` 0xffffffff,
- a ``numpy.uint32`` array is returned.
+ Currently, only 32 bit or 64 bit integers can be sampled.
""" # NOQA
if size is None:
return self._interval(mx, 1).reshape(())
@@ -618,18 +614,18 @@ class RandomState(object):
size = (size, )
if mx == 0:
- return cupy.zeros(size, dtype=numpy.int32)
+ return cupy.zeros(size, dtype=numpy.uint32)
if mx < 0:
raise ValueError(
'mx must be non-negative (actual: {})'.format(mx))
- elif mx <= 0x7fffffff:
- dtype = numpy.int32
elif mx <= 0xffffffff:
dtype = numpy.uint32
+ elif mx <= 0xffffffffffffffff:
+ dtype = numpy.uint64
else:
raise ValueError(
- 'mx must be within uint32 range (actual: {})'.format(mx))
+ 'mx must be within uint64 range (actual: {})'.format(mx))
mask = (1 << mx.bit_length()) - 1
mask = cupy.array(mask, dtype=dtype)
@@ -640,11 +636,16 @@ class RandomState(object):
return cupy.array(())
sample = cupy.empty((n,), dtype=dtype)
+ # 32-bit RNG will be called to fill 32-bit or 64-bit `sample`
+ generate_args = (
+ self._generator,
+ sample.data.ptr,
+ sample.view(dtype=numpy.uint32).size,
+ )
n_rem = n # The number of remaining elements to sample
ret = None
while n_rem > 0:
- curand.generate(
- self._generator, sample.data.ptr, sample.size)
+ curand.generate(*generate_args)
# Drop the samples that exceed the upper limit
sample &= mask
success = sample <= mx
@@ -1118,10 +1119,6 @@ class RandomState(object):
'high is out of bounds for {}'.format(cupy.dtype(dtype).name))
diff = hi - lo - 1
- if diff > cupy.iinfo(cupy.int32).max - cupy.iinfo(cupy.int32).min + 1:
- raise NotImplementedError(
- 'Sampling from a range whose extent is larger than int32 '
- 'range is currently not supported')
x = self._interval(diff, size).astype(dtype, copy=False)
cupy.add(x, lo, out=x)
return x
