diff --git a/.github/workflows/build-spec.yml b/.github/workflows/build-spec.yml new file mode 100644 index 0000000..1e3ebf6 --- /dev/null +++ b/.github/workflows/build-spec.yml @@ -0,0 +1,47 @@ +name: Build GraphBLAS C++ Specification +on: [push] +permissions: + contents: write +jobs: + Build-GraphBLAS-Spec: + runs-on: ubuntu-latest + container: + image: benbrock/graphblas-cpp:build-docs-0.2 + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Build spec + run: | + cd $GITHUB_WORKSPACE/markdown + make + mkdir graphblas-cpp-spec + cp graphblas.pdf graphblas-cpp-spec + cp graphblas.html graphblas-cpp-spec + mkdir github-pages + cp graphblas.html github-pages/index.html + - name: Check on spec + run: ls $GITHUB_WORKSPACE/markdown + - name: Archive GraphBLAS C++ Spec + uses: actions/upload-artifact@v2 + with: + name: graphblas-cpp-spec + path: | + ${{ github.workspace }}/markdown/graphblas-cpp-spec + - name: Archive GitHub Pages + uses: actions/upload-artifact@v2 + with: + name: github-pages + path: | + ${{ github.workspace }}/markdown/github-pages + Deploy-GitHub-Pages: + needs: Build-GraphBLAS-Spec + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + if: ${{ github.ref == 'refs/heads/master' }} + steps: + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v1 diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..ffff7c4 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,4166 @@ + + + + + + + GraphBLAS C++ API Specification v1.0 + + + + + +
+

GraphBLAS C++ API Specification v1.0

+
+ +
+

Intro

+

The GraphBLAS standard defines a set of generalized matrix and vector +operations based on semiring algebraic structures. These operations can +be used to express a wide variety of graph algorithms. This +specification document defines the C++ programming interface for the +GraphBLAS standard, referred to as the . The GraphBLAS C++ API defines a +collection of data structures, algorithms, views, operators, and +concepts for implementing graph algorithms. These API components are +based around mathematical objects, such as matrices and vectors, and +operations, such as generalized matrix multiplication and element-wise +operations. The GraphBLAS Math +Specification provides a complete specification of the mechanics of +these structures and operations, and provides a rigorous mathematical +definition of the operations and data structures provided in this +specification.

+

Data Structures

+

This specification provides data structures for storing matrices and +vectors. These implement the matrix and vector range concepts also defined in this specification.

+

Matrices

+

Matrices are two-dimensional collections of sparse values. Each +matrix has a defined number of rows and columns, which define its . In +addition, each matrix has a defined number of , which are indices inside +the bounds of the matrix which actually contain scalar values. A matrix +has a fixed , which is the type of the stored values, as well as an , +which is the type of the indices.

+

GraphBLAS matrices are sparse, consist of a well-defined set of +stored values, and have no implicit zero value for empty indices. As +such, operations may not arbitrarily insert explicit zero values into +the matrix, but must produce an output with the exact set of values as +specified by the GraphBLAS Math Specification.

+

The GraphBLAS matrix data structure defined in this specification, +grb::matrix, provides mechanisms for creating, +manipulating, and iterating through GraphBLAS matrices. It also includes +a mechanism for influencing the storage format through compile-time +hints. GraphBLAS operations that accept matrices can be called with +other types so long as they fulfill the GraphBLAS matrix concepts.

+

Vectors

+

Vectors are one-dimensional collections of sparse values. Each vector +has a defined number of indices, which defines its shape. Similarly, it +has a defined number of stored stored values, which must lie at indices +within its shape. Its scalar values have a fixed scalar type, and it has +a fixed index type for storing indices. Vectors follow the same sparsity +rules as matrices, and similarly the GraphBLAS matrix concepts.

+

Concepts

+

The GraphBLAS C++ Specification defines matrix and vector concepts. +These define the interface that a type must support in order to be used +by GraphBLAS operations. The intention is that data structures defined +by other libraries may be used in GraphBLAS operations so long as they +define a small number of customization points that perform insert, find, +and iteration operations over the matrix or vector.

+

Version Conformance

+

A C++ GraphBLAS library should define the macro +GRAPHBLAS_CPP_VERSION to indicate its level of conformance +with the GraphBLAS C++ API. To indicate conformance with the GraphBLAS +0.1a draft specification, a library should provide the macro +GRAPHBLAS_CPP_VERSION with a value greater than or equal to +202207L.

+

Exposition Only

+
// Define the `GRAPHBLAS_CPP_VERSION` macro to indicate
+// conformance to the GraphBLAS 0.1 Draft Specification.
+#define GRAPHBLAS_CPP_VERSION 202207L
+

Basic Concepts

+

GraphBLAS defines a collection of objects, functions, and concepts to +facilitate the implementation of graph algorithms. These programming +facilities are further separated into GraphBLAS containers, +which include matrices and vectors, GraphBLAS operations, which +are algorithms such as matrix-vector multiplication that operate over +GraphBLAS containers, and GraphBLAS operators, which are binary +and unary operators that operate over scalar elements that may be held +in a container. The C++ API also defines a series of concepts +defining the interface a container or operator must fulfill in order to +to be used with a particular operation, as well as views, which +provide lazily evaluated, mutated views of a GraphBLAS object.

+

GraphBLAS Containers

+

GraphBLAS containers, which include matrices and vectors, are sparse +data structures holding a collection of stored scalar values. Each +GraphBLAS container has a shape, which defines the dimension(s) of the +object. Stored values can be inserted at indices within the dimensions +of the object. Since GraphBLAS containers are sparse, they keep explicit +track of which index locations in the object hold stored values. There +is no implied zero value associated with a GraphBLAS container, since +the annhilator value will change from operation to operation, and the +insertion of explicit “zeros” could cause incorrect results. As such, no +GraphBLAS operation will arbitrarily insert explicit zeros. In the +GraphBLAS C++ API, each container has associated with it a scalar type, +which is the type of the stored scalar values, as well as an index type, +which is the type used to indicate the locations of stored values, as +well as the matrix shape.

+

TODO: be more specific here. Could use some help from +math spec?

+

Matrices

+

GraphBLAS matrices are two-dimensional sparse arrays. As previously +discussed, they have a scalar type, which defines the type of scalar +values stored inside the matrix, as well as an index type, which is used +to refer to the row and column index of each stored value. For a matrix +type A, these types can be retrieved using the expression +grb::matrix_scalar_t<A> to retrieve the scalar type +and grb::matrix_index_t<A> to retrieve the index +type. In the GraphBLAS C++ API, matrices are associative arrays similar +to instantiations of std::unordered_map. They map keys, +which are row and column indices, to values, which are the stored scalar +values. Like the C++ standard library’s associative containers, +GraphBLAS matrices are ranges, and iterating through a GraphBLAS matrix +reveals a collection of tuples, with each tuple holding a key and value. +The key is a tuple-like type holding the row and column indices, and the +value is the stored scalar value. The row and column are provided only +as const references, while the value may be mutated. Matrices also +support insert, assign, and find operations to write or read to a +particular location in the matrix.

+

Vectors

+

GraphBLAS similars are analogous to matrices, except that they are +only one-dimensional sparse arrays. They hold a scalar type, which +defines the scalar values stored inside the vector, as well as an index +type, which holds the index of an element within the vector. For a +vector V, these types can be retrieved with the expressions +grb::vector_scalar_t<V> and +grb::vector_index_t<V>. Like matrices, vectors are +associative arrays, except that their key values are a single index type +element, and not a tuple. Like matrices, vectors are ranges, with the +value type being a tuple holding the index type and scalar type, with +only the scalar type being mutable if the vector is non-const. +Individual elements can be modified using insert, assign, and find.

+

grb::matrix

+
template <typename T,
+          std::integral I = std::size_t,
+          typename Hint = grb::sparse,
+          typename Allocator = std::allocator<T>>
+class grb::matrix;
+

Template Parameters

+

T - type of scalar values stored in the matrix

+

I - type, satisfying std::integral, used to +store indices in the matrix

+

Hint - one or a composition of compile-time hints that +may be used to affect the backend storage type

+

Allocator - allocator type used to allocate memory for +the matrix

+

Member Types

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Member TypeDefinition
scalar_typeT, the type of elements stored in the matrix
index_typeI, an integer type used to store matrix indices
key_typeA tuple-like type storing two index_type elements
map_typescalar_type
value_typegrb::matrix_entry<T, I>, a tuple-like type +storing the indices and the stored element
size_typeA large unsigned integer type, usually std::size_t
difference_typeA large signed integer type, usually +std::ptrdiff_t
allocator_typeAllocator
iteratorAn iterator type fulfilling std::forward_iterator
const_iteratorA const iterator fulfilling std::forward_iterator
referencegrb::matrix_reference<T, I>
const_referencegrb::matrix_reference<const T, I>
scalar_referenceReference to scalar_type
const_scalar_referenceConst reference to scalar_type
hint_typeHint
+

Methods

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodDescription
(constructor)Constructs matrix
(destructor)Destructs matrix
operator=Assigns matrix
sizeNumber of stored elements in matrix
max_sizeReturns the maximum possible number of elements
emptyReturn whether the matrix is empty
shapeReturn the dimensions of the matrix
begin
cbegin
Returns iterator to beginning of container
end
cend
Returns iterator to one past last element in container
reshapeModify dimensions of the matrix
clearClears all elements from the container
insertInsert elements
insert_or_assignInserts or assigns elements
eraseErases elements
findFinds an element
atAccess element
operator[]Access or insert element
+

grb::matrix::matrix

+
matrix(const Allocator& alloc = Allocator());    (1)
+matrix(grb::index<index_type> shape,
+       const Allocator& alloc = Allocator());    (2)
+matrix(const matrix& other);                     (3)
+matrix(matrix&& other);                          (4)
+

Constructs new grb::matrix data structure.

+
    +
  1. Constructs an empty matrix of dimension 0 x 0.
  2. +
  3. Constructs an empty matrix of dimension +shape[0] x shape[1].
  4. +
  5. Copy constructor. Constructs a matrix with the dimensions and +contents of other.
  6. +
  7. Move constructor. Constructs a matrix with the dimensions and +contents of other using move semantics. After the move, +other is guaranteed to be empty.
  8. +
+

Parameters

+

shape - shape of the matrix to be constructed

+

other - another matrix to construct the new matrix +from

+

Complexity

+
    +
  1. Constant
  2. +
  3. Implementation defined
  4. +
  5. Implementation defined
  6. +
  7. Implementation defined
  8. +
+

Exceptions

+

Calls to Allocator::allocate may throw.

+

grb::matrix::~matrix

+
~matrix();
+

Destroys the grb::matrix. The destructors of the +elements are called and storage is deallocated.

+

Complexity

+

Linear in the size of the vector.

+

grb::matrix::operator=

+
matrix& operator=(const matrix& other);          (1)
+matrix& operator=(matrix&& other);               (2)
+

Replaces the matrix with the contents and shape of another +matrix.

+
    +
  1. Copy assignment operator. Modifies the shape of the matrix to be +equal to that of other and copies the stored values to be +the same as other.
  2. +
  3. Move constructor. Replaces the contents of the matrix with those of +other using move semantics. After the move assignment +operation completes, other is in a valid but indeterminate +state.
  4. +
+

Parameters

+

other - another matrix to assign the matrix to

+

Complexity

+
    +
  1. Implementation defined
  2. +
  3. Constant
  4. +
+

Exceptions

+
    +
  1. Calls to Allocator::allocate may throw.
  2. +
+

grb::matrix::size

+
size_type size() noexcept;
+

Returns the number of elements stored in the matrix.

+

Parameters

+

(none)

+

Return value

+

Number of stored elements.

+

Complexity

+

Constant

+

grb::matrix::max_size

+
size_type max_size() const noexcept;
+

Returns the maximum possible number of elements that could be stored +in the matrix due to system or implementation limitations.

+

Parameters

+

(none)

+

Return value

