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 @@ + + +
+ + + +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.
+This specification provides data structures for storing matrices and +vectors. These implement the matrix and vector range concepts also defined in this specification.
+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 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.
+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.
+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
.
// Define the `GRAPHBLAS_CPP_VERSION` macro to indicate
+// conformance to the GraphBLAS 0.1 Draft Specification.
+#define GRAPHBLAS_CPP_VERSION 202207L
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, 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?
+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.
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;
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 Type | +Definition | +
---|---|
scalar_type |
+T , the type of elements stored in the matrix |
+
index_type |
+I , an integer type used to store matrix indices |
+
key_type |
+A tuple-like type storing two index_type elements |
+
map_type |
+scalar_type |
+
value_type |
+grb::matrix_entry<T, I> , a tuple-like type
+storing the indices and the stored element |
+
size_type |
+A large unsigned integer type, usually std::size_t |
+
difference_type |
+A large signed integer type, usually
+std::ptrdiff_t |
+
allocator_type |
+Allocator |
+
iterator |
+An iterator type fulfilling std::forward_iterator |
+
const_iterator |
+A const iterator fulfilling std::forward_iterator |
+
reference |
+grb::matrix_reference<T, I> |
+
const_reference |
+grb::matrix_reference<const T, I> |
+
scalar_reference |
+Reference to scalar_type |
+
const_scalar_reference |
+Const reference to scalar_type |
+
hint_type |
+Hint |
+
Method | +Description | +
---|---|
(constructor) |
+Constructs matrix | +
(destructor) |
+Destructs matrix | +
operator= |
+Assigns matrix | +
size |
+Number of stored elements in matrix | +
max_size |
+Returns the maximum possible number of elements | +
empty |
+Return whether the matrix is empty | +
shape |
+Return the dimensions of the matrix | +
begin cbegin |
+Returns iterator to beginning of container | +
end cend |
+Returns iterator to one past last element in container | +
reshape |
+Modify dimensions of the matrix | +
clear |
+Clears all elements from the container | +
insert |
+Insert elements | +
insert_or_assign |
+Inserts or assigns elements | +
erase |
+Erases elements | +
find |
+Finds an element | +
at |
+Access element | +
operator[] |
+Access or insert element | +
grb::matrix::matrix
(const Allocator& alloc = Allocator()); (1)
+ matrix(grb::index<index_type> shape,
+ matrixconst Allocator& alloc = Allocator()); (2)
+ (const matrix& other); (3)
+ matrix(matrix&& other); (4) matrix
Constructs new grb::matrix
data structure.
0 x 0
.shape[0] x shape[1]
.other
.other
using move semantics. After the move,
+other
is guaranteed to be empty.shape
- shape of the matrix to be constructed
other
- another matrix to construct the new matrix
+from
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.
Linear in the size of the vector.
+grb::matrix::operator=
& operator=(const matrix& other); (1)
+ matrix& operator=(matrix&& other); (2) matrix
Replaces the matrix with the contents and shape of another +matrix.
+other
and copies the stored values to be
+the same as other
.other
using move semantics. After the move assignment
+operation completes, other
is in a valid but indeterminate
+state.other
- another matrix to assign the matrix to
Allocator::allocate
may throw.grb::matrix::size
size_type size() noexcept;
Returns the number of elements stored in the matrix.
+(none)
+Number of stored elements.
+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.
+(none)
+Maximum possible number of elements.
+Constant
+grb::matrix::empty
bool empty() noexcept;
Returns whether the matrix is empty, that is where
+size() == 0
.
(none)
+Whether the matrix is empty.
+Constant
+grb::matrix::shape
::index<I> shape() const noexcept; grb
Returns the dimensions of the matrix.
+(none)
+Dimensions of the matrix.
+Constant
+grb::matrix::begin
+and grb::matrix::cbegin
() noexcept;
+ iterator begin() const noexcept;
+ const_iterator begin() const noexcept; const_iterator cbegin
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()
.
(none)
+Iterator to the first element
+Constant
+grb::matrix::end
+and grb::matrix::cend
() noexcept;
+ iterator end() const noexcept;
+ const_iterator end() const noexcept; const_iterator cend
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.
+(none)
+Iterator to one past the last element.
+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
shape
- New matrix shape
None
+Implementation defined
+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.
+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.
+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.
and (3) Insert the element value
if an element does
+not already exist at the corresponding index in the matrix.
first
, last
- Range of elements to
+insert
value
- element to insert
None
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.
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))
.
k
- the index location to assign obj
obj
- the scalar value to be assigned
M
must fulfill
+std::is_assignable<scalar_type&, M>
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.
Implementation defined.
+grb::matrix::erase
size_type erase(grb::index<I> index);
Erases the element stored at index index
if one
+exists.
index
- the index of element to erase
Returns the number of elements erased (0 or 1).
+Implementation defined.
+grb::matrix::find
(grb::index<I> index);
+ iterator find(grb::index<I> index) const; const_iterator find
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()
.
index
- Location of the matrix element to find
An iterator pointing to the matrix element at the corresponding
+index, or end()
if there is no element at the location.
Implementation defined
+grb::matrix::operator[]
operator[](grb::index<I> index);
+ scalar_reference operator[](grb::index<I> index) const; const_scalar_reference
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.
index
- Location of the matrix element
A reference to the scalar value at location (index[0]
,
+[index[1]
).
Implementation defined
+grb::matrix::at
(grb::index<I> index);
+ scalar_reference at(grb::index<I> index) const; const_scalar_reference at
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
.
index
- Location of the matrix element
A reference to the scalar value at location (index[0]
,
+[index[1]
).
Implementation defined
+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;
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 Type | +Definition | +
---|---|
scalar_type |
+T , the type of scalar elements stored in the
+vector |
+
index_type |
+I , an integer type used to store vector indices |
+
key_type |
+index_type |
+
map_type |
+scalar_type |
+
value_type |
+grb::vector_entry<T, I> , a tuple-like type
+storing the indices and the stored element |
+
size_type |
+A large unsigned integer type, usually std::size_t |
+
difference_type |
+A large signed integer type, usually
+std::ptrdiff_t |
+
allocator_type |
+Allocator |
+
iterator |
+An iterator type fulfilling std::forward_iterator |
+
const_iterator |
+A const iterator fulfilling std::forward_iterator |
+
reference |
+grb::vector_ref<T, I> |
+
const_reference |
+grb::vector_ref<const T, I> |
+
scalar_reference |
+Reference to scalar_type |
+
const_scalar_reference |
+Const reference to scalar_type |
+
hint_type |
+Hint |
+
Method | +Description | +
---|---|
(constructor) |
+Constructs vector | +
size |
+Number of stored elements in vector | +
max_size |
+Returns the maximum possible number of elements | +
empty |
+Return whether the vector is empty | +
shape |
+Return the dimension of the vector | +
begin cbegin |
+Returns iterator to beginning of container | +
end cend |
+Returns iterator to one past last element in container | +
reshape |
+Modify the dimension of the vector | +
clear |
+Clears all elements from the container | +
insert |
+Insert elements | +
insert_or_assign |
+Inserts or assigns elements | +
find |
+Finds an element | +
operator[] |
+Access or insert element | +
grb::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) vector
Constructs new grb::vector
data structure.
shape
.shape
- shape of the vector to be constructed
May throw std::bad_alloc
.
grb::vector::size
size_type size() noexcept;
Returns the number of elements stored in the vector.
+(none)
+Number of stored elements.
+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.
+(none)
+Maximum possible number of elements.
+Constant
+grb::vector::empty
bool empty() noexcept;
Returns whether the vector is empty, that is where
+size() == 0
.
(none)
+Whether the vector is empty.
+Constant
+grb::vector::shape
index_type shape() const noexcept;
Returns the dimension of the vector.
+(none)
+Dimension of the vector.
+Constant
+grb::vector::begin
+and grb::vector::cbegin
() noexcept;
+ iterator begin() const noexcept;
+ const_iterator begin() const noexcept; const_iterator cbegin
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()
.
(none)
+Iterator to the first element
+Constant
+grb::vector::end
+and grb::vector::cend
() noexcept;
+ iterator end() const noexcept;
+ const_iterator end() const noexcept; const_iterator cend
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.
+(none)
+Iterator to one past the last element.
+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.
shape
- New vector shape
None
+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.
+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.
+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.
and (3) Insert the element value
if an element does
+not already exist at the corresponding index in the vector.
first
, last
- Range of elements to
+insert
value
- element to insert
None
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.
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))
.
k
- the index location to assign obj
obj
- the scalar value to be assigned
M
must fulfill
+std::is_assignable<scalar_type&, M>
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.
Implementation defined.
+grb::vector::erase
size_type erase(index_type index);
Erases the element stored at index index
if one
+exists.
index
- the index of the scalar value to erase
Returns the number of elements erased (0 or 1).
+Implementation defined.
+grb::vector::find
(index_type index);
+ iterator find(index_type index) const; const_iterator find
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()
.
index
- Location of the vector element to find
An iterator pointing to the vector element at the corresponding
+index, or end()
if there is no element at the location.
Implementation defined
+grb::vector::operator[]
operator[](index_type index);
+ scalar_reference operator[](index_type index) const; const_scalar_reference
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.
index
- Location of the vector element
A reference to the scalar value at location index
.
Implementation defined
+grb::vector::at
(index_type index);
+ scalar_reference at(index_type index) const; const_scalar_reference at
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
.
index
- Location of the vector element
A reference to the scalar value at location index
.
Implementation defined
+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.
T
- type, satisfying std::integral
, used to
+store indices
Member Type | +Definition | +
---|---|
index_type |
+T |
+
first_type |
+T |
+
second_type |
+T |
+
Member Name | +Type | +
---|---|
first |
+T |
+
second |
+T |
+
Method | +Description | +
---|---|
(constructor) |
+Constructs index | +
operator[] |
+Get one of the indices | +
get |
+Get one of the indices | +
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.
#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.
+ ::matrix<float, std::size_t, grb::dense> x({10, 10});
+ grb
+// Create a matrix with the compile-time hint compose<sparse, row>.
+ // A GraphBLAS implementation may choose to employ a compressed sparse row
+ // storage format.
+ ::matrix<float, std::size_t, grb::compose<grb::sparse, grb::row>> y({10, 10});
+ grb
+
+// No change in data structure semantics is implied by a hint.
+ [{2, 3}] = 12;
+ x[{3, 6}] = 12;
+ x
+[{6, 7}] = 1;
+ y[{6, 7}] = 2.5;
+ y
+::print(x);
+ grb::print(y);
+ grb
+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.
+namespace views {
+inline constexpr /* unspecified */ transpose = /* unspecified */;
+ }
template <MatrixRange M>
+auto transpose(M&& matrix); MatrixRange
matrix
- a GraphBLAS matrix or matrix view
M
must meet the requirements of
+MatrixRange
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.
namespace views {
+inline constexpr /* unspecified */ transform = /* unspecified */;
+ }
template <MatrixRange M, std::copy_constructible Fn>
+auto transform (M&& matrix, Fn&& fn); (1)
+ MatrixRange
+template <VectorRange V, std::copy_constructible Fn>
+auto transform(V&& vector, Fn&& fn); (2) VectorRange
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.
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.
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
M
must meet the requirements of
+MatrixRange
V
must meet the requirements of
+VectorRange
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
.
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
.
#include <grb/grb.hpp>
+
+int main(int argc, char** argv) {
+::matrix<float> a({10, 10});
+ grb
+[{1, 2}] = 12.0f;
+ a[{3, 4}] = 123.2f;
+ a[{7, 8}] = 8.0f;;
+ a
+::print(a, "original matrix");
+ grb
+// 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;
+ });
+
+::print(idx_view, "index transformed view");
+ grb
+return 0;
+ }
template <MatrixRange M>
+::structure_view<M> structure(M&& matrix); (1)
+ grb
+template <VectorRange V>
+::structure_view<V> structure(V&& vector); (2) grb
matrix
- a GraphBLAS matrix or matrix view
vector
- a GraphBLAS vector or vector view
matrix
must meet the requirements of
+MatrixRange
vector
must meet the requirements of
+VectorRange
inline constexpr bool always_true = [](auto&&) { return true; };
+
+template <typename O>
+using structure_view = grb::transform_view<O, decltype(always_true)>;
+
+template <MatrixRange M>
+::structure_view<M> structure(M&& matrix) {
+ grbreturn grb::transform(std::forward<M>(matrix), always_true);
+ }
+
+template <VectorRange V>
+::structure_view<V> structure(V&& vector) {
+ grbreturn grb::transform(std::forward<V>(vector), always_true);
+ }
template <MatrixRange M, typename Fn>
+::filter_view<M> filter(M&& matrix, Fn&& fn); (1)
+ grb
+template <VectorRange V, typename Fn>
+::filter_view<V> filter(V&& vector, Fn&& fn); (2) grb
matrix
- a GraphBLAS matrix
vector
- a GraphBLAS vector
fn
- a function determining which elements should be
+filtered out
M
must meet the requirements of
+MaskMatrixRange
V
must meet the requirements of
+MaskVectorRange
fn
must accept an argument of type
+std::ranges::value_type_t<M>
(1) or
+std::ranges::value_type_t<V>
(2) and return a value
+of type bool
.
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.
template <MaskMatrixRange M>
+::complement_view<M> complement(M&& mask); (1)
+ grb
+template <MaskVectorRange V>
+::complement_view<V> complement(V&& mask); (2) grb
mask
- a GraphBLAS mask
M
must meet the requirements of
+MaskMatrixRange
V
must meet the requirements of
+MaskVectorRange
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.
Returns a matrix view satisfying the requirements
+MaskMatrixRange
.
Returns a vector view satisfying the requirements
+MaskVectorRange
.
template <MatrixRange Matrix, MaskMatrixRange M>
+::masked_view<Matrix, M> mask(Matrix&& matrix, M&& mask); (1)
+ grb
+template <VectorRange Vector, MaskVectorRange M>
+::masked_view<Vector, M> mask(Vector&& vector, M&& mask); (2) grb
matrix
- a GraphBLAS matrix or vector
mask
- a GraphBLAS mask with the same shape as
+matrix
(1) or vector
(2)
Matrix
must meet the requirements of
+MatrixRange
Vector
must meet the requirements of
+VectorRange
M
must meet the requirements of
+MaskMatrixRange
(1) or MaskVectorRange
+(2)
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.
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.The exception grb::invalid_argument
is thrown if the
+mask
does not have the same shape as matrix
+(1) or vector
(2).
template <MatrixRange M>
+::submatrix_view<M> submatrix(M&& matrix, grb::index<I> rows, grb::index<I> cols); grb
matrix
- a GraphBLAS matrix
rows
- the span of rows in the submatrix view
cols
- the span of columns in the submatrix view
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.
Returns the exception grb::invalid_argument
if
+rows[0] > rows[1]
or
+cols[0] > cols[1]
.
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.
+They work the same way as binary operators, but are quite a bit +simpler, since there is only one value to operate upon.
+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:
op<T, U, V>
, where the input arguments are
+explicitly specified to be T
and U
and the
+return value is V
.op<T, U, void>
, where the input arguments are
+explicitly specified to be T
and U
, and the
+return value is deduced.op<void, void, void>
, where the inputs arguments
+and return type are all deduced upon invocation.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.
+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.
+ ::plus<> p1;
+ grb
+ 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;
+ }
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`.
+ ::plus<int> p1;
+ grb
+ int a = 1024;
+ int b = 12;
+
+ // int + int -> int
+ int c = p1(a, b);
+
+ return 0;
+ }
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`.
+ ::plus<std::size_t, std::uint8_t> p1;
+ grb
+ 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;
+ }
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`.
+ ::plus<std::size_t, std::uint8_t, int> p1;
+ grb
+ 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.
Specialization | +Description | +
---|---|
plus<void, void, void> |
+deduces argument and return types | +
plus<T, U, void> |
+deduces return type based on T and U |
+
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
Method | +Description | +
---|---|
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
.
lhs
, rhs
- values to sum
The result of lhs + rhs
.
May throw exceptions if the underlying operator+()
+operation throws exceptions
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
.
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.
Specialization | +Description | +
---|---|
multiplies<void, void, void> |
+deduces argument and return types | +
multiplies<T, U, void> |
+deduces return type based on T and U |
+
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
Method | +Description | +
---|---|
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
.
lhs
, rhs
- values to multiply
The result of lhs * rhs
.
May throw exceptions if the underlying operator*()
+operation throws exceptions
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
.
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.
Specialization | +Description | +
---|---|
minus<void, void, void> |
+deduces argument and return types | +
minus<T, U, void> |
+deduces return type based on T and U |
+
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
Method | +Description | +
---|---|
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
.
lhs
, rhs
- values to subtract
The result of lhs - rhs
.
May throw exceptions if the underlying operator-()
+operation throws exceptions
grb::minus
does not form a monoid for arithmetic
+types.
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.
Specialization | +Description | +
---|---|
divides<void, void, void> |
+deduces argument and return types | +
divides<T, U, void> |
+deduces return type based on T and U |
+
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
Method | +Description | +
---|---|
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
.
lhs
, rhs
- values to divide
The result of lhs / rhs
.
May throw exceptions if the underlying operator/()
+operation throws exceptions
grb::divides
does not form a monoid for arithmetic
+types.
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.
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.
Specialization | +Description | +
---|---|
max<void, void, void> |
+deduces argument and return types | +
max<T, U, void> |
+deduces return type based on T and U |
+
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
Method | +Description | +
---|---|
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
.
lhs
, rhs
- values to take the max of
The larger of lhs
and rhs
.
May throw exceptions if the underlying operator<()
+operation throws exceptions
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
.
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()),
+ , T
+ U>;
+
+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(),
+ , T
+ U>
+ 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()),
+ , T
+ U>;
+
+constexpr auto operator()(const T& a, const U& b) const
+-> std::conditional_t<
+ std::numeric_limits<T>::max() < std::numeric_limits<U>::max(),
+ , T
+ U>
+ 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.
Specialization | +Description | +
---|---|
min<void, void, void> |
+deduces argument and return types | +
min<T, U, void> |
+deduces return type based on T and U |
+
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
Method | +Description | +
---|---|
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
.
lhs
, rhs
- values to take the min of
The smaller of lhs
and rhs
.
May throw exceptions if the underlying operator<()
+operation throws exceptions
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
.
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()),
+ , T
+ U>;
+
+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(),
+ , T
+ U>
+ 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()),
+ , T
+ U>;
+
+constexpr auto operator()(const T& a, const U& b) const
+-> std::conditional_t<
+ std::numeric_limits<U>::lowest() < std::numeric_limits<T>::lowest(),
+ , T
+ U>
+ requires(!(std::is_integral_v<T> && std::is_integral_v<U>));
TODO: need “disablers” for all these CPOs. Also, “converted to +its decayed type?”
+grb::get
inline constexpr /* unspecified */ get = /* unspecified */;
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:
tuple.get<I>()
, if that expression is valid.get(tuple)
found through
+argument-dependent lookup.std::get<I>(tuple)
.In all other cases, a call to grb::get
is
+ill-formed.
grb::size
template <typename T>
+inline constexpr /* unspecified */ size = std::ranges::size;
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:
t.size()
, if that expression is valid.size(t)
, found through
+argument-dependent lookup.In all other cases, a call to grb::size
is
+ill-formed.
grb::shape
template <typename T>
+inline constexpr /* unspecified */ shape = /* unspecified */;
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:
t.shape()
if that expression is valid.shape(t)
, if that expression is valid,
+including any declarations of shape
found through
+argument-dependent lookup.In all other cases, a call to grb::shape
is
+ill-formed.
grb::find
template <typename T>
+inline constexpr /* unspecified */ find = /* unspecified */;
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:
r.find(t)
if that expression is valid.find(r, t)
found through
+argument-dependent lookup.std::find(r, t)
, if that
+expression is valid.In all other cases, a call to grb::find
is
+ill-formed.
grb::insert
template <typename T>
+inline constexpr /* unspecified */ insert = /* unspecified */;
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:
r.insert(t)
if that expression is valid.insert(r, t)
found through
+argument-dependent lookup.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>>
+ ::matrix<T, I, Hint, Allocator>
+ grb(std::string file_path); read_matrix
Constructs a new GraphBLAS matrix based on the contents of a +file.
+T
- type of scalar values stored in matrix
I
- type of matrix indices
Hint
- compile-time hint for backend storage format.
Allocator
- allocator type
file_path
- string holding the file path of the matrix
+to be read
Returns a GraphBLAS matrix whose dimensions and contents correspond
+to the file located at file_path
.
Complexity is implementation-defined.
+file_path
cannot be read, the exception
+grb::matrix_io::file_error
is thrown.file_path
is recognized as an
+unsupported format, the exception
+grb::matrix_io::unsupported_file_format
is thrown.Allocator::allocate
may throw.GraphBLAS implementations must define the file formats that they +support. Implementations are strongly encouraged to support the +MatrixMarket format.
+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
.
Fn
can be invoked with two arguments
+of type T
and U
.V
.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>;
+ };
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.
// 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(); };
+ (fn, 12, 13);
+ apply}
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.
Fn
fulfills the concept
+BinaryOperator<T, T, T>
for some type
+T
.T
.T
,
+accessible using
+grb::monoid_traits<Fn, T>::identity()
.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 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.
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)
.T
is
+accessible using std::tuple_element
, with the N’th stored
+value equal to the N’th type in Types
.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
._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>>>());
// 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;
+ ("%d, %d, %f\n", i, j, v);
+ printf}
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.
Entry
is a tuple-like type with a size of 2.Entry
+is a tuple-like type fulfilling TupleLike<I, I>
,
+storing the row and column index of the matrix entry.Entry
+holds the matrix entry’s scalar value, and is convertible to
+T
.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>; };
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.
Entry
, representing the
+scalar value, is assignable to elements of type U
.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>;
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.
M
has a scalar type of the stored values, accessible
+with grb::matrix_scalar_t<M>
M
has an index type used to reference the indices of
+the stored values, accessible with
+grb::matrix_index_t<M>
.M
is a range with a value type that represents a matrix
+tuple, containing both the index and scalar value for each stored
+value.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
.M
has a method find()
that takes an index
+tuple and returns an iterator.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>,
+ ::matrix_index_t<M>>;
+ grb{grb::shape(matrix)} -> Tuplelike<grb::matrix_index_t<M>,
+ ::matrix_index_t<M>>;
+ grb{grb::find(matrix, {grb::matrix_index_t<M>{}, grb::matrix_index_t<M>{}})}
+ -> std::convertible_to<std::ranges::iterator_t<M>>;
+ };
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.
M
is a matrix range.M
fulfills the requirements of
+MutableMatrixEntry<T, I>
.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.template <typename M, typename T>
+concept MutableMatrixRange = MatrixRange<M> &&
+<std::ranges::range_value_t<M>
+ MutableMatrixEntry::matrix_scalar_t<M>,
+ grb::matrix_index_t<M>,
+ grb> &&
+ Trequires(M matrix, T value) {
+ {grb::insert(matrix, {{grb::matrix_index_t<M>{}, grb::matrix_index_t<M>{}},
+ }) -> std::ranges::iterator_t<M>;
+ value}
+ };
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.
M
is a matrix range.M
is convertible to
+bool
.template <typename M>
+concept MaskMatrixRange = MatrixRange<M> &&
+std::is_convertible_v<grb::matrix_scalar_t<M>, bool>;
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.
Entry
is a tuple-like type with a size of 2.Entry
+fulfills std::integral
.Entry
+holds the vector’s scalar value, and is convertible to
+T
.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>; };
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.
Entry
, representing the
+scalar value, is assignable to elements of type U
.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>;
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.
+V
has a scalar type of the stored values, accessible
+with grb::vector_scalar_t<V>
V
has an index type used to reference the indices of
+the stored values, accessible with
+grb::vector_index_t<V>
.V
is a range with a value type that represents a vector
+tuple, containing both the index and scalar value for each stored
+value.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
.V
has a method find()
that takes an index
+and returns an iterator.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>,
+ ::vector_index_t<V>>;
+ grb{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>>;
+ };
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.
V
is a vector range.M
fulfills the requirements of
+MutableVectorEntry<T, I>
.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.template <typename V, typename T>
+concept MutableVectorRange = VectorRange<V> &&
+<std::ranges::range_value_t<V>,
+ MutableVectorEntry::vector_scalar_t<V>,
+ grb::vector_index_t<V>,
+ grb> &&
+ Trequires(V vector, T value) {
+ {grb::insert(vector, {grb::vector_index_t<V>{}, value})}
+ -> std::same_as<std::ranges::iterator_t<V>>;
+ };
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.
M
is a vector range.M
is convertible to
+bool
.template <typename M>
+concept MaskVectorRange = VectorRange<M> &&
+std::is_convertible_v<grb::vector_scalar_t<M>, bool>;
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.
Fn
- type of commutative binary operator
T
- type on which Fn
forms a commutative
+monoid
Member Type | +Definition | +Description | +
---|---|---|
type |
+T |
+type of the monoid | +
The default specialization has the following member functions:
+Function | +Description | ++ |
---|---|---|
identity |
+the identity value of the monoid | ++ |
grb::monoid_traits<Fn, T>::identity
static constexpr T identity() noexcept;
Returns the identity of the monoid.
+None
+Constant
+May not throw exceptions
+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>();
+ }
+ }
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.
+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.
+std::execution::sequenced_policy
std::execution::parallel_policy
std::execution::parallel_unsequenced_policy
std::execution::unsequenced_policy
GraphBLAS implementations may also provide implementation-defined +execution policies. Implementations must define the execution behavior +for any execution policies they define.
+Exceptions may be thrown to indicate error conditions. A number of +exceptions are defined which will be thrown in different error +conditions.
+grb::out_of_range
is thrown if an index is provided
+which lies outside the dimensions of the matrix, or if a value is not
+present at the index.
grb::matrix_io::file_error
is thrown if a file
+cannot be read.
grb::invalid_argument
is thrown if objects’
+dimensions are incompatible.
std::bad_alloc
. - Some functions and methods may
+allocate memory using a user-provided allocator, which may throw.
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.
template <MatrixRange A,
+,
+ MatrixRange B<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_matrix_mask<>
+ MaskMatrixRange M >
+multiply_result_t<A, B, Reduce, Combine>
+(A&& a, (1)
+ multiply&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{});
+ M
+template <MatrixRange A,
+,
+ MatrixRange B<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine = grb::multiplies<>,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce = grb::plus<>,
+ grb= grb::full_matrix_mask<>,
+ MaskMatrixRange M <grb::combine_result_t<A, B, Combine>> C,
+ MutableMatrixRange<grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb>
+void multiply(C&& c, (2)
+&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{},
+ M&& acc = Accumulate{},
+ Accumulatebool merge = false);
+
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ MatrixRange B<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_matrix_mask<>
+ MaskMatrixRange M >
+multiply_result_t<A, B, Reduce, Combine>
+(ExecutionPolicy&& policy, (3)
+ multiply&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{});
+ M
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ MatrixRange B<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_matrix_mask<>,
+ MaskMatrixRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableMatrixRange>
+void multiply(ExecutionPolicy&& policy, (4)
+&& c,
+ C&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{},
+ M&& acc = Accumulate{},
+ Accumulatebool merge = false);
template <MatrixRange A,
+,
+ VectorRange B<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+<A, B, Reduce, Combine>
+ mutiply_result(A&& a, (5)
+ multiply&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{});
+ M
+
+template <MatrixRange A,
+,
+ VectorRange B<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine = grb::multiplies<>,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce = grb::plus<>,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::combine_result_t<A, B, Combine>> C,
+ MutableVectorRange<grb::vector_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right<>
+ grb>
+void multiply(C&& c, (6)
+&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{},
+ M&& acc = Accumulate{},
+ Accumulatebool merge = false);
+
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ VectorRange B<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+<A, B, Reduce, Combine>
+ mutiply_result(A&& a, (7)
+ multiply&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{});
+ M
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ VectorRange B<grb::matrix_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableVectorRange>
+void multiply(C&& c, (8)
+&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{},
+ M&& acc = Accumulate{},
+ Accumulatebool merge = false);
template <VectorRange A,
+,
+ VectorRange B<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb>
+<A, B, Reduce, Combine>
+ mutiply_result(A&& a, (9)
+ multiply&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{});
+ Combine
+template <VectorRange A,
+,
+ VectorRange B<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb<grb::vector_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grbstd::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&& acc = Accumulate{},
+ Accumulatebool merge = false);
+
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ VectorRange B<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb>
+<A, B, Reduce, Combine>
+ mutiply_result(ExecutionPolicy&& policy, (11)
+ multiply&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{});
+ Combine
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ VectorRange B<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb<grb::vector_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grbstd::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&& acc = Accumulate{},
+ Accumulatebool merge = false);
template <VectorRange A,
+,
+ MatrixRange B<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+<A, B, Reduce, Combine>
+ mutiply_result(A&& a, (13)
+ multiply&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{});
+ M
+template <VectorRange A,
+,
+ MatrixRange B<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine = grb::multiplies<>,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce = grb::plus<>,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::combine_result_t<A, B, Combine>> C,
+ MutableVectorRange<grb::vector_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb>
+void multiply(C&& c, (14)
+&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{},
+ M&& acc = Accumulate{},
+ Accumulatebool merge = false);
+
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ MatrixRange B<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+<A, B, Reduce, Combine>
+ mutiply_result(ExecutionPolicy&& policy, (15)
+ multiply&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{});
+ M
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ MatrixRange B<grb::vector_scalar_t<A>, grb::matrix_scalar_t<B>> Combine,
+ BinaryOperator<grb::combine_result_t<A, B, Combine>,
+ BinaryOperator::combine_result_t<A, B, Combine>,
+ grb::combine_result_t<A, B, Combine>> Reduce,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::vector_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableVectorRange>
+void multiply(ExecutionPolicy&& policy, (16)
+&& c,
+ C&& a,
+ A&& b,
+ B&& reduce = Reduce{},
+ Reduce&& combine = Combine{},
+ Combine&& mask = M{},
+ M&& acc = Accumulate{},
+ Accumulatebool merge = false);
Behavior is non-deterministic if reduce
is not
+associative or not commutative.
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
A
must meet the requirements of
+MatrixRange
(1-8) or VectorRange
+(9-16)
B
must meet the requirements of
+MatrixRange
(1-4,13-16) or VectorRange
+(5-12)
Reduce
must meet the requirements of
+BinaryOperator<grb::combine_result_type_t<A, B, Combine>, grb::combine_result_type_t<A, B, Combine>, grb::combine_result_type_t<A, B, Combine>>
Combine
must meet the requirements of
+BinaryOperator<grb::container_value_t<A>, grb::container_value_t<B>>
M
must meet the requirements of
+MaskMatrixRange
(1-8) or VectorMaskRange
+(9-16)
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.
a.shape()[0]
by
+b.shape()[1]
a.shape()[0]
combine_result_t<A, B, Combine>
b.shape()[1]
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)))
.
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.
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.
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
.
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 is implementation-defined.
+The exception grb::invalid_argument
may be thrown if any
+of the following conditions occur:
a.shape()[1] != b.shape()[0]
.mask.shape()[0] < a.shape()[0] || mask.shape()[1] < b.shape()[1]
c.shape()[0] != a.shape()[0] || c.shape()[1] != b.shape()[1]
.a.shape()[1] != b.shape()
.mask.shape() < a.shape()[0]
c.shape() != a.shape()[0]
.a.shape() != b.shape()
.mask.shape() < a.shape()[0]
c.shape() != a.shape()[0]
.a.shape() != b.shape()[0]
.mask.shape() < b.shape()[1]
c.shape() != b.shape()[1]
.If the algorithm fails to allocate memory,
+std::bad_alloc
is thrown.
ewise_union
Perform an element-wise union between two GraphBLAS matrices or +vectors.
+template <MatrixRange A,
+,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>
+ MaskMatrixRange M >
+ewise_union_result_t<A, B, Combine>
+(A&& a, B&& b, Combine&& combine, M&& mask = M{}); (1)
+ ewise_union
+template <MatrixRange A,
+,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>,
+ MaskMatrixRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableMatrixRange>
+void ewise_union(C&& c, A&& a, B&& b,
+&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (2)
+
+
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>
+ MaskMatrixRange M >
+ewise_union_result_t<A, B, Combine>
+(ExecutionPolicy&& policy,
+ ewise_union&& a, B&& b,
+ A&& combine, M&& mask = M{}); (3)
+ Combine
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>,
+ MaskMatrixRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableMatrixRange>
+void ewise_union(ExecutionPolicy&& policy,
+&& c, A&& a, B&& b,
+ C&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (4)
template <VectorRange A,
+,
+ VectorRange B<grb::vector_scalar_t<A>,
+ BinaryOperator::vector_scalar_t<B>> Combine,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+ewise_union_result_t<A, B, Combine>
+(A&& a, B&& b, Combine&& combine, M&& mask = M{}); (5)
+ ewise_union
+template <VectorRange A,
+,
+ VectorRange B<grb::vector_scalar_t_t<A>,
+ BinaryOperator::vector_scalar_t_t<B>> Combine,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableVectorRange>
+void ewise_union(C&& c, A&& a, B&& b,
+&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (6)
+
+
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ VectorRange B<grb::vector_scalar_t<A>,
+ BinaryOperator::vector_scalar_t<B>> Combine,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+ewise_union_result_t<A, B, Combine>
+(ExecutionPolicy&& policy,
+ ewise_union&& a, B&& b,
+ A&& combine, M&& mask = M{}); (7)
+ Combine
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ VectorRange B<grb::vector_scalar_t_t<A>,
+ BinaryOperator::vector_scalar_t_t<B>> Combine,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableVectorRange>
+void ewise_union(ExecutionPolicy&& policy,
+&& c, A&& a, B&& b,
+ C&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (8)
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
A
must meet the requirements of
+MatrixRange
(1,2,3,4) or VectorRange
+(5,6,7,8).
B
must meet the requirements of
+MatrixRange
(1,2,3,4) or VectorRange
+(5,6,7,8).
C
must meet the requirements of
+MutableMatrixRange<grb::combine_result_t<A, B, Combine>>
+(2,4) or
+MutableVectorRange<grb::combine_result_t<A, B, Combine>>
+(6,8).
Combine
must meet the requirements of
+BinaryOperator<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>>
+(1,2,3,4) or
+BinaryOperator<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>>
+(5,6,7,8).
M
must meet the requirements of
+MaskMatrixRange
(1,2,3,4) or MaskVectorRange
+(5,6,7,8).
Accumulate
must meet the requirements of
+BinaryOperator<grb::matrix_scalar_t<C>, grb::combine_result_t<A, B, Combine>>
+(2,4) or
+BinaryOperator<grb::vector_scalar_t<C>, grb::combine_result_t<A, B, Combine>>
+(6,8).
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])
.
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
.
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.
The exception grb::invalid_argument
may be thrown if any
+of the following conditions occur:
a
and b
incompatible,
+that is a.shape() != b.shape()
.c
, if given, does not match
+a
’s shape, that is c.shape() != a.shape()
mask.shape()[0] < a.shape()[0] || mask.shape()[1] < a.shape()[1]
+(1,2,3,4) or mask.shape() < a.shape()
in (5,6,7,8).#include <grb/grb.hpp>
+
+int main(int argc, char** argv) {
+::matrix<float> x({10, 10});
+ grb::matrix<float> y({10, 10});
+ grb
+[{0, 1}] = 12;
+ x[{2, 5}] = 12;
+ x[{2, 7}] = 12;
+ x[{5, 3}] = 12;
+ x
+[{0, 1}] = 12;
+ y[{1, 5}] = 12;
+ y[{2, 7}] = 12;
+ y[{5, 3}] = 12;
+ y
+auto z = grb::ewise_union(x, y, grb::plus{});
+
+::print(z);
+ grb
+return 0;
+ }
ewise_intersection
Perform an element-wise intersection between two GraphBLAS matrices +or vectors.
+template <MatrixRange A,
+,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>
+ MaskMatrixRange M >
+ewise_intersection_result_t<A, B, Combine>
+(A&& a, B&& b, Combine&& combine, M&& mask = M{}); (1)
+ ewise_intersection
+template <MatrixRange A,
+,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>,
+ MaskMatrixRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableMatrixRange>
+void ewise_intersection(C&& c, A&& a, B&& b,
+&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (2)
+
+
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>
+ MaskMatrixRange M >
+ewise_intersection_result_t<A, B, Combine>
+(ExecutionPolicy&& policy,
+ ewise_intersection&& a, B&& b,
+ A&& combine, M&& mask = M{}); (3)
+ Combine
+template <typename ExecutionPolicy,
+,
+ MatrixRange A,
+ MatrixRange B<grb::matrix_scalar_t<A>,
+ BinaryOperator::matrix_scalar_t<B>> Combine,
+ grb= grb::full_matrix_mask<>,
+ MaskMatrixRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableMatrixRange>
+void ewise_intersection(ExecutionPolicy&& policy,
+&& c, A&& a, B&& b,
+ C&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (4)
template <VectorRange A,
+,
+ VectorRange B<grb::vector_scalar_t_t<A>,
+ BinaryOperator::vector_scalar_t_t<B>> Combine,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+ ewise_intersection_result_t<A, B, Combine, M>
+(A&& a, B&& b, Combine&& combine, M&& mask = M{}); (5)
+ ewise_intersection
+template <VectorRange A,
+,
+ VectorRange B<grb::vector_scalar_t_t<A>,
+ BinaryOperator::vector_scalar_t_t<B>> Combine,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableVectorRange>
+void ewise_intersection(C&& c, A&& a, B&& b,
+&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (6)
+
+
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ VectorRange B<grb::vector_scalar_t_t<A>,
+ BinaryOperator::vector_scalar_t_t<B>> Combine,
+ grb= grb::full_vector_mask<>
+ MaskVectorRange M >
+ ewise_intersection_result_t<A, B, Combine, M>
+(ExecutionPolicy&& policy,
+ ewise_intersection&& a, B&& b,
+ A&& combine, M&& mask = M{}); (7)
+ Combine
+template <typename ExecutionPolicy,
+,
+ VectorRange A,
+ VectorRange B<grb::vector_scalar_t_t<A>,
+ BinaryOperator::vector_scalar_t_t<B>> Combine,
+ grb= grb::full_vector_mask<>,
+ MaskVectorRange M <grb::matrix_scalar_t<C>,
+ BinaryOperator::combine_result_t<A, B, Combine>> Accumulate = grb::take_right,
+ grb<grb::combine_result_t<A, B, Combine>> C
+ MutableVectorRange>
+void ewise_intersection(ExecutionPolicy&& policy,
+&& c, A&& a, B&& b,
+ C&& combine, M&& mask = M{},
+ Combine&& acc = Accumulate{},
+ Accumulatebool merge = false); (8)
Perform an element-wise intersection.
+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
A
must meet the requirements of
+MatrixRange
(1,2,3,4) or VectorRange
+(5,6,7,8).
B
must meet the requirements of
+MatrixRange
(1,2,3,4) or VectorRange
+(5,6,7,8).
C
must meet the requirements of
+MutableMatrixRange<grb::combine_result_t<A, B, Combine>>
+(2,4) or
+MutableVectorRange<grb::combine_result_t<A, B, Combine>>
+(6,8).
Combine
must meet the requirements of
+BinaryOperator<grb::matrix_scalar_t<A>, grb::matrix_scalar_t<B>>
+(1,2,3,4) or
+BinaryOperator<grb::vector_scalar_t<A>, grb::vector_scalar_t<B>>
+(5,6,7,8).
M
must meet the requirements of
+MaskMatrixRange
(1,2,3,4) or MaskVectorRange
+(5,6,7,8).
Accumulate
must meet the requirements of
+BinaryOperator<grb::matrix_scalar_t<C>, grb::combine_result_t<A, B, Combine>>
+(2,4) or
+BinaryOperator<grb::vector_scalar_t<C>, grb::combine_result_t<A, B, Combine>>
+(6,8).
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])
.
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
.
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.
The exception grb::invalid_argument
may be thrown if any
+of the following conditions occur:
a
and b
incompatible,
+that is a.shape() != b.shape()
.c
, if given, does not match
+a
’s shape, that is c.shape() != a.shape()
mask.shape()[0] < a.shape()[0] || mask.shape()[1] < a.shape()[1]
+(1,2,3,4) or mask.shape() < a.shape()
(5,6,7,8).#include <grb/grb.hpp>
+
+int main(int argc, char** argv) {
+::matrix<float> x({10, 10});
+ grb::matrix<float> y({10, 10});
+ grb
+[{0, 1}] = 12;
+ x[{2, 5}] = 12;
+ x[{2, 7}] = 12;
+ x[{5, 3}] = 12;
+ x
+[{0, 1}] = 12;
+ y[{1, 5}] = 12;
+ y[{2, 7}] = 12;
+ y[{5, 3}] = 12;
+ y
+auto z = grb::ewise_intersection(x, y, grb::multiplies{});
+
+::print(z);
+ grb
+return 0;
+ }
assign
template <grb::MatrixRange B,
+::MutableMatrixRange<grb::matrix_scalar_t<B>> A>
+ grbvoid 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,
+::MutableVectorRange<grb::vector_scalar_t<V> U>
+ grbvoid 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.
+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
A
must be a mutable matrix range for the scalar
+value being assigned, that is it must meet the requirements of
+grb::MutableMatrixRange<grb::matrix_scalar_t<B>>
+(1) or grb::MutableMatrixRange<T>
(2)
B
must meet the requirements of
+grb::MatrixRange
U
must be a mutable vector range for the scalar
+value being assigned, that is it must meet the requirements of
+grb::MutableVectorRange<grb::vector_scalar_t<V>
+(3) or grb::MutableVectorRange<T>
(4)
V
must meet the requirements of
+grb::VectorRange
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
.