Sampling vec_nnz=1 element from an index set WITHOUT replacement is the same as sampling one element WITH replacement. Our without replacement function, repeated_fisher_yates, has a lot of overhead that's only really needed for the case vec_nnz > 1. We should modify repeated_fisher_yates so that it's more efficient in the casevec_nnz=1. This should just be a matter of calling the overload of sample_indices_iid_uniform that includes the rademachers argument:
|
state_t sample_indices_iid_uniform(int64_t n, int64_t k, sint_t* samples, T* rademachers, const state_t &state) { |
There's a slight complication where we need to update the compute_next_state function to use the appropriate analytic formula for the number of counters consumed when generating a SASO with vec_nnz=1.
|
template <typename RNG = DefaultRNG> |
|
RNGState<RNG> compute_next_state(SparseDist dist, RNGState<RNG> state) { |
|
int64_t num_mavec, incrs_per_mavec; |
|
if (dist.major_axis == Axis::Short) { |
|
num_mavec = std::max(dist.n_rows, dist.n_cols); |
|
incrs_per_mavec = dist.vec_nnz; |
|
// ^ SASOs don't try to be frugal with CBRNG increments. |
|
// See repeated_fisher_yates. |
|
} else { |
|
num_mavec = std::min(dist.n_rows, dist.n_cols); |
|
incrs_per_mavec = (int64_t) std::ceil((double) dist.vec_nnz / ((double) state.len_c/2)); |
|
// ^ LASOs do try to be frugal with CBRNG increments. |
|
// See sample_indices_iid_uniform. |
|
} |
|
int64_t full_incr = num_mavec * incrs_per_mavec; |
|
state.counter.incr(full_incr); |
|
return state; |
|
} |
This update should suffice for the SASO branch.
if (dist.vec_nnz == 1) {
incrs_per_matvec = (int64_t) std::ceil((double) dist.vec_nnz / ((double) state.len_c/2));
} else {
incrs_per_matvec = dist.vec_nnz;
}
Sampling
vec_nnz=1element from an index set WITHOUT replacement is the same as sampling one element WITH replacement. Our without replacement function, repeated_fisher_yates, has a lot of overhead that's only really needed for the casevec_nnz > 1. We should modify repeated_fisher_yates so that it's more efficient in the casevec_nnz=1. This should just be a matter of calling the overload of sample_indices_iid_uniform that includes therademachersargument:RandBLAS/RandBLAS/util.hh
Line 482 in ab55e0e
There's a slight complication where we need to update the compute_next_state function to use the appropriate analytic formula for the number of counters consumed when generating a SASO with vec_nnz=1.
RandBLAS/RandBLAS/sparse_skops.hh
Lines 266 to 283 in ab55e0e
This update should suffice for the SASO branch.