+

Maximum possible number of elements.

+

Complexity

+

Constant

+

grb::matrix::empty

+
bool empty() noexcept;
+

Returns whether the matrix is empty, that is where +size() == 0.

+

Parameters

+

(none)

+

Return value

+

Whether the matrix is empty.

+

Complexity

+

Constant

+

grb::matrix::shape

+
grb::index<I> shape() const noexcept;
+

Returns the dimensions of the matrix.

+

Parameters

+

(none)

+

Return value

+

Dimensions of the matrix.

+

Complexity

+

Constant

+

grb::matrix::begin +and grb::matrix::cbegin

+
iterator begin() noexcept;
+const_iterator begin() const noexcept;
+const_iterator cbegin() const noexcept;
+

Returns an iterator to the first element of the matrix data +structure. If the matrix is empty, returns an element that compares as +equal to end().

+

Parameters

+

(none)

+

Return value

+

Iterator to the first element

+

Complexity

+

Constant

+

grb::matrix::end +and grb::matrix::cend

+
iterator end() noexcept;
+const_iterator end() const noexcept;
+const_iterator cend() const noexcept;
+

Returns an iterator to one past the last element of the matrix data +structure. This element is used only to signify the end of the +container, and accessing it has undefined behavior.

+

Parameters

+

(none)

+

Return value

+

Iterator to one past the last element.

+

Complexity

+

Constant

+

grb::matrix::reshape

+
void reshape(grb::index<I> shape) noexcept;
+

Reshape the matrix. That is, modify the matrix dimensions such that +matrix shape is now shape[0] x shape[1]. If +any nonzeros lie outside of the new matrix shape, they are removed from +the matrix

+

Parameters

+

shape - New matrix shape

+

Return value

+

None

+

Complexity

+

Implementation defined

+

Exceptions

+

Calls to Allocator::allocate may throw.

+

grb::matrix::clear

+
void clear() noexcept;
+

Clear all stored scalar values from the matrix. The matrix maintains +the same shape, but after return will now have a size of 0.

+

Complexity

+

Implementation defined

+

grb::matrix::insert

+
template <typename InputIt>
+void insert(InputIt first, InputIt last);                    (1)
+std::pair<iterator, bool> insert(const value_type& value);   (2)
+std::pair<iterator, bool> insert(value_type&& value);        (3)
+

Inserts an element or number of elements into the matrix, if the +matrix doesn’t already contain a stored element at the corresponding +index.

+
    +
  1. Insert each element in the range [first, last) if an +element does not already exist in the matrix at the corresponding index. +If multiple elements in [first, last) have the same +indices, it is undefined which element is inserted.

  2. +
  3. and (3) Insert the element value if an element does +not already exist at the corresponding index in the matrix.

  4. +
+

Parameters

+

first, last - Range of elements to +insert

+

value - element to insert

+

Return value

+
    +
  1. None

  2. +
  3. and (3) return a std::pair containing an +iterator and a bool value. The +bool value indicates whether or not the insertion was +successful. If the insertion was successful, the first value contains an +iterator to the newly inserted element. If it was unsuccessful, it +contains an iterator to the element that prevented insertion.

  4. +
+

Complexity

+

Implementation defined

+

grb::matrix::insert_or_assign

+
template <class M>
+std::pair<iterator, bool> insert_or_assign(key_type k, M&& obj);
+

Inserts an element into index k in the matrix and +assigns to the scalar value if one already exists.

+

If an element already exists at index location k, +assigns std::forward<M>(obj) to the scalar value +stored at that index. If no element exists, inserts obj at +the index as if by calling insert with +value_type(k, std::forward<M>(obj)).

+

Parameters

+

k - the index location to assign obj

+

obj - the scalar value to be assigned

+

Type Requirements

+

M must fulfill +std::is_assignable<scalar_type&, M>

+

Return Value

+

Returns an std::pair with the first element holding an +iterator to the newly inserted or assigned value and the second element +holding a bool value that is true if the +element was inserted and false otherwise.

+

Complexity

+

Implementation defined.

+

grb::matrix::erase

+
size_type erase(grb::index<I> index);
+

Erases the element stored at index index if one +exists.

+

Parameters

+

index - the index of element to erase

+

Return Value

+

Returns the number of elements erased (0 or 1).

+

Complexity

+

Implementation defined.

+

grb::matrix::find

+
iterator find(grb::index<I> index);
+const_iterator find(grb::index<I> index) const;
+

Finds the element at location (index[0], +index[1]) in the matrix, returning an iterator to the +element. If no element is present at the location, returns +end().

+

Parameters

+

index - Location of the matrix element to find

+

Return value

+

An iterator pointing to the matrix element at the corresponding +index, or end() if there is no element at the location.

+

Complexity

+

Implementation defined

+

grb::matrix::operator[]

+
scalar_reference operator[](grb::index<I> index);
+const_scalar_reference operator[](grb::index<I> index) const;
+

Returns a reference to the scalar value stored at location +(index[0], index[1]) in the matrix. If no +value is stored at the location, inserts a default constructed value at +the location and returns a reference to it.

+

Parameters

+

index - Location of the matrix element

+

Return value

+

A reference to the scalar value at location (index[0], +[index[1]).

+

Complexity

+

Implementation defined

+

grb::matrix::at

+
scalar_reference at(grb::index<I> index);
+const_scalar_reference at(grb::index<I> index) const;
+

Returns a reference to the scalar value stored at location +(index[0], index[1]) in the matrix. If no +value is stored at the location, throws the exception +grb::out_of_range.

+

Parameters

+

index - Location of the matrix element

+

Return value

+

A reference to the scalar value at location (index[0], +[index[1]).

+

Complexity

+

Implementation defined

+

Exceptions

+

If no element exists at location (index[0], +index[1]), throws the exception +grb::out_of_range.

+

grb::vector

+
template <typename T,
+          std::integral I = std::size_t,
+          typename Hint = grb::sparse,
+          typename Allocator = std::allocator<T>>
+class grb::vector;
+

Template Parameters

+

T - type of scalar values stored in the vector

+

I - type, satisfying std::integral, used to +store indices in the vector

+

Hint - one or a composition of compile-time hints that +may be used to affect the backend storage type

+

Allocator - allocator type used to allocate memory

+

Member Types

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Member TypeDefinition
scalar_typeT, the type of scalar elements stored in the +vector
index_typeI, an integer type used to store vector indices
key_typeindex_type
map_typescalar_type
value_typegrb::vector_entry<T, I>, a tuple-like type +storing the indices and the stored element
size_typeA large unsigned integer type, usually std::size_t
difference_typeA large signed integer type, usually +std::ptrdiff_t
allocator_typeAllocator
iteratorAn iterator type fulfilling std::forward_iterator
const_iteratorA const iterator fulfilling std::forward_iterator
referencegrb::vector_ref<T, I>
const_referencegrb::vector_ref<const T, I>
scalar_referenceReference to scalar_type
const_scalar_referenceConst reference to scalar_type
hint_typeHint
+

Methods

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodDescription
(constructor)Constructs vector
sizeNumber of stored elements in vector
max_sizeReturns the maximum possible number of elements
emptyReturn whether the vector is empty
shapeReturn the dimension of the vector
begin
cbegin
Returns iterator to beginning of container
end
cend
Returns iterator to one past last element in container
reshapeModify the dimension of the vector
clearClears all elements from the container
insertInsert elements
insert_or_assignInserts or assigns elements
findFinds an element
operator[]Access or insert element
+

grb::vector::vector

+
vector();                                           (1)
+vector(const Allocator& alloc);                     (2)
+vector(index_type shape);                           (3)
+vector(index_type shape, const Allocator& alloc);   (4)
+vector(const vector& other);                        (5)
+vector(vector&& other);                             (6)
+

Constructs new grb::vector data structure.

+
    +
  1. and 2) Constructs an empty vector of dimension 0.
  2. +
  3. and 4) Constructs an empty vector of dimension +shape.
  4. +
  5. Copy constructor
  6. +
  7. Move constructor
  8. +
+

Parameters

+

shape - shape of the vector to be constructed

+

Complexity

+
    +
  1. Constant
  2. +
  3. Implementation defined
  4. +
+

Exceptions

+

May throw std::bad_alloc.

+

grb::vector::size

+
size_type size() noexcept;
+

Returns the number of elements stored in the vector.

+

Parameters

+

(none)

+

Return value

+

Number of stored elements.

+

Complexity

+

Constant

+

grb::vector::max_size

+
size_type max_size() noexcept;
+

Returns the maximum possible number of elements that could be stored +in the vector due to platform or implementation limitations.

+

Parameters

+

(none)

+

Return value

+

Maximum possible number of elements.

+

Complexity

+

Constant

+

grb::vector::empty

+
bool empty() noexcept;
+

Returns whether the vector is empty, that is where +size() == 0.

+

Parameters

+

(none)

+

Return value

+

Whether the vector is empty.

+

Complexity

+

Constant

+

grb::vector::shape

+
index_type shape() const noexcept;
+

Returns the dimension of the vector.

+

Parameters

+

(none)

+

Return value

+

Dimension of the vector.

+

Complexity

+

Constant

+

grb::vector::begin +and grb::vector::cbegin

+
iterator begin() noexcept;
+const_iterator begin() const noexcept;
+const_iterator cbegin() const noexcept;
+

Returns an iterator to the first element of the vector data +structure. If the vector is empty, returns an element that compares as +equal to end().

+

Parameters

+

(none)

+

Return value

+

Iterator to the first element

+

Complexity

+

Constant

+

grb::vector::end +and grb::vector::cend

+
iterator end() noexcept;
+const_iterator end() const noexcept;
+const_iterator cend() const noexcept;
+

Returns an iterator to one past the last element of the vector data +structure. This element is used only to signify the end of the +container, and accessing it has undefined behavior.

+

Parameters

+

(none)

+

Return value

+

Iterator to one past the last element.

+

Complexity

+

Constant

+

grb::vector::reshape

+
void reshape(index_type shape);
+

Reshape the vector. That is, modify the vector dimension such that +vector is now of dimension shape. If any nonzeros lie +outside of the new vector shape, they are removed from the vector.

+

Parameters

+

shape - New vector shape

+

Return value

+

None

+

Complexity

+

Implementation defined

+

grb::vector::clear

+
void clear();
+

Clear all stored scalar values from the vector. The vector maintains +the same shape, but after return will now have a size of 0.

+

Complexity

+

Implementation defined

+

grb::vector::insert

+
template <typename InputIt>
+void insert(InputIt first, InputIt last);                    (1)
+std::pair<iterator, bool> insert(const value_type& value);   (2)
+std::pair<iterator, bool> insert(value_type&& value);        (3)
+

Inserts an element or number of elements into the vector, if the +vector doesn’t already contain a stored element at the corresponding +index.

+
    +
  1. Insert elements in the range [first, last) if an +element does not already exist in the vector at the corresponding index. +If multiple elements in [first, last) have the same +indices, it is undefined which element is inserted.

  2. +
  3. and (3) Insert the element value if an element does +not already exist at the corresponding index in the vector.

  4. +
+

Parameters

+

first, last - Range of elements to +insert

+

value - element to insert

+

Return value

+
    +
  1. None

  2. +
  3. and (3) return a std::pair containing an +iterator and a bool value. The +bool value indicates whether or not the insertion was +successful. If the insertion was successful, the first value contains an +iterator to the newly inserted element. If it was unsuccessful, it +contains an iterator to the element that prevented insertion.

  4. +
+

Complexity

+

Implementation defined

+

grb::vector::insert_or_assign

+
template <class M>
+std::pair<iterator, bool> insert_or_assign(key_type k, M&& obj);
+

Inserts an element into index k in the vector and +assigns to the scalar value if one already exists.

+

If an element already exists at index location k, +assigns std::forward<M>(obj) to the scalar value +stored at that index. If no element exists, inserts obj at +the index as if by calling insert with +value_type(k, std::forward<M>(obj)).

+

Parameters

+

k - the index location to assign obj

+

obj - the scalar value to be assigned

+

Type Requirements

+

M must fulfill +std::is_assignable<scalar_type&, M>

+

Return Value

+

Returns an std::pair with the first element holding an +iterator to the newly inserted or assigned value and the second element +holding a bool value that is true if the +element was inserted and false otherwise.

+

Complexity

+

Implementation defined.

+

grb::vector::erase

+
size_type erase(index_type index);
+

Erases the element stored at index index if one +exists.

+

Parameters

+

index - the index of the scalar value to erase

+

Return Value

+

Returns the number of elements erased (0 or 1).

+

Complexity

+

Implementation defined.

+

grb::vector::find

+
iterator find(index_type index);
+const_iterator find(index_type index) const;
+

Finds the element at location index in the vector, +returning an iterator to the element. If no element is present at the +location, returns end().

+

Parameters

+

index - Location of the vector element to find

+

Return value

+

An iterator pointing to the vector element at the corresponding +index, or end() if there is no element at the location.

+

Complexity

+

Implementation defined

+

grb::vector::operator[]

+
scalar_reference operator[](index_type index);
+const_scalar_reference operator[](index_type index) const;
+

Returns a reference to the scalar value stored at location +index in the vector. If no value is stored at the location, +inserts a default constructed value at the location and returns a +reference to it.

+

Parameters

+

index - Location of the vector element

+

Return value

+

A reference to the scalar value at location index.

+

Complexity

+

Implementation defined

+

grb::vector::at

+
scalar_reference at(index_type index);
+const_scalar_reference at(index_type index) const;
+

Returns a reference to the scalar value stored at location +index in the vector. If no value is stored at the location, +throws the exception grb::out_of_range.

+

Parameters

+

index - Location of the vector element

+

Return value

+

A reference to the scalar value at location index.

+

Complexity

+

Implementation defined

+

Exceptions

+

If no element exists at location index, throws the +exception grb::out_of_range.

+

grb::index

+
template <std::integral T>
+struct grb::index;
+

grb::index is a tuple-like type used to store matrix +indices and dimensions.

+

Template Parameters

+

T - type, satisfying std::integral, used to +store indices

+

Member Types

+ + + + + + + + + + + + + + + + + + + + + +
Member TypeDefinition
index_typeT
first_typeT
second_typeT
+

Member Objects

+ + + + + + + + + + + + + + + + + +
Member NameType
firstT
secondT
+

Methods

+ + + + + + + + + + + + + + + + + + + + + +
MethodDescription
(constructor)Constructs index
operator[]Get one of the indices
getGet one of the indices
+

Sparse Storage Format Hints

+

This section defines compile-time hints that can be used to direct +the storage format used to organize data inside GraphBLAS objects. +Storage hints can be used as optional template arguments to +grb::matrix, grb::vector, as well as some API +functions that return a matrix or vector. These compile-time hints +provide a mechanism for users to suggest to the GraphBLAS implementation +which storage format might be most appropriate for a particular matrix. +However, these compile-time hints are indeed hints to the +implementation and do not enforce any change in semantics to a matrix or +vector data structure and do not require it to use any particular +storage format. GraphBLAS implementations are encouraged to document +which storage formats they support, as well as how different hints will +affect which storage formats are used.

+

Example

+
#include <grb/grb.hpp>
+
+int main(int argc, char** argv) {
+  // Create a matrix with the `dense` compile-time hint.
+  // The implementation may choose to employ a dense storage format.
+  grb::matrix<float, std::size_t, grb::dense> x({10, 10});
+
+  // Create a matrix with the compile-time hint compose<sparse, row>.
+  // A GraphBLAS implementation may choose to employ a compressed sparse row
+  // storage format.
+  grb::matrix<float, std::size_t, grb::compose<grb::sparse, grb::row>> y({10, 10});
+
+
+  // No change in data structure semantics is implied by a hint.
+  x[{2, 3}] = 12;
+  x[{3, 6}] = 12;
+
+  y[{6, 7}] = 1;
+  y[{6, 7}] = 2.5;
+
+  grb::print(x);
+  grb::print(y);
+
+  return 0;
+}
+

grb::sparse

+
using sparse = /* undefined */;
+

Compile-time hint to suggest to the GraphBLAS implementation that a +sparse or compressed storage format is appropriate.

+

grb::dense

+
using dense = /* undefined */;
+

Compile-time hint to suggest to the GraphBLAS implementation that a +dense storage format is appropriate.

+

grb::row

+
using row = /* undefined */;
+

Compile-time hint to suggest to the GraphBLAS implementation that a +row-major storage format is appropriate.

+

grb::column

+
using column = /* undefined */;
+

Compile-time hint to suggest to the GraphBLAS implementation that a +column-major storage format is appropriate.

+

grb::compose

+
template <typename... Hints>
+using compose = /* undefined */;
+

Type alias used to combine multiple compile-time hints together.

+

Views

+

grb::views::transpose

+
namespace views {
+  inline constexpr /* unspecified */ transpose = /* unspecified */;
+}
+
Call signature
+
template <MatrixRange M>
+MatrixRange auto transpose(M&& matrix);
+

Parameters

+

matrix - a GraphBLAS matrix or matrix view

+

Type Requirements

+ +

Return Value

+

Returns a matrix view that is equal to the transpose of +matrix, satisfying MatrixRange.

+

If the value returned by transpose outlives the lifetime +of matrix, then the behavior is undefined.

+

grb::views::transform

+
namespace views {
+  inline constexpr /* unspecified */ transform = /* unspecified */;
+}
+
Call signature
+
template <MatrixRange M, std::copy_constructible Fn>
+MatrixRange auto transform (M&& matrix, Fn&& fn);             (1)
+
+template <VectorRange V, std::copy_constructible Fn>
+VectorRange auto transform(V&& vector, Fn&& fn);              (2)
+
    +
  1. fn must accept an argument of type +std::ranges::range_value_t<M> and return a value of +some type. The return type of fn will be the scalar type of +the transform view.

  2. +
  3. fn must accept an argument of type +std::ranges::range_value_t<V> and return a value of +some type. The return type of fn will be the scalar type of +the transform view.

  4. +
+

Parameters

+

matrix - a GraphBLAS matrix or matrix view satisfying +MatrixRange

+

vector - a GraphBLAS vector or vector view satisfying +VectorRange

+

fn - function used to transform matrix values +element-wise

+

Type Requirements

+ +

Return Value

+
    +
  1. Returns a view of matrix satisfying +MatrixRange. The stored scalar values will correspond to +every stored scalar value in matrix transformed using the +function fn.

  2. +
  3. Returns a view of vector satisfying +VectorRange. The stored scalar values will correspond to +every stored scalar value in vector transformed using the +function fn.

  4. +
+

Example

+
#include <grb/grb.hpp>
+
+int main(int argc, char** argv) {
+  grb::matrix<float> a({10, 10});
+
+  a[{1, 2}] = 12.0f;
+  a[{3, 4}] = 123.2f;
+  a[{7, 8}] = 8.0f;;
+
+  grb::print(a, "original matrix");
+
+  // Transform each scalar value based on its
+  // row and column index.
+  auto idx_view = grb::views::transform(a, [](auto&& entry) {
+                                              auto&& [idx, v] = entry;
+                                              auto&& [i, j] = idx;
+                                              return i + j;
+                                           });
+
+  grb::print(idx_view, "index transformed view");
+
+  return 0;
+}
+

grb::structure

+
template <MatrixRange M>
+grb::structure_view<M> structure(M&& matrix);                 (1) 
+
+template <VectorRange V>
+grb::structure_view<V> structure(V&& vector);                 (2)
+

Parameters

+

matrix - a GraphBLAS matrix or matrix view

+

vector - a GraphBLAS vector or vector view

+

Type Requirements

+ +

Return Value

+
    +
  1. Returns a view of the matrix
  2. +
+

Possible Implementation

+
inline constexpr bool always_true = [](auto&&) { return true; };
+
+template <typename O>
+using structure_view = grb::transform_view<O, decltype(always_true)>;
+
+template <MatrixRange M>
+grb::structure_view<M> structure(M&& matrix) {
+  return grb::transform(std::forward<M>(matrix), always_true);
+}
+
+template <VectorRange V>
+grb::structure_view<V> structure(V&& vector) {
+  return grb::transform(std::forward<V>(vector), always_true);
+}
+

grb::filter

+
template <MatrixRange M, typename Fn>
+grb::filter_view<M> filter(M&& matrix, Fn&& fn);              (1)
+
+template <VectorRange V, typename Fn>
+grb::filter_view<V> filter(V&& vector, Fn&& fn);              (2)
+

Parameters

+

matrix - a GraphBLAS matrix

+

vector - a GraphBLAS vector

+

fn - a function determining which elements should be +filtered out

+

Type Requirements

+ +

Return Value

+

Returns a filtered view of the matrix matrix or vector +vector. The return value fulfills the requirements of +MatrixRange (1) or VectorRange (2) . The +return value has the same shape as the input object, but without +elements for which fn(e) evaluates to false.

+

grb::complement

+
template <MaskMatrixRange M>
+grb::complement_view<M> complement(M&& mask);                 (1)
+
+template <MaskVectorRange V>
+grb::complement_view<V> complement(V&& mask);                 (2)
+

Parameters

+

mask - a GraphBLAS mask

+

Type Requirements

+ +

Return Value

+

TODO: Scott, Jose, is this the behavior we want? Returns the +complement view of a matrix or vector mask. At every index in +mask with no stored value or with a scalar value equal to +false when converted to bool, the returned +view has a stored value with the scalar value true. At +every stored value in mask with a scalar value equal to +true when converted to bool, the return view +has no stored value.

+
    +
  1. Returns a matrix view satisfying the requirements +MaskMatrixRange.

  2. +
  3. Returns a vector view satisfying the requirements +MaskVectorRange.

  4. +
+

grb::mask

+
template <MatrixRange Matrix, MaskMatrixRange M>
+grb::masked_view<Matrix, M> mask(Matrix&& matrix, M&& mask);                 (1)
+
+template <VectorRange Vector, MaskVectorRange M>
+grb::masked_view<Vector, M> mask(Vector&& vector, M&& mask);                 (2)
+

Parameters

+

matrix - a GraphBLAS matrix or vector

+

mask - a GraphBLAS mask with the same shape as +matrix (1) or vector (2)

+

Type Requirements

+ +

Return Value

+

Returns a view of the matrix matrix (1) or vector +vector that has been masked using mask. Any +value in matrix for which mask does not have +an entry at the corresponding location or for which mask +has a value equal to false when converted to +bool will not be visible in the returned mask view.

+
    +
  1. Returns a matrix view satisfying the requirements +MatrixRange. Any values in matrix for which +grb::find(mask, index) == grb::end(mask) || bool(*grb::find(mask, index)) == false +will be masked out of the returned matrix view.
  2. +
+

Exceptions

+

The exception grb::invalid_argument is thrown if the +mask does not have the same shape as matrix +(1) or vector (2).

+

grb::submatrix_view

+
template <MatrixRange M>
+grb::submatrix_view<M> submatrix(M&& matrix, grb::index<I> rows, grb::index<I> cols);
+

Parameters

+

matrix - a GraphBLAS matrix

+

rows - the span of rows in the submatrix view

+

cols - the span of columns in the submatrix view

+

Return Value

+

Returns a view of the submatrix of GraphBLAS matrix +matrix formed by the intersection of rows +rows[0] to rows[1] and columns +cols[0] to cols[1]. The returned matrix range +has shape +grb::min(rows[1], grb::shape(matrix)[0]) - grb::max(rows[0], 0) +by +grb::min(cols[1], grb::shape(matrix)[1]) - grb::max(cols[0], 0) +and contains all stored values for whose index the expression +index[0] >= rows[0] && index[0] < rows[1] && index[1] >= cols[0] && index[1] < cols[1] +holds true.

+

Exceptions

+

