Skip to content

Short-circuit repeated_fisher_yates when vec_nnz==1. #149

Description

@rileyjmurray

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;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions