DrTimothyAldenDavis / GraphBLAS

SuiteSparse:GraphBLAS: graph algorithms in the language of linear algebra. For production: (default) STABLE branch. Code development: ask me for the right branch before submitting a PR. video intro: https://youtu.be/Tj5y6d7FegI .
http://faculty.cse.tamu.edu/davis/GraphBLAS.html
Other
359 stars 63 forks source link

Best Way to Construct GrB_Vector of all Trues but a Few Falses #4

Closed victorstewart closed 4 years ago

victorstewart commented 4 years ago

I'm constructing a mask, and I have a list of GrB_Index that specifies which indexes are to be made false, but all the rest I want true (so I can probe them in the matrix).

I wanted to just use GrB_assign to set all the values to true, and then use GrB_Vector_build to feed in tuples of the indexes I want set to False... but obviously we aren't allowed to build on the GrB_Vector if it is nonempty.

So what's the most efficient way to accomplish this?

GrB_Info batch(GrB_Matrix A, GrB_Index src, GrB_Index *dests, GrB_Index destsCount)
{
    GrB_Index n;
    GrB_Matrix_nrows(&n, A);             

    GrB_Index *destsValues;
    destsValues = malloc(destsCount * sizeof(GrB_Index));
    memset(destsValues, 0, destsCount * sizeof(GrB_Index));

    GrB_Vector mask;                                
    GrB_Vector_new(&mask, GrB_BOOL, n);             
    GrB_assign(mask, NULL, GrB_NULL, true, GrB_ALL, n, GrB_NULL);
    GrB_Vector_build(mask, dests, destsValues, destsCount, GrB_LOR);

    // etc...
}
DrTimothyAldenDavis commented 4 years ago

If you want to create a mask vector that is mostly true, and use it as a mask in a subsequent GrB operation, like GrB_whatever (C, mask, ...), then it would be better to use a complemented mask. Set the mask to be true according to the list you have. Then when you use the mask, use a complemented descriptor.

victorstewart commented 4 years ago

Okay is that way more efficient than say building a mostly false with GrB_Vector_build then using GrB_Vector_apply with GrB_LNOT to make it mostly true? If GrB_Vector maintains its sparsity throughout these operations then surely.

DrTimothyAldenDavis commented 4 years ago

I'm unsure what you mean by a "mostly false" mask. Do you mean very sparse? Do you mean all entries present but mostly equal to false? Those are very different.

GrB_Vector_apply will preserve the sparsity pattern. There are 3 states to consider: entry present and true, entry present and false, entry not present.

If a mask is used as a valued-mask (not structural) and not complemented, then "entry present and true" says the entry C for GrB_whatever (C,mask, ...) can be modified.

If a mask is used as a structural mask and not complemented, then the values are ignored, just if the entry is present. So C(i) is modified if mask(i) is present. GrB_Vector apply to negate the entries has no effect.

If the mask descriptor is complemented, then negate those statements above, that is "C(i) is modified" becomes "C(i) is not modified".

victorstewart commented 4 years ago

oh i see! I was unaware of the 3 states I thought an entry not present was equivalent to false. My first day delving into GraphBLAS.

so in the usage of GrB_vxm the mask is a valued mask not a structural one? So if a mask entry is present and true and complemented then C(i) can NOT be modified, but every other entry in C can be modified. And if the mask entry is present and true and NOT complemented then the corresponding C(i) entries are the only ones that can be modified?

and generally which functions use values vs structural masks?

DrTimothyAldenDavis commented 4 years ago

All functions can use any option: no mask, valued mask, complemented valued mask, structural mask, complemented structural mask, and (yes) even "complemented no mask" which unusual. It does nothing, except for GrB_assign on a submatrix.