Users of the above operations will notice that the entire input A is scanned unconditionally, and the mask is applied only after the fact in GB_accum_mask. This is acknowledged in Source/select/GB_selector.c, but makes the mask on select essentially decorative. In practice, assign, apply, mxv, mxm, and eWise*` all exploit the mask to prune work, but select does not.
For our service, the tradeoff is thus this:
GrB_assign + GrB_select to achieve O(M) runtime via using O(M) memory, or
- prevent memory spikes but accept O(A) runtime via
GrB_select with a mask M
Compare with GrB_assign, which applies an operation over A restricted by mask M via iterating over mask entries and binary-searches into A. Fundamentally, I think select can do the same, something along the lines of:
- pass M into
GB_selector
- iterate over entries of M
- probe A for each masked index
- apply predicate to matched entries
- skip GB_accum_mask since the mask is already applied during selection