Returns the exception grb::invalid_argument if +rows[0] > rows[1] or +cols[0] > cols[1].

+

Pre-Defined Operators

+

The GraphBLAS C++ API defines a number of binary and unary operators. +Operators are defined as function objects and typically perform +arithmetic or logical operations like addition, multiplication, +negation, and logical and.

+

TODO: Discuss Unary Operators

+

They work the same way as binary operators, but are quite a bit +simpler, since there is only one value to operate upon.

+

Binary Operator Template +Parameters

+

GraphBLAS’s binary operators allow flexiblility in terms of whether +all, some, or none of the types are explicitly declared. If one or more +types are not explicitly declared, they are deduced at the callsite +where the operator is invoked. For each binary operator op, +there are three partial specializations defined:

+
    +
  1. op<T, U, V>, where the input arguments are +explicitly specified to be T and U and the +return value is V.
  2. +
  3. op<T, U, void>, where the input arguments are +explicitly specified to be T and U, and the +return value is deduced.
  4. +
  5. op<void, void, void>, where the inputs arguments +and return type are all deduced upon invocation.
  6. +
+

All binary operators have the following default template +parameters:

+
template <typename T = void, typename U = T, typename V = void>
+struct op;
+

This means the user can use a binary operator with zero, one, two, or +three template parameters explicitly specified. The types of the input +arguments and return value will be explicitly defined or reduced +accordingly.

+

No Types Specified

+

If a user specifies no template parameters when using a binary +operator, the result is a function object in which the input argument +and return value types are all deduced at the callsite.

+
#include <grb/grb.hpp>
+#include <iostream>
+int main(int argc, char** argv) {
+  // No types are explicitly specified.
+  // We can use this operator with values of
+  // any types for which an operator+() is defined.
+  grb::plus<> p1;
+  
+  std::size_t a = 1024;
+  std::uint8_t b = 12;
+  
+  // `std::size_t` and `std::uint8_t` deduced as types of input arguments.
+  // `std::size_t` will be deduced as type of return value.
+  // std::size_t + std::uint8_t -> std::size_t
+  auto c = p1(a, b);
+  
+  return 0;
+}
+

One Type Specified

+

If a user specifies one template parameters when using a binary +operator, the result is a function object in which the the two input +arguments are of the type specified, and the return value type is +deduced.

+
#include <grb/grb.hpp>
+#include <iostream>
+int main(int argc, char** argv) {
+  // Explicitly specify `int` as the type of both input values.
+  // Return value type will be deduced as `int`.
+  grb::plus<int> p1;
+  
+  int a = 1024;
+  int b = 12;
+  
+  // int + int -> int
+  int c = p1(a, b);
+  
+  return 0;
+}
+

Two Types Specified

+

If a user specifies two template parameters when using a binary +operator, the result is a function object in which the the two input +arguments are of the types specified, and the return value type is +deduced.

+
#include <grb/grb.hpp>
+#include <iostream>
+int main(int argc, char** argv) {
+  // Explicitly specify `std::size_t` for the lefthand argument
+  // and `std::uint8_t` for the righthand argument.
+  // Return value type will be deduced as `std::size_t`.
+  grb::plus<std::size_t, std::uint8_t> p1;
+  
+  std::size_t a = 1024;
+  std::uint8_t b = 12;
+  
+  // std::size_t + std::uint8_t -> std::size_t
+  std::size_t c = p1(a, b);
+  
+  return 0;
+}
+

Three Types Specified

+

If a user specifies all three template parameters when using a binary +operator, both of the input argument types as well as the return value +type of the function are explicitly specified.

+
#include <grb/grb.hpp>
+#include <iostream>
+int main(int argc, char** argv) {
+  // Explicitly specify `std::size_t` for the lefthand argument
+  // and `std::uint8_t` for the righthand argument.
+  // Return value type explicitly specified as `int`.
+  grb::plus<std::size_t, std::uint8_t, int> p1;
+  
+  std::size_t a = 1024;
+  std::uint8_t b = 12;
+  
+  // std::size_t + std::uint8_t -> std::size_t
+  std::size_t c =  p1(a, b);
+  
+  return 0;
+}
+

grb::plus

+
template <typename T = void, typename U = T, typename V = void>
+struct plus;
+

grb::plus is a binary operator. It forms a monoid on +arithmetic types.

+

Specializations

+ + + + + + + + + + + + + + + + + +
SpecializationDescription
plus<void, void, void>deduces argument and return types
plus<T, U, void>deduces return type based on T and U
+

Template Parameters

+

T - Type of the left hand argument of the operator

+

U - Type of the right hand argument of the operator

+

V - Return type of the operator

+

Methods

+ + + + + + + + + + + + + +
MethodDescription
operator()returns the sum of the two arguments
+

grb::plus::operator()

+
constexpr V operator()( const T& lhs, const U& rhs ) const;
+

Returns the sum of lhs and rhs.

+

Parameters

+

lhs, rhs - values to sum

+

Return Value

+

The result of lhs + rhs.

+

Exceptions

+

May throw exceptions if the underlying operator+() +operation throws exceptions

+

Monoid Traits

+

grb::plus forms a monoid on any arithmetic type +A with the identity value 0, as long as +T, U, and V are equal to void or +A.

+

Specialization Details

+

grb::plus<void, void, void>

+
template <>
+struct plus<void, void, void>;
+

Version of grb::plus with both arguments and return +types deduced.

+

grb::plus::operator()

+
template <typename T, typename U>
+constexpr auto operator()(T&& lhs, U&& rhs) const
+  -> decltype(std::forward<T>(lhs) + std::forward<U>(rhs));
+

grb::plus<T, U, void>

+
template <typename T = void, typename U = T>
+struct plus<T, U, void>;
+

Version of grb::plus with explicit types for the +arguments, but return type deduced.

+

grb::plus::operator()

+
constexpr auto operator()(const T& lhs, const U& rhs) const
+  -> decltype(lhs + rhs);
+

grb::multiplies

+
template <typename T = void, typename U = T, typename V = void>
+struct multiplies;
+

grb::multiplies is a binary operator. It forms a monoid +on arithmetic types.

+

Specializations

+ + + + + + + + + + + + + + + + + +
SpecializationDescription
multiplies<void, void, void>deduces argument and return types
multiplies<T, U, void>deduces return type based on T and U
+

Template Parameters

+

T - Type of the left hand argument of the operator

+

U - Type of the right hand argument of the operator

+

V - Return type of the operator

+

Methods

+ + + + + + + + + + + + + +
MethodDescription
operator()returns the product of the two arguments
+

grb::multiplies::operator()

+
constexpr V operator()( const T& lhs, const U& rhs ) const;
+

Returns the product of lhs and rhs.

+

Parameters

+

lhs, rhs - values to multiply

+

Return Value

+

The result of lhs * rhs.

+

Exceptions

+

May throw exceptions if the underlying operator*() +operation throws exceptions

+

Monoid Traits

+

grb::multiplies forms a monoid on any arithmetic type +A with the identity value 1, as long as +T, U, and V are equal to void or +A.

+

Specialization Details

+
grb::multiplies<void, void, void>
+
template <>
+struct multiplies<void, void, void>;
+

Version of grb::multiplies with both arguments and +return types deduced.

+
grb::multiplies::operator()
+
template <typename T, typename U>
+constexpr auto operator()(T&& lhs, U&& rhs) const
+  -> decltype(std::forward<T>(lhs) * std::forward<U>(rhs));
+
grb::multiplies<T, U, void>
+
template <typename T = void, typename U = T>
+struct multiplies<T, U, void>;
+

Version of grb::multiplies with explicit types for the +arguments, but return type deduced.

+
grb::multiplies::operator()
+
constexpr auto operator()(const T& lhs, const U& rhs) const
+  -> decltype(lhs * rhs);
+

grb::minus

+
template <typename T = void, typename U = T, typename V = void>
+struct minus;
+

grb::minus is a binary operator that subtracts two +values.

+

Specializations

+ + + + + + + + + + + + + + + + + +
SpecializationDescription
minus<void, void, void>deduces argument and return types
minus<T, U, void>deduces return type based on T and U
+

Template Parameters

+

T - Type of the left hand argument of the operator

+

U - Type of the right hand argument of the operator

+

V - Return type of the operator

+

Methods

+ + + + + + + + + + + + + +
MethodDescription
operator()returns the difference of the two arguments
+

grb::minus::operator()

+
constexpr V operator()( const T& lhs, const U& rhs ) const;
+

Returns the difference of lhs and rhs.

+

Parameters

+

lhs, rhs - values to subtract

+

Return Value

+

The result of lhs - rhs.

+

Exceptions

+

May throw exceptions if the underlying operator-() +operation throws exceptions

+

Monoid Traits

+

grb::minus does not form a monoid for arithmetic +types.

+

Specialization Details

+

grb::minus<void, void, void>

+
template <>
+struct minus<void, void, void>;
+

Version of grb::minus with both arguments and return +types deduced.

+

grb::minus::operator()

+
template <typename T, typename U>
+constexpr auto operator()(T&& lhs, U&& rhs) const
+  -> decltype(std::forward<T>(lhs) - std::forward<U>(rhs));
+

grb::minus<T, U, void>

+
template <typename T = void, typename U = T>
+struct minus<T, U, void>;
+

Version of grb::minus with explicit types for the +arguments, but return type deduced.

+

grb::minus::operator()

+
constexpr auto operator()(const T& lhs, const U& rhs) const
+  -> decltype(lhs - rhs);
+

grb::divides

+
template <typename T = void, typename U = T, typename V = void>
+struct divides;
+

grb::divides is a binary operator that divides two +values.

+

Specializations

+ + + + + + + + + + + + + + + + + +
SpecializationDescription
divides<void, void, void>deduces argument and return types
divides<T, U, void>deduces return type based on T and U
+

Template Parameters

+

T - Type of the left hand argument of the operator

+

U - Type of the right hand argument of the operator

+

V - Return type of the operator

+

Methods

+ + + + + + + + + + + + + +
MethodDescription
operator()returns the difference of the two arguments
+

grb::divides::operator()

+
constexpr V operator()( const T& lhs, const U& rhs ) const;
+

Returns the difference of lhs and rhs.

+

Parameters

+

lhs, rhs - values to divide

+

Return Value

+

The result of lhs / rhs.

+

Exceptions

+

May throw exceptions if the underlying operator/() +operation throws exceptions

+

Monoid Traits

+

grb::divides does not form a monoid for arithmetic +types.

+

Specialization Details

+

grb::divides<void, void, void>

+
template <>
+struct divides<void, void, void>;
+

Version of grb::divides with both arguments and return +types deduced.

+

grb::divides::operator()

+
template <typename T, typename U>
+constexpr auto operator()(T&& lhs, U&& rhs) const
+  -> decltype(std::forward<T>(lhs) / std::forward<U>(rhs));
+

grb::divides<T, U, void>

+
template <typename T = void, typename U = T>
+struct divides<T, U, void>;
+

Version of grb::divides with explicit types for the +arguments, but return type deduced.

+
grb::divides::operator()
+
constexpr auto operator()(const T& lhs, const U& rhs) const
+  -> decltype(lhs / rhs);
+

grb::max

+
template <typename T = void, typename U = T, typename V = void>
+struct max;
+

grb::max is a binary operator that returns the larger of +two arguments. When both input arguments have integral types, +std::cmp_less is used for comparison. When one or both +arguments have non-integral types, operator< is used for +comparison. It forms a monoid on arithmetic types.

+

Specializations

+ + + + + + + + + + + + + + + + + +
SpecializationDescription
max<void, void, void>deduces argument and return types
max<T, U, void>deduces return type based on T and U
+

Template Parameters

+

T - Type of the left hand argument of the operator

+

U - Type of the right hand argument of the operator

+

V - Return type of the operator

+

Methods

+ + + + + + + + + + + + + +
MethodDescription
operator()returns the larger of two arguments
+

grb::max::operator()

+
constexpr V operator()( const T& lhs, const U& rhs ) const;
+

