This PR contains a complete rewrite of RandBLAS' API. The important functionality is declared in three headers: base.hh, sparse.hh, and dense.hh, which define functionality in the RandBLAS::base, RandBLAS::sparse, and RandBLAS::dense namespaces. Here's a breakdown of what can be found in each of these headers
RandBLAS/include/base.hh
This defines functionality for the counter-based random number generators (CBRNGs) that RandBLAS uses for basic random number generation.
The state of a CBRNG is specified by a "counter" and a "key". Conceptually these can be thought of as 128-bit or 256-bit integers. The key specifies the stream of numbers that a CBRNG will produce. One accesses random numbers within the stream by specifying the value of the counter.
From an implementation standpoint, there is a bit of complexity in representing counters and keys. This is because the 128-bit / 256-bit integers will actually be represented by arrays of simpler numeric types. The functionality defined in this header file tries to hide that complexity. It also hides the fact that we're relying on Random123 for implementation of our CBRNGs.
Important definitions
RNGName is a character-based enumeration used to specify the type of CBRNG.
RNGName::Philox is associated with theRandBLAS::base::Philox CBRNG (which is just an alias of r123::Philox4x32.
RNGName::Threefry is associated with the RandBLAS::blase::Threefry CBRNG (which is just an alias of r123::Threefry4x32).
RNGState is a type of struct for carrying counters, keys, and an RNGName.
These structs appear in the public API.
Users should construct RNGState structs by specifying a 32-bit or 64-bit unsigned integer for the counter and a 32-bit unsigned integer for the key.
Random123_RNGState<T_gen> is a type of struct that carries counters and keys for the CBRNG T_gen.
The counters and keys are not "just" arrays of unsigned 32-bit ints; they're Random123-specific data structures.
This is an implementation artifact and not part of the public API.
RandBLAS/include/sparse.hh
This defines the API for constructing and using sparse sketching operators. The function lskges reads as "left-sketch a general matrix, with a sparse sketching operator". Important definitions are below.
SparseDistName is a character-based enumeration that specifies qualitative information in a sparse sketching operator. It's used to indicate whether one wants to work with "short-axis-sparse operators" (SASOs) or "long-axis-sparse operators" (LASOs), in the sense of the RandLAPACK book. Right now, sparse.cc only implements SASOs, and the SASOs must have more columns than rows. Note that any sketching operator with more columns than rows can only be used to sketch from the left.
SparseDist is a type of struct that specifies the distribution over sparse sketching operators. SparseDist.family specifies whether we're working with SASOs or LASOs, while SparseDist.n_rows and SparseDist.n_col specify the dimensions of the sketching operator. SparseDist.vec_nnz is the number of nonzeros in each short-axis vector (for SASOs) or long-axis vector (for LASOs).
SparseSkOp is a type of struct for representing a specific sparse sketching operator. The distribution from which the sketching operator is sampled is specified in SparseSkOp.dist. The state of the CBRNG used to define the sketching operator is given in SparseSkOp.seed_state. After a program defines a SparseSkOp object S, the next time it needs to seed a CBRNG it should do so with S.next_state.
RandBLAS/include/dense.hh
This defines the API for constructing and using dense sketching operators. The function lskge3 reads as "left-sketch a general matrix, with a BLAS 3 operation". This header file defines similar enumerations and structs as sparse.hh. Differences are highlighted below.
DenseDistName is a character-based enumeration analogous to SparseDistName. The options are ...
Gaussian,
Uniform (uniform over [-1, 1]),
Rademacher (uniform over {+1, -1}),
Haar (uniform over row-orthonormal or column-orthonormal matrices), and
DisjointIntervals (uniform over $[-2, -1] \cup [1, 2]$).
Of these, only Gaussian and Uniform are implemented.
DenseDist is a type of struct that's analogous to SparseDist. The only difference between these two structs is that the former lacks the .vec_nnz field of the latter.
DenseSkOp is a type of struct that's analogous to SparseSkOp. One difference is that it features an attribute DenseDist.layout which says whether the buffer that represents a sketching operator should be interpreted in row-major or column-major order. Implementations in dense.cc also allow lazy instantiation of the memory that's needed for a DenseSkOp object. The behavior of lazy memory allocation or lazy random number generation are governed by DenseSkOp.filled, DenseSkOp.persistent, and DenseSkOp.buff.
This PR contains a complete rewrite of RandBLAS' API. The important functionality is declared in three headers:
base.hh
,sparse.hh
, anddense.hh
, which define functionality in theRandBLAS::base
,RandBLAS::sparse
, andRandBLAS::dense
namespaces. Here's a breakdown of what can be found in each of these headersRandBLAS/include/base.hh
This defines functionality for the counter-based random number generators (CBRNGs) that RandBLAS uses for basic random number generation.
The state of a CBRNG is specified by a "counter" and a "key". Conceptually these can be thought of as 128-bit or 256-bit integers. The key specifies the stream of numbers that a CBRNG will produce. One accesses random numbers within the stream by specifying the value of the counter.
From an implementation standpoint, there is a bit of complexity in representing counters and keys. This is because the 128-bit / 256-bit integers will actually be represented by arrays of simpler numeric types. The functionality defined in this header file tries to hide that complexity. It also hides the fact that we're relying on Random123 for implementation of our CBRNGs.
Important definitions
RNGName
is a character-based enumeration used to specify the type of CBRNG.RNGName::Philox
is associated with theRandBLAS::base::Philox
CBRNG (which is just an alias ofr123::Philox4x32
.RNGName::Threefry
is associated with theRandBLAS::blase::Threefry
CBRNG (which is just an alias ofr123::Threefry4x32
).RNGState
is a type of struct for carrying counters, keys, and an RNGName.RNGState
structs by specifying a 32-bit or 64-bit unsigned integer for the counter and a 32-bit unsigned integer for the key.Random123_RNGState<T_gen>
is a type of struct that carries counters and keys for the CBRNGT_gen
.RandBLAS/include/sparse.hh
This defines the API for constructing and using sparse sketching operators. The function
lskges
reads as "left-sketch a general matrix, with a sparse sketching operator". Important definitions are below.SparseDistName
is a character-based enumeration that specifies qualitative information in a sparse sketching operator. It's used to indicate whether one wants to work with "short-axis-sparse operators" (SASOs) or "long-axis-sparse operators" (LASOs), in the sense of the RandLAPACK book. Right now,sparse.cc
only implements SASOs, and the SASOs must have more columns than rows. Note that any sketching operator with more columns than rows can only be used to sketch from the left.SparseDist
is a type of struct that specifies the distribution over sparse sketching operators.SparseDist.family
specifies whether we're working with SASOs or LASOs, whileSparseDist.n_rows
andSparseDist.n_col
specify the dimensions of the sketching operator.SparseDist.vec_nnz
is the number of nonzeros in each short-axis vector (for SASOs) or long-axis vector (for LASOs).SparseSkOp
is a type of struct for representing a specific sparse sketching operator. The distribution from which the sketching operator is sampled is specified inSparseSkOp.dist
. The state of the CBRNG used to define the sketching operator is given inSparseSkOp.seed_state
. After a program defines aSparseSkOp
objectS
, the next time it needs to seed a CBRNG it should do so withS.next_state
.RandBLAS/include/dense.hh
This defines the API for constructing and using dense sketching operators. The function
lskge3
reads as "left-sketch a general matrix, with a BLAS 3 operation". This header file defines similar enumerations and structs assparse.hh
. Differences are highlighted below.DenseDistName
is a character-based enumeration analogous toSparseDistName
. The options are ...Of these, only Gaussian and Uniform are implemented.
DenseDist
is a type of struct that's analogous toSparseDist
. The only difference between these two structs is that the former lacks the.vec_nnz
field of the latter.DenseSkOp
is a type of struct that's analogous toSparseSkOp
. One difference is that it features an attributeDenseDist.layout
which says whether the buffer that represents a sketching operator should be interpreted in row-major or column-major order. Implementations indense.cc
also allow lazy instantiation of the memory that's needed for aDenseSkOp
object. The behavior of lazy memory allocation or lazy random number generation are governed byDenseSkOp.filled
,DenseSkOp.persistent
, andDenseSkOp.buff
.