diff --git a/include/graphblas/descriptors.hpp b/include/graphblas/descriptors.hpp index ea2331f6c..1fe3f9836 100644 --- a/include/graphblas/descriptors.hpp +++ b/include/graphblas/descriptors.hpp @@ -24,21 +24,31 @@ * @date 15 March, 2016 */ -#include -#include - #ifndef _H_GRB_DESCRIPTOR #define _H_GRB_DESCRIPTOR +#include + + namespace grb { /** * Descriptors indicate pre- or post-processing for some or all of the - * arguments to a GraphBLAS call. + * arguments to an ALP/GraphBLAS call. An example is to transpose the input + * matrix during a sparse matrix--vector multiplication: + * grb::mxv< grb::descriptors::transpose_matrix >( y, A, x, ring ); + * the above thus computes \f$ y \to y + A^Tx \f$ and not \f$ y \to y + Ax \f$. + * + * Such pre-processing often happens on-the-fly, without significant overhead + * to the primitive costings in any of its cost dimensions -- work, intra- and + * inter-process data movement, synchronisations, and memory usage. * - * They can be combined using bit-wise operators. For instance, to both - * indicate the matrix needs be transposed and the mask needs be - * inverted, the following descriptor can be passed: + * \note If the application of a descriptor is \em not without significant + * overhead, a backend \em must clearly indicate so. + * + * Descriptors may be combined using bit-wise operators. For instance, to both + * indicate the matrix needs be transposed and the mask needs be inverted, the + * following descriptor can be passed: * transpose_matrix | invert_mask */ typedef unsigned int Descriptor; @@ -107,9 +117,31 @@ namespace grb { static constexpr Descriptor structural_complement = structural | invert_mask; /** - * Indicates all vectors used in a computation are dense. This is a hint that - * might affect performance but will never affect the semantics of the - * computation. + * Indicates that all input vectors to an ALP/GraphBLAS primitive are + * structurally dense. + * + * If a user passes this descriptor but one or more vectors input to the call + * are \em not structurally dense, then #ILLEGAL shall be returned. + * + * \warning All vectors includes any vectors that operate as masks. + * Thus if the primitive is to operate with structurally sparse masks + * but with otherwise dense vectors, then the dense descriptor may + * \em not be defined. + * + * \warning For in-place operations with vector outputs --which are all + * ALP/GraphBLAS primitives with vector outputs except grb::set and + * grb::eWiseApply-- the output vector is also an input vector. Thus + * passing this descriptor to such primitive indicates that also the + * output vector is structurally dense. + * + * \warning Vectors with explicit zeroes (under the semiring passed to the + * related primitive) will be computed with explicitly. + * + * The benefits of using this descriptor whenever possible are two-fold: + * 1) less run-time overhead as code handling sparsity is disabled; + * 2) smaller binary sizes as code handling structurally sparse vectors is + * not emitted (unless required elsewhere). + * The consistent use of this descriptor is hence strongly encouraged. */ static constexpr Descriptor dense = 16; diff --git a/src/graphblas/descriptors.cpp b/src/graphblas/descriptors.cpp index 0dfcf29b3..60e5db4f9 100644 --- a/src/graphblas/descriptors.cpp +++ b/src/graphblas/descriptors.cpp @@ -17,6 +17,9 @@ #include +#include + + std::string grb::descriptors::toString( const grb::Descriptor descr ) { std::ostringstream os; if( descr == 0 ) { @@ -36,23 +39,22 @@ std::string grb::descriptors::toString( const grb::Descriptor descr ) { os << " mask must be interpreted structurally, and not by value\n"; } if( descr & dense ) { - os << " user guarantees all vectors in this call are dense\n"; + os << " user guarantees that all input vectors to this call are dense\n"; } if( descr & add_identity ) { os << " an identity matrix is added to the input matrix\n"; } if( descr & use_index ) { - os << " instead of using input vector elements, use their index " - "instead\n"; + os << " instead of using input vector elements, use their index instead\n"; } if( descr & explicit_zero ) { os << " the operation should take zeroes into account explicitly " "when computing output\n"; } if( descr & no_casting ) { - os << " disallow casting between types during the requested " - "computation\n"; + os << " disallow casting between types during the requested computation\n"; } } return os.str(); } +