Returns the larger of lhs and rhs.

+

Parameters

+

lhs, rhs - values to take the max of

+

Return Value

+

The larger of lhs and rhs.

+

Exceptions

+

May throw exceptions if the underlying operator<() +operation throws exceptions

+

Monoid Traits

+

grb::max forms a monoid on any arithmetic type +A with the identity value +std::min(std::numeric_limits<A>::lowest(), -std::numeric_limits<A>::infinity()), +as long as T, U, and V are equal +to void or A.

+

Specialization Details

+

grb::max<void, void, void>

+
template <>
+struct max<void, void, void>;
+

Version of grb::max with both arguments and return types +deduced.

+

grb::max::operator()

+
template <std::integral T, std::integral U>
+constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+      std::cmp_less(std::numeric_limits<T>::max(),
+                    std::numeric_limits<U>::max()),
+      U, T
+     >;
+
+template <typename T, typename U>
+constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+      std::numeric_limits<T>::max() < std::numeric_limits<U>::max(),
+      U, T
+     >
+requires(!(std::is_integral_v<T> && std::is_integral_v<U>));
+

grb::max<T, U, void>

+
template <typename T = void, typename U = T>
+struct max<T, U, void>;
+

Version of grb::max with explicit types for the +arguments, but return type deduced.

+

grb::max::operator()

+
constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+      std::cmp_less(std::numeric_limits<T>::max(),
+                    std::numeric_limits<U>::max()),
+      U, T
+     >;
+
+constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+      std::numeric_limits<T>::max() < std::numeric_limits<U>::max(),
+      U, T
+     >
+requires(!(std::is_integral_v<T> && std::is_integral_v<U>));
+

grb::min

+
template <typename T = void, typename U = T, typename V = void>
+struct min;
+

grb::min is a binary operator that returns the smaller +of two arguments. using operator< for comparison. When +both input arguments have integral types, std::cmp_less is +used for comparison. When one or both arguments have non-integral types, +operator< is used for comparison. It forms a monoid on +arithmetic types.

+

Specializations

+ + + + + + + + + + + + + + + + + +
SpecializationDescription
min<void, void, void>deduces argument and return types
min<T, U, void>deduces return type based on T and U
+

Template Parameters

+

T - Type of the left hand argument of the operator

+

U - Type of the right hand argument of the operator

+

V - Return type of the operator

+

Methods

+ + + + + + + + + + + + + +
MethodDescription
operator()returns the smaller of two arguments
+

grb::min::operator()

+
constexpr V operator()( const T& lhs, const U& rhs ) const;
+

Returns the smaller of lhs and rhs.

+

Parameters

+

lhs, rhs - values to take the min of

+

Return Value

+

The smaller of lhs and rhs.

+

Exceptions

+

May throw exceptions if the underlying operator<() +operation throws exceptions

+

Monoid Traits

+

grb::min forms a monoid on any arithmetic type +A with the identity value +std::max(std::numeric_limits<A>::max(), std::numeric_limits<A>::infinity()), +as long as T, U, and V are equal +to void or A.

+

Specialization Details

+

grb::min<void, void, void>

+
template <>
+struct min<void, void, void>;
+

Version of grb::min with both arguments and return types +deduced.

+

grb::min::operator()

+
template <std::integral T, std::integral U>
+constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+       std::cmp_less(std::numeric_limits<U>::lowest(),
+                     std::numeric_limits<T>::lowest()),
+       U, T
+     >;
+
+template <typename T, typename U>
+constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+       std::numeric_limits<U>::lowest() < std::numeric_limits<T>::lowest(),
+       U, T
+     >
+requires(!(std::is_integral_v<T> && std::is_integral_v<U>));
+

grb::min<T, U, void>

+
template <typename T = void, typename U = T>
+struct min<T, U, void>;
+

Version of grb::min with explicit types for the +arguments, but return type deduced.

+

grb::min::operator()

+
constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+       std::cmp_less(std::numeric_limits<U>::lowest(),
+                     std::numeric_limits<T>::lowest()),
+       U, T
+     >;
+
+constexpr auto operator()(const T& a, const U& b) const
+  -> std::conditional_t<
+       std::numeric_limits<U>::lowest() < std::numeric_limits<T>::lowest(),
+       U, T
+     >
+requires(!(std::is_integral_v<T> && std::is_integral_v<U>));
+

Utilities

+

TODO: need “disablers” for all these CPOs. Also, “converted to +its decayed type?”

+

grb::get

+
inline constexpr /* unspecified */ get = /* unspecified */;
+

Call Signature

+
template <std::size_t I, typename T>
+requires /* see below */
+constexpr std::tuple_element<I, T> get(T&& tuple);
+

TODO: we need someone who understands CPOs a little better to +understand this.

+

Returns the I'th element stored in the tuple-like object +tuple.

+

A call to grb::get is expression-equivalent to:

+
    +
  1. tuple.get<I>(), if that expression is valid.
  2. +
  3. Otherwise, any calls to get(tuple) found through +argument-dependent lookup.
  4. +
  5. Otherwise, std::get<I>(tuple).
  6. +
+

In all other cases, a call to grb::get is +ill-formed.

+

grb::size

+
template <typename T>
+inline constexpr /* unspecified */ size = std::ranges::size;
+

Call Signature

+
template <typename T>
+constexpr auto size(T&& t);
+

Returns the number of stored values in a GraphBLAS matrix, vector, or +other range. Whenever grb::size(e) is valid for an +expression e, the return type is integer-like.

+

A call to grb::size(t) is expression-equivalent to:

+
    +
  1. t.size(), if that expression is valid.
  2. +
  3. Otherwise, any calls to size(t), found through +argument-dependent lookup.
  4. +
+

In all other cases, a call to grb::size is +ill-formed.

+

grb::shape

+
template <typename T>
+inline constexpr /* unspecified */ shape = /* unspecified */;
+

Call Signature

+
template <typename T>
+requires /* see below */
+constexpr auto shape(T&& t);
+

Returns the shape of a GraphBLAS object. If T fulfills +the requirements of MatrixRange, then the return type will +be a tuple-like type storing two integer-like values, fulfilling the +requirements of TupleLike<I, I>, where I +is the index type of T. If T fulfills the +requirements of VectorRange, then the return type will be +I, where I is the index type of +T.

+

A call to grb::shape is expression-equivalent to:

+
    +
  1. t.shape() if that expression is valid.
  2. +
  3. Otherwise, shape(t), if that expression is valid, +including any declarations of shape found through +argument-dependent lookup.
  4. +
+

In all other cases, a call to grb::shape is +ill-formed.

+

grb::find

+
template <typename T>
+inline constexpr /* unspecified */ find = /* unspecified */;
+

Call Signature

+
template <typename R, typename T>
+requires /* see below */
+constexpr auto find(R&& r, T&& t);
+

Return an iterator to the stored value in the GraphBLAS matrix or +vector r at index location t.

+

A call to grb::find is expression-equivalent to:

+
    +
  1. r.find(t) if that expression is valid.
  2. +
  3. Otherwise, any calls to find(r, t) found through +argument-dependent lookup.
  4. +
  5. Otherwise, any calls to std::find(r, t), if that +expression is valid.
  6. +
+

In all other cases, a call to grb::find is +ill-formed.

+

grb::insert

+
template <typename T>
+inline constexpr /* unspecified */ insert = /* unspecified */;
+

Call Signature

+
template <typename R, typename T>
+requires /* see below */
+constexpr auto insert(R&& r, T&& t);
+

Attempt to insert the value t into the GraphBLAS matrix +or vector r.

+

A call to grb::insert is expression-equivalent to:

+
    +
  1. r.insert(t) if that expression is valid.
  2. +
  3. Otherwise, any calls to insert(r, t) found through +argument-dependent lookup.
  4. +
+

scalar_result_type_t

+
template <typename A, typename B, typename Combine>
+using scalar_result_type_t = std::declval<Combine>()(
+                                std::declval<scalar_type_t<A>>(),
+                                std::declval<scalar_type_t<B>>());
+

The type of the scalar elements produced by combining GraphBLAS +objects of type A and B elementwise using a +binary operator of type Combine.

+

multiply_result_t

+
template <typename A, typename B, typename Reduce, typename Combine, typename Mask>
+using multiply_result_t = /* undefined */;
+

The type returned when multiply is called on GraphBLAS matrix or +vector ranges of type A and B using binary +operators Reduce and Combine with mask +Mask.

+

The scalar type of the returned matrix will be +combine_result_t<A, B, Combine>, and the index type +will be grb::container_index_t<A> or +grb::container_index_t<B>, whichever is able to store +the larger value.

+

combine_result_t

+
template <typename A, typename B, typename Combine>
+using combine_result_t = std::invoke_result_t<Combine, A, B>;
+

The type returned when the binary operator Combine is +called with an element of the scalar type of A as the first +argument and an element of the scalar type of B as the +second argument. A and B must be GraphBLAS +matrix or vector objects.

+

ewise_union_result_t

+
template <typename A, typename B, typename Combine, typename Mask>
+using ewise_union_result_t = /* undefined */;
+

The type returned when ewise_union is called on the +GraphBLAS matrix or vector ranges of type A and +B using the binary operator Combine.

+

ewise_intersection_result_t

+
template <typename A, typename B, typename Combine, typename Mask>
+using ewise_intersection_result_t = /* undefined */;
+

The type returned when ewise_intersection is called on +the GraphBLAS matrix or vector ranges of type A and +B using the binary operator Combine.

+

read_matrix

+

+template <typename T,
+          std::integral I = std::size_t,
+          typename Hint = grb::sparse,
+          typename Allocator = std::allocator<T>>
+grb::matrix<T, I, Hint, Allocator>
+read_matrix(std::string file_path);
+

Constructs a new GraphBLAS matrix based on the contents of a +file.

+

Template Parameters

+

T - type of scalar values stored in matrix

+

I - type of matrix indices

+

Hint - compile-time hint for backend storage format.

+

Allocator - allocator type

+

Parameters

+

file_path - string holding the file path of the matrix +to be read

+

Return Value

+

Returns a GraphBLAS matrix whose dimensions and contents correspond +to the file located at file_path.

+

Complexity

+

Complexity is implementation-defined.

+

Exceptions

+ +

Notes

+

GraphBLAS implementations must define the file formats that they +support. Implementations are strongly encouraged to support the +MatrixMarket format.

+

Example

+

Concepts

+

Binary Operator

+

Binary operators are function objects that are invocable with two +arguments, returning a single value. Binary operators can be callables +defined by a GraphBLAS library, the C++ Standard Library, or application +developers. Binary operators may be callable with a variety of different +types, or only with elements of a single type. We say a binary operator +is valid for a particular operation T x U -> V if it is +callable with arguments of type T and U and +returns a value convertible to type V.

+

Requirements

+
    +
  1. Callable of type Fn can be invoked with two arguments +of type T and U.
  2. +
  3. The return value is convertible to type V.
  4. +
+

Concept

+
template <typename Fn, typename T, typename U = T, typename V = grb::any>
+concept BinaryOperator = requires(Fn fn, T t, U u) {
+                           {fn(t, u)} -> std::convertible_to<V>;
+                         };
+

Remarks

+

The last two arguments are defaulted unless explicit template +parameters are provided. The second parameter to the concept, +U, which is the right-hand side input to the binary +operator, defaults to T. The final parameter, +V, which represents the output of the binary operator, +defaults to grb::any, meaning that the return value may +have any type.

+

Example

+
// Constrain `Fn` to require a binary operator that accepts two integers
+// as arguments and returns a value of any type.
+template <BinaryOperator<int> Fn>
+auto apply(Fn&& fn, int a, int b) {
+  return fn(a, b);
+}
+
+// The following code will result in an error, since the function passed
+// does not fulfill the BinaryOperator<int> requirement, as it cannot accept
+// integers.
+void test() {
+  auto fn = [](std::string a, std::string b) { return a.size() + b.size(); };
+  apply(fn, 12, 13);
+}
+

