pf_random_fill_streams Interface

public interface pf_random_fill_streams

Fills v with ONE draw of each of size(v) consecutive streams, starting at stream i0.

The other axis. Where pf_random_fill_draws fixes the stream and walks the draws, this fixes the draw and walks the streams -- so it is the bulk form of the loop this module's own documentation opens with, x(i) = pf_random_at(seed, i). Element k is exactly pf_random_at(seed, i0 + k - 1 [, draw]), so the two forms are interchangeable and a prefix is a prefix.

v is a rank-1 real(real64) or real(real32) array, intent(out); i0 is integer(int32) or integer(int64); seed and draw are integer(int64), and draw (default 1) is which draw of every one of those streams to take. A zero-sized v is a defined no-op.

Precondition, on the STREAM axis this time: i0 + size(v) - 1 must not exceed huge(int64). Same reasoning as the draw-axis fill's own precondition -- the last element's stream has to be nameable. Note i0 may be negative, and usually the whole range is nowhere near the boundary.

It cannot be as cheap per value as pf_random_fill_draws, and that is the contract rather than the implementation. Each stream needs its own block, and one real64 value consumes two of that block's four words -- the other two belong to draw 2 of the same stream, which this call is not asking for. A real32 value consumes one of four. So where the draw-axis fill amortises one enciphering over two (or four) values, this one enciphers per value and wins only by removing the per-element call. Measured on machine B against the scalar loop it replaces: 1.28x on gfortran and 1.48x on ifx for real64, 1.47x and 1.60x for real32. When several values per stream are wanted, pf_random_fill_draws remains much the cheaper shape.

An INTEGER v takes two further required arguments, lo and hi, which share v's kind -- call pf_random_fill_streams(seed, i0, v, lo, hi [, draw]). Element k is exactly pf_random_int_at(seed, i0+k-1, lo, hi [, draw]). This axis was already one enciphering per value for the real kinds, so unlike the draw-axis integer form there is nothing given up here at all: it is the same work with the per-element call removed.


Module Procedures

private pure subroutine pf_random_fill_streams_r64_i32(seed, i0, v, draw)

pf_random_fill_streams filling real64 from an integer(int32) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int32), intent(in) :: i0

first stream index; sign-extends, so any value is valid

real(kind=real64), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1

private pure subroutine pf_random_fill_streams_r64_i64(seed, i0, v, draw)

pf_random_fill_streams filling real64 from an integer(int64) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int64), intent(in) :: i0

first stream index; every value is valid

real(kind=real64), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1

private pure subroutine pf_random_fill_streams_r32_i32(seed, i0, v, draw)

pf_random_fill_streams filling real32 from an integer(int32) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int32), intent(in) :: i0

first stream index; sign-extends, so any value is valid

real(kind=real32), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1

private pure subroutine pf_random_fill_streams_r32_i64(seed, i0, v, draw)

pf_random_fill_streams filling real32 from an integer(int64) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int64), intent(in) :: i0

first stream index; every value is valid

real(kind=real32), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1

private pure subroutine pf_random_fill_streams_i32_i32(seed, i0, v, lo, hi, draw)

pf_random_fill_streams filling integer(int32) from an integer(int32) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int32), intent(in) :: i0

first stream index; sign-extends, so any value is valid

integer(kind=int32), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int32), intent(in) :: lo

one end of the closed range

integer(kind=int32), intent(in) :: hi

the other end; lo > hi is swapped, not an error

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1

private pure subroutine pf_random_fill_streams_i32_i64(seed, i0, v, lo, hi, draw)

pf_random_fill_streams filling integer(int32) from an integer(int64) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int64), intent(in) :: i0

first stream index; every value is valid

integer(kind=int32), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int32), intent(in) :: lo

one end of the closed range

integer(kind=int32), intent(in) :: hi

the other end; lo > hi is swapped, not an error

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1

private pure subroutine pf_random_fill_streams_i64_i32(seed, i0, v, lo, hi, draw)

pf_random_fill_streams filling integer(int64) from an integer(int32) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int32), intent(in) :: i0

first stream index; sign-extends, so any value is valid

integer(kind=int64), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int64), intent(in) :: lo

one end of the closed range

integer(kind=int64), intent(in) :: hi

the other end; lo > hi is swapped, not an error

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1

private pure subroutine pf_random_fill_streams_i64_i64(seed, i0, v, lo, hi, draw)

pf_random_fill_streams filling integer(int64) from an integer(int64) first stream index.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: seed

the stream family's seed

integer(kind=int64), intent(in) :: i0

first stream index; every value is valid

integer(kind=int64), intent(out) :: v(:)

filled from streams i0 .. i0+size(v)-1

integer(kind=int64), intent(in) :: lo

one end of the closed range

integer(kind=int64), intent(in) :: hi

the other end; lo > hi is swapped, not an error

integer(kind=int64), intent(in), optional :: draw

which draw of each stream; absent means 1