Skip to content

Commit

Permalink
Random module documentation updates (chapel-lang#24545)
Browse files Browse the repository at this point in the history
Get Random module docs up to date to reflect changes over the last two
release cycles.

- [x] inspected docs

[ reviewed by @benharsh ] - thanks!
  • Loading branch information
jeremiah-corrado authored Mar 12, 2024
2 parents 148c8b6 + 7c27f80 commit 0e44231
Showing 1 changed file with 71 additions and 73 deletions.
144 changes: 71 additions & 73 deletions modules/standard/Random.chpl
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,27 @@
/*
Support for pseudorandom number generation.
This module defines a :record:`randomStream` type (based upon the PCG
algorithm) that can be used to generate pseudorandom numbers in parallel.
The ``randomStream`` type can be used to generate individual random numbers
via :proc:`randomStream.getNext` or to fill an array with random numbers via
:proc:`randomStream.fill`. There are also several other methods available
for manipulating arrays, parallel iteration, or adjusting the stream's
position.
This module provides the :record:`randomStream` type that represents a
conceptual stream of random numbers of a particular scalar type. Individual
numbers can be generated with :proc:`randomStream.next`, or an iterable
sequence of numbers can be generated by providing a domain argument to
``next``. The stream's position in its sequence can be updated with
:proc:`randomStream.skipTo`. Additionally, there are several methods for
generating random numbers from arrays, domains, and ranges.
This module contains a few top-level procedures that can be used for
manipulating arrays:
This module also contains a few top-level procedures for doing common tasks
with pseudorandom numbers:
* :proc:`fillRandom` fills an array with random numbers in parallel
* :proc:`shuffle` randomly re-arranges the elements of an array
* :proc:`permute` creates a random permutation of an array's domain
* :proc:`permute` create a random permutation of an array, domain, or range
* :proc:`choose` randomly selects an element from an array, domain, or range
* :proc:`sample` randomly samples elements from an array, domain, or range
These procedures will create a temporary ``randomStream`` and then call the
corresponding method on it. For repeated use of one or more of the above
operations, it is recommended to create a :record:``randomStream`` and call
the relevant method on it repeatedly.
Seed Generation
---------------
Expand All @@ -47,38 +54,18 @@
implementation specific manner which is designed to minimize the chance
that two distinct ``randomStream``'s will have the same seed.
Prior to Chapel 1.33, seed values could be generated with the now
deprecated ``RandomSupport.SeedGenerator`` type. For a non-deprecated
replacement, see :proc:`~NPBRandom.oddTimeSeed`. Note that the
``NPBRandom`` module is not stable.
Note About Deprecations and Future Work
---------------------------------------
Before Chapel 1.33, this module was unstable. It defined an abstract
random stream interface (:class:`RandomStreamInterface`) and two
implementations of that interface (based on the PCG and NPB algorithms).
As of Chapel 1.33, this module is partially stable and defines a single
:record:`randomStream` type that is based on the PCG algorithm. The
NPB algorithm is still available via the :mod:`NPBRandom` package module.
The ``RandomStreamInterface`` is now deprecated.
Various symbols used to switch between the two algorithms have also been
deprecated. These include:
* :proc:`createRandomStream`
* :type:`RNG`
* :param:`defaultRNG`
* :type:`RandomStream`
* overloads of the top-level methods that accept an ``algorithm`` argument
Future Work
-----------
In a future release, we intend to use Chapel's interface features to
define one or more interfaces for random streams. At that point, the
:record:`randomStream` type will be an implementation of the interface(s)
for generating a seedable stream of random numbers.
We'd also like to experiment with adding a thread-safe and type-agnostic
random number generator that can be used as a "global" random number
generator.
*/
module Random {

Expand Down Expand Up @@ -674,46 +661,56 @@ module Random {
number of the specified type. This allows for the generation of random
numbers in parallel, where each task involved in the parallel iteration can
request random numbers within a particular range and traverse that range of
the sequence independently of other tasks (see :proc:`randomStream.iterate`
(*unstable*)).
the sequence independently of other tasks (see :proc:`randomStream.next`).
Although parallel iteration is supported, the type itself is not
thread-safe. In particular, it is not safe to call methods such as
:proc:`next` or :proc:`fill` on the same ``randomStream`` from multiple
tasks concurrently. When multiple tasks need to generate random numbers
concurrently, a couple of approaches can be taken (other than using a
parallel safe lock to protect the ``randomStream``):
* Use the randomStream's parallel iteration methods:
Although parallel iteration is supported via the ``iterate`` method, the
type itself is not thread-safe. In particular, it is not safe to call
methods such as ``getNext`` or ``fill`` on a ``randomStream`` from multiple
tasks concurrently.
.. code-block:: chapel
Several high-level methods are provided to generate random numbers or
var A: [1..n] int;
var rs = new randomStream(int);
forall (r, a) in zip(rs.next(A.domain), A) do a = r;
* Create a random stream for each task using task-private variables:
.. code-block:: chapel
var A: [1..n] int;
forall a in A with (var rs = new randomStream(int)) do a = rs.next();
The ``randomStream`` provides several methods to generate random numbers or
to manipulate arrays using random numbers:
* :proc:`randomStream.fill` to fill an array with random numbers
* :proc:`randomStream.shuffle` to randomly re-arrange the elements of an
array
* :proc:`randomStream.permute` to create a random permutation of
an arrays domain, and store it in the array
* :proc:`randomStream.choice` to randomly sample from an array or
range (*unstable*)
Note that these methods have top-level counterparts that will internally
create a ``randomStream`` and then call the corresponding method on it —
convenient for one-off uses. To generate many random numbers, it is
* :proc:`randomStream.fill`: fill an array with random numbers
* :proc:`randomStream.shuffle`: randomly re-arrange the elements of
an array
* :proc:`randomStream.permute`: create a random permutation of an
array, domain, or range
* :proc:`randomStream.choose` randomly sample an element from an array,
domain or range
* :proc:`randomStream.sample` randomly sample elements from an array,
domain, or range (with or without replacement)
Note that the module provides top-level counterparts to these methods that
internally create a ``randomStream`` and then call the corresponding method
on it — convenient for one-off uses. To generate many random numbers, it is
generally more efficient to create a ``randomStream`` and call the relevant
method on it repeatedly.
An individual random number can be requested using :proc:`randomStream.getNext`
which will advance the stream to the next position and return the value at
that position. The position of the stream can also be manipulated using:
* :proc:`randomStream.skipToNth` to skip to a particular position in the
stream (*unstable*)
* :proc:`randomStream.getNth` to skip to a particular position in the
stream and return the value at that position (*unstable*)
A ``randomStream`` can be initialized with a user-provided seed value. Two
``randomStream`` instances initialized with the same seed will produce
identical sequences of random numbers. When not provided explicitly, a seed
value will be generated in an implementation specific manner designed to
minimize the chance that two distinct instances of the ``randomStream``
will have the same seed.
An individual random number can be generated using
:proc:`randomStream.next` which will advance the stream to the next
position and return the value at that position. The position of the stream
can also be manipulated directly using :proc:`randomStream.skipTo`.
When copied, the ``randomStream``'s seed, state, and position in the stream
will also be copied. This means that the copy and original will produce the
Expand Down Expand Up @@ -842,17 +839,18 @@ module Random {
}

/*
Fill the array with pseudorandom values sampled from this stream.
Fill the array with pseudorandom values sampled from this stream in
parallel.
:arg arr: The rectangular array to be filled
*/
proc ref fill(ref arr: []) where arr.isRectangular() do
this.pcg.fillRandom(arr);

/*
Fill the array with pseudorandom values within a particular range. Each
array element is set to a number in [``min``, ``max``] (inclusive)
sampled from this stream.
Fill the array with pseudorandom values within a particular range in
parallel. Each array element is set to a number in [``min``, ``max``]
(inclusive) sampled from this stream.
:arg arr: The rectangular array to be filled
:arg min: The minimum value to sample
Expand Down

0 comments on commit 0e44231

Please sign in to comment.