Monoid

+

GraphBLAS monoids are commutative monoids. Throughout this +specification, they are referred to simply as monoids. They are binary +operators that have special properties when applied to elements of some +type T. We say that a function object Fn forms +on a monoid on type T if the following requirements are +met.

+

Requirements

+
    +
  1. Callable of type Fn fulfills the concept +BinaryOperator<T, T, T> for some type +T.
  2. +
  3. The operation is associative and commutative for type +T.
  4. +
  5. The operation has an identity element for type T, +accessible using +grb::monoid_traits<Fn, T>::identity().
  6. +
+

Concept

+
template <typename Fn, typename T>
+concept Monoid = BinaryOperator<Fn, T, T, T> &&
+                 requires { {grb::monoid_traits<Fn, T>::identity()} -> std::same_as<T>; };
+

Tuple-Like Type

+

Tuple-like types are types that, similar to instantiations of +std::tuple or std::pair, store multiple +values. The number of values stored in the tuple-like type, as well as +the type of each value, are known at compile time. We say that a type +T is tuple-like for the parameter pack of types +Types if it fulfills the following requirements.

+

Requirements

+
    +
  1. The tuple T has a size accessible using template +std::tuple_size whose type is equal to +std::size_t and whose value is equal to +sizeof...(Types).
  2. +
  3. The type of each stored value in the tuple T is +accessible using std::tuple_element, with the N’th stored +value equal to the N’th type in Types.
  4. +
  5. Each stored value in T is accessible using the +customization point object grb::get, which will invoke +either the method get() if it is present in the tuple type +T or std::get(). The type of the return value +for the N’th element must be convertible to the N’th element of +Types.
  6. +
+

Concept

+

_TODO: this concept could refactored to be a bit more elegant.

+
template <typename T, std::size_t I, typename U = grb::any>
+concept TupleElementGettable = requires(T tuple) {
+                                 {grb::get<I>(tuple)} -> std::convertible_to<U>;
+                               };
+template <typename T, typename... Args>
+concept TupleLike =
+  requires {
+    typename std::tuple_size<std::remove_cvref_t<T>>::type;
+    requires std::same_as<std::remove_cvref_t<decltype(std::tuple_size_v<std::remove_cvref_t<T>>)>, std::size_t>;
+  } &&
+  sizeof...(Args) == std::tuple_size_v<std::remove_cvref_t<T>> &&
+  []<std::size_t... I>(std::index_sequence<I...>) {
+    return (TupleElementGettable<T, I, Args> && ...);
+  }(std::make_index_sequence<std::tuple_size_v<std::remove_cvref_t<T>>>());
+

Example

+
// The Concept `TupleLike<int, int, float>` constraints `T`
+// to be a tuple-like type storing int, int, float.
+template<TupleLike<int, int, float> T>
+void print_tuple(T&& tuple) {
+  auto&& [i, j, v] = tuple;
+  printf("%d, %d, %f\n", i, j, v);
+}
+

Matrix Entry

+

Matrix entries represent entries in a GraphBLAS matrix, which include +both a tuple-like index storing the row and column index of the stored +scalar value, as well as the scalar value itself. We say that a type +Entry is a valid matrix entry for the scalar type +T and index type I if the following +requirements are met.

+

Requirements

+
    +
  1. Entry is a tuple-like type with a size of 2.
  2. +
  3. The first element stored in the tuple-like type Entry +is a tuple-like type fulfilling TupleLike<I, I>, +storing the row and column index of the matrix entry.
  4. +
  5. The second element stored in the tuple-like type Entry +holds the matrix entry’s scalar value, and is convertible to +T.
  6. +
+

Concept

+
template <typename Entry, typename T, typename I>
+concept MatrixEntry = TupleLike<Entry, grb::any, grb::any> &&
+                      requires(Entry entry) { {grb::get<0>(entry)} -> TupleLike<I, I>; } &&
+                      requires(Entry entry) { {grb::get<1>(entry)} -> std::convertible_to<T>; };
+

Mutable Matrix Entry

+

A mutable matrix entry is an entry in a matrix that fulfills all the +requirements of matrix entry, but whose stored scalar value can be +mutated by assigning to some value of type U. We say that a +matrix entry Entry is a mutable matrix entry for scalar +type T, index type I, and output type +U, if it fulfills all the requirements of matrix entry as +well as the following requirements.

+

Requirements

+
    +
  1. The second element of the tuple Entry, representing the +scalar value, is assignable to elements of type U.
  2. +
+

Concept

+
template <typename Entry, typename T, typename I, typename U>
+concept MutableMatrixEntry = MatrixEntry<Entry, T, I> &&
+                             std::is_assignable_v<decltype(std::get<1>(std::declval<Entry>())), U>;
+

Matrix Range

+

A matrix in GraphBLAS consists of a range of values distributed over +a two-dimensional domain. In addition to grb::matrix, which directly stores +a collection of values, there are other types, such as views, that +fulfill the same interface. We say that a type M is a +matrix range if the following requirements are met.

+

Requirements

+
    +
  1. M has a scalar type of the stored values, accessible +with grb::matrix_scalar_t<M>
  2. +
  3. M has an index type used to reference the indices of +the stored values, accessible with +grb::matrix_index_t<M>.
  4. +
  5. M is a range with a value type that represents a matrix +tuple, containing both the index and scalar value for each stored +value.
  6. +
  7. M has a shape, which is a tuple-like object of size +two, holding the number of rows and the number of columns, accessible by +invoking the method shape() on an object of type +M.
  8. +
  9. M has a method find() that takes an index +tuple and returns an iterator.
  10. +
+

Concept

+
template <typename M>
+concept MatrixRange = std::ranges::sized_range<M> &&
+  requires(M matrix) {
+    typename grb::matrix_scalar_t<M>;
+    typename grb::matrix_index_t<M>;
+    {std::declval<std::ranges::range_value_t<std::remove_cvref_t<M>>>()}
+      -> MatrixEntry<grb::matrix_scalar_t<M>,
+                     grb::matrix_index_t<M>>;
+    {grb::shape(matrix)} -> Tuplelike<grb::matrix_index_t<M>,
+                                  grb::matrix_index_t<M>>;
+    {grb::find(matrix, {grb::matrix_index_t<M>{}, grb::matrix_index_t<M>{}})}
+                 -> std::convertible_to<std::ranges::iterator_t<M>>;
+  };
+

Mutable Matrix Range

+

Some matrices and matrix-like objects are mutable, meaning +that their stored values may be modified. Examples of mutable matrix +ranges include instantiations of grb::matrix and certain +matrix views that allow adding new values and modifying old values, such +as grb::transpose. We say that a type M is a +mutable matrix range for the scalar value T if the +following requirements are met.

+

Requirements

+
    +
  1. M is a matrix range.
  2. +
  3. The value type of M fulfills the requirements of +MutableMatrixEntry<T, I>.
  4. +
  5. M has a method insert() that takes a +matrix entry tuple and attempts to insert the element into the matrix, +returning an iterator to the new element on success and returning an +iterator to the end on failure.
  6. +
+

Concept

+
template <typename M, typename T>
+concept MutableMatrixRange = MatrixRange<M> &&
+                             MutableMatrixEntry<std::ranges::range_value_t<M>
+                                                grb::matrix_scalar_t<M>,
+                                                grb::matrix_index_t<M>,
+                                                T> &&
+  requires(M matrix, T value) {
+    {grb::insert(matrix, {{grb::matrix_index_t<M>{}, grb::matrix_index_t<M>{}},
+                          value}) -> std::ranges::iterator_t<M>;
+    }
+  };
+

Mask Matrix Range

+

Some operations require masks, which can be used to avoid computing +and storing certain parts of the output. We say that a type +M is a mask matrix range if the following requirements are +met.

+

Requirements

+
    +
  1. M is a matrix range.
  2. +
  3. The scalar value type of M is convertible to +bool.
  4. +
+

Concept

+
template <typename M>
+concept MaskMatrixRange = MatrixRange<M> &&
+                          std::is_convertible_v<grb::matrix_scalar_t<M>, bool>;
+

Vector Entry

+

Vector entries represent entries in a GraphBLAS vector, which include +both an std::integral index storing the index of the stored +scalar value, as well as the scalar value itself. We say that a type +Entry is a valid matrix entry for the scalar type +T and index type I if the following +requirements are met.

+

Requirements

+
    +
  1. Entry is a tuple-like type with a size of 2.
  2. +
  3. The first element stored in the tuple-like type Entry +fulfills std::integral.
  4. +
  5. The second element stored in the tuple-like type Entry +holds the vector’s scalar value, and is convertible to +T.
  6. +
+

Concept

+
template <typename Entry, typename T, typename I>
+concept VectorEntry = TupleLike<Entry, grb::any, grb::any> &&
+                      requires(Entry entry) { {grb::get<0>(entry)} -> std::integral; } &&
+                      requires(Entry entry) { {grb::get<1>(entry)} -> std::convertible_to<T>; };
+

Mutable Vector Entry

+

A mutable vector entry is an entry in a vector that fulfills all the +requirements of vector entry, but whose stored scalar value can be +mutated by assigning to some value of type U. We say that a +vector entry Entry is a mutable vector entry for scalar +type T, index type I, and output type +U, if it fulfills all the requirements of vector entry as +well as the following requirements.

+

Requirements

+
    +
  1. The second element of the tuple Entry, representing the +scalar value, is assignable to elements of type U.
  2. +
+

Concept

+
template <typename Entry, typename T, typename I, typename U>
+concept MutableVectorEntry = VectorEntry<Entry, T, I> &&
+                             std::is_assignable_v<decltype(std::get<1>(std::declval<Entry>())), U>;
+

Vector Range

+

A vector in GraphBLAS consists of a range of values distributed over +a one-dimensional domain. In addition to grb::vector, which directly stores +a collection of values, there are other types, such as views, that +fulfill the same interface. We say that a type V is a +vector range if the following requirements are met.

+

TODO: make requirements list find CPO, not method.

+

Requirements

+
    +
  1. V has a scalar type of the stored values, accessible +with grb::vector_scalar_t<V>
  2. +
  3. V has an index type used to reference the indices of +the stored values, accessible with +grb::vector_index_t<V>.
  4. +
  5. V is a range with a value type that represents a vector +tuple, containing both the index and scalar value for each stored +value.
  6. +
  7. V has a shape, which is an integer-like object, holding +the dimension of the vector, accessible by invoking the method +shape() on an object of type V.
  8. +
  9. V has a method find() that takes an index +and returns an iterator.
  10. +
+

Concept

+

TODO: this is a bit sketchy, and needs to have some of the +components fleshed out.

+
template <typename M>
+concept VectorRange = std::ranges::sized_range<V> &&
+  requires(V vector) {
+    typename grb::vector_scalar_t<V>;
+    typename grb::vector_index_t<V>;
+    {std::declval<std::ranges::range_value_t<std::remove_cvref_t<V>>>()}
+      -> VectorEntry<grb::vector_scalar_t<V>,
+                     grb::vector_index_t<V>>;
+    {grb::shape(vector)} -> std::same_as<grb::vector_index_t<V>>;
+    {grb::find(vector, grb::vector_index_t<V>)} -> std::convertible_to<std::ranges::iterator_t<V>>;
+  };
+

Mutable Vector Range

+

Some vectors and vector-like objects are mutable, meaning +that their stored values may be modified. Examples of mutable vector +ranges include instantiations of grb::vector and certain +vector views that allow adding new values and modifying old values, such +as grb::transpose. We say that a type V is a +mutable vector range for the scalar value T if the +following requirements are met.

+

Requirements

+
    +
  1. V is a vector range.
  2. +
  3. The value type of M fulfills the requirements of +MutableVectorEntry<T, I>.
  4. +
  5. M has a method insert() that takes a +vector entry tuple and attempts to insert the element into the vector +returning an iterator to the new element on success and returning an +iterator to the end on failure.
  6. +
+

Concept

+
template <typename V, typename T>
+concept MutableVectorRange = VectorRange<V> &&
+                             MutableVectorEntry<std::ranges::range_value_t<V>,
+                                                grb::vector_scalar_t<V>,
+                                                grb::vector_index_t<V>,
+                                                T> &&
+  requires(V vector, T value) {
+    {grb::insert(vector, {grb::vector_index_t<V>{}, value})}
+      -> std::same_as<std::ranges::iterator_t<V>>;
+  };
+

Mask Vector Range

+

Some operations require masks, which can be used to avoid computing +and storing certain parts of the output. We say that a type +M is a mask vector range if the following requirements are +met.

+

Requirements

+
    +
  1. M is a vector range.
  2. +
  3. The scalar value type of M is convertible to +bool.
  4. +
+

Concept

+
template <typename M>
+concept MaskVectorRange = VectorRange<M> &&
+                          std::is_convertible_v<grb::vector_scalar_t<M>, bool>;
+

Type Traits

+

grb::monoid_traits

+
template <typename Fn, typename T>
+struct monoid_traits;
+

The monoid_traits template struct provides information +about the monoid that is formed by the commutative binary operator +Fn on the type T. Namely, it provides a way to +retrieve the monoid’s identity.

+

Users can specialize monoid_traits for custom operators, +which will make their identity elements available to GraphBLAS +algorithms, possibly enabling optimizations. The default specialization +of monoid_traits detects and provides the identity of the +monoid if it has an identity method.

+

Template Parameters

+

Fn - type of commutative binary operator

+

T - type on which Fn forms a commutative +monoid

+

Member Types

+ + + + + + + + + + + + + + + +
Member TypeDefinitionDescription
typeTtype of the monoid
+

The default specialization has the following member functions:

+

Member Functions

+ + + + + + + + + + + + + + + +
FunctionDescription
identitythe identity value of the monoid
+

grb::monoid_traits<Fn, T>::identity

+
static constexpr T identity() noexcept;
+

Returns the identity of the monoid.

+

Parameters

+

None

+

Complexity

+

Constant

+

Exceptions

+

May not throw exceptions

+

Possible Implementation

+
template <typename Fn, typename T>
+static constexpr T grb::monoid_traits<Fn, T>::identity() noexcept {
+  if constexpr(requires { {Fn::identity() } -> std::same_as<T> }) {
+    return Fn::identity();
+  } else if constexpr(requires { {Fn:: template identity<T>()} -> std::same_as<T> }) {
+    return Fn:: template identity<T>();
+  }
+}
+

Specializations

+
template <std::arithmetic T>
+struct grb::monoid_traits<std::plus<T>, T>;
+
+template <std::arithmetic T>
+struct grb::monoid_traits<std::plus<void>, T>;
+
template <std::arithmetic T>
+struct grb::monoid_traits<std::multiplies<T>, T>;
+
+template <std::arithmetic T>
+struct grb::monoid_traits<std::multiplies<void>, T>;
+

grb::matrix_value_t

+
template <typename Matrix>
+using matrix_value_t = std::ranges::range_value_t<Matrix>;
+

Obtain the value type of the matrix-like type Matrix. +Equal to std::ranges::range_value_t<Matrix>.

+

grb::vector_value_t

+
template <typename Vector>
+using vector_value_t = std::ranges::range_value_t<Vector>;
+

Obtain the value type of the vector-like type Vector. +Equal to std::ranges::range_value_t<Vector>.

+

grb::matrix_scalar_t

+
template <typename Matrix>
+using matrix_scalar_t = std::remove_cvref_t<typename std::tuple_element<1, matrix_value_t<Matrix>>::type>;
+

Obtain the type of scalar values stored in the matrix-like type +Matrix. Equal to the second element stored in the matrix’s +tuple-like value type.

+

grb::vector_scalar_t

+
template <typename Vector>
+using vector_scalar_t = std::remove_cvref_t<typename std::tuple_element<1, vector_value_t<Vector>>::type>;
+

Obtain the type of scalar values stored in the vector-like type +Vector. Equal to the second element stored in the vector’s +tuple-like value type.

+

grb::matrix_key_t

+
template <typename Matrix>
+using matrix_key_t = std::remove_cvref_t<typename std::tuple_element<0, matrix_value_t<Matrix>>::type>;
+

Obtain the key type of the matrix. This is a tuple-like type used to +store each scalar value’s row and column indices.

+

grb::matrix_index_t

+
template <typename Matrix>
+using matrix_index_t = std::remove_cvref_t<typename std::tuple_element<0, matrix_key_t<Matrix>>::type>;
+

Obtain the integer-like type used to store matrix indices.

+

Algorithms

+

Execution Policy

+

Execution policies are objects that indicate the kind of parallelism +allowed when executing an algorithm. For versions of GraphBLAS +algorithms that support execution policies, users may pass in the +execution policies defined in the C++ standard library.

+ +

GraphBLAS implementations may also provide implementation-defined +execution policies. Implementations must define the execution behavior +for any execution policies they define.

+

Exceptions and Error +Handling

+

Exceptions may be thrown to indicate error conditions. A number of +exceptions are defined which will be thrown in different error +conditions.

+

GraphBLAS-Defined Exceptions

+ +

Other Exceptions

+ +

std::bad_alloc. - Some functions and methods may +allocate memory using a user-provided allocator, which may throw.

+ +

Multiply

+

The function grb::multiply in GraphBLAS is used to +multiply a matrix times a matrix, a matrix times a vector, or a vector +times a matrix, depending on the types of the input arguments.

+

Matrix Times Matrix

+
template <MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskMatrixRange M = grb::full_matrix_mask<>
+>
+multiply_result_t<A, B, Reduce, Combine>
+multiply(A&& a,                                                                         (1)
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{},
+         M&& mask = M{});
+
+template <MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine = grb::multiplies<>,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce = grb::plus<>,
+          MaskMatrixRange M = grb::full_matrix_mask<>,
+          MutableMatrixRange<grb::combine_result_t<A, B, Combine>> C,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+>
+void multiply(C&& c,                                                                    (2)
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              M&& mask = M{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskMatrixRange M = grb::full_matrix_mask<>
+>
+multiply_result_t<A, B, Reduce, Combine>
+multiply(ExecutionPolicy&& policy,                                                      (3)
+         A&& a,
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{},
+         M&& mask = M{});
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskMatrixRange M = grb::full_matrix_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableMatrixRange<grb::combine_result_t<A, B, Combine>> C
+>
+void multiply(ExecutionPolicy&& policy,                                                 (4)
+              C&& c,
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              M&& mask = M{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+

Matrix Times Vector

+
template <MatrixRange A,
+          VectorRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskVectorRange M = grb::full_vector_mask<>
+>
+mutiply_result<A, B, Reduce, Combine>
+multiply(A&& a,                                                                         (5)
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{},
+         M&& mask = M{});
+
+
+template <MatrixRange A,
+          VectorRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine = grb::multiplies<>,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce = grb::plus<>,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C,
+          BinaryOperator<grb::vector_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right<>
+>
+void multiply(C&& c,                                                                    (6)
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              M&& mask = M{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          VectorRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskVectorRange M = grb::full_vector_mask<>
+>
+mutiply_result<A, B, Reduce, Combine>
+multiply(A&& a,                                                                         (7)
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{},
+         M&& mask = M{});
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          VectorRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C
+>
+void multiply(C&& c,                                                                    (8)
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              M&& mask = M{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+

Vector Times Vector

+
template <VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+>
+mutiply_result<A, B, Reduce, Combine>
+multiply(A&& a,                                                                         (9)
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{});
+
+template <VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          BinaryOperator<grb::vector_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          std::assignable_from<grb::combine_result_t<A, B, Combine>> C
+>
+void multiply(C&& c,                                                                   (10)
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+>
+mutiply_result<A, B, Reduce, Combine>
+multiply(ExecutionPolicy&& policy,                                                     (11)
+         A&& a,
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{});
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          BinaryOperator<grb::vector_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          std::assignable_from<grb::combine_result_t<A, B, Combine>> C
+>
+void multiply(ExecutionPolicy&& policy,                                                (12)
+              C&& c,
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+

Vector Times Matrix

+
template <VectorRange A,
+          MatrixRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskVectorRange M = grb::full_vector_mask<>
+>
+mutiply_result<A, B, Reduce, Combine>
+multiply(A&& a,                                                                        (13)
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{},
+         M&& mask = M{});
+
+template <VectorRange A,
+          MatrixRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine = grb::multiplies<>,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce = grb::plus<>,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C,
+          BinaryOperator<grb::vector_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+>
+void multiply(C&& c,                                                                   (14)
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              M&& mask = M{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          MatrixRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskVectorRange M = grb::full_vector_mask<>
+>
+mutiply_result<A, B, Reduce, Combine>
+multiply(ExecutionPolicy&& policy,                                                     (15)
+         A&& a,
+         B&& b,
+         Reduce&& reduce = Reduce{},
+         Combine&& combine = Combine{},
+         M&& mask = M{});
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          MatrixRange B,
+          BinaryOperator<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+          BinaryOperator<grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>,
+                         grb::combine_result_t<A, B, Combine>> Reduce,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          BinaryOperator<grb::vector_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C
+>
+void multiply(ExecutionPolicy&& policy,                                                (16)
+              C&& c,
+              A&& a,
+              B&& b,
+              Reduce&& reduce = Reduce{},
+              Combine&& combine = Combine{},
+              M&& mask = M{},
+              Accumulate&& acc = Accumulate{},
+              bool merge = false);
+

Behavior is non-deterministic if reduce is not +associative or not commutative.

+

Parameters

+

policy - the execution policy to use

+

a - the left-hand side of the product being computed

+

b - the right-hand side of the product being +computed

+

reduce - a binary operator

+

combine - a binary operator

+

mask - write mask used to determine which elements of +the output will be computed

+

c - if given, the output object to which to write the +result

+

acc - the accumulator used to accumulate partial results +into the output object

+

merge - whether to merge in values from c +outside of the write area indicated by mask

+

Type Requirements

+ +

Return Value

+

If the output matrix or vector argument, c, is supplied, +no value is returned.

+

NOTE: `combine_result_t<A, B, Combine> is actually +incorrect here. Should be result of reduction.

+

If c is not supplied as an argument, returns the result +of the multiplication.

+
    +
  1. +
  2. +
  3. +
  4. +
+

In the case that a GraphBLAS matrix or vector is returned, its scalar +type is combine_result_t<A, B, Combine>, and its +index type is equal to either grb::matrix_index_t<A> +or grb::matrix_index_t<B>, whichever one has the +larger std::numeric_limits<T>::max(). An element of +the result at index location index will only be computed if +a scalar value equal to true when converted to +bool exists in mask, that is +grb::find(mask, index) != grb::end(mask) && bool(grb::get<1>(*grb::find(mask, index))).

+
Matrix Times Matrix
+

A generalized matrix times matrix multiplication is performed, as +defined in the GraphBLAS Math +Specification. Each element of the output is produced by combing the +elements in corresponding indices of a row of a and column +of b and using reduce to perform a reduction +to a single value.

+
Matrix Times Vector
+

A generalized matrix times vector multiplication is performed, as +defined in the GraphBLAS Math +Specification. Each element of the output vector is produced by +combining elements in each row of a with the corresponding +elements of the vector b and using reduce to +perform a reduction of these to a single value in the output vector.

+
Vector Times Vector
+

A generalized dot product is performed, as defined in the GraphBLAS Math +Specification. The corresponding elements of vectors a +and b are combined and reduced into a single value using +reduce.

+
Vector Times Matrix
+

A generalized matrix times vector multiplication is performed, as +defined in the GraphBLAS Math +Specification. Each element of the output vector is produced by +combining elements in each column of b with the +corresponding elements of the vector a and using +reduce to perform a reduction of these to a single value in +the output vector.

+

Complexity

+

Complexity is implementation-defined.

+

Exceptions

+

The exception grb::invalid_argument may be thrown if any +of the following conditions occur:

+
Matrix Times Matrix
+ +
Matrix Times Vector
+ +
Vector Times Vector
+ +
Vector Times Matrix
+ +

If the algorithm fails to allocate memory, +std::bad_alloc is thrown.

+

Notes

+

Example

+

ewise_union

+

Perform an element-wise union between two GraphBLAS matrices or +vectors.

+

Element-Wise Matrix Union

+
template <MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>
+>
+ewise_union_result_t<A, B, Combine>
+ewise_union(A&& a, B&& b, Combine&& combine, M&& mask = M{});                (1)
+
+template <MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableMatrixRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_union(C&& c, A&& a, B&& b,
+                 Combine&& combine, M&& mask = M{},
+                 Accumulate&& acc = Accumulate{},
+                 bool merge = false);                                        (2)
+
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>
+>
+ewise_union_result_t<A, B, Combine>
+ewise_union(ExecutionPolicy&& policy,
+            A&& a, B&& b,
+            Combine&& combine, M&& mask = M{});                              (3)
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableMatrixRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_union(ExecutionPolicy&& policy,
+                 C&& c, A&& a, B&& b,
+                 Combine&& combine, M&& mask = M{},
+                 Accumulate&& acc = Accumulate{},
+                 bool merge = false);                                        (4)
+

Element-Wise Vector Union

+
template <VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t<A>,
+                         grb::vector_scalar_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>
+>
+ewise_union_result_t<A, B, Combine>
+ewise_union(A&& a, B&& b, Combine&& combine, M&& mask = M{});                (5)
+
+template <VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t_t<A>,
+                         grb::vector_scalar_t_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_union(C&& c, A&& a, B&& b,
+                 Combine&& combine, M&& mask = M{},
+                 Accumulate&& acc = Accumulate{},
+                 bool merge = false);                                        (6)
+
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t<A>,
+                         grb::vector_scalar_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>
+>
+ewise_union_result_t<A, B, Combine>
+ewise_union(ExecutionPolicy&& policy,
+            A&& a, B&& b,
+            Combine&& combine, M&& mask = M{});                              (7)
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t_t<A>,
+                         grb::vector_scalar_t_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_union(ExecutionPolicy&& policy,
+                 C&& c, A&& a, B&& b,
+                 Combine&& combine, M&& mask = M{},
+                 Accumulate&& acc = Accumulate{},
+                 bool merge = false);                                        (8)
+

Parameters

+

policy - the execution policy to use

+

a - matrix or vector on the left-hand side of the +element-wise operation

+

b - matrix or vector on the right-hand side of the +element-wise operation

+

c - output matrix or vector in which to store the result +of the multiply operation

+

combine - binary operator used to combine elements of +a and b

+

mask - determines which parts of the output matrix will +be computed

+

acc - binary operator used to combine elements of the +result with stored elements in corresponding locations in +c

+

merge - flag declaring whether to merge in elements of +c outside the range indicated by mask

+

Type Requirements

+ +

Return Value

+

If the output matrix or vector parameter, c, is +supplied, no value is returned.

+

If the parameter c is not supplied, the function returns +a GraphBLAS matrix (1,3) or GraphBLAS vector (5,7) equal to the +element-wise union of a and b, with the binary +operator combine used to combine scalar values stored at +the same index and mask used to determine which parts of +the output are computed. For (1,3), the type of the return value +satisfies the requirements of MatrixRange, and for (5,7) +the type of the return value satisfies the requirements of +VectorRange. The return value has the same shape as +a and b. Index idx in the return +value holds a stored value if and only if an element exists at that +index in both a or b and an element equal to +true when cast to bool exists at that index in +mask. If a value exists at idx in +a but not in b, the return value will hold a +value equal to a[idx]. If a value exists in b +but not in a, it will hold a value equal to +b[idx]. If a value exists at idx in both +a and b, it will hold a value equal to +fn(a[idx], b[idx]).

+

Preconditions

+

The parameters a and b must share the same +shape. If an output object c is given, it must also have +the same shape. For the parameter mask, each dimension of +its shape must be equal to or greater than the corresponding dimension +of a and b’s shapes. fn must not +modify any element of a, b, or +mask.

+

Postconditions

+

In (2,4) and (6,8), an element-wise union is performed as described +in the GraphBLAS Math +Specification and the result written to c. In (1,3) and +(5,7), none of the input arguments will be modified, and the result is +returned as a value.

+

Exceptions

+

The exception grb::invalid_argument may be thrown if any +of the following conditions occur:

+ +

Notes

+

Example

+
#include <grb/grb.hpp>
+
+int main(int argc, char** argv) {
+  grb::matrix<float> x({10, 10});
+  grb::matrix<float> y({10, 10});
+
+  x[{0, 1}] = 12;
+  x[{2, 5}] = 12;
+  x[{2, 7}] = 12;
+  x[{5, 3}] = 12;
+
+  y[{0, 1}] = 12;
+  y[{1, 5}] = 12;
+  y[{2, 7}] = 12;
+  y[{5, 3}] = 12;
+
+  auto z = grb::ewise_union(x, y, grb::plus{});
+
+  grb::print(z);
+
+  return 0;
+}
+

ewise_intersection

+

Perform an element-wise intersection between two GraphBLAS matrices +or vectors.

+

Element-Wise Matrix +Intersection

+
template <MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>
+>
+ewise_intersection_result_t<A, B, Combine>
+ewise_intersection(A&& a, B&& b, Combine&& combine, M&& mask = M{});         (1)
+
+template <MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableMatrixRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_intersection(C&& c, A&& a, B&& b,
+                        Combine&& combine, M&& mask = M{},
+                        Accumulate&& acc = Accumulate{},
+                        bool merge = false);                                 (2)
+
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>
+>
+ewise_intersection_result_t<A, B, Combine>
+ewise_intersection(ExecutionPolicy&& policy,
+                   A&& a, B&& b,
+                   Combine&& combine, M&& mask = M{});                       (3)
+
+template <typename ExecutionPolicy,
+          MatrixRange A,
+          MatrixRange B,
+          BinaryOperator<grb::matrix_scalar_t<A>,
+                         grb::matrix_scalar_t<B>> Combine,
+          MaskMatrixRange M = grb::full_matrix_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableMatrixRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_intersection(ExecutionPolicy&& policy,
+                        C&& c, A&& a, B&& b,
+                        Combine&& combine, M&& mask = M{},
+                        Accumulate&& acc = Accumulate{},
+                        bool merge = false);                                 (4)
+

Element-Wise Vector +Intersection

+
template <VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t_t<A>,
+                         grb::vector_scalar_t_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>
+          >
+ewise_intersection_result_t<A, B, Combine, M>
+ewise_intersection(A&& a, B&& b, Combine&& combine, M&& mask = M{});         (5)
+
+template <VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t_t<A>,
+                         grb::vector_scalar_t_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_intersection(C&& c, A&& a, B&& b,
+                        Combine&& combine, M&& mask = M{},
+                        Accumulate&& acc = Accumulate{},
+                        bool merge = false);                                 (6)
+
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t_t<A>,
+                         grb::vector_scalar_t_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>
+          >
+ewise_intersection_result_t<A, B, Combine, M>
+ewise_intersection(ExecutionPolicy&& policy,
+                   A&& a, B&& b,
+                   Combine&& combine, M&& mask = M{});                       (7)
+
+template <typename ExecutionPolicy,
+          VectorRange A,
+          VectorRange B,
+          BinaryOperator<grb::vector_scalar_t_t<A>,
+                         grb::vector_scalar_t_t<B>> Combine,
+          MaskVectorRange M = grb::full_vector_mask<>,
+          BinaryOperator<grb::matrix_scalar_t<C>,
+                         grb::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+          MutableVectorRange<grb::combine_result_t<A, B, Combine>> C
+>
+void ewise_intersection(ExecutionPolicy&& policy,
+                        C&& c, A&& a, B&& b,
+                        Combine&& combine, M&& mask = M{},
+                        Accumulate&& acc = Accumulate{},
+                        bool merge = false);                                 (8)
+

Perform an element-wise intersection.

+

Parameters

+

policy - the execution policy to use

+

a - matrix or vector on the left-hand side of the +element-wise operation

+

b - matrix or vector on the right-hand side of the +element-wise operation

+

c - output matrix or vector in which to store the result +of the multiply operation

+

combine - binary operator used to combine elements of +a and b

+

mask - determines which parts of the output matrix will +be computed

+

acc - binary operator used to combine elements of the +result with stored elements in corresponding locations in +c

+

merge - flag declaring whether to merge in elements of +c outside the range indicated by mask

+

Type Requirements

+ +

Return Value

+

If the output matrix or vector parameter, c, is +supplied, no value is returned.

+

If the parameter c is not supplied, the function returns +a GraphBLAS matrix (1) or GraphBLAS vector (3) equal to the element-wise +intersection of a and b, with the binary +operator combine used to combine scalar values and +mask used to determine which parts of the output are +computed. For (1), the type of the return value satisfies the +requirements of MatrixRange, and for (3) the type of the +return value satisfies the requirements of VectorRange. The +return value has the same shape as a and b. +Index idx will only hold an element in the return value if +an element exists at idx in both a, +b, and mask, and the element of +mask holds a value equal to true when +converted to bool. The value at that index will be equal to +the value fn(a[idx], b[idx]).

+

Preconditions

+

The parameters a and b must share the same +shape. If an output object c is given, it must also have +the same shape. For the parameter mask, each dimension of +its shape must be equal to or greater than the corresponding dimension +of a and b’s shapes. fn must not +modify any element of a, b, or +mask.

+

Postconditions

+

In (2,4) and (6,8), an element-wise intersection is performed as +described in the GraphBLAS Math +Specification and the result written to c. In (1,3) and +(5,7), none of the input arguments will be modified, and the result is +returned as a value.

+

Exceptions

+

The exception grb::invalid_argument may be thrown if any +of the following conditions occur:

+ +

Notes

+

Example

+
#include <grb/grb.hpp>
+
+int main(int argc, char** argv) {
+  grb::matrix<float> x({10, 10});
+  grb::matrix<float> y({10, 10});
+
+  x[{0, 1}] = 12;
+  x[{2, 5}] = 12;
+  x[{2, 7}] = 12;
+  x[{5, 3}] = 12;
+
+  y[{0, 1}] = 12;
+  y[{1, 5}] = 12;
+  y[{2, 7}] = 12;
+  y[{5, 3}] = 12;
+
+  auto z = grb::ewise_intersection(x, y, grb::multiplies{});
+
+  grb::print(z);
+
+  return 0;
+}
+

assign

+
template <grb::MatrixRange B,
+          grb::MutableMatrixRange<grb::matrix_scalar_t<B>> A>
+void assign(A&& a, B&& b);                                                   (1)
+
+template <typename T, grb::MutableMatrixRange A<T>>
+void assign(A&& a, const T& value);                                          (2)
+
+
+template <grb::VectorRange V,
+          grb::MutableVectorRange<grb::vector_scalar_t<V> U>
+void assign(U&& u, V&& v);                                                   (3)
+
+
+template <typename T, grb::MutableVectorRange V<T>>
+void assign(U&& u, const T& value);                                          (4)
+

Assigns every element of a GraphbLAS matrix or vector to either (1, +3) another GraphBLAS matrix or vector with the same shape, or (2, 4) a +single scalar value.

+

Parameters

+

a - the matrix to be assigned

+

b - the matrix whose contents will be assigned to +a

+

u - the vector to be assigned

+

v - the vector whose contents will be assigned to +v

+

value - a scalar value to be assigned to every index +location in a

+

Type Requirements

+ +

Exceptions

+

The exception grb::invalid_argument is thrown if +a and b or u and v +are not the same shape. std::bad_alloc may be thrown if +a or u’s allocator is unable to allocate +memory.

+

Other exceptions may be thrown while assigning or constructing to +a or u.

+ +