1\documentclass[12pt]{article} 2\batchmode 3\usepackage{url} 4\urlstyle{sf} 5\usepackage[svgnames]{xcolor} 6\usepackage[colorlinks,linkcolor=Blue,citecolor=Blue,urlcolor=Blue]{hyperref} 7\usepackage{amssymb} 8\usepackage{amsmath} 9\usepackage{framed} 10\usepackage{mdframed} 11% \usepackage{geometry} 12% \usepackage{pdflscape} 13\newmdenv[backgroundcolor=white]{spec} 14\newmdenv[backgroundcolor=yellow]{alert} 15\hyphenation{Suite-Sparse} 16\hyphenation{Graph-BLAS} 17\hyphenation{Suite-Sparse-Graph-BLAS} 18 19\DeclareMathOperator{\sech}{sech} 20\DeclareMathOperator{\csch}{csch} 21\DeclareMathOperator{\arcsec}{arcsec} 22\DeclareMathOperator{\arccot}{arcCot} 23\DeclareMathOperator{\arccsc}{arcCsc} 24\DeclareMathOperator{\arccosh}{arcCosh} 25\DeclareMathOperator{\arcsinh}{arcsinh} 26\DeclareMathOperator{\arctanh}{arctanh} 27\DeclareMathOperator{\arcsech}{arcsech} 28\DeclareMathOperator{\arccsch}{arcCsch} 29\DeclareMathOperator{\arccoth}{arcCoth} 30\DeclareMathOperator{\sgn}{sgn} 31\DeclareMathOperator{\erf}{erf} 32\DeclareMathOperator{\erfc}{erfc} 33 34\newenvironment{packed_itemize}{ 35\begin{itemize} 36 \setlength{\itemsep}{1pt} 37 \setlength{\parskip}{0pt} 38 \setlength{\parsep}{0pt} 39}{\end{itemize}} 40 41\title{User Guide for SuiteSparse:GraphBLAS} 42 43\author{Timothy A. Davis \\ 44\small 45davis@tamu.edu, Texas A\&M University. \\ 46\small 47\url{http://suitesparse.com} \\ 48\small 49\url{https://people.engr.tamu.edu/davis} \\ 50\small 51\url{https://twitter.com/DocSparse} 52} 53 54% version and date are set by cmake 55\input{GraphBLAS_version.tex} 56 57%------------------------------------------------------------------------------- 58\begin{document} 59%------------------------------------------------------------------------------- 60\maketitle 61 62\begin{abstract} 63SuiteSparse:GraphBLAS is a full implementation of the GraphBLAS standard, 64which defines a set of sparse matrix operations on an extended algebra of 65semirings using an almost unlimited variety of operators and types. When 66applied to sparse adjacency matrices, these algebraic operations are equivalent 67to computations on graphs. GraphBLAS provides a powerful and expressive 68framework for creating high-performance graph algorithms based on the elegant 69mathematics of sparse matrix operations on a semiring. 70 71\vspace{1in} 72SuiteSparse:GraphBLAS is under the Apache-2.0 license, except for 73the \verb'@GrB' MATLAB interface, which is licensed under the GNU GPLv3 (or 74later). Refer to the SPDX license identifier in each file for details. Note 75that all of the compiled \verb'libgraphblas.so' is under the Apache-2.0 76license. 77 78\end{abstract} 79 80\newpage 81{\small 82\tableofcontents 83} 84 85\newpage 86%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 87\section{Introduction} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 88%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 89\label{intro} 90 91The GraphBLAS standard defines sparse matrix and vector operations on an 92extended algebra of semirings. The operations are useful for creating a wide 93range of graph algorithms. 94 95For example, consider the matrix-matrix multiplication, ${\bf C=AB}$. Suppose 96${\bf A}$ and ${\bf B}$ are sparse $n$-by-$n$ Boolean adjacency matrices of two 97undirected graphs. If the matrix multiplication is redefined to use logical 98AND instead of scalar multiply, and if it uses the logical OR instead of add, 99then the matrix ${\bf C}$ is the sparse Boolean adjacency matrix of a graph 100that has an edge $(i,j)$ if node $i$ in ${\bf A}$ and node $j$ in ${\bf B}$ 101share any neighbor in common. The OR-AND pair forms an algebraic semiring, and 102many graph operations like this one can be succinctly represented by matrix 103operations with different semirings and different numerical types. GraphBLAS 104provides a wide range of built-in types and operators, and allows the user 105application to create new types and operators without needing to recompile the 106GraphBLAS library. 107 108For more details on SuiteSparse:GraphBLAS, and its use in LAGraph, see 109\cite{Davis18,Davis18b,DavisAznavehKolodziej19,Davis20,Mattson19}. 110 111A full and precise definition of the GraphBLAS specification is provided in 112{\em The GraphBLAS C API Specification} by {Ayd\i n Bulu\c{c}, Timothy Mattson, 113Scott McMillan, Jos\'e Moreira, Carl Yang, and Benjamin Brock} 114\cite{BulucMattsonMcMillanMoreiraYang17,spec}, based on {\em GraphBLAS 115Mathematics} by Jeremy Kepner \cite{Kepner2017}. The GraphBLAS C API 116Specification is available at \url{http://graphblas.org}. This version of 117SuiteSparse:GraphBLAS conforms to Version \input{GraphBLAS_API_version.tex} of 118{\em The GraphBLAS C API specification}. 119 120In this User Guide, aspects of the GraphBLAS specification that would be true 121for any GraphBLAS implementation are simply called ``GraphBLAS.'' Details 122unique to this particular implementation are referred to as 123SuiteSparse:GraphBLAS. 124 125All functions, objects, and macros with a name of the form \verb'GxB_*' are 126SuiteSparse-specific extensions to the spec. 127 128\begin{alert} 129{\bf SPEC:} Non-obvious deviations or additions to the v1.3 GraphBLAS C API 130Specification are highlighted in a box like this one, except for \verb'GxB*' 131methods. They are not highlighted since their name makes it clear that they 132are extensions to the v1.3 GraphBLAS C API. 133\end{alert} 134 135\newpage 136%------------------------------------------------------------------------------- 137\subsection{Release Notes} 138%------------------------------------------------------------------------------- 139 140\begin{itemize} 141 142\item Version 5.0.5 (May 17, 2021) 143 144 \begin{packed_itemize} 145 \item (26) performance bug fix: reduce-to-vector where \verb'A' is 146 hypersparse CSR with a transposed descriptor (or CSC with no 147 transpose), and some cases for \verb'GrB_mxm/mxv/vxm' when computing 148 \verb'C=A*B' with A hypersparse CSC and \verb'B' bitmap/full (or 149 \verb'A' bitmap/full and \verb'B' hypersparse CSR), the wrong internal 150 method was being selected via the auto-selection strategy, resulting in 151 a significant slowdown in some cases. 152 \end{packed_itemize} 153 154\item Version 5.0.4 (May 13, 2021) 155 156 \begin{packed_itemize} 157 \item \verb'@GrB' MATLAB interface: changed license 158 to GNU General Public License v3.0 or later. 159 \end{packed_itemize} 160 161\item Version 5.0.3 (May 12, 2021) 162 163 \begin{packed_itemize} 164 \item (25) bug fix: disabling \verb'ANY_PAIR' semirings by editting 165 \verb'Source/GB_control.h' would cause a segfault if those disabled 166 semirings were used. 167 \item demos are no longer built by default 168 \item (24) bug fix: new functions in v5.0.2 not declared as \verb'extern' 169 in \verb'GraphBLAS.h'. 170 \item \verb'GrB_Matrix_reduce_BinaryOp' reinstated from v4.0.3; 171 same limit on built-in ops that correspond to known monoids. 172 \end{packed_itemize} 173 174\item Version 5.0.2 (May 5, 2021) 175 176 \begin{packed_itemize} 177 \item (23) bug fix: \verb'GrB_Matrix_apply_BinaryOp1st' and \verb'2nd' 178 were using the 179 wrong descriptors for \verb'GrB_INP0' and \verb'GrB_INP1'. 180 Caught by Erik Welch, Anaconda. 181 \item memory pool added for faster allocation/free of small blocks 182 \item \verb'@GrB' MATLAB interface ported to MATLAB R2021a. 183 \item \verb'GxB_PRINTF' and \verb'GxB_FLUSH' global options added. 184 \item \verb'GxB_Matrix_diag': construct a diagonal matrix from a vector 185 \item \verb'GxB_Vector_diag': extract a diagonal from a matrix 186 \item \verb'concat/split': methods to concatenate and split matrices. 187 \item \verb'import/export': 188 size of arrays now in bytes, not entries. This change 189 is required for better internal memory management, and it is not 190 backward compatible with the \verb'GxB*import/export' functions in v4.0. 191 A new parameter, \verb'is_uniform', has been added to all import/export 192 methods, which indicates that the matrix values are all the same. 193 \item (22) bug fix: SIMD vectorization was missing 194 \verb'reduction(+,task_cnvals)' in 195 \verb'GB_dense_subassign_06d_template.c'. Caught by Jeff Huang, Texas 196 A\&M, with his software package for race-condition detection. 197 \item \verb'GrB_Matrix_reduce_BinaryOp': removed. Use a monoid instead, 198 with \verb'GrB_reduce' or \verb'GrB_Matrix_reduce_Monoid'. 199 \end{packed_itemize} 200 201\item Version 4.0.3 (Jan 19, 2021) 202 203 \begin{packed_itemize} 204 \item faster min/max monoids 205 \item MATLAB: \verb'G=GrB(G)' converts \verb'G' from v3 object to v4 206 \end{packed_itemize} 207 208\item Version 4.0.2 (Jan 13, 2021) 209 210 \begin{packed_itemize} 211 \item ability to load \verb'*.mat' files saved with the v3 \verb'GrB' 212 MATLAB interface. 213 \end{packed_itemize} 214 215\item Version 4.0.1 (Jan 4, 2021) 216 217 \begin{packed_itemize} 218 \item significant performance improvements: compared with v3.3.3, 219 up to 5x faster in breadth-first-search (using 220 \verb'LAGraph_bfs_parent2'), and 2x faster in 221 Betweenness-Centrality (using \verb'LAGraph_bc_batch5'). 222 \item \verb'GrB_wait(void)', with no inputs: removed 223 \item \verb'GrB_wait(&object)': polymorphic function added 224 \item \verb'GrB_*_nvals': no longer guarantees completion; 225 use \verb'GrB_wait(&object)' 226 or non-polymorphic \verb'GrB_*_wait (&object)' instead 227 \item \verb'GrB_error': now has two parameters: a string 228 (\verb'char **') and an object. 229 \item \verb'GrB_Matrix_reduce_BinaryOp' limited to built-in operators that 230 correspond to known monoids. 231 \item \verb'GrB_*_extractTuples': may return indices out of order 232 \item removed internal features: GBI iterator, slice and hyperslice matrices 233 \item bitmap/full matrices and vectors added 234 \item positional operators and semirings: 235 \verb'GxB_FIRSTI_INT32' and related ops 236 \item jumbled matrices: sort left pending, like zombies and pending tuples 237 \item \verb'GxB_get/set': added \verb'GxB_SPARSITY_*' 238 (hyper, sparse, bitmap, or full) and \verb'GxB_BITMAP_SWITCH'. 239 \item \verb'GxB_HYPER': enum renamed to \verb'GxB_HYPER_SWITCH' 240 \item \verb'GxB*import/export': API modified 241 \item \verb'GxB_SelectOp': \verb'nrows' and \verb'ncols' removed 242 from function signature. 243 \item OpenMP tasking removed from mergesort and replaced with parallel 244 for loops. Just as fast on Linux/Mac; now the performance ports to 245 Windows. 246 \item \verb'GxB_BURBLE' added as a supported feature. This was an 247 undocumented feature of prior versions. 248 \item bug fix: \verb'A({lo,hi})=scalar' in MATLAB, 249 \verb'A(lo:hi)=scalar' was OK 250 \end{packed_itemize} 251 252\item Version 3.3.3 (July 14, 2020). 253 Bug fix: \verb'w<m>=A*u' with mask non-empty and u empty. 254 255\item Version 3.3.2 (July 3, 2020). Minor changes to build system. 256 257\item Version 3.3.1 (June 30, 2020). Bug fix to \verb'GrB_assign' and 258 \verb'GxB_subassign' when the assignment is simple (\verb'C=A') but 259 with typecasting. 260 261\item Version 3.3.0 (June 26, 2020). Compliant with V1.3 of the C API 262 (except that the polymorphic \verb'GrB_wait(&object)' doesn't appear yet; 263 it will appear in V4.0). 264 265 Added complex types (\verb'GxB_FC32' and \verb'GxB_FC64'), many unary 266 operators, binary operators, monoids, and semirings. Added bitwise 267 operators, and their monoids and semirings. Added the predefined monoids 268 and semirings from the v1.3 spec. MATLAB interface: added complex matrices 269 and operators, and changed behavior of integer operations to more closely 270 match the behavior on MATLAB integer matrices. The rules for typecasting 271 large floating point values to integers has changed. The specific 272 object-based \verb'GrB_Matrix_wait', \verb'GrB_Vector_wait', etc, functions 273 have been added. The no-argument \verb'GrB_wait()' is deprecated. Added 274 \verb'GrB_getVersion', \verb'GrB_Matrix_resize', \verb'GrB_Vector_resize', 275 \verb'GrB_kronecker', \verb'GrB_*_wait', scalar binding with binary 276 operators for \verb'GrB_apply', \verb'GrB_Matrix_removeElement', and 277 \verb'GrB_Vector_removeElement'. 278 279\item Version 3.2.0 (Feb 20, 2020). Faster \verb'GrB_mxm', \verb'GrB_mxv', and 280 \verb'GrB_vxm', and faster operations on dense matrices/vectors. Removed 281 compile-time user objects (\verb'GxB_*_define'), since these were not 282 compatible with the faster matrix operations. Added the \verb'ANY' and 283 \verb'PAIR' operators. Added the predefined descriptor, \verb'GrB_DESC_*'. 284 Added the structural mask option. Changed default chunk size to 65,536. 285 Note that v3.2.0 is not compatible with the MS Visual Studio compiler; use 286 v3.1.2 instead. 287 MATLAB interface modified: \verb'GrB.init' is now optional. 288 289\item Version 3.1.2 (Dec, 2019). Changes to allow SuiteSparse:GraphBLAS 290 to be compiled with the Microsoft Visual Studio compiler. This compiler 291 does not support the \verb'_Generic' keyword, so the polymorphic functions 292 are not available. Use the equivalent non-polymorphic functions instead, 293 when compiling GraphBLAS with MS Visual Studio. In addition, 294 variable-length arrays are not supported, so user-defined types are limited 295 to 128 bytes in size. These changes have no effect if you have an ANSI C11 296 compliant compiler. 297 298 MATLAB interface modified: \verb'GrB.init' is now required. 299 300\item Version 3.1.0 (Oct 1, 2019). MATLAB interface added. See the \newline 301 \verb'GraphBLAS/GraphBLAS' folder for details and documentation, 302 and Section~\ref{matlab}. 303 304\item Version 3.0 (July 26, 2019), with OpenMP parallelism. 305 306The version number is increased to 3.0, since 307this version is not backward compatible with V2.x. The \verb'GxB_select' 308operation changes; the \verb'Thunk' parameter was formerly a 309\verb'const void *' pointer, and is now a \verb'GxB_Scalar'. A new parameter 310is added to \verb'GxB_SelectOp_new', to define the expected type of 311\verb'Thunk'. A new parameter is added to \verb'GxB_init', to specify whether 312or not the user-provided memory management functions are thread safe. 313 314The remaining changes add new features, and are upward compatible with V2.x. 315The major change is the addition of OpenMP parallelism. This addition has no 316effect on the API, except that round-off errors can differ with the number of 317threads used, for floating-point types. \verb'GxB_set' can optionally define 318the number of threads to use (the default is \verb'omp_get_max_threads'). The 319number of threads can also defined globally, and/or in the 320\verb'GrB_Descriptor'. The \verb'RDIV' and \verb'RMINUS' operators are added, 321which are defined as $f(x,y)=y/x$ and $f(x,y)=y-x$, respectively. Additional 322options are added to \verb'GxB_get'. 323 324\item Version 2.3.3 (May 2019): Collected Algorithm of the ACM. 325No changes from V2.3.2 other than the documentation. 326 327\item Version 2.3 (Feb 2019) improves the performance of many GraphBLAS 328operations, including an early-exit for monoids. These changes have a 329significant impact on breadth-first-search (a performance bug was also fixed in 330the two BFS \verb'Demo' codes). The matrix and vector import/export functions 331were added (Section~\ref{import_export}), in support of the new LAGraph project 332(\url{https://github.com/GraphBLAS/LAGraph}, see also Section~\ref{lagraph}). 333LAGraph includes a push-pull BFS in GraphBLAS that is faster than two versions 334in the \verb'Demo' folder. \verb'GxB_init' was added to allow the memory 335manager functions (\verb'malloc', etc) to be specified. 336 337\item 338Version 2.2 (Nov 2018) 339adds user-defined objects at compile-time, via user \verb'*.m4' files placed in 340\verb'GraphBLAS/User', which use the \verb'GxB_*_define' macros 341(NOTE: feature removed in v3.2). 342The default matrix format is now \verb'GxB_BY_ROW'. 343Also added are the \verb'GxB_*print' methods for printing the contents of each 344GraphBLAS object (Section~\ref{fprint}). PageRank demos have been added to 345the \verb'Demos' folder. 346 347\item 348Version 2.1 (Oct 2018) was 349a major update with support for new matrix formats 350(by row or column, and hypersparse matrices), and MATLAB-like colon notation 351(\verb'I=begin:end' or \verb'I=begin:inc:end'). Some graph algorithms are more 352naturally expressed with matrices stored by row, and this version includes the 353new \verb'GxB_BY_ROW' format. The default format in Version 2.1 and 354prior versions is by column. 355New extensions to GraphBLAS in this version include \verb'GxB_get', 356\verb'GxB_set', and \verb'GxB_AxB_METHOD', \verb'GxB_RANGE', \verb'GxB_STRIDE', 357and \verb'GxB_BACKWARDS', and their related definitions, described in 358Sections~\ref{descriptor},~\ref{options},~and~\ref{colon}. 359 360\item 361Version 2.0 (March 2018) addressed changes in the GraphBLAS C API 362Specification and added \verb'GxB_kron' and \verb'GxB_resize'. 363 364\item 365Version 1.1 (Dec 2017) primarily improved the performance. 366 367\item 368Version 1.0 was released on Nov 25, 2017. 369\end{itemize} 370 371%------------------------------------------------------------------------------- 372\subsubsection{Regarding historical and deprecated functions and symbols} 373%------------------------------------------------------------------------------- 374 375When a \verb'GxB*' function or symbol is added to the C API Specification with 376a \verb'GrB*' name, the new \verb'GrB*' name should be used instead, if 377possible. However, the old \verb'GxB*' name will be kept as long as possible 378for historical reasons. Historical functions and symbols will not always be 379documented here in the SuiteSparse:GraphBLAS User Guide, but they will be kept 380in \verb'GraphbBLAS.h' and kept in good working order in the library. 381Historical functions and symbols would only be removed in the very unlikely 382case that they cause a serious conflict with future methods. 383 384The only methods that have been fully deprecated and removed are the no-input 385\verb'GrB_wait' and \verb'GrB_error' methods, which are incompatible with the 386new 1-input \verb'GrB_wait' and 2-input \verb'GrB_error' methods defined in 387the latest version of the C API Specification, and the 388\verb'GrB_Matrix_reduce_BinaryOp' function, which is limited to binary 389operators that correspond to built-in monoids. 390 391\newpage 392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 393\section{Basic Concepts} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 394%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 395\label{basic} 396 397Since the {\em GraphBLAS C API Specification} provides a precise definition of 398GraphBLAS, not every detail of every function is provided here. For example, 399some error codes returned by GraphBLAS are self-explanatory, but since a 400specification must precisely define all possible error codes a function can 401return, these are listed in detail in the {\em GraphBLAS C API Specification}. 402However, including them here is not essential and the additional information on 403the page might detract from a clearer view of the essential features of the 404GraphBLAS functions. 405 406This User Guide also assumes the reader is familiar with MATLAB. 407MATLAB supports only the conventional plus-times semiring on sparse 408double and complex matrices, but a MATLAB-like notation easily extends to the 409arbitrary semirings used in GraphBLAS. The matrix multiplication in the 410example in the Introduction can be written in MATLAB notation as \verb'C=A*B', 411if the Boolean \verb'OR-AND' semiring is understood. Relying on a MATLAB-like 412notation allows the description in this User Guide to be expressive, easy to 413understand, and terse at the same time. {\em The GraphBLAS C API 414Specification} also makes use of some MATLAB-like language, such as the colon 415notation. 416 417MATLAB notation will always appear here in fixed-width font, such as 418\verb'C=A*B(:,j)'. In standard mathematical notation it would be written as 419the matrix-vector multiplication ${\bf C = A b}_j$ where ${\bf b}_j$ is the 420$j$th column of the matrix ${\bf B}$. The GraphBLAS standard is a C API and 421SuiteSparse:GraphBLAS is written in C, and so a great deal of C syntax appears 422here as well, also in fixed-width font. This User Guide alternates between all 423three styles as needed. 424 425%=============================================================================== 426\subsection{Graphs and sparse matrices} %======================================= 427%=============================================================================== 428\label{sparse} 429 430Graphs can be huge, with many nodes and edges. A dense adjacency matrix ${\bf 431A}$ for a graph of $n$ nodes takes $O(n^2)$ memory, which is impossible if $n$ 432is, say, a million. Let $|{\bf A}|$ denote the number of entries in a matrix. 433Most graphs arising in practice are sparse, however, with only $|{\bf A}|=O(n)$ 434edges, where $|{\bf A}|$ denotes the number of edges in the graph, or the 435number of explicit entries present in the data structure for the matrix ${\bf 436A}$. Sparse graphs with millions of nodes and edges can easily be created by 437representing them as sparse matrices, where only explicit values need to be 438stored. Some graphs are {\em hypersparse}, with ${|\bf A}| << n$. 439SuiteSparse:GraphBLAS supports two kinds of sparse matrix formats: a regular 440sparse format, taking $O(n+|{\bf A}|)$ space, and a hypersparse format taking 441only $O(|{\bf A}|)$ space. As a result, creating a sparse matrix of size 442$n$-by-$n$ where $n=2^{60}$ (about $10^{18}$) can be done on quite easily on a 443commodity laptop, limited only by $|{\bf A}|$. 444 445A sparse matrix data structure only stores a subset of the possible $n^2$ 446entries, and it assumes the values of entries not stored have some implicit 447value. In conventional linear algebra, this implicit value is zero, but it 448differs with different semirings. Explicit values are called {\em entries} and 449they appear in the data structure. The {\em pattern} of a matrix defines 450where its explicit entries appear. It will be referenced in one of two 451equivalent ways. It can be viewed as a set of indices $(i,j)$, where $(i,j)$ 452is in the pattern of a matrix ${\bf A}$ if ${\bf A}(i,j)$ is an explicit value. 453It can also be viewed as a Boolean matrix ${\bf S}$ where ${\bf S}(i,j)$ is 454true if $(i,j)$ is an explicit entry and false otherwise. In MATLAB notation, 455\verb'S=spones(A)' or \verb'S=(A~=0)', if the implicit value is zero. The 456\verb'(i,j)' pairs, and their values, can also be extracted from the matrix via 457the MATLAB expression \verb'[I,J,X]=find(A)', where the \verb'k'th tuple 458\verb'(I(k),J(k),X(k))' represents the explicit entry \verb'A(I(k),J(k))', with 459numerical value \verb'X(k)' equal to $a_{ij}$, with row index $i$=\verb'I(k)' 460and column index $j$=\verb'J(k)'. 461 462The entries in the pattern of ${\bf A}$ can take on any value, including the 463implicit value, whatever it happens to be. This differs slightly from MATLAB, 464which always drops all explicit zeros from its sparse matrices. This is a 465minor difference but it cannot be done in GraphBLAS. For example, in the 466max-plus tropical algebra, the implicit value is negative infinity, and zero 467has a different meaning. Here, the MATLAB notation used will assume that no 468explicit entries are ever dropped because their explicit value happens to match 469the implicit value. 470 471{\em Graph Algorithms in the Language on Linear Algebra}, Kepner and Gilbert, 472eds., provides a framework for understanding how graph algorithms can be 473expressed as matrix computations \cite{KepnerGilbert2011}. For additional 474background on sparse matrix algorithms, see also \cite{Davis06book} and 475\cite{DavisRajamanickamSidLakhdar16}. 476 477%=============================================================================== 478\subsection{Overview of GraphBLAS methods and operations} %===================== 479%=============================================================================== 480\label{overview} 481 482GraphBLAS provides a collection of {\em methods} to create, query, and free its 483of objects: sparse matrices, sparse vectors, scalars, types, operators, 484monoids, semirings, and a descriptor object used for parameter settings. 485Details are given in Section~\ref{objects}. Once these objects are created 486they can be used in mathematical {\em operations} (not to be confused with the 487how the term {\em operator} is used in GraphBLAS). A short summary of these 488operations and their nearest MATLAB analog is given in the table below. 489 490% \vspace{0.1in} 491\begin{tabular}{ll} 492operation & approximate MATLAB analog \\ 493\hline 494matrix multiplication & \verb'C=A*B' \\ 495element-wise operations & \verb'C=A+B' and \verb'C=A.*B' \\ 496reduction to a vector or scalar & \verb's=sum(A)' \\ 497apply unary operator & \verb'C=-A' \\ 498transpose & \verb"C=A'" \\ 499submatrix extraction & \verb'C=A(I,J)' \\ 500submatrix assignment & \verb'C(I,J)=A' \\ 501select & \verb'C=tril(A)' \\ 502\hline 503\end{tabular} 504\vspace{0.1in} 505 506GraphBLAS can do far more than what MATLAB can do in these rough analogs, but 507the list provides a first step in describing what GraphBLAS can do. Details of 508each GraphBLAS operation are given in Section~\ref{operations}. With this 509brief overview, the full scope of GraphBLAS extensions of these operations can 510now be described. 511 512GraphBLAS has 13 built-in scalar types: Boolean, single and double precision 513floating-point (real and complex), and 8, 16, 32, and 64-bit signed and 514unsigned integers. In addition, user-defined scalar types can be created from 515nearly any C \verb'typedef', as long as the entire type fits in a fixed-size 516contiguous block of memory (of arbitrary size). All of these types can be used 517to create GraphBLAS sparse matrices, vectors, or scalars. 518 519The scalar addition of conventional matrix multiplication is replaced with a 520{\em monoid}. A monoid is an associative and commutative binary operator 521\verb'z=f(x,y)' where all three domains are the same (the types of \verb'x', 522\verb'y', and \verb'z'), and where the operator has an identity value \verb'id' 523such that \verb'f(x,id)=f(id,x)=x'. Performing matrix multiplication with a 524semiring uses a monoid in place of the ``add'' operator, scalar addition being 525just one of many possible monoids. The identity value of addition is zero, 526since $x+0=0+x=x$. GraphBLAS includes many built-in operators suitable for 527use as a monoid: min (with an identity value of positive infinity), max (whose 528identity is negative infinity), add (identity is zero), multiply (with an 529identity of one), four logical operators: AND, OR, exclusive-OR, and 530Boolean equality (XNOR), four bitwise operators (AND, OR, XOR, and XNOR), 531and the ANY operator. 532User-created monoids can be defined with any associative and 533commutative operator that has an identity value. 534 535Finally, a semiring can use any built-in or user-defined binary operator 536\verb'z=f(x,y)' as its ``multiply'' operator, as long as the type of its 537output, \verb'z' matches the type of the semiring's monoid. 538The user application can create any semiring based on any types, monoids, 539and multiply operators, as long these few rules are followed. 540 541Just considering built-in types and operators, GraphBLAS can perform 542\verb'C=A*B' in thousands of unique semirings. With typecasting, any of these 543semirings can be applied to matrices \verb'C', \verb'A', and \verb'B' of 13 544predefined types, in any combination. This results in millions of possible 545kinds of sparse matrix multiplication supported by GraphBLAS, and this is 546counting just built-in types and operators. By contrast, MATLAB provides just 547two semirings for its sparse matrix multiplication \verb'C=A*B': 548plus-times-double and plus-times-complex, not counting the typecasting that 549MATLAB does when multiplying a real matrix times a complex matrix. 550 551A monoid can also be used in a reduction operation, like \verb's=sum(A)' in 552MATLAB. MATLAB provides the plus, times, min, and max reductions of a real or 553complex sparse matrix as \verb's=sum(A)', \verb's=prod(A)', \verb's=min(A)', 554and \verb's=max(A)', respectively. In GraphBLAS, any monoid can be used (min, 555max, plus, times, AND, OR, exclusive-OR, equality, bitwise operators, 556or any user-defined monoid on any user-defined type). 557 558Element-wise operations are also expanded from what can be done in MATLAB. 559Consider matrix addition, \verb'C=A+B' in MATLAB. The pattern of the result is 560the set union of the pattern of \verb'A' and \verb'B'. In GraphBLAS, any 561binary operator can be used in this set-union ``addition.'' The operator is 562applied to entries in the intersection. Entries in \verb'A' but not \verb'B', 563or visa-versa, are copied directly into \verb'C', without any application of 564the binary operator. The accumulator operation for ${\bf Z = C \odot T}$ 565described in Section~\ref{accummask} is one example of this set-union 566application of an arbitrary binary operator. 567 568Consider element-wise multiplication, \verb'C=A.*B' in MATLAB. The operator 569(multiply in this case) is applied to entries in the set intersection, and the 570pattern of \verb'C' just this set intersection. Entries in \verb'A' but not 571\verb'B', or visa-versa, do not appear in \verb'C'. In GraphBLAS, any binary 572operator can be used in this manner, not just scalar multiplication. The 573difference between element-wise ``add'' and ``multiply'' is not the operators, 574but whether or not the pattern of the result is the set union or the set 575intersection. In both cases, the operator is only applied to the set 576intersection. 577 578Finally, GraphBLAS includes a {\em non-blocking} mode where operations can be 579left pending, and saved for later. This is very useful for submatrix 580assignment (\verb'C(I,J)=A' where \verb'I' and \verb'J' are integer vectors), 581or scalar assignment (\verb'C(i,j)=x' where \verb'i' and \verb'j' are scalar 582integers). Because of how MATLAB stores its matrices, adding and deleting 583individual entries is very costly. For example, this is very slow in MATLAB, 584taking $O(nz^2)$ time: 585 586 \begin{mdframed} 587 {\footnotesize 588 \begin{verbatim} 589 A = sparse (m,n) ; % an empty sparse matrix 590 for k = 1:nz 591 compute a value x, row index i, and column index j 592 A (i,j) = x ; 593 end\end{verbatim}}\end{mdframed} 594 595The above code is very easy read and simple to write, but exceedingly slow. In 596MATLAB, the method below is preferred and is far faster, taking at most 597$O(|{\bf A}| \log |{\bf A}| +n)$ time. It can easily be a million times faster 598than the method above. Unfortunately the second method below is a little 599harder to read and a little less natural to write: 600 601 \begin{mdframed} 602 {\footnotesize 603 \begin{verbatim} 604 I = zeros (nz,1) ; 605 J = zeros (nz,1) ; 606 X = zeros (nz,1) ; 607 for k = 1:nz 608 compute a value x, row index i, and column index j 609 I (k) = i ; 610 J (k) = j ; 611 X (k) = x ; 612 end 613 A = sparse (I,J,X,m,n) ; \end{verbatim}} \end{mdframed} 614 615GraphBLAS can do both methods. SuiteSparse:GraphBLAS stores its matrices in a 616format that allows for pending computations, which are done later in bulk, and 617as a result it can do both methods above equally as fast as the MATLAB 618\verb'sparse' function, allowing the user to write simpler code. 619 620%=============================================================================== 621\subsection{The accumulator and the mask} %===================================== 622%=============================================================================== 623\label{accummask} 624 625Most GraphBLAS operations can be modified via transposing input matrices, using 626an accumulator operator, applying a mask or its complement, and by clearing all 627entries the matrix \verb'C' after using it in the accumulator operator but 628before the final results are written back into it. All of these steps are 629optional, and are controlled by a descriptor object that holds parameter 630settings (see Section~\ref{descriptor}) that control the following options: 631 632\begin{itemize} 633\item the input matrices \verb'A' and/or \verb'B' can be transposed first. 634 635\item an accumulator operator can be used, like the plus in the statement 636 \verb'C=C+A*B'. The accumulator operator can be any binary operator, and 637 an element-wise ``add'' (set union) is performed using the operator. 638 639\item an optional {\em mask} can be used to selectively write the results to 640 the output. The mask is a sparse Boolean matrix \verb'Mask' whose size is 641 the same size as the result. If \verb'Mask(i,j)' is true, then the 642 corresponding entry in the output can be modified by the computation. If 643 \verb'Mask(i,j)' is false, then the corresponding in the output is 644 protected and cannot be modified by the computation. The \verb'Mask' 645 matrix acts exactly like logical matrix indexing in MATLAB, with one 646 minor difference: in GraphBLAS notation, the mask operation is $\bf C 647 \langle M \rangle = Z$, where the mask $\bf M$ appears only on the 648 left-hand side. In MATLAB, it would appear on both sides as 649 \verb'C(Mask)=Z(Mask)'. If no mask is provided, the \verb'Mask' matrix is 650 implicitly all true. This is indicated by passing the value 651 \verb'GrB_NULL' in place of the \verb'Mask' argument in GraphBLAS 652 operations. 653 654\end{itemize} 655 656\noindent 657This process can be described in mathematical notation as: 658 \vspace{-0.2in} 659 {\small 660 \begin{tabbing} 661 \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \\ 662 \> ${\bf A = A}^{\sf T}$, if requested via descriptor (first input option) \\ 663 \> ${\bf B = B}^{\sf T}$, if requested via descriptor (second input option) \\ 664 \> ${\bf T}$ is computed according to the specific operation \\ 665 \> ${\bf C \langle M \rangle = C \odot T}$, 666 accumulating and writing the results back via the mask 667 \end{tabbing} } 668\noindent 669The application of the mask and the accumulator operator is written as 670${\bf C \langle M \rangle = C \odot T}$ where ${\bf Z = C \odot T}$ denotes the 671application of the accumulator operator, and 672${\bf C \langle M \rangle = Z}$ 673denotes the mask operator via the Boolean matrix ${\bf M}$. The Accumulator 674Phase, ${\bf Z = C \odot T}$, is performed as follows: 675 \vspace{-0.2in} 676 % accum: Z = C odot T 677 {\small 678 \begin{tabbing} 679 \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \\ 680 \> {\bf Accumulator Phase}: compute ${\bf Z = C \odot T}$: \\ 681 \> \> if \verb'accum' is \verb'NULL' \\ 682 \> \>\> ${\bf Z = T}$ \\ 683 \> \> else \\ 684 \> \>\> ${\bf Z = C \odot T}$ 685 \end{tabbing}} 686The accumulator operator is $\odot$ in GraphBLAS notation, or \verb'accum' 687in the code. The pattern of ${\bf C \odot T}$ is the set union of the 688patterns of ${\bf C}$ and ${\bf T}$, and the operator is applied only on the 689set intersection of ${\bf C}$ and ${\bf T}$. Entries in neither the pattern 690of ${\bf C}$ nor ${\bf T}$ do not appear in the pattern of ${\bf Z}$. That is: 691 \newpage % \vspace{-0.2in} 692 {\small 693 \begin{tabbing} 694 \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \\ 695 \> for all entries $(i,j)$ in ${\bf C \cap T}$ 696 (that is, entries in both ${\bf C}$ and ${\bf T}$) \\ 697 \> \> $z_{ij} = c_{ij} \odot t_{ij}$ \\ 698 \> for all entries $(i,j)$ in ${\bf C \setminus T}$ 699 (that is, entries in ${\bf C}$ but not ${\bf T}$) \\ 700 \> \> $z_{ij} = c_{ij}$ \\ 701 \> for all entries $(i,j)$ in ${\bf T \setminus C}$ 702 (that is, entries in ${\bf T}$ but not ${\bf C}$) \\ 703 \> \> $z_{ij} = t_{ij}$ 704 \end{tabbing} } 705The Accumulator Phase is followed by the Mask/Replace Phase, 706${\bf C \langle M \rangle = Z}$ 707as controlled by the \verb'GrB_REPLACE' and \verb'GrB_COMP' descriptor options: 708 \vspace{-0.2in} 709 % mask/replace/scmp: C<M> = Z 710 {\small 711 \begin{tabbing} 712 \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \\ 713 \>{\bf Mask/Replace Phase}: compute ${\bf C \langle M \rangle = Z}$: \\ 714 \> \> if (\verb'GrB_REPLACE') delete all entries in ${\bf C}$ \\ 715 \> \> if \verb'Mask' is \verb'NULL' \\ 716 \> \>\> if (\verb'GrB_COMP') \\ 717 \> \>\>\> ${\bf C}$ is not modified \\ 718 \> \>\> else \\ 719 \> \>\>\> ${\bf C = Z}$ \\ 720 \> \> else \\ 721 \> \>\> if (\verb'GrB_COMP') \\ 722 \> \>\>\> ${\bf C \langle \neg M \rangle = Z}$ \\ 723 \> \>\> else \\ 724 \> \>\>\> ${\bf C \langle M \rangle = Z}$ 725 \end{tabbing} } 726Both phases of the accum/mask process are illustrated in MATLAB notation in 727Figure~\ref{fig_accummask}. A GraphBLAS operation starts with its primary 728computation, producing a result \verb'T'; for matrix multiply, \verb'T=A*B', or 729if \verb'A' is transposed first, \verb"T=A'*B", for example. Applying the 730accumulator, mask (or its complement) to obtain the final result matrix 731\verb'C' can be expressed in the MATLAB \verb'accum_mask' function shown in the 732figure. This function is an exact, fully functional, and nearly-complete 733description of the GraphBLAS accumulator/mask operation. The only aspects it 734does not consider are typecasting (see Section~\ref{typecasting}), and the 735value of the implicit identity (for those, see another version in the 736\verb'Test' folder). 737 738\begin{figure} 739\begin{mdframed}[leftmargin=-0.4in,userdefinedwidth=5.8in] 740{\footnotesize 741\begin{verbatim} 742function C = accum_mask (C, Mask, accum, T, C_replace, Mask_complement) 743[m n] = size (C.matrix) ; 744Z.matrix = zeros (m, n) ; 745Z.pattern = false (m, n) ; 746 747if (isempty (accum)) 748 Z = T ; % no accum operator 749else 750 % Z = accum (C,T), like Z=C+T but with an binary operator, accum 751 p = C.pattern & T.pattern ; Z.matrix (p) = accum (C.matrix (p), T.matrix (p)); 752 p = C.pattern & ~T.pattern ; Z.matrix (p) = C.matrix (p) ; 753 p = ~C.pattern & T.pattern ; Z.matrix (p) = T.matrix (p) ; 754 Z.pattern = C.pattern | T.pattern ; 755end 756 757% apply the mask to the values and pattern 758C.matrix = mask (C.matrix, Mask, Z.matrix, C_replace, Mask_complement) ; 759C.pattern = mask (C.pattern, Mask, Z.pattern, C_replace, Mask_complement) ; 760end 761 762function C = mask (C, Mask, Z, C_replace, Mask_complement) 763% replace C if requested 764if (C_replace) 765 C (:,:) = 0 ; 766end 767if (isempty (Mask)) % if empty, Mask is implicit ones(m,n) 768 % implicitly, Mask = ones (size (C)) 769 if (~Mask_complement) 770 C = Z ; % this is the default 771 else 772 C = C ; % Z need never have been computed 773 end 774else 775 % apply the mask 776 if (~Mask_complement) 777 C (Mask) = Z (Mask) ; 778 else 779 C (~Mask) = Z (~Mask) ; 780 end 781end 782end \end{verbatim} } 783\end{mdframed} 784\caption{Applying the mask and accumulator, ${\bf C \langle M \rangle = C \odot T}$\label{fig_accummask}} 785\end{figure} 786 787One aspect of GraphBLAS cannot be as easily expressed in a MATLAB sparse 788matrix: namely, what is the implicit value of entries not in the pattern? To 789accommodate this difference in the \verb'accum_mask' MATLAB function, each 790sparse matrix \verb'A' is represented with its values \verb'A.matrix' and its 791pattern, \verb'A.pattern'. The latter could be expressed as the sparse matrix 792\verb'A.pattern=spones(A)' or \verb'A.pattern=(A~=0)' in MATLAB, if the 793implicit value is zero. With different semirings, entries not in the pattern 794can be \verb'1', \verb'+Inf', \verb'-Inf', or whatever is the identity value of 795the monoid. As a result, Figure~\ref{fig_accummask} performs its computations 796on two MATLAB matrices: the values in \verb'A.matrix' and the pattern in the 797logical matrix \verb'A.pattern'. Implicit values are untouched. 798 799The final computation in Figure~\ref{fig_accummask} with a complemented 800\verb'Mask' is easily expressed in MATLAB as \verb'C(~Mask)=Z(~Mask)' but this 801is costly if \verb'Mask' is very sparse (the typical case). It can be computed 802much faster in MATLAB without complementing the sparse \verb'Mask' via: 803 804 {\footnotesize 805 \begin{verbatim} 806 R = Z ; R (Mask) = C (Mask) ; C = R ; \end{verbatim} } 807 808A set of MATLAB functions that precisely compute the ${\bf C \langle M \rangle 809= C \odot T}$ operation according to the full GraphBLAS specification is 810provided in SuiteSparse:GraphBLAS as \verb'GB_spec_accum.m', which computes 811${\bf Z=C\odot T}$, and \verb'GB_spec_mask.m', which computes ${\bf C \langle M 812\rangle = Z}$. SuiteSparse:GraphBLAS includes a complete list of 813\verb'GB_spec_*' functions that illustrate every GraphBLAS operation. 814 815The methods in Figure~\ref{fig_accummask} rely heavily on MATLAB's logical 816matrix indexing. For those unfamiliar with logical indexing in MATLAB, here is 817short summary. Logical matrix indexing in MATLAB is written as \verb'A(Mask)' 818where \verb'A' is any matrix and \verb'Mask' is a logical matrix the same size 819as \verb'A'. The expression \verb'x=A(Mask)' produces a column vector \verb'x' 820consisting of the entries of \verb'A' where \verb'Mask' is true. On the 821left-hand side, logical submatrix assignment \verb'A(Mask)=x' does the 822opposite, copying the components of the vector \verb'x' into the places in 823\verb'A' where \verb'Mask' is true. For example, to negate all values greater 824than 10 using logical indexing in MATLAB: 825 826 \begin{mdframed} 827 {\footnotesize 828 \begin{verbatim} 829 >> A = magic (4) 830 A = 831 16 2 3 13 832 5 11 10 8 833 9 7 6 12 834 4 14 15 1 835 >> A (A>10) = - A (A>10) 836 A = 837 -16 2 3 -13 838 5 -11 10 8 839 9 7 6 -12 840 4 -14 -15 1 \end{verbatim} } \end{mdframed} 841 842In MATLAB, logical indexing with a sparse matrix \verb'A' and sparse logical 843matrix \verb'Mask' is a built-in method. The Mask operator in GraphBLAS works 844identically as sparse logical indexing in MATLAB, but is typically far faster 845in SuiteSparse:GraphBLAS than the same operation using MATLAB sparse matrices. 846 847%=============================================================================== 848\subsection{Typecasting} %====================================================== 849%=============================================================================== 850\label{typecasting} 851 852If an operator \verb'z=f(x)' or \verb'z=f(x,y)' is used with inputs that do not 853match its inputs \verb'x' or \verb'y', or if its result \verb'z' does not match 854the type of the matrix it is being stored into, then the values are typecasted. 855Typecasting in GraphBLAS extends beyond just operators. Almost all GraphBLAS 856methods and operations are able to typecast their results, as needed. 857 858If one type can be typecasted into the other, they are said to be {\em 859compatible}. All built-in types are compatible with each other. GraphBLAS 860cannot typecast user-defined types thus any user-defined type is only 861compatible with itself. When GraphBLAS requires inputs of a specific type, or 862when one type cannot be typecast to another, the GraphBLAS function returns an 863error code, \verb'GrB_DOMAIN_MISMATCH' (refer to Section~\ref{error} for a 864complete list of error codes). Typecasting can only be done between built-in 865types, and it follows the rules of the ANSI C language (not MATLAB) wherever 866the rules of ANSI C are well-defined. 867 868However, unlike MATLAB, the ANSI C11 language specification states that the 869results of typecasting a \verb'float' or \verb'double' to an integer type is 870not always defined. In SuiteSparse:GraphBLAS, whenever C leaves the result 871undefined the rules used in MATLAB are followed. In particular \verb'+Inf' 872converts to the largest integer value, \verb'-Inf' converts to the smallest 873(zero for unsigned integers), and \verb'NaN' converts to zero. Positive values 874outside the range of the integer are converted to the largest positive integer, 875and negative values less than the most negative integer are converted to that 876most negative integer. Other than these special cases, SuiteSparse:GraphBLAS 877trusts the C compiler for the rest of its typecasting. 878 879Typecasting to \verb'bool' is fully defined in the C language specification, 880even for \verb'NaN'. The result is \verb'false' if the value compares equal to 881zero, and true otherwise. Thus \verb'NaN' converts to \verb'true'. This is 882unlike MATLAB, which does not allow a typecast of a \verb'NaN' to the MATLAB 883logical type. 884 885\begin{alert} 886{\bf SPEC:} the GraphBLAS API C Specification states that typecasting follows 887the rules of ANSI C. Yet C leaves some typecasting undefined. All typecasting 888between built-in types in SuiteSparse:GraphBLAS is precisely defined, as an 889extension to the spec. 890\end{alert} 891 892%=============================================================================== 893\subsection{Notation and list of GraphBLAS operations} %======================== 894%=============================================================================== 895\label{list} 896 897As a summary of what GraphBLAS can do, the following table lists all GraphBLAS 898operations. Upper case letters denote a matrix, lower case letters are 899vectors, and ${\bf AB}$ denote the multiplication of two matrices over a 900semiring. 901 902\vspace{0.05in} 903{\footnotesize 904\begin{tabular}{lll} 905\hline 906\verb'GrB_mxm' & matrix-matrix multiply & ${\bf C \langle M \rangle = C \odot AB}$ \\ 907\verb'GrB_vxm' & vector-matrix multiply & ${\bf w^{\sf T}\langle m^{\sf T}\rangle = w^{\sf T}\odot u^{\sf T}A}$ \\ 908\verb'GrB_mxv' & matrix-vector multiply & ${\bf w \langle m \rangle = w \odot Au}$ \\ 909\hline 910\verb'GrB_eWiseMult' & element-wise, & ${\bf C \langle M \rangle = C \odot (A \otimes B)}$ \\ 911 & set intersection & ${\bf w \langle m \rangle = w \odot (u \otimes v)}$ \\ 912\hline 913\verb'GrB_eWiseAdd' & element-wise, & ${\bf C \langle M \rangle = C \odot (A \oplus B)}$ \\ 914 & set union & ${\bf w \langle m \rangle = w \odot (u \oplus v)}$ \\ 915\hline 916\verb'GrB_extract' & extract submatrix & ${\bf C \langle M \rangle = C \odot A(I,J)}$ \\ 917 & & ${\bf w \langle m \rangle = w \odot u(i)}$ \\ 918\hline 919\verb'GxB_subassign' & assign submatrix & ${\bf C (I,J) \langle M \rangle = C(I,J) \odot A}$ \\ 920 & (with submask for ${\bf C(I,J)}$) 921 & ${\bf w (i) \langle m \rangle = w(i) \odot u}$ \\ 922\hline 923\verb'GrB_assign' & assign submatrix & ${\bf C \langle M \rangle (I,J) = C(I,J) \odot A}$ \\ 924 & (with mask for ${\bf C}$) 925 & ${\bf w \langle m \rangle (i) = w(i) \odot u}$ \\ 926\hline 927\verb'GrB_apply' & apply unary operator & ${\bf C \langle M \rangle = C \odot} f{\bf (A)}$ \\ 928 & & ${\bf w \langle m \rangle = w \odot} f{\bf (u)}$ \\ 929 & apply binary operator & ${\bf C \langle M \rangle = C \odot} f({\bf A},y)$ \\ 930 & & ${\bf C \langle M \rangle = C \odot} f(x,{\bf A})$ \\ 931 & & ${\bf w \langle m \rangle = w \odot} f({\bf u},y)$ \\ 932 & & ${\bf w \langle m \rangle = w \odot} f(x,{\bf u})$ \\ 933\hline 934\verb'GxB_select' & apply select operator & ${\bf C \langle M \rangle = C \odot} f({\bf A},k)$ \\ 935 & & ${\bf w \langle m \rangle = w \odot} f({\bf u},k)$ \\ 936\hline 937\verb'GrB_reduce' & reduce to vector & ${\bf w \langle m \rangle = w \odot} [{\oplus}_j {\bf A}(:,j)]$ \\ 938 & reduce to scalar & $s = s \odot [{\oplus}_{ij} {\bf A}(i,j)]$ \\ 939\hline 940\verb'GrB_transpose' & transpose & ${\bf C \langle M \rangle = C \odot A^{\sf T}}$ \\ 941\hline 942\verb'GrB_kronecker' & Kronecker product & ${\bf C \langle M \rangle = C \odot \mbox{kron}(A, B)}$ \\ 943\hline 944\end{tabular} 945} 946\vspace{0.15in} 947 948Each operation takes an optional \verb'GrB_Descriptor' argument that modifies 949the operation. The input matrices ${\bf A}$ and ${\bf B}$ can be optionally 950transposed, the mask ${\bf M}$ can be complemented, and ${\bf C}$ can be 951cleared of its entries after it is used in ${\bf Z = C \odot T}$ but before 952the ${\bf C \langle M \rangle = Z}$ assignment. 953Vectors are never transposed via the descriptor. 954 955Let ${\bf A \oplus B}$ denote the element-wise operator that produces a set 956union pattern (like \verb'A+B' in MATLAB). Any binary operator can be used 957this way in GraphBLAS, not just plus. Let ${\bf A \otimes B}$ denote the 958element-wise operator that produces a set intersection pattern (like 959\verb'A.*B' in MATLAB); any binary operator can be used this way, not just 960times. 961 962Reduction of a matrix ${\bf A}$ to a vector reduces the $i$th row of ${\bf A}$ 963to a scalar $w_i$. This is like \verb"w=sum(A')" since by default, MATLAB 964reduces down the columns, not across the rows. 965 966\newpage 967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 968\section{Interfaces to MATLAB, Python, Julia, Java} %%%%%%%%%%%%%%%%%%%%%%%%%%%% 969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 970 971The MATLAB interface to SuiteSparse:GraphBLAS is included with this 972distribution, described in Section~\ref{matlab}. 973It is fully polished, and fully tested, but does have 974some limitations that will be addressed in future releases. 975 976A beta version of a Python interface is now available, as is a 977Julia interface. These are not part of the SuiteSparse:GraphBLAS distribution. 978See the links below (see Sections \ref{python} and \ref{julia}). 979 980%=============================================================================== 981\subsection{MATLAB Interface} 982%=============================================================================== 983\label{matlab} 984 985An easy-to-use MATLAB interface for SuiteSparse:GraphBLAS is available; see the 986documentation in the \verb'GraphBLAS/GraphBLAS' folder for details. Start with 987the \verb'README.md' file in that directory. An easy-to-read output of the 988MATLAB demos can be found in \verb'GraphBLAS/GraphBLAS/demo/html'. 989 990The MATLAB interface adds the \verb'@GrB' class, which is an opaque MATLAB 991object that contains a GraphBLAS matrix, either double or single precision 992(real or complex), boolean, or any of the built-in integer types. MATLAB 993sparse and full matrices can be arbitrarily mixed with GraphBLAS matrices. The 994following overloaded operators and methods all work as you would expect for any 995matrix. The matrix multiplication \verb'A*B' uses the conventional 996\verb'PLUS_TIMES' semiring. 997 998{\footnotesize 999\begin{verbatim} 1000A+B A-B A*B A.*B A./B A.\B A.^b A/b C=A(I,J) 1001-A +A ~A A' A.' A&B A|B b\A C(I,J)=A 1002A~=B A>B A==B A<=B A>=B A<B [A,B] [A;B] A(1:end,1:end) \end{verbatim}} 1003 1004For a list of overloaded operations and static methods, type 1005\verb'methods GrB' in MATLAB, or \verb'help GrB' for more details. 1006 1007{\bf Limitations:} 1008Some features for MATLAB sparse matrices are not yet available for 1009GraphBLAS matrices. Some of these may be added in future releases. 1010 1011\begin{packed_itemize} 1012 \item If you save a GrB matrix object from MATLAB using one version 1013 of SuiteSparse:GraphBLAS, you can load it back in in that version or in 1014 a later version. You cannot go backwards, and save in v5.x and load in 1015 v4.x, for example. 1016 \item \verb'GrB' matrices with dimension larger than \verb'2^53' do not 1017 display properly in the MATLAB \verb'whos' command. MATLAB gets this 1018 information from \verb'size(A)', which returns a correct result, but 1019 MATLAB rounds it to double before displaying it. The size is displayed 1020 correctly with \verb'disp' or \verb'display'. 1021 \item Non-blocking mode is not exploited; this would require 1022 a MATLAB mexFunction to modify its inputs, which is 1023 technically possible but not permitted by the MATLAB API. 1024 This can have significant impact on performance, if a MATLAB 1025 m-file makes many repeated tiny changes to a matrix. This kind of 1026 computation can often be done with good performance in the C API, 1027 but will be very slow in MATLAB. 1028 \item Linear indexing, or \verb'A(:)' for a 2D matrix, and 1029 a single output of \verb'I=find(A)'. 1030 \item The second output for \verb'min' and \verb'max', 1031 and the \verb'includenan' option. 1032 \item Singleton expansion. 1033 \item Dynamically growing arrays, where \verb'C(i)=x' can increase 1034 the size of \verb'C'. 1035 \item Saturating element-wise binary and unary operators for integers. 1036 For \verb'C=A+B' with MATLAB \verb'uint8' matrices, results 1037 saturate if they exceed 255. This is not compatible with 1038 a monoid for \verb'C=A*B', and thus MATLAB does not support 1039 matrix-matrix multiplication with \verb'uint8' matrices. 1040 In GraphBLAS, \verb'uint8' addition acts in a modulo fashion. 1041 Saturating binary operators could be added in the future, 1042 so that \verb"GrB.eadd (A, '+saturate', B)" could return the 1043 MATLAB result. 1044 \item Solvers, so that \verb'x=A\b' could return a GF(2) solution, 1045 for example. 1046 \item Sparse matrices with dimension higher than 2. 1047\end{packed_itemize} 1048 1049%=============================================================================== 1050\subsection{Python Interface} 1051%=============================================================================== 1052\label{python} 1053 1054See Michel Pelletier's Python interface at 1055\href{https://github.com/michelp/pygraphblas}{https://github.com/michelp/pygraphblas}; 1056it also appears at 1057\href{https://anaconda.org/conda-forge/pygraphblas}{https://anaconda.org/conda-forge/pygraphblas}. 1058 1059See Jim Kitchen and Erik Welch's (both from Anaconda, Inc.) Python interface at 1060\href{https://github.com/metagraph-dev/grblas}{https://github.com/metagraph-dev/grblas}. 1061See also 1062\href{https://anaconda.org/conda-forge/graphblas}{https://anaconda.org/conda-forge/graphblas}. 1063 1064%=============================================================================== 1065\subsection{Julia Interface} 1066%=============================================================================== 1067\label{julia} 1068 1069See Abhinav Mehndiratta's Julia interface at \\ 1070\href{https://github.com/abhinavmehndiratta/SuiteSparseGraphBLAS.jl}{https://github.com/abhinavmehndiratta/SuiteSparseGraphBLAS.jl}. 1071 1072%=============================================================================== 1073\subsection{Java Interface} 1074%=============================================================================== 1075\label{java} 1076 1077Fabian Murariu is working on a Java interface. 1078See \newline 1079\href{https://github.com/fabianmurariu/graphblas-java-native}{https://github.com/fabianmurariu/graphblas-java-native}. 1080 1081\newpage 1082%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1083\section{GraphBLAS Context and Sequence} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1084%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1085\label{context} 1086 1087A user application that directly relies on GraphBLAS must include the 1088\verb'GraphBLAS.h' header file: 1089 1090\begin{mdframed}[userdefinedwidth=6in] 1091{\footnotesize 1092\begin{verbatim} 1093 #include "GraphBLAS.h" 1094\end{verbatim} 1095} \end{mdframed} 1096 1097The \verb'GraphBLAS.h' file defines functions, types, and macros prefixed with 1098\verb'GrB_' and \verb'GxB_' that may be used in user applications. The prefix 1099\verb'GrB_' denote items that appear in the official {\em GraphBLAS C API 1100Specification}. The prefix \verb'GxB_' refers to SuiteSparse-specific 1101extensions to the GraphBLAS API. 1102 1103The \verb'GraphBLAS.h' file includes all the definitions required to use 1104GraphBLAS, including the following macros that can assist a user application in 1105compiling and using GraphBLAS. 1106 1107There are two version numbers associated with SuiteSparse:GraphBLAS: 1108the version of the {\em GraphBLAS C API Specification} it 1109conforms to, and the version of the implementation itself. These can 1110be used in the following manner in a user application: 1111 1112{\footnotesize 1113\begin{verbatim} 1114 #if GxB_SPEC_VERSION >= GxB_VERSION (2,0,3) 1115 ... use features in GraphBLAS specification 2.0.3 ... 1116 #else 1117 ... only use features in early specifications 1118 #endif 1119 1120 #if GxB_IMPLEMENTATION >= GxB_VERSION (4,0,0) 1121 ... use features from version 4.0.1 (or later) 1122 of a specific GraphBLAS implementation 1123 #endif \end{verbatim}} 1124 1125SuiteSparse:GraphBLAS also defines the following strings with \verb'#define'. 1126Refer to the \verb'GraphBLAS.h' file for details. 1127 1128\vspace{0.2in} 1129{\footnotesize 1130\begin{tabular}{ll} 1131\hline 1132Macro & purpose \\ 1133\hline 1134\verb'GxB_IMPLEMENTATION_ABOUT' 1135 & this particular implementation, copyright, and URL \\ 1136\verb'GxB_IMPLEMENTATION_DATE' 1137 & the date of this implementation \\ 1138\verb'GxB_SPEC_ABOUT' 1139 & the GraphBLAS specification for this implementation \\ 1140\verb'GxB_SPEC_DATE' 1141 & the date of the GraphBLAS specification \\ 1142\verb'GxB_IMPLEMENTATION_LICENSE' 1143 & the license for this particular implementation \\ 1144\hline 1145\end{tabular} 1146} 1147\vspace{0.2in} 1148 1149Finally, SuiteSparse:GraphBLAS gives itself a unique name of the form 1150\verb'GxB_SUITESPARSE_GRAPHBLAS' that the user application can use in 1151\verb'#ifdef' tests. This is helpful in case a particular implementation 1152provides non-standard features that extend the GraphBLAS specification, such as 1153additional predefined built-in operators, or if a GraphBLAS implementation does 1154not yet fully implement all of the GraphBLAS specification. The 1155SuiteSparse:GraphBLAS name is provided in its \verb'GraphBLAS.h' file as: 1156 1157 {\footnotesize 1158 \begin{verbatim} 1159 #define GxB_SUITESPARSE_GRAPHBLAS \end{verbatim}} 1160 1161For example, SuiteSparse:GraphBLAS predefines additional built-in operators not 1162in the specification. If the user application wishes to use these in any 1163GraphBLAS implementation, an \verb'#ifdef' can control when they are used. 1164Refer to the examples in the \verb'GraphBLAS/Demo' folder. 1165 1166As another example, the GraphBLAS API states that an 1167implementation need not define the order in which \verb'GrB_Matrix_build' 1168assembles duplicate tuples in its \verb'[I,J,X]' input arrays. As a result, no 1169particular ordering should be relied upon in general. However, 1170SuiteSparse:GraphBLAS does guarantee an ordering, and this guarantee will be 1171kept in future versions of SuiteSparse:GraphBLAS as well. Since not all 1172implementations will ensure a particular ordering, the following can be used to 1173exploit the ordering returned by SuiteSparse:GraphBLAS. 1174 1175 {\footnotesize 1176 \begin{verbatim} 1177 #ifdef GxB_SUITESPARSE_GRAPHBLAS 1178 // duplicates in I, J, X assembled in a specific order; 1179 // results are well-defined even if op is not associative. 1180 GrB_Matrix_build (C, I, J, X, nvals, op) ; 1181 #else 1182 // duplicates in I, J, X assembled in no particular order; 1183 // results are undefined if op is not associative. 1184 GrB_Matrix_build (C, I, J, X, nvals, op) ; 1185 #endif \end{verbatim}} 1186 1187The remainder of this section describes GraphBLAS functions that create, 1188modify, and destroy the GraphBLAS context, or provide utility methods for 1189dealing with errors: 1190 1191\vspace{0.2in} 1192{\footnotesize 1193\begin{tabular}{lll} 1194\hline 1195GraphBLAS function & purpose & Section \\ 1196\hline 1197\verb'GrB_init' & start up GraphBLAS & \ref{init} \\ 1198\verb'GrB_getVersion'& C API supported by the library & \ref{getVersion} \\ 1199\verb'GxB_init' & start up GraphBLAS with different \verb'malloc' & \ref{xinit} \\ 1200\verb'GrB_Info' & status code returned by GraphBLAS functions & \ref{info} \\ 1201\verb'GrB_error' & get more details on the last error & \ref{error} \\ 1202\verb'GrB_finalize' & finish GraphBLAS & \ref{finalize} \\ 1203\hline 1204\end{tabular} 1205} 1206\vspace{0.2in} 1207 1208%=============================================================================== 1209\subsection{{\sf GrB\_Index:} the GraphBLAS integer} %========================== 1210%=============================================================================== 1211\label{grbindex} 1212 1213Matrix and vector dimensions and indexing rely on a specific integer, 1214\verb'GrB_Index', which is defined in \verb'GraphBLAS.h' as 1215 1216 {\footnotesize 1217 \begin{verbatim} 1218 typedef uint64_t GrB_Index ; \end{verbatim}} 1219 1220Row and column indices of an \verb'nrows'-by-\verb'ncols' matrix range from 1221zero to the \verb'nrows-1' for the rows, and zero to \verb'ncols-1' for the 1222columns. Indices are zero-based, like C, and not one-based, like MATLAB. In 1223SuiteSparse:GraphBLAS, the largest size permitted for any integer of 1224\verb'GrB_Index' is $2^{60}$. The largest \verb'GrB_Matrix' that 1225SuiteSparse:GraphBLAS can construct is thus $2^{60}$-by-$2^{60}$. An 1226$n$-by-$n$ matrix $A$ that size can easily be constructed in practice with 1227$O(|{\bf A}|)$ memory requirements, where $|{\bf A}|$ denotes the number of 1228entries that explicitly appear in the pattern of ${\bf A}$. The time and 1229memory required to construct a matrix that large does not depend on $n$, since 1230SuiteSparse:GraphBLAS can represent ${\bf A}$ in hypersparse form (see 1231Section~\ref{hypersparse}). The largest \verb'GrB_Vector' that can be 1232constructed is $2^{60}$-by-1. 1233 1234%=============================================================================== 1235\subsection{{\sf GrB\_init:} initialize GraphBLAS} %============================ 1236%=============================================================================== 1237\label{init} 1238 1239\begin{mdframed}[userdefinedwidth=6in] 1240{\footnotesize 1241\begin{verbatim} 1242typedef enum 1243{ 1244 GrB_NONBLOCKING = 0, // methods may return with pending computations 1245 GrB_BLOCKING = 1 // no computations are ever left pending 1246} 1247GrB_Mode ; 1248\end{verbatim} 1249}\end{mdframed} 1250 1251\begin{mdframed}[userdefinedwidth=6in] 1252{\footnotesize 1253\begin{verbatim} 1254GrB_Info GrB_init // start up GraphBLAS 1255( 1256 GrB_Mode mode // blocking or non-blocking mode 1257) ; 1258\end{verbatim} 1259}\end{mdframed} 1260 1261\hypertarget{link:init}{\mbox{ }}% 1262\verb'GrB_init' must be called before any other GraphBLAS operation. It 1263defines the mode that GraphBLAS will use: blocking or non-blocking. With 1264blocking mode, all operations finish before returning to the user application. 1265With non-blocking mode, operations can be left pending, and are computed only 1266when needed. Non-blocking mode can be much faster than blocking mode, by many 1267orders of magnitude in extreme cases. Blocking mode should be used only when 1268debugging a user application. The mode cannot be changed once it is set by 1269\verb'GrB_init'. 1270 1271GraphBLAS objects are opaque. This allows GraphBLAS to 1272postpone operations and then do them later in a more efficient manner by 1273rearranging them and grouping them together. In non-blocking mode, the 1274computations required to construct an opaque GraphBLAS object might not be 1275finished when the GraphBLAS method or operation returns to the user. However, 1276user-provided arrays are not opaque, and GraphBLAS methods and operations that 1277read them (such as \verb'GrB_Matrix_build') or write to them (such as 1278\verb'GrB_Matrix_extractTuples') always finish reading them, or creating them, 1279when the method or operation returns to the user application. 1280 1281All methods and operations that extract values from a GraphBLAS object and 1282return them into non-opaque user arrays always ensure that the user-visible 1283arrays are fully populated when they return: \verb'GrB_*_reduce' (to scalar), 1284\verb'GrB_*_nvals', \verb'GrB_*_extractElement', and 1285\verb'GrB_*_extractTuples'. These functions do {\em not} guarantee that the 1286opaque objects they depend on are finalized. To do that, use 1287\verb'GrB_wait(&object)' instead. 1288 1289SuiteSparse:GraphBLAS is multithreaded internally, via OpenMP, and it is also 1290safe to use in a multithreaded user application. See Section~\ref{sec:install} 1291for details. 1292User threads must not operate on the same matrices at the same time, with one 1293exception. Multiple user threads can use the same matrices or vectors as 1294read-only inputs to GraphBLAS operations or methods, but only if they have no 1295pending operations (use \verb'GrB_Matrix_wait' or \verb'GrB_Vector_wait' 1296first). User threads cannot simultaneously modify a matrix or vector via any 1297GraphBLAS operation or method. 1298 1299It is safe to use the internal parallelism in SuiteSparse:GraphBLAS on 1300matrices, vectors, and scalars that are not yet completed. The library 1301handles this on its own. The \verb'GrB_*_wait(&object)' function is only 1302needed when a user application makes multiple calls to GraphBLAS in parallel, 1303from multiple user threads. 1304 1305With multiple user threads, exactly one user thread must call \verb'GrB_init' 1306before any user thread may call any \verb'GrB_*' or \verb'GxB_*' function. 1307When the user application is finished, exactly one user thread must call 1308\verb'GrB_finalize', after which no user thread may call any \verb'GrB_*' or 1309\verb'GxB_*' function. 1310The mode of a GraphBLAS session can be queried with \verb'GxB_get'; 1311see Section~\ref{options} for details. 1312 1313\newpage 1314%=============================================================================== 1315\subsection{{\sf GrB\_getVersion:} determine the C API Version} %=============== 1316%=============================================================================== 1317\label{getVersion} 1318 1319\begin{mdframed}[userdefinedwidth=6in] 1320{\footnotesize 1321\begin{verbatim} 1322GrB_Info GrB_getVersion // runtime access to C API version number 1323( 1324 unsigned int *version, // returns GRB_VERSION 1325 unsigned int *subversion // returns GRB_SUBVERSION 1326) ; 1327\end{verbatim} 1328}\end{mdframed} 1329 1330GraphBLAS defines two compile-time constants that 1331define the version of the C API Specification 1332that is implemented by the library: 1333\verb'GRB_VERSION' and \verb'GRB_SUBVERSION'. 1334If the user program was compiled with one 1335version of the library but linked with a different one later on, the 1336compile-time version check with \verb'GRB_VERSION' would be stale. 1337\verb'GrB_getVersion' thus provides a runtime access of the version of the C 1338API Specification supported by the library. 1339 1340\begin{alert} 1341{\bf SPEC:} 1342This version of SuiteSparse:GraphBLAS supports 1343\input{GraphBLAS_API_version.tex} 1344of the C API Specification, with the exception of changes to \verb'GrB_wait', 1345\verb'GrB_error', and \verb'GrB_Matrix_reduce_BinaryOp'. 1346\end{alert} 1347 1348%=============================================================================== 1349\subsection{{\sf GxB\_init:} initialize with alternate malloc} %================ 1350%=============================================================================== 1351\label{xinit} 1352 1353\begin{mdframed}[userdefinedwidth=6in] 1354{\footnotesize 1355\begin{verbatim} 1356GrB_Info GxB_init // start up GraphBLAS and also define malloc, etc 1357( 1358 GrB_Mode mode, // blocking or non-blocking mode 1359 // pointers to memory management functions. 1360 void * (* user_malloc_function ) (size_t), 1361 void * (* user_calloc_function ) (size_t, size_t), 1362 void * (* user_realloc_function ) (void *, size_t), 1363 void (* user_free_function ) (void *), 1364 bool user_malloc_is_thread_safe 1365) ; 1366\end{verbatim} 1367}\end{mdframed} 1368 1369\verb'GxB_init' is identical to \verb'GrB_init', except that it also redefines 1370the memory management functions that SuiteSparse:GraphBLAS will use. Giving 1371the user application control over this is particularly important when using the 1372\verb'GxB_*import' and \verb'GxB_*export' functions described in 1373Section~\ref{import_export}, since they require the user application and 1374GraphBLAS to use the same memory manager. 1375 1376\verb'user_calloc_function' and \verb'user_realloc_function' are optional, and 1377may be \verb'NULL'. If \verb'NULL', then the \verb'user_malloc_function' is 1378relied on instead, for all memory allocations. 1379 1380These 1381functions can only be set once, when GraphBLAS starts. Either \verb'GrB_init' 1382or \verb'GxB_init' must be called before any other GraphBLAS operation, but 1383not both. The last argument to \verb'GxB_init' informs GraphBLAS as to 1384whether or not the functions are thread-safe. The ANSI C and Intel TBB 1385functions are thread-safe, but the MATLAB \verb'mxMalloc' and related 1386functions are not thread-safe. If not thread-safe, GraphBLAS calls 1387the functions from inside an OpenMP critical section. 1388 1389The following usage is identical to \verb'GrB_init(mode)': 1390 1391 {\footnotesize 1392 \begin{verbatim} 1393 GxB_init (mode, malloc, calloc, realloc, free, true) ; \end{verbatim}} 1394 1395SuiteSparse:GraphBLAS can be compiled as normal (outside of MATLAB) and then 1396linked into a MATLAB \verb'mexFunction'. However, a \verb'mexFunction' should 1397use the MATLAB memory managers. To do this, use the following instead of 1398\verb'GrB_init(mode)' in a MATLAB \verb'mexFunction', with the flag 1399\verb'false' since these functions are not thread-safe: 1400 1401 {\footnotesize 1402 \begin{verbatim} 1403 #include "mex.h" 1404 #include "GraphBLAS.h" 1405 ... 1406 GxB_init (mode, mxMalloc, mxCalloc, mxRealloc, mxFree, false) ; \end{verbatim}} 1407 1408Passing in the last parameter as \verb'false' requires that GraphBLAS be 1409compiled with OpenMP. Internally, SuiteSparse:GraphBLAS never calls any memory 1410management function inside a parallel region. Results are undefined if all 1411three of the following conditions hold: (1) the user application calls 1412GraphBLAS in parallel from multiple user-level threads, (2) the memory 1413functions are not thread-safe, and (3) GraphBLAS is not compiled with OpenMP. 1414Safety is guaranteed if at least one of those conditions is false. 1415 1416To use the scalable Intel TBB memory manager: 1417 1418 {\footnotesize 1419 \begin{verbatim} 1420 #include "tbb/scalable_allocator.h" 1421 #include "GraphBLAS.h" 1422 ... 1423 GxB_init (mode, scalable_malloc, scalable_calloc, scalable_realloc, 1424 scalable_free, true) ; \end{verbatim}} 1425 1426\newpage 1427%=============================================================================== 1428\subsection{{\sf GrB\_Info:} status code returned by GraphBLAS} %=============== 1429%=============================================================================== 1430\label{info} 1431 1432Each GraphBLAS method and operation returns its status to the caller as its 1433return value, an enumerated type (an \verb'enum') called \verb'GrB_Info'. The 1434first two values in the following table denote a successful status, the rest 1435are error codes. 1436 1437\vspace{0.2in} 1438\noindent 1439{\small 1440\begin{tabular}{llp{2.8in}} 1441\hline 1442\verb'GrB_SUCCESS' & 0 & the method or operation was successful \\ 1443\verb'GrB_NO_VALUE' & 1 & the method was successful, but the entry \\ 1444 & & does not appear in the matrix or vector. \\ 1445\hline 1446\hline 1447\verb'GrB_UNINITIALIZED_OBJECT' & 2 & object has not been initialized \\ 1448\verb'GrB_INVALID_OBJECT' & 3 & object is corrupted \\ 1449\verb'GrB_NULL_POINTER' & 4 & input pointer is \verb'NULL' \\ 1450\verb'GrB_INVALID_VALUE' & 5 & generic error code; some value is bad \\ 1451\verb'GrB_INVALID_INDEX' & 6 & a row or column index is out of bounds \\ 1452\verb'GrB_DOMAIN_MISMATCH' & 7 & object domains are not compatible \\ 1453\verb'GrB_DIMENSION_MISMATCH' & 8 & matrix dimensions do not match \\ 1454\verb'GrB_OUTPUT_NOT_EMPTY' & 9 & output matrix already has values in it \\ 1455\hline 1456\verb'GrB_OUT_OF_MEMORY' & 10 & out of memory \\ 1457\verb'GrB_INSUFFICIENT_SPACE' & 11 & output array not large enough \\ 1458\verb'GrB_INDEX_OUT_OF_BOUNDS' & 12 & a row or column index is out of bounds \\ 1459\hline 1460\verb'GrB_PANIC' & 13 & unrecoverable error. 1461\\ 1462\hline 1463\end{tabular} 1464\vspace{0.2in} 1465} 1466 1467Not all GraphBLAS methods or operations can return all status codes. Any 1468GraphBLAS method or operation can return an out-of-memory condition, 1469\verb'GrB_OUT_OF_MEMORY', or a panic, \verb'GrB_PANIC'. These two errors, and 1470the \verb'GrB_INDEX_OUT_OF_BOUNDS' error, are called {\em execution errors}. 1471The other errors are called {\em API} errors. An API error is detected 1472immediately, regardless of the blocking mode. The detection of an execution 1473error may be deferred until the pending operations complete. 1474 1475In the discussions of each method and operation in this User Guide, most of the 1476obvious error code returns are not discussed. For example, if a required input 1477is a \verb'NULL' pointer, then \verb'GrB_NULL_POINTER' is returned. Only error 1478codes specific to the method or that require elaboration are discussed here. 1479For a full list of the status codes that each GraphBLAS function can return, 1480refer to {\em The GraphBLAS C API Specification} \cite{spec}. 1481 1482\newpage 1483%=============================================================================== 1484\subsection{{\sf GrB\_error:} get more details on the last error} %============= 1485%=============================================================================== 1486\label{error} 1487 1488\begin{mdframed}[userdefinedwidth=6in] 1489{\footnotesize 1490\begin{verbatim} 1491GrB_Info GrB_error // return a string describing the last error 1492( 1493 const char **error, // error string 1494 <type> object // a GrB_matrix, GrB_Vector, etc. 1495) ; 1496\end{verbatim} 1497}\end{mdframed} 1498 1499Each GraphBLAS method and operation returns a \verb'GrB_Info' error code. The 1500\verb'GrB_error' function returns additional information on the error for a 1501particular object in a null-terminated string. The string returned by 1502\verb'GrB_error' is never a \verb'NULL' string, but it may have length zero 1503(with the first entry being the \verb"'\0'" string-termination value). The 1504string must not be freed or modified. 1505 1506 {\footnotesize 1507 \begin{verbatim} 1508 info = GrB_some_method_here (C, ...) ; 1509 if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) 1510 { 1511 char *err ; 1512 GrB_error (&err, C) ; 1513 printf ("info: %d error: %s\n", info, err) ; 1514 } \end{verbatim}} 1515 1516If \verb'C' has no error status, or if the error is not recorded in 1517the string, an empty non-null string is returned. In particular, 1518out-of-memory conditions result in an empty string fro \verb'GrB_error'. 1519 1520SuiteSparse:GraphBLAS reports many helpful details via \verb'GrB_error'. For 1521example, if a row or column index is out of bounds, the report will state what 1522those bounds are. If a matrix dimension is incorrect, the mismatching 1523dimensions will be provided. \verb'GrB_BinaryOp_new', \verb'GrB_UnaryOp_new', 1524and \verb'GxB_SelectOp_new' record the name the function passed to them, and 1525\verb'GrB_Type_new' records the name of its type parameter, and these are 1526printed if the user-defined types and operators are used incorrectly. Refer to 1527the output of the example programs in the \verb'Demo' and \verb'Test' folder, 1528which intentionally generate errors to illustrate the use of \verb'GrB_error'. 1529 1530The only functions in GraphBLAS that return an error string are functions that 1531have a single input/output argument \verb'C', as a \verb'GrB_Matrix', 1532\verb'GrB_Vector', \verb'GxB_Scalar', or \verb'GrB_Descriptor'. Methods that 1533create these objects (such as \verb'GrB_Matrix_new') return a \verb'NULL' 1534object on failure, so these methods cannot also return an error string in 1535\verb'C'. 1536 1537Any subsequent GraphBLAS method that modifies the object \verb'C' clears the 1538error string. 1539 1540Note that \verb'GrB_NO_VALUE' is an not error, but an informational status. 1541\verb'GrB_*_extractElment(&x,A,i,j)', which does \verb'x=A(i,j)', returns this 1542value to indicate that \verb'A(i,j)' is not present in the matrix. That 1543method does not have an input/output object so it cannot return an error 1544string. 1545 1546The \verb'GrB_error' function is a polymorphic function for the 1547following variants: 1548 1549\begin{mdframed}[userdefinedwidth=6in] 1550{\footnotesize 1551\begin{verbatim} 1552GrB_Info GrB_Type_error (const char **error, const GrB_Type type) ; 1553GrB_Info GrB_UnaryOp_error (const char **error, const GrB_UnaryOp op) ; 1554GrB_Info GrB_BinaryOp_error (const char **error, const GrB_BinaryOp op) ; 1555GrB_Info GxB_SelectOp_error (const char **error, const GxB_SelectOp op) ; 1556GrB_Info GrB_Monoid_error (const char **error, const GrB_Monoid monoid) ; 1557GrB_Info GrB_Semiring_error (const char **error, const GrB_Semiring semiring) ; 1558GrB_Info GxB_Scalar_error (const char **error, const GxB_Scalar s) ; 1559GrB_Info GrB_Vector_error (const char **error, const GrB_Vector v) ; 1560GrB_Info GrB_Matrix_error (const char **error, const GrB_Vector A) ; 1561GrB_Info GrB_Descriptor_error (const char **error, const GrB_Descriptor d) ; 1562\end{verbatim} 1563}\end{mdframed} 1564 1565Currently, only \verb'GrB_Matrix_error', \verb'GrB_Vector_error', 1566\verb'GxB_Scalar_error', and \verb'GrB_Descriptor_error' are able to return 1567non-empty error strings. The latter can return an error string only from 1568\verb'GrB_Descriptor_set' and \verb'GxB_set(d,...)'. 1569 1570The only GraphBLAS methods (Section~\ref{objects}) that return an error string 1571are \verb'*setElement', \verb'*removeElement', 1572\verb'GxB_Matrix_Option_set(A,...)', \newline 1573\verb'GxB_Vector_Option_set(v,...)', \verb'GrB_Descriptor_set', and 1574\verb'GxB_Desc_set(d,...)'. All GraphBLAS operations discussed in 1575Section~\ref{operations} can return an error string in their input/output 1576object, except for \verb'GrB_reduce' when reducing to a scalar. 1577 1578\begin{alert} 1579{\bf SPEC:} \verb'GrB_error' conforms to a draft of the v2.0 GraphBLAS C 1580Specification. The v1.3 version of this function has the signature \newline 1581\verb'const char *GrB_error (void)', with no inputs, which is no 1582longer supported in SuiteSparse:GraphBLAS v4 or later. 1583\end{alert} 1584 1585\newpage 1586%=============================================================================== 1587\subsection{{\sf GrB\_wait:} on all objects} %================================== 1588%=============================================================================== 1589\label{wait_all} 1590 1591\begin{mdframed}[userdefinedwidth=6in] 1592{\footnotesize 1593\begin{verbatim} 1594GrB_Info GrB_wait ( ) ; // wait for all objects: NOT SUPPORTED 1595\end{verbatim} 1596}\end{mdframed} 1597 1598\begin{alert} 1599{\bf SPEC:} The v1.3 GraphBLAS C API Specification includes \verb'GrB_wait ( )' 1600with no inputs, which waits for all objects computed by any user thread. This 1601has serious performance issues and thus it is no longer implemented in 1602SuiteSparse:GraphBLAS v4 and later. SuiteSparse:GraphBLAS only provides 1603\verb'GrB_wait (&object)', to wait on a single object. 1604\end{alert} 1605 1606%=============================================================================== 1607\subsection{{\sf GrB\_finalize:} finish GraphBLAS} %============================ 1608%=============================================================================== 1609\label{finalize} 1610 1611\begin{mdframed}[userdefinedwidth=6in] 1612{\footnotesize 1613\begin{verbatim} 1614GrB_Info GrB_finalize ( ) ; // finish GraphBLAS 1615\end{verbatim} 1616}\end{mdframed} 1617 1618\verb'GrB_finalize' must be called as the last GraphBLAS operation, even after 1619all calls to \verb'GrB_free'. All GraphBLAS objects created by the user 1620application should be freed first, before calling \verb'GrB_finalize' since 1621\verb'GrB_finalize' will not free those objects. In non-blocking mode, 1622GraphBLAS may leave some computations as pending. These computations can be 1623safely abandoned if the user application frees all GraphBLAS objects it has 1624created and then calls \verb'GrB_finalize'. When the user application is 1625finished, exactly one user thread must call \verb'GrB_finalize'. 1626 1627\newpage 1628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1629\section{GraphBLAS Objects and their Methods} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1630%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1631\label{objects} 1632 1633GraphBLAS defines eight different objects to represent matrices and vectors, 1634their scalar data type (or domain), binary and unary operators on scalar types, 1635monoids, semirings, and a {\em descriptor} object used to specify optional 1636parameters that modify the behavior of a GraphBLAS operation. 1637SuiteSparse:GraphBLAS adds two additional objects: a scalar 1638(\verb'GxB_Scalar'), and an operator for selecting entries from a matrix or 1639vector (\verb'GxB_SelectOp'). 1640 1641The GraphBLAS API makes a distinction between {\em methods} and {\em 1642operations}. A method is a function that works on a GraphBLAS object, creating 1643it, destroying it, or querying its contents. An operation (not to be confused 1644with an operator) acts on matrices and/or vectors in a semiring. 1645 1646\vspace{0.1in} 1647\noindent 1648{\small 1649\begin{tabular}{ll} 1650\hline 1651\verb'GrB_Type' & a scalar data type \\ 1652\verb'GrB_UnaryOp' & a unary operator $z=f(x)$, where $z$ and $x$ are scalars\\ 1653\verb'GrB_BinaryOp' & a binary operator $z=f(x,y)$, where $z$, $x$, and $y$ are scalars\\ 1654\verb'GxB_SelectOp' & a select operator \\ 1655\verb'GrB_Monoid' & an associative and commutative binary operator \\ 1656 & and its identity value \\ 1657\verb'GrB_Semiring' & a monoid that defines the ``plus'' and a binary operator\\ 1658 & that defines the ``multiply'' for an algebraic semiring \\ 1659\verb'GrB_Matrix' & a 2D sparse matrix of any type \\ 1660\verb'GrB_Vector' & a 1D sparse column vector of any type \\ 1661\verb'GxB_Scalar' & a scalar of any type \\ 1662\verb'GrB_Descriptor'& a collection of parameters that modify an operation \\ 1663\hline 1664\end{tabular} 1665} 1666\vspace{0.1in} 1667 1668Each of these objects is implemented in C as an opaque handle, which is a 1669pointer to a data structure held by GraphBLAS. User applications may not 1670examine the content of the object directly; instead, they can pass the handle 1671back to GraphBLAS which will do the work. Assigning one handle to another 1672is valid but it does not make a copy of the underlying object. 1673 1674\newpage 1675%=============================================================================== 1676\subsection{The GraphBLAS type: {\sf GrB\_Type}} %============================== 1677%=============================================================================== 1678\label{type} 1679 1680A GraphBLAS \verb'GrB_Type' defines the type of scalar values that a matrix or 1681vector contains, and the type of scalar operands for a unary or binary 1682operator. There are 13 built-in types, and a user application can define 1683any types of its own as well. The built-in types correspond to built-in types 1684in C (\verb'#include <stdbool.h>' and \verb'#include <stdint.h>'), and the 1685classes in MATLAB, as listed in the following table. 1686 1687MATLAB allows for \verb'double complex' sparse matrices, but the 1688\verb'class(A)' for such a matrix is just \verb'double'. MATLAB treats 1689the complex types as properties of a class. 1690 1691\vspace{0.2in} 1692\noindent 1693{\footnotesize 1694\begin{tabular}{lllll} 1695\hline 1696GraphBLAS & C type & MATLAB & description & range \\ 1697type & & class & & \\ 1698\hline 1699\verb'GrB_BOOL' & \verb'bool' & \verb'logical' & Boolean & true (1), false (0) \\ 1700\hline 1701\verb'GrB_INT8' & \verb'int8_t' & \verb'int8' & 8-bit signed integer & -128 to 127 \\ 1702\verb'GrB_INT16' & \verb'int16_t' & \verb'int16' & 16-bit integer & $-2^{15}$ to $2^{15}-1$ \\ 1703\verb'GrB_INT32' & \verb'int32_t' & \verb'int32' & 32-bit integer & $-2^{31}$ to $2^{31}-1$ \\ 1704\verb'GrB_INT64' & \verb'int64_t' & \verb'int64' & 64-bit integer & $-2^{63}$ to $2^{63}-1$ \\ 1705\hline 1706\verb'GrB_UINT8' & \verb'uint8_t' & \verb'uint8' & 8-bit unsigned integer & 0 to 255 \\ 1707\verb'GrB_UINT16' & \verb'uint16_t' & \verb'uint16' & 16-bit unsigned integer & 0 to $2^{16}-1$ \\ 1708\verb'GrB_UINT32' & \verb'uint32_t' & \verb'uint32' & 32-bit unsigned integer & 0 to $2^{32}-1$ \\ 1709\verb'GrB_UINT64' & \verb'uint64_t' & \verb'uint64' & 64-bit unsigned integer & 0 to $2^{64}-1$ \\ 1710\hline 1711\verb'GrB_FP32' & \verb'float' & \verb'single' & 32-bit IEEE 754 & \verb'-Inf' to \verb'+Inf'\\ 1712\verb'GrB_FP64' & \verb'double' & \verb'double' & 64-bit IEEE 754 & \verb'-Inf' to \verb'+Inf'\\ 1713\hline 1714\verb'GxB_FC32' & \verb'float complex' & \verb'single' & 32-bit IEEE 754 & \verb'-Inf' to \verb'+Inf'\\ 1715 & & \verb'~isreal(.)' & complex & \\ 1716\hline 1717\verb'GxB_FC64' & \verb'double complex' & \verb'double' & 64-bit IEEE 754 & \verb'-Inf' to \verb'+Inf'\\ 1718 & & \verb'~isreal(.)' & complex & \\ 1719\hline 1720\end{tabular} 1721} 1722\vspace{0.2in} 1723 1724The ANSI C11 definitions of \verb'float complex' and \verb'double complex' 1725are not always available. The \verb'GraphBLAS.h' header defines them as 1726\verb'GxB_FC32_t' and \verb'GxB_FC64_t', respectively. 1727 1728The user application can also define new types based on any \verb'typedef' in 1729the C language whose values are held in a contiguous region of memory. For 1730example, a user-defined \verb'GrB_Type' could be created to hold any C 1731\verb'struct' whose content is self-contained. A C \verb'struct' containing 1732pointers might be problematic because GraphBLAS would not know to dereference 1733the pointers to traverse the entire ``scalar'' entry, but this can be done if 1734the objects referenced by these pointers are not moved. A user-defined complex 1735type with real and imaginary types can be defined, or even a ``scalar'' type 1736containing a fixed-sized dense matrix (see Section~\ref{type_new}). The 1737possibilities are endless. GraphBLAS can create and operate on sparse matrices 1738and vectors in any of these types, including any user-defined ones. For 1739user-defined types, GraphBLAS simply moves the data around itself (via 1740\verb'memcpy'), and then passes the values back to user-defined functions when 1741it needs to do any computations on the type. The next sections describe the 1742methods for the \verb'GrB_Type' object: 1743 1744\vspace{0.2in} 1745{\footnotesize 1746\begin{tabular}{ll} 1747\hline 1748\verb'GrB_Type_new' & create a user-defined type \\ 1749\verb'GrB_Type_wait' & wait for a user-defined type \\ 1750\verb'GxB_Type_size' & return the size of a type \\ 1751\verb'GrB_Type_free' & free a user-defined type \\ 1752\hline 1753\end{tabular} 1754} 1755\vspace{0.2in} 1756 1757\newpage 1758%------------------------------------------------------------------------------- 1759\subsubsection{{\sf GrB\_Type\_new:} create a user-defined type} 1760%------------------------------------------------------------------------------- 1761\label{type_new} 1762 1763\begin{mdframed}[userdefinedwidth=6in] 1764{\footnotesize 1765\begin{verbatim} 1766GrB_Info GrB_Type_new // create a new GraphBLAS type 1767( 1768 GrB_Type *type, // handle of user type to create 1769 size_t sizeof_ctype // size = sizeof (ctype) of the C type 1770) ; 1771\end{verbatim} 1772}\end{mdframed} 1773 1774\verb'GrB_Type_new' creates a new user-defined type. The \verb'type' is a 1775handle, or a pointer to an opaque object. The handle itself must not be 1776\verb'NULL' on input, but the content of the handle can be undefined. On 1777output, the handle contains a pointer to a newly created type. 1778The \verb'ctype' is the type in C that will be used to construct the new 1779GraphBLAS type. It can be either a built-in C type, or defined by a 1780\verb'typedef'. 1781The second parameter should be passed as \verb'sizeof(ctype)'. The only 1782requirement on the C type is that \verb'sizeof(ctype)' is valid in C, and 1783that the type reside in a contiguous block of memory so that it can be moved 1784with \verb'memcpy'. For example, to create a user-defined type called 1785\verb'Complex' for double-precision complex values using the ANSI C11 1786\verb'double complex' type, the following can be used. A complete example can 1787be found in the \verb'usercomplex.c' and \verb'usercomplex.h' files in the 1788\verb'Demo' folder. 1789 1790 {\footnotesize 1791 \begin{verbatim} 1792 #include <math.h> 1793 #include <complex.h> 1794 GrB_Type Complex ; 1795 GrB_Type_new (&Complex, sizeof (double complex)) ; \end{verbatim} } 1796 1797To demonstrate the flexibility of the \verb'GrB_Type', consider a ``scalar'' 1798consisting of 4-by-4 floating-point matrix and a string. This type might be 1799useful for the 4-by-4 translation/rotation/scaling matrices that arise in 1800computer graphics, along with a string containing a description or even a 1801regular expression that can be parsed and executed in a user-defined operator. 1802All that is required is a fixed-size type, where \verb'sizeof(ctype)' is 1803a constant. 1804 1805 {\footnotesize 1806 \begin{verbatim} 1807 typedef struct 1808 { 1809 float stuff [4][4] ; 1810 char whatstuff [64] ; 1811 } 1812 wildtype ; 1813 GrB_Type WildType ; 1814 GrB_Type_new (&WildType, sizeof (wildtype)) ; \end{verbatim} } 1815 1816With this type a sparse matrix can be created in which each entry consists of a 18174-by-4 dense matrix \verb'stuff' and a 64-character string \verb'whatstuff'. 1818GraphBLAS treats this 4-by-4 as a ``scalar.'' Any GraphBLAS method or operation 1819that simply moves data can be used with this type without any further 1820information from the user application. For example, entries of this type can 1821be assigned to and extracted from a matrix or vector, and matrices containing 1822this type can be transposed. A working example (\verb'wildtype.c' 1823in the \verb'Demo' folder) creates matrices and multiplies them with 1824a user-defined semiring with this type. 1825 1826Performing arithmetic on matrices and vectors with user-defined types requires 1827operators to be defined. Refer to Section~\ref{user} for more details on these 1828example user-defined types. 1829 1830%------------------------------------------------------------------------------- 1831\subsubsection{{\sf GrB\_Type\_wait:} wait for a type} 1832%------------------------------------------------------------------------------- 1833 1834\begin{mdframed}[userdefinedwidth=6in] 1835{\footnotesize 1836\begin{verbatim} 1837GrB_Info GrB_wait // wait for a user-defined type 1838( 1839 GrB_Type *type // type to wait for 1840) ; 1841\end{verbatim} 1842}\end{mdframed} 1843 1844After creating a user-defined type, a GraphBLAS library may choose to exploit 1845non-blocking mode to delay its creation. \verb'GrB_Type_wait(&type)' ensures 1846the \verb'type' is completed. SuiteSparse:GraphBLAS currently does nothing for 1847\verb'GrB_Type_wait(&type)', except to ensure that \verb'type' is valid. 1848 1849%------------------------------------------------------------------------------- 1850\subsubsection{{\sf GxB\_Type\_size:} return the size of a type} 1851%------------------------------------------------------------------------------- 1852 1853\begin{mdframed}[userdefinedwidth=6in] 1854{\footnotesize 1855\begin{verbatim} 1856GrB_Info GxB_Type_size // determine the size of the type 1857( 1858 size_t *size, // the sizeof the type 1859 GrB_Type type // type to determine the sizeof 1860) ; 1861\end{verbatim} 1862}\end{mdframed} 1863 1864This function acts just like \verb'sizeof(type)' in the C language. For 1865example \verb'GxB_Type_size (&s, GrB_INT32)' sets \verb's' to 4, the same as 1866\verb'sizeof(int32_t)'. 1867 1868\newpage 1869%------------------------------------------------------------------------------- 1870\subsubsection{{\sf GrB\_Type\_free:} free a user-defined type} 1871%------------------------------------------------------------------------------- 1872\label{type_free} 1873 1874\begin{mdframed}[userdefinedwidth=6in] 1875{\footnotesize 1876\begin{verbatim} 1877GrB_Info GrB_free // free a user-defined type 1878( 1879 GrB_Type *type // handle of user-defined type to free 1880) ; 1881\end{verbatim} 1882}\end{mdframed} 1883 1884\verb'GrB_Type_free' frees a user-defined type. 1885Either usage: 1886 1887 {\small 1888 \begin{verbatim} 1889 GrB_Type_free (&type) ; 1890 GrB_free (&type) ; \end{verbatim}} 1891 1892\noindent 1893frees the user-defined \verb'type' and 1894sets \verb'type' to \verb'NULL'. 1895It safely does nothing if passed a \verb'NULL' 1896handle, or if \verb'type == NULL' on input. 1897 1898It is safe to attempt to free a built-in type. SuiteSparse:GraphBLAS silently 1899ignores the request and returns \verb'GrB_SUCCESS'. A user-defined type should 1900not be freed until all operations using the type are completed. 1901SuiteSparse:GraphBLAS attempts to detect this condition but it must query a 1902freed object in its attempt. This is hazardous and not recommended. 1903Operations on such objects whose type has been freed leads to undefined 1904behavior. 1905 1906It is safe to first free a type, and then a matrix of that type, but after the 1907type is freed the matrix can no longer be used. The only safe thing that can 1908be done with such a matrix is to free it. 1909 1910The function signature of \verb'GrB_Type_free' uses the generic name 1911\verb'GrB_free', which can free any GraphBLAS object. See Section~\ref{free} 1912details. GraphBLAS includes many such generic functions. When describing a 1913specific variation, a function is described with its specific name in this User 1914Guide (such as \verb'GrB_Type_free'). When discussing features applicable to 1915all specific forms, the generic name is used instead (such as \verb'GrB_free'). 1916 1917\newpage 1918%=============================================================================== 1919\subsection{GraphBLAS unary operators: {\sf GrB\_UnaryOp}, $z=f(x)$} %========== 1920%=============================================================================== 1921\label{unaryop} 1922 1923A unary operator is a scalar function of the form $z=f(x)$. The domain (type) 1924of $z$ and $x$ need not be the same. 1925 1926In the notation in the tables 1927below, $T$ is any of the 13 built-in types and is a place-holder for 1928\verb'BOOL', \verb'INT8', \verb'UINT8', ... 1929\verb'FP32', \verb'FP64', \verb'FC32', or \verb'FC64'. 1930For example, \verb'GrB_AINV_INT32' is a unary operator that computes 1931\verb'z=-x' for two values \verb'x' and \verb'z' of type \verb'GrB_INT32'. 1932 1933The notation $R$ refers to any real type (all but \verb'FC32' and \verb'FC64'), 1934$I$ refers to any integer type (\verb'INT*' and \verb'UINT*'), 1935$F$ refers to any real or complex floating point type 1936(\verb'FP32', \verb'FP64', \verb'FC32', or \verb'FC64'), 1937and $Z$ refers to any complex floating point type 1938(\verb'FC32' or \verb'FC64'). 1939 1940The logical negation operator \verb'GrB_LNOT' only works on Boolean types. The 1941\verb'GxB_LNOT_'$R$ functions operate on inputs of type $R$, implicitly 1942typecasting their input to Boolean and returning result of type $R$, with a 1943value 1 for true and 0 for false. The operators \verb'GxB_LNOT_BOOL' and 1944\verb'GrB_LNOT' are identical. 1945 1946\vspace{0.2in} 1947{\footnotesize 1948\begin{tabular}{|llll|} 1949\hline 1950\multicolumn{4}{|c|}{Unary operators for all types} \\ 1951\hline 1952GraphBLAS name & types (domains) & $z=f(x)$ & description \\ 1953\hline 1954\verb'GxB_ONE_'$T$ & $T \rightarrow T$ & $z = 1$ & one \\ 1955\verb'GrB_IDENTITY_'$T$ & $T \rightarrow T$ & $z = x$ & identity \\ 1956\verb'GrB_AINV_'$T$ & $T \rightarrow T$ & $z = -x$ & additive inverse \\ 1957\verb'GrB_MINV_'$T$ & $T \rightarrow T$ & $z = 1/x$ & multiplicative inverse \\ 1958\hline 1959\end{tabular} 1960 1961\vspace{0.2in} 1962\begin{tabular}{|llll|} 1963\hline 1964\multicolumn{4}{|c|}{Unary operators for real and integer types} \\ 1965\hline 1966GraphBLAS name & types (domains) & $z=f(x)$ & description \\ 1967\hline 1968\verb'GrB_ABS_'$T$ & $R \rightarrow R$ & $z = |x|$ & absolute value \\ 1969\verb'GrB_LNOT' & \verb'bool' 1970 $\rightarrow$ 1971 \verb'bool' & $z = \lnot x$ & logical negation \\ 1972\verb'GxB_LNOT_'$R$ & $R \rightarrow R$ & $z = \lnot (x \ne 0)$ & logical negation \\ 1973\verb'GrB_BNOT_'$I$ & $I \rightarrow I$ & $z = \lnot x$ & bitwise negation \\ 1974\hline 1975\end{tabular} 1976 1977\vspace{0.2in} 1978\begin{tabular}{|llll|} 1979\hline 1980\multicolumn{4}{|c|}{Positional unary operators for any type (including user-defined)} \\ 1981\hline 1982GraphBLAS name & types (domains) & $z=f(a_{ij})$ & description \\ 1983\hline 1984\verb'GxB_POSITIONI_'$T$ & $ \rightarrow T$ & $z = i$ & row index (0-based) \\ 1985\verb'GxB_POSITIONI1_'$T$ & $ \rightarrow T$ & $z = i+1$ & row index (1-based) \\ 1986\verb'GxB_POSITIONJ_'$T$ & $ \rightarrow T$ & $z = j$ & column index (0-based) \\ 1987\verb'GxB_POSITIONJ1_'$T$ & $ \rightarrow T$ & $z = j+1$ & column index (1-based) \\ 1988\hline 1989\end{tabular} 1990\vspace{0.2in} 1991 1992\begin{tabular}{|llll|} 1993\hline 1994\multicolumn{4}{|c|}{Unary operators for floating-point types (real and complex)} \\ 1995\hline 1996GraphBLAS name & types (domains) & $z=f(x)$ & description \\ 1997\hline 1998\verb'GxB_SQRT_'$F$ & $F \rightarrow F$ & $z = \sqrt(x)$ & square root \\ 1999\verb'GxB_LOG_'$F$ & $F \rightarrow F$ & $z = \log_e(x)$ & natural logarithm \\ 2000\verb'GxB_EXP_'$F$ & $F \rightarrow F$ & $z = e^x$ & natural exponent \\ 2001\hline 2002\verb'GxB_LOG10_'$F$ & $F \rightarrow F$ & $z = \log_{10}(x)$ & base-10 logarithm \\ 2003\verb'GxB_LOG2_'$F$ & $F \rightarrow F$ & $z = \log_2(x)$ & base-2 logarithm \\ 2004\verb'GxB_EXP2_'$F$ & $F \rightarrow F$ & $z = 2^x$ & base-2 exponent \\ 2005\hline 2006\verb'GxB_EXPM1_'$F$ & $F \rightarrow F$ & $z = e^x - 1$ & natural exponent - 1 \\ 2007\verb'GxB_LOG1P_'$F$ & $F \rightarrow F$ & $z = \log(x+1)$ & natural log of $x+1$ \\ 2008\hline 2009\verb'GxB_SIN_'$F$ & $F \rightarrow F$ & $z = \sin(x)$ & sine \\ 2010\verb'GxB_COS_'$F$ & $F \rightarrow F$ & $z = \cos(x)$ & cosine \\ 2011\verb'GxB_TAN_'$F$ & $F \rightarrow F$ & $z = \tan(x)$ & tangent \\ 2012\hline 2013\verb'GxB_ASIN_'$F$ & $F \rightarrow F$ & $z = \sin^{-1}(x)$ & inverse sine \\ 2014\verb'GxB_ACOS_'$F$ & $F \rightarrow F$ & $z = \cos^{-1}(x)$ & inverse cosine \\ 2015\verb'GxB_ATAN_'$F$ & $F \rightarrow F$ & $z = \tan^{-1}(x)$ & inverse tangent \\ 2016\hline 2017\verb'GxB_SINH_'$F$ & $F \rightarrow F$ & $z = \sinh(x)$ & hyperbolic sine \\ 2018\verb'GxB_COSH_'$F$ & $F \rightarrow F$ & $z = \cosh(x)$ & hyperbolic cosine \\ 2019\verb'GxB_TANH_'$F$ & $F \rightarrow F$ & $z = \tanh(x)$ & hyperbolic tangent \\ 2020\hline 2021\verb'GxB_ASINH_'$F$ & $F \rightarrow F$ & $z = \sinh^{-1}(x)$ & inverse hyperbolic sine \\ 2022\verb'GxB_ACOSH_'$F$ & $F \rightarrow F$ & $z = \cosh^{-1}(x)$ & inverse hyperbolic cosine \\ 2023\verb'GxB_ATANH_'$F$ & $F \rightarrow F$ & $z = \tanh^{-1}(x)$ & inverse hyperbolic tangent \\ 2024\hline 2025\verb'GxB_SIGNUM_'$F$ & $F \rightarrow F$ & $z = \sgn(x)$ & sign, or signum function \\ 2026\verb'GxB_CEIL_'$F$ & $F \rightarrow F$ & $z = \lceil x \rceil $ & ceiling function \\ 2027\verb'GxB_FLOOR_'$F$ & $F \rightarrow F$ & $z = \lfloor x \rfloor $ & floor function \\ 2028\verb'GxB_ROUND_'$F$ & $F \rightarrow F$ & $z = \mbox{round}(x)$ & round to nearest \\ 2029\verb'GxB_TRUNC_'$F$ & $F \rightarrow F$ & $z = \mbox{trunc}(x)$ & round towards zero \\ 2030\hline 2031\verb'GxB_LGAMMA_'$F$ & $F \rightarrow F$ & $z = \log(|\Gamma (x)|)$ & log of gamma function \\ 2032\verb'GxB_TGAMMA_'$F$ & $F \rightarrow F$ & $z = \Gamma(x)$ & gamma function \\ 2033\verb'GxB_ERF_'$F$ & $F \rightarrow F$ & $z = \erf(x)$ & error function \\ 2034\verb'GxB_ERFC_'$F$ & $F \rightarrow F$ & $z = \erfc(x)$ & complimentary error function \\ 2035\hline 2036\verb'GxB_FREXPX_'$F$ & $F \rightarrow F$ & $z = \mbox{frexpx}(x)$ & normalized fraction \\ 2037\verb'GxB_FREXPE_'$F$ & $F \rightarrow F$ & $z = \mbox{frexpe}(x)$ & normalized exponent \\ 2038\hline 2039\verb'GxB_ISINF_'$F$ & $F \rightarrow $ \verb'bool' & $z = \mbox{isinf}(x)$ & true if $\pm \infty$ \\ 2040\verb'GxB_ISNAN_'$F$ & $F \rightarrow $ \verb'bool' & $z = \mbox{isnan}(x)$ & true if \verb'NaN' \\ 2041\verb'GxB_ISFINITE_'$F$ & $F \rightarrow $ \verb'bool' & $z = \mbox{isfinite}(x)$ & true if finite \\ 2042\hline 2043\end{tabular} 2044\vspace{0.2in} 2045 2046\begin{tabular}{|llll|} 2047\hline 2048\multicolumn{4}{|c|}{Unary operators for complex types} \\ 2049\hline 2050GraphBLAS name & types (domains) & $z=f(x)$ & description \\ 2051\hline 2052\verb'GxB_CONJ_'$Z$ & $Z \rightarrow Z$ & $z = \overline{x}$ & complex conjugate \\ 2053\verb'GxB_ABS_'$Z$ & $Z \rightarrow F$ & $z = |x|$ & absolute value \\ 2054\verb'GxB_CREAL_'$Z$ & $Z \rightarrow F$ & $z = \mbox{real}(x)$ & real part \\ 2055\verb'GxB_CIMAG_'$Z$ & $Z \rightarrow F$ & $z = \mbox{imag}(x)$ & imaginary part \\ 2056\verb'GxB_CARG_'$Z$ & $Z \rightarrow F$ & $z = \mbox{carg}(x)$ & angle \\ 2057\hline 2058\end{tabular} 2059} 2060\vspace{0.2in} 2061 2062A positional unary operator return the row or column index of an entry. For a 2063matrix $z=f(a_{ij})$ returns $z = i$ or $z = j$, or +1 for 1-based indices. 2064The latter is useful in the MATLAB interface, where row and column indices are 20651-based. When applied to a vector, $j$ is always zero, and $i$ is the index in 2066the vector. Positional unary operators come in two types: \verb'INT32' and 2067\verb'INT64', which is the type of the output, $z$. The functions are agnostic 2068to the type of their inputs; they only depend on the position of the entries, 2069not their values. 2070User-defined positional operators cannot be defined by \verb'GrB_UnaryOp_new'. 2071 2072\verb'GxB_FREXPX' \verb'GxB_FREXPE' return the mantissa and exponent, 2073respectively, from the ANSI C11 \verb'frexp' function. The exponent is 2074returned as a floating-point value, not an integer. 2075 2076The operators \verb'GxB_EXPM1_FC*' and \verb'GxB_LOG1P_FC*' for complex 2077types are currently not accurate. They will be revised in a future version. 2078 2079The functions \verb'casin', \verb'casinf', \verb'casinh', and \verb'casinhf' 2080provided by Microsoft Visual Studio for computing $\sin^{-1}(x)$ and 2081$\sinh^{-1}(x)$ when $x$ is complex do not compute the correct result. Thus, 2082the unary operators \verb'GxB_ASIN_FC32', \verb'GxB_ASIN_FC64' 2083\verb'GxB_ASINH_FC32', and \verb'GxB_ASINH_FC64' do not work properly if the MS 2084Visual Studio compiler is used. These functions work properly if the gcc, icc, 2085or clang compilers are used on Linux or MacOS. 2086 2087Integer division by zero normally terminates an application, but this is 2088avoided in SuiteSparse:GraphBLAS. For details, see the binary 2089\verb'GrB_DIV_'$T$ operators. 2090 2091\begin{alert} 2092{\bf SPEC:} The definition of integer division by zero is an extension to the spec. 2093\end{alert} 2094 2095The next sections define the following methods for the \verb'GrB_UnaryOp' 2096object: 2097 2098\vspace{0.1in} 2099{\footnotesize 2100\begin{tabular}{ll} 2101\hline 2102\verb'GrB_UnaryOp_new' & create a user-defined unary operator \\ 2103\verb'GrB_UnaryOp_wait' & wait for a user-defined unary operator \\ 2104\verb'GxB_UnaryOp_ztype' & return the type of the output $z$ for $z=f(x)$\\ 2105\verb'GxB_UnaryOp_xtype' & return the type of the input $x$ for $z=f(x)$\\ 2106\verb'GrB_UnaryOp_free' & free a user-defined unary operator \\ 2107\hline 2108\end{tabular} 2109} 2110\vspace{0.1in} 2111 2112\newpage 2113%------------------------------------------------------------------------------- 2114\subsubsection{{\sf GrB\_UnaryOp\_new:} create a user-defined unary operator} 2115%------------------------------------------------------------------------------- 2116\label{unaryop_new} 2117 2118\begin{mdframed}[userdefinedwidth=6in] 2119{\footnotesize 2120\begin{verbatim} 2121GrB_Info GrB_UnaryOp_new // create a new user-defined unary operator 2122( 2123 GrB_UnaryOp *unaryop, // handle for the new unary operator 2124 void *function, // pointer to the unary function 2125 GrB_Type ztype, // type of output z 2126 GrB_Type xtype // type of input x 2127) ; 2128\end{verbatim} }\end{mdframed} 2129 2130\verb'GrB_UnaryOp_new' creates a new unary operator. The new operator is 2131returned in the \verb'unaryop' handle, which must not be \verb'NULL' on input. 2132On output, its contents contains a pointer to the new unary operator. 2133 2134The two types \verb'xtype' and \verb'ztype' are the GraphBLAS types of the 2135input $x$ and output $z$ of the user-defined function $z=f(x)$. These types 2136may be built-in types or user-defined types, in any combination. The two types 2137need not be the same, but they must be previously defined before passing them 2138to \verb'GrB_UnaryOp_new'. 2139 2140The \verb'function' argument to \verb'GrB_UnaryOp_new' is a pointer to a 2141user-defined function with the following signature: 2142 2143 {\footnotesize 2144 \begin{verbatim} 2145 void (*f) (void *z, const void *x) ; \end{verbatim} } 2146 2147When the function \verb'f' is called, the arguments \verb'z' and \verb'x' are 2148passed as \verb'(void *)' pointers, but they will be pointers to values of the 2149correct type, defined by \verb'ztype' and \verb'xtype', respectively, when the 2150operator was created. 2151 2152{\bf NOTE:} 2153The pointers may not be unique. That is, the user function may be 2154called with multiple pointers that point to the same space, such as when 2155\verb'z=f(z,y)' is to be computed by a binary operator, or \verb'z=f(z)' for a 2156unary operator. Any parameters passed to the user-callable function may be 2157aliased to each other. 2158 2159\newpage 2160%------------------------------------------------------------------------------- 2161\subsubsection{{\sf GrB\_UnaryOp\_wait:} wait for a unary operator} 2162%------------------------------------------------------------------------------- 2163 2164\begin{mdframed}[userdefinedwidth=6in] 2165{\footnotesize 2166\begin{verbatim} 2167GrB_Info GrB_wait // wait for a user-defined unary operator 2168( 2169 GrB_UnaryOp *unaryop // unary operator to wait for 2170) ; 2171\end{verbatim} 2172}\end{mdframed} 2173 2174After creating a user-defined unary operator, a GraphBLAS library may choose to 2175exploit non-blocking mode to delay its creation. 2176\verb'GrB_UnaryOp_wait(&unaryop)' ensures the \verb'op' is completed. 2177SuiteSparse:GraphBLAS currently does nothing for 2178\verb'GrB_UnaryOp_wait(&unaryop)', except to ensure that the \verb'unaryop' is 2179valid. 2180 2181%------------------------------------------------------------------------------- 2182\subsubsection{{\sf GxB\_UnaryOp\_ztype:} return the type of $z$} 2183%------------------------------------------------------------------------------- 2184\label{unaryop_ztype} 2185 2186\begin{mdframed}[userdefinedwidth=6in] 2187{\footnotesize 2188\begin{verbatim} 2189GrB_Info GxB_UnaryOp_ztype // return the type of z 2190( 2191 GrB_Type *ztype, // return type of output z 2192 GrB_UnaryOp unaryop // unary operator 2193) ; 2194\end{verbatim} 2195}\end{mdframed} 2196 2197\verb'GxB_UnaryOp_ztype' returns the \verb'ztype' of the unary operator, which 2198is the type of $z$ in the function $z=f(x)$. 2199 2200%------------------------------------------------------------------------------- 2201\subsubsection{{\sf GxB\_UnaryOp\_xtype:} return the type of $x$} 2202%------------------------------------------------------------------------------- 2203\label{unaryop_xtype} 2204 2205\begin{mdframed}[userdefinedwidth=6in] 2206{\footnotesize 2207\begin{verbatim} 2208GrB_Info GxB_UnaryOp_xtype // return the type of x 2209( 2210 GrB_Type *xtype, // return type of input x 2211 GrB_UnaryOp unaryop // unary operator 2212) ; 2213\end{verbatim} 2214}\end{mdframed} 2215 2216\verb'GxB_UnaryOp_xtype' returns the \verb'xtype' of the unary operator, which 2217is the type of $x$ in the function $z=f(x)$. 2218 2219\newpage 2220%------------------------------------------------------------------------------- 2221\subsubsection{{\sf GrB\_UnaryOp\_free:} free a user-defined unary operator} 2222%------------------------------------------------------------------------------- 2223\label{unaryop_free} 2224 2225\begin{mdframed}[userdefinedwidth=6in] 2226{\footnotesize 2227\begin{verbatim} 2228GrB_Info GrB_free // free a user-created unary operator 2229( 2230 GrB_UnaryOp *unaryop // handle of unary operator to free 2231) ; 2232\end{verbatim} 2233}\end{mdframed} 2234 2235\verb'GrB_UnaryOp_free' frees a user-defined unary operator. 2236Either usage: 2237 2238 {\small 2239 \begin{verbatim} 2240 GrB_UnaryOp_free (&unaryop) ; 2241 GrB_free (&unaryop) ; \end{verbatim}} 2242 2243\noindent 2244frees the \verb'unaryop' and sets \verb'unaryop' to \verb'NULL'. 2245It safely does nothing if passed a \verb'NULL' 2246handle, or if \verb'unaryop == NULL' on input. 2247It does nothing at all if passed a built-in unary operator. 2248 2249\newpage 2250%=============================================================================== 2251\subsection{GraphBLAS binary operators: {\sf GrB\_BinaryOp}, $z=f(x,y)$} %====== 2252%=============================================================================== 2253\label{binaryop} 2254 2255A binary operator is a scalar function of the form $z=f(x,y)$. The types of 2256$z$, $x$, and $y$ need not be the same. The built-in binary operators are 2257listed in the tables below. The notation $T$ refers to any of the 13 2258built-in types, but two of those types are SuiteSparse extensions 2259(\verb'GxB_FC32' and \verb'GxB_FC64'). For those types, the operator name 2260always starts with \verb'GxB', not \verb'GrB'). 2261 2262The six \verb'GxB_IS*' comparison operators and the \verb'GxB_*' logical 2263operators all return a result one for true and zero for false, in the same 2264domain $T$ or $R$ as their inputs. These six comparison operators are useful 2265as ``multiply'' operators for creating semirings with non-Boolean monoids. 2266 2267\vspace{0.2in} 2268{\footnotesize 2269\begin{tabular}{|llll|} 2270\hline 2271\multicolumn{4}{|c|}{Binary operators for all 13 types} \\ 2272\hline 2273GraphBLAS name & types (domains) & $z=f(x,y)$ & description \\ 2274\hline 2275% numeric TxT->T 2276\verb'GrB_FIRST_'$T$ & $T \times T \rightarrow T$ & $z = x$ & first argument \\ 2277\verb'GrB_SECOND_'$T$ & $T \times T \rightarrow T$ & $z = y$ & second argument \\ 2278\verb'GxB_ANY_'$T$ & $T \times T \rightarrow T$ & $z = x$ or $y$ & pick $x$ or $y$ arbitrarily \\ 2279\verb'GxB_PAIR_'$T$ & $T \times T \rightarrow T$ & $z = 1$ & one \\ 2280\verb'GrB_PLUS_'$T$ & $T \times T \rightarrow T$ & $z = x+y$ & addition \\ 2281\verb'GrB_MINUS_'$T$ & $T \times T \rightarrow T$ & $z = x-y$ & subtraction \\ 2282\verb'GxB_RMINUS_'$T$ & $T \times T \rightarrow T$ & $z = y-x$ & reverse subtraction \\ 2283\verb'GrB_TIMES_'$T$ & $T \times T \rightarrow T$ & $z = xy$ & multiplication \\ 2284\verb'GrB_DIV_'$T$ & $T \times T \rightarrow T$ & $z = x/y$ & division \\ 2285\verb'GxB_RDIV_'$T$ & $T \times T \rightarrow T$ & $z = y/x$ & reverse division \\ 2286\verb'GxB_POW_'$T$ & $T \times T \rightarrow T$ & $z = x^y$ & power \\ 2287\hline 2288% TxT->T comparison 2289\verb'GxB_ISEQ_'$T$ & $T \times T \rightarrow T$ & $z = (x == y)$ & equal \\ 2290\verb'GxB_ISNE_'$T$ & $T \times T \rightarrow T$ & $z = (x \ne y)$ & not equal \\ 2291\hline 2292\end{tabular} 2293} 2294\vspace{0.2in} 2295 2296The \verb'GxB_POW_*' operators for real types do not return a complex result, 2297and thus $z = f(x,y) = x^y$ is undefined if $x$ is negative and $y$ is not an 2298integer. To compute a complex result, use \verb'GxB_POW_FC32' or 2299\verb'GxB_POW_FC64'. 2300 2301Operators that require the domain to be ordered (\verb'MIN', \verb'MAX', and 2302relative comparisons less-than, greater-than, and so on) are not defined for 2303complex types. These are listed in the following table: 2304 2305\vspace{0.2in} 2306{\footnotesize 2307\begin{tabular}{|llll|} 2308\hline 2309\multicolumn{4}{|c|}{Binary operators for all non-complex types} \\ 2310\hline 2311GraphBLAS name & types (domains) & $z=f(x,y)$ & description \\ 2312\hline 2313% numeric RxR->R 2314\verb'GrB_MIN_'$R$ & $R \times R \rightarrow R$ & $z = \min(x,y)$ & minimum \\ 2315\verb'GrB_MAX_'$R$ & $R \times R \rightarrow R$ & $z = \max(x,y)$ & maximum \\ 2316\hline 2317% RxR->R comparison 2318\verb'GxB_ISGT_'$R$ & $R \times R \rightarrow R$ & $z = (x > y)$ & greater than \\ 2319\verb'GxB_ISLT_'$R$ & $R \times R \rightarrow R$ & $z = (x < y)$ & less than \\ 2320\verb'GxB_ISGE_'$R$ & $R \times R \rightarrow R$ & $z = (x \ge y)$ & greater than or equal \\ 2321\verb'GxB_ISLE_'$R$ & $R \times R \rightarrow R$ & $z = (x \le y)$ & less than or equal \\ 2322\hline 2323% RxR->R logical 2324\verb'GxB_LOR_'$R$ & $R \times R \rightarrow R$ & $z = (x \ne 0) \vee (y \ne 0) $ & logical OR \\ 2325\verb'GxB_LAND_'$R$ & $R \times R \rightarrow R$ & $z = (x \ne 0) \wedge (y \ne 0) $ & logical AND \\ 2326\verb'GxB_LXOR_'$R$ & $R \times R \rightarrow R$ & $z = (x \ne 0) \veebar (y \ne 0) $ & logical XOR \\ 2327\hline 2328\end{tabular} 2329} 2330\vspace{0.2in} 2331 2332Another set of six kinds of built-in comparison operators have the form $T 2333\times T \rightarrow $\verb'bool'. Note that when $T$ is \verb'bool', the six 2334operators give the same results as the six \verb'GxB_IS*_BOOL' operators in the 2335table above. These six comparison operators are useful as ``multiply'' 2336operators for creating semirings with Boolean monoids. 2337 2338\vspace{0.2in} 2339{\footnotesize 2340\begin{tabular}{|llll|} 2341\hline 2342\multicolumn{4}{|c|}{Binary comparison operators for all 13 types} \\ 2343\hline 2344GraphBLAS name & types (domains) & $z=f(x,y)$ & description \\ 2345\hline 2346% 6 TxT -> bool comparison 2347\verb'GrB_EQ_'$T$ & $T \times T \rightarrow $\verb'bool' & $z = (x == y)$ & equal \\ 2348\verb'GrB_NE_'$T$ & $T \times T \rightarrow $\verb'bool' & $z = (x \ne y)$ & not equal \\ 2349\hline 2350\multicolumn{4}{ }{\mbox{ }} \\ 2351\hline 2352\multicolumn{4}{|c|}{Binary comparison operators for non-complex types} \\ 2353\hline 2354GraphBLAS name & types (domains) & $z=f(x,y)$ & description \\ 2355\hline 2356\verb'GrB_GT_'$R$ & $R \times R \rightarrow $\verb'bool' & $z = (x > y)$ & greater than \\ 2357\verb'GrB_LT_'$R$ & $R \times R \rightarrow $\verb'bool' & $z = (x < y)$ & less than \\ 2358\verb'GrB_GE_'$R$ & $R \times R \rightarrow $\verb'bool' & $z = (x \ge y)$ & greater than or equal \\ 2359\verb'GrB_LE_'$R$ & $R \times R \rightarrow $\verb'bool' & $z = (x \le y)$ & less than or equal \\ 2360\hline 2361\end{tabular} 2362} 2363\vspace{0.2in} 2364 2365GraphBLAS has four built-in binary operators that operate purely in 2366the Boolean domain. The first three are identical to the \verb'GxB_L*_BOOL' 2367operators described above, just with a shorter name. The \verb'GrB_LXNOR' 2368operator is the same as \verb'GrB_EQ_BOOL'. 2369 2370\vspace{0.2in} 2371{\footnotesize 2372\begin{tabular}{|llll|} 2373\hline 2374\multicolumn{4}{|c|}{Binary operators for the boolean type only} \\ 2375\hline 2376GraphBLAS name & types (domains) & $z=f(x,y)$ & description \\ 2377\hline 2378% 3 bool x bool -> bool 2379\verb'GrB_LOR' & \verb'bool' 2380 $\times$ \verb'bool' 2381 $\rightarrow$ \verb'bool' & $z = x \vee y $ & logical OR \\ 2382\verb'GrB_LAND' & \verb'bool' 2383 $\times$ \verb'bool' 2384 $\rightarrow$ \verb'bool' & $z = x \wedge y $ & logical AND \\ 2385\verb'GrB_LXOR' & \verb'bool' 2386 $\times$ \verb'bool' 2387 $\rightarrow$ \verb'bool' & $z = x \veebar y $ & logical XOR \\ 2388\verb'GrB_LXNOR' & \verb'bool' 2389 $\times$ \verb'bool' 2390 $\rightarrow$ \verb'bool' & $z = \lnot (x \veebar y) $ & logical XNOR \\ 2391\hline 2392\end{tabular} 2393} 2394\vspace{0.2in} 2395 2396The following operators are defined for real floating-point types only (\verb'GrB_FP32' and \verb'GrB_FP64'). 2397They are identical to the ANSI C11 functions of the same name. The last one in the table constructs 2398the corresponding complex type. 2399 2400{\footnotesize 2401\begin{tabular}{|llll|} 2402\hline 2403\multicolumn{4}{|c|}{Binary operators for the real floating-point types only} \\ 2404\hline 2405GraphBLAS name & types (domains) & $z=f(x,y)$ & description \\ 2406\hline 2407\verb'GxB_ATAN2_'$F$ & $F \times F \rightarrow F$ & $z = \tan^{-1}(y/x)$ & 4-quadrant arc tangent \\ 2408\verb'GxB_HYPOT_'$F$ & $F \times F \rightarrow F$ & $z = \sqrt{x^2+y^2}$ & hypotenuse \\ 2409\verb'GxB_FMOD_'$F$ & $F \times F \rightarrow F$ & & ANSI C11 \verb'fmod' \\ 2410\verb'GxB_REMAINDER_'$F$ & $F \times F \rightarrow F$ & & ANSI C11 \verb'remainder' \\ 2411\verb'GxB_LDEXP_'$F$ & $F \times F \rightarrow F$ & & ANSI C11 \verb'ldexp' \\ 2412\verb'GxB_COPYSIGN_'$F$ & $F \times F \rightarrow F$ & & ANSI C11 \verb'copysign' \\ 2413\hline 2414\verb'GxB_CMPLX_'$F$ & $F \times F \rightarrow Z$ & $z = x + y \times i$ & complex from real \& imag \\ 2415\hline 2416\end{tabular} 2417} 2418\vspace{0.2in} 2419 2420Eight bitwise operators are predefined for signed and unsigned integers. 2421 2422\vspace{0.2in} 2423{\footnotesize 2424\begin{tabular}{|llll|} 2425\hline 2426\multicolumn{4}{|c|}{Binary operators for signed and unsigned integers} \\ 2427\hline 2428GraphBLAS name & types (domains) & $z=f(x,y)$ & description \\ 2429\hline 2430\verb'GrB_BOR_'$I$ & $I \times I \rightarrow I$ & \verb'z=x|y' & bitwise logical OR \\ 2431\verb'GrB_BAND_'$I$ & $I \times I \rightarrow I$ & \verb'z=x&y' & bitwise logical AND \\ 2432\verb'GrB_BXOR_'$I$ & $I \times I \rightarrow I$ & \verb'z=x^y' & bitwise logical XOR \\ 2433\verb'GrB_BXNOR_'$I$ & $I \times I \rightarrow I$ & \verb'z=~(x^y)' & bitwise logical XNOR \\ 2434\hline 2435\verb'GxB_BGET_'$I$ & $I \times I \rightarrow I$ & & get bit y of x \\ 2436\verb'GxB_BSET_'$I$ & $I \times I \rightarrow I$ & & set bit y of x \\ 2437\verb'GxB_BCLR_'$I$ & $I \times I \rightarrow I$ & & clear bit y of x \\ 2438\verb'GxB_BSHIFT_'$I$ & $I \times $\verb'int8'$ \rightarrow I$ & & bit shift \\ 2439\hline 2440\end{tabular} 2441} 2442\vspace{0.2in} 2443 2444There are two sets of built-in comparison operators in SuiteSparse:Graph\-BLAS, 2445but they are not redundant. They are identical except for the type (domain) of 2446their output, $z$. The \verb'GrB_EQ_'$T$ and related operators compare their 2447inputs of type $T$ and produce a Boolean result of true or false. The 2448\verb'GxB_ISEQ_'$T$ and related operators do the same comparison and produce a 2449result with same type $T$ as their input operands, returning one for true or 2450zero for false. The \verb'IS*' comparison operators are useful when combining 2451comparisons with other non-Boolean operators. For example, a \verb'PLUS-ISEQ' 2452semiring counts how many terms of the comparison are true. With this semiring, 2453matrix multiplication ${\bf C=AB}$ for two weighted undirected graphs ${\bf A}$ 2454and ${\bf B}$ computes $c_{ij}$ as the number of edges node $i$ and $j$ have in 2455common that have identical edge weights. Since the output type of the 2456``multiplier'' operator in a semiring must match the type of its monoid, the 2457Boolean \verb'EQ' cannot be combined with a non-Boolean \verb'PLUS' monoid to 2458perform this operation. 2459 2460Likewise, SuiteSparse:GraphBLAS has two sets of logical OR, AND, and XOR 2461operators. Without the \verb'_'$T$ suffix, the three operators \verb'GrB_LOR', 2462\verb'GrB_LAND', and \verb'GrB_LXOR' operate purely in the Boolean domain, 2463where all input and output types are \verb'GrB_BOOL'. The second set 2464(\verb'GxB_LOR_'$T$ \verb'GxB_LAND_'$T$ and \verb'GxB_LXOR_'$T$) provides 2465Boolean operators to all 11 real domains, implicitly typecasting their inputs from 2466type $T$ to Boolean and returning a value of type $T$ that is 1 for true or 2467zero for false. The set of \verb'GxB_L*_'$T$ operators are useful since they 2468can be combined with non-Boolean monoids in a semiring. 2469 2470\begin{alert} 2471{\bf SPEC:} The definition of integer division by zero is an extension to the spec. 2472\end{alert} 2473 2474Floating-point operations follow the IEEE 754 standard. Thus, computing $x/0$ 2475for a floating-point $x$ results in \verb'+Inf' if $x$ is positive, \verb'-Inf' 2476if $x$ is negative, and \verb'NaN' if $x$ is zero. The application is not 2477terminated. However, integer division by zero normally terminates an 2478application. SuiteSparse:GraphBLAS avoids this by adopting the same rules as 2479MATLAB, which are analogous to how the IEEE standard handles floating-point 2480division by zero. For integers, when $x$ is positive, $x/0$ is the largest 2481positive integer, for negative $x$ it is the minimum integer, and 0/0 results 2482in zero. For example, for an integer $x$ of type \verb'GrB_INT32', 1/0 is 2483$2^{31}-1$ and (-1)/0 is $-2^{31}$. Refer to Section~\ref{type} for a list of 2484integer ranges. 2485 2486Eight positional operators are predefined. They differ when used in a semiring 2487and when used in \verb'GrB_eWise*' and \verb'GrB_apply'. Positional operators 2488cannot be used in \verb'GrB_build', nor can they be used as the \verb'accum' 2489operator for any operation. 2490 2491The positional binary operators do not depend on the type or numerical value of 2492their inputs, just their position in a matrix or vector. For a vector, $j$ is 2493always 0, and $i$ is the index into the vector. There are two types $T$ 2494available: \verb'INT32' and \verb'INT64', which is the type of the output $z$. 2495User-defined positional operators cannot be defined by \verb'GrB_BinaryOp_new'. 2496 2497\vspace{0.2in} 2498{\footnotesize 2499\begin{tabular}{|llll|} 2500\hline 2501\multicolumn{4}{|c|}{Positional binary operators for any type (including user-defined)} \\ 2502\multicolumn{4}{|c|}{when used as a multiplicative operator in a semiring} \\ 2503\hline 2504GraphBLAS name & types (domains) & $z=f(a_{ik},b_{kj})$ & description \\ 2505\hline 2506\verb'GxB_FIRSTI_'$T$ & $ \rightarrow T$ & $z = i$ & row index of $a_{ik}$ (0-based) \\ 2507\verb'GxB_FIRSTI1_'$T$ & $ \rightarrow T$ & $z = i+1$ & row index of $a_{ik}$ (1-based) \\ 2508\verb'GxB_FIRSTJ_'$T$ & $ \rightarrow T$ & $z = k$ & column index of $a_{ik}$ (0-based) \\ 2509\verb'GxB_FIRSTJ1_'$T$ & $ \rightarrow T$ & $z = k+1$ & column index of $a_{ik}$ (1-based) \\ 2510\verb'GxB_SECONDI_'$T$ & $ \rightarrow T$ & $z = k$ & row index of $b_{kj}$ (0-based) \\ 2511\verb'GxB_SECONDI1_'$T$ & $ \rightarrow T$ & $z = k+1$ & row index of $b_{kj}$ (1-based) \\ 2512\verb'GxB_SECONDJ_'$T$ & $ \rightarrow T$ & $z = j$ & column index of $b_{kj}$ (0-based) \\ 2513\verb'GxB_SECONDJ1_'$T$ & $ \rightarrow T$ & $z = j+1$ & column index of $b_{kj}$ (1-based) \\ 2514\hline 2515\end{tabular} 2516} 2517 2518\vspace{0.2in} 2519{\footnotesize 2520\begin{tabular}{|llll|} 2521\hline 2522\multicolumn{4}{|c|}{Positional binary operators for any type (including user-defined)} \\ 2523\multicolumn{4}{|c|}{when used in all other methods} \\ 2524\hline 2525GraphBLAS name & types (domains) & $z=f(a_{ij},b_{ij})$ & description \\ 2526\hline 2527\verb'GxB_FIRSTI_'$T$ & $ \rightarrow T$ & $z = i$ & row index of $a_{ij}$ (0-based) \\ 2528\verb'GxB_FIRSTI1_'$T$ & $ \rightarrow T$ & $z = i+1$ & row index of $a_{ij}$ (1-based) \\ 2529\verb'GxB_FIRSTJ_'$T$ & $ \rightarrow T$ & $z = j$ & column index of $a_{ij}$ (0-based) \\ 2530\verb'GxB_FIRSTJ1_'$T$ & $ \rightarrow T$ & $z = j+1$ & column index of $a_{ij}$ (1-based) \\ 2531\verb'GxB_SECONDI_'$T$ & $ \rightarrow T$ & $z = i$ & row index of $b_{ij}$ (0-based) \\ 2532\verb'GxB_SECONDI1_'$T$ & $ \rightarrow T$ & $z = i+1$ & row index of $b_{ij}$ (1-based) \\ 2533\verb'GxB_SECONDJ_'$T$ & $ \rightarrow T$ & $z = j$ & column index of $b_{ij}$ (0-based) \\ 2534\verb'GxB_SECONDJ1_'$T$ & $ \rightarrow T$ & $z = j+1$ & column index of $b_{ij}$ (1-based) \\ 2535\hline 2536\end{tabular} 2537} 2538\vspace{0.2in} 2539 2540The next sections define the following methods for the \verb'GrB_BinaryOp' 2541object: 2542 2543\vspace{0.2in} 2544{\footnotesize 2545\begin{tabular}{ll} 2546\hline 2547\verb'GrB_BinaryOp_new' & create a user-defined binary operator \\ 2548\verb'GrB_BinaryOp_wait' & wait for a user-defined binary operator \\ 2549\verb'GxB_BinaryOp_ztype' & return the type of the output $z$ for $z=f(x,y)$\\ 2550\verb'GxB_BinaryOp_xtype' & return the type of the input $x$ for $z=f(x,y)$\\ 2551\verb'GxB_BinaryOp_ytype' & return the type of the input $y$ for $z=f(x,y)$\\ 2552\verb'GrB_BinaryOp_free' & free a user-defined binary operator \\ 2553\hline 2554\end{tabular} 2555} 2556\vspace{0.2in} 2557 2558\newpage 2559%------------------------------------------------------------------------------- 2560\subsubsection{{\sf GrB\_BinaryOp\_new:} create a user-defined binary operator} 2561%------------------------------------------------------------------------------- 2562\label{binaryop_new} 2563 2564\begin{mdframed}[userdefinedwidth=6in] 2565{\footnotesize 2566\begin{verbatim} 2567GrB_Info GrB_BinaryOp_new 2568( 2569 GrB_BinaryOp *binaryop, // handle for the new binary operator 2570 void *function, // pointer to the binary function 2571 GrB_Type ztype, // type of output z 2572 GrB_Type xtype, // type of input x 2573 GrB_Type ytype // type of input y 2574) ; 2575\end{verbatim} 2576}\end{mdframed} 2577 2578\verb'GrB_BinaryOp_new' creates a new binary operator. The new operator is 2579returned in the \verb'binaryop' handle, which must not be \verb'NULL' on input. 2580On output, its contents contains a pointer to the new binary operator. 2581 2582The three types \verb'xtype', \verb'ytype', and \verb'ztype' are the GraphBLAS 2583types of the inputs $x$ and $y$, and output $z$ of the user-defined function 2584$z=f(x,y)$. These types may be built-in types or user-defined types, in any 2585combination. The three types need not be the same, but they must be previously 2586defined before passing them to \verb'GrB_BinaryOp_new'. 2587 2588The final argument to \verb'GrB_BinaryOp_new' is a pointer to a user-defined 2589function with the following signature: 2590 2591 {\footnotesize 2592 \begin{verbatim} 2593 void (*f) (void *z, const void *x, const void *y) ; \end{verbatim} } 2594 2595When the function \verb'f' is called, the arguments \verb'z', \verb'x', and 2596\verb'y' are passed as \verb'(void *)' pointers, but they will be pointers to 2597values of the correct type, defined by \verb'ztype', \verb'xtype', and 2598\verb'ytype', respectively, when the operator was created. 2599 2600{\bf NOTE:} SuiteSparse:GraphBLAS may call the function with the pointers 2601\verb'z' and \verb'x' equal to one another, in which case \verb'z=f(z,y)' 2602should be computed. Future versions may use additional pointer aliasing. 2603 2604\newpage 2605%------------------------------------------------------------------------------- 2606\subsubsection{{\sf GrB\_BinaryOp\_wait:} wait for a binary operator} 2607%------------------------------------------------------------------------------- 2608 2609\begin{mdframed}[userdefinedwidth=6in] 2610{\footnotesize 2611\begin{verbatim} 2612GrB_Info GrB_wait // wait for a user-defined binary operator 2613( 2614 GrB_BinaryOp *binaryop // binary operator to wait for 2615) ; 2616\end{verbatim} 2617}\end{mdframed} 2618 2619After creating a user-defined binary operator, a GraphBLAS library may choose 2620to exploit non-blocking mode to delay its creation. 2621\verb'GrB_BinaryOp_wait(&binaryop)' ensures the \verb'binaryop' is completed. 2622SuiteSparse:GraphBLAS currently does nothing for 2623\verb'GrB_BinaryOp_wait(&binaryop)', except to ensure that the \verb'binaryop' 2624is valid. 2625 2626%------------------------------------------------------------------------------- 2627\subsubsection{{\sf GxB\_BinaryOp\_ztype:} return the type of $z$} 2628%------------------------------------------------------------------------------- 2629\label{binaryop_ztype} 2630 2631\begin{mdframed}[userdefinedwidth=6in] 2632{\footnotesize 2633\begin{verbatim} 2634GrB_Info GxB_BinaryOp_ztype // return the type of z 2635( 2636 GrB_Type *ztype, // return type of output z 2637 GrB_BinaryOp binaryop // binary operator to query 2638) ; 2639\end{verbatim} 2640} \end{mdframed} 2641 2642\verb'GxB_BinaryOp_ztype' 2643returns the \verb'ztype' of the binary operator, which is the 2644type of $z$ in the function $z=f(x,y)$. 2645 2646%------------------------------------------------------------------------------- 2647\subsubsection{{\sf GxB\_BinaryOp\_xtype:} return the type of $x$} 2648%------------------------------------------------------------------------------- 2649\label{binaryop_xtype} 2650 2651\begin{mdframed}[userdefinedwidth=6in] 2652{\footnotesize 2653\begin{verbatim} 2654GrB_Info GxB_BinaryOp_xtype // return the type of x 2655( 2656 GrB_Type *xtype, // return type of input x 2657 GrB_BinaryOp binaryop // binary operator to query 2658) ; 2659\end{verbatim} 2660}\end{mdframed} 2661 2662\verb'GxB_BinaryOp_xtype' 2663returns the \verb'xtype' of the binary operator, which is the 2664type of $x$ in the function $z=f(x,y)$. 2665 2666\newpage 2667%------------------------------------------------------------------------------- 2668\subsubsection{{\sf GxB\_BinaryOp\_ytype:} return the type of $y$} 2669%------------------------------------------------------------------------------- 2670\label{binaryop_ytype} 2671 2672\begin{mdframed}[userdefinedwidth=6in] 2673{\footnotesize 2674\begin{verbatim} 2675GrB_Info GxB_BinaryOp_ytype // return the type of y 2676( 2677 GrB_Type *ytype, // return type of input y 2678 GrB_BinaryOp binaryop // binary operator to query 2679) ; 2680\end{verbatim} 2681} \end{mdframed} 2682 2683\verb'GxB_BinaryOp_ytype' 2684returns the \verb'ytype' of the binary operator, which is the 2685type of $y$ in the function $z=f(x,y)$. 2686 2687%------------------------------------------------------------------------------- 2688\subsubsection{{\sf GrB\_BinaryOp\_free:} free a user-defined binary operator} 2689%------------------------------------------------------------------------------- 2690\label{binaryop_free} 2691 2692\begin{mdframed}[userdefinedwidth=6in] 2693{\footnotesize 2694\begin{verbatim} 2695GrB_Info GrB_free // free a user-created binary operator 2696( 2697 GrB_BinaryOp *binaryop // handle of binary operator to free 2698) ; 2699\end{verbatim} 2700} \end{mdframed} 2701 2702\verb'GrB_BinaryOp_free' frees a user-defined binary operator. 2703Either usage: 2704 2705 {\small 2706 \begin{verbatim} 2707 GrB_BinaryOp_free (&op) ; 2708 GrB_free (&op) ; \end{verbatim}} 2709 2710\noindent 2711frees the \verb'op' and sets \verb'op' to \verb'NULL'. 2712It safely does nothing if passed a \verb'NULL' 2713handle, or if \verb'op == NULL' on input. 2714It does nothing at all if passed a built-in binary operator. 2715 2716%------------------------------------------------------------------------------- 2717\subsubsection{{\sf ANY} and {\sf PAIR} operators} 2718%------------------------------------------------------------------------------- 2719\label{any_pair} 2720 2721SuiteSparse:GraphBLAS v3.2.0 adds two new operators, \verb'ANY' and 2722\verb'PAIR'. 2723 2724The \verb'PAIR' operator is simple to describe: just $f(x,y)=1$. It is called 2725the \verb'PAIR' operator since it returns $1$ in a semiring when a pair of 2726entries $a_{ik}$ and $b_{kj}$ is found in the matrix multiply. This operator 2727is simple yet very useful. It allows purely symbolic computations to be 2728performed on matrices of any type, without having to typecast them to Boolean 2729with all values being true. Typecasting need not be performed on the inputs to 2730the \verb'PAIR' operator, and the \verb'PAIR' operator does not have to access 2731the values of the matrix, so it is a very fast operator to use. 2732 2733The \verb'ANY' operator is very unusual, but very powerful. It is the function 2734$f_{\mbox{any}}(x,y)=x$, or $y$, where GraphBLAS has to freedom to select 2735either $x$, or $y$, at its own discretion. Do not confuse the \verb'ANY' 2736operator with the \verb'any' function in MATLAB, which computes a reduction 2737using the logical OR operator. 2738 2739The \verb'ANY' function is associative and commutative, and can thus serve as 2740an operator for a monoid. The selection of $x$ are $y$ is not randomized. 2741Instead, SuiteSparse:GraphBLAS uses this freedom to compute as fast a result as 2742possible. When used in a dot product, \[ c_{ij} = \sum_k a_{ik} b_{kj} \] for 2743example, the computation can terminate as soon as any matching pair of entries 2744is found. When used in a parallel saxpy-style computation, the \verb'ANY' 2745operator allows for a relaxed form of synchronization to be used, resulting 2746in a fast benign race condition. 2747 2748Because of this benign race condition, the result of the \verb'ANY' monoid can 2749be non-deterministic, unless it is coupled with the \verb'PAIR' multiplicative 2750operator. In this case, the \verb'ANY_PAIR' semiring will return a 2751deterministic result, since $f_{\mbox{any}}(1,1)$ is always 1. 2752 2753When paired with a different operator, the results are non-deterministic. This 2754gives a powerful method when computing results for which any value selected by 2755the \verb'ANY' operator is valid. One such example is the breadth-first-search 2756tree. Suppose node $j$ is at level $v$, and there are multiple nodes $i$ at 2757level $v-1$ for which the edge $(i,j)$ exists in the graph. Any of these nodes 2758$i$ can serve as a valid parent in the BFS tree. Using the \verb'ANY' 2759operator, GraphBLAS can quickly compute a valid BFS tree; if it used again on 2760the same inputs, it might return a different, yet still valid, BFS tree, due to 2761the non-deterministic nature of intra-thread synchronization. 2762 2763\newpage 2764%=============================================================================== 2765\subsection{SuiteSparse:GraphBLAS select operators: {\sf GxB\_SelectOp}} %====== 2766%=============================================================================== 2767\label{selectop} 2768 2769\begin{alert} 2770NOTE: the API for the select function has changed in v4.0.1 of 2771SuiteSparse:GraphBLAS. The former function signature (in v3.3.3 and earlier) 2772included the dimensions of the matrix. These are not needed since they can be 2773passed in as part of the \verb'thunk', if needed. 2774\end{alert} 2775 2776A select operator is a scalar function of the form 2777$z=f(i,j,a_{ij},\mbox{thunk})$ that is applied to the entries $a_{ij}$ of 2778an $m$-by-$n$ matrix. The domain (type) of $z$ is always boolean. The domain 2779(type) of $a_{ij}$ can be any built-in or user-defined type, or it can be 2780\verb'GrB_NULL' if the operator is type-generic. 2781 2782The \verb'GxB_SelectOp' operator is used by \verb'GxB_select' (see Section 2783\ref{select}) to select entries from a matrix. Each entry \verb'A(i,j)' is 2784evaluated with the operator, which returns true if the entry is to be kept in 2785the output, or false if it is not to appear in the output. The signature of 2786the select function \verb'f' is as follows: 2787 2788{\footnotesize 2789\begin{verbatim} 2790bool f // returns true if A(i,j) is kept 2791( 2792 const GrB_Index i, // row index of A(i,j) 2793 const GrB_Index j, // column index of A(i,j) 2794 const void *x, // value of A(i,j), or NULL if f is type-generic 2795 const void *thunk // user-defined auxiliary data 2796) ; \end{verbatim}} 2797 2798Operators can be used on any type, including user-defined types, except that 2799the comparisons \verb'GT', \verb'GE', \verb'LT', and \verb'LE' can only be used 2800with built-in types. User-defined select operators can also be created. 2801 2802\vspace{0.2in} 2803{\footnotesize 2804\begin{tabular}{lll} 2805\hline 2806GraphBLAS name & MATLAB & description \\ 2807 & analog & \\ 2808\hline 2809\verb'GxB_TRIL' & \verb'C=tril(A,k)' & true for \verb'A(i,j)' if \verb'(j-i) <= k' \\ 2810\verb'GxB_TRIU' & \verb'C=triu(A,k)' & true for \verb'A(i,j)' if \verb'(j-i) >= k' \\ 2811\verb'GxB_DIAG' & \verb'C=diag(A,k)' & true for \verb'A(i,j)' if \verb'(j-i) == k' \\ 2812\verb'GxB_OFFDIAG' & \verb'C=A-diag(A,k)' & true for \verb'A(i,j)' if \verb'(j-i) != k' \\ 2813\hline 2814\verb'GxB_NONZERO' & \verb'C=A(A~=0)' & true if \verb'A(i,j)' is nonzero\\ 2815\verb'GxB_EQ_ZERO' & \verb'C=A(A==0)' & true if \verb'A(i,j)' is zero\\ 2816\verb'GxB_GT_ZERO' & \verb'C=A(A>0)' & true if \verb'A(i,j)' is greater than zero \\ 2817\verb'GxB_GE_ZERO' & \verb'C=A(A>=0)' & true if \verb'A(i,j)' is greater than or equal to zero \\ 2818\verb'GxB_LT_ZERO' & \verb'C=A(A<0)' & true if \verb'A(i,j)' is less than zero \\ 2819\verb'GxB_LE_ZERO' & \verb'C=A(A<=0)' & true if \verb'A(i,j)' is less than or equal to zero \\ 2820\hline 2821\verb'GxB_NE_THUNK' & \verb'C=A(A~=k)' & true if \verb'A(i,j)' is not equal to \verb'k'\\ 2822\verb'GxB_EQ_THUNK' & \verb'C=A(A==k)' & true if \verb'A(i,j)' is equal to \verb'k'\\ 2823\verb'GxB_GT_THUNK' & \verb'C=A(A>k)' & true if \verb'A(i,j)' is greater than \verb'k' \\ 2824\verb'GxB_GE_THUNK' & \verb'C=A(A>=k)' & true if \verb'A(i,j)' is greater than or equal to \verb'k' \\ 2825\verb'GxB_LT_THUNK' & \verb'C=A(A<k)' & true if \verb'A(i,j)' is less than \verb'k' \\ 2826\verb'GxB_LE_THUNK' & \verb'C=A(A<=k)' & true if \verb'A(i,j)' is less than or equal to \verb'k' \\ 2827% 2828\hline 2829\end{tabular} 2830} 2831\vspace{0.2in} 2832 2833The following methods operate on the \verb'GxB_SelectOp' object: 2834 2835\vspace{0.1in} 2836{\footnotesize 2837\begin{tabular}{ll} 2838\hline 2839\verb'GxB_SelectOp_new' & create a user-defined select operator \\ 2840\verb'GxB_SelectOp_wait' & wait for a user-defined select operator \\ 2841\verb'GxB_SelectOp_xtype' & return the type of the input $x$ \\ 2842\verb'GxB_SelectOp_ttype' & return the type of the input {\em thunk} \\ 2843\verb'GxB_SelectOp_free' & free a user-defined select operator \\ 2844\hline 2845\end{tabular} 2846} 2847\vspace{0.1in} 2848 2849\newpage 2850%------------------------------------------------------------------------------- 2851\subsubsection{{\sf GxB\_SelectOp\_new:} create a user-defined select operator} 2852%------------------------------------------------------------------------------- 2853\label{selectop_new} 2854 2855\begin{mdframed}[userdefinedwidth=6in] 2856{\footnotesize 2857\begin{verbatim} 2858GrB_Info GxB_SelectOp_new // create a new user-defined select operator 2859( 2860 GxB_SelectOp *selectop, // handle for the new select operator 2861 void *function, // pointer to the select function 2862 GrB_Type xtype, // type of input x, or NULL if type-generic 2863 GrB_Type ttype // type of input thunk, or NULL if type-generic 2864) ; 2865\end{verbatim} }\end{mdframed} 2866 2867\verb'GxB_SelectOp_new' creates a new select operator. The new operator is 2868returned in the \verb'selectop' handle, which must not be \verb'NULL' on input. 2869On output, its contents contains a pointer to the new select operator. 2870 2871The \verb'function' argument to \verb'GxB_SelectOp_new' is a pointer to a 2872user-defined function whose signature is given at the beginning of 2873Section~\ref{selectop}. Given the properties of an entry $a_{ij}$ in a 2874matrix, the \verb'function' should return \verb'true' if the entry 2875should be kept in the output of \verb'GxB_select', or \verb'false' if it should 2876not appear in the output. 2877 2878The type \verb'xtype' is the GraphBLAS type of the input $x$ of the 2879user-defined function $z=f(i,j,x,\mbox{thunk})$. The type may be built-in 2880or user-defined, or it may even be \verb'GrB_NULL'. If the \verb'xtype' is 2881\verb'GrB_NULL', then the \verb'selectop' is type-generic. 2882 2883The type \verb'ttype' is the GraphBLAS type of the input {\em thunk} of the 2884user-defined function $z=f(i,j,x,\mbox{thunk})$. The type may be built-in 2885or user-defined, or it may even be \verb'GrB_NULL'. If the \verb'ttype' is 2886\verb'GrB_NULL', then the \verb'selectop' does not access this parameter. 2887The \verb'const void *thunk' parameter on input to the user \verb'function' 2888will be passed as \verb'NULL'. 2889 2890%------------------------------------------------------------------------------- 2891\subsubsection{{\sf GB\_SelectOp\_wait:} wait for a select operator} 2892%------------------------------------------------------------------------------- 2893 2894\begin{mdframed}[userdefinedwidth=6in] 2895{\footnotesize 2896\begin{verbatim} 2897GrB_Info GrB_wait // wait for a user-defined select operator 2898( 2899 GxB_SelectOp *selectop // select operator to wait for 2900) ; 2901\end{verbatim} 2902}\end{mdframed} 2903 2904After creating a user-defined select operator, a GraphBLAS library may choose 2905to exploit non-blocking mode to delay its creation. 2906\verb'GxB_SelectOp_wait(&selectop)' ensures the \verb'selectop' is completed. 2907SuiteSparse:GraphBLAS currently does nothing for 2908\verb'GxB_SelectOp_wait(&selectop)', except to ensure that the \verb'selectop' 2909is valid. 2910 2911%------------------------------------------------------------------------------- 2912\subsubsection{{\sf GxB\_SelectOp\_xtype:} return the type of $x$} 2913%------------------------------------------------------------------------------- 2914\label{selectop_xtype} 2915 2916\begin{mdframed}[userdefinedwidth=6in] 2917{\footnotesize 2918\begin{verbatim} 2919GrB_Info GxB_SelectOp_xtype // return the type of x 2920( 2921 GrB_Type *xtype, // return type of input x 2922 GxB_SelectOp selectop // select operator 2923) ; 2924 2925\end{verbatim} 2926}\end{mdframed} 2927 2928\verb'GxB_SelectOp_xtype' returns the \verb'xtype' of the select operator, 2929which is the type of $x$ in the function $z=f(i,j,x,\mbox{thunk})$. If the 2930select operator is type-generic, \verb'xtype' is returned as \verb'GrB_NULL'. 2931This is not an error condition, but simply indicates that the 2932\verb'selectop' is type-generic. 2933 2934%------------------------------------------------------------------------------- 2935\subsubsection{{\sf GxB\_SelectOp\_ttype:} return the type of the {\em thunk}} 2936%------------------------------------------------------------------------------- 2937\label{selectop_ttype} 2938 2939\begin{mdframed}[userdefinedwidth=6in] 2940{\footnotesize 2941\begin{verbatim} 2942GrB_Info GxB_SelectOp_ttype // return the type of thunk 2943( 2944 GrB_Type *ttype, // return type of input thunk 2945 GxB_SelectOp selectop // select operator 2946) ; 2947 2948\end{verbatim} 2949}\end{mdframed} 2950 2951\verb'GxB_SelectOp_ttype' returns the \verb'ttype' of the select operator, 2952which is the type of {\em thunk} in the function $z=f(i,j,x,\mbox{thunk})$. 2953If the select operator does not use this parameter, \verb'ttype' is returned as 2954\verb'GrB_NULL'. This is not an error condition, but simply indicates that the 2955\verb'selectop' does not use this parameter. 2956 2957%------------------------------------------------------------------------------- 2958\subsubsection{{\sf GxB\_SelectOp\_free:} free a user-defined select operator} 2959%------------------------------------------------------------------------------- 2960\label{selectop_free} 2961 2962\begin{mdframed}[userdefinedwidth=6in] 2963{\footnotesize 2964\begin{verbatim} 2965GrB_Info GrB_free // free a user-created select operator 2966( 2967 GxB_SelectOp *selectop // handle of select operator to free 2968) ; 2969\end{verbatim} 2970}\end{mdframed} 2971 2972\verb'GxB_SelectOp_free' frees a user-defined select operator. Either usage: 2973 2974 {\small 2975 \begin{verbatim} 2976 GxB_SelectOp_free (&selectop) ; 2977 GrB_free (&selectop) ; \end{verbatim}} 2978 2979\noindent 2980frees the \verb'selectop' and sets \verb'selectop' to \verb'NULL'. It safely 2981does nothing if passed a \verb'NULL' handle, or if \verb'selectop == NULL' on 2982input. It does nothing at all if passed a built-in select operator. 2983 2984\newpage 2985%=============================================================================== 2986\subsection{GraphBLAS monoids: {\sf GrB\_Monoid}} %============================= 2987%=============================================================================== 2988\label{monoid} 2989 2990A {\em monoid} is defined on a single domain (that is, a single type), $T$. It 2991consists of an associative binary operator $z=f(x,y)$ whose three operands $x$, 2992$y$, and $z$ are all in this same domain $T$ (that is $T \times T \rightarrow 2993T$). The associative operator must also have an identity element, or ``zero'' 2994in this domain, such that $f(x,0)=f(0,x)=x$. Recall that an associative 2995operator $f(x,y)$ is one for which the condition $f(a, f(b,c)) = f(f (a,b),c)$ 2996always holds. That is, operator can be applied in any order and the results 2997remain the same. 2998 2999Predefined binary operators that can be used to form monoids are listed in the 3000table below. Most of these are the binary operators of predefined monoids, 3001except that the bitwise monoids are predefined only for the unsigned integer 3002types, not the signed integers. 3003 3004Recall that $T$ denotes any built-in type (including boolean, integer, 3005floating point real, and complex), $R$ denotes any non-complex type, and 3006$I$ denotes any integer type. 3007 3008\vspace{0.2in} 3009\noindent 3010{\footnotesize 3011\begin{tabular}{lllll} 3012\hline 3013GraphBLAS & types (domains) & expression & identity & terminal \\ 3014operator & & $z=f(x,y)$ & & \\ 3015\hline 3016% numeric TxT->T 3017\verb'GrB_PLUS_'$T$ & $T \times T \rightarrow T$ & $z = x+y$ & 0 & none \\ 3018\verb'GrB_TIMES_'$T$ & $T \times T \rightarrow T$ & $z = xy$ & 1 & 0 or none (see note) \\ 3019\verb'GxB_ANY_'$T$ & $T \times T \rightarrow T$ & $z = x$ or $y$ & any & any \\ 3020\hline 3021\verb'GrB_MIN_'$R$ & $R \times R \rightarrow R$ & $z = \min(x,y)$ & $+\infty$ & $-\infty$ \\ 3022\verb'GrB_MAX_'$R$ & $R \times R \rightarrow R$ & $z = \max(x,y)$ & $-\infty$ & $+\infty$ \\ 3023\hline 3024% bool x bool -> bool 3025\verb'GrB_LOR' & \verb'bool' $\times$ \verb'bool' $\rightarrow$ \verb'bool' & $z = x \vee y $ & false & true \\ 3026\verb'GrB_LAND' & \verb'bool' $\times$ \verb'bool' $\rightarrow$ \verb'bool' & $z = x \wedge y $ & true & false \\ 3027\verb'GrB_LXOR' & \verb'bool' $\times$ \verb'bool' $\rightarrow$ \verb'bool' & $z = x \veebar y $ & false & none \\ 3028\verb'GrB_LXNOR' & \verb'bool' $\times$ \verb'bool' $\rightarrow$ \verb'bool' & $z =(x == y)$ & true & none \\ 3029\hline 3030% bitwise 3031\verb'GrB_BOR_'$I$ & $I$ $\times$ $I$ $\rightarrow$ $I$ & \verb'z=x|y' & all bits zero & all bits one \\ 3032\verb'GrB_BAND_'$I$ & $I$ $\times$ $I$ $\rightarrow$ $I$ & \verb'z=x&y' & all bits one & all bits zero \\ 3033\verb'GrB_BXOR_'$I$ & $I$ $\times$ $I$ $\rightarrow$ $I$ & \verb'z=x^y' & all bits zero & none \\ 3034\verb'GrB_BXNOR_'$I$ & $I$ $\times$ $I$ $\rightarrow$ $I$ & \verb'z=~(x^y)' & all bits one & none \\ 3035\hline 3036\end{tabular} 3037} 3038\vspace{0.2in} 3039 3040The above table lists the GraphBLAS operator, its type, expression, identity 3041value, and {\em terminal} value (if any). For these built-in operators, the 3042terminal values are the {\em annihilators} of the function, which is the value 3043$z$ so that $z=f(z,y)$ regardless of the value of $y$. For example 3044$\min(-\infty,y) = -\infty$ for any $y$. For integer domains, $+\infty$ and 3045$-\infty$ are the largest and smallest integer in their range. With unsigned 3046integers, the smallest value is zero, and thus \verb'GrB_MIN_UINT8' has an 3047identity of 255 and a terminal value of 0. 3048 3049When computing with a monoid, the computation can terminate early if the 3050terminal value arises. No further work is needed since the result will not 3051change. This value is called the terminal value instead of the annihilator, 3052since a user-defined operator can be created with a terminal value that is not 3053an annihilator. See Section~\ref{monoid_terminal_new} for an example. 3054 3055The \verb'GxB_ANY_*' monoid can terminate as soon as it finds any value at all. 3056 3057{\bf NOTE:} 3058The \verb'GrB_TIMES_FP*' operators do not have a terminal value of zero, since 3059they comply with the IEEE 754 standard, and \verb'0*NaN' is not zero, but 3060\verb'NaN'. Technically, their terminal value is \verb'NaN', but this value is 3061rare in practice and thus the terminal condition is not worth checking. 3062 3063% 40: (min,max,+,*) x (int8,16,32,64, uint8,16,32,64, fp32, fp64) 3064The C API Specification includes 44 predefined monoids, with the naming 3065convention \verb'GrB_op_MONOID_type'. Forty monoids are available for the four 3066operators \verb'MIN', \verb'MAX', \verb'PLUS', and \verb'TIMES', each with the 306710 non-boolean real types. Four boolean monoids are predefined: 3068\verb'GrB_LOR_MONOID_BOOL', \verb'GrB_LAND_MONOID_BOOL', 3069\verb'GrB_LXOR_MONOID_BOOL', and \verb'GrB_LXNOR_MONOID_BOOL'. 3070 3071% 13 ANY 3072% 4 complex (PLUS, TIMES) 3073% 16 bitwise 3074% 33 total 3075These all appear in SuiteSparse:GraphBLAS, which adds 33 additional predefined 3076\verb'GxB*' monoids, with the naming convention \verb'GxB_op_type_MONOID'. The 3077\verb'ANY' operator can be used for all 13 types (including complex). The 3078\verb'PLUS' and \verb'TIMES' operators are provided for both complex types, for 30794 additional complex monoids. Sixteen monoids are predefined for four bitwise 3080operators (\verb'BOR', \verb'BAND', \verb'BXOR', and \verb'BNXOR'), each with 3081four unsigned integer types (\verb'UINT8', \verb'UINT16', \verb'UINT32', and 3082\verb'UINT64'). 3083 3084The next sections define the following methods for the \verb'GrB_Monoid' 3085object: 3086 3087\vspace{0.2in} 3088{\footnotesize 3089\begin{tabular}{ll} 3090\hline 3091\verb'GrB_Monoid_new' & create a user-defined monoid \\ 3092\verb'GrB_Monoid_wait' & wait for a user-defined monoid \\ 3093\verb'GxB_Monoid_terminal_new' & create a monoid that has a terminal value\\ 3094\verb'GxB_Monoid_operator' & return the monoid operator \\ 3095\verb'GxB_Monoid_identity' & return the monoid identity value \\ 3096\verb'GxB_Monoid_terminal' & return the monoid terminal value (if any) \\ 3097\verb'GrB_Monoid_free' & free a monoid \\ 3098\hline 3099\end{tabular} 3100} 3101\vspace{0.2in} 3102 3103\newpage 3104%------------------------------------------------------------------------------- 3105\subsubsection{{\sf GrB\_Monoid\_new:} create a monoid} 3106%------------------------------------------------------------------------------- 3107\label{monoid_new} 3108 3109\begin{mdframed}[userdefinedwidth=6in] 3110{\footnotesize 3111\begin{verbatim} 3112GrB_Info GrB_Monoid_new // create a monoid 3113( 3114 GrB_Monoid *monoid, // handle of monoid to create 3115 GrB_BinaryOp op, // binary operator of the monoid 3116 <type> identity // identity value of the monoid 3117) ; 3118\end{verbatim} 3119} \end{mdframed} 3120 3121\verb'GrB_Monoid_new' creates a monoid. The operator, \verb'op', must be an 3122associative binary operator, either built-in or user-defined. 3123 3124In the definition above, \verb'<type>' is a place-holder for the specific type 3125of the monoid. For built-in types, it is the C type corresponding to the 3126built-in type (see Section~\ref{type}), such as \verb'bool', \verb'int32_t', 3127\verb'float', or \verb'double'. In this case, \verb'identity' is a 3128scalar value of the particular type, not a pointer. For 3129user-defined types, \verb'<type>' is \verb'void *', and thus \verb'identity' is 3130a not a scalar itself but a \verb'void *' pointer to a memory location 3131containing the identity value of the user-defined operator, \verb'op'. 3132 3133If \verb'op' is a built-in operator with a known identity value, then the 3134\verb'identity' parameter is ignored, and its known identity value is used 3135instead. 3136 3137%------------------------------------------------------------------------------- 3138\subsubsection{{\sf GrB\_Monoid\_wait:} wait for a monoid} 3139%------------------------------------------------------------------------------- 3140 3141\begin{mdframed}[userdefinedwidth=6in] 3142{\footnotesize 3143\begin{verbatim} 3144GrB_Info GrB_wait // wait for a user-defined monoid 3145( 3146 GrB_Monoid *monoid // monoid to wait for 3147) ; 3148\end{verbatim} 3149}\end{mdframed} 3150 3151After creating a user-defined monoid, a GraphBLAS library may choose to exploit 3152non-blocking mode to delay its creation. \verb'GrB_Monoid_wait(&monoid)' 3153ensures the \verb'monoid' is completed. SuiteSparse:GraphBLAS currently does 3154nothing for \verb'GrB_Monoid_wait(&monoid)', except to ensure that the 3155\verb'monoid' is valid. 3156 3157\newpage 3158%------------------------------------------------------------------------------- 3159\subsubsection{{\sf GxB\_Monoid\_terminal\_new:} create a monoid with terminal} 3160%------------------------------------------------------------------------------- 3161\label{monoid_terminal_new} 3162 3163\begin{mdframed}[userdefinedwidth=6in] 3164{\footnotesize 3165\begin{verbatim} 3166GrB_Info GxB_Monoid_terminal_new // create a monoid that has a terminal value 3167( 3168 GrB_Monoid *monoid, // handle of monoid to create 3169 GrB_BinaryOp op, // binary operator of the monoid 3170 <type> identity, // identity value of the monoid 3171 <type> terminal // terminal value of the monoid 3172) ; 3173\end{verbatim} 3174} \end{mdframed} 3175 3176\verb'GxB_Monoid_terminal_new' is identical to \verb'GrB_Monoid_new', except 3177that it allows for the specification of a {\em terminal value}. The 3178\verb'<type>' of the terminal value is the same as the \verb'identity' 3179parameter; see Section~\ref{monoid_new} for details. 3180 3181The terminal value of a monoid is the value $z$ for which $z=f(z,y)$ for any 3182$y$, where $z=f(x,y)$ is the binary operator of the monoid. This is also 3183called the {\em annihilator}, but the term {\em terminal value} is used here. 3184This is because all annihilators are terminal values, but a terminal value need 3185not be an annihilator, as described in the \verb'MIN' example below. 3186 3187If the terminal value is encountered during computation, the rest of the 3188computations can be skipped. This can greatly improve the performance of 3189\verb'GrB_reduce', and matrix multiply in specific cases (when a dot product 3190method is used). For example, using \verb'GrB_reduce' to compute the sum of 3191all entries in a \verb'GrB_FP32' matrix with $e$ entries takes $O(e)$ time, 3192since a monoid based on \verb'GrB_PLUS_FP32' has no terminal value. By 3193contrast, a reduction using \verb'GrB_LOR' on a \verb'GrB_BOOL' matrix can take 3194as little as $O(1)$ time, if a \verb'true' value is found in the matrix very 3195early. 3196 3197Monoids based on the built-in \verb'GrB_MIN_*' and \verb'GrB_MAX_*' operators 3198(for any type), the boolean \verb'GrB_LOR', and the boolean \verb'GrB_LAND' 3199operators all have terminal values. For example, the identity value of 3200\verb'GrB_LOR' is \verb'false', and its terminal value is \verb'true'. When 3201computing a reduction of a set of boolean values to a single value, once a 3202\verb'true' is seen, the computation can exit early since the result is now 3203known. 3204 3205If \verb'op' is a built-in operator with known identity and terminal values, 3206then the \verb'identity' and \verb'terminal' parameters are ignored, and its 3207known identity and terminal values are used instead. 3208 3209There may be cases in which the user application needs to use a non-standard 3210terminal value for a built-in operator. For example, suppose the matrix has 3211type \verb'GrB_FP32', but all values in the matrix are known to be 3212non-negative. The annihilator value of \verb'MIN' is \verb'-INFINITY', but 3213this will never be seen. However, the computation could could terminate when 3214finding the value zero. This is an example of using a terminal value that is 3215not actually an annihilator, but it functions like one since the monoid will 3216operate strictly on non-negative values. In this case, a monoid created with 3217\verb'GrB_MIN_FP32' will not terminate early. To create a monoid that can 3218terminate early, create a user-defined operator that computes the same thing as 3219\verb'GrB_MIN_FP32', and then create a monoid based on this user-defined 3220operator with a terminal value of zero and an identity of \verb'+INFINITY'. 3221 3222%------------------------------------------------------------------------------- 3223\subsubsection{{\sf GxB\_Monoid\_operator:} return the monoid operator} 3224%------------------------------------------------------------------------------- 3225\label{monoid_operator} 3226 3227\begin{mdframed}[userdefinedwidth=6in] 3228{\footnotesize 3229\begin{verbatim} 3230GrB_Info GxB_Monoid_operator // return the monoid operator 3231( 3232 GrB_BinaryOp *op, // returns the binary op of the monoid 3233 GrB_Monoid monoid // monoid to query 3234) ; 3235\end{verbatim} 3236} \end{mdframed} 3237 3238\verb'GxB_Monoid_operator' returns the binary operator of the monoid. 3239 3240%------------------------------------------------------------------------------- 3241\subsubsection{{\sf GxB\_Monoid\_identity:} return the monoid identity} 3242%------------------------------------------------------------------------------- 3243 3244\begin{mdframed}[userdefinedwidth=6in] 3245{\footnotesize 3246\begin{verbatim} 3247GrB_Info GxB_Monoid_identity // return the monoid identity 3248( 3249 void *identity, // returns the identity of the monoid 3250 GrB_Monoid monoid // monoid to query 3251) ; 3252\end{verbatim} 3253} \end{mdframed} 3254 3255\verb'GxB_Monoid_identity' returns the identity value of the monoid. The 3256\verb'void *' pointer, \verb'identity', must be non-\verb'NULL' and must point 3257to a memory space of size at least equal to the size of the type of the 3258\verb'monoid'. The type size can be obtained via \verb'GxB_Monoid_operator' to 3259return the monoid additive operator, then \verb'GxB_BinaryOp_ztype' to obtain 3260the \verb'ztype', followed by \verb'GxB_Type_size' to get its size. 3261 3262\newpage 3263%------------------------------------------------------------------------------- 3264\subsubsection{{\sf GxB\_Monoid\_terminal:} return the monoid terminal value} 3265%------------------------------------------------------------------------------- 3266 3267\begin{mdframed}[userdefinedwidth=6in] 3268{\footnotesize 3269\begin{verbatim} 3270GrB_Info GxB_Monoid_terminal // return the monoid terminal 3271( 3272 bool *has_terminal, // true if the monoid has a terminal value 3273 void *terminal, // returns the terminal of the monoid 3274 GrB_Monoid monoid // monoid to query 3275) ; 3276\end{verbatim} 3277} \end{mdframed} 3278 3279\verb'GxB_Monoid_terminal' returns the terminal value of the monoid (if any). 3280The \verb'void *' pointer, \verb'terminal', must be non-\verb'NULL' and must 3281point to a memory space of size at least equal to the size of the type of the 3282\verb'monoid'. The type size can be obtained via \verb'GxB_Monoid_operator' to 3283return the monoid additive operator, then \verb'GxB_BinaryOp_ztype' to obtain 3284the \verb'ztype', followed by \verb'GxB_Type_size' to get its size. 3285 3286If the monoid has a terminal value, then \verb'has_terminal' is \verb'true', 3287and its value is returned in the \verb'terminal' parameter. If it has no 3288terminal value, then \verb'has_terminal' is \verb'false', and the 3289\verb'terminal' parameter is not modified. 3290 3291% \newpage 3292%------------------------------------------------------------------------------- 3293\subsubsection{{\sf GrB\_Monoid\_free:} free a monoid} 3294%------------------------------------------------------------------------------- 3295\label{monoid_free} 3296 3297\begin{mdframed}[userdefinedwidth=6in] 3298{\footnotesize 3299\begin{verbatim} 3300GrB_Info GrB_free // free a user-created monoid 3301( 3302 GrB_Monoid *monoid // handle of monoid to free 3303) ; 3304\end{verbatim} 3305} \end{mdframed} 3306 3307\verb'GrB_Monoid_frees' frees a monoid. Either usage: 3308 3309 {\small 3310 \begin{verbatim} 3311 GrB_Monoid_free (&monoid) ; 3312 GrB_free (&monoid) ; \end{verbatim}} 3313 3314\noindent 3315frees the \verb'monoid' and sets \verb'monoid' to \verb'NULL'. It safely does 3316nothing if passed a \verb'NULL' handle, or if \verb'monoid == NULL' on input. 3317It does nothing at all if passed a built-in monoid. 3318 3319\newpage 3320%=============================================================================== 3321\subsection{GraphBLAS semirings: {\sf GrB\_Semiring}} %========================= 3322%=============================================================================== 3323\label{semiring} 3324 3325A {\em semiring} defines all the operators required to define the 3326multiplication of two sparse matrices in GraphBLAS, ${\bf C=AB}$. The ``add'' 3327operator is a commutative and associative monoid, and the binary ``multiply'' 3328operator defines a function $z=fmult(x,y)$ where the type of $z$ matches the 3329exactly with the monoid type. SuiteSparse:GraphBLAS includes 1,473 predefined 3330built-in semirings. The next sections define the following methods for the 3331\verb'GrB_Semiring' object: 3332 3333\vspace{0.2in} 3334{\footnotesize 3335\begin{tabular}{ll} 3336\hline 3337\verb'GrB_Semiring_new' & create a user-defined semiring \\ 3338\verb'GrB_Semiring_wait' & wait for a user-defined semiring \\ 3339\verb'GxB_Semiring_add' & return the additive monoid of a semiring \\ 3340\verb'GxB_Semiring_multiply' & return the binary operator of a semiring \\ 3341\verb'GrB_Semiring_free' & free a semiring \\ 3342\hline 3343\end{tabular} 3344} 3345 3346% \newpage 3347%------------------------------------------------------------------------------- 3348\subsubsection{{\sf GrB\_Semiring\_new:} create a semiring} 3349%------------------------------------------------------------------------------- 3350\label{semiring_new} 3351 3352\begin{mdframed}[userdefinedwidth=6in] 3353{\footnotesize 3354\begin{verbatim} 3355GrB_Info GrB_Semiring_new // create a semiring 3356( 3357 GrB_Semiring *semiring, // handle of semiring to create 3358 GrB_Monoid add, // add monoid of the semiring 3359 GrB_BinaryOp multiply // multiply operator of the semiring 3360) ; 3361\end{verbatim} 3362} \end{mdframed} 3363 3364\verb'GrB_Semiring_new' creates a new semiring, with \verb'add' being the 3365additive monoid and \verb'multiply' being the binary ``multiply'' operator. In 3366addition to the standard error cases, the function returns 3367\verb'GrB_DOMAIN_MISMATCH' if the output (\verb'ztype') domain of 3368\verb'multiply' does not match the domain of the \verb'add' monoid. Using 3369built-in types and operators, 2,438 semirings can be built. This count 3370excludes redundant Boolean operators (for example \verb'GrB_TIMES_BOOL' and 3371\verb'GrB_LAND' are different operators but they are redundant since they 3372always return the same result). 3373 3374The v1.3 C API Specification for GraphBLAS includes 124 predefined semirings, 3375with names of the form \verb'GrB_add_mult_SEMIRING_type', where \verb'add' is 3376the operator of the additive monoid, \verb'mult' is the multiply operator, and 3377\verb'type' is the type of the input $x$ to the multiply operator, $f(x,y)$. 3378The name of the domain for the additive monoid does not appear in the name, 3379since it always matches the type of the output of the \verb'mult' operator. 3380 3381Twelve kinds of \verb'GrB*' semirings are available for all 10 real, non-boolean types: 3382 \verb'PLUS_TIMES', \verb'PLUS_MIN', 3383 \verb'MIN_PLUS', \verb'MIN_TIMES', \verb'MIN_FIRST', \verb'MIN_SECOND', \verb'MIN_MAX', 3384 \verb'MAX_PLUS', \verb'MAX_TIMES', \verb'MAX_FIRST', \verb'MAX_SECOND', and \verb'MAX_MIN'. 3385Four semirings are for boolean types only: 3386 \verb'LOR_LAND', \verb'LAND_LOR', \verb'LXOR_LAND', and \verb'LXNOR_LOR'. 3387 3388SuiteSparse:GraphBLAS pre-defines 1,553 semirings from built-in types and 3389operators, listed below. The naming convention is \verb'GxB_add_mult_type'. 3390The 124 \verb'GrB*' semirings are a subset of the list below, included with two 3391names: \verb'GrB*' and \verb'GxB*'. If the \verb'GrB*' name is provided, its 3392use is preferred, for portability to other GraphBLAS implementations. 3393 3394\vspace{-0.05in} 3395\begin{itemize} 3396\item 1000 semirings with a multiplier $T \times T \rightarrow T$ where $T$ is 3397 any of the 10 non-Boolean, real types, from the complete cross product of: 3398 3399 \vspace{-0.05in} 3400 \begin{itemize} 3401 \item 5 monoids (\verb'MIN', \verb'MAX', \verb'PLUS', \verb'TIMES', \verb'ANY') 3402 \item 20 multiply operators 3403 (\verb'FIRST', \verb'SECOND', \verb'PAIR', \verb'MIN', \verb'MAX', 3404 \verb'PLUS', \verb'MINUS', \verb'RMINUS', \verb'TIMES', \verb'DIV', \verb'RDIV', 3405 \verb'ISEQ', \verb'ISNE', \verb'ISGT', 3406 \verb'ISLT', \verb'ISGE', \verb'ISLE', 3407 \verb'LOR', \verb'LAND', \verb'LXOR'). 3408 \item 10 non-Boolean types, $T$ 3409 \end{itemize} 3410 3411\item 300 semirings with a comparison operator $T \times T \rightarrow$ 3412 \verb'bool', where $T$ is non-Boolean and real, from the complete cross product of: 3413 3414 \vspace{-0.05in} 3415 \begin{itemize} 3416 \item 5 Boolean monoids 3417 (\verb'LAND', \verb'LOR', \verb'LXOR', \verb'EQ', \verb'ANY') 3418 \item 6 multiply operators 3419 (\verb'EQ', \verb'NE', \verb'GT', \verb'LT', \verb'GE', \verb'LE') 3420 \item 10 non-Boolean types, $T$ 3421 \end{itemize} 3422 3423\item 55 semirings with purely Boolean types, \verb'bool' $\times$ \verb'bool' 3424 $\rightarrow$ \verb'bool', from the complete cross product of: 3425 3426 \vspace{-0.05in} 3427 \begin{itemize} 3428 \item 5 Boolean monoids 3429 (\verb'LAND', \verb'LOR', \verb'LXOR', \verb'EQ', \verb'ANY') 3430 \item 11 multiply operators 3431 (\verb'FIRST', \verb'SECOND', \verb'PAIR', \verb'LOR', \verb'LAND', \verb'LXOR', 3432 \verb'EQ', \verb'GT', \verb'LT', \verb'GE', \verb'LE') 3433 \end{itemize} 3434 3435\item 54 complex semirings, $Z \times Z \rightarrow Z$ where $Z$ is 3436 \verb'GxB_FC32' (single precision complex) or 3437 \verb'GxB_FC64' (double precision complex): 3438 3439 \vspace{-0.05in} 3440 \begin{itemize} 3441 \item 3 complex monoids (\verb'PLUS', \verb'TIMES', \verb'ANY') 3442 \item 9 complex multiply operators 3443 (\verb'FIRST', \verb'SECOND', \verb'PAIR', \verb'PLUS', \verb'MINUS', 3444 \verb'TIMES', \verb'DIV', \verb'RDIV', \verb'RMINUS') 3445 \item 2 complex types, $Z$ 3446 \end{itemize} 3447 3448\item 64 bitwise semirings, $U \times U \rightarrow U$ where $U$ is 3449 an unsigned integer. 3450 3451 \vspace{-0.05in} 3452 \begin{itemize} 3453 \item 4 bitwise monoids (\verb'BOR', \verb'BAND', \verb'BXOR', \verb'BXNOR') 3454 \item 4 bitwise multiply operators (the same list) 3455 \item 4 unsigned integer types 3456 \end{itemize} 3457 3458\item 80 positional semirings, $X \times X \rightarrow T$ where $T$ is 3459 \verb'INT32' or \verb'INT64': 3460 3461 \vspace{-0.05in} 3462 \begin{itemize} 3463 \item 5 monoids (\verb'MIN', \verb'MAX', \verb'PLUS', \verb'TIMES', \verb'ANY') 3464 \item 8 positional operators 3465 (\verb'FIRSTI', \verb'FIRSTI1', \verb'FIRSTJ', \verb'FIRSTJ1', 3466 \verb'SECONDI', \verb'SECONDI1', \verb'SECONDJ', \verb'SECONDJ1') 3467 \item 2 integer types (\verb'INT32', \verb'INT64') 3468 \end{itemize} 3469 3470\end{itemize} 3471 3472%------------------------------------------------------------------------------- 3473\subsubsection{{\sf GrB\_Semiring\_wait:} wait for a semiring} 3474%------------------------------------------------------------------------------- 3475 3476\begin{mdframed}[userdefinedwidth=6in] 3477{\footnotesize 3478\begin{verbatim} 3479GrB_Info GrB_wait // wait for a user-defined semiring 3480( 3481 GrB_Semiring *semiring // semiring to wait for 3482) ; 3483\end{verbatim} 3484}\end{mdframed} 3485 3486After creating a user-defined semiring, a GraphBLAS library may choose to 3487exploit non-blocking mode to delay its creation. 3488\verb'GrB_Semiring_wait(&semiring)' ensures the \verb'semiring' is completed. 3489SuiteSparse:GraphBLAS currently does nothing for 3490\verb'GrB_Semiring_wait(&semiring)', except to ensure that the \verb'semiring' 3491is valid. 3492 3493%------------------------------------------------------------------------------- 3494\subsubsection{{\sf GxB\_Semiring\_add:} return the additive monoid of a semiring} 3495%------------------------------------------------------------------------------- 3496\label{semiring_add} 3497 3498\begin{mdframed}[userdefinedwidth=6in] 3499{\footnotesize 3500\begin{verbatim} 3501GrB_Info GxB_Semiring_add // return the add monoid of a semiring 3502( 3503 GrB_Monoid *add, // returns add monoid of the semiring 3504 GrB_Semiring semiring // semiring to query 3505) ; 3506\end{verbatim} 3507} \end{mdframed} 3508 3509\verb'GxB_Semiring_add' returns the additive monoid of a semiring. 3510 3511\newpage 3512%------------------------------------------------------------------------------- 3513\subsubsection{{\sf GxB\_Semiring\_multiply:} return multiply operator of a semiring} 3514%------------------------------------------------------------------------------- 3515\label{semiring_multiply} 3516 3517\begin{mdframed}[userdefinedwidth=6in] 3518{\footnotesize 3519\begin{verbatim} 3520GrB_Info GxB_Semiring_multiply // return multiply operator of a semiring 3521( 3522 GrB_BinaryOp *multiply, // returns multiply operator of the semiring 3523 GrB_Semiring semiring // semiring to query 3524) ; 3525\end{verbatim} 3526} \end{mdframed} 3527 3528\verb'GxB_Semiring_multiply' returns the binary multiplicative operator of a 3529semiring. 3530 3531%------------------------------------------------------------------------------- 3532\subsubsection{{\sf GrB\_Semiring\_free:} free a semiring} 3533%------------------------------------------------------------------------------- 3534\label{semiring_free} 3535 3536\begin{mdframed}[userdefinedwidth=6in] 3537{\footnotesize 3538\begin{verbatim} 3539GrB_Info GrB_free // free a user-created semiring 3540( 3541 GrB_Semiring *semiring // handle of semiring to free 3542) ; 3543\end{verbatim} 3544} \end{mdframed} 3545 3546\verb'GrB_Semiring_free' frees a semiring. Either usage: 3547 3548 {\small 3549 \begin{verbatim} 3550 GrB_Semiring_free (&semiring) ; 3551 GrB_free (&semiring) ; \end{verbatim}} 3552 3553\noindent 3554frees the \verb'semiring' and sets \verb'semiring' to \verb'NULL'. It safely 3555does nothing if passed a \verb'NULL' handle, or if \verb'semiring == NULL' on 3556input. It does nothing at all if passed a built-in semiring. 3557 3558\newpage 3559%=============================================================================== 3560\subsection{GraphBLAS scalars: {\sf GxB\_Scalar}} %============================= 3561%=============================================================================== 3562\label{scalar} 3563 3564This section describes a set of methods that create, modify, query, 3565and destroy a SuiteSparse:GraphBLAS scalar, \verb'GxB_Scalar': 3566 3567\vspace{0.2in} 3568{\footnotesize 3569\begin{tabular}{ll} 3570\hline 3571\verb'GxB_Scalar_new' & create a scalar \\ 3572\verb'GxB_Scalar_wait' & wait for a scalar \\ 3573\verb'GxB_Scalar_dup' & copy a scalar \\ 3574\verb'GxB_Scalar_clear' & clear a scalar of its entry \\ 3575\verb'GxB_Scalar_nvals' & return the number of entries in a 3576 scalar (0 or 1) \\ 3577\verb'GxB_Scalar_type' & return the type of a scalar \\ 3578\verb'GxB_Scalar_setElement' & set the single entry of a scalar \\ 3579\verb'GxB_Scalar_extractElement' & get the single entry from a scalar \\ 3580\verb'GxB_Scalar_free' & free a scalar \\ 3581\hline 3582\end{tabular} 3583} 3584 3585%------------------------------------------------------------------------------- 3586\subsubsection{{\sf GxB\_Scalar\_new:} create a scalar} 3587%------------------------------------------------------------------------------- 3588\label{scalar_new} 3589 3590\begin{mdframed}[userdefinedwidth=6in] 3591{\footnotesize 3592\begin{verbatim} 3593GrB_Info GxB_Scalar_new // create a new GxB_Scalar with no entry 3594( 3595 GxB_Scalar *s, // handle of GxB_Scalar to create 3596 GrB_Type type // type of GxB_Scalar to create 3597) ; 3598\end{verbatim} 3599} \end{mdframed} 3600 3601\verb'GxB_Scalar_new' creates a new scalar with no 3602entry in it, of the given type. This is analogous to MATLAB statement 3603\verb's = sparse(0)', except that GraphBLAS can create scalars any 3604type. The pattern of the new scalar is empty. 3605 3606%------------------------------------------------------------------------------- 3607\subsubsection{{\sf GxB\_Scalar\_wait:} wait for a scalar} 3608%------------------------------------------------------------------------------- 3609 3610\begin{mdframed}[userdefinedwidth=6in] 3611{\footnotesize 3612\begin{verbatim} 3613GrB_Info GrB_wait // wait for a scalar 3614( 3615 GxB_Scalar *s // scalar to wait for 3616) ; 3617\end{verbatim} 3618}\end{mdframed} 3619 3620In non-blocking mode, the computations for a \verb'GxB_Scalar' may be delayed. 3621In this case, the scalar is not yet safe to use by multiple independent user 3622threads. A user application may force completion of a scalar \verb's' via 3623\verb'GxB_Scalar_wait(&s)'. After this call, different user threads may safely 3624call GraphBLAS operations that use the scalar \verb's' as an input parameter. 3625 3626\newpage 3627%------------------------------------------------------------------------------- 3628\subsubsection{{\sf GxB\_Scalar\_dup:} copy a scalar} 3629%------------------------------------------------------------------------------- 3630\label{scalar_dup} 3631 3632\begin{mdframed}[userdefinedwidth=6in] 3633{\footnotesize 3634\begin{verbatim} 3635GrB_Info GxB_Scalar_dup // make an exact copy of a GxB_Scalar 3636( 3637 GxB_Scalar *s, // handle of output GxB_Scalar to create 3638 const GxB_Scalar t // input GxB_Scalar to copy 3639) ; 3640\end{verbatim} 3641} \end{mdframed} 3642 3643\verb'GxB_Scalar_dup' makes a deep copy of a scalar, like \verb's=t' in 3644MATLAB. In GraphBLAS, it is possible, and valid, to write the following: 3645 3646 {\footnotesize 3647 \begin{verbatim} 3648 GxB_Scalar t, s ; 3649 GxB_Scalar_new (&t, GrB_FP64) ; 3650 s = t ; // s is a shallow copy of t \end{verbatim}} 3651 3652Then \verb's' and \verb't' can be used interchangeably. However, only a pointer 3653reference is made, and modifying one of them modifies both, and freeing one of 3654them leaves the other as a dangling handle that should not be used. 3655If two different scalars are needed, then this should be used instead: 3656 3657 {\footnotesize 3658 \begin{verbatim} 3659 GxB_Scalar t, s ; 3660 GxB_Scalar_new (&t, GrB_FP64) ; 3661 GxB_Scalar_dup (&s, t) ; // like s = t, but making a deep copy \end{verbatim}} 3662 3663Then \verb's' and \verb't' are two different scalars that currently have 3664the same value, but they do not depend on each other. Modifying one has no 3665effect on the other. 3666 3667%------------------------------------------------------------------------------- 3668\subsubsection{{\sf GxB\_Scalar\_clear:} clear a scalar of its entry} 3669%------------------------------------------------------------------------------- 3670\label{scalar_clear} 3671 3672\begin{mdframed}[userdefinedwidth=6in] 3673{\footnotesize 3674\begin{verbatim} 3675GrB_Info GxB_Scalar_clear // clear a GxB_Scalar of its entry 3676( // type remains unchanged. 3677 GxB_Scalar s // GxB_Scalar to clear 3678) ; 3679\end{verbatim} 3680} \end{mdframed} 3681 3682\verb'GxB_Scalar_clear' clears the entry from a scalar. The pattern of 3683\verb's' is empty, just as if it were created fresh with \verb'GxB_Scalar_new'. 3684Analogous with \verb's = sparse (0)' in MATLAB. The type of \verb's' does not 3685change. Any pending updates to the scalar are discarded. 3686 3687\newpage 3688%------------------------------------------------------------------------------- 3689\subsubsection{{\sf GxB\_Scalar\_nvals:} return the number of entries in a scalar} 3690%------------------------------------------------------------------------------- 3691\label{scalar_nvals} 3692 3693\begin{mdframed}[userdefinedwidth=6in] 3694{\footnotesize 3695\begin{verbatim} 3696GrB_Info GxB_Scalar_nvals // get the number of entries in a GxB_Scalar 3697( 3698 GrB_Index *nvals, // GxB_Scalar has nvals entries (0 or 1) 3699 const GxB_Scalar s // GxB_Scalar to query 3700) ; 3701\end{verbatim} 3702} \end{mdframed} 3703 3704\verb'GxB_Scalar_nvals' returns the number of entries in a scalar, which 3705is either 0 or 1. Roughly analogous to \verb'nvals = nnz(s)' in MATLAB, except 3706that the implicit value in GraphBLAS need not be zero and \verb'nnz' (short for 3707``number of nonzeros'') in MATLAB is better described as ``number of entries'' 3708in GraphBLAS. 3709 3710%------------------------------------------------------------------------------- 3711\subsubsection{{\sf GxB\_Scalar\_type:} return the type of a scalar} 3712%------------------------------------------------------------------------------- 3713\label{scalar_type} 3714 3715\begin{mdframed}[userdefinedwidth=6in] 3716{\footnotesize 3717\begin{verbatim} 3718GrB_Info GxB_Scalar_type // get the type of a GxB_Scalar 3719( 3720 GrB_Type *type, // returns the type of the GxB_Scalar 3721 const GxB_Scalar s // GxB_Scalar to query 3722) ; 3723\end{verbatim} 3724} \end{mdframed} 3725 3726\verb'GxB_Scalar_type' returns the type of a scalar. Analogous to 3727\verb'type = class (s)' in MATLAB. 3728 3729%------------------------------------------------------------------------------- 3730\subsubsection{{\sf GxB\_Scalar\_setElement:} set the single entry of a scalar} 3731%------------------------------------------------------------------------------- 3732\label{scalar_setElement} 3733 3734\begin{mdframed}[userdefinedwidth=6in] 3735{\footnotesize 3736\begin{verbatim} 3737GrB_Info GxB_Scalar_setElement // s = x 3738( 3739 GxB_Scalar s, // GxB_Scalar to modify 3740 <type> x // user scalar to assign to s 3741) ; 3742\end{verbatim} } \end{mdframed} 3743 3744\verb'GxB_Scalar_setElement' sets the single entry in a scalar, like 3745\verb's = sparse(x)' in MATLAB notation. For further details of this function, 3746see \verb'GxB_Matrix_setElement' in Section~\ref{matrix_setElement}. 3747If an error occurs, \verb'GrB_error(&err,s)' returns details about the error. 3748 3749\newpage 3750%------------------------------------------------------------------------------- 3751\subsubsection{{\sf GxB\_Scalar\_extractElement:} get the single entry from a scalar} 3752%------------------------------------------------------------------------------- 3753\label{scalar_extractElement} 3754 3755\begin{mdframed}[userdefinedwidth=6in] 3756{\footnotesize 3757\begin{verbatim} 3758GrB_Info GxB_Scalar_extractElement // x = s 3759( 3760 <type> *x, // user scalar extracted 3761 const GxB_Scalar s // GxB_Sclar to extract an entry from 3762) ; 3763\end{verbatim} } \end{mdframed} 3764 3765\verb'GxB_Scalar_extractElement' extracts the single entry from a sparse 3766scalar, like \verb'x = full(s)' in MATLAB. Further details of this method are 3767discussed in Section~\ref{matrix_extractElement}, which discusses 3768\verb'GrB_Matrix_extractElement'. {\bf NOTE: } if no entry is present in the 3769scalar \verb's', then \verb'x' is not modified, and the return value of 3770\verb'GxB_Scalar_extractElement' is \verb'GrB_NO_VALUE'. 3771 3772%------------------------------------------------------------------------------- 3773\subsubsection{{\sf GxB\_Scalar\_free:} free a scalar} 3774%------------------------------------------------------------------------------- 3775\label{scalar_free} 3776 3777\begin{mdframed}[userdefinedwidth=6in] 3778{\footnotesize 3779\begin{verbatim} 3780GrB_Info GrB_free // free a GxB_Scalar 3781( 3782 GxB_Scalar *s // handle of GxB_Scalar to free 3783) ; 3784\end{verbatim} 3785} \end{mdframed} 3786 3787\verb'GxB_Scalar_free' frees a scalar. Either usage: 3788 3789 {\small 3790 \begin{verbatim} 3791 GxB_Scalar_free (&s) ; 3792 GrB_free (&s) ; \end{verbatim}} 3793 3794\noindent 3795frees the scalar \verb's' and sets \verb's' to \verb'NULL'. It safely 3796does nothing if passed a \verb'NULL' handle, or if \verb's == NULL' on input. 3797Any pending updates to the scalar are abandoned. 3798 3799\newpage 3800%=============================================================================== 3801\subsection{GraphBLAS vectors: {\sf GrB\_Vector}} %============================= 3802%=============================================================================== 3803\label{vector} 3804 3805This section describes a set of methods that create, modify, query, 3806and destroy a GraphBLAS sparse vector, \verb'GrB_Vector': 3807 3808\vspace{0.2in} 3809{\footnotesize 3810\begin{tabular}{ll} 3811\hline 3812\verb'GrB_Vector_new' & create a vector \\ 3813\verb'GrB_Vector_wait' & wait for a vector \\ 3814\verb'GrB_Vector_dup' & copy a vector \\ 3815\verb'GrB_Vector_clear' & clear a vector of all entries \\ 3816\verb'GrB_Vector_size' & return the size of a vector \\ 3817\verb'GrB_Vector_nvals' & return the number of entries in a vector \\ 3818\verb'GxB_Vector_type' & return the type of a vector \\ 3819\verb'GrB_Vector_build' & build a vector from a set of tuples \\ 3820\verb'GrB_Vector_setElement' & add an entry to a vector \\ 3821\verb'GrB_Vector_extractElement' & get an entry from a vector \\ 3822\verb'GrB_Vector_removeElement' & remove an entry from a vector \\ 3823\verb'GrB_Vector_extractTuples' & get all entries from a vector \\ 3824\verb'GrB_Vector_resize' & resize a vector \\ 3825% new in v5:------------ 3826\verb'GxB_Vector_diag' & extract a diagonal from a matrix \\ 3827%----------------------- 3828\verb'GrB_Vector_free' & free a vector \\ 3829\hline 3830\hline 3831\verb'GxB_Vector_import_CSC' & import a vector in CSC format \\ 3832\verb'GxB_Vector_export_CSC' & export a vector in CSC format \\ 3833\hline 3834\verb'GxB_Vector_import_Bitmap' & import a vector in bitmap format \\ 3835\verb'GxB_Vector_export_Bitmap' & export a vector in bitmap format \\ 3836\hline 3837\verb'GxB_Vector_import_Full' & import a vector in full format \\ 3838\verb'GxB_Vector_export_Full' & export a vector in full format \\ 3839\hline 3840\end{tabular} 3841} 3842 3843\vspace{0.2in} 3844Refer to Section~\ref{import_export} for a discussion the import/export 3845methods. 3846 3847\newpage 3848%------------------------------------------------------------------------------- 3849\subsubsection{{\sf GrB\_Vector\_new:} create a vector} 3850%------------------------------------------------------------------------------- 3851\label{vector_new} 3852 3853\begin{mdframed}[userdefinedwidth=6in] 3854{\footnotesize 3855\begin{verbatim} 3856GrB_Info GrB_Vector_new // create a new vector with no entries 3857( 3858 GrB_Vector *v, // handle of vector to create 3859 GrB_Type type, // type of vector to create 3860 GrB_Index n // vector dimension is n-by-1 3861) ; 3862\end{verbatim} 3863} \end{mdframed} 3864 3865\verb'GrB_Vector_new' creates a new \verb'n'-by-\verb'1' sparse vector with no 3866entries in it, of the given type. This is analogous to MATLAB statement 3867\verb'v = sparse (n,1)', except that GraphBLAS can create sparse vectors any 3868type. The pattern of the new vector is empty. 3869 3870%------------------------------------------------------------------------------- 3871\subsubsection{{\sf GrB\_Vector\_wait:} wait for a vector} 3872%------------------------------------------------------------------------------- 3873 3874\begin{mdframed}[userdefinedwidth=6in] 3875{\footnotesize 3876\begin{verbatim} 3877GrB_Info GrB_wait // wait for a vector 3878( 3879 GrB_Vector *w // vector to wait for 3880) ; 3881\end{verbatim} 3882}\end{mdframed} 3883 3884In non-blocking mode, the computations for a \verb'GrB_Vector' may be delayed. 3885In this case, the vector is not yet safe to use by multiple independent user 3886threads. A user application may force completion of a vector \verb'w' via 3887\verb'GrB_Vector_wait(&w)'. After this call, different user threads may safely 3888call GraphBLAS operations that use the vector \verb'w' as an input parameter. 3889 3890% \newpage 3891%------------------------------------------------------------------------------- 3892\subsubsection{{\sf GrB\_Vector\_dup:} copy a vector} 3893%------------------------------------------------------------------------------- 3894\label{vector_dup} 3895 3896\begin{mdframed}[userdefinedwidth=6in] 3897{\footnotesize 3898\begin{verbatim} 3899GrB_Info GrB_Vector_dup // make an exact copy of a vector 3900( 3901 GrB_Vector *w, // handle of output vector to create 3902 const GrB_Vector u // input vector to copy 3903) ; 3904\end{verbatim} 3905} \end{mdframed} 3906 3907\verb'GrB_Vector_dup' makes a deep copy of a sparse vector, like \verb'w=u' in 3908MATLAB. In GraphBLAS, it is possible, and valid, to write the following: 3909 3910 {\footnotesize 3911 \begin{verbatim} 3912 GrB_Vector u, w ; 3913 GrB_Vector_new (&u, GrB_FP64, n) ; 3914 w = u ; // w is a shallow copy of u \end{verbatim}} 3915 3916Then \verb'w' and \verb'u' can be used interchangeably. However, only a pointer 3917reference is made, and modifying one of them modifies both, and freeing one of 3918them leaves the other as a dangling handle that should not be used. 3919If two different vectors are needed, then this should be used instead: 3920 3921 {\footnotesize 3922 \begin{verbatim} 3923 GrB_Vector u, w ; 3924 GrB_Vector_new (&u, GrB_FP64, n) ; 3925 GrB_Vector_dup (&w, u) ; // like w = u, but making a deep copy \end{verbatim}} 3926 3927Then \verb'w' and \verb'u' are two different vectors that currently have the 3928same set of values, but they do not depend on each other. Modifying one has 3929no effect on the other. 3930 3931%------------------------------------------------------------------------------- 3932\subsubsection{{\sf GrB\_Vector\_clear:} clear a vector of all entries} 3933%------------------------------------------------------------------------------- 3934\label{vector_clear} 3935 3936\begin{mdframed}[userdefinedwidth=6in] 3937{\footnotesize 3938\begin{verbatim} 3939GrB_Info GrB_Vector_clear // clear a vector of all entries; 3940( // type and dimension remain unchanged. 3941 GrB_Vector v // vector to clear 3942) ; 3943\end{verbatim} 3944} \end{mdframed} 3945 3946\verb'GrB_Vector_clear' clears all entries from a vector. All values 3947\verb'v(i)' are now equal to the implicit value, depending on what semiring 3948ring is used to perform computations on the vector. The pattern of \verb'v' is 3949empty, just as if it were created fresh with \verb'GrB_Vector_new'. Analogous 3950with \verb'v (:) = sparse(0)' in MATLAB. The type and dimension of \verb'v' do 3951not change. Any pending updates to the vector are discarded. 3952 3953%------------------------------------------------------------------------------- 3954\subsubsection{{\sf GrB\_Vector\_size:} return the size of a vector} 3955%------------------------------------------------------------------------------- 3956\label{vector_size} 3957 3958\begin{mdframed}[userdefinedwidth=6in] 3959{\footnotesize 3960\begin{verbatim} 3961GrB_Info GrB_Vector_size // get the dimension of a vector 3962( 3963 GrB_Index *n, // vector dimension is n-by-1 3964 const GrB_Vector v // vector to query 3965) ; 3966\end{verbatim} 3967} \end{mdframed} 3968 3969\verb'GrB_Vector_size' returns the size of a vector (the number of rows). 3970Analogous to \verb'n = length(v)' or \verb'n = size(v,1)' in MATLAB. 3971 3972\newpage 3973%------------------------------------------------------------------------------- 3974\subsubsection{{\sf GrB\_Vector\_nvals:} return the number of entries in a vector} 3975%------------------------------------------------------------------------------- 3976\label{vector_nvals} 3977 3978\begin{mdframed}[userdefinedwidth=6in] 3979{\footnotesize 3980\begin{verbatim} 3981GrB_Info GrB_Vector_nvals // get the number of entries in a vector 3982( 3983 GrB_Index *nvals, // vector has nvals entries 3984 const GrB_Vector v // vector to query 3985) ; 3986\end{verbatim} 3987} \end{mdframed} 3988 3989\verb'GrB_Vector_nvals' returns the number of entries in a vector. Roughly 3990analogous to \verb'nvals = nnz(v)' in MATLAB, except that the implicit value in 3991GraphBLAS need not be zero and \verb'nnz' (short for ``number of nonzeros'') in 3992MATLAB is better described as ``number of entries'' in GraphBLAS. 3993 3994% \newpage 3995%------------------------------------------------------------------------------- 3996\subsubsection{{\sf GxB\_Vector\_type:} return the type of a vector} 3997%------------------------------------------------------------------------------- 3998\label{vector_type} 3999 4000\begin{mdframed}[userdefinedwidth=6in] 4001{\footnotesize 4002\begin{verbatim} 4003GrB_Info GxB_Vector_type // get the type of a vector 4004( 4005 GrB_Type *type, // returns the type of the vector 4006 const GrB_Vector v // vector to query 4007) ; 4008\end{verbatim} 4009} \end{mdframed} 4010 4011\verb'GxB_Vector_type' returns the type of a vector. Analogous to 4012\verb'type = class (v)' in MATLAB. 4013 4014%------------------------------------------------------------------------------- 4015\subsubsection{{\sf GrB\_Vector\_build:} build a vector from a set of tuples} 4016%------------------------------------------------------------------------------- 4017\label{vector_build} 4018 4019\begin{mdframed}[userdefinedwidth=6in] 4020{\footnotesize 4021\begin{verbatim} 4022GrB_Info GrB_Vector_build // build a vector from (I,X) tuples 4023( 4024 GrB_Vector w, // vector to build 4025 const GrB_Index *I, // array of row indices of tuples 4026 const <type> *X, // array of values of tuples 4027 GrB_Index nvals, // number of tuples 4028 const GrB_BinaryOp dup // binary function to assemble duplicates 4029) ; 4030\end{verbatim} 4031} \end{mdframed} 4032 4033\verb'GrB_Vector_build' constructs a sparse vector \verb'w' from a set of 4034tuples, \verb'I' and \verb'X', each of length \verb'nvals'. The vector 4035\verb'w' must have already been initialized with \verb'GrB_Vector_new', and it 4036must have no entries in it before calling \verb'GrB_Vector_build'. 4037 4038This function is just like \verb'GrB_Matrix_build' (see 4039Section~\ref{matrix_build}), except that it builds a sparse vector instead of a 4040sparse matrix. For a description of what \verb'GrB_Vector_build' does, refer 4041to \verb'GrB_Matrix_build'. For a vector, the list of column indices \verb'J' 4042in \verb'GrB_Matrix_build' is implicitly a vector of length \verb'nvals' all 4043equal to zero. Otherwise the methods are identical. 4044 4045\begin{alert} 4046{\bf SPEC:} As an extension to the spec, results are defined even if \verb'dup' is non-associative. 4047\end{alert} 4048 4049%------------------------------------------------------------------------------- 4050\subsubsection{{\sf GrB\_Vector\_setElement:} add an entry to a vector} 4051%------------------------------------------------------------------------------- 4052\label{vector_setElement} 4053 4054\begin{mdframed}[userdefinedwidth=6in] 4055{\footnotesize 4056\begin{verbatim} 4057GrB_Info GrB_Vector_setElement // w(i) = x 4058( 4059 GrB_Vector w, // vector to modify 4060 <type> x, // scalar to assign to w(i) 4061 GrB_Index i // index 4062) ; 4063\end{verbatim} } \end{mdframed} 4064 4065\verb'GrB_Vector_setElement' sets a single entry in a vector, \verb'w(i) = x'. 4066The operation is exactly like setting a single entry in an \verb'n'-by-1 4067matrix, \verb'A(i,0) = x', where the column index for a vector is implicitly 4068\verb'j=0'. For further details of this function, see 4069\verb'GrB_Matrix_setElement' in Section~\ref{matrix_setElement}. 4070If an error occurs, \verb'GrB_error(&err,w)' returns details about the error. 4071 4072%------------------------------------------------------------------------------- 4073\subsubsection{{\sf GrB\_Vector\_extractElement:} get an entry from a vector} 4074%------------------------------------------------------------------------------- 4075\label{vector_extractElement} 4076 4077\begin{mdframed}[userdefinedwidth=6in] 4078{\footnotesize 4079\begin{verbatim} 4080GrB_Info GrB_Vector_extractElement // x = v(i) 4081( 4082 <type> *x, // scalar extracted 4083 const GrB_Vector v, // vector to extract an entry from 4084 GrB_Index i // index 4085) ; 4086\end{verbatim} } \end{mdframed} 4087 4088\verb'GrB_Vector_extractElement' extracts a single entry from a vector, 4089\verb'x = v(i)'. The method is identical to extracting a single entry 4090\verb'x = A(i,0)' from an \verb'n'-by-1 matrix, so further details of this 4091method are discussed in Section~\ref{matrix_extractElement}, which discusses 4092\verb'GrB_Matrix_extractElement'. In this case, the column index is implicitly 4093\verb'j=0'. 4094{\bf NOTE: } if no entry is present at \verb'v(i)', then 4095\verb'x' is not modified, and the return value of 4096\verb'GrB_Vector_extractElement' is \verb'GrB_NO_VALUE'. 4097 4098\newpage 4099%------------------------------------------------------------------------------- 4100\subsubsection{{\sf GrB\_Vector\_removeElement:} remove an entry from a vector} 4101%------------------------------------------------------------------------------- 4102\label{vector_removeElement} 4103 4104\begin{mdframed}[userdefinedwidth=6in] 4105{\footnotesize 4106\begin{verbatim} 4107GrB_Info GrB_Vector_removeElement 4108( 4109 GrB_Vector w, // vector to remove an entry from 4110 GrB_Index i // index 4111) ; 4112\end{verbatim} } \end{mdframed} 4113 4114\verb'GrB_Vector_removeElement' removes a single entry \verb'w(i)' from a vector. 4115If no entry is present at \verb'w(i)', then the vector is not modified. 4116If an error occurs, \verb'GrB_error(&err,w)' returns details about the error. 4117 4118%------------------------------------------------------------------------------- 4119\subsubsection{{\sf GrB\_Vector\_extractTuples:} get all entries from a vector} 4120%------------------------------------------------------------------------------- 4121\label{vector_extractTuples} 4122 4123\begin{mdframed}[userdefinedwidth=6in] 4124{\footnotesize 4125\begin{verbatim} 4126GrB_Info GrB_Vector_extractTuples // [I,~,X] = find (v) 4127( 4128 GrB_Index *I, // array for returning row indices of tuples 4129 <type> *X, // array for returning values of tuples 4130 GrB_Index *nvals, // I, X size on input; # tuples on output 4131 const GrB_Vector v // vector to extract tuples from 4132) ; 4133\end{verbatim} } \end{mdframed} 4134 4135\verb'GrB_Vector_extractTuples' extracts all tuples from a sparse vector, 4136analogous to \verb'[I,~,X] = find(v)' in MATLAB. This function is identical to 4137its \verb'GrB_Matrix_extractTuples' counterpart, except that the array of 4138column indices \verb'J' does not appear in this function. Refer to 4139Section~\ref{matrix_extractTuples} where further details of this function are 4140described. 4141 4142%------------------------------------------------------------------------------- 4143\subsubsection{{\sf GrB\_Vector\_resize:} resize a vector} 4144%------------------------------------------------------------------------------- 4145\label{vector_resize} 4146 4147\begin{mdframed}[userdefinedwidth=6in] 4148{\footnotesize 4149\begin{verbatim} 4150GrB_Info GrB_Vector_resize // change the size of a vector 4151( 4152 GrB_Vector u, // vector to modify 4153 GrB_Index nrows_new // new number of rows in vector 4154) ; 4155\end{verbatim} } \end{mdframed} 4156 4157\verb'GrB_Vector_resize' changes the size of a vector. If the dimension 4158decreases, entries that fall outside the resized vector are deleted. 4159 4160\newpage 4161%------------------------------------------------------------------------------- 4162\subsubsection{{\sf GxB\_Vector\_diag:} extract a diagonal from a matrix} 4163%------------------------------------------------------------------------------- 4164\label{vector_diag} 4165 4166\begin{mdframed}[userdefinedwidth=6in] 4167{\footnotesize 4168\begin{verbatim} 4169GrB_Info GxB_Vector_diag // extract a diagonal from a matrix 4170( 4171 GrB_Vector v, // output vector 4172 const GrB_Matrix A, // input matrix 4173 int64_t k, 4174 const GrB_Descriptor desc // unused, except threading control 4175) ; 4176\end{verbatim} } \end{mdframed} 4177 4178 4179\verb'GxB_Vector_diag' extracts a vector \verb'v' from an input matrix 4180\verb'A', which may be rectangular. If \verb'k' = 0, the main diagonal of 4181\verb'A' is extracted; \verb'k' $> 0$ denotes diagonals above the main diagonal 4182of \verb'A', and \verb'k' $< 0$ denotes diagonals below the main diagonal of 4183\verb'A'. Let \verb'A' have dimension $m$-by-$n$. If \verb'k' is in the range 41840 to $n-1$, then \verb'v' has length $\min(m,n-k)$. If \verb'k' is negative 4185and in the range -1 to $-m+1$, then \verb'v' has length $\min(m+k,n)$. If 4186\verb'k' is outside these ranges, \verb'v' has length 0 (this is not an error). 4187This function computes the same thing as the MATLAB statement 4188\verb'v=diag(A,k)' when \verb'A' is a matrix, except that 4189\verb'GxB_Vector_diag' can also do typecasting. 4190 4191The vector \verb'v' must already exist on input, and 4192\verb'GrB_Vector_size (&len,v)' must return \verb'len' = 0 if \verb'k' $\ge n$ 4193or \verb'k' $\le -m$, \verb'len' $=\min(m,n-k)$ if \verb'k' is in the range 0 4194to $n-1$, and \verb'len' $=\min(m+k,n)$ if \verb'k' is in the range -1 to 4195$-m+1$. Any existing entries in \verb'v' are discarded. The type of \verb'v' 4196is preserved, so that if the type of \verb'A' and \verb'v' differ, the entries 4197are typecasted into the type of \verb'v'. Any settings made to \verb'v' by 4198\verb'GxB_Vector_Option_set' (bitmap switch and sparsity control) are 4199unchanged. 4200 4201%------------------------------------------------------------------------------- 4202\subsubsection{{\sf GrB\_Vector\_free:} free a vector} 4203%------------------------------------------------------------------------------- 4204\label{vector_free} 4205 4206\begin{mdframed}[userdefinedwidth=6in] 4207{\footnotesize 4208\begin{verbatim} 4209GrB_Info GrB_free // free a vector 4210( 4211 GrB_Vector *v // handle of vector to free 4212) ; 4213\end{verbatim} 4214} \end{mdframed} 4215 4216\verb'GrB_Vector_free' frees a vector. Either usage: 4217 4218 {\small 4219 \begin{verbatim} 4220 GrB_Vector_free (&v) ; 4221 GrB_free (&v) ; \end{verbatim}} 4222 4223\noindent 4224frees the vector \verb'v' and sets \verb'v' to \verb'NULL'. It safely does 4225nothing if passed a \verb'NULL' handle, or if \verb'v == NULL' on input. Any 4226pending updates to the vector are abandoned. 4227 4228\newpage 4229%=============================================================================== 4230\subsection{GraphBLAS matrices: {\sf GrB\_Matrix}} %============================ 4231%=============================================================================== 4232\label{matrix} 4233 4234This section describes a set of methods that create, modify, query, 4235and destroy a GraphBLAS sparse matrix, \verb'GrB_Matrix': 4236 4237\vspace{0.2in} 4238{\footnotesize 4239\begin{tabular}{ll} 4240\hline 4241\verb'GrB_Matrix_new' & create a matrix \\ 4242\verb'GrB_Matrix_wait' & wait for a matrix \\ 4243\verb'GrB_Matrix_dup' & copy a matrix \\ 4244\verb'GrB_Matrix_clear' & clear a matrix of all entries \\ 4245\verb'GrB_Matrix_nrows' & return the number of rows of a matrix \\ 4246\verb'GrB_Matrix_ncols' & return the number of columns of a matrix \\ 4247\verb'GrB_Matrix_nvals' & return the number of entries in a matrix \\ 4248\verb'GxB_Matrix_type' & return the type of a matrix \\ 4249\verb'GrB_Matrix_build' & build a matrix from a set of tuples \\ 4250\verb'GrB_Matrix_setElement' & add an entry to a matrix \\ 4251\verb'GrB_Matrix_extractElement'& get an entry from a matrix \\ 4252\verb'GrB_Matrix_removeElement' & remove an entry from a matrix \\ 4253\verb'GrB_Matrix_extractTuples' & get all entries from a matrix \\ 4254\verb'GrB_Matrix_resize' & resize a matrix \\ 4255% new in v5:------------ 4256\verb'GxB_Matrix_concat' & concatenate many matrices into one matrix \\ 4257\verb'GxB_Matrix_split' & split one matrix into many matrices \\ 4258\verb'GxB_Matrix_diag' & construct a diagonal matrix from a vector \\ 4259%----------------------- 4260\verb'GrB_Matrix_free' & free a matrix \\ 4261\hline 4262\hline 4263\verb'GxB_Matrix_import_CSR' & import a matrix in CSR form \\ 4264\verb'GxB_Matrix_export_CSR' & export a matrix in CSR form \\ 4265\hline 4266\verb'GxB_Matrix_import_CSC' & import a matrix in CSC form \\ 4267\verb'GxB_Matrix_export_CSC' & export a matrix in CSC form \\ 4268\hline 4269\verb'GxB_Matrix_import_HyperCSR' & import a matrix in HyperCSR form \\ 4270\verb'GxB_Matrix_export_HyperCSR' & export a matrix in HyperCSR form \\ 4271\hline 4272\verb'GxB_Matrix_import_HyperCSC' & import a matrix in HyperCSC form \\ 4273\verb'GxB_Matrix_export_HyperCSC' & export a matrix in HyperCSC form \\ 4274\hline 4275\verb'GxB_Matrix_import_BitmapR' & import a matrix in BitmapR form \\ 4276\verb'GxB_Matrix_export_BitmapR' & export a matrix in BitmapR form \\ 4277\hline 4278\verb'GxB_Matrix_import_BitmapC' & import a matrix in BitmapC form \\ 4279\verb'GxB_Matrix_export_BitmapC' & export a matrix in BitmapC form \\ 4280\hline 4281\verb'GxB_Matrix_import_FullR' & import a matrix in FullR form \\ 4282\verb'GxB_Matrix_export_FullR' & export a matrix in FullR form \\ 4283\hline 4284\verb'GxB_Matrix_import_FullC' & import a matrix in FullC form \\ 4285\verb'GxB_Matrix_export_FullC' & export a matrix in FullC form \\ 4286\hline 4287\end{tabular} 4288} 4289\vspace{0.2in} 4290 4291Refer to Section~\ref{import_export} for a discussion the import/export 4292methods. 4293 4294\newpage 4295%------------------------------------------------------------------------------- 4296\subsubsection{{\sf GrB\_Matrix\_new:} create a matrix} 4297%------------------------------------------------------------------------------- 4298\label{matrix_new} 4299 4300\begin{mdframed}[userdefinedwidth=6in] 4301{\footnotesize 4302\begin{verbatim} 4303GrB_Info GrB_Matrix_new // create a new matrix with no entries 4304( 4305 GrB_Matrix *A, // handle of matrix to create 4306 GrB_Type type, // type of matrix to create 4307 GrB_Index nrows, // matrix dimension is nrows-by-ncols 4308 GrB_Index ncols 4309) ; 4310\end{verbatim} } \end{mdframed} 4311 4312\verb'GrB_Matrix_new' creates a new \verb'nrows'-by-\verb'ncols' sparse matrix 4313with no entries in it, of the given type. This is analogous to the MATLAB 4314statement \verb'A = sparse (nrows, ncols)', except that GraphBLAS can create 4315sparse matrices of any type. 4316 4317%------------------------------------------------------------------------------- 4318\subsubsection{{\sf GrB\_Matrix\_wait:} wait for a matrix} 4319%------------------------------------------------------------------------------- 4320 4321\begin{mdframed}[userdefinedwidth=6in] 4322{\footnotesize 4323\begin{verbatim} 4324GrB_Info GrB_wait // wait for a matrix 4325( 4326 GrB_Matrix *C // matrix to wait for 4327) ; 4328\end{verbatim} 4329}\end{mdframed} 4330 4331In non-blocking mode, the computations for a \verb'GrB_Matrix' may be delayed. 4332In this case, the matrix is not yet safe to use by multiple independent user 4333threads. A user application may force completion of a matrix \verb'C' via 4334\verb'GrB_Matrix_wait(&C)'. After this call, different user threads may safely 4335call GraphBLAS operations that use the matrix \verb'C' as an input parameter. 4336 4337\newpage 4338%------------------------------------------------------------------------------- 4339\subsubsection{{\sf GrB\_Matrix\_dup:} copy a matrix} 4340%------------------------------------------------------------------------------- 4341\label{matrix_dup} 4342 4343\begin{mdframed}[userdefinedwidth=6in] 4344{\footnotesize 4345\begin{verbatim} 4346GrB_Info GrB_Matrix_dup // make an exact copy of a matrix 4347( 4348 GrB_Matrix *C, // handle of output matrix to create 4349 const GrB_Matrix A // input matrix to copy 4350) ; 4351\end{verbatim} } \end{mdframed} 4352 4353\verb'GrB_Matrix_dup' makes a deep copy of a sparse matrix, like \verb'C=A' in 4354MATLAB. In GraphBLAS, it is possible, and valid, to write the following: 4355 4356 {\footnotesize 4357 \begin{verbatim} 4358 GrB_Matrix A, C ; 4359 GrB_Matrix_new (&A, GrB_FP64, n) ; 4360 C = A ; // C is a shallow copy of A \end{verbatim}} 4361 4362Then \verb'C' and \verb'A' can be used interchangeably. However, only a 4363pointer reference is made, and modifying one of them modifies both, and freeing 4364one of them leaves the other as a dangling handle that should not be used. If 4365two different matrices are needed, then this should be used instead: 4366 4367 {\footnotesize 4368 \begin{verbatim} 4369 GrB_Matrix A, C ; 4370 GrB_Matrix_new (&A, GrB_FP64, n) ; 4371 GrB_Matrix_dup (&C, A) ; // like C = A, but making a deep copy \end{verbatim}} 4372 4373Then \verb'C' and \verb'A' are two different matrices that currently have the 4374same set of values, but they do not depend on each other. Modifying one has 4375no effect on the other. 4376 4377%------------------------------------------------------------------------------- 4378\subsubsection{{\sf GrB\_Matrix\_clear:} clear a matrix of all entries} 4379%------------------------------------------------------------------------------- 4380\label{matrix_clear} 4381 4382\begin{mdframed}[userdefinedwidth=6in] 4383{\footnotesize 4384\begin{verbatim} 4385GrB_Info GrB_Matrix_clear // clear a matrix of all entries; 4386( // type and dimensions remain unchanged 4387 GrB_Matrix A // matrix to clear 4388) ; 4389\end{verbatim} } \end{mdframed} 4390 4391\verb'GrB_Matrix_clear' clears all entries from a matrix. All values 4392\verb'A(i,j)' are now equal to the implicit value, depending on what semiring 4393ring is used to perform computations on the matrix. The pattern of \verb'A' is 4394empty, just as if it were created fresh with \verb'GrB_Matrix_new'. Analogous 4395with \verb'A (:,:) = 0' in MATLAB. The type and dimensions of \verb'A' do not 4396change. Any pending updates to the matrix are discarded. 4397 4398% \newpage 4399%------------------------------------------------------------------------------- 4400\subsubsection{{\sf GrB\_Matrix\_nrows:} return the number of rows of a matrix} 4401%------------------------------------------------------------------------------- 4402\label{matrix_nrows} 4403 4404\begin{mdframed}[userdefinedwidth=6in] 4405{\footnotesize 4406\begin{verbatim} 4407GrB_Info GrB_Matrix_nrows // get the number of rows of a matrix 4408( 4409 GrB_Index *nrows, // matrix has nrows rows 4410 const GrB_Matrix A // matrix to query 4411) ; 4412\end{verbatim} } \end{mdframed} 4413 4414\verb'GrB_Matrix_nrows' returns the number of rows of a matrix 4415(\verb'nrows=size(A,1)' in MATLAB). 4416 4417% \newpage 4418%------------------------------------------------------------------------------- 4419\subsubsection{{\sf GrB\_Matrix\_ncols:} return the number of columns of a matrix} 4420%------------------------------------------------------------------------------- 4421\label{matrix_ncols} 4422 4423\begin{mdframed}[userdefinedwidth=6in] 4424{\footnotesize 4425\begin{verbatim} 4426GrB_Info GrB_Matrix_ncols // get the number of columns of a matrix 4427( 4428 GrB_Index *ncols, // matrix has ncols columns 4429 const GrB_Matrix A // matrix to query 4430) ; 4431\end{verbatim} 4432} \end{mdframed} 4433 4434\verb'GrB_Matrix_ncols' returns the number of columns of a matrix 4435(\verb'ncols=size(A,2)' in MATLAB). 4436 4437%------------------------------------------------------------------------------- 4438\subsubsection{{\sf GrB\_Matrix\_nvals:} return the number of entries in a matrix} 4439%------------------------------------------------------------------------------- 4440\label{matrix_nvals} 4441 4442\begin{mdframed}[userdefinedwidth=6in] 4443{\footnotesize 4444\begin{verbatim} 4445GrB_Info GrB_Matrix_nvals // get the number of entries in a matrix 4446( 4447 GrB_Index *nvals, // matrix has nvals entries 4448 const GrB_Matrix A // matrix to query 4449) ; 4450\end{verbatim} } \end{mdframed} 4451 4452\verb'GrB_Matrix_nvals' returns the number of entries in a matrix. Roughly 4453analogous to \verb'nvals = nnz(A)' in MATLAB, except that the implicit value in 4454GraphBLAS need not be zero and \verb'nnz' (short for ``number of nonzeros'') in 4455MATLAB is better described as ``number of entries'' in GraphBLAS. 4456 4457\newpage 4458%------------------------------------------------------------------------------- 4459\subsubsection{{\sf GxB\_Matrix\_type:} return the type of a matrix} 4460%------------------------------------------------------------------------------- 4461\label{matrix_type} 4462 4463\begin{mdframed}[userdefinedwidth=6in] 4464{\footnotesize 4465\begin{verbatim} 4466GrB_Info GxB_Matrix_type // get the type of a matrix 4467( 4468 GrB_Type *type, // returns the type of the matrix 4469 const GrB_Matrix A // matrix to query 4470) ; 4471\end{verbatim} } \end{mdframed} 4472 4473\verb'GxB_Matrix_type' returns the type of a matrix, like \verb'type=class(A)' 4474in MATLAB. 4475 4476%------------------------------------------------------------------------------- 4477\subsubsection{{\sf GrB\_Matrix\_build:} build a matrix from a set of tuples} 4478%------------------------------------------------------------------------------- 4479\label{matrix_build} 4480 4481\begin{mdframed}[userdefinedwidth=6in] 4482{\footnotesize 4483\begin{verbatim} 4484GrB_Info GrB_Matrix_build // build a matrix from (I,J,X) tuples 4485( 4486 GrB_Matrix C, // matrix to build 4487 const GrB_Index *I, // array of row indices of tuples 4488 const GrB_Index *J, // array of column indices of tuples 4489 const <type> *X, // array of values of tuples 4490 GrB_Index nvals, // number of tuples 4491 const GrB_BinaryOp dup // binary function to assemble duplicates 4492) ; 4493\end{verbatim} } \end{mdframed} 4494 4495\verb'GrB_Matrix_build' constructs a sparse matrix \verb'C' from a set of 4496tuples, \verb'I', \verb'J', and \verb'X', each of length \verb'nvals'. The 4497matrix \verb'C' must have already been initialized with \verb'GrB_Matrix_new', 4498and it must have no entries in it before calling \verb'GrB_Matrix_build'. Thus 4499the dimensions and type of \verb'C' are not changed by this function, but are 4500inherited from the prior call to \verb'GrB_Matrix_new' or 4501\verb'GrB_matrix_dup'. 4502 4503An error is returned (\verb'GrB_INDEX_OUT_OF_BOUNDS') if any row index in 4504\verb'I' is greater than or equal to the number of rows of \verb'C', or if any 4505column index in \verb'J' is greater than or equal to the number of columns of 4506\verb'C' 4507 4508Any duplicate entries with identical indices are assembled using the binary 4509\verb'dup' operator provided on input. All three types (\verb'x', \verb'y', 4510\verb'z' for \verb'z=dup(x,y)') must be identical. The types of \verb'dup', 4511\verb'C' and \verb'X' must all be compatible. See Section~\ref{typecasting} 4512regarding typecasting and compatibility. The values in \verb'X' are 4513typecasted, if needed, into the type of \verb'dup'. Duplicates are then 4514assembled into a matrix \verb'T' of the same type as \verb'dup', using 4515\verb'T(i,j) = dup (T (i,j), X (k))'. After \verb'T' is constructed, it is 4516typecasted into the result \verb'C'. That is, typecasting does not occur at 4517the same time as the assembly of duplicates. 4518 4519\begin{alert} 4520{\bf SPEC:} As an extension to the spec, results are defined even if \verb'dup' 4521is non-associative. 4522\end{alert} 4523 4524The GraphBLAS API requires \verb'dup' to be associative so 4525that entries can be assembled in any order, and states that the result is 4526undefined if \verb'dup' is not associative. However, SuiteSparse:GraphBLAS 4527guarantees a well-defined order of assembly. Entries in the tuples 4528\verb'[I,J,X]' are first sorted in increasing order of row and column index, 4529with ties broken by the position of the tuple in the \verb'[I,J,X]' list. If 4530duplicates appear, they are assembled in the order they appear in the 4531\verb'[I,J,X]' input. That is, if the same indices \verb'i' and \verb'j' 4532appear in positions \verb'k1', \verb'k2', \verb'k3', and \verb'k4' in 4533\verb'[I,J,X]', where \verb'k1 < k2 < k3 < k4', then the following operations 4534will occur in order: 4535 4536 {\footnotesize 4537 \begin{verbatim} 4538 T (i,j) = X (k1) ; 4539 T (i,j) = dup (T (i,j), X (k2)) ; 4540 T (i,j) = dup (T (i,j), X (k3)) ; 4541 T (i,j) = dup (T (i,j), X (k4)) ; \end{verbatim}} 4542 4543This is a well-defined order but the user should not depend upon it when using 4544other GraphBLAS implementations since the GraphBLAS API does not 4545require this ordering. 4546 4547However, SuiteSparse:GraphBLAS guarantees this ordering, even when it compute 4548the result in parallel. With this well-defined order, several operators become 4549very useful. In particular, the \verb'SECOND' operator results in the last 4550tuple overwriting the earlier ones. The \verb'FIRST' operator means the value 4551of the first tuple is used and the others are discarded. 4552 4553The acronym \verb'dup' is used here for the name of binary function used for 4554assembling duplicates, but this should not be confused with the \verb'_dup' 4555suffix in the name of the function \verb'GrB_Matrix_dup'. The latter function 4556does not apply any operator at all, nor any typecasting, but simply makes a 4557pure deep copy of a matrix. 4558 4559The parameter \verb'X' is a pointer to any C equivalent built-in type, or a 4560\verb'void *' pointer. The \verb'GrB_Matrix_build' function uses the 4561\verb'_Generic' feature of ANSI C11 to detect the type of pointer passed as the 4562parameter \verb'X'. If \verb'X' is a pointer to a built-in type, then the 4563function can do the right typecasting. If \verb'X' is a \verb'void *' pointer, 4564then it can only assume \verb'X' to be a pointer to a user-defined type that is 4565the same user-defined type of \verb'C' and \verb'dup'. This function has no 4566way of checking this condition that the \verb'void * X' pointer points to an 4567array of the correct user-defined type, so behavior is undefined if the user 4568breaks this condition. 4569 4570The \verb'GrB_Matrix_build' method is analogous to \verb'C = sparse (I,J,X)' in 4571MATLAB, with several important extensions that go beyond that which MATLAB can 4572do. In particular, the MATLAB \verb'sparse' function only provides one option 4573for assembling duplicates (summation), and it can only build double, double 4574complex, and logical sparse matrices. 4575 4576%------------------------------------------------------------------------------- 4577\subsubsection{{\sf GrB\_Matrix\_setElement:} add an entry to a matrix} 4578%------------------------------------------------------------------------------- 4579\label{matrix_setElement} 4580 4581\begin{mdframed}[userdefinedwidth=6in] 4582{\footnotesize 4583\begin{verbatim} 4584GrB_Info GrB_Matrix_setElement // C (i,j) = x 4585( 4586 GrB_Matrix C, // matrix to modify 4587 <type> x, // scalar to assign to C(i,j) 4588 GrB_Index i, // row index 4589 GrB_Index j // column index 4590) ; 4591\end{verbatim} } \end{mdframed} 4592 4593\verb'GrB_Matrix_setElement' sets a single entry in a matrix, \verb'C(i,j)=x'. 4594If the entry is already present in the pattern of \verb'C', it is overwritten 4595with the new value. If the entry is not present, it is added to \verb'C'. In 4596either case, no entry is ever deleted by this function. Passing in a value of 4597\verb'x=0' simply creates an explicit entry at position \verb'(i,j)' whose 4598value is zero, even if the implicit value is assumed to be zero. 4599 4600An error is returned (\verb'GrB_INVALID_INDEX') if the row index \verb'i' is 4601greater than or equal to the number of rows of \verb'C', or if the column index 4602\verb'j' is greater than or equal to the number of columns of \verb'C'. Note 4603that this error code differs from the same kind of condition in 4604\verb'GrB_Matrix_build', which returns \verb'GrB_INDEX_OUT_OF_BOUNDS'. This is 4605because \verb'GrB_INVALID_INDEX' is an API error, and is caught immediately 4606even in non-blocking mode, whereas \verb'GrB_INDEX_OUT_OF_BOUNDS' is an 4607execution error whose detection may wait until the computation completes 4608sometime later. 4609 4610The scalar \verb'x' is typecasted into the type of \verb'C'. Any value can be 4611passed to this function and its type will be detected, via the \verb'_Generic' 4612feature of ANSI C11. For a user-defined type, \verb'x' is a \verb'void *' 4613pointer that points to a memory space holding a single entry of this 4614user-defined type. This user-defined type must exactly match the user-defined 4615type of \verb'C' since no typecasting is done between user-defined types. 4616 4617\paragraph{\bf Performance considerations:} % BLOCKING: setElement, *assign 4618SuiteSparse:GraphBLAS exploits the non-blocking mode to greatly improve the 4619performance of this method. Refer to the example shown in 4620Section~\ref{overview}. If the entry exists in the pattern already, it is 4621updated right away and the work is not left pending. Otherwise, it is placed 4622in a list of pending updates, and the later on the updates are done all at 4623once, using the same algorithm used for \verb'GrB_Matrix_build'. In other 4624words, \verb'setElement' in SuiteSparse:GraphBLAS builds its own internal list 4625of tuples \verb'[I,J,X]', and then calls \verb'GrB_Matrix_build' whenever the 4626matrix is needed in another computation, or whenever \verb'GrB_Matrix_wait' is 4627called. 4628 4629As a result, if calls to \verb'setElement' are mixed with calls to most other 4630methods and operations (even \verb'extractElement') then the pending updates 4631are assembled right away, which will be slow. Performance will be good if many 4632\verb'setElement' updates are left pending, and performance will be poor if the 4633updates are assembled frequently. 4634 4635A few methods and operations can be intermixed with \verb'setElement', in 4636particular, some forms of the \verb'GrB_assign' and \verb'GxB_subassign' 4637operations are compatible with the pending updates from \verb'setElement'. 4638Section~\ref{compare_assign} gives more details on which \verb'GxB_subassign' 4639and \verb'GrB_assign' operations can be interleaved with calls to 4640\verb'setElement' without forcing updates to be assembled. Other methods that 4641do not access the existing entries may also be done without forcing the updates 4642to be assembled, namely \verb'GrB_Matrix_clear' (which erases all pending 4643updates), \verb'GrB_Matrix_free', \verb'GrB_Matrix_ncols', 4644\verb'GrB_Matrix_nrows', \verb'GxB_Matrix_type', and of course 4645\verb'GrB_Matrix_setElement' itself. All other methods and operations cause 4646the updates to be assembled. Future versions of SuiteSparse:GraphBLAS may 4647extend this list. 4648 4649See Section~\ref{random} for an example of how to use 4650\verb'GrB_Matrix_setElement'. 4651If an error occurs, \verb'GrB_error(&err,C)' returns details about the error. 4652 4653\newpage 4654%------------------------------------------------------------------------------- 4655\subsubsection{{\sf GrB\_Matrix\_extractElement:} get an entry from a matrix} 4656%------------------------------------------------------------------------------- 4657\label{matrix_extractElement} 4658 4659\begin{mdframed}[userdefinedwidth=6in] 4660{\footnotesize 4661\begin{verbatim} 4662GrB_Info GrB_Matrix_extractElement // x = A(i,j) 4663( 4664 <type> *x, // extracted scalar 4665 const GrB_Matrix A, // matrix to extract a scalar from 4666 GrB_Index i, // row index 4667 GrB_Index j // column index 4668) ; 4669\end{verbatim} } \end{mdframed} 4670 4671\verb'GrB_Matrix_extractElement' extracts a single entry from a matrix 4672\verb'x=A(i,j)'. 4673 4674An error is returned (\verb'GrB_INVALID_INDEX') if the row index \verb'i' is 4675greater than or equal to the number of rows of \verb'C', or if column index 4676\verb'j' is greater than or equal to the number of columns of \verb'C'. 4677 4678{\bf NOTE: } if no entry is present at \verb'A(i,j)', then 4679\verb'x' is not modified, and the return value of 4680\verb'GrB_Matrix_extractElement' is \verb'GrB_NO_VALUE'. 4681 4682If the entry is not present then GraphBLAS does not know its value, since its 4683value depends on the implicit value, which is the identity value of the 4684additive monoid of the semiring. It is not a characteristic of the matrix 4685itself, but of the semiring it is used in. A matrix can be used in any 4686compatible semiring, and even a mixture of semirings, so the implicit value can 4687change as the semiring changes. 4688 4689As a result, if the entry is present, \verb'x=A(i,j)' is performed and the 4690scalar \verb'x' is returned with this value. The method returns 4691\verb'GrB_SUCCESS'. If the entry is not present, \verb'x' is not modified, and 4692\verb'GrB_NO_VALUE' is returned to the caller. What this means is up to the 4693caller. 4694 4695The function knows the type of the pointer \verb'x', so it can do typecasting 4696as needed, from the type of \verb'A' into the type of \verb'x'. User-defined 4697types cannot be typecasted, so if \verb'A' has a user-defined type then 4698\verb'x' must be a \verb'void *' pointer that points to a memory space the same 4699size as a single scalar of the type of \verb'A'. 4700 4701Currently, this method causes all pending updates from 4702\verb'GrB_setElement', \verb'GrB_assign', or \verb'GxB_subassign' to be 4703assembled, so its use can have performance implications. Calls to this 4704function should not be arbitrarily intermixed with calls to these other two 4705functions. Everything will work correctly and results will be predictable, it 4706will just be slow. 4707 4708\newpage 4709%------------------------------------------------------------------------------- 4710\subsubsection{{\sf GrB\_Matrix\_removeElement:} remove an entry from a matrix} 4711%------------------------------------------------------------------------------- 4712\label{matrix_removeElement} 4713 4714\begin{mdframed}[userdefinedwidth=6in] 4715{\footnotesize 4716\begin{verbatim} 4717GrB_Info GrB_Matrix_removeElement 4718( 4719 GrB_Matrix C, // matrix to remove an entry from 4720 GrB_Index i, // row index 4721 GrB_Index j // column index 4722) ; 4723\end{verbatim} } \end{mdframed} 4724 4725\verb'GrB_Matrix_removeElement' removes a single entry \verb'A(i,j)' from a matrix. 4726If no entry is present at \verb'A(i,j)', then the matrix is not modified. 4727If an error occurs, \verb'GrB_error(&err,A)' returns details about the error. 4728 4729%------------------------------------------------------------------------------- 4730\subsubsection{{\sf GrB\_Matrix\_extractTuples:} get all entries from a matrix} 4731%------------------------------------------------------------------------------- 4732\label{matrix_extractTuples} 4733 4734\begin{mdframed}[userdefinedwidth=6in] 4735{\footnotesize 4736\begin{verbatim} 4737GrB_Info GrB_Matrix_extractTuples // [I,J,X] = find (A) 4738( 4739 GrB_Index *I, // array for returning row indices of tuples 4740 GrB_Index *J, // array for returning col indices of tuples 4741 <type> *X, // array for returning values of tuples 4742 GrB_Index *nvals, // I,J,X size on input; # tuples on output 4743 const GrB_Matrix A // matrix to extract tuples from 4744) ; 4745\end{verbatim} } \end{mdframed} 4746 4747\verb'GrB_Matrix_extractTuples' extracts all the entries from the matrix 4748\verb'A', returning them as a list of tuples, analogous to 4749\verb'[I,J,X]=find(A)' in MATLAB. Entries in the tuples \verb'[I,J,X]' are 4750unique. No pair of row and column indices \verb'(i,j)' appears more than once. 4751 4752The GraphBLAS API states the tuples can be returned in any order. If 4753\verb'GrB_wait(&A)' is called first, then SuiteSparse:GraphBLAS chooses to 4754always return them in sorted order, depending on whether the matrix is stored 4755by row or by column. Otherwise, the indices can be returned in any order. 4756 4757The number of tuples in the matrix \verb'A' is given by 4758\verb'GrB_Matrix_nvals(&anvals,A)'. If \verb'anvals' is larger than the size 4759of the arrays (\verb'nvals' in the parameter list), an error 4760\verb'GrB_INSUFFICIENT_SIZE' is returned, and no tuples are extracted. If 4761\verb'nvals' is larger than \verb'anvals', then only the first \verb'anvals' 4762entries in the arrays \verb'I' \verb'J', and \verb'X' are modified, containing 4763all the tuples of \verb'A', and the rest of \verb'I' \verb'J', and \verb'X' are 4764left unchanged. On output, \verb'nvals' contains the number of tuples 4765extracted. 4766 4767\begin{alert} 4768{\bf SPEC:} As an extension to the spec, the arrays \verb'I', \verb'J', and/or 4769\verb'X' may be passed in as \verb'NULL' pointers. In this case, 4770\verb'GrB_Matrix_extractTuples' does not return a component specified as 4771\verb'NULL'. This is not an error condition. 4772\end{alert} 4773 4774% \newpage 4775%------------------------------------------------------------------------------- 4776\subsubsection{{\sf GrB\_Matrix\_resize:} resize a matrix} 4777%------------------------------------------------------------------------------- 4778\label{matrix_resize} 4779 4780\begin{mdframed}[userdefinedwidth=6in] 4781{\footnotesize 4782\begin{verbatim} 4783GrB_Info GrB_Matrix_resize // change the size of a matrix 4784( 4785 GrB_Matrix A, // matrix to modify 4786 const GrB_Index nrows_new, // new number of rows in matrix 4787 const GrB_Index ncols_new // new number of columns in matrix 4788) ; 4789\end{verbatim} } \end{mdframed} 4790 4791\verb'GrB_Matrix_resize' changes the size of a matrix. 4792If the dimensions decrease, entries that fall outside the resized 4793matrix are deleted. 4794 4795%------------------------------------------------------------------------------- 4796\subsubsection{{\sf GxB\_Matrix\_concat:} concatenate matrices } 4797%------------------------------------------------------------------------------- 4798\label{matrix_concat} 4799 4800\begin{mdframed}[userdefinedwidth=6in] 4801{\footnotesize 4802\begin{verbatim} 4803GrB_Info GxB_Matrix_concat // concatenate a 2D array of matrices 4804( 4805 GrB_Matrix C, // input/output matrix for results 4806 const GrB_Matrix *Tiles, // 2D row-major array of size m-by-n 4807 const GrB_Index m, 4808 const GrB_Index n, 4809 const GrB_Descriptor desc // unused, except threading control 4810) ; 4811\end{verbatim} } \end{mdframed} 4812 4813\verb'GxB_Matrix_concat' concatenates an array of matrices (\verb'Tiles') into 4814a single \verb'GrB_Matrix' \verb'C'. 4815 4816\verb'Tiles' is an \verb'm'-by-\verb'n' dense array of matrices held in 4817row-major format, where \verb'Tiles [i*n+j]' is the $(i,j)$th tile, and where 4818\verb'm' $> 0$ and \verb'n' $> 0$ must hold. Let $A_{i,j}$ denote the 4819$(i,j)$th tile. The matrix \verb'C' is constructed by concatenating these 4820tiles together, as: 4821 4822\[ 4823C = 4824\left[ 4825\begin{array}{ccccc} 4826 A_{0,0} & A_{0,1} & A_{0,2} & \cdots & A_{0,n-1} \\ 4827 A_{1,0} & A_{1,1} & A_{1,2} & \cdots & A_{1,n-1} \\ 4828 \cdots & \\ 4829 A_{m-1,0} & A_{m-1,1} & A_{m-1,2} & \cdots & A_{m-1,n-1} 4830\end{array} 4831\right] 4832\] 4833 4834On input, the matrix \verb'C' must already exist. Any existing entries in 4835\verb'C' are discarded. \verb'C' must have dimensions \verb'nrows' by 4836\verb'ncols' where \verb'nrows' is the sum of the number of rows in the 4837matrices $A_{i,0}$ for all $i$, and \verb'ncols' is the sum of the number of 4838columns in the matrices $A_{0,j}$ for all $j$. All matrices in any given tile 4839row $i$ must have the same number of rows (that is, and all matrices in any 4840given tile column $j$ must have the same number of columns). 4841 4842The type of \verb'C' is unchanged, and all matrices $A_{i,j}$ are typecasted 4843into the type of \verb'C'. Any settings made to \verb'C' by 4844\verb'GxB_Matrix_Option_set' (format by row or by column, bitmap switch, hyper 4845switch, and sparsity control) are unchanged. 4846 4847%------------------------------------------------------------------------------- 4848\subsubsection{{\sf GxB\_Matrix\_split:} split a matrix } 4849%------------------------------------------------------------------------------- 4850\label{matrix_split} 4851 4852\begin{mdframed}[userdefinedwidth=6in] 4853{\footnotesize 4854\begin{verbatim} 4855GrB_Info GxB_Matrix_split // split a matrix into 2D array of matrices 4856( 4857 GrB_Matrix *Tiles, // 2D row-major array of size m-by-n 4858 const GrB_Index m, 4859 const GrB_Index n, 4860 const GrB_Index *Tile_nrows, // array of size m 4861 const GrB_Index *Tile_ncols, // array of size n 4862 const GrB_Matrix A, // input matrix to split 4863 const GrB_Descriptor desc // unused, except threading control 4864) ; 4865\end{verbatim} } \end{mdframed} 4866 4867\verb'GxB_Matrix_split' does the opposite of \verb'GxB_Matrix_concat'. It 4868splits a single input matrix \verb'A' into a 2D array of tiles. On input, the 4869\verb'Tiles' array must be a non-\verb'NULL' pointer to a previously allocated 4870array of size at least \verb'm*n' where both \verb'm' and \verb'n' must be 4871greater than zero. The \verb'Tiles_nrows' array has size \verb'm', and 4872\verb'Tiles_ncols' has size \verb'n'. The $(i,j)$th tile has dimension 4873\verb'Tiles_nrows[i]'-by-\verb'Tiles_ncols[j]'. The sum of 4874\verb'Tiles_nrows [0:m-1]' must equal the number of rows of \verb'A', and the 4875sum of \verb'Tiles_ncols [0:n-1]' must equal the number of columns of \verb'A'. 4876The type of each tile is the same as the type of \verb'A'; no typecasting is 4877done. 4878 4879\newpage 4880%------------------------------------------------------------------------------- 4881\subsubsection{{\sf GxB\_Matrix\_diag:} construct a diagonal matrix} 4882%------------------------------------------------------------------------------- 4883\label{matrix_diag} 4884 4885\begin{mdframed}[userdefinedwidth=6in] 4886{\footnotesize 4887\begin{verbatim} 4888GrB_Info GxB_Matrix_diag // construct a diagonal matrix from a vector 4889( 4890 GrB_Matrix C, // output matrix 4891 const GrB_Vector v, // input vector 4892 int64_t k, 4893 const GrB_Descriptor desc // unused, except threading control 4894) ; 4895\end{verbatim} } \end{mdframed} 4896 4897\verb'GxB_Matrix_diag' constructs a matrix from a vector. Let $n$ be the 4898length of the \verb'v' vector, from \verb'GrB_Vector_size (&n, v)'. If 4899\verb'k' = 0, then \verb'C' is an $n$-by-$n$ diagonal matrix with the entries 4900from \verb'v' along the main diagonal of \verb'C', with \verb'C(i,i)=v(i)'. If 4901\verb'k' is nonzero, \verb'C' is square with dimension $n+|k|$. If \verb'k' is 4902positive, it denotes diagonals above the main diagonal, with 4903\verb'C(i,i+k)=v(i)'. 4904If \verb'k' is negative, it denotes diagonals below the main diagonal of 4905\verb'C', with \verb'C(i-k,i)=v(i)'. This behavior is identical to the MATLAB 4906statement \verb'C=diag(v,k)', where \verb'v' is a vector, except that 4907\verb'GxB_Matrix_diag' can also do typecasting. 4908 4909\verb'C' must already exist on input, of the correct size. Any existing 4910entries in \verb'C' are discarded. The type of \verb'C' is preserved, so that 4911if the type of \verb'C' and \verb'v' differ, the entries are typecasted into 4912the type of \verb'C'. Any settings made to \verb'C' by 4913\verb'GxB_Matrix_Option_set' (format by row or by column, bitmap switch, hyper 4914switch, and sparsity control) are unchanged. 4915 4916%------------------------------------------------------------------------------- 4917\subsubsection{{\sf GrB\_Matrix\_free:} free a matrix} 4918%------------------------------------------------------------------------------- 4919\label{matrix_free} 4920 4921\begin{mdframed}[userdefinedwidth=6in] 4922{\footnotesize 4923\begin{verbatim} 4924GrB_Info GrB_free // free a matrix 4925( 4926 GrB_Matrix *A // handle of matrix to free 4927) ; 4928\end{verbatim} } \end{mdframed} 4929 4930\verb'GrB_Matrix_free' frees a matrix. Either usage: 4931 4932 {\small 4933 \begin{verbatim} 4934 GrB_Matrix_free (&A) ; 4935 GrB_free (&A) ; \end{verbatim}} 4936 4937\noindent 4938frees the matrix \verb'A' and sets \verb'A' to \verb'NULL'. It safely does 4939nothing if passed a \verb'NULL' handle, or if \verb'A == NULL' on input. Any 4940pending updates to the matrix are abandoned. 4941 4942\newpage 4943%=============================================================================== 4944\subsection{GraphBLAS matrix and vector import/export} %======================== 4945%=============================================================================== 4946\label{import_export} 4947 4948The import/export functions allow the user application to create a 4949\verb'GrB_Matrix' or \verb'GrB_Vector' object, and to extract its contents, 4950faster and with less memory overhead than the \verb'GrB_*_build' and 4951\verb'GrB_*_extractTuples' functions. 4952 4953The semantics of import/export are the same as the {\em move constructor} in 4954C++. On import, the user provides a set of arrays that have been previously 4955allocated via the ANSI C \verb'malloc', \verb'calloc', or \verb'realloc' 4956functions (by default), or by the corresponding functions passed to 4957\verb'GxB_init'. The arrays define the content of the matrix or vector. 4958Unlike \verb'GrB_*_build', the GraphBLAS library then takes ownership of the 4959user's input arrays and may either: 4960 4961\begin{enumerate} 4962\item incorporate them 4963into its internal data structure for the new \verb'GrB_Matrix' or 4964\verb'GrB_Vector', potentially creating the \verb'GrB_Matrix' or 4965\verb'GrB_Vector' in constant time with no memory copying performed, or 4966\item if 4967the library does not support the import format directly, then it may convert 4968the input to its internal format, and then free the user's input arrays. 4969\item A 4970GraphBLAS implementation may also choose to use a mix of the two strategies. 4971\end{enumerate} 4972 4973SuiteSparse:GraphBLAS takes the first approach, and so the import functions 4974always take $O(1)$ time, and require $O(1)$ memory space to be allocated. 4975 4976Regardless of the method chosen, as listed above, the input arrays are no 4977longer owned by the user application. If \verb'A' is a \verb'GrB_Matrix' 4978created by an import, the user input arrays are freed no later than 4979\verb'GrB_free(&A)', and may be freed earlier, at the discretion of the 4980GraphBLAS library. The data structure of the \verb'GrB_Matrix' and 4981\verb'GrB_Vector' remain opaque. 4982 4983The export of a \verb'GrB_Matrix' or \verb'GrB_Vector' is symmetric with the 4984import operation. The export changes the ownership of the arrays, where the 4985\verb'GrB_Matrix' or \verb'GrB_Vector' no longer exists when the export 4986completes, and instead the user is returned several arrays that contain the 4987matrix or vector in the requested format. Ownership of these arrays is given 4988to the user application, which is then responsible for freeing them via the 4989ANSI C \verb'free' function (by default), or by the \verb'free_function' that 4990was passed in to \verb'GxB_init'. Alternatively, these arrays can be 4991re-imported into a \verb'GrB_Matrix' or \verb'GrB_Vector', at which point they 4992again become the responsibility of GraphBLAS. 4993 4994For an export, if the output format matches the current internal format of the 4995matrix or vector then these arrays are returned to the user application in 4996$O(1)$ time and with no memory copying performed. Otherwise, the 4997\verb'GrB_Matrix' or \verb'GrB_Vector' is first converted into the requested 4998format, and then exported. 4999 5000Exporting a matrix or vector forces completion of any pending operations on the 5001matrix, with one exception. SuiteSparse:GraphBLAS supports three kinds of 5002pending operations: {\em zombies} (pending deletions), {\em pending tuples} 5003(pending insertions), and a {\em lazy sort}. In the latter, if the matrix or 5004vector is left in a {\em jumbled} state, indices in any row or column may 5005appear out of order. If unjumbled, the indices always appear in ascending 5006order. 5007 5008The vector import/export methods use a three formats for a \verb'GrB_Vector'. 5009Eight different formats are provided for the import/export of a 5010\verb'GrB_Matrix'. For each format, the numerical value array (\verb'Ax' or 5011\verb'vx') has a C type corresponding to one of the 13 built-in types in 5012GraphBLAS (\verb'bool', \verb'int*_t', \verb'uint*_t', \verb'float', 5013\verb'double' \verb'float complex', \verb'double complex'), or that corresponds 5014with the user-defined type. No typecasting is done on import or export. 5015 5016\begin{alert} 5017% {\bf FUTURE:} 5018For the import methods, the numerical array must be large enough to hold all 5019the entries, but in a future release of SuiteSparse: GraphBLAS, it may be 5020specified as an array of length one. This will indicate that all entries in 5021the matrix or vector being constructed have the same uniform value, given by 5022\verb'Ax[0]' for matrices and \verb'vx[0]' for vectors. Likewise, on export, a 5023future release of SuiteSparse:GraphBLAS may return arrays of size large 5024enough only to hold a single entry. Even though there may be many more entries 5025than that in the matrix or vector. This will be indicated, on both import 5026and export, with the \verb'is_uniform' boolean flag. 5027 5028If \verb'is_uniform' is true, then all entries present in the matrix or vector 5029have the same value, and the \verb'Ax' array (for matrices) or \verb'vx' array 5030(for vectors) only need to be large enough to hold a single value. 5031 5032Currently, uniform-valued matrices are not yet supported in this release of 5033SuiteSparse:GraphBLAS. On export, \verb'is_uniform' will always be false. 5034On import, an error is returned if \verb'is_uniform' is true on input. 5035This feature will be added later, but the \verb'is_uniform' parameter is 5036added now, so that the API does not need to change once this feature is 5037implemented. 5038\end{alert} 5039 5040The export of a \verb'GrB_Vector' in \verb'CSC' format may return the indices 5041in a jumbled state, in any order. 5042 5043For a \verb'GrB_Matrix' in \verb'CSR' or \verb'HyperCSR' format, if the matrix 5044is returned as jumbled, the column indices in any given row may appear out of 5045order. For \verb'CSC' or \verb'HyperCSC' formats, if the matrix is returned as 5046jumbled, the row indices in any given column may appear out of order. 5047 5048On import, if the user-provided arrays contain jumbled row or column vectors, 5049then the input flag \verb'jumbled' must be passed in as \verb'true'. On 5050export, if \verb'*jumbled' is \verb'NULL', this indicates to the export method 5051that the user expects the exported matrix or vector to be returned in an 5052ordered, unjumbled state. If \verb'*jumbled' is provided, then it is return as 5053\verb'true' if the indices may appear out of order, or \verb'false' if they are 5054known to be in ascending order. 5055 5056Matrices and vectors in bitmap or full format are never jumbled. 5057 5058The table below lists the methods presented in this section. 5059 5060\vspace{0.2in} 5061{\footnotesize 5062\begin{tabular}{lll} 5063\hline 5064method & purpose & Section \\ 5065\hline 5066\verb'GxB_Vector_import_CSC' & import a vector in CSC format 5067 & \ref{vector_import_csc} \\ 5068\verb'GxB_Vector_export_CSC' & export a vector in CSC format 5069 & \ref{vector_export_csc} \\ 5070\hline 5071\verb'GxB_Vector_import_Bitmap' & import a vector in bitmap format 5072 & \ref{vector_import_bitmap} \\ 5073\verb'GxB_Vector_export_Bitmap' & export a vector in bitmap format 5074 & \ref{vector_export_bitmap} \\ 5075\hline 5076\verb'GxB_Vector_import_Full' & import a vector in full format 5077 & \ref{vector_import_full} \\ 5078\verb'GxB_Vector_export_Full' & export a vector in full format 5079 & \ref{vector_export_full} \\ 5080\hline 5081\hline 5082\verb'GxB_Matrix_import_CSR' & import a matrix in CSR form 5083 & \ref{matrix_import_csr} \\ 5084\verb'GxB_Matrix_export_CSR' & export a matrix in CSR form 5085 & \ref{matrix_export_csr} \\ 5086\hline 5087\verb'GxB_Matrix_import_CSC' & import a matrix in CSC form 5088 & \ref{matrix_import_csc} \\ 5089\verb'GxB_Matrix_export_CSC' & export a matrix in CSC form 5090 & \ref{matrix_export_csc} \\ 5091\hline 5092\verb'GxB_Matrix_import_HyperCSR' & import a matrix in HyperCSR form 5093 & \ref{matrix_import_hypercsr} \\ 5094\verb'GxB_Matrix_export_HyperCSR' & export a matrix in HyperCSR form 5095 & \ref{matrix_export_hypercsr} \\ 5096\hline 5097\verb'GxB_Matrix_import_HyperCSC' & import a matrix in HyperCSC form 5098 & \ref{matrix_import_hypercsc} \\ 5099\verb'GxB_Matrix_export_HyperCSC' & export a matrix in HyperCSC form 5100 & \ref{matrix_export_hypercsc} \\ 5101\hline 5102\verb'GxB_Matrix_import_BitmapR' & import a matrix in BitmapR form 5103 & \ref{matrix_import_bitmapr} \\ 5104\verb'GxB_Matrix_export_BitmapR' & export a matrix in BitmapR form 5105 & \ref{matrix_export_bitmapr} \\ 5106\hline 5107\verb'GxB_Matrix_import_BitmapC' & import a matrix in BitmapC form 5108 & \ref{matrix_import_bitmapc} \\ 5109\verb'GxB_Matrix_export_BitmapC' & export a matrix in BitmapC form 5110 & \ref{matrix_export_bitmapc} \\ 5111\hline 5112\verb'GxB_Matrix_import_FullR' & import a matrix in FullR form 5113 & \ref{matrix_import_fullr} \\ 5114\verb'GxB_Matrix_export_FullR' & export a matrix in FullR form 5115 & \ref{matrix_export_fullr} \\ 5116\hline 5117\verb'GxB_Matrix_import_FullC' & import a matrix in FullC form 5118 & \ref{matrix_import_fullc} \\ 5119\verb'GxB_Matrix_export_FullC' & export a matrix in FullC form 5120 & \ref{matrix_export_fullc} \\ 5121\hline 5122\end{tabular} 5123} 5124\vspace{0.2in} 5125 5126\newpage 5127%------------------------------------------------------------------------------- 5128\subsubsection{{\sf GxB\_Vector\_import\_CSC} import a vector in CSC form} 5129%------------------------------------------------------------------------------- 5130\label{vector_import_csc} 5131 5132\begin{mdframed}[userdefinedwidth=6in] 5133{\footnotesize 5134\begin{verbatim} 5135GrB_Info GxB_Vector_import_CSC // import a vector in CSC format 5136( 5137 GrB_Vector *v, // handle of vector to create 5138 GrB_Type type, // type of vector to create 5139 GrB_Index n, // vector length 5140 GrB_Index **vi, // indices, vi_size >= nvals(v)*sizeof(int64_t) 5141 void **vx, // values, vx_size >= nvals(v)*(type size) 5142 GrB_Index vi_size, // size of vi in bytes 5143 GrB_Index vx_size, // size of vx in bytes 5144 bool is_uniform, // if true, v has uniform values (not yet supported) 5145 GrB_Index nvals, // # of entries in vector 5146 bool jumbled, // if true, indices may be unsorted 5147 const GrB_Descriptor desc 5148) ; 5149\end{verbatim} 5150} \end{mdframed} 5151 5152\noindent 5153\verb'GxB_Vector_import_CSC' is analogous to \verb'GxB_Matrix_import_CSC'. 5154Refer to the description of \verb'GxB_Matrix_import_CSC' for details 5155(Section~\ref{matrix_import_csc}). 5156 5157If successful, \verb'v' is created as a \verb'n'-by-1 \verb'GrB_Vector'. Its entries are 5158the row indices given by \verb'vi', with the corresponding values in \verb'vx'. 5159The two pointers \verb'vi' and \verb'vx' are returned as \verb'NULL', which 5160denotes that they are no longer owned by the user application. They have 5161instead been moved into the new \verb'GrB_Vector' \verb'v'. If \verb'jumbled' 5162is true, the row indices in \verb'vi' must appear in sorted order. No 5163duplicates can appear. These conditions are not checked, so results are 5164undefined if they are not met exactly. The user application can check the 5165resulting vector \verb'v' with \verb'GxB_print', if desired, which will 5166determine if these conditions hold. 5167 5168If not successful, \verb'v' is returned as \verb'NULL' and \verb'vi' and 5169\verb'vx' are not modified. 5170 5171\newpage 5172%------------------------------------------------------------------------------- 5173\subsubsection{{\sf GxB\_Vector\_export\_CSC:} export a vector in CSC form} 5174%------------------------------------------------------------------------------- 5175\label{vector_export_csc} 5176 5177\begin{mdframed}[userdefinedwidth=6in] 5178{\footnotesize 5179\begin{verbatim} 5180GrB_Info GxB_Vector_export_CSC // export and free a CSC vector 5181( 5182 GrB_Vector *v, // handle of vector to export and free 5183 GrB_Type *type, // type of vector exported 5184 GrB_Index *n, // length of the vector 5185 GrB_Index **vi, // indices, vi_size >= nvals(v)*sizeof(int64_t) 5186 void **vx, // values, vx_size >= nvals(v)*(type size) 5187 GrB_Index *vi_size, // size of vi in bytes 5188 GrB_Index *vx_size, // size of vx in bytes 5189 bool *is_uniform, // if true, v has uniform values (not yet supported) 5190 GrB_Index *nvals, // # of entries in vector 5191 bool *jumbled, // if true, indices may be unsorted 5192 const GrB_Descriptor desc 5193) ; 5194\end{verbatim} 5195} \end{mdframed} 5196 5197\verb'GxB_Vector_export_CSC' is analogous to \verb'GxB_Matrix_export_CSC'. 5198Refer to the description of \verb'GxB_Matrix_export_CSC' for details 5199(Section~\ref{matrix_export_csc}). 5200 5201Exporting a vector forces completion of any pending operations on the vector, 5202except that indices may be exported out of order (\verb'jumbled' is \verb'true' 5203if they may be out of order, \verb'false' if sorted in ascending order). If 5204\verb'jumbled' is \verb'NULL' on input, then the indices are always returned in 5205sorted order. 5206 5207If successful, \verb'v' is returned as \verb'NULL', and its contents are 5208returned to the user, with its \verb'type', dimension \verb'n', and number of 5209entries \verb'nvals'. A list of row indices of entries that were in 5210\verb'v' is returned in \verb'vi', and the corresponding numerical values are 5211returned in \verb'vx'. If \verb'nvals' is zero, the \verb'vi' and \verb'vx' 5212arrays are returned as \verb'NULL'; this is not an error condition. 5213 5214If not successful, \verb'v' is unmodified and \verb'vi' and \verb'vx' are 5215not modified. 5216 5217\newpage 5218%------------------------------------------------------------------------------- 5219\subsubsection{{\sf GxB\_Vector\_import\_Bitmap} import a vector in bitmap form} 5220%------------------------------------------------------------------------------- 5221\label{vector_import_bitmap} 5222 5223\begin{mdframed}[userdefinedwidth=6in] 5224{\footnotesize 5225\begin{verbatim} 5226GrB_Info GxB_Vector_import_Bitmap // import a bitmap vector 5227( 5228 GrB_Vector *v, // handle of vector to create 5229 GrB_Type type, // type of vector to create 5230 GrB_Index n, // vector length 5231 int8_t **vb, // bitmap, vb_size >= n 5232 void **vx, // values, vx_size >= n * (type size) 5233 GrB_Index vb_size, // size of vb in bytes 5234 GrB_Index vx_size, // size of vx in bytes 5235 bool is_uniform, // if true, v has uniform values (not yet supported) 5236 GrB_Index nvals, // # of entries in bitmap 5237 const GrB_Descriptor desc 5238) ; 5239\end{verbatim} 5240} \end{mdframed} 5241 5242\noindent 5243\verb'GxB_Vector_import_Bitmap' is analogous to 5244\verb'GxB_Matrix_import_BitmapC'. Refer to the description of 5245\verb'GxB_Matrix_import_BitmapC' for details 5246(Section~\ref{matrix_import_bitmapc}). 5247 5248If successful, \verb'v' is created as a \verb'n'-by-1 \verb'GrB_Vector'. 5249Its entries are determined by \verb'vb', where \verb'vb[i]=1' denotes that 5250the entry $v(i)$ is present with value given by \verb'vx[i]', and 5251\verb'vb[i]=0' denotes that the entry $v(i)$ is not present (\verb'vx[i]' is 5252ignored in this case). 5253 5254The two pointers \verb'vb' and \verb'vx' are returned as \verb'NULL', which 5255denotes that they are no longer owned by the user application. They have 5256instead been moved into the new \verb'GrB_Vector' \verb'v'. 5257 5258The \verb'vb' array must not hold any values other than 0 and 1. The value 5259\verb'nvals' must exactly match the number of 1s in the \verb'vb' array. These 5260conditions are not checked, so results are undefined if they are not met 5261exactly. The user application can check the resulting vector \verb'v' with 5262\verb'GxB_print', if desired, which will determine if these conditions hold. 5263 5264If not successful, \verb'v' is returned as \verb'NULL' and \verb'vb' and 5265\verb'vx' are not modified. 5266 5267\newpage 5268%------------------------------------------------------------------------------- 5269\subsubsection{{\sf GxB\_Vector\_export\_Bitmap:} export a vector in bitmap form} 5270%------------------------------------------------------------------------------- 5271\label{vector_export_bitmap} 5272 5273\begin{mdframed}[userdefinedwidth=6in] 5274{\footnotesize 5275\begin{verbatim} 5276GrB_Info GxB_Vector_export_Bitmap // export and free a bitmap vector 5277( 5278 GrB_Vector *v, // handle of vector to export and free 5279 GrB_Type *type, // type of vector exported 5280 GrB_Index *n, // length of the vector 5281 int8_t **vb, // bitmap, vb_size >= n 5282 void **vx, // values, vx_size >= n * (type size) 5283 GrB_Index *vb_size, // size of vb in bytes 5284 GrB_Index *vx_size, // size of vx in bytes 5285 bool *is_uniform, // if true, v has uniform values (not yet supported) 5286 GrB_Index *nvals, // # of entries in bitmap 5287 const GrB_Descriptor desc 5288) ; 5289\end{verbatim} 5290} \end{mdframed} 5291 5292\verb'GxB_Vector_export_Bitmap' is analogous to 5293\verb'GxB_Matrix_export_BitmapC'. Refer to the description of 5294\verb'GxB_Matrix_export_BitmapC' for details 5295(Section~\ref{matrix_export_bitmapc}). 5296 5297Exporting a vector forces completion of any pending operations on the vector. 5298 5299If successful, \verb'v' is returned as \verb'NULL', and its contents are 5300returned to the user, with its \verb'type', dimension \verb'n', and number of 5301entries \verb'nvals'. The entries that were in \verb'v' are returned in 5302\verb'vb', where \verb'vb[i]=1' means $v(i)$ is present with value 5303\verb'vx[i]', and \verb'vb[i]=0' means $v(i)$ is not present (\verb'vx[i]' is 5304undefined in this case). The corresponding numerical values are returned in 5305\verb'vx'. 5306 5307If not successful, \verb'v' is unmodified and \verb'vb' and \verb'vx' are not 5308modified. 5309 5310 5311\newpage 5312%------------------------------------------------------------------------------- 5313\subsubsection{{\sf GxB\_Vector\_import\_Full} import a vector in full form} 5314%------------------------------------------------------------------------------- 5315\label{vector_import_full} 5316 5317\begin{mdframed}[userdefinedwidth=6in] 5318{\footnotesize 5319\begin{verbatim} 5320GrB_Info GxB_Vector_import_Full // import a full vector 5321( 5322 GrB_Vector *v, // handle of vector to create 5323 GrB_Type type, // type of vector to create 5324 GrB_Index n, // vector length 5325 void **vx, // values, vx_size >= nvals(v) * (type size) 5326 GrB_Index vx_size, // size of vx in bytes 5327 bool is_uniform, // if true, v has uniform values (not yet supported) 5328 const GrB_Descriptor desc 5329) ; 5330\end{verbatim} 5331} \end{mdframed} 5332 5333\noindent 5334\verb'GxB_Vector_import_Full' is analogous to \verb'GxB_Matrix_import_FullC'. 5335Refer to the description of \verb'GxB_Matrix_import_BitmapC' for details 5336(Section~\ref{matrix_import_fullc}). 5337 5338If successful, \verb'v' is created as a \verb'n'-by-1 \verb'GrB_Vector'. 5339All entries are present, and the value of $v(i)$ is given by \verb'vx[i]'. 5340 5341The pointer \verb'vx' is returned as \verb'NULL', which denotes that it is no 5342longer owned by the user application. It has instead been moved into the new 5343\verb'GrB_Vector' \verb'v'. 5344 5345If not successful, \verb'v' is returned as \verb'NULL' and 5346\verb'vx' is not modified. 5347 5348\newpage 5349%------------------------------------------------------------------------------- 5350\subsubsection{{\sf GxB\_Vector\_export\_Full:} export a vector in full form} 5351%------------------------------------------------------------------------------- 5352\label{vector_export_full} 5353 5354\begin{mdframed}[userdefinedwidth=6in] 5355{\footnotesize 5356\begin{verbatim} 5357GrB_Info GxB_Vector_export_Full // export and free a full vector 5358( 5359 GrB_Vector *v, // handle of vector to export and free 5360 GrB_Type *type, // type of vector exported 5361 GrB_Index *n, // length of the vector 5362 void **vx, // values, vx_size >= nvals(v) * (type size) 5363 GrB_Index *vx_size, // size of vx in bytes 5364 bool *is_uniform, // if true, v has uniform values (not yet supported) 5365 const GrB_Descriptor desc 5366) ; 5367\end{verbatim} 5368} \end{mdframed} 5369 5370\verb'GxB_Vector_export_Full' is analogous to \verb'GxB_Matrix_export_FullC'. 5371Refer to the description of \verb'GxB_Matrix_export_FullC' for details 5372(Section~\ref{matrix_export_fullc}). 5373 5374Exporting a vector forces completion of any pending operations on the vector. 5375All entries in \verb'v' must be present. In other words, prior to the export, 5376\verb'GrB_Vector_nvals' for a vector of length \verb'n' must report that the 5377vector contains \verb'n' entries; \verb'GrB_INVALID_VALUE' is returned if this 5378condition does not hold. 5379 5380If successful, \verb'v' is returned as \verb'NULL', and its contents are 5381returned to the user, with its \verb'type' and dimension \verb'n'. The entries 5382that were in \verb'v' are returned in the array \verb'vx', \verb'vb', where 5383\verb'vb[i]=1' means $v(i)$ is present with value where the value of $v(i)$ is 5384\verb'vx[i]'. 5385 5386If not successful, \verb'v' is unmodified and \verb'vx' is not modified. 5387 5388\newpage 5389%------------------------------------------------------------------------------- 5390\subsubsection{{\sf GxB\_Matrix\_import\_CSR:} import a CSR matrix} 5391%------------------------------------------------------------------------------- 5392\label{matrix_import_csr} 5393 5394\begin{mdframed}[userdefinedwidth=6in] 5395{\footnotesize 5396\begin{verbatim} 5397GrB_Info GxB_Matrix_import_CSR // import a CSR matrix 5398( 5399 GrB_Matrix *A, // handle of matrix to create 5400 GrB_Type type, // type of matrix to create 5401 GrB_Index nrows, // number of rows of the matrix 5402 GrB_Index ncols, // number of columns of the matrix 5403 GrB_Index **Ap, // row "pointers", Ap_size >= (nrows+1)*sizeof(int64_t) 5404 GrB_Index **Aj, // column indices, Aj_size >= nvals(A)*sizeof(int64_t) 5405 void **Ax, // values, Ax_size >= nvals(A) * (type size) 5406 GrB_Index Ap_size, // size of Ap in bytes 5407 GrB_Index Aj_size, // size of Aj in bytes 5408 GrB_Index Ax_size, // size of Ax in bytes 5409 bool is_uniform, // if true, A has uniform values (not yet supported) 5410 bool jumbled, // if true, indices in each row may be unsorted 5411 const GrB_Descriptor desc 5412) ; 5413\end{verbatim} 5414} \end{mdframed} 5415 5416\verb'GxB_Matrix_import_CSR' imports a matrix from 3 user arrays in CSR format. 5417In the resulting \verb'GrB_Matrix A', the \verb'CSR' format is a sparse matrix 5418with a format (\verb'GxB_FORMAT') of \verb'GxB_BY_ROW'. 5419 5420The first four arguments of \verb'GxB_Matrix_import_CSR' are the same as 5421all four arguments of \verb'GrB_Matrix_new', because this function is similar. 5422It creates a new \verb'GrB_Matrix A', with the given type and dimensions. 5423The \verb'GrB_Matrix A' does not exist on input. 5424 5425Unlike \verb'GrB_Matrix_new', this function also populates the new matrix 5426\verb'A' with the three arrays \verb'Ap', \verb'Aj' and \verb'Ax', provided by 5427the user, all of which must have been created with the ANSI C \verb'malloc', 5428\verb'calloc', or \verb'realloc' functions (by default), or by the 5429corresponding \verb'malloc_function', \verb'calloc_function', or 5430\verb'realloc_function' provided to \verb'GxB_init'. These arrays define the 5431pattern and values of the new matrix \verb'A': 5432 5433\begin{itemize} 5434\item \verb'GrB_Index Ap [nrows+1] ;' The \verb'Ap' array is the row 5435``pointer'' array. It does not actual contain pointers. More precisely, it is 5436an integer array that defines where the column indices and values appear in 5437\verb'Aj' and \verb'Ax', for each row. The number of entries in row \verb'i' 5438is given by the expression \verb'Ap [i+1] - Ap [i]'. 5439 5440\item \verb'GrB_Index Aj [nvals] ;' The \verb'Aj' array defines the 5441column indices of entries in each row. 5442 5443\item \verb'ctype Ax [nvals] ;' The \verb'Ax' array defines the values of 5444entries in each row. It is passed in as a \verb'(void *)' pointer, but it must 5445point to an array of size \verb'nvals' values, each of size 5446\verb'sizeof(ctype)', where \verb'ctype' is the exact type in C that corresponds 5447to the \verb'GrB_Type type' parameter. That is, if \verb'type' is 5448\verb'GrB_INT32', then \verb'ctype' is \verb'int32_t'. User types 5449may be used, just the same as built-in types. 5450\end{itemize} 5451 5452The content of the three arrays \verb'Ap' \verb'Aj', and \verb'Ax' is very 5453specific. This content is not checked, since this function takes only 5454$O(1)$ time. Results are undefined if the following specification is not 5455followed exactly. 5456 5457The column indices of entries in the ith row of the matrix are held in 5458\verb'Aj [Ap [i] ... Ap[i+1]]', and the corresponding values are held in the 5459same positions in \verb'Ax'. Column indices must be in the range 0 to 5460\verb'ncols'-1. If \verb'jumbled' is \verb'false', column indices must appear 5461in ascending order within each row. If \verb'jumbled' is \verb'true', column 5462indices may appear in any order within each row. No duplicate column indices 5463may appear in any row. \verb'Ap [0]' must equal zero, and \verb'Ap [nrows]' 5464must equal nvals. The \verb'Ap' array must be of size \verb'nrows'+1 (or 5465larger), and the \verb'Aj' and \verb'Ax' arrays must have size at least 5466\verb'nvals'. 5467 5468If \verb'nvals' is zero, then the content of the \verb'Aj' and \verb'Ax' arrays 5469is not accessed and they may be \verb'NULL' on input (if not \verb'NULL', they 5470are still freed and returned as \verb'NULL', if the method is successful). 5471 5472An example of the CSR format is shown below. Consider the following 5473matrix with 10 nonzero entries, and suppose the zeros are not stored. 5474 5475 \begin{equation} 5476 \label{eqn:Aexample} 5477 A = \left[ 5478 \begin{array}{cccc} 5479 4.5 & 0 & 3.2 & 0 \\ 5480 3.1 & 2.9 & 0 & 0.9 \\ 5481 0 & 1.7 & 3.0 & 0 \\ 5482 3.5 & 0.4 & 0 & 1.0 \\ 5483 \end{array} 5484 \right] 5485 \end{equation} 5486 5487The \verb'Ap' array has length 5, since the matrix is 4-by-4. The first entry 5488must always zero, and \verb'Ap [5] = 10' is the number of entries. 5489The content of the arrays is shown below: 5490 5491{\footnotesize 5492\begin{verbatim} 5493 int64_t Ap [ ] = { 0, 2, 5, 7, 10 } ; 5494 int64_t Aj [ ] = { 0, 2, 0, 1, 3, 1, 2, 0, 1, 3 } ; 5495 double Ax [ ] = { 4.5, 3.2, 3.1, 2.9, 0.9, 1.7, 3.0, 3.5, 0.4, 1.0 } ; \end{verbatim} } 5496 5497Spaces have been added to the \verb'Ap' array, just for illustration. Row zero 5498is in \verb'Aj [0..1]' (column indices) and \verb'Ax [0..1]' (values), starting 5499at \verb'Ap [0] = 0' and ending at \verb'Ap [0+1]-1 = 1'. The list of column 5500indices of row one is at \verb'Aj [2..4]' and row two is in \verb'Aj [5..6]'. 5501The last row (three) appears \verb'Aj [7..9]', because \verb'Ap [3] = 7' and 5502\verb'Ap [4]-1 = 10-1 = 9'. The corresponding numerical values appear in the 5503same positions in \verb'Ax'. 5504 5505To iterate over the rows and entries of this matrix, the following code can be 5506used 5507(assuming it has type \verb'GrB_FP64'): 5508 5509 {\footnotesize 5510 \begin{verbatim} 5511 int64_t nvals = Ap [nrows] ; 5512 for (int64_t i = 0 ; i < nrows ; i++) 5513 { 5514 // get A(i,:) 5515 for (int64_t p = Ap [i] ; p < Ap [i+1] ; p++) 5516 { 5517 // get A(i,j) 5518 int64_t j = Aj [p] ; // column index 5519 double aij = Ax [is_uniform ? 0 : p] ; // numerical value 5520 } 5521 } \end{verbatim}} 5522 5523On successful creation of \verb'A', the three pointers \verb'Ap', \verb'Aj', 5524and \verb'Ax' are set to \verb'NULL' on output. This denotes to the user 5525application that it is no longer responsible for freeing these arrays. 5526Internally, GraphBLAS has moved these arrays into its internal data structure. 5527They will eventually be freed no later than when the user does 5528\verb'GrB_free(&A)', but they may be freed or resized later, if the matrix 5529changes. If an export is performed, the freeing of these three arrays again 5530becomes the responsibility of the user application. 5531 5532The \verb'GxB_Matrix_import_CSR' function will rarely fail, since it allocates 5533just $O(1)$ space. If it does fail, it returns \verb'GrB_OUT_OF_MEMORY', 5534and it leaves the three user arrays unmodified. They are still owned by 5535the user application, which is eventually responsible for freeing them with 5536\verb'free(Ap)', etc. 5537 5538\newpage 5539%------------------------------------------------------------------------------- 5540\subsubsection{{\sf GxB\_Matrix\_export\_CSR:} export a CSR matrix} 5541%------------------------------------------------------------------------------- 5542\label{matrix_export_csr} 5543 5544\begin{mdframed}[userdefinedwidth=6in] 5545{\footnotesize 5546\begin{verbatim} 5547GrB_Info GxB_Matrix_export_CSR // export and free a CSR matrix 5548( 5549 GrB_Matrix *A, // handle of matrix to export and free 5550 GrB_Type *type, // type of matrix exported 5551 GrB_Index *nrows, // number of rows of the matrix 5552 GrB_Index *ncols, // number of columns of the matrix 5553 GrB_Index **Ap, // row "pointers", Ap_size >= (nrows+1)*sizeof(int64_t) 5554 GrB_Index **Aj, // column indices, Aj_size >= nvals(A)*sizeof(int64_t) 5555 void **Ax, // values, Ax_size >= nvals(A)*(type size) 5556 GrB_Index *Ap_size, // size of Ap in bytes 5557 GrB_Index *Aj_size, // size of Aj in bytes 5558 GrB_Index *Ax_size, // size of Ax in bytes 5559 bool *is_uniform, // if true, A has uniform values (not yet supported) 5560 bool *jumbled, // if true, indices in each row may be unsorted 5561 const GrB_Descriptor desc 5562) ; 5563 5564\end{verbatim} 5565} \end{mdframed} 5566 5567\verb'GxB_Matrix_export_CSR' exports a matrix in CSR form. 5568 5569If successful, the \verb'GrB_Matrix A' is freed, and \verb'A' is returned as 5570\verb'NULL'. Its type is returned in the \verb'type' parameter, its dimensions 5571in \verb'nrows' and \verb'ncols', and the CSR format is in the three arrays 5572\verb'Ap', \verb'Aj', and \verb'Ax'. If the matrix has no entries, the 5573\verb'Aj' and \verb'Ax' arrays may be returned as \verb'NULL'; this is not an 5574error, and \verb'GxB_Matrix_import_CSR' also allows these two arrays to be 5575\verb'NULL' on input when the matrix has no entries. After a successful 5576export, the user application is responsible for freeing these three arrays via 5577\verb'free' (or the \verb'free' function passed to \verb'GxB_init'). The CSR 5578format is described in Section~\ref{matrix_import_csr}. 5579 5580If \verb'jumbled' is returned as \verb'false', column indices will appear in 5581ascending order within each row. If \verb'jumbled' is returned as \verb'true', 5582column indices may appear in any order within each row. If \verb'jumbled' is 5583passed in as \verb'NULL', then column indices will be returned in ascending 5584order in each row. No duplicate column indices will appear in any row. 5585\verb'Ap [0]' is zero, and \verb'Ap [nrows]' is equal to the number of entries 5586in the matrix (\verb'nvals'). The \verb'Ap' array will be of size 5587\verb'nrows'+1 (or larger), and the \verb'Aj' and \verb'Ax' arrays will have 5588size at least \verb'nvals'. 5589 5590This method takes $O(1)$ time if the matrix is already in CSR format 5591internally. Otherwise, the matrix is converted to CSR format and then 5592exported. 5593 5594\newpage 5595%------------------------------------------------------------------------------- 5596\subsubsection{{\sf GxB\_Matrix\_import\_CSC:} import a CSC matrix} 5597%------------------------------------------------------------------------------- 5598\label{matrix_import_csc} 5599 5600\begin{mdframed}[userdefinedwidth=6in] 5601{\footnotesize 5602\begin{verbatim} 5603GrB_Info GxB_Matrix_import_CSC // import a CSC matrix 5604( 5605 GrB_Matrix *A, // handle of matrix to create 5606 GrB_Type type, // type of matrix to create 5607 GrB_Index nrows, // number of rows of the matrix 5608 GrB_Index ncols, // number of columns of the matrix 5609 GrB_Index **Ap, // col "pointers", Ap_size >= (ncols+1)*sizeof(int64_t) 5610 GrB_Index **Ai, // row indices, Ai_size >= nvals(A)*sizeof(int64_t) 5611 void **Ax, // values, Ax_size >= nvals(A) * (type size) 5612 GrB_Index Ap_size, // size of Ap in bytes 5613 GrB_Index Ai_size, // size of Ai in bytes 5614 GrB_Index Ax_size, // size of Ax in bytes 5615 bool is_uniform, // if true, A has uniform values (not yet supported) 5616 bool jumbled, // if true, indices in each column may be unsorted 5617 const GrB_Descriptor desc 5618) ; 5619\end{verbatim} 5620} \end{mdframed} 5621 5622\verb'GxB_Matrix_import_CSC' imports a matrix from 3 user arrays in CSC format. 5623The \verb'GrB_Matrix A' is created in the \verb'CSC' format, which is a 5624\verb'GxB_FORMAT' of \verb'GxB_BY_COL'. The arguments are identical to 5625\verb'GxB_Matrix_import_CSR', except for how the 3 user arrays are 5626interpreted. The column ``pointer'' array has size \verb'ncols+1'. The row 5627indices of the columns are in \verb'Ai', and must appear in ascending order in 5628each column. The corresponding numerical values are held in \verb'Ax'. The 5629row indices of column \verb'j' are held in \verb'Ai [Ap [j]...Ap [j+1]-1]', 5630and the corresponding numerical values are in the same locations in \verb'Ax'. 5631 5632The same matrix from Equation~\ref{eqn:Aexample}in 5633the last section (repeated here): 5634 5635 \begin{equation} 5636 A = \left[ 5637 \begin{array}{cccc} 5638 4.5 & 0 & 3.2 & 0 \\ 5639 3.1 & 2.9 & 0 & 0.9 \\ 5640 0 & 1.7 & 3.0 & 0 \\ 5641 3.5 & 0.4 & 0 & 1.0 \\ 5642 \end{array} 5643 \right] 5644 \end{equation} 5645 5646is held in CSC form as follows: 5647 5648{\footnotesize 5649\begin{verbatim} 5650 int64_t Ap [ ] = { 0, 3, 6, 8, 10 } ; 5651 int64_t Ai [ ] = { 0, 1, 3, 1, 2, 3, 0, 2, 1, 3 } ; 5652 double Ax [ ] = { 4.5, 3.1, 3.5, 2.9, 1.7, 0.4, 3.2, 3.0, 0.9, 1.0 } ; \end{verbatim} } 5653 5654That is, the row indices of column 1 (the second column) are in 5655\verb'Ai [3..5]', and the values in the same place in \verb'Ax', 5656since \verb'Ap [1] = 3' and \verb'Ap [2]-1 = 5'. 5657 5658To iterate over the columns and entries of this matrix, the following code can 5659be used 5660(assuming it has type \verb'GrB_FP64'): 5661 5662 {\footnotesize 5663 \begin{verbatim} 5664 int64_t nvals = Ap [ncols] ; 5665 for (int64_t j = 0 ; j < ncols ; j++) 5666 { 5667 // get A(:,j) 5668 for (int64_t p = Ap [j] ; p < Ap [j+1] ; p++) 5669 { 5670 // get A(i,j) 5671 int64_t i = Ai [p] ; // row index 5672 double aij = Ax [is_uniform ? 0 : p] ; // numerical value 5673 } 5674 } \end{verbatim}} 5675 5676The method is identical to \verb'GxB_Matrix_import_CSR'; just the format is 5677transposed. 5678 5679If \verb'Ap [ncols]' is zero, then the content of the \verb'Ai' and \verb'Ax' arrays 5680is not accessed and they may be \verb'NULL' on input (if not \verb'NULL', they 5681are still freed and returned as \verb'NULL', if the method is successful). 5682 5683\newpage 5684%------------------------------------------------------------------------------- 5685\subsubsection{{\sf GxB\_Matrix\_export\_CSC:} export a CSC matrix} 5686%------------------------------------------------------------------------------- 5687\label{matrix_export_csc} 5688 5689\begin{mdframed}[userdefinedwidth=6in] 5690{\footnotesize 5691\begin{verbatim} 5692GrB_Info GxB_Matrix_export_CSC // export and free a CSC matrix 5693( 5694 GrB_Matrix *A, // handle of matrix to export and free 5695 GrB_Type *type, // type of matrix exported 5696 GrB_Index *nrows, // number of rows of the matrix 5697 GrB_Index *ncols, // number of columns of the matrix 5698 GrB_Index **Ap, // column "pointers", Ap_size >= ncols+1 5699 GrB_Index **Ai, // row indices, Ai_size >= nvals(A)*sizeof(int64_t) 5700 void **Ax, // values, Ax_size >= nvals(A)*(type size) 5701 GrB_Index *Ap_size, // size of Ap in bytes 5702 GrB_Index *Ai_size, // size of Ai in bytes 5703 GrB_Index *Ax_size, // size of Ax in bytes 5704 bool *is_uniform, // if true, A has uniform values (not yet supported) 5705 bool *jumbled, // if true, indices in each column may be unsorted 5706 const GrB_Descriptor desc 5707) ; 5708\end{verbatim} 5709} \end{mdframed} 5710 5711\verb'GxB_Matrix_export_CSC' exports a matrix in CSC form. 5712 5713If successful, the \verb'GrB_Matrix A' is freed, and \verb'A' is returned as 5714\verb'NULL'. Its type is returned in the \verb'type' parameter, its dimensions 5715in \verb'nrows' and \verb'ncols', and the CSC format is in the three arrays 5716\verb'Ap', \verb'Ai', and \verb'Ax'. If the matrix has no entries, \verb'Ai' 5717and \verb'Ax' arrays are returned as \verb'NULL'; this is not an error, and 5718\verb'GxB_Matrix_import_CSC' also allows these two arrays to be \verb'NULL' on 5719input when the matrix has no entries. After a successful export, the user 5720application is responsible for freeing these three arrays via \verb'free' (or 5721the \verb'free' function passed to \verb'GxB_init'). The CSC format is 5722described in Section~\ref{matrix_import_csc}. 5723 5724This method takes $O(1)$ time if the matrix is already in CSC format 5725internally. Otherwise, the matrix is converted to CSC format and then 5726exported. 5727 5728\newpage 5729%------------------------------------------------------------------------------- 5730\subsubsection{{\sf GxB\_Matrix\_import\_HyperCSR:} import a HyperCSR matrix} 5731%------------------------------------------------------------------------------- 5732\label{matrix_import_hypercsr} 5733 5734\begin{mdframed}[userdefinedwidth=6in] 5735{\footnotesize 5736\begin{verbatim} 5737GrB_Info GxB_Matrix_import_HyperCSR // import a hypersparse CSR matrix 5738( 5739 GrB_Matrix *A, // handle of matrix to create 5740 GrB_Type type, // type of matrix to create 5741 GrB_Index nrows, // number of rows of the matrix 5742 GrB_Index ncols, // number of columns of the matrix 5743 GrB_Index **Ap, // row "pointers", Ap_size >= (nvec+1)*sizeof(int64_t) 5744 GrB_Index **Ah, // row indices, Ah_size >= (nvec)*sizeof(int64_t) 5745 GrB_Index **Aj, // column indices, Aj_size >= nvals(A)*sizeof(int64_t) 5746 void **Ax, // values, Ax_size >= nvals(A) * (type size) 5747 GrB_Index Ap_size, // size of Ap in bytes 5748 GrB_Index Ah_size, // size of Ah in bytes 5749 GrB_Index Aj_size, // size of Aj in bytes 5750 GrB_Index Ax_size, // size of Ax in bytes 5751 bool is_uniform, // if true, A has uniform values (not yet supported) 5752 GrB_Index nvec, // number of rows that appear in Ah 5753 bool jumbled, // if true, indices in each row may be unsorted 5754 const GrB_Descriptor desc 5755) ; 5756\end{verbatim} 5757} \end{mdframed} 5758 5759\verb'GxB_Matrix_import_HyperCSR' imports a matrix in hypersparse CSR format. 5760The hypersparse HyperCSR format is identical to the CSR format, except that the 5761\verb'Ap' array itself becomes sparse, if the matrix has rows that are 5762completely empty. An array \verb'Ah' of size \verb'nvec' provides a list of 5763rows that appear in the data structure. For example, consider 5764Equation~\ref{eqn:Ahyper}, which is a sparser version of the matrix in 5765Equation~\ref{eqn:Aexample}. Row 2 and column 1 of this matrix are all zero. 5766 5767 \begin{equation} 5768 \label{eqn:Ahyper} 5769 A = \left[ 5770 \begin{array}{cccc} 5771 4.5 & 0 & 3.2 & 0 \\ 5772 3.1 & 0 & 0 & 0.9 \\ 5773 0 & 0 & 0 & 0 \\ 5774 3.5 & 0 & 0 & 1.0 \\ 5775 \end{array} 5776 \right] 5777 \end{equation} 5778 5779The conventional CSR format would appear as follows. Since the third row (row 57802) is all zero, accessing \verb'Ai [Ap [2] ... Ap [3]-1]' gives an empty set 5781(\verb'[2..1]'), and the number of entries in this row is 5782\verb'Ap [i+1] - Ap [i]' \verb'= Ap [3] - Ap [2] = 0'. 5783 5784{\footnotesize 5785\begin{verbatim} 5786 int64_t Ap [ ] = { 0, 2,2, 4, 5 } ; 5787 int64_t Aj [ ] = { 0, 2, 0, 3, 0 3 } 5788 double Ax [ ] = { 4.5, 3.2, 3.1, 0.9, 3.5, 1.0 } ; \end{verbatim} } 5789 5790A hypersparse CSR format for this same matrix would discard 5791these duplicate integers in \verb'Ap'. Doing so requires 5792another array, \verb'Ah', that keeps track of the rows that appear 5793in the data structure. 5794 5795{\footnotesize 5796\begin{verbatim} 5797 int64_t nvec = 3 ; 5798 int64_t Ah [ ] = { 0, 1, 3 } ; 5799 int64_t Ap [ ] = { 0, 2, 4, 5 } ; 5800 int64_t Aj [ ] = { 0, 2, 0, 3, 0 3 } 5801 double Ax [ ] = { 4.5, 3.2, 3.1, 0.9, 3.5, 1.0 } ; \end{verbatim} } 5802 5803Note that the \verb'Aj' and \verb'Ax' arrays are the same in the CSR and 5804HyperCSR formats. The row indices in \verb'Ah' must appear in ascending 5805order, and no duplicates can appear. To iterate over this data structure 5806(assuming it has type \verb'GrB_FP64'): 5807 5808 {\footnotesize 5809 \begin{verbatim} 5810 int64_t nvals = Ap [nvec] ; 5811 for (int64_t k = 0 ; k < nvec ; k++) 5812 { 5813 int64_t i = Ah [k] ; // row index 5814 // get A(i,:) 5815 for (int64_t p = Ap [k] ; p < Ap [k+1] ; p++) 5816 { 5817 // get A(i,j) 5818 int64_t j = Aj [p] ; // column index 5819 double aij = Ax [is_uniform ? 0 : p] ; // numerical value 5820 } 5821 } \end{verbatim}} 5822 5823\vspace{-0.05in} 5824This is more complex than the CSR format, but it requires at most 5825$O(e)$ space, where $A$ is $m$-by-$n$ with $e$ = \verb'nvals' entries. The 5826CSR format requires $O(m+e)$ space. If $e << m$, then the size $m+1$ 5827of \verb'Ap' can dominate the memory required. In the hypersparse form, 5828\verb'Ap' takes on size \verb'nvec+1', and \verb'Ah' has size \verb'nvec', 5829where \verb'nvec' is the number of rows that appear in the data structure. 5830The CSR format can be viewed as a dense array (of size \verb'nrows') 5831of sparse row vectors. By contrast, the hypersparse CSR format is a sparse 5832array (of size \verb'nvec') of sparse row vectors. 5833 5834The import takes $O(1)$ time. If successful, the four arrays \verb'Ah', 5835\verb'Ap', \verb'Aj', and \verb'Ax' are returned as \verb'NULL', and the 5836hypersparse \verb'GrB_Matrix A' is created. 5837 5838If the matrix has no entries, then the content of the \verb'Aj' and \verb'Ax' arrays 5839is not accessed and they may be \verb'NULL' on input (if not \verb'NULL', they 5840are still freed and returned as \verb'NULL', if the method is successful). 5841 5842\newpage 5843%------------------------------------------------------------------------------- 5844\subsubsection{{\sf GxB\_Matrix\_export\_HyperCSR:} export a HyperCSR matrix} 5845%------------------------------------------------------------------------------- 5846\label{matrix_export_hypercsr} 5847 5848\begin{mdframed}[userdefinedwidth=6in] 5849{\footnotesize 5850\begin{verbatim} 5851GrB_Info GxB_Matrix_export_HyperCSR // export and free a hypersparse CSR matrix 5852( 5853 GrB_Matrix *A, // handle of matrix to export and free 5854 GrB_Type *type, // type of matrix exported 5855 GrB_Index *nrows, // number of rows of the matrix 5856 GrB_Index *ncols, // number of columns of the matrix 5857 GrB_Index **Ap, // row "pointers", Ap_size >= (nvec+1)*sizeof(int64_t) 5858 GrB_Index **Ah, // row indices, Ah_size >= nvec*sizeof(int64_t) 5859 GrB_Index **Aj, // column indices, Aj_size >= nvals(A)*sizeof(int64_t) 5860 void **Ax, // values, Ax_size >= nvals(A)*(type size) 5861 GrB_Index *Ap_size, // size of Ap in bytes 5862 GrB_Index *Ah_size, // size of Ah in bytes 5863 GrB_Index *Aj_size, // size of Aj in bytes 5864 GrB_Index *Ax_size, // size of Ax in bytes 5865 bool *is_uniform, // if true, A has uniform values (not yet supported) 5866 GrB_Index *nvec, // number of rows that appear in Ah 5867 bool *jumbled, // if true, indices in each row may be unsorted 5868 const GrB_Descriptor desc 5869) ; 5870\end{verbatim} 5871} \end{mdframed} 5872 5873\verb'GxB_Matrix_export_HyperCSR' exports a matrix in HyperCSR format. 5874 5875If successful, the \verb'GrB_Matrix A' is freed, and \verb'A' is returned as 5876\verb'NULL'. Its type is returned in the \verb'type' parameter, its dimensions 5877in \verb'nrows' and \verb'ncols'. and the number of non-empty rows in 5878\verb'nvec'. The hypersparse CSR format is in the four arrays \verb'Ah', 5879\verb'Ap', \verb'Aj', and \verb'Ax'. If the matrix has no entries, the 5880\verb'Aj' and \verb'Ax' arrays are returned as \verb'NULL'; this is not an 5881error. After a successful export, the user application is responsible for 5882freeing these three arrays via \verb'free' (or the \verb'free' function passed 5883to \verb'GxB_init'). The hypersparse CSR format is described in 5884Section~\ref{matrix_import_hypercsr}. 5885 5886This method takes $O(1)$ time if the matrix is already in HyperCSR format 5887internally. Otherwise, the matrix is converted to HyperCSR format and then 5888exported. 5889 5890\newpage 5891%------------------------------------------------------------------------------- 5892\subsubsection{{\sf GxB\_Matrix\_import\_HyperCSC:} import a HyperCSC matrix} 5893%------------------------------------------------------------------------------- 5894\label{matrix_import_hypercsc} 5895 5896\begin{mdframed}[userdefinedwidth=6in] 5897{\footnotesize 5898\begin{verbatim} 5899GrB_Info GxB_Matrix_import_HyperCSC // import a hypersparse CSC matrix 5900( 5901 GrB_Matrix *A, // handle of matrix to create 5902 GrB_Type type, // type of matrix to create 5903 GrB_Index nrows, // number of rows of the matrix 5904 GrB_Index ncols, // number of columns of the matrix 5905 GrB_Index **Ap, // col "pointers", Ap_size >= (nvec+1)*sizeof(int64_t) 5906 GrB_Index **Ah, // column indices, Ah_size >= nvec*sizeof(int64_t) 5907 GrB_Index **Ai, // row indices, Ai_size >= nvals(A)*sizeof(int64_t) 5908 void **Ax, // values, Ax_size >= nvals(A)*(type size) 5909 GrB_Index Ap_size, // size of Ap in bytes 5910 GrB_Index Ah_size, // size of Ah in bytes 5911 GrB_Index Ai_size, // size of Ai in bytes 5912 GrB_Index Ax_size, // size of Ax in bytes 5913 bool is_uniform, // if true, A has uniform values (not yet supported) 5914 GrB_Index nvec, // number of columns that appear in Ah 5915 bool jumbled, // if true, indices in each column may be unsorted 5916 const GrB_Descriptor desc 5917) ; 5918\end{verbatim} 5919} \end{mdframed} 5920 5921\verb'GxB_Matrix_import_HyperCSC' imports a matrix in hypersparse CSC format. 5922It is identical to \verb'GxB_Matrix_import_HyperCSR', except the data 5923structure defined by the four arrays \verb'Ah', \verb'Ap', \verb'Ai', and 5924\verb'Ax' holds the matrix as a sparse array of \verb'nvec' sparse column 5925vectors. The following code iterates over the matrix, 5926assuming it has type \verb'GrB_FP64': 5927 5928 \vspace{-0.10in} 5929 {\footnotesize 5930 \begin{verbatim} 5931 int64_t nvals = Ap [nvec] ; 5932 for (int64_t k = 0 ; k < nvec ; k++) 5933 { 5934 int64_t j = Ah [k] ; // column index 5935 // get A(:,j) 5936 for (int64_t p = Ap [k] ; p < Ap [k+1] ; p++) 5937 { 5938 // get A(i,j) 5939 int64_t i = Ai [p] ; // row index 5940 double aij = Ax [is_uniform ? 0 : p] ; // numerical value 5941 } 5942 } \end{verbatim}} 5943 5944\newpage 5945%------------------------------------------------------------------------------- 5946\subsubsection{{\sf GxB\_Matrix\_export\_HyperCSC:} export a HyperCSC matrix} 5947%------------------------------------------------------------------------------- 5948\label{matrix_export_hypercsc} 5949 5950\begin{mdframed}[userdefinedwidth=6in] 5951{\footnotesize 5952\begin{verbatim} 5953GrB_Info GxB_Matrix_export_HyperCSC // export and free a hypersparse CSC matrix 5954( 5955 GrB_Matrix *A, // handle of matrix to export and free 5956 GrB_Type *type, // type of matrix exported 5957 GrB_Index *nrows, // number of rows of the matrix 5958 GrB_Index *ncols, // number of columns of the matrix 5959 GrB_Index **Ap, // column "pointers", Ap_size >= nvec+1 5960 GrB_Index **Ah, // column indices, Ah_size >= nvec 5961 GrB_Index **Ai, // row indices, Ai_size >= nvals(A) 5962 void **Ax, // values, Ax_size >= nvals(A) 5963 GrB_Index *Ap_size, // size of Ap 5964 GrB_Index *Ah_size, // size of Ah 5965 GrB_Index *Ai_size, // size of Ai 5966 GrB_Index *Ax_size, // size of Ax 5967 bool *is_uniform, // if true, A has uniform values (not yet supported) 5968 GrB_Index *nvec, // number of columns that appear in Ah 5969 bool *jumbled, // if true, indices in each column may be unsorted 5970 const GrB_Descriptor desc 5971) ; 5972\end{verbatim} 5973} \end{mdframed} 5974 5975\verb'GxB_Matrix_export_HyperCSC' exports a matrix in HyperCSC form. 5976 5977If successful, the \verb'GrB_Matrix A' is freed, and \verb'A' is 5978returned as \verb'NULL'. Its type is returned in the \verb'type' parameter, 5979its dimensions in \verb'nrows' and \verb'ncols', and the number of non-empty 5980rows in \verb'nvec'. The hypersparse CSC format is in the four arrays 5981\verb'Ah', \verb'Ap', \verb'Ai', and \verb'Ax'. If the matrix has no entries, 5982the \verb'Ai' and \verb'Ax' arrays are returned as \verb'NULL'; this is not an 5983error. After a successful export, the user application is responsible for 5984freeing these three arrays via \verb'free' (or the \verb'free' function passed 5985to \verb'GxB_init'). The hypersparse CSC format is described in 5986Section~\ref{matrix_import_hypercsc}. 5987 5988This method takes $O(1)$ time if the matrix is already in HyperCSC format 5989internally. Otherwise, the matrix is converted to HyperCSC format and then 5990exported. 5991 5992\newpage 5993%------------------------------------------------------------------------------- 5994\subsubsection{{\sf GxB\_Matrix\_import\_BitmapR:} import a BitmapR matrix} 5995%------------------------------------------------------------------------------- 5996\label{matrix_import_bitmapr} 5997{ 5998\begin{mdframed}[userdefinedwidth=6in] 5999{\footnotesize 6000\begin{verbatim} 6001GrB_Info GxB_Matrix_import_BitmapR // import a bitmap matrix, held by row 6002( 6003 GrB_Matrix *A, // handle of matrix to create 6004 GrB_Type type, // type of matrix to create 6005 GrB_Index nrows, // number of rows of the matrix 6006 GrB_Index ncols, // number of columns of the matrix 6007 int8_t **Ab, // bitmap, Ab_size >= nrows*ncols 6008 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6009 GrB_Index Ab_size, // size of Ab in bytes 6010 GrB_Index Ax_size, // size of Ax in bytes 6011 bool is_uniform, // if true, A has uniform values (not yet supported) 6012 GrB_Index nvals, // # of entries in bitmap 6013 const GrB_Descriptor desc 6014) ; 6015\end{verbatim} 6016} \end{mdframed} 6017 6018\verb'GxB_Matrix_import_BitmapR' imports a matrix from 2 user arrays in BitmapR 6019format. 6020 6021The first four arguments of \verb'GxB_Matrix_import_BitmapR' are the same as 6022all four arguments of \verb'GrB_Matrix_new', because this function is similar. 6023It creates a new \verb'GrB_Matrix A', with the given type and dimensions. 6024The \verb'GrB_Matrix A' does not exist on input. 6025 6026The \verb'GrB_Matrix' \verb'A' is created from the arrays \verb'Ab' and 6027\verb'Ax', each of which are size \verb'nrows*ncols'. Both arrays must have 6028been created with the ANSI C \verb'malloc', \verb'calloc', or \verb'realloc' 6029functions (by default), or by the corresponding \verb'malloc_function', 6030\verb'calloc_function', or \verb'realloc_function' provided to \verb'GxB_init'. 6031These arrays define the pattern and values of the new matrix \verb'A': 6032 6033\begin{itemize} 6034\item \verb'int8_t Ab [nrows*ncols] ;' The \verb'Ab' array defines which 6035entries of \verb'A' are present. If \verb'Ab[i*ncols+j]=1', then the entry 6036$A(i,j)$ is present, with value \verb'Ax[i*ncols+j]'. If 6037\verb'Ab[i*ncols+j]=0', then the entry $A(i,j)$ is not present. The \verb'Ab' 6038array must contain only 0s and 1s. The \verb'nvals' input must exactly match 6039the number of 1s in the \verb'Ab' array. 6040 6041\item \verb'ctype Ax [nrows*ncols] ;' The \verb'Ax' array defines the values 6042of entries in the matrix. It is passed in as a \verb'(void *)' pointer, but it 6043must point to an array of size \verb'nrows*ncols' values, each of size 6044\verb'sizeof(ctype)', where \verb'ctype' is the exact type in C that 6045corresponds to the \verb'GrB_Type type' parameter. That is, if \verb'type' is 6046\verb'GrB_INT32', then \verb'ctype' is \verb'int32_t'. User types may be used, 6047just the same as built-in types. 6048If \verb'Ab[p]' is zero, the value of \verb'Ax[p]' is ignored. 6049 6050\end{itemize} 6051 6052To iterate over the rows and entries of this matrix, the following code can be 6053used (assuming it has type \verb'GrB_FP64'): 6054 6055 {\footnotesize 6056 \begin{verbatim} 6057 for (int64_t i = 0 ; i < nrows ; i++) 6058 { 6059 // get A(i,:) 6060 for (int64_t j = 0 ; j < ncols ; j++) 6061 { 6062 // get A(i,j) 6063 int64_t p = i*ncols + j ; 6064 if (Ab [p]) 6065 { 6066 double aij = Ax [is_uniform ? 0 : p] ; // numerical value 6067 } 6068 } 6069 } \end{verbatim}} 6070 6071On successful creation of \verb'A', the two pointers \verb'Ab', \verb'Ax', 6072are set to \verb'NULL' on output. This denotes to the user 6073application that it is no longer responsible for freeing these arrays. 6074Internally, GraphBLAS has moved these arrays into its internal data structure. 6075They will eventually be freed no later than when the user does 6076\verb'GrB_free(&A)', but they may be freed or resized later, if the matrix 6077changes. If an export is performed, the freeing of these three arrays again 6078becomes the responsibility of the user application. 6079 6080The \verb'GxB_Matrix_import_BitmapR' function will rarely fail, since it allocates 6081just $O(1)$ space. If it does fail, it returns \verb'GrB_OUT_OF_MEMORY', 6082and it leaves the two user arrays unmodified. They are still owned by 6083the user application, which is eventually responsible for freeing them with 6084\verb'free(Ab)', etc. 6085} 6086\newpage 6087%------------------------------------------------------------------------------- 6088\subsubsection{{\sf GxB\_Matrix\_export\_BitmapR:} export a BitmapR matrix} 6089%------------------------------------------------------------------------------- 6090\label{matrix_export_bitmapr} 6091 6092\begin{mdframed}[userdefinedwidth=6in] 6093{\footnotesize 6094\begin{verbatim} 6095GrB_Info GxB_Matrix_export_BitmapR // export and free a bitmap matrix, by row 6096( 6097 GrB_Matrix *A, // handle of matrix to export and free 6098 GrB_Type *type, // type of matrix exported 6099 GrB_Index *nrows, // number of rows of the matrix 6100 GrB_Index *ncols, // number of columns of the matrix 6101 int8_t **Ab, // bitmap, Ab_size >= nrows*ncols 6102 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6103 GrB_Index *Ab_size, // size of Ab in bytes 6104 GrB_Index *Ax_size, // size of Ax in bytes 6105 bool *is_uniform, // if true, A has uniform values (not yet supported) 6106 GrB_Index *nvals, // # of entries in bitmap 6107 const GrB_Descriptor desc 6108) ; 6109\end{verbatim} 6110} \end{mdframed} 6111 6112\verb'GxB_Matrix_export_BitmapR' exports a matrix in BitmapR form. 6113 6114If successful, the \verb'GrB_Matrix A' is freed, and \verb'A' is returned as 6115\verb'NULL'. Its type is returned in the \verb'type' parameter, its dimensions 6116in \verb'nrows' and \verb'ncols', and the number of entries in \verb'nvals'. 6117 6118The BitmapR format is in the two arrays \verb'Ab', and \verb'Ax'. After a 6119successful export, the user application is responsible for freeing these three 6120arrays via \verb'free' (or the \verb'free' function passed to \verb'GxB_init'). 6121The BitmapR format is described in Section~\ref{matrix_import_bitmapr}. 6122If \verb'Ab[p]' is zero, the value of \verb'Ax[p]' is undefined. 6123 6124This method takes $O(1)$ time if the matrix is already in BitmapR format 6125internally. Otherwise, the matrix is converted to BitmapR format and then 6126exported. 6127 6128 6129\newpage 6130%------------------------------------------------------------------------------- 6131\subsubsection{{\sf GxB\_Matrix\_import\_BitmapC:} import a BitmapC matrix} 6132%------------------------------------------------------------------------------- 6133\label{matrix_import_bitmapc} 6134 6135\begin{mdframed}[userdefinedwidth=6in] 6136{\footnotesize 6137\begin{verbatim} 6138GrB_Info GxB_Matrix_import_BitmapC // import a bitmap matrix, held by column 6139( 6140 GrB_Matrix *A, // handle of matrix to create 6141 GrB_Type type, // type of matrix to create 6142 GrB_Index nrows, // number of rows of the matrix 6143 GrB_Index ncols, // number of columns of the matrix 6144 int8_t **Ab, // bitmap, Ab_size >= nrows*ncols 6145 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6146 GrB_Index Ab_size, // size of Ab in bytes 6147 GrB_Index Ax_size, // size of Ax in bytes 6148 bool is_uniform, // if true, A has uniform values (not yet supported) 6149 GrB_Index nvals, // # of entries in bitmap 6150 const GrB_Descriptor desc 6151) ; 6152\end{verbatim} 6153} \end{mdframed} 6154 6155\verb'GxB_Matrix_import_BitmapC' imports a matrix from 2 user arrays in BitmapC 6156format. It is identical to \verb'GxB_Matrix_import_BitmapR', except that the 6157entry $A(i,j)$ is held in \verb'Ab[i+j*nrows]' and \verb'Ax[i+j*nrows]', 6158in column-major format. 6159 6160%------------------------------------------------------------------------------- 6161\subsubsection{{\sf GxB\_Matrix\_export\_BitmapC:} export a BitmapC matrix} 6162%------------------------------------------------------------------------------- 6163\label{matrix_export_bitmapc} 6164 6165\begin{mdframed}[userdefinedwidth=6in] 6166{\footnotesize 6167\begin{verbatim} 6168GrB_Info GxB_Matrix_export_BitmapC // export and free a bitmap matrix, by col 6169( 6170 GrB_Matrix *A, // handle of matrix to export and free 6171 GrB_Type *type, // type of matrix exported 6172 GrB_Index *nrows, // number of rows of the matrix 6173 GrB_Index *ncols, // number of columns of the matrix 6174 int8_t **Ab, // bitmap, Ab_size >= nrows*ncols 6175 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6176 GrB_Index *Ab_size, // size of Ab in bytes 6177 GrB_Index *Ax_size, // size of Ax in bytes 6178 bool *is_uniform, // if true, A has uniform values (not yet supported) 6179 GrB_Index *nvals, // # of entries in bitmap 6180 const GrB_Descriptor desc 6181) ; 6182\end{verbatim} 6183} \end{mdframed} 6184 6185\verb'GxB_Matrix_export_BitmapC' exports a matrix in BitmapC form. 6186It is identical to \verb'GxB_Matrix_export_BitmapR', except that the 6187entry $A(i,j)$ is held in \verb'Ab[i+j*nrows]' and \verb'Ax[i+j*nrows]', 6188in column-major format. 6189 6190\newpage 6191%------------------------------------------------------------------------------- 6192\subsubsection{{\sf GxB\_Matrix\_import\_FullR:} import a FullR matrix} 6193%------------------------------------------------------------------------------- 6194\label{matrix_import_fullr} 6195 6196\begin{mdframed}[userdefinedwidth=6in] 6197{\footnotesize 6198\begin{verbatim} 6199GrB_Info GxB_Matrix_import_FullR // import a full matrix, held by row 6200( 6201 GrB_Matrix *A, // handle of matrix to create 6202 GrB_Type type, // type of matrix to create 6203 GrB_Index nrows, // number of rows of the matrix 6204 GrB_Index ncols, // number of columns of the matrix 6205 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6206 GrB_Index Ax_size, // size of Ax in bytes 6207 bool is_uniform, // if true, A has uniform values (not yet supported) 6208 const GrB_Descriptor desc 6209) ; 6210\end{verbatim} 6211} \end{mdframed} 6212 6213\verb'GxB_Matrix_import_FullR' imports a matrix from a user arrays in FullR 6214format. The \verb'FullR' format is identical to \verb'BitmapR', except that 6215all entries are present. The value of $A(i,j)$ is \verb'Ax[i*ncols+j]'. 6216 6217To iterate over the rows and entries of this matrix, the following code can be 6218used (assuming it has type \verb'GrB_FP64'): 6219 6220 {\footnotesize 6221 \begin{verbatim} 6222 for (int64_t i = 0 ; i < nrows ; i++) 6223 { 6224 // get A(i,:) 6225 for (int64_t j = 0 ; j < ncols ; j++) 6226 { 6227 // get A(i,j) 6228 int64_t p = i*ncols + j ; 6229 double aij = Ax [is_uniform ? 0 : p] ; // numerical value 6230 } 6231 } \end{verbatim}} 6232 6233\newpage 6234%------------------------------------------------------------------------------- 6235\subsubsection{{\sf GxB\_Matrix\_export\_FullR:} export a FullR matrix} 6236%------------------------------------------------------------------------------- 6237\label{matrix_export_fullr} 6238 6239\begin{mdframed}[userdefinedwidth=6in] 6240{\footnotesize 6241\begin{verbatim} 6242GrB_Info GxB_Matrix_export_FullR // export and free a full matrix, by row 6243( 6244 GrB_Matrix *A, // handle of matrix to export and free 6245 GrB_Type *type, // type of matrix exported 6246 GrB_Index *nrows, // number of rows of the matrix 6247 GrB_Index *ncols, // number of columns of the matrix 6248 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6249 GrB_Index *Ax_size, // size of Ax in bytes 6250 bool *is_uniform, // if true, A has uniform values (not yet supported) 6251 const GrB_Descriptor desc 6252) ; 6253\end{verbatim} 6254} \end{mdframed} 6255 6256\verb'GxB_Matrix_export_FullR' exports a matrix in FullR form. It is identical 6257to \verb'GxB_Matrix_export_BitmapR', except that all entries must be present. 6258 6259That is, prior to export, \verb'GrB_Matrix_nvals (&nvals, A)' must return 6260\verb'nvals' equal to \verb'nrows*ncols'. Otherwise, if the \verb'A' is 6261exported with \newline \verb'GxB_Matrix_export_FullR', an error is returned 6262(\verb'GrB_INVALID_VALUE') and the matrix is not exported. 6263 6264\newpage 6265%------------------------------------------------------------------------------- 6266\subsubsection{{\sf GxB\_Matrix\_import\_FullC:} import a FullC matrix} 6267%------------------------------------------------------------------------------- 6268\label{matrix_import_fullc} 6269 6270\begin{mdframed}[userdefinedwidth=6in] 6271{\footnotesize 6272\begin{verbatim} 6273GrB_Info GxB_Matrix_import_FullC // import a full matrix, held by column 6274( 6275 GrB_Matrix *A, // handle of matrix to create 6276 GrB_Type type, // type of matrix to create 6277 GrB_Index nrows, // number of rows of the matrix 6278 GrB_Index ncols, // number of columns of the matrix 6279 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6280 GrB_Index Ax_size, // size of Ax in bytes 6281 bool is_uniform, // if true, A has uniform values (not yet supported) 6282 const GrB_Descriptor desc 6283) ; 6284\end{verbatim} 6285} \end{mdframed} 6286 6287\verb'GxB_Matrix_import_FullC' imports a matrix from a user arrays in FullC 6288format. The \verb'FullC' format is identical to \verb'BitmapC', except that 6289all entries are present. The value of $A(i,j)$ is \verb'Ax[i+j*nrows]'. 6290 6291To iterate over the rows and entries of this matrix, the following code can be 6292used (assuming it has type \verb'GrB_FP64'): 6293 6294 {\footnotesize 6295 \begin{verbatim} 6296 for (int64_t i = 0 ; i < nrows ; i++) 6297 { 6298 // get A(i,:) 6299 for (int64_t j = 0 ; j < ncols ; j++) 6300 { 6301 // get A(i,j) 6302 int64_t p = i + j*nrows ; 6303 double aij = Ax [is_uniform ? 0 : p] ; // numerical value 6304 } 6305 } \end{verbatim}} 6306 6307Note that the \verb'is_uniform' feature is not yet implemented. Once it is 6308added to SuiteSparse:GraphBLAS, a full matrix with uniform values will take 6309only $O(1)$ time and memory to create and hold in memory. Some operations 6310need not traverse over all entries of the matrix, and these operations will 6311be very fast with full matrices with uniform values. 6312 6313\newpage 6314%------------------------------------------------------------------------------- 6315\subsubsection{{\sf GxB\_Matrix\_export\_FullC:} export a FullC matrix} 6316%------------------------------------------------------------------------------- 6317\label{matrix_export_fullc} 6318 6319\begin{mdframed}[userdefinedwidth=6in] 6320{\footnotesize 6321\begin{verbatim} 6322GrB_Info GxB_Matrix_export_FullC // export and free a full matrix, by column 6323( 6324 GrB_Matrix *A, // handle of matrix to export and free 6325 GrB_Type *type, // type of matrix exported 6326 GrB_Index *nrows, // number of rows of the matrix 6327 GrB_Index *ncols, // number of columns of the matrix 6328 void **Ax, // values, Ax_size >= nrows*ncols * (type size) 6329 GrB_Index *Ax_size, // size of Ax in bytes 6330 bool *is_uniform, // if true, A has uniform values (not yet supported) 6331 const GrB_Descriptor desc 6332) ; 6333\end{verbatim} 6334} \end{mdframed} 6335 6336\verb'GxB_Matrix_export_FullC' exports a matrix in FullC form. It is identical 6337to \verb'GxB_Matrix_export_BitmapC', except that all entries must be present. 6338 6339That is, prior to export, \verb'GrB_Matrix_nvals (&nvals, A)' must return 6340\verb'nvals' equal to \verb'nrows*ncols'. Otherwise, if the \verb'A' is 6341exported with \newline \verb'GxB_Matrix_export_FullC', an error is returned 6342(\verb'GrB_INVALID_VALUE') and the matrix is not exported. 6343 6344\newpage 6345%=============================================================================== 6346\subsection{GraphBLAS descriptors: {\sf GrB\_Descriptor}} %===================== 6347%=============================================================================== 6348\label{descriptor} 6349 6350A GraphBLAS {\em descriptor} modifies the behavior of a GraphBLAS operation. 6351If the descriptor is \verb'GrB_NULL', defaults are used. 6352 6353The access to these parameters and their values is governed 6354by two \verb'enum' types, \verb'GrB_Desc_Field' and \verb'GrB_Desc_Value': 6355 6356\begin{mdframed}[userdefinedwidth=6in] 6357{\footnotesize 6358\begin{verbatim} 6359#define GxB_NTHREADS 5 // for both GrB_Desc_field and GxB_Option_field 6360#define GxB_CHUNK 7 6361typedef enum 6362{ 6363 GrB_OUTP = 0, // descriptor for output of a method 6364 GrB_MASK = 1, // descriptor for the mask input of a method 6365 GrB_INP0 = 2, // descriptor for the first input of a method 6366 GrB_INP1 = 3, // descriptor for the second input of a method 6367 GxB_DESCRIPTOR_NTHREADS = GxB_NTHREADS, // number of threads to use 6368 GxB_DESCRIPTOR_CHUNK = GxB_CHUNK, // chunk size for small problems 6369 GxB_AxB_METHOD = 1000, // descriptor for selecting C=A*B algorithm 6370 GxB_SORT = 35 // control sort in GrB_mxm 6371} 6372GrB_Desc_Field ; 6373 6374typedef enum 6375{ 6376 // for all GrB_Descriptor fields: 6377 GxB_DEFAULT = 0, // default behavior of the method 6378 // for GrB_OUTP only: 6379 GrB_REPLACE = 1, // clear the output before assigning new values to it 6380 // for GrB_MASK only: 6381 GrB_COMP = 2, // use the complement of the mask 6382 GrB_STRUCTURE = 4, // use the structure of the mask 6383 // for GrB_INP0 and GrB_INP1 only: 6384 GrB_TRAN = 3, // use the transpose of the input 6385 // for GxB_AxB_METHOD only: 6386 GxB_AxB_GUSTAVSON = 1001, // gather-scatter saxpy method 6387 GxB_AxB_DOT = 1003, // dot product 6388 GxB_AxB_HASH = 1004, // hash-based saxpy method 6389 GxB_AxB_SAXPY = 1005 // saxpy method (any kind) 6390} 6391GrB_Desc_Value ; 6392\end{verbatim} } \end{mdframed} 6393 6394\newpage 6395 6396\begin{itemize} 6397\item \verb'GrB_OUTP' is a parameter that modifies the output of a 6398 GraphBLAS operation. In the 6399 default case, the output is not cleared, and ${\bf C \langle M \rangle = Z 6400 = C \odot T}$ is computed as-is, where ${\bf T}$ is the results of the 6401 particular GraphBLAS operation. 6402 6403 In the non-default case, ${\bf Z = C \odot T}$ is first computed, using the 6404 results of ${\bf T}$ and the accumulator $\odot$. After this is done, if 6405 the \verb'GrB_OUTP' descriptor field is set to \verb'GrB_REPLACE', then the 6406 output is cleared of its entries. Next, the assignment ${\bf C \langle M 6407 \rangle = Z}$ is performed. 6408 6409\item \verb'GrB_MASK' is a parameter that modifies the \verb'Mask', 6410 even if the mask is not present. 6411 6412 If this parameter is set to its default value, and if the mask is not 6413 present (\verb'Mask==NULL') then implicitly \verb'Mask(i,j)=1' for all 6414 \verb'i' and \verb'j'. If the mask is present then \verb'Mask(i,j)=1' 6415 means that \verb'C(i,j)' is to be modified by the ${\bf C \langle M \rangle 6416 = Z}$ update. Otherwise, if \verb'Mask(i,j)=0', then \verb'C(i,j)' is not 6417 modified, even if \verb'Z(i,j)' is an entry with a different value; that 6418 value is simply discarded. 6419 6420 If the \verb'GrB_MASK' parameter is set to \verb'GrB_COMP', then the 6421 use of the mask is complemented. In this case, if the mask is not present 6422 (\verb'Mask==NULL') then implicitly \verb'Mask(i,j)=0' for all \verb'i' and 6423 \verb'j'. This means that none of ${\bf C}$ is modified and the entire 6424 computation of ${\bf Z}$ might as well have been skipped. That is, a 6425 complemented empty mask means no modifications are made to the output 6426 object at all, except perhaps to clear it in accordance with the 6427 \verb'GrB_OUTP' descriptor. With a complemented mask, if the mask is 6428 present then \verb'Mask(i,j)=0' means that \verb'C(i,j)' is to be modified 6429 by the ${\bf C \langle M \rangle = Z}$ update. Otherwise, if 6430 \verb'Mask(i,j)=1', then \verb'C(i,j)' is not modified, even if 6431 \verb'Z(i,j)' is an entry with a different value; that value is simply 6432 discarded. 6433 6434 If the \verb'GrB_MASK' parameter is set to \verb'GrB_STRUCTURE', 6435 then the values of the mask are ignored, and just the pattern of the 6436 entries is used. Any entry \verb'M(i,j)' in the pattern is treated as if 6437 it were true. 6438 6439 The \verb'GrB_COMP' and \verb'GrB_STRUCTURE' settings can be combined, 6440 either by setting the mask option twice (once with each value), or by 6441 setting the mask option to \verb'GrB_COMP+GrB_STRUCTURE' (the latter is an 6442 extension to the spec). 6443 6444 Using a parameter to complement the \verb'Mask' is very useful because 6445 constructing the actual complement of a very sparse mask is impossible 6446 since it has too many entries. If the number of places in \verb'C' 6447 that should be modified is very small, then use a sparse mask without 6448 complementing it. If the number of places in \verb'C' that should 6449 be protected from modification is very small, then use a sparse mask 6450 to indicate those places, and use a descriptor \verb'GrB_MASK' that 6451 complements the use of the mask. 6452 6453\item \verb'GrB_INP0' and \verb'GrB_INP1' modify the use of the 6454 first and second input matrices \verb'A' and \verb'B' of the GraphBLAS 6455 operation. 6456 6457 If the \verb'GrB_INP0' is set to \verb'GrB_TRAN', then \verb'A' is 6458 transposed before using it in the operation. Likewise, if 6459 \verb'GrB_INP1' is set to \verb'GrB_TRAN', then the second input, 6460 typically called \verb'B', is transposed. 6461 6462 Vectors and scalars are never transposed via the descriptor. If a method's 6463 first parameter is a matrix and the second a vector or scalar, then 6464 \verb'GrB_INP0' modifies the matrix parameter and 6465 \verb'GrB_INP1' is ignored. If a method's first parameter is a 6466 vector or scalar and the second a matrix, then \verb'GrB_INP1' 6467 modifies the matrix parameter and \verb'GrB_INP0' is ignored. 6468 6469 To clarify this in each function, the inputs are labeled as 6470 \verb'first input:' and \verb'second input:' in the function signatures. 6471 6472\item \verb'GxB_AxB_METHOD' suggests the method that should be 6473 used to compute \verb'C=A*B'. All the methods compute the same result, 6474 except they may have different floating-point roundoff errors. This 6475 descriptor should be considered as a hint; SuiteSparse:GraphBLAS is 6476 free to ignore it. 6477 6478 \begin{itemize} 6479 6480 \item \verb'GxB_DEFAULT' means that a method is selected automatically. 6481 6482 \item \verb'GxB_AxB_SAXPY': select any saxpy-based method: 6483 \verb'GxB_AxB_GUSTAVSON', and/or 6484 \verb'GxB_AxB_HASH', or any mix of the two, 6485 in contrast to the dot-product method. 6486 6487 \item \verb'GxB_AxB_GUSTAVSON': an extended version of Gustavson's method 6488 \cite{Gustavson78}, which is a very good general-purpose method, but 6489 sometimes the workspace can be too large. Assuming all matrices are stored 6490 by column, it computes \verb'C(:,j)=A*B(:,j)' with a sequence of {\em 6491 saxpy} operations (\verb'C(:,j)+=A(:,k)*B(k:,j)' for each nonzero 6492 \verb'B(k,j)'). In the {\em coarse Gustavson} method, each internal thread 6493 requires workspace of size $m$, to the number of rows of \verb'C', which is 6494 not suitable if the matrices are extremely sparse or if there are many 6495 threads. For the {\em fine Gustavson} method, threads can share workspace 6496 and update it via atomic operations. If all matrices are stored by row, 6497 then it computes \verb'C(i,:)=A(i,:)*B' in a sequence of sparse {\em saxpy} 6498 operations, and using workspace of size $n$ per thread, or group of 6499 threads, corresponding to the number of columns of \verb'C'. 6500 6501 \item \verb'GxB_AxB_HASH': a hash-based method, based on 6502 \cite{10.1145/3229710.3229720}. It is very efficient for hypersparse 6503 matrices, matrix-vector-multiply, and when $|{\bf B}|$ is small. 6504 SuiteSparse:GraphBLAS includes a {\em coarse hash} method, in which 6505 each thread has its own hash workspace, and a {\em fine hash} 6506 method, in which groups of threads share a single hash workspace, 6507 as concurrent data structure, using atomics. 6508 6509% [2] Yusuke Nagasaka, Satoshi Matsuoka, Ariful Azad, and Aydın Buluç. 2018. 6510% High-Performance Sparse Matrix-Matrix Products on Intel KNL and Multicore 6511% Architectures. In Proc. 47th Intl. Conf. on Parallel Processing (ICPP '18). 6512% Association for Computing Machinery, New York, NY, USA, Article 34, 1–10. 6513% DOI:https://doi.org/10.1145/3229710.3229720 6514 6515\item \verb'GxB_AxB_DOT': computes \verb"C(i,j)=A(i,:)*B(j,:)'", for each 6516 entry \verb'C(i,j)'. If the mask is present and not complemented, only 6517 entries for which \verb'M(i,j)=1' are computed. This is a very specialized 6518 method that works well only if the mask is present, very sparse, and not 6519 complemented, when \verb'C' is small, or when \verb'C' is bitmap or full. 6520 For example, it works very well 6521 when \verb'A' and \verb'B' are tall and thin, and \verb"C<M>=A*B'" or 6522 \verb"C=A*B'" are computed. These expressions assume all matrices are in 6523 CSR format. If in CSC format, then the dot-product method used for 6524 \verb"A'*B". The method is impossibly slow if \verb'C' is large and the 6525 mask is not present, since it takes $\Omega(mn)$ time if \verb'C' is 6526 $m$-by-$n$ in that case. It does not use any workspace at all. Since it 6527 uses no workspace, it can work very well for extremely sparse or 6528 hypersparse matrices, when the mask is present and not complemented. 6529 6530 \end{itemize} 6531 6532\item \verb'GxB_NTHREADS' controls how many threads a method uses. 6533 By default (if set to zero, or \verb'GxB_DEFAULT'), all available threads 6534 are used. The maximum available threads is controlled by the global 6535 setting, which is \verb'omp_get_max_threads ( )' by default. If set to 6536 some positive integer \verb'nthreads' less than this maximum, at most 6537 \verb'nthreads' threads will be used. See Section~\ref{omp_parallelism} 6538 for details. 6539 6540\item \verb'GxB_CHUNK' is a \verb'double' value that controls how many threads 6541 a method uses for small problems. See Section~\ref{omp_parallelism} for 6542 details. 6543 6544\item \verb'GxB_SORT' provides a hint to \verb'GrB_mxm', \verb'GrB_mxv', 6545 \verb'GrB_vxm', and \verb'GrB_reduce' (to vector). These methods can leave 6546 the output matrix or vector in a jumbled state, where the final sort is 6547 left as pending work. This is typically fastest, since some algorithms can 6548 tolerate jumbled matrices on input, and sometimes the sort can be skipped 6549 entirely. However, if the matrix or vector will be immediately exported in 6550 unjumbled form, or provided as input to a method that requires it to not be 6551 jumbled, then sorting it during the matrix multiplication is faster. 6552 By default, these methods leave the result in jumbled form (a {\em lazy 6553 sort}), if \verb'GxB_SORT' is set to zero (\verb'GxB_DEFAULT'). A nonzero 6554 value will inform the matrix multiplication to sort its result, instead. 6555 6556\end{itemize} 6557 6558%------------------------------------------------------------------------------- 6559\subsubsection{{\sf GrB\_Descriptor\_new:} create a new descriptor} 6560%------------------------------------------------------------------------------- 6561\label{descriptor_new} 6562 6563\begin{mdframed}[userdefinedwidth=6in] 6564{\footnotesize 6565\begin{verbatim} 6566GrB_Info GrB_Descriptor_new // create a new descriptor 6567( 6568 GrB_Descriptor *descriptor // handle of descriptor to create 6569) ; 6570\end{verbatim} } \end{mdframed} 6571 6572\verb'GrB_Descriptor_new' creates a new descriptor, with all fields set to 6573their defaults (output is not replaced, the mask is not complemented, the mask 6574is valued not structural, neither input matrix is transposed, the method 6575used in \verb'C=A*B' is selected automatically, and \verb'GrB_mxm' leaves 6576the final sort as pending work). 6577 6578%------------------------------------------------------------------------------- 6579\subsubsection{{\sf GrB\_Descriptor\_wait:} wait for a descriptor} 6580%------------------------------------------------------------------------------- 6581 6582\begin{mdframed}[userdefinedwidth=6in] 6583{\footnotesize 6584\begin{verbatim} 6585GrB_Info GrB_wait // wait for a descriptor 6586( 6587 GrB_Descriptor *descriptor // descriptor to wait for 6588) ; 6589\end{verbatim} 6590}\end{mdframed} 6591 6592After creating a user-defined descriptor, a GraphBLAS library may choose to 6593exploit non-blocking mode to delay its creation. 6594\verb'GrB_Descriptor_wait(&d)' ensures the descriptor \verb'd' is completed. 6595SuiteSparse:GraphBLAS currently does nothing for 6596\verb'GrB_Descriptor_wait(&d)', except to ensure that \verb'd' is valid. 6597 6598\newpage 6599%------------------------------------------------------------------------------- 6600\subsubsection{{\sf GrB\_Descriptor\_set:} set a parameter in a descriptor} 6601%------------------------------------------------------------------------------- 6602\label{descriptor_set} 6603 6604\begin{mdframed}[userdefinedwidth=6in] 6605{\footnotesize 6606\begin{verbatim} 6607GrB_Info GrB_Descriptor_set // set a parameter in a descriptor 6608( 6609 GrB_Descriptor desc, // descriptor to modify 6610 GrB_Desc_Field field, // parameter to change 6611 GrB_Desc_Value val // value to change it to 6612) ; 6613\end{verbatim} } \end{mdframed} 6614 6615\verb'GrB_Descriptor_set' sets a descriptor field (\verb'GrB_OUTP', 6616\verb'GrB_MASK', \verb'GrB_INP0', \verb'GrB_INP1', or \verb'GxB_AxB_METHOD') to 6617a particular value. Use \verb'GxB_Dec_set' to set the value of 6618\verb'GxB_NTHREADS', \verb'GxB_CHUNK', and \verb'GxB_SORT'. 6619If an error occurs, \verb'GrB_error(&err,desc)' returns details about the error. 6620 6621\vspace{0.2in} 6622\noindent 6623{\footnotesize 6624\begin{tabular}{|l|p{2.4in}|p{2.2in}|} 6625\hline 6626Descriptor & Default & Non-default \\ 6627field & & \\ 6628\hline 6629 6630\verb'GrB_OUTP' 6631 & \verb'GxB_DEFAULT': 6632 The output matrix is not cleared. The operation computes 6633 ${\bf C \langle M \rangle = C \odot T}$. 6634 & \verb'GrB_REPLACE': 6635 After computing ${\bf Z=C\odot T}$, 6636 the output {\bf C} is cleared of all entries. 6637 Then ${\bf C \langle M \rangle = Z}$ is performed. \\ 6638 6639\hline 6640 6641\verb'GrB_MASK' 6642 & \verb'GxB_DEFAULT': 6643 The Mask is not complemented. \verb'Mask(i,j)=1' means the value $C_{ij}$ 6644 can be modified by the operation, while \verb'Mask(i,j)=0' means the value 6645 $C_{ij}$ shall not be modified by the operation. 6646 & \verb'GrB_COMP': 6647 The Mask is complemented. \verb'Mask(i,j)=0' means the value $C_{ij}$ 6648 can be modified by the operation, while \verb'Mask(i,j)=1' means the value 6649 $C_{ij}$ shall not be modified by the operation. \\ 6650 & 6651 & \verb'GrB_STRUCTURE': 6652 The values of the Mask are ignored. If \verb'Mask(i,j)' is an entry 6653 in the \verb'Mask' matrix, it is treated as if \verb'Mask(i,j)=1'. 6654 The two options \verb'GrB_COMP' and \verb'GrB_STRUCTURE' can be 6655 combined, with two subsequent calls, or with a single call with the setting 6656 \verb'GrB_COMP+GrB_STRUCTURE'. \\ 6657 6658\hline 6659 6660\verb'GrB_INP0' 6661 & \verb'GxB_DEFAULT': 6662 The first input is not transposed prior to using it in the operation. 6663 & \verb'GrB_TRAN': 6664 The first input is transposed prior to using it in the operation. Only 6665 matrices are transposed, never vectors. \\ 6666 6667\hline 6668 6669\verb'GrB_INP1' 6670 & \verb'GxB_DEFAULT': 6671 The second input is not transposed prior to using it in the operation. 6672 & \verb'GrB_TRAN': 6673 The second input is transposed prior to using it in the operation. Only 6674 matrices are transposed, never vectors. \\ 6675 6676\hline 6677 6678\verb'GrB_AxB_METHOD' 6679 & \verb'GxB_DEFAULT': 6680 The method for \verb'C=A*B' is selected automatically. 6681 & \verb'GxB_AxB_'{\em method}: The selected method is used to compute 6682 \verb'C=A*B'. \\ 6683 6684\hline 6685\end{tabular} 6686} 6687 6688\newpage 6689%------------------------------------------------------------------------------- 6690\subsubsection{{\sf GxB\_Desc\_set:} set a parameter in a descriptor} 6691%------------------------------------------------------------------------------- 6692\label{desc_set} 6693 6694\begin{mdframed}[userdefinedwidth=6in] 6695{\footnotesize 6696\begin{verbatim} 6697GrB_Info GxB_Desc_set // set a parameter in a descriptor 6698( 6699 GrB_Descriptor desc, // descriptor to modify 6700 GrB_Desc_Field field, // parameter to change 6701 ... // value to change it to 6702) ; 6703\end{verbatim} } \end{mdframed} 6704 6705\verb'GxB_Desc_set' is like \verb'GrB_Descriptor_set', except that the type of 6706the third parameter can vary with the field. This function can modify all 6707descriptor settings, including those that do not have the type 6708\verb'GrB_Desc_Value'. See also \verb'GxB_set' described in 6709Section~\ref{options}. If an error occurs, \verb'GrB_error(&err,desc)' returns 6710details about the error. 6711 6712%------------------------------------------------------------------------------- 6713\subsubsection{{\sf GxB\_Desc\_get:} get a parameter from a descriptor} 6714%------------------------------------------------------------------------------- 6715\label{desc_get} 6716 6717\begin{mdframed}[userdefinedwidth=6in] 6718{\footnotesize 6719\begin{verbatim} 6720GrB_Info GxB_Desc_get // get a parameter from a descriptor 6721( 6722 GrB_Descriptor desc, // descriptor to query; NULL means defaults 6723 GrB_Desc_Field field, // parameter to query 6724 ... // value of the parameter 6725) ; 6726\end{verbatim} } \end{mdframed} 6727 6728\verb'GxB_Desc_get' returns the value of a single field in a descriptor. The 6729type of the third parameter is a pointer to a variable type, whose type depends 6730on the field. See also \verb'GxB_get' described in Section~\ref{options}. 6731 6732%------------------------------------------------------------------------------- 6733\subsubsection{{\sf GrB\_Descriptor\_free:} free a descriptor} 6734%------------------------------------------------------------------------------- 6735\label{descriptor_free} 6736 6737\begin{mdframed}[userdefinedwidth=6in] 6738{\footnotesize 6739\begin{verbatim} 6740GrB_Info GrB_free // free a descriptor 6741( 6742 GrB_Descriptor *descriptor // handle of descriptor to free 6743) ; 6744\end{verbatim} } \end{mdframed} 6745 6746\verb'GrB_Descriptor_free' frees a descriptor. 6747Either usage: 6748 6749 {\small 6750 \begin{verbatim} 6751 GrB_Descriptor_free (&descriptor) ; 6752 GrB_free (&descriptor) ; \end{verbatim}} 6753 6754\noindent 6755frees the \verb'descriptor' and sets \verb'descriptor' to \verb'NULL'. It 6756safely does nothing if passed a \verb'NULL' handle, or if 6757\verb'descriptor == NULL' on input. 6758 6759\newpage 6760%------------------------------------------------------------------------------- 6761\subsubsection{{\sf GrB\_DESC\_*:} predefined descriptors} 6762%------------------------------------------------------------------------------- 6763\label{descriptor_predefined} 6764 6765Version 1.3 of the GraphBLAS C API Specification adds predefined descriptors, 6766and these have been added as of v3.2.0 of SuiteSparse:GraphBLAS. They are 6767listed in the table below. A dash in the table indicates the default. 6768These descriptors may not be modified or freed. 6769Attempts to modify them result in an error (\verb'GrB_INVALID_VALUE'); attempts 6770to free them are silently ignored. 6771% \verb'GrB_NULL' is the default descriptor, with all settings at their defaults: 6772% \verb'OUTP': do not replace the output, 6773% \verb'MASK': mask is valued and not complemented, 6774% \verb'INP0': first input not transposed, and 6775% \verb'INP1': second input not transposed. 6776% For these pre-defined descriptors, the 6777% \verb'GxB_NTHREADS', 6778% \verb'GxB_CHUNK', and 6779% \verb'GxB_SORT' settings are at their default values. 6780 6781\vspace{0.2in} 6782\noindent 6783{\footnotesize 6784\begin{tabular}{|l|lllll|} 6785\hline 6786Descriptor & \verb'OUTP' & \verb'MASK' & \verb'MASK' & \verb'INP0' & \verb'INP1' \\ 6787 & & structural & complement & & \\ 6788\hline 6789\verb'GrB_NULL' & - & - & - & - & - \\ 6790\verb'GrB_DESC_T1' & - & - & - & - & \verb'GrB_TRAN' \\ 6791\verb'GrB_DESC_T0' & - & - & - & \verb'GrB_TRAN' & - \\ 6792\verb'GrB_DESC_T0T1' & - & - & - & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6793\hline 6794\verb'GrB_DESC_C' & - & - & \verb'GrB_COMP' & - & - \\ 6795\verb'GrB_DESC_CT1' & - & - & \verb'GrB_COMP' & - & \verb'GrB_TRAN' \\ 6796\verb'GrB_DESC_CT0' & - & - & \verb'GrB_COMP' & \verb'GrB_TRAN' & - \\ 6797\verb'GrB_DESC_CT0T1' & - & - & \verb'GrB_COMP' & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6798\hline 6799\verb'GrB_DESC_S' & - & \verb'GrB_STRUCTURE' & - & - & - \\ 6800\verb'GrB_DESC_ST1' & - & \verb'GrB_STRUCTURE' & - & - & \verb'GrB_TRAN' \\ 6801\verb'GrB_DESC_ST0' & - & \verb'GrB_STRUCTURE' & - & \verb'GrB_TRAN' & - \\ 6802\verb'GrB_DESC_ST0T1' & - & \verb'GrB_STRUCTURE' & - & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6803\hline 6804\verb'GrB_DESC_SC' & - & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & - & - \\ 6805\verb'GrB_DESC_SCT1' & - & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & - & \verb'GrB_TRAN' \\ 6806\verb'GrB_DESC_SCT0' & - & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & \verb'GrB_TRAN' & - \\ 6807\verb'GrB_DESC_SCT0T1' & - & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6808\hline 6809\verb'GrB_DESC_R' & \verb'GrB_REPLACE' & - & - & - & - \\ 6810\verb'GrB_DESC_RT1' & \verb'GrB_REPLACE' & - & - & - & \verb'GrB_TRAN' \\ 6811\verb'GrB_DESC_RT0' & \verb'GrB_REPLACE' & - & - & \verb'GrB_TRAN' & - \\ 6812\verb'GrB_DESC_RT0T1' & \verb'GrB_REPLACE' & - & - & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6813\hline 6814\verb'GrB_DESC_RC' & \verb'GrB_REPLACE' & - & \verb'GrB_COMP' & - & - \\ 6815\verb'GrB_DESC_RCT1' & \verb'GrB_REPLACE' & - & \verb'GrB_COMP' & - & \verb'GrB_TRAN' \\ 6816\verb'GrB_DESC_RCT0' & \verb'GrB_REPLACE' & - & \verb'GrB_COMP' & \verb'GrB_TRAN' & - \\ 6817\verb'GrB_DESC_RCT0T1' & \verb'GrB_REPLACE' & - & \verb'GrB_COMP' & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6818\hline 6819\verb'GrB_DESC_RS' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & - & - & - \\ 6820\verb'GrB_DESC_RST1' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & - & - & \verb'GrB_TRAN' \\ 6821\verb'GrB_DESC_RST0' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & - & \verb'GrB_TRAN' & - \\ 6822\verb'GrB_DESC_RST0T1' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & - & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6823\hline 6824\verb'GrB_DESC_RSC' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & - & - \\ 6825\verb'GrB_DESC_RSCT1' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & - & \verb'GrB_TRAN' \\ 6826\verb'GrB_DESC_RSCT0' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & \verb'GrB_TRAN' & - \\ 6827\verb'GrB_DESC_RSCT0T1' & \verb'GrB_REPLACE' & \verb'GrB_STRUCTURE' & \verb'GrB_COMP' & \verb'GrB_TRAN' & \verb'GrB_TRAN' \\ 6828\hline 6829\end{tabular}} 6830 6831\newpage 6832%=============================================================================== 6833\subsection{{\sf GrB\_free:} free any GraphBLAS object} %======================= 6834%=============================================================================== 6835\label{free} 6836 6837Each of the ten objects has \verb'GrB_*_new' and \verb'GrB_*_free' methods 6838that are specific to each object. They can also be accessed by a generic 6839function, \verb'GrB_free', that works for all ten objects. If \verb'G' is any 6840of the ten objects, the statement 6841 6842 {\footnotesize 6843 \begin{verbatim} 6844 GrB_free (&G) ; \end{verbatim} } 6845 6846\noindent 6847frees the object and sets the variable \verb'G' to \verb'NULL'. It is safe to 6848pass in a \verb'NULL' handle, or to free an object twice: 6849 6850 {\footnotesize 6851 \begin{verbatim} 6852 GrB_free (NULL) ; // SuiteSparse:GraphBLAS safely does nothing 6853 GrB_free (&G) ; // the object G is freed and G set to NULL 6854 GrB_free (&G) ; // SuiteSparse:GraphBLAS safely does nothing \end{verbatim} } 6855 6856\noindent 6857However, the following sequence of operations is not safe. The first two are 6858valid but the last statement will lead to undefined behavior. 6859 6860 {\footnotesize 6861 \begin{verbatim} 6862 H = G ; // valid; creates a 2nd handle of the same object 6863 GrB_free (&G) ; // valid; G is freed and set to NULL; H now undefined 6864 GrB_some_method (H) ; // not valid; H is undefined \end{verbatim}} 6865 6866Some objects are predefined, such as the built-in types. If a user application 6867attempts to free a built-in object, SuiteSparse:GraphBLAS will safely do 6868nothing. The \verb'GrB_free' function in SuiteSparse:GraphBLAS always 6869returns \verb'GrB_SUCCESS'. 6870 6871\newpage 6872%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6873\section{The mask, accumulator, and replace option} %%%%%%%%%%%%%%%%%%%%%%%%%%%% 6874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6875\label{sec:maskaccum} 6876 6877After a GraphBLAS operation computes a result ${\bf T}$, (for example, ${\bf 6878T=AB}$ for \verb'GrB_mxm'), the results are assigned to an output matrix ${\bf 6879C}$ via the mask/ accumulator phase, written as ${\bf C \langle M \rangle = C 6880\odot T}$. This phase is affected by the \verb'GrB_REPLACE' option in the 6881descriptor, the presence of an optional binary accumulator operator ($\odot$), 6882the presence of the optional mask matrix ${\bf M}$, and the status of the mask 6883descriptor. The interplay of these options is summarized in 6884Table~\ref{tab:maskaccum}. 6885 6886The mask ${\bf M}$ may be present, or not. It may be structural or valued, and 6887it may be complemented, or not. These options may be combined, for a total of 68888 cases, although the structural/valued option as no effect if ${\bf M}$ is not 6889present. If ${\bf M}$ is not present and not complemented, then $m_{ij}$ is 6890implicitly true. If not present yet complemented, then all $m_{ij}$ entries are 6891implicitly zero; in this case, ${\bf T}$ need not be computed at all. Either 6892${\bf C}$ is not modified, or all its entries are cleared if the replace option 6893is enabled. If ${\bf M}$ is present, and the structural option is used, then 6894$m_{ij}$ is treated as true if it is an entry in the matrix (its value is 6895ignored). Otherwise, the value of $m_{ij}$ is used. In both cases, entries 6896not present are implicitly zero. These values are negated if the mask is 6897complemented. All of these various cases are combined to give a single 6898effective value of the mask at position ${ij}$. 6899 6900The combination of all these options are presented in the 6901Table~\ref{tab:maskaccum}. The first column is the \verb'GrB_REPLACE' option. 6902The second column lists whether or not the accumulator operator is present. 6903The third column lists whether or not $c_{ij}$ exists on input to the 6904mask/accumulator phase (a dash means that it does not exist). The fourth 6905column lists whether or not the entry $t_{ij}$ is present in the result matrix 6906${\bf T}$. The mask column is the final effective value of $m_{ij}$, after 6907accounting for the presence of ${\bf M}$ and the mask options. Finally, the 6908last column states the result of the mask/accum step; if no action is listed in 6909this column, then $c_{ij}$ is not modified. 6910 6911Several important observations can be made from this table. First, 6912if no mask is present (and the mask-complement descriptor option is not used), 6913then only the first half of the table is used. In this case, the \verb'GrB_REPLACE' 6914option has no effect. The entire matrix ${\bf C}$ is modified. 6915 6916Consider the cases when $c_{ij}$ is present but $t_{ij}$ is not, and there is no 6917mask or the effective value of the mask is true for this ${ij}$ position. With 6918no accumulator operator, $c_{ij}$ is deleted. If the accumulator operator is 6919present and the replace option is not used, $c_{ij}$ remains unchanged. 6920 6921\begin{table} 6922{\small 6923\begin{tabular}{lllll|l} 6924\hline 6925repl & accum & ${\bf C}$ & ${\bf T}$ & mask & action taken by ${\bf C \langle M \rangle = C \odot T}$ \\ 6926\hline 6927 - &- & $c_{ij}$ & $t_{ij}$ & 1 & $c_{ij} = t_{ij}$, update \\ 6928 - &- & - & $t_{ij}$ & 1 & $c_{ij} = t_{ij}$, insert \\ 6929 - &- & $c_{ij}$ & - & 1 & delete $c_{ij}$ because $t_{ij}$ not present \\ 6930 - &- & - & - & 1 & \\ 6931 - &- & $c_{ij}$ & $t_{ij}$ & 0 & \\ 6932 - &- & - & $t_{ij}$ & 0 & \\ 6933 - &- & $c_{ij}$ & - & 0 & \\ 6934 - &- & - & - & 0 & \\ 6935\hline 6936 yes&- & $c_{ij}$ & $t_{ij}$ & 1 & $c_{ij} = t_{ij}$, update \\ 6937 yes&- & - & $t_{ij}$ & 1 & $c_{ij} = t_{ij}$, insert \\ 6938 yes&- & $c_{ij}$ & - & 1 & delete $c_{ij}$ because $t_{ij}$ not present \\ 6939 yes&- & - & - & 1 & \\ 6940 yes&- & $c_{ij}$ & $t_{ij}$ & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 6941 yes&- & - & $t_{ij}$ & 0 & \\ 6942 yes&- & $c_{ij}$ & - & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 6943 yes&- & - & - & 0 & \\ 6944\hline 6945 - &yes & $c_{ij}$ & $t_{ij}$ & 1 & $c_{ij} = c_{ij} \odot t_{ij}$, apply accumulator \\ 6946 - &yes & - & $t_{ij}$ & 1 & $c_{ij} = t_{ij}$, insert \\ 6947 - &yes & $c_{ij}$ & - & 1 & \\ 6948 - &yes & - & - & 1 & \\ 6949 - &yes & $c_{ij}$ & $t_{ij}$ & 0 & \\ 6950 - &yes & - & $t_{ij}$ & 0 & \\ 6951 - &yes & $c_{ij}$ & - & 0 & \\ 6952 - &yes & - & - & 0 & \\ 6953\hline 6954 yes&yes & $c_{ij}$ & $t_{ij}$ & 1 & $c_{ij} = c_{ij} \odot t_{ij}$, apply accumulator \\ 6955 yes&yes & - & $t_{ij}$ & 1 & $c_{ij} = t_{ij}$, insert \\ 6956 yes&yes & $c_{ij}$ & - & 1 & \\ 6957 yes&yes & - & - & 1 & \\ 6958 yes&yes & $c_{ij}$ & $t_{ij}$ & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 6959 yes&yes & - & $t_{ij}$ & 0 & \\ 6960 yes&yes & $c_{ij}$ & - & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 6961 yes&yes & - & - & 0 & \\ 6962\hline 6963\end{tabular} 6964} 6965\caption{Results of the mask/accumulator phase \label{tab:maskaccum}} 6966\end{table} 6967 6968 6969\newpage 6970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6971\section{SuiteSparse:GraphBLAS Options} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6973\label{options} 6974 6975SuiteSparse:GraphBLAS includes two type-generic methods, \verb'GxB_set' and 6976\verb'GxB_get', that set and query various options and parameters settings, 6977including a generic way to set values in the \verb'GrB_Descriptor' object. 6978Using these methods, the user application can provide hints to 6979SuiteSparse:GraphBLAS on how it should store and operate on its matrices. 6980These hints have no effect on the results of any GraphBLAS operation (except 6981perhaps floating-point roundoff differences), but they can have a great impact 6982on the amount of time or memory taken. 6983 6984\begin{itemize} 6985 6986\item \verb'GxB_set (field, value)' provides hints to 6987 SuiteSparse:GraphBLAS on how it should store all matrices created after 6988 calling this function: by row, by column. It provides hints as to when to 6989 use {\em hypersparse} \cite{BulucGilbert08,BulucGilbert12} or {\em bitmap} 6990 formats. These are global options that modify all matrices created after 6991 calling this method. The global settings also control the number of 6992 threads used, and the heuristic for selecting the number of threads for 6993 small problems (the ``chunk''). 6994 6995{\footnotesize 6996\begin{tabular}{lll} 6997field & value & description \\ 6998\hline 6999\verb'GxB_HYPER_SWITCH' & \verb'double' & hypersparsity control (0 to 1) \\ 7000\verb'GxB_BITMAP_SWITCH' & \verb'double [8]' & bitmap control \\ 7001\verb'GxB_FORMAT' & \verb'int' & \verb'GxB_BY_ROW' 7002 or \verb'GxB_BY_COL' \\ 7003\verb'GxB_GLOBAL_NTHREADS' & \verb'int' & number of threads to use \\ 7004\verb'GxB_NTHREADS' & \verb'int' & number of threads to use \\ 7005\verb'GxB_GLOBAL_CHUNK' & \verb'double' & chunk size \\ 7006\verb'GxB_CHUNK' & \verb'double' & chunk size \\ 7007\verb'GxB_BURBLE' & \verb'int' & diagnostic output \\ 7008\verb'GxB_PRINTF' & see below & diagnostic output \\ 7009\verb'GxB_FLUSH' & see below & diagnostic output \\ 7010\verb'GxB_MEMORY_POOL' & \verb'int64_t [64]' & memory pool control \\ 7011\end{tabular} 7012} 7013 7014\item \verb'GxB_set (GrB_Matrix A, field, value)' provides hints to 7015 SuiteSparse: GraphBLAS on how to store a particular matrix. 7016 7017{\footnotesize 7018\begin{tabular}{lll} 7019field & value & description \\ 7020\hline 7021\verb'GxB_HYPER_SWITCH' & \verb'double' & hypersparsity control (0 to 1) \\ 7022\verb'GxB_BITMAP_SWITCH' & \verb'double' & bitmap control (0 to 1) \\ 7023\verb'GxB_FORMAT' & \verb'int' & \verb'GxB_BY_ROW' 7024 or \verb'GxB_BY_COL' \\ 7025\verb'GxB_SPARSITY_CONTROL' & \verb'int' & 0 to 15 \\ 7026\end{tabular} 7027} 7028 7029\item \verb'GxB_set (GrB_Vector v, field, value)' provides hints to 7030 SuiteSparse: GraphBLAS on how to store a particular vector. 7031 7032{\footnotesize 7033\begin{tabular}{lll} 7034field & value & description \\ 7035\hline 7036\verb'GxB_BITMAP_SWITCH' & \verb'double' & bitmap control (0 to 1) \\ 7037\verb'GxB_SPARSITY_CONTROL' & \verb'int' & 0 to 15 \\ 7038\end{tabular} 7039} 7040 7041\item \verb'GxB_set (GrB_Descriptor desc, field, value)' sets 7042 the value of a field in a \verb'GrB_Descriptor'. 7043 7044{\footnotesize 7045\begin{tabular}{lll} 7046field & value & description \\ 7047\hline 7048\verb'GrB_OUTP' & \verb'GrB_Desc_field' & replace option \\ 7049\verb'GrB_MASK' & \verb'GrB_Desc_field' & mask option \\ 7050\verb'GrB_INP0' & \verb'GrB_Desc_field' & transpose input 0 \\ 7051\verb'GrB_INP1' & \verb'GrB_Desc_field' & transpose input 1 \\ 7052\verb'GxB_DESCRIPTOR_NTHREADS' & \verb'int' & number of threads to use \\ 7053\verb'GxB_NTHREADS' & \verb'int' & number of threads to use \\ 7054\verb'GxB_DESCRIPTOR_CHUNK' & \verb'double' & chunk size \\ 7055\verb'GxB_CHUNK' & \verb'double' & chunk size \\ 7056\verb'GxB_AxB_METHOD' & \verb'int' & method for matrix multiply \\ 7057\verb'GxB_SORT' & \verb'int' & lazy vs aggressive sort \\ 7058\end{tabular} 7059} 7060 7061\end{itemize} 7062 7063The \verb'GxB_get' method queries a \verb'GrB_Descriptor', a \verb'GrB_Matrix', 7064a \verb'GrB_Vector', or the global options. 7065 7066\begin{itemize} 7067 7068\item \verb'GxB_get (field, &value)' retrieves the value of 7069 a global option. 7070 7071{\footnotesize 7072\begin{tabular}{lll} 7073field & value & description \\ 7074\hline 7075\verb'GxB_HYPER_SWITCH' & \verb'double' & hypersparsity control (0 to 1) \\ 7076\verb'GxB_BITMAP_SWITCH' & \verb'double [8]' & bitmap control \\ 7077\verb'GxB_FORMAT' & \verb'int' & \verb'GxB_BY_ROW' 7078 or \verb'GxB_BY_COL' \\ 7079\verb'GxB_GLOBAL_NTHREADS' & \verb'int' & number of threads to use \\ 7080\verb'GxB_NTHREADS' & \verb'int' & number of threads to use \\ 7081\verb'GxB_GLOBAL_CHUNK' & \verb'double' & chunk size \\ 7082\verb'GxB_CHUNK' & \verb'double' & chunk size \\ 7083\verb'GxB_BURBLE' & \verb'int' & diagnostic output \\ 7084\verb'GxB_PRINTF' & see below & diagnostic output \\ 7085\verb'GxB_FLUSH' & see below & diagnostic output \\ 7086\verb'GxB_MEMORY_POOL' & \verb'int64_t [64]' & memory pool control \\ 7087\hline 7088\verb'GxB_MODE' & \verb'int' & blocking/non-blocking \\ 7089\verb'GxB_LIBRARY_NAME' & \verb'char *' & name of library \\ 7090\verb'GxB_LIBRARY_VERSION' & \verb'int [3]' & library version \\ 7091\verb'GxB_LIBRARY_DATE' & \verb'char *' & release date \\ 7092\verb'GxB_LIBRARY_ABOUT' & \verb'char *' & about the library \\ 7093\verb'GxB_LIBRARY_LICENSE' & \verb'char *' & license \\ 7094\verb'GxB_LIBRARY_COMPILE_DATE' & \verb'char *' & date of compilation \\ 7095\verb'GxB_LIBRARY_COMPILE_TIME' & \verb'char *' & time of compilation \\ 7096\verb'GxB_LIBRARY_URL' & \verb'char *' & url of library \\ 7097\verb'GxB_API_VERSION' & \verb'int [3]' & C API version \\ 7098\verb'GxB_API_DATE' & \verb'char *' & C API date \\ 7099\verb'GxB_API_ABOUT' & \verb'char *' & about the C API \\ 7100\verb'GxB_API_URL' & \verb'char *' & \verb'http://graphblas.org' \\ 7101\end{tabular} 7102} 7103 7104\item \verb'GxB_get (GrB_Matrix A, field, &value)' retrieves the current 7105 value of an option from a particular matrix \verb'A'. 7106 7107{\footnotesize 7108\begin{tabular}{lll} 7109field & value & description \\ 7110\hline 7111\verb'GxB_HYPER_SWITCH' & \verb'double' & hypersparsity control (0 to 1) \\ 7112\verb'GxB_BITMAP_SWITCH' & \verb'double' & bitmap control (0 to 1) \\ 7113\verb'GxB_FORMAT' & \verb'int' & \verb'GxB_BY_ROW' 7114 or \verb'GxB_BY_COL' \\ 7115\verb'GxB_SPARSITY_CONTROL' & \verb'int' & 0 to 15 \\ 7116\verb'GxB_SPARSITY_STATUS' & \verb'int' & 1, 2, 4, or 8 \\ 7117\end{tabular} 7118} 7119 7120\item \verb'GxB_get (GrB_Vector A, field, &value)' retrieves the current 7121 value of an option from a particular vector \verb'v'. 7122 7123{\footnotesize 7124\begin{tabular}{lll} 7125field & value & description \\ 7126\hline 7127\verb'GxB_BITMAP_SWITCH' & \verb'double' & bitmap control (0 to 1) \\ 7128\verb'GxB_FORMAT' & \verb'int' & \verb'GxB_BY_ROW' 7129 or \verb'GxB_BY_COL' \\ 7130\verb'GxB_SPARSITY_CONTROL' & \verb'int' & 0 to 15 \\ 7131\verb'GxB_SPARSITY_STATUS' & \verb'int' & 1, 2, 4, or 8 \\ 7132\end{tabular} 7133} 7134 7135\item \verb'GxB_get (GrB_Descriptor desc, field, &value)' retrieves the value 7136 of a field in a descriptor. 7137 7138{\footnotesize 7139\begin{tabular}{lll} 7140field & value & description \\ 7141\hline 7142\verb'GrB_OUTP' & \verb'GrB_Desc_field' & replace option \\ 7143\verb'GrB_MASK' & \verb'GrB_Desc_field' & mask option \\ 7144\verb'GrB_INP0' & \verb'GrB_Desc_field' & transpose input 0 \\ 7145\verb'GrB_INP1' & \verb'GrB_Desc_field' & transpose input 1 \\ 7146\verb'GxB_DESCRIPTOR_NTHREADS' & \verb'int' & number of threads to use \\ 7147\verb'GxB_NTHREADS' & \verb'int' & number of threads to use \\ 7148\verb'GxB_DESCRIPTOR_CHUNK' & \verb'double' & chunk size \\ 7149\verb'GxB_CHUNK' & \verb'double' & chunk size \\ 7150\verb'GxB_AxB_METHOD' & \verb'int' & method for matrix multiply \\ 7151\verb'GxB_SORT' & \verb'int' & lazy vs aggressive sort \\ 7152\end{tabular} 7153} 7154 7155\end{itemize} 7156 7157%------------------------------------------------------------------------------- 7158\subsection{OpenMP parallelism} 7159%------------------------------------------------------------------------------- 7160\label{omp_parallelism} 7161 7162SuiteSparse:GraphBLAS is a parallel library, based on OpenMP. By 7163default, all GraphBLAS operations will use up to the maximum number of threads 7164specified by the \verb'omp_get_max_threads' OpenMP function. For small 7165problems, GraphBLAS may choose to use fewer threads, using two parameters: the 7166maximum number of threads to use (which may differ from the 7167\verb'omp_get_max_threads' value), and a parameter called the \verb'chunk'. 7168Suppose \verb'work' is a measure of the work an operation needs to perform (say 7169the number of entries in the two input matrices for \verb'GrB_eWiseAdd'). No 7170more than \verb'floor(work/chunk)' threads will be used (or one thread if the 7171ratio is less than 1). 7172 7173The default \verb'chunk' value is 65,536, but this may change in future versions, 7174or it may be modified when GraphBLAS is installed on a particular machine. 7175 7176Both parameters can be set in two ways: 7177 7178\begin{itemize} 7179 7180\item Globally: If the following methods are used, then all subsequent 7181GraphBLAS operations will use these settings. Note the typecast, 7182\verb'(double)' \verb'chunk'. This is necessary if a literal constant such as 7183\verb'20000' is passed as this argument. The type of the constant must be 7184\verb'double'. 7185 7186 {\footnotesize 7187 \begin{verbatim} 7188 int nthreads_max = 40 ; 7189 GxB_set (GxB_NTHREADS, nthreads_max) ; 7190 GxB_set (GxB_CHUNK, (double) 20000) ; \end{verbatim} } 7191 7192\item Per operation: Most GraphBLAS operations take a \verb'GrB_Descriptor' 7193input, and this can be modified to set the number of threads and chunk 7194size for the operation that uses this descriptor. Note that \verb'chunk' 7195is a \verb'double'. 7196 7197 {\footnotesize 7198 \begin{verbatim} 7199 GrB_Descriptor desc ; 7200 GrB_Descriptor_new (&desc) 7201 int nthreads_max = 40 ; 7202 GxB_set (desc, GxB_NTHREADS, nthreads_max) ; 7203 double chunk = 20000 ; 7204 GxB_set (desc, GxB_CHUNK, chunk) ; \end{verbatim} } 7205 7206\end{itemize} 7207 7208The smaller of \verb'nthreads_max' and \verb'floor(work/chunk)' is used for any 7209given GraphBLAS operation, except that a single thread is used if this value is 7210zero or less. 7211 7212If either parameter is set to \verb'GxB_DEFAULT', then default values are used. 7213The default for \verb'nthreads_max' is the return value from 7214\verb'omp_get_max_threads', and the default chunk size is currently 65,536. 7215 7216If a descriptor value for either parameter is left at its default, or set to 7217\verb'GxB_DEFAULT', then the global setting is used. This global setting may 7218have been modified from its default, and this modified value will be used. 7219 7220For example, suppose \verb'omp_get_max_threads' reports 8 threads. If \newline 7221\verb'GxB_set (GxB_NTHREADS, 4)' is used, then the global setting is four 7222threads, not eight. If a descriptor is used but its \verb'GxB_NTHREADS' is not 7223set, or set to \verb'GxB_DEFAULT', then any operation that uses this descriptor 7224will use 4 threads. 7225 7226%------------------------------------------------------------------------------- 7227\subsection{Storing a matrix by row or by column} 7228%------------------------------------------------------------------------------- 7229 7230The GraphBLAS \verb'GrB_Matrix' is entirely opaque to the user application, and 7231the GraphBLAS API does not specify how the matrix should be stored. However, 7232choices made in how the matrix is represented in a particular implementation, 7233such as SuiteSparse:GraphBLAS, can have a large impact on performance. 7234 7235Many graph algorithms are just as fast in any format, but some algorithms are 7236much faster in one format or the other. For example, suppose the user 7237application stores a directed graph as a matrix \verb'A', with the edge $(i,j)$ 7238represented as the value \verb'A(i,j)', and the application makes many accesses 7239to the $i$th row of the matrix, with \verb'GrB_Col_extract' 7240\verb'(w,...,A,GrB_ALL,...,i,desc)' with the transposed descriptor 7241(\verb'GrB_INP0' set to \verb'GrB_TRAN'). If the matrix is stored by column 7242this can be extremely slow, just like the expression \verb'w=A(i,:)' in MATLAB, 7243where \verb'i' is a scalar. Since this is a typical use-case in graph 7244algorithms, the default format in SuiteSparse:GraphBLAS is to store its 7245matrices by row, in Compressed Sparse Row format (CSR). 7246 7247MATLAB stores its sparse matrices by column, in ``non-hypersparse'' format, in 7248what is called the Compressed Sparse Column format, or CSC for short. An 7249\verb'm'-by-\verb'n' matrix in MATLAB is represented as a set of \verb'n' 7250column vectors, each with a sorted list of row indices and values of the 7251nonzero entries in that column. As a result, \verb'w=A(:,j)' is very fast in 7252MATLAB, since the result is already held in the data structure a single list, 7253the $j$th column vector. However, \verb'w=A(i,:)' is very slow in MATLAB, 7254since every column in the matrix has to be searched to see if it contains row 7255\verb'i'. In MATLAB, if many such accesses are made, it is much better to 7256transpose the matrix (say \verb"AT=A'") and then use \verb"w=AT(:,i)" instead. 7257This can have a dramatic impact on the performance of MATLAB. 7258 7259Likewise, if \verb'u' is a very sparse column vector and \verb'A' is stored by 7260column, then \verb"w=u'*A" (via \verb'GrB_vxm') is slower than \verb'w=A*u' 7261(via \verb'GrB_mxv'). The opposite is true if the matrix is stored by row. 7262 7263An example of this can be found in Section B.1 of Version 1.2 of the GraphBLAS 7264API Specification, where the breadth-first search \verb'BFS' uses 7265\verb'GrB_vxm' to compute \verb"q'=q'*A". This method is not fast if the 7266matrix \verb'A' is stored by column. The \verb'bfs5' and \verb'bfs6' examples 7267in the \verb'Demo/' folder of SuiteSparse:GraphBLAS use \verb'GrB_vxm', 7268which is fast since the matrices are assumed to be stored in their 7269default format, by row. 7270 7271SuiteSparse:GraphBLAS stores its sparse matrices by row, by default. In 7272Versions 2.1 and earlier, the matrices were stored by column, by default. 7273However, it can also be instructed to store any selected matrices, or all 7274matrices, by column instead (just like MATLAB), so that \verb'w=A(:,j)' (via 7275\verb'GrB_Col_extract') is very fast. The change in data format has no effect 7276on the result, just the time and memory usage. To use a column-oriented format 7277by default, the following can be done in a user application that tends to 7278access its matrices by column. 7279 7280 {\footnotesize 7281 \begin{verbatim} 7282 GrB_init (...) ; 7283 // just after GrB_init: do the following: 7284 #ifdef GxB_SUITESPARSE_GRAPHBLAS 7285 GxB_set (GxB_FORMAT, GxB_BY_COL) ; 7286 #endif \end{verbatim} } 7287 7288If this is done, and no other \verb'GxB_set' calls are made with 7289\verb'GxB_FORMAT', all matrices will be stored by column. Alternatively, 7290SuiteSparse:GraphBLAS can be compiled with \verb'-DBYCOL', which changes the 7291default format to \verb'GxB_BY_COL', with no calls to any \verb'GxB_*' 7292function. The default format is now \verb'GxB_BY_ROW'. 7293 7294%------------------------------------------------------------------------------- 7295\subsection{Hypersparse matrices} 7296\label{hypersparse} 7297%------------------------------------------------------------------------------- 7298 7299MATLAB can store an \verb'm'-by-\verb'n' matrix with a very large value of 7300\verb'm', since a CSC data structure takes $O(n+|{\bf A}|)$ memory, independent 7301of \verb'm', where $|{\bf A}|$ is the number of nonzeros in the matrix. It 7302cannot store a matrix with a huge \verb'n', and this structure is also 7303inefficient when $|{\bf A}|$ is much smaller than \verb'n'. In contrast, 7304SuiteSparse:GraphBLAS can store its matrices in {\em hypersparse} format, 7305taking only $O(|{\bf A}|)$ memory, independent of how it is stored (by row or 7306by column) and independent of both \verb'm' and \verb'n' 7307\cite{BulucGilbert08,BulucGilbert12}. 7308 7309In both the CSR and CSC formats, the matrix is held as a set of sparse vectors. 7310In non-hypersparse format, the set of sparse vectors is itself dense; all 7311vectors are present, even if they are empty. For example, an 7312\verb'm'-by-\verb'n' matrix in non-hypersparse CSC format contains \verb'n' 7313sparse vectors. Each column vector takes at least one integer to represent, 7314even for a column with no entries. This allows for quick lookup for a 7315particular vector, but the memory required is $O(n+|{\bf A}|)$. With a 7316hypersparse CSC format, the set of vectors itself is sparse, and columns with 7317no entries take no memory at all. The drawback of the hypersparse format is 7318that finding an arbitrary column vector \verb'j', such as for the computation 7319\verb'C=A(:,j)', takes $O(\log k)$ time if there $k \le n$ vectors in the data 7320structure. One advantage of the hypersparse structure is the memory required 7321for an \verb'm'-by-\verb'n' hypersparse CSC matrix is only $O(|{\bf A}|)$, 7322independent of \verb'm' and \verb'n'. Algorithms that must visit all non-empty 7323columns of a matrix are much faster when working with hypersparse matrices, 7324since empty columns can be skipped. 7325 7326The \verb'hyper_switch' parameter controls the hypersparsity of the internal 7327data structure for a matrix. The parameter is typically in the range 0 to 1. 7328The default is \verb'hyper_switch' = \verb'GxB_HYPER_DEFAULT', which is an 7329\verb'extern' \verb'const' \verb'double' value, currently set to 0.0625, or 73301/16. This default ratio may change in the future. 7331 7332The \verb'hyper_switch' determines how the matrix is converted between the 7333hypersparse and non-hypersparse formats. Let $n$ be the number of columns of a 7334CSC matrix, or the number of rows of a CSR matrix. The matrix can have at most 7335$n$ non-empty vectors. 7336 7337Let $k$ be the actual number of non-empty vectors. That is, for the CSC 7338format, $k \le n$ is the number of columns that have at least one entry. Let 7339$h$ be the value of \verb'hyper_switch'. 7340 7341If a matrix is currently hypersparse, it can be converted to non-hypersparse if 7342the either condition $n \le 1$ or $k > 2nh$ holds, or both. Otherwise, it 7343stays hypersparse. Note that if $n \le 1$ the matrix is always stored as 7344non-hypersparse. 7345 7346If currently non-hypersparse, it can be converted to hypersparse if 7347both conditions $n > 1$ and $k \le nh$ hold. Otherwise, it stays 7348non-hypersparse. Note that if $n \le 1$ the matrix always remains 7349non-hypersparse. 7350 7351The default value of \verb'hyper_switch' is assigned at startup by 7352\verb'GrB_init', and can then be modified globally with \verb'GxB_set'. All 7353new matrices are created with the same \verb'hyper_switch', determined by the 7354global value. Once a particular matrix \verb'A' has been constructed, its 7355hypersparsity ratio can be modified from the default with: 7356 7357 {\footnotesize 7358 \begin{verbatim} 7359 double hyper_switch = 0.2 ; 7360 GxB_set (A, GxB_HYPER_SWITCH, hyper_switch) ; \end{verbatim}} 7361 7362To force a matrix to always be non-hypersparse, use \verb'hyper_switch' equal to 7363\verb'GxB_NEVER_HYPER'. To force a matrix to always stay hypersparse, set 7364\verb'hyper_switch' to \verb'GxB_ALWAYS_HYPER'. 7365 7366A \verb'GrB_Matrix' can thus be held in one of four formats: any combination of 7367hyper/non-hyper and CSR/CSC. All \verb'GrB_Vector' objects are always stored 7368in non-hypersparse CSC format. 7369 7370A new matrix created via \verb'GrB_Matrix_new' starts with $k=0$ and is created 7371in hypersparse form by default unless $n \le 1$ or if $h<0$, where $h$ is the 7372global \verb'hyper_switch' value. The matrix is created in either 7373\verb'GxB_BY_ROW' or \verb'GxB_BY_COL' format, as determined by the last call 7374to \verb'GxB_set(GxB_FORMAT,...)' or \verb'GrB_init'. 7375 7376A new matrix \verb'C' created via \verb'GrB_dup (&C,A)' inherits the CSR/CSC 7377format, hypersparsity format, and \verb'hyper_switch' from \verb'A'. 7378 7379%------------------------------------------------------------------------------- 7380\subsection{Bitmap matrices} 7381\label{bitmap_switch} 7382%------------------------------------------------------------------------------- 7383 7384By default, SuiteSparse:GraphBLAS switches between all four formats 7385(hypersparse, sparse, bitmap, and full) automatically. Let $d = |{\bf A}|/mn$ 7386for an $m$-by-$n$ matrix $\bf A$ with $|{\bf A}|$ entries. If the matrix is 7387currently in sparse or hypersparse format, and is modified so that $d$ exceeds 7388a given threshold, it is converted into bitmap format. The default threshold 7389is controlled by the \verb'GxB_BITMAP_SWITCH' setting, which can be set 7390globally, or for a particular matrix or vector. 7391 7392The default value of the switch to bitmap format depends on $\min(m,n)$, for a 7393matrix of size $m$-by-$n$. For the global setting, the bitmap switch is a 7394\verb'double' array of size \verb'GxB_NBITMAP_SWITCH'. The defaults are given 7395below: 7396 7397\vspace{0.2in} 7398{\small 7399\begin{tabular}{lll} 7400parameter & default & matrix sizes \\ 7401\hline 7402\verb'bitmap_switch [0]' & 0.04 & $\min(m,n) = 1$ (and all vectors) \\ 7403\verb'bitmap_switch [1]' & 0.05 & $\min(m,n) = 2$ \\ 7404\verb'bitmap_switch [2]' & 0.06 & $\min(m,n) = 3$ to 4 \\ 7405\verb'bitmap_switch [3]' & 0.08 & $\min(m,n) = 5$ to 8 \\ 7406\verb'bitmap_switch [4]' & 0.10 & $\min(m,n) = 9$ to 16\\ 7407\verb'bitmap_switch [5]' & 0.20 & $\min(m,n) = 17$ to 32\\ 7408\verb'bitmap_switch [6]' & 0.30 & $\min(m,n) = 33$ to 64 \\ 7409\verb'bitmap_switch [7]' & 0.40 & $\min(m,n) > 64$ \\ 7410\end{tabular} 7411} 7412\vspace{0.2in} 7413 7414That is, by default a \verb'GrB_Vector' is held in bitmap format if its density 7415exceeds 4\%. To change the global settings, do the following: 7416 7417{\footnotesize 7418\begin{verbatim} 7419 double bswitch [GxB_NBITMAP_SWITCH] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 } ; 7420 GxB_set (GxB_BITMAP_SWITCH, bswitch) ; 7421\end{verbatim} 7422} 7423 7424If the matrix is currently in bitmap format, it is converted to full if all 7425entries are present, or to sparse/hypersparse if $d$ drops below $b/2$, if its 7426bitmap switch is $b$. A matrix or vector with $d$ between $b/2$ and $b$ 7427remains in its current format. 7428 7429%------------------------------------------------------------------------------- 7430\subsection{Parameter types} 7431%------------------------------------------------------------------------------- 7432The \verb'GxB_Option_Field' enumerated type gives the type of the \verb'field' 7433parameter for the second argument of \verb'GxB_set' and \verb'GxB_get', 7434for setting global options or matrix options. 7435 7436{\footnotesize 7437\begin{verbatim} 7438typedef enum 7439{ 7440 // for matrix/vector get/set and global get/set: 7441 GxB_HYPER_SWITCH = 0, // defines switch to hypersparse (double value) 7442 GxB_BITMAP_SWITCH = 34, // defines switch to hypersparse (double value) 7443 GxB_FORMAT = 1, // defines CSR/CSC format: GxB_BY_ROW or GxB_BY_COL 7444 GxB_SPARSITY_CONTROL = 32, // control the sparsity of a matrix or vector 7445 7446 // for global get/set only: 7447 GxB_GLOBAL_NTHREADS = GxB_NTHREADS, // max number of threads to use 7448 GxB_GLOBAL_CHUNK = GxB_CHUNK, // chunk size for small problems 7449 GxB_BURBLE = 99, // diagnositic output 7450 GxB_PRINTF = 101, // printf function for diagnostic output 7451 GxB_FLUSH = 102, // flush function for diagnostic output 7452 7453 // for matrix/vector get only: 7454 GxB_SPARSITY_STATUS = 33, // query the sparsity of a matrix or vector 7455 7456 // for global get only: 7457 GxB_MODE = 2, // mode passed to GrB_init (blocking or non-blocking) 7458 GxB_LIBRARY_NAME = 8, // name of the library (char *) 7459 GxB_LIBRARY_VERSION = 9, // library version (3 int's) 7460 GxB_LIBRARY_DATE = 10, // date of the library (char *) 7461 GxB_LIBRARY_ABOUT = 11, // about the library (char *) 7462 GxB_LIBRARY_URL = 12, // URL for the library (char *) 7463 GxB_LIBRARY_LICENSE = 13, // license of the library (char *) 7464 GxB_LIBRARY_COMPILE_DATE = 14, // date library was compiled (char *) 7465 GxB_LIBRARY_COMPILE_TIME = 15, // time library was compiled (char *) 7466 GxB_API_VERSION = 16, // API version (3 int's) 7467 GxB_API_DATE = 17, // date of the API (char *) 7468 GxB_API_ABOUT = 18, // about the API (char *) 7469 GxB_API_URL = 19, // URL for the API (char *) 7470} 7471GxB_Option_Field ; 7472\end{verbatim} } 7473 7474The \verb'GxB_FORMAT' field can be by row or by column, set to a value 7475with the type \verb'GxB_Format_Value': 7476 7477{\footnotesize 7478\begin{verbatim} 7479typedef enum 7480{ 7481 GxB_BY_ROW = 0, // CSR: compressed sparse row format 7482 GxB_BY_COL = 1 // CSC: compressed sparse column format 7483} 7484GxB_Format_Value ; 7485\end{verbatim} } 7486 7487The default format (in SuiteSparse:GraphBLAS Version 2.2 and later) is by row. 7488The format in SuiteSparse:GraphBLAS Version 2.1 and earlier was by column, 7489just like MATLAB. 7490 7491The default format is given by the predefined value \verb'GxB_FORMAT_DEFAULT', 7492which is equal to \verb'GxB_BY_ROW' if default compile-time options are used. 7493To change the default at compile time to \verb'GxB_BY_COL', compile the 7494SuiteSparse: GraphBLAS library with \verb'-DBYCOL'. This changes 7495\verb'GxB_FORMAT_DEFAULT' to \verb'GxB_BY_COL'. The default hypersparsity 7496ratio is 0.0625 (1/16), but this value may change in the future. 7497 7498Setting the \verb'GxB_HYPER_SWITCH' field to \verb'GxB_ALWAYS_HYPER' ensures a matrix 7499always stays hypersparse. If set to \verb'GxB_NEVER_HYPER', it always stays 7500non-hypersparse. At startup, \verb'GrB_init' defines the following initial 7501settings: 7502 7503{\footnotesize 7504\begin{verbatim} 7505 GxB_set (GxB_HYPER_SWITCH, GxB_HYPER_DEFAULT) ; 7506 GxB_set (GxB_FORMAT, GxB_FORMAT_DEFAULT) ; 7507\end{verbatim} } 7508 7509That is, by default, all new matrices are held by column in CSR format, unless 7510\verb'-DBYCOL' is used at compile time, in which case the default is to store 7511all new matrices by row in CSC format. If a matrix has fewer than $n/16$ 7512columns, it can be converted to hypersparse format. If it has more than $n/8$ 7513columns, it can be converted to non-hypersparse format. These options can be 7514changed for all future matrices with \verb'GxB_set'. For example, to change 7515all future matrices to be in non-hypersparse CSC when created, use: 7516 7517{\footnotesize 7518\begin{verbatim} 7519 GxB_set (GxB_HYPER_SWITCH, GxB_NEVER_HYPER) ; 7520 GxB_set (GxB_FORMAT, GxB_BY_COL) ; 7521\end{verbatim} } 7522 7523Then if a particular matrix needs a different format, then (as an example): 7524 7525{\footnotesize 7526\begin{verbatim} 7527 GxB_set (A, GxB_HYPER_SWITCH, 0.1) ; 7528 GxB_set (A, GxB_FORMAT, GxB_BY_ROW) ; 7529\end{verbatim} } 7530 7531This changes the matrix \verb'A' so that it is stored by row, and it is 7532converted from non-hypersparse to hypersparse format if it has fewer than 10\% 7533non-empty columns. If it is hypersparse, it is a candidate for conversion to 7534non-hypersparse if has 20\% or more non-empty columns. If it has between 10\% 7535and 20\% non-empty columns, it remains in its current format. 7536MATLAB only supports a non-hypersparse CSC format. The format in 7537SuiteSparse:GraphBLAS that is equivalent to the MATLAB format is: 7538 7539{\footnotesize 7540\begin{verbatim} 7541 GrB_init (...) ; 7542 GxB_set (GxB_HYPER_SWITCH, GxB_NEVER_HYPER) ; 7543 GxB_set (GxB_FORMAT, GxB_BY_COL) ; 7544 // no subsequent use of GxB_HYPER_SWITCH or GxB_FORMAT 7545\end{verbatim} } 7546 7547The \verb'GxB_HYPER_SWITCH' and \verb'GxB_FORMAT' options should be considered as 7548suggestions from the user application as to how SuiteSparse:GraphBLAS can 7549obtain the best performance for a particular application. 7550SuiteSparse:GraphBLAS is free to ignore any of these suggestions, both now and 7551in the future, and the available options and formats may be augmented in the 7552future. Any prior options no longer needed in future versions of 7553SuiteSparse:GraphBLAS will be silently ignored, so the use these options is 7554safe for future updates. 7555 7556The sparsity status of a matrix can be queried with the following, which 7557returns a value of \verb'GxB_HYPERSPARSE' \verb'GxB_SPARSE' \verb'GxB_BITMAP' 7558or \verb'GxB_FULL'. 7559 7560{\footnotesize 7561\begin{verbatim} 7562 int sparsity ; 7563 GxB_get (A, GxB_SPARSITY_STATUS, &sparsity) ; \end{verbatim}} 7564 7565The sparsity format of a matrix can be controlled with \verb'GxB_set', which 7566can be any mix (a sum or bitwise or) of \verb'GxB_HYPERSPARSE' 7567\verb'GxB_SPARSE' \verb'GxB_BITMAP', and \verb'GxB_FULL'. By default, a matrix 7568or vector can be held in any format, with the default setting 7569\verb'GxB_AUTO_SPARSITY', which is equal to \verb'GxB_HYPERSPARSE' + 7570\verb'GxB_SPARSE' + \verb'GxB_BITMAP' + \verb'GxB_FULL'. To enable a matrix to 7571take on just \verb'GxB_SPARSE' or \verb'GxB_FULL' formats, but not 7572\verb'GxB_HYPERSPARSE' or \verb'GxB_BITMAP', for example, use the following: 7573 7574{\footnotesize 7575\begin{verbatim} 7576 GxB_set (A, GxB_SPARSITY_CONTROL, GxB_SPARSE + GxB_FULL) ; \end{verbatim}} 7577 7578In this case, SuiteSparse:GraphBLAS will hold the matrix in sparse format 7579(\verb'CSC' or \verb'CSC', depending on its \verb'GxB_FORMAT'), unless all 7580entries are present, in which case it will be converted to full format. 7581 7582Only the least 4 bits of the sparsity control are considered, so the 7583formats can be bitwise negated. For example, to allow for any format 7584except full: 7585 7586{\footnotesize 7587\begin{verbatim} 7588 GxB_set (A, GxB_SPARSITY_CONTROL, ~GxB_FULL) ; \end{verbatim}} 7589 7590%------------------------------------------------------------------------------- 7591\subsection{{\sf GxB\_BURBLE}, {\sf GxB\_PRINTF}, {\sf GxB\_FLUSH}: diagnostics} 7592%------------------------------------------------------------------------------- 7593 7594\verb'GxB_set (GxB_BURBLE, ...)' controls the burble setting. It can also be 7595controlled via \verb'GrB.burble(b)' in the MATLAB interface. 7596 7597{\footnotesize 7598\begin{verbatim} 7599 GxB_set (GxB_BURBLE, true) ; // enable burble 7600 GxB_set (GxB_BURBLE, false) ; // disable burble \end{verbatim}} 7601 7602If enabled, SuiteSparse:GraphBLAS reports which internal kernels it uses, and 7603how much time is spent. If you see the word \verb'generic', it means that 7604SuiteSparse:GraphBLAS was unable to use is faster kernels in 7605\verb'Source/Generated', but used a generic kernel that relies on function 7606pointers. This is done for user-defined types and operators, and when 7607typecasting is performed, and it is typically slower than the kernels in 7608\verb'Source/Generated'. 7609 7610If you see a lot of \verb'wait' statements, it may mean that a lot of time is 7611spent finishing a matrix or vector. This may be the result of an inefficient 7612use of the \verb'setElement' and \verb'assign' methods. If this occurs you 7613might try changing the sparsity format of a vector or matrix to 7614\verb'GxB_BITMAP', assuming there's enough space for it. 7615 7616\verb'GxB_set (GxB_PRINTF, printf)' allows the user application to change the 7617function used to print diagnostic output. This also controls the output of the 7618\verb'GxB_*print' functions. By default this parameter is \verb'NULL', in 7619which case the ANSI C11 \verb'printf' function is used. The parameter is a 7620function pointer with the same signature as the ANSI C11 \verb'printf' 7621function. The MATLAB interface to GraphBLAS uses the following so that 7622GraphBLAS can print to the MATLAB Command Window: 7623 7624{\footnotesize 7625\begin{verbatim} 7626 GxB_set (GxB_PRINTF, mexPrintf) \end{verbatim}} 7627 7628After each call to the \verb'printf' function, an optional 7629\verb'flush' function is called, which is \verb'NULL' by default. If 7630\verb'NULL', the function is not used. This can be changed with 7631\verb'GxB_set (GxB_FLUSH, flush)'. The \verb'flush' function takes no 7632arguments, and returns an \verb'int' which is 0 if successful, or any nonzero 7633value on failure (the same output as the ANSI C11 \verb'fflush' function, 7634except that \verb'flush' has no inputs). 7635 7636%------------------------------------------------------------------------------- 7637\subsection{Other global options} 7638%------------------------------------------------------------------------------- 7639 7640\verb'GxB_MODE' can only be 7641queried by \verb'GxB_get'; it cannot be modified by \verb'GxB_set'. The mode 7642is the value passed to \verb'GrB_init' (blocking or non-blocking). 7643 7644All threads in the same user application share the same global options, 7645including hypersparsity, bitmap options, and CSR/CSC format determined by 7646\verb'GxB_set', and the the blocking mode determined by \verb'GrB_init'. 7647Specific format and hypersparsity parameters of each matrix are specific to 7648that matrix and can be independently changed. 7649 7650The \verb'GxB_LIBRARY_*' options can be used with \verb'GxB_get' to query the 7651current implementation. For all of these, \verb'GxB_get' returns a string 7652(\verb'char *'), except for \verb'GxB_LIBRARY_VERSION', which takes as input an 7653\verb'int' array of size three. The \verb'GxB_API_*' options can be used with 7654\verb'GxB_get' to query the current GraphBLAS C API Specification. For all of 7655these, \verb'GxB_get' returns a string (\verb'char *'), except for 7656\verb'GxB_API_VERSION', which takes as input an \verb'int' array of size three. 7657 7658\newpage 7659%=============================================================================== 7660\subsection{{\sf GxB\_Global\_Option\_set:} set a global option} 7661%=============================================================================== 7662 7663\begin{mdframed}[userdefinedwidth=6in] 7664{\footnotesize 7665\begin{verbatim} 7666GrB_Info GxB_set // set a global default option 7667( 7668 const GxB_Option_Field field, // option to change 7669 ... // value to change it to 7670) ; 7671\end{verbatim} } \end{mdframed} 7672 7673This usage of \verb'GxB_set' sets the value of a global option. 7674The \verb'field' parameter can be 7675\verb'GxB_HYPER_SWITCH', 7676\verb'GxB_BITMAP_SWITCH', 7677\verb'GxB_FORMAT', 7678\verb'GxB_NTHREADS', 7679\verb'GxB_CHUNK', 7680\verb'GxB_BURBLE', 7681\verb'GxB_PRINTF', 7682\verb'GxB_FLUSH', 7683or 7684\verb'GxB_MEMORY_POOL'. 7685 7686For example, the following usage sets the global hypersparsity ratio to 0.2, 7687the format of future matrices to \verb'GxB_BY_COL', the maximum number 7688of threads to 4, the chunk size to 10000, and enables the burble. 7689No existing matrices are changed. 7690 7691{\footnotesize 7692\begin{verbatim} 7693 GxB_set (GxB_HYPER_SWITCH, 0.2) ; 7694 GxB_set (GxB_FORMAT, GxB_BY_COL) ; 7695 GxB_set (GxB_NTHREADS, 4) ; 7696 GxB_set (GxB_CHUNK, (double) 10000) ; 7697 GxB_set (GxB_BURBLE, true) ; 7698 GxB_set (GxB_PRINTF, mexPrintf) ; 7699\end{verbatim} } 7700 7701The memory pool parameter sets an upper bound on the number of freed blocks of 7702memory that SuiteSparse:GraphBLAS keeps in its internal memory pool for future 7703allocations. \verb'free_pool_limit' is an \verb'int64_t' array of size 64, 7704and \verb'free_pool_limit [k]' is the upper bound on the number of blocks 7705of size $2^k$ that are kept in the pool. Passing in a \verb'NULL' pointer 7706sets the defaults. Passing in an array of size 64 whose entries are all zero 7707disables the memory pool entirely. 7708 7709%=============================================================================== 7710\subsection{{\sf GxB\_Matrix\_Option\_set:} set a matrix option} 7711%=============================================================================== 7712 7713\begin{mdframed}[userdefinedwidth=6in] 7714{\footnotesize 7715\begin{verbatim} 7716GrB_Info GxB_set // set an option in a matrix 7717( 7718 GrB_Matrix A, // matrix to modify 7719 const GxB_Option_Field field, // option to change 7720 ... // value to change it to 7721) ; 7722\end{verbatim} } \end{mdframed} 7723 7724This usage of \verb'GxB_set' sets the value of a matrix option, for a 7725particular matrix. 7726The \verb'field' parameter can be 7727\verb'GxB_HYPER_SWITCH', 7728\verb'GxB_BITMAP_SWITCH', 7729\verb'GxB_SPARSITY_CONTROL', or 7730\verb'GxB_FORMAT'. 7731 7732For example, the following usage sets the hypersparsity ratio to 0.2, and the 7733format of \verb'GxB_BY_COL', for a particular matrix \verb'A', and sets the 7734sparsity control to \verb'GxB_SPARSE+GxB_FULL' (allowing the matrix to be held 7735in CSC or FullC formats, but not BitmapC or HyperCSC). SuiteSparse:GraphBLAS 7736currently applies these changes immediately, but since they are simply hints, 7737future versions of SuiteSparse:GraphBLAS may delay the change in format if it 7738can obtain better performance. 7739 7740If the setting is just \verb'GxB_FULL' and some entries are missing, then 7741the matrix is held in bitmap format. 7742 7743{\footnotesize 7744\begin{verbatim} 7745 GxB_set (A, GxB_HYPER_SWITCH, 0.2) ; 7746 GxB_set (A, GxB_FORMAT, GxB_BY_COL) ; 7747 GxB_set (A, GxB_SPARSITY_CONTROL, GxB_SPARSE + GxB_FULL) ; 7748\end{verbatim} } 7749 7750For performance, the matrix option should be set as soon as it is created with 7751\verb'GrB_Matrix_new', so the internal transformation takes less time. 7752 7753If an error occurs, \verb'GrB_error(&err,A)' returns details about the error. 7754 7755%=============================================================================== 7756\subsection{{\sf GxB\_Desc\_set:} set a {\sf GrB\_Descriptor} value} 7757%=============================================================================== 7758\label{gxbset} 7759 7760\begin{mdframed}[userdefinedwidth=6in] 7761{\footnotesize 7762\begin{verbatim} 7763GrB_Info GxB_set // set a parameter in a descriptor 7764( 7765 GrB_Descriptor desc, // descriptor to modify 7766 const GrB_Desc_Field field, // parameter to change 7767 ... // value to change it to 7768) ; 7769\end{verbatim} } \end{mdframed} 7770 7771This usage is similar to \verb'GrB_Descriptor_set', just with a name that is 7772consistent with the other usages of this generic function. Unlike 7773\verb'GrB_Descriptor_set', the \verb'field' may also be \verb'GxB_NTHREADS', 7774\verb'GxB_CHUNK', or \verb'GxB_SORT'. Refer to 7775Sections~\ref{descriptor_set}~and~\ref{desc_set} for details. 7776 7777If an error occurs, \verb'GrB_error(&err,desc)' returns details about the error. 7778 7779\newpage 7780%=============================================================================== 7781\subsection{{\sf GxB\_Global\_Option\_get:} retrieve a global option} 7782%=============================================================================== 7783\label{gxbget} 7784 7785\begin{mdframed}[userdefinedwidth=6in] 7786{\footnotesize 7787\begin{verbatim} 7788GrB_Info GxB_get // gets the current global default option 7789( 7790 const GxB_Option_Field field, // option to query 7791 ... // return value of the global option 7792) ; 7793\end{verbatim} } \end{mdframed} 7794 7795This usage of \verb'GxB_get' retrieves the value of a global option. The 7796\verb'field' parameter can be one of the following: 7797 7798\vspace{0.2in} 7799{\footnotesize 7800\begin{tabular}{ll} 7801 \hline 7802 \verb'GxB_HYPER_SWITCH' & sparse/hyper setting \\ 7803 \verb'GxB_BITMAP_SWITCH' & bitmap/sparse setting \\ 7804 \verb'GxB_FORMAT' & by row/col setting \\ 7805 \verb'GxB_MODE' & blocking / non-blocking \\ 7806 \verb'GxB_NTHREADS' & default number of threads \\ 7807 \verb'GxB_CHUNK' & default chunk size \\ 7808 \verb'GxB_BURBLE' & burble setting \\ 7809 \verb'GxB_PRINTF' & printf function \\ 7810 \verb'GxB_FLUSH' & flush function \\ 7811 \verb'GxB_MEMORY_POOL' & memory pool control \\ 7812 \hline 7813 \verb'GxB_LIBRARY_NAME' & the string 7814 \verb'"SuiteSparse:GraphBLAS"' \\ 7815 \verb'GxB_LIBRARY_VERSION' & \verb'int' array of size 3 \\ 7816 \verb'GxB_LIBRARY_DATE' & date of release \\ 7817 \verb'GxB_LIBRARY_ABOUT' & author, copyright \\ 7818 \verb'GxB_LIBRARY_LICENSE' & license for the library \\ 7819 \verb'GxB_LIBRARY_COMPILE_DATE' & date of compilation \\ 7820 \verb'GxB_LIBRARY_COMPILE_TIME' & time of compilation \\ 7821 \verb'GxB_LIBRARY_URL' & URL of the library \\ 7822 \hline 7823 \verb'GxB_API_VERSION' & GraphBLAS C API Specification Version \\ 7824 \verb'GxB_API_DATE' & date of the C API Spec. \\ 7825 \verb'GxB_API_ABOUT' & about of the C API Spec. \\ 7826 \verb'GxB_API_URL' & URL of the spec \\ 7827 \hline 7828\end{tabular} 7829} 7830\vspace{0.2in} 7831 7832For example: 7833 7834{\footnotesize 7835\begin{verbatim} 7836 double h ; 7837 GxB_get (GxB_HYPER_SWITCH, &h) ; 7838 printf ("hyper_switch = %g for all new matrices\n", h) ; 7839 7840 double b [GxB_BITMAP_SWITCH] ; 7841 GxB_get (GxB_BITMAP_SWITCH, b) ; 7842 for (int k = 0 ; k < GxB_NBITMAP_SWITCH ; k++) 7843 { 7844 printf ("bitmap_switch [%d] = %g ", k, b [k]) ; 7845 if (k == 0) 7846 { 7847 printf ("for vectors and matrices with 1 row or column\n") ; 7848 } 7849 else if (k == GxB_NBITMAP_SWITCH - 1) 7850 { 7851 printf ("for matrices with min dimension > %d\n", 1 << (k-1)) ; 7852 } 7853 else 7854 { 7855 printf ("for matrices with min dimension %d to %d\n", 7856 (1 << (k-1)) + 1, 1 << k) ; 7857 } 7858 } 7859 7860 GxB_Format_Value s ; 7861 GxB_get (GxB_FORMAT, &s) ; 7862 if (s == GxB_BY_COL) printf ("all new matrices are stored by column\n") ; 7863 else printf ("all new matrices are stored by row\n") ; 7864 7865 GrB_mode mode ; 7866 GxB_get (GxB_MODE, &mode) ; 7867 if (mode == GrB_BLOCKING) printf ("GrB_init(GrB_BLOCKING) was called.\n") ; 7868 else printf ("GrB_init(GrB_NONBLOCKING) was called.\n") ; 7869 7870 int nthreads_max ; 7871 GxB_get (GxB_NTHREADS, &nthreads_max) ; 7872 printf ("max # of threads to use: %d\n", nthreads_max) ; 7873 7874 double chunk ; 7875 GxB_get (GxB_CHUNK, &chunk) ; 7876 printf ("chunk size: %g\n", chunk) ; 7877 7878 int64_t free_pool_limit [64] ; 7879 GxB_get (GxB_MEMORY_POOL, free_pool_limit) ; 7880 for (int k = 0 ; k < 64 ; k++) 7881 printf ("pool %d: limit %ld\n", free_pool_limit [k]) ; 7882 7883 char *name ; 7884 int ver [3] ; 7885 GxB_get (GxB_LIBRARY_NAME, &name) ; 7886 GxB_get (GxB_LIBRARY_VERSION, ver) ; 7887 printf ("Library %s, version %d.%d.%d\n", name, ver [0], ver [1], ver [2]) ; \end{verbatim} } 7888 7889\newpage 7890%=============================================================================== 7891\subsection{{\sf GxB\_Matrix\_Option\_get:} retrieve a matrix option} 7892%=============================================================================== 7893 7894\begin{mdframed}[userdefinedwidth=6in] 7895{\footnotesize 7896\begin{verbatim} 7897GrB_Info GxB_get // gets the current option of a matrix 7898( 7899 GrB_Matrix A, // matrix to query 7900 GxB_Option_Field field, // option to query 7901 ... // return value of the matrix option 7902) ; 7903\end{verbatim} } \end{mdframed} 7904 7905This usage of \verb'GxB_get' retrieves the value of a matrix option. The 7906\verb'field' parameter can be 7907\verb'GxB_HYPER_SWITCH', 7908\verb'GxB_BITMAP_SWITCH', 7909\verb'GxB_SPARSITY_CONTROL', 7910\verb'GxB_SPARSITY_STATUS', 7911or 7912\verb'GxB_FORMAT'. 7913For example: 7914 7915\vspace{-0.1in} 7916{\footnotesize 7917\begin{verbatim} 7918 double h, b ; 7919 int sparsity, scontrol ; 7920 GxB_get (A, GxB_SPARSITY_STATUS, &sparsity) ; 7921 GxB_get (A, GxB_HYPER_SWITCH, &h) ; 7922 printf ("matrix A has hyper_switch = %g\n", h) ; 7923 GxB_get (A, GxB_BITMAP_SWITCH, &b) ; 7924 printf ("matrix A has bitmap_switch = %g\n", b) ; 7925 switch (sparsity) 7926 { 7927 case GxB_HYPERSPARSE: printf ("matrix A is hypersparse\n") ; break ; 7928 case GxB_SPARSE: printf ("matrix A is sparse\n" ) ; break ; 7929 case GxB_BITMAP: printf ("matrix A is bitmap\n" ) ; break ; 7930 case GxB_FULL: printf ("matrix A is full\n" ) ; break ; 7931 } 7932 GxB_Format_Value s ; 7933 GxB_get (A, GxB_FORMAT, &s) ; 7934 printf ("matrix A is stored by %s\n", (s == GxB_BY_COL) ? "col" : "row") ; 7935 GxB_get (A, GxB_SPARSITY_CONTROL, &scontrol) ; 7936 if (scontrol & GxB_HYPERSPARSE) printf ("A may become hypersparse\n") ; 7937 if (scontrol & GxB_SPARSE ) printf ("A may become sparse\n") ; 7938 if (scontrol & GxB_BITMAP ) printf ("A may become bitmap\n") ; 7939 if (scontrol & GxB_FULL ) printf ("A may become full\n") ; \end{verbatim} } 7940 7941\newpage 7942%=============================================================================== 7943\subsection{{\sf GxB\_Desc\_get:} retrieve a {\sf GrB\_Descriptor} value} 7944%=============================================================================== 7945 7946\begin{mdframed}[userdefinedwidth=6in] 7947{\footnotesize 7948\begin{verbatim} 7949GrB_Info GxB_get // get a parameter from a descriptor 7950( 7951 GrB_Descriptor desc, // descriptor to query; NULL means defaults 7952 GrB_Desc_Field field, // parameter to query 7953 ... // value of the parameter 7954) ; 7955\end{verbatim} } \end{mdframed} 7956 7957This usage is the same as \verb'GxB_Desc_get'. The \verb'field' parameter can 7958be \verb'GrB_OUTP', \verb'GrB_MASK', \verb'GrB_INP0', \verb'GrB_INP1', 7959\verb'GxB_AxB_METHOD', 7960\verb'GxB_NTHREADS', 7961\verb'GxB_CHUNK', or 7962\verb'GxB_SORT'. 7963Refer to Section~\ref{desc_get} for details. 7964 7965%=============================================================================== 7966\subsection{Summary of usage of {\sf GxB\_set} and {\sf GxB\_get}} 7967%=============================================================================== 7968 7969The different usages of \verb'GxB_set' and \verb'GxB_get' are summarized below. 7970 7971\noindent 7972To set/get the global options: 7973 7974 {\footnotesize 7975 \begin{verbatim} 7976 GxB_set (GxB_HYPER_SWITCH, double h) ; 7977 GxB_set (GxB_HYPER_SWITCH, GxB_ALWAYS_HYPER) ; 7978 GxB_set (GxB_HYPER_SWITCH, GxB_NEVER_HYPER) ; 7979 GxB_get (GxB_HYPER_SWITCH, double *h) ; 7980 double b [GxB_NBITMAP_SWITCH] ; 7981 GxB_set (GxB_BITMAP_SWITCH, b) ; 7982 GxB_set (GxB_BITMAP_SWITCH, NULL) ; // set defaults 7983 GxB_get (GxB_BITMAP_SWITCH, b) ; 7984 GxB_set (GxB_FORMAT, GxB_BY_ROW) ; 7985 GxB_set (GxB_FORMAT, GxB_BY_COL) ; 7986 GxB_get (GxB_FORMAT, GxB_Format_Value *s) ; 7987 GxB_set (GxB_NTHREADS, int nthreads_max) ; 7988 GxB_get (GxB_NTHREADS, int *nthreads_max) ; 7989 GxB_set (GxB_CHUNK, double chunk) ; 7990 GxB_get (GxB_CHUNK, double *chunk) ; 7991 GxB_set (GxB_BURBLE, bool burble) ; 7992 GxB_get (GxB_BURBLE, bool *burble) ; 7993 GxB_set (GxB_PRINTF, void *printf_function) ; 7994 GxB_get (GxB_PRINTF, void **printf_function) ; 7995 GxB_set (GxB_FLUSH, void *flush_function) ; 7996 GxB_get (GxB_FLUSH, void **flush_function) ; 7997 int64_t free_pool_limit [64] ; 7998 GxB_set (GxB_MEMORY_POOL, free_pool_limit) ; 7999 GxB_set (GxB_MEMORY_POOL, NULL) ; // set defaults 8000 GxB_get (GxB_MEMORY_POOL, free_pool_limit) ; \end{verbatim} } 8001 8002\noindent 8003To get global options that can be queried but not modified: 8004 8005 {\footnotesize 8006 \begin{verbatim} 8007 GxB_get (GxB_MODE, GrB_Mode *mode) ; 8008 GxB_get (GxB_LIBRARY_NAME, char **) ; 8009 GxB_get (GxB_LIBRARY_VERSION, int *) ; 8010 GxB_get (GxB_LIBRARY_DATE, char **) ; 8011 GxB_get (GxB_LIBRARY_ABOUT, char **) ; 8012 GxB_get (GxB_LIBRARY_LICENSE, char **) ; 8013 GxB_get (GxB_LIBRARY_COMPILE_DATE, char **) ; 8014 GxB_get (GxB_LIBRARY_COMPILE_TIME, char **) ; 8015 GxB_get (GxB_LIBRARY_URL, char **) ; 8016 GxB_get (GxB_API_VERSION, int *) ; 8017 GxB_get (GxB_API_DATE, char **) ; 8018 GxB_get (GxB_API_ABOUT, char **) ; 8019 GxB_get (GxB_API_URL, char **) ; \end{verbatim} } 8020 8021\noindent 8022To set/get a matrix option or status 8023 8024 {\footnotesize 8025 \begin{verbatim} 8026 GxB_set (GrB_Matrix A, GxB_HYPER_SWITCH, double h) ; 8027 GxB_set (GrB_Matrix A, GxB_HYPER_SWITCH, GxB_ALWAYS_HYPER) ; 8028 GxB_set (GrB_Matrix A, GxB_HYPER_SWITCH, GxB_NEVER_HYPER) ; 8029 GxB_get (GrB_Matrix A, GxB_HYPER_SWITCH, double *h) ; 8030 GxB_set (GrB_Matrix A, GxB_BITMAP_SWITCH, double b) ; 8031 GxB_get (GrB_Matrix A, GxB_BITMAP_SWITCH, double *b) ; 8032 GxB_set (GrB_Matrix A, GxB_FORMAT, GxB_BY_ROW) ; 8033 GxB_set (GrB_Matrix A, GxB_FORMAT, GxB_BY_COL) ; 8034 GxB_get (GrB_Matrix A, GxB_FORMAT, GxB_Format_Value *s) ; 8035 GxB_set (GrB_Matrix A, GxB_SPARSITY_CONTROL, GxB_AUTO_SPARSITY) ; 8036 GxB_set (GrB_Matrix A, GxB_SPARSITY_CONTROL, scontrol) ; 8037 GxB_get (GrB_Matrix A, GxB_SPARSITY_CONTROL, int *scontrol) ; 8038 GxB_get (GrB_Matrix A, GxB_SPARSITY_STATUS, int *sparsity) ; \end{verbatim} } 8039 8040\noindent 8041To set/get a vector option or status: 8042 8043 {\footnotesize 8044 \begin{verbatim} 8045 GxB_set (GrB_Vector v, GxB_BITMAP_SWITCH, double b) ; 8046 GxB_get (GrB_Vector v, GxB_BITMAP_SWITCH, double *b) ; 8047 GxB_set (GrB_Vector v, GxB_FORMAT, GxB_BY_ROW) ; 8048 GxB_set (GrB_Vector v, GxB_FORMAT, GxB_BY_COL) ; 8049 GxB_get (GrB_Vector v, GxB_FORMAT, GxB_Format_Value *s) ; 8050 GxB_set (GrB_Vector v, GxB_SPARSITY_CONTROL, GxB_AUTO_SPARSITY) ; 8051 GxB_set (GrB_Vector v, GxB_SPARSITY_CONTROL, scontrol) ; 8052 GxB_get (GrB_Vector v, GxB_SPARSITY_CONTROL, int *scontrol) ; 8053 GxB_get (GrB_Vector v, GxB_SPARSITY_STATUS, int *sparsity) ; \end{verbatim} } 8054 8055\noindent 8056To set/get a descriptor field: 8057 8058 {\footnotesize 8059 \begin{verbatim} 8060 GxB_set (GrB_Descriptor d, GrB_OUTP, GxB_DEFAULT) ; 8061 GxB_set (GrB_Descriptor d, GrB_OUTP, GrB_REPLACE) ; 8062 GxB_get (GrB_Descriptor d, GrB_OUTP, GrB_Desc_Value *v) ; 8063 GxB_set (GrB_Descriptor d, GrB_MASK, GxB_DEFAULT) ; 8064 GxB_set (GrB_Descriptor d, GrB_MASK, GrB_COMP) ; 8065 GxB_set (GrB_Descriptor d, GrB_MASK, GrB_STRUCTURE) ; 8066 GxB_set (GrB_Descriptor d, GrB_MASK, GrB_COMP+GrB_STRUCTURE) ; 8067 GxB_get (GrB_Descriptor d, GrB_MASK, GrB_Desc_Value *v) ; 8068 GxB_set (GrB_Descriptor d, GrB_INP0, GxB_DEFAULT) ; 8069 GxB_set (GrB_Descriptor d, GrB_INP0, GrB_TRAN) ; 8070 GxB_get (GrB_Descriptor d, GrB_INP0, GrB_Desc_Value *v) ; 8071 GxB_set (GrB_Descriptor d, GrB_INP1, GxB_DEFAULT) ; 8072 GxB_set (GrB_Descriptor d, GrB_INP1, GrB_TRAN) ; 8073 GxB_get (GrB_Descriptor d, GrB_INP1, GrB_Desc_Value *v) ; 8074 GxB_set (GrB_Descriptor d, GxB_AxB_METHOD, GxB_DEFAULT) ; 8075 GxB_set (GrB_Descriptor d, GxB_AxB_METHOD, GxB_AxB_GUSTAVSON) ; 8076 GxB_set (GrB_Descriptor d, GxB_AxB_METHOD, GxB_AxB_HASH) ; 8077 GxB_set (GrB_Descriptor d, GxB_AxB_METHOD, GxB_AxB_SAXPY) ; 8078 GxB_set (GrB_Descriptor d, GxB_AxB_METHOD, GxB_AxB_DOT) ; 8079 GxB_get (GrB_Descriptor d, GrB_AxB_METHOD, GrB_Desc_Value *v) ; 8080 GxB_set (GrB_Descriptor d, GxB_NTHREADS, int nthreads) ; 8081 GxB_get (GrB_Descriptor d, GxB_NTHREADS, int *nthreads) ; 8082 GxB_set (GrB_Descriptor d, GxB_CHUNK, double chunk) ; 8083 GxB_get (GrB_Descriptor d, GxB_CHUNK, double *chunk) ; 8084 GxB_set (GrB_Descriptor d, GxB_SORT, sort) ; 8085 GxB_get (GrB_Descriptor d, GxB_SORT, int *sort) ; \end{verbatim} } 8086 8087\newpage 8088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8089\section{SuiteSparse:GraphBLAS Colon and Index Notation} %%%%%%%%%%%%%%%%%%%%%%% 8090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8091\label{colon} 8092 8093MATLAB uses a colon notation to index into matrices, such as 8094\verb'C=A(2:4,3:8)', which extracts \verb'C' as 3-by-6 submatrix from \verb'A', 8095from rows 2 through 4 and columns 3 to 8 of the matrix \verb'A'. A single 8096colon is used to denote all rows, \verb'C=A(:,9)', or all columns, 8097\verb'C=A(12,:)', which refers to the 9th column and 12th row of \verb'A', 8098respectively. An arbitrary integer list can be given as well, such as the 8099MATLAB statements: 8100 8101 {\footnotesize 8102 \begin{verbatim} 8103 I = [2 1 4] ; 8104 J = [3 5] ; 8105 C = A (I,J) ; \end{verbatim} } 8106\noindent 8107which creates the 3-by-2 matrix \verb'C' as follows: 8108\[ 8109C = 8110\left[ 8111\begin{array}{cc} 8112a_{2,3} & a_{2,5} \\ 8113a_{1,3} & a_{1,5} \\ 8114a_{4,3} & a_{4,5} \\ 8115\end{array} 8116\right] 8117\] 8118 8119The GraphBLAS API can do the equivalent of \verb'C=A(I,J)', 8120\verb'C=A(:,J)', \verb'C=A(I,:)', and \verb'C=A(:,:)', by passing a parameter 8121\verb'const GrB_Index *I' as either an array of size \verb'ni', or as the 8122special value \verb'GrB_ALL', which corresponds to the stand-alone colon 8123\verb'C=A(:,J)', and the same can be done for \verb'J'.. To compute 8124\verb'C=A(2:4,3:8)' in GraphBLAS requires the user application to create two 8125explicit integer arrays \verb'I' and \verb'J' of size 3 and 5, respectively, 8126and then fill them with the explicit values \verb'[2,3,4]' and 8127\verb'[3,4,5,6,7,8]'. This works well if the lists are small, or if the matrix 8128has more entries than rows or columns. 8129 8130However, particularly with hypersparse matrices, the size of the explicit 8131arrays \verb'I' and \verb'J' can vastly exceed the number of entries in the 8132matrix. When using its hypersparse format, SuiteSparse:GraphBLAS allows the 8133user application to create a \verb'GrB_Matrix' with dimensions up to $2^{60}$, 8134with no memory constraints. The only constraint on memory usage in a 8135hypersparse matrix is the number of entries in the matrix. 8136 8137For example, creating a $n$-by-$n$ matrix \verb'A' of type \verb'GrB_FP64' with 8138$n=2^{60}$ and one million entries is trivial to do in Version 2.1 (and later) 8139of SuiteSparse:GraphBLAS, taking at most 24MB of space. SuiteSparse:GraphBLAS 8140Version 2.1 (or later) could do this on an old smartphone. However, using just 8141the pure GraphBLAS API, constructing \verb'C=A(0:(n/2),0:(n/2))' 8142in SuiteSparse Version 2.0 would require the creation of an integer array 8143\verb'I' of size $2^{59}$, containing the sequence 0, 1, 2, 3, ...., requiring 8144about 4 ExaBytes of memory (4 million terabytes). This is roughly 1000 times 8145larger than the memory size of the world's largest computer in 2018. 8146 8147SuiteSparse:GraphBLAS Version 2.1 and later extends the GraphBLAS API with a 8148full implementation of the MATLAB colon notation for integers, 8149\verb'I=begin:inc:end'. This extension allows the construction of the matrix 8150\verb'C=A(0:(n/2),0:(n/2))' in this example, with dimension $2^{59}$, probably 8151taking just milliseconds on an old smartphone. 8152 8153The \verb'GrB_extract', \verb'GrB_assign', and \verb'GxB_subassign' operations 8154(described in the Section~\ref{operations}) each have parameters that define a 8155list of integer indices, using two parameters: 8156 8157 \vspace{-0.05in} 8158 {\footnotesize 8159 \begin{verbatim} 8160 const GrB_Index *I ; // an array, or a special value GrB_ALL 8161 GrB_Index ni ; // the size of I, or a special value \end{verbatim}} 8162 8163\vspace{-0.05in} 8164These two parameters define five kinds of index lists, which can be used to 8165specify either an explicit or implicit list of row indices and/or column 8166indices. The length of the list of indices is denoted \verb'|I|'. This 8167discussion applies equally to the row indices \verb'I' and the column indices 8168\verb'J'. The five kinds are listed below. 8169 8170\begin{enumerate} 8171\item 8172 An explicit list of indices, such as \verb'I = [2 1 4 7 2]' in MATLAB 8173 notation, is handled by passing in \verb'I' as a pointer to an array of 8174 size 5, and passing \verb'ni=5' as the size of the list. 8175 The length of the explicit list is \verb'ni=|I|'. 8176 Duplicates may appear, except that for some uses of \verb'GrB_assign' 8177 and \verb'GxB_subassign', duplicates lead to undefined behavior 8178 according to the GraphBLAS C API Specification. 8179 SuiteSparse:GraphBLAS specifies how duplicates are handled in all cases, 8180 as an addition to the specification. 8181 See Section~\ref{duplicates} for details. 8182 8183\item To specify all rows of a matrix, use \verb'I = GrB_ALL'. The 8184 parameter \verb'ni' is ignored. This is equivalent to \verb'C=A(:,J)' 8185 in MATLAB. In GraphBLAS, this is the sequence \verb'0:(m-1)' if \verb'A' 8186 has \verb'm' rows, with length \verb'|I|=m'. If \verb'J' is used the 8187 columns of an \verb'm'-by-\verb'n' matrix, then \verb'J=GrB_ALL' refers to 8188 all columns, and is the sequence \verb'0:(n-1)', of length \verb'|J|=n'. 8189 8190\item To specify a contiguous range of indices, such as \verb'I=10:20' 8191 in MATLAB, the array \verb'I' has size 2, and \verb'ni' is passed to 8192 SuiteSparse:GraphBLAS as the special value \verb'ni = GxB_RANGE'. The 8193 beginning index is \verb'I[GxB_BEGIN]' and the ending index is 8194 \verb'I[GxB_END]'. Both values must be non-negative since 8195 \verb'GrB_Index' is an unsigned integer (\verb'uint64_t'). The value of 8196 \verb'I[GxB_INC]' is ignored. 8197 8198 \vspace{-0.05in} 8199 {\footnotesize 8200 \begin{verbatim} 8201 // to specify I = 10:20 8202 GrB_Index I [2], ni = GxB_RANGE ; 8203 I [GxB_BEGIN] = 10 ; // the start of the sequence 8204 I [GxB_END ] = 20 ; // the end of the sequence \end{verbatim}} 8205 8206 \vspace{-0.05in} 8207 Let $b$ = \verb'I[GxB_BEGIN]', let $e$ = \verb'I[GxB_END]', 8208 The sequence has length zero if $b > e$; otherwise the length is 8209 $|I| = (e-b) + 1$. 8210 8211\item To specify a strided range of indices with a non-negative stride, 8212 such as \verb'I=3:2:10', the array \verb'I' has size 3, and \verb'ni' has 8213 the special value \verb'GxB_STRIDE'. This is the sequence 3, 5, 7, 9, of 8214 length 4. Note that 10 does not appear in the list. The end point need 8215 not appear if the increment goes past it. 8216 8217 \vspace{-0.05in} 8218 {\footnotesize 8219 \begin{verbatim} 8220 // to specify I = 3:2:10 8221 GrB_Index I [3], ni = GxB_STRIDE ; 8222 I [GxB_BEGIN ] = 3 ; // the start of the sequence 8223 I [GxB_INC ] = 2 ; // the increment 8224 I [GxB_END ] = 10 ; // the end of the sequence \end{verbatim}} 8225 8226 \vspace{-0.05in} 8227 The \verb'GxB_STRIDE' sequence is the same as the \verb'List' generated by 8228 the following for loop: 8229 8230 \vspace{-0.05in} 8231 {\footnotesize 8232 \begin{verbatim} 8233 int64_t k = 0 ; 8234 GrB_Index *List = (a pointer to an array of large enough size) 8235 for (int64_t i = I [GxB_BEGIN] ; i <= I [GxB_END] ; i += I [GxB_INC]) 8236 { 8237 // i is the kth entry in the sequence 8238 List [k++] = i ; 8239 } \end{verbatim}} 8240 8241 \vspace{-0.05in} 8242 Then passing the explicit array \verb'List' and its length \verb'ni=k' has 8243 the same effect as passing in the array \verb'I' of size 3, with 8244 \verb'ni=GxB_STRIDE'. The latter is simply much faster to produce, and 8245 much more efficient for SuiteSparse:GraphBLAS to process. 8246 8247 Let $b$ = \verb'I[GxB_BEGIN]', let $e$ = \verb'I[GxB_END]', and let 8248 $\Delta$ = \verb'I[GxB_INC]'. The sequence has length zero if $b > e$ or 8249 $\Delta=0$. Otherwise, the length of the sequence is 8250 \[ 8251 |I| = \Bigl\lfloor\dfrac{e-b}{\Delta}\Bigr\rfloor + 1 8252 \] 8253 8254\item 8255 In MATLAB notation, if the stride is negative, the sequence is decreasing. 8256 For example, \verb'10:-2:1' is the sequence 10, 8, 6, 4, 2, in that order. 8257 In SuiteSparse:GraphBLAS, use \verb'ni = GxB_BACKWARDS', with an array 8258 \verb'I' of size 3. The following example specifies defines the equivalent 8259 of the MATLAB expression \verb'10:-2:1' in SuiteSparse:GraphBLAS: 8260 8261 \vspace{-0.1in} 8262 {\footnotesize 8263 \begin{verbatim} 8264 // to specify I = 10:-2:1 8265 GrB_Index I [3], ni = GxB_BACKWARDS ; 8266 I [GxB_BEGIN ] = 10 ; // the start of the sequence 8267 I [GxB_INC ] = 2 ; // the magnitude of the increment 8268 I [GxB_END ] = 1 ; // the end of the sequence \end{verbatim}} 8269 8270 \vspace{-0.1in} 8271 The value -2 cannot be assigned to the \verb'GrB_Index' array \verb'I', 8272 since that is an unsigned type. The signed increment is represented 8273 instead with the special value \verb'ni = GxB_BACKWARDS'. 8274 The \verb'GxB_BACKWARDS' sequence is the same as generated by the following 8275 for loop: 8276 8277 \vspace{-0.1in} 8278 {\footnotesize 8279 \begin{verbatim} 8280 int64_t k = 0 ; 8281 GrB_Index *List = (a pointer to an array of large enough size) 8282 for (int64_t i = I [GxB_BEGIN] ; i >= I [GxB_END] ; i -= I [GxB_INC]) 8283 { 8284 // i is the kth entry in the sequence 8285 List [k++] = i ; 8286 } \end{verbatim}} 8287 8288 \vspace{-0.1in} 8289 Let $b$ = \verb'I[GxB_BEGIN]', let $e$ = \verb'I[GxB_END]', and let 8290 $\Delta$ = \verb'I[GxB_INC]' (note that $\Delta$ is not negative). The 8291 sequence has length zero if $b < e$ or $\Delta=0$. Otherwise, the length 8292 of the sequence is 8293 \[ 8294 |I| = \Bigl\lfloor\dfrac{b-e}{\Delta}\Bigr\rfloor + 1 8295 \] 8296 8297\end{enumerate} 8298 8299Since \verb'GrB_Index' is an unsigned integer, all three values 8300\verb'I[GxB_BEGIN]', \verb'I[GxB_INC]', and \verb'I[GxB_END]' must 8301be non-negative. 8302 8303Just as in MATLAB, it is valid to specify an empty sequence of length zero. 8304For example, \verb'I = 5:3' has length zero in MATLAB and the same is 8305true for a \verb'GxB_RANGE' sequence in SuiteSparse:GraphBLAS, with 8306\verb'I[GxB_BEGIN]=5' and \verb'I[GxB_END]=3'. This has the same 8307effect as array \verb'I' with \verb'ni=0'. 8308 8309\newpage 8310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8311\section{GraphBLAS Operations} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8312%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8313\label{operations} 8314 8315The next sections define each of the GraphBLAS operations, also listed in the 8316table below. SuiteSparse:GraphBLAS extensions (\verb'GxB_subassign', 8317\verb'GxB_select') are included in the table. 8318 8319\vspace{0.2in} 8320{\small 8321\begin{tabular}{lll} 8322\hline 8323\verb'GrB_mxm' & matrix-matrix multiply & ${\bf C \langle M \rangle = C \odot AB}$ \\ 8324\verb'GrB_vxm' & vector-matrix multiply & ${\bf w^{\sf T}\langle m^{\sf T}\rangle = w^{\sf T}\odot u^{\sf T}A}$ \\ 8325\verb'GrB_mxv' & matrix-vector multiply & ${\bf w \langle m \rangle = w \odot Au}$ \\ 8326\hline 8327\verb'GrB_eWiseMult' & element-wise, & ${\bf C \langle M \rangle = C \odot (A \otimes B)}$ \\ 8328 & set union & ${\bf w \langle m \rangle = w \odot (u \otimes v)}$ \\ 8329\hline 8330\verb'GrB_eWiseAdd' & element-wise, & ${\bf C \langle M \rangle = C \odot (A \oplus B)}$ \\ 8331 & set intersection & ${\bf w \langle m \rangle = w \odot (u \oplus v)}$ \\ 8332\hline 8333\verb'GrB_extract' & extract submatrix & ${\bf C \langle M \rangle = C \odot A(I,J)}$ \\ 8334 & & ${\bf w \langle m \rangle = w \odot u(i)}$ \\ 8335\hline 8336\verb'GxB_subassign' & assign submatrix, & ${\bf C (I,J) \langle M \rangle = C(I,J) \odot A}$ \\ 8337 & with submask for ${\bf C(I,J)}$ 8338 & ${\bf w (i) \langle m \rangle = w(i) \odot u}$ \\ 8339\hline 8340\verb'GrB_assign' & assign submatrix & ${\bf C \langle M \rangle (I,J) = C(I,J) \odot A}$ \\ 8341 & with submask for ${\bf C}$ 8342 & ${\bf w \langle m \rangle (i) = w(i) \odot u}$ \\ 8343\hline 8344\verb'GrB_apply' & apply unary operator & ${\bf C \langle M \rangle = C \odot} f{\bf (A)}$ \\ 8345 & & ${\bf w \langle m \rangle = w \odot} f{\bf (u)}$ \\ 8346 & apply binary operator & ${\bf C \langle M \rangle = C \odot} f(x,{\bf A})$ \\ 8347 & & ${\bf C \langle M \rangle = C \odot} f({\bf A},y)$ \\ 8348 & & ${\bf w \langle m \rangle = w \odot} f(x,{\bf x})$ \\ 8349 & & ${\bf w \langle m \rangle = w \odot} f({\bf u},y)$ \\ 8350\hline 8351\verb'GxB_select' & apply select operator & ${\bf C \langle M \rangle = C \odot} f{\bf (A,k)}$ \\ 8352 & & ${\bf w \langle m \rangle = w \odot} f{\bf (u,k)}$ \\ 8353\hline 8354\verb'GrB_reduce' & reduce to vector & ${\bf w \langle m \rangle = w \odot} [{\oplus}_j {\bf A}(:,j)]$ \\ 8355 & reduce to scalar & $s = s \odot [{\oplus}_{ij} {\bf A}(I,J)]$ \\ 8356\hline 8357\verb'GrB_transpose' & transpose & ${\bf C \langle M \rangle = C \odot A^{\sf T}}$ \\ 8358\hline 8359\verb'GrB_kronecker' & Kronecker product & ${\bf C \langle M \rangle = C \odot \mbox{kron}(A, B)}$ \\ 8360\hline 8361\end{tabular} 8362} 8363\vspace{0.2in} 8364 8365If an error occurs, \verb'GrB_error(&err,C)' or \verb'GrB_error(&err,w)' 8366returns details about the error, for operations that return a modified matrix 8367\verb'C' or vector \verb'w'. The only operation that cannot return an error 8368string is reduction to a scalar with \verb'GrB_reduce'. 8369 8370\newpage 8371%=============================================================================== 8372\subsection{{\sf GrB\_mxm:} matrix-matrix multiply} %=========================== 8373%=============================================================================== 8374\label{mxm} 8375 8376\begin{mdframed}[userdefinedwidth=6in] 8377{\footnotesize 8378\begin{verbatim} 8379GrB_Info GrB_mxm // C<Mask> = accum (C, A*B) 8380( 8381 GrB_Matrix C, // input/output matrix for results 8382 const GrB_Matrix Mask, // optional mask for C, unused if NULL 8383 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 8384 const GrB_Semiring semiring, // defines '+' and '*' for A*B 8385 const GrB_Matrix A, // first input: matrix A 8386 const GrB_Matrix B, // second input: matrix B 8387 const GrB_Descriptor desc // descriptor for C, Mask, A, and B 8388) ; 8389\end{verbatim} } \end{mdframed} 8390 8391\verb'GrB_mxm' multiplies two sparse matrices \verb'A' and \verb'B' using the 8392\verb'semiring'. The input matrices \verb'A' and \verb'B' may be transposed 8393according to the descriptor, \verb'desc' (which may be \verb'NULL') and then 8394typecasted to match the multiply operator of the \verb'semiring'. Next, 8395\verb'T=A*B' is computed on the \verb'semiring', precisely defined in the 8396\verb'GB_spec_mxm.m' script in \verb'GraphBLAS/Test'. The actual algorithm 8397exploits sparsity and does not take $O(n^3)$ time, but it computes the 8398following: 8399 8400{\footnotesize 8401\begin{verbatim} 8402[m s] = size (A.matrix) ; 8403[s n] = size (B.matrix) ; 8404T.matrix = zeros (m, n, multiply.ztype) ; 8405T.pattern = zeros (m, n, 'logical') ; 8406T.matrix (:,:) = identity ; % the identity of the semiring's monoid 8407T.class = multiply.ztype ; % the ztype of the semiring's multiply op 8408A = cast (A.matrix, multiply.xtype) ; % the xtype of the semiring's multiply op 8409B = cast (B.matrix, multiply.ytype) ; % the ytype of the semiring's multiply op 8410for j = 1:n 8411 for i = 1:m 8412 for k = 1:s 8413 % T (i,j) += A (i,k) * B (k,j), using the semiring 8414 if (A.pattern (i,k) && B.pattern (k,j)) 8415 z = multiply (A (i,k), B (k,j)) ; 8416 T.matrix (i,j) = add (T.matrix (i,j), z) ; 8417 T.pattern (i,j) = true ; 8418 end 8419 end 8420 end 8421end \end{verbatim}} 8422 8423Finally, \verb'T' is typecasted into the type of \verb'C', and the results are 8424written back into \verb'C' via the \verb'accum' and \verb'Mask', ${\bf C 8425\langle M \rangle = C \odot T}$. The latter step is reflected in the MATLAB 8426function \verb'GB_spec_accum_mask.m', discussed in Section~\ref{accummask}. 8427 8428\paragraph{\bf Performance considerations:} 8429Suppose all matrices are in \verb'GxB_BY_COL' format, and \verb'B' is extremely 8430sparse but \verb'A' is not as sparse. Then computing \verb'C=A*B' is very 8431fast, and much faster than when \verb'A' is extremely sparse. For example, if 8432\verb'A' is square and \verb'B' is a column vector that is all nonzero except 8433for one entry \verb'B(j,0)=1', then \verb'C=A*B' is the same as extracting 8434column \verb'A(:,j)'. This is very fast if \verb'A' is stored by column but 8435slow if \verb'A' is stored by row. If \verb'A' is a sparse row with a single 8436entry \verb'A(0,i)=1', then \verb'C=A*B' is the same as extracting row 8437\verb'B(i,:)'. This is fast if \verb'B' is stored by row but slow if \verb'B' 8438is stored by column. 8439 8440If the user application needs to repeatedly extract rows and columns from a 8441matrix, whether by matrix multiplication or by \verb'GrB_extract', then keep 8442two copies: one stored by row, and other by column, and use the copy that 8443results in the fastest computation. 8444 8445By default, \verb'GrB_mxm', \verb'GrB_mxv', \verb'GrB_vxm', and 8446\verb'GrB_reduce' (to vector) can return their result in a jumbled state, with 8447the sort left pending. It can sometimes be faster for these methods to do the 8448sort as they compute their result. Use the \verb'GxB_SORT' descriptor setting 8449to select this option. Refer to Section~\ref{descriptor} for details. 8450 8451\newpage 8452%=============================================================================== 8453\subsection{{\sf GrB\_vxm:} vector-matrix multiply} %=========================== 8454%=============================================================================== 8455\label{vxm} 8456 8457\begin{mdframed}[userdefinedwidth=6in] 8458{\footnotesize 8459\begin{verbatim} 8460GrB_Info GrB_vxm // w'<mask> = accum (w, u'*A) 8461( 8462 GrB_Vector w, // input/output vector for results 8463 const GrB_Vector mask, // optional mask for w, unused if NULL 8464 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 8465 const GrB_Semiring semiring, // defines '+' and '*' for u'*A 8466 const GrB_Vector u, // first input: vector u 8467 const GrB_Matrix A, // second input: matrix A 8468 const GrB_Descriptor desc // descriptor for w, mask, and A 8469) ; 8470\end{verbatim} } \end{mdframed} 8471 8472\verb'GrB_vxm' multiplies a row vector \verb"u'" times a matrix \verb'A'. The 8473matrix \verb'A' may be first transposed according to \verb'desc' (as the second 8474input, \verb'GrB_INP1'); the column vector \verb'u' is never transposed via the 8475descriptor. The inputs \verb'u' and \verb'A' are typecasted to match the 8476\verb'xtype' and \verb'ytype' inputs, respectively, of the multiply operator of 8477the \verb'semiring'. Next, an intermediate column vector \verb"t=A'*u" is 8478computed on the \verb'semiring' using the same method as \verb'GrB_mxm'. 8479Finally, the column vector \verb't' is typecasted from the \verb'ztype' of the 8480multiply operator of the \verb'semiring' into the type of \verb'w', and the 8481results are written back into \verb'w' using the optional accumulator 8482\verb'accum' and \verb'mask'. 8483 8484The last step is ${\bf w \langle m \rangle = w \odot t}$, as described 8485in Section~\ref{accummask}, except that all the 8486terms are column vectors instead of matrices. 8487 8488\paragraph{\bf Performance considerations:} % u'=u'*A 8489If the \verb'GxB_FORMAT' of \verb'A' is \verb'GxB_BY_ROW', and the default 8490descriptor is used (\verb'A' is not transposed), then \verb'GrB_vxm' is faster 8491than than \verb'GrB_mxv' with its default descriptor, when the vector \verb'u' 8492is very sparse. 8493However, if the \verb'GxB_FORMAT' of \verb'A' is \verb'GxB_BY_COL', then 8494\verb'GrB_mxv' with its default descriptor is faster than \verb'GrB_vxm' with 8495its default descriptor, when the vector \verb'u' is very sparse. 8496Using the non-default \verb'GrB_TRAN' descriptor for \verb'A' makes the 8497\verb'GrB_vxm' operation equivalent to \verb'GrB_mxv' with its default 8498descriptor (with the operands reversed in the multiplier, as well). The 8499reverse is true as well; \verb'GrB_mxv' with \verb'GrB_TRAN' is the same as 8500\verb'GrB_vxm' with a default descriptor. 8501 8502The breadth-first search presented in Section~\ref{bfs} of this User Guide uses 8503\verb'GrB_vxm' instead of \verb'GrB_mxv', since the default format in 8504SuiteSparse:GraphBLAS is \verb'GxB_BY_ROW'. This corresponds to ``push'' step 8505of a direction-optimized BFS. If the matrix is stored by column, then use 8506\verb'GrB_mxv' for the ``push'' instead. 8507 8508\newpage 8509%=============================================================================== 8510\subsection{{\sf GrB\_mxv:} matrix-vector multiply} %=========================== 8511%=============================================================================== 8512\label{mxv} 8513 8514\begin{mdframed}[userdefinedwidth=6in] 8515{\footnotesize 8516\begin{verbatim} 8517GrB_Info GrB_mxv // w<mask> = accum (w, A*u) 8518( 8519 GrB_Vector w, // input/output vector for results 8520 const GrB_Vector mask, // optional mask for w, unused if NULL 8521 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 8522 const GrB_Semiring semiring, // defines '+' and '*' for A*B 8523 const GrB_Matrix A, // first input: matrix A 8524 const GrB_Vector u, // second input: vector u 8525 const GrB_Descriptor desc // descriptor for w, mask, and A 8526) ; 8527\end{verbatim} } \end{mdframed} 8528 8529\verb'GrB_mxv' multiplies a matrix \verb'A' times a column vector \verb'u'. 8530The matrix \verb'A' may be first transposed according to \verb'desc' (as the 8531first input); the column vector \verb'u' is never transposed via the 8532descriptor. The inputs \verb'A' and \verb'u' are typecasted to match the 8533\verb'xtype' and \verb'ytype' inputs, respectively, of the multiply operator of 8534the \verb'semiring'. Next, an intermediate column vector \verb't=A*u' is 8535computed on the \verb'semiring' using the same method as \verb'GrB_mxm'. 8536Finally, the column vector \verb't' is typecasted from the \verb'ztype' of the 8537multiply operator of the \verb'semiring' into the type of \verb'w', and the 8538results are written back into \verb'w' using the optional accumulator 8539\verb'accum' and \verb'mask'. 8540 8541The last step is ${\bf w \langle m \rangle = w \odot t}$, as described 8542in Section~\ref{accummask}, except that all the terms are column vectors instead 8543of matrices. 8544 8545\paragraph{\bf Performance considerations:} % u=A*u 8546Refer to the discussion of \verb'GrB_vxm'. In SuiteSparse:GraphBLAS, 8547\verb'GrB_mxv' is very efficient when \verb'u' is sparse or dense, when the 8548default descriptor is used, and when the matrix is \verb'GxB_BY_COL'. When 8549\verb'u' is very sparse and \verb'GrB_INP0' is set to its non-default 8550\verb'GrB_TRAN', then this method is not efficient if the matrix is in 8551\verb'GxB_BY_COL' format. If an application needs to perform \verb"A'*u" 8552repeatedly where \verb'u' is very sparse, then use the \verb'GxB_BY_ROW' format 8553for \verb'A' instead. 8554 8555\newpage 8556%=============================================================================== 8557\subsection{{\sf GrB\_eWiseMult:} element-wise operations, set intersection} %== 8558%=============================================================================== 8559\label{eWiseMult} 8560 8561Element-wise ``multiplication'' is shorthand for applying a binary operator 8562element-wise on two matrices or vectors \verb'A' and \verb'B', for all entries 8563that appear in the set intersection of the patterns of \verb'A' and \verb'B'. 8564This is like \verb'A.*B' for two sparse matrices in MATLAB, except that in 8565GraphBLAS any binary operator can be used, not just multiplication. 8566 8567The pattern of the result of the element-wise ``multiplication'' is exactly 8568this set intersection. Entries in \verb'A' but not \verb'B', or visa versa, do 8569not appear in the result. 8570 8571Let $\otimes$ denote the binary operator to be used. The computation ${\bf T = 8572A \otimes B}$ is given below. Entries not in the intersection of ${\bf A}$ and 8573${\bf B}$ do not appear in the pattern of ${\bf T}$. That is: 8574 \vspace{-0.2in} 8575 {\small 8576 \begin{tabbing} 8577 \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \\ 8578 \> for all entries $(i,j)$ in ${\bf A \cap B}$ \\ 8579 \> \> $t_{ij} = a_{ij} \otimes b_{ij}$ \\ 8580 \end{tabbing} } 8581 \vspace{-0.2in} 8582 8583Depending on what kind of operator is used and what the implicit value is 8584assumed to be, this can give the Hadamard product. This is the case for 8585\verb'A.*B' in MATLAB since the implicit value is zero. However, computing a 8586Hadamard product is not necessarily the goal of the \verb'eWiseMult' operation. 8587It simply applies any binary operator, built-in or user-defined, to the set 8588intersection of \verb'A' and \verb'B', and discards any entry outside this 8589intersection. Its usefulness in a user's application does not depend upon it 8590computing a Hadamard product in all cases. The operator need not be 8591associative, commutative, nor have any particular property except for type 8592compatibility with \verb'A' and \verb'B', and the output matrix \verb'C'. 8593 8594The generic name for this operation is \verb'GrB_eWiseMult', which can be used 8595for both matrices and vectors. 8596 8597\newpage 8598%------------------------------------------------------------------------------- 8599\subsubsection{{\sf GrB\_eWiseMult\_Vector:} element-wise vector multiply} 8600%------------------------------------------------------------------------------- 8601\label{eWiseMult_vector} 8602 8603\begin{mdframed}[userdefinedwidth=6in] 8604{\footnotesize 8605\begin{verbatim} 8606GrB_Info GrB_eWiseMult // w<mask> = accum (w, u.*v) 8607( 8608 GrB_Vector w, // input/output vector for results 8609 const GrB_Vector mask, // optional mask for w, unused if NULL 8610 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 8611 const <operator> multiply, // defines '.*' for t=u.*v 8612 const GrB_Vector u, // first input: vector u 8613 const GrB_Vector v, // second input: vector v 8614 const GrB_Descriptor desc // descriptor for w and mask 8615) ; 8616\end{verbatim} 8617} \end{mdframed} 8618 8619\verb'GrB_Vector_eWiseMult' computes the element-wise ``multiplication'' of two 8620vectors \verb'u' and \verb'v', element-wise using any binary operator (not just 8621times). The vectors are not transposed via the descriptor. The vectors 8622\verb'u' and \verb'v' are first typecasted into the first and second inputs of 8623the \verb'multiply' operator. Next, a column vector \verb't' is computed, 8624denoted ${\bf t = u \otimes v}$. The pattern of \verb't' is the set 8625intersection of \verb'u' and \verb'v'. The result \verb't' has the type of the 8626output \verb'ztype' of the \verb'multiply' operator. 8627 8628The \verb'operator' is typically a \verb'GrB_BinaryOp', but the method is 8629type-generic for this parameter. If given a monoid (\verb'GrB_Monoid'), the 8630additive operator of the monoid is used as the \verb'multiply' binary operator. 8631If given a semiring (\verb'GrB_Semiring'), the multiply operator of the 8632semiring is used as the \verb'multiply' binary operator. 8633 8634The next and final step is ${\bf w \langle m \rangle = w \odot t}$, as 8635described in Section~\ref{accummask}, except that all the terms are column 8636vectors instead of matrices. Note for all GraphBLAS operations, including this 8637one, the accumulator ${\bf w \odot t}$ is always applied in a set union manner, 8638even though ${\bf t = u \otimes v}$ for this operation is applied in a set 8639intersection manner. 8640 8641\newpage 8642%------------------------------------------------------------------------------- 8643\subsubsection{{\sf GrB\_eWiseMult\_Matrix:} element-wise matrix multiply} 8644%------------------------------------------------------------------------------- 8645\label{eWiseMult_matrix} 8646 8647\begin{mdframed}[userdefinedwidth=6in] 8648{\footnotesize 8649\begin{verbatim} 8650GrB_Info GrB_eWiseMult // C<Mask> = accum (C, A.*B) 8651( 8652 GrB_Matrix C, // input/output matrix for results 8653 const GrB_Matrix Mask, // optional mask for C, unused if NULL 8654 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 8655 const <operator> multiply, // defines '.*' for T=A.*B 8656 const GrB_Matrix A, // first input: matrix A 8657 const GrB_Matrix B, // second input: matrix B 8658 const GrB_Descriptor desc // descriptor for C, Mask, A, and B 8659) ; 8660\end{verbatim} 8661} \end{mdframed} 8662 8663\verb'GrB_Matrix_eWiseMult' computes the element-wise ``multiplication'' of two 8664matrices \verb'A' and \verb'B', element-wise using any binary operator (not 8665just times). The input matrices may be transposed first, according to the 8666descriptor \verb'desc'. They are then typecasted into the first and second 8667inputs of the \verb'multiply' operator. Next, a matrix \verb'T' is computed, 8668denoted ${\bf T = A \otimes B}$. The pattern of \verb'T' is the set 8669intersection of \verb'A' and \verb'B'. The result \verb'T' has the type of the 8670output \verb'ztype' of the \verb'multiply' operator. 8671 8672The \verb'multiply' operator is typically a \verb'GrB_BinaryOp', but the method 8673is type-generic for this parameter. If given a monoid (\verb'GrB_Monoid'), the 8674additive operator of the monoid is used as the \verb'multiply' binary operator. 8675If given a semiring (\verb'GrB_Semiring'), the multiply operator of the 8676semiring is used as the \verb'multiply' binary operator. 8677 8678\vspace{0.05in} 8679The operation can be expressed in MATLAB notation as: 8680 {\footnotesize 8681 \begin{verbatim} 8682 [nrows, ncols] = size (A.matrix) ; 8683 T.matrix = zeros (nrows, ncols, multiply.ztype) ; 8684 T.class = multiply.ztype ; 8685 p = A.pattern & B.pattern ; 8686 A = cast (A.matrix (p), multiply.xtype) ; 8687 B = cast (B.matrix (p), multiply.ytype) ; 8688 T.matrix (p) = multiply (A, B) ; 8689 T.pattern = p ; \end{verbatim} } 8690 8691The final step is ${\bf C \langle M \rangle = C \odot T}$, as described in 8692Section~\ref{accummask}. Note for all GraphBLAS operations, including this 8693one, the accumulator ${\bf C \odot T}$ is always applied in a set union manner, 8694even though ${\bf T = A \otimes B}$ for this operation is applied in a set 8695intersection manner. 8696 8697\newpage 8698%=============================================================================== 8699\subsection{{\sf GrB\_eWiseAdd:} element-wise operations, set union} %========== 8700%=============================================================================== 8701\label{eWiseAdd} 8702 8703Element-wise ``addition'' is shorthand for applying a binary operator 8704element-wise on two matrices or vectors \verb'A' and \verb'B', for all entries 8705that appear in the set intersection of the patterns of \verb'A' and \verb'B'. 8706This is like \verb'A+B' for two sparse matrices in MATLAB, except that in 8707GraphBLAS any binary operator can be used, not just addition. The pattern of 8708the result of the element-wise ``addition'' is the set union of the pattern of 8709\verb'A' and \verb'B'. Entries in neither in \verb'A' nor in \verb'B' do 8710not appear in the result. 8711 8712Let $\oplus$ denote the binary operator to be used. The computation ${\bf T = 8713A \oplus B}$ is exactly the same as the computation with accumulator operator 8714as described in Section~\ref{accummask}. It acts like a sparse matrix 8715addition, except that any operator can be used. The pattern of ${\bf A \oplus 8716B}$ is the set union of the patterns of ${\bf A}$ and ${\bf B}$, and the 8717operator is applied only on the set intersection of ${\bf A}$ and ${\bf B}$. 8718Entries not in either the pattern of ${\bf A}$ or ${\bf B}$ do not appear in 8719the pattern of ${\bf T}$. That is: 8720 \vspace{-0.2in} 8721 {\small 8722 \begin{tabbing} 8723 \hspace{2em} \= \hspace{2em} \= \hspace{2em} \= \\ 8724 \> for all entries $(i,j)$ in ${\bf A \cap B}$ \\ 8725 \> \> $t_{ij} = a_{ij} \oplus b_{ij}$ \\ 8726 \> for all entries $(i,j)$ in ${\bf A \setminus B}$ \\ 8727 \> \> $t_{ij} = a_{ij}$ \\ 8728 \> for all entries $(i,j)$ in ${\bf B \setminus A}$ \\ 8729 \> \> $t_{ij} = b_{ij}$ 8730 \end{tabbing} 8731 } 8732 8733The only difference between element-wise ``multiplication'' (${\bf T =A \otimes 8734B}$) and ``addition'' (${\bf T = A \oplus B}$) is the pattern of the result, 8735and what happens to entries outside the intersection. With $\otimes$ the 8736pattern of ${\bf T}$ is the intersection; with $\oplus$ it is the set union. 8737Entries outside the set intersection are dropped for $\otimes$, and kept for 8738$\oplus$; in both cases the operator is only applied to those (and only those) 8739entries in the intersection. Any binary operator can be used interchangeably 8740for either operation. 8741 8742Element-wise operations do not operate on the implicit values, even implicitly, 8743since the operations make no assumption about the semiring. As a result, the 8744results can be different from MATLAB, which can always assume the implicit 8745value is zero. For example, \verb'C=A-B' is the conventional matrix 8746subtraction in MATLAB. Computing \verb'A-B' in GraphBLAS with \verb'eWiseAdd' 8747will apply the \verb'MINUS' operator to the intersection, entries in \verb'A' 8748but not \verb'B' will be unchanged and appear in \verb'C', and entries in 8749neither \verb'A' nor \verb'B' do not appear in \verb'C'. For these cases, the 8750results matches the MATLAB \verb'C=A-B'. Entries in \verb'B' but not \verb'A' 8751do appear in \verb'C' but they are not negated; they cannot be subtracted from 8752an implicit value in \verb'A'. This is by design. If conventional matrix 8753subtraction of two sparse matrices is required, and the implicit value is known 8754to be zero, use \verb'GrB_apply' to negate the values in \verb'B', and then 8755use \verb'eWiseAdd' with the \verb'PLUS' operator, to compute \verb'A+(-B)'. 8756 8757The generic name for this operation is \verb'GrB_eWiseAdd', which can be used 8758for both matrices and vectors. 8759 8760There is another minor difference in two variants of the element-wise 8761functions. If given a \verb'semiring', the \verb'eWiseAdd' functions use the 8762binary operator of the semiring's monoid, while the \verb'eWiseMult' functions 8763use the multiplicative operator of the semiring. 8764 8765% \newpage 8766%------------------------------------------------------------------------------- 8767\subsubsection{{\sf GrB\_eWiseAdd\_Vector:} element-wise vector addition} 8768%------------------------------------------------------------------------------- 8769\label{eWiseAdd_vector} 8770 8771\begin{mdframed}[userdefinedwidth=6in] 8772{\footnotesize 8773\begin{verbatim} 8774GrB_Info GrB_eWiseAdd // w<mask> = accum (w, u+v) 8775( 8776 GrB_Vector w, // input/output vector for results 8777 const GrB_Vector mask, // optional mask for w, unused if NULL 8778 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 8779 const <operator> add, // defines '+' for t=u+v 8780 const GrB_Vector u, // first input: vector u 8781 const GrB_Vector v, // second input: vector v 8782 const GrB_Descriptor desc // descriptor for w and mask 8783) ; 8784\end{verbatim} } \end{mdframed} 8785 8786\verb'GrB_Vector_eWiseAdd' computes the element-wise ``addition'' of two 8787vectors \verb'u' and \verb'v', element-wise using any binary operator (not just 8788plus). The vectors are not transposed via the descriptor. Entries in the 8789intersection of \verb'u' and \verb'v' are first typecasted into the first and 8790second inputs of the \verb'add' operator. Next, a column vector \verb't' is 8791computed, denoted ${\bf t = u \oplus v}$. The pattern of \verb't' is the set 8792union of \verb'u' and \verb'v'. The result \verb't' has the type of the output 8793\verb'ztype' of the \verb'add' operator. 8794 8795The \verb'add' operator is typically a \verb'GrB_BinaryOp', but the method is 8796type-generic for this parameter. If given a monoid (\verb'GrB_Monoid'), the 8797additive operator of the monoid is used as the \verb'add' binary operator. If 8798given a semiring (\verb'GrB_Semiring'), the additive operator of the monoid of 8799the semiring is used as the \verb'add' binary operator. 8800 8801The final step is ${\bf w \langle m \rangle = w \odot t}$, as described in 8802Section~\ref{accummask}, except that all the terms are column vectors instead 8803of matrices. 8804 8805% \newpage 8806%------------------------------------------------------------------------------- 8807\subsubsection{{\sf GrB\_eWiseAdd\_Matrix:} element-wise matrix addition} 8808%------------------------------------------------------------------------------- 8809\label{eWiseAdd_matrix} 8810 8811\begin{mdframed}[userdefinedwidth=6in] 8812{\footnotesize 8813\begin{verbatim} 8814GrB_Info GrB_eWiseAdd // C<Mask> = accum (C, A+B) 8815( 8816 GrB_Matrix C, // input/output matrix for results 8817 const GrB_Matrix Mask, // optional mask for C, unused if NULL 8818 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 8819 const <operator> add, // defines '+' for T=A+B 8820 const GrB_Matrix A, // first input: matrix A 8821 const GrB_Matrix B, // second input: matrix B 8822 const GrB_Descriptor desc // descriptor for C, Mask, A, and B 8823) ; 8824\end{verbatim} } \end{mdframed} 8825 8826\verb'GrB_Matrix_eWiseAdd' computes the element-wise ``addition'' of two 8827matrices \verb'A' and \verb'B', element-wise using any binary operator (not 8828just plus). The input matrices may be transposed first, according to the 8829descriptor \verb'desc'. Entries in the intersection then typecasted into the 8830first and second inputs of the \verb'add' operator. Next, a matrix \verb'T' is 8831computed, denoted ${\bf T = A \oplus B}$. The pattern of \verb'T' is the set 8832union of \verb'A' and \verb'B'. The result \verb'T' has the type of the output 8833\verb'ztype' of the \verb'add' operator. 8834 8835The \verb'add' operator is typically a \verb'GrB_BinaryOp', but the method is 8836type-generic for this parameter. If given a monoid (\verb'GrB_Monoid'), the 8837additive operator of the monoid is used as the \verb'add' binary operator. If 8838given a semiring (\verb'GrB_Semiring'), the additive operator of the monoid of 8839the semiring is used as the \verb'add' binary operator. 8840 8841\vspace{0.05in} 8842The operation can be expressed in MATLAB notation as: 8843 {\footnotesize 8844 \begin{verbatim} 8845 [nrows, ncols] = size (A.matrix) ; 8846 T.matrix = zeros (nrows, ncols, add.ztype) ; 8847 p = A.pattern & B.pattern ; 8848 A = GB_mex_cast (A.matrix (p), add.xtype) ; 8849 B = GB_mex_cast (B.matrix (p), add.ytype) ; 8850 T.matrix (p) = add (A, B) ; 8851 p = A.pattern & ~B.pattern ; T.matrix (p) = cast (A.matrix (p), add.ztype) ; 8852 p = ~A.pattern & B.pattern ; T.matrix (p) = cast (B.matrix (p), add.ztype) ; 8853 T.pattern = A.pattern | B.pattern ; 8854 T.class = add.ztype ; \end{verbatim} } 8855Except for when typecasting is performed, this is identical to how the 8856\verb'accum' operator is applied in Figure~\ref{fig_accummask}. 8857 8858The final step is ${\bf C \langle M \rangle = C \odot T}$, as described in 8859Section~\ref{accummask}. 8860 8861\newpage 8862%=============================================================================== 8863\subsection{{\sf GrB\_extract:} submatrix extraction } %======================== 8864%=============================================================================== 8865\label{extract} 8866 8867The \verb'GrB_extract' function is a generic name for three specific functions: 8868\verb'GrB_Vector_extract', \verb'GrB_Col_extract', and 8869\verb'GrB_Matrix_extract'. The generic name appears in the function signature, 8870but the specific function name is used when describing what each variation 8871does. 8872 8873% \newpage 8874%------------------------------------------------------------------------------- 8875\subsubsection{{\sf GrB\_Vector\_extract:} extract subvector from vector} 8876%------------------------------------------------------------------------------- 8877\label{extract_vector} 8878 8879\begin{mdframed}[userdefinedwidth=6in] 8880{\footnotesize 8881\begin{verbatim} 8882GrB_Info GrB_extract // w<mask> = accum (w, u(I)) 8883( 8884 GrB_Vector w, // input/output vector for results 8885 const GrB_Vector mask, // optional mask for w, unused if NULL 8886 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 8887 const GrB_Vector u, // first input: vector u 8888 const GrB_Index *I, // row indices 8889 const GrB_Index ni, // number of row indices 8890 const GrB_Descriptor desc // descriptor for w and mask 8891) ; 8892\end{verbatim} } \end{mdframed} 8893 8894\verb'GrB_Vector_extract' extracts a subvector from another vector, identical 8895to \verb't = u (I)' in MATLAB where \verb'I' is an integer vector of row 8896indices. Refer to \verb'GrB_Matrix_extract' for further details; vector 8897extraction is the same as matrix extraction with \verb'n'-by-1 matrices. 8898See Section~\ref{colon} for a description of \verb'I' and \verb'ni'. 8899The final step is ${\bf w \langle m \rangle = w \odot 8900t}$, as described in Section~\ref{accummask}, except that all the terms are 8901column vectors instead of matrices. 8902 8903\newpage 8904%------------------------------------------------------------------------------- 8905\subsubsection{{\sf GrB\_Matrix\_extract:} extract submatrix from matrix} 8906%------------------------------------------------------------------------------- 8907\label{extract_matrix} 8908 8909\begin{mdframed}[userdefinedwidth=6in] 8910{\footnotesize 8911\begin{verbatim} 8912GrB_Info GrB_extract // C<Mask> = accum (C, A(I,J)) 8913( 8914 GrB_Matrix C, // input/output matrix for results 8915 const GrB_Matrix Mask, // optional mask for C, unused if NULL 8916 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 8917 const GrB_Matrix A, // first input: matrix A 8918 const GrB_Index *I, // row indices 8919 const GrB_Index ni, // number of row indices 8920 const GrB_Index *J, // column indices 8921 const GrB_Index nj, // number of column indices 8922 const GrB_Descriptor desc // descriptor for C, Mask, and A 8923) ; 8924\end{verbatim} } \end{mdframed} 8925 8926\verb'GrB_Matrix_extract' extracts a submatrix from another matrix, identical 8927to \verb'T = A(I,J)' in MATLAB where \verb'I' and \verb'J' are integer vectors 8928of row and column indices, respectively, except that indices are zero-based in 8929GraphBLAS and one-based in MATLAB. The input matrix \verb'A' may be transposed 8930first, via the descriptor. The type of \verb'T' and \verb'A' are the same. 8931The size of \verb'C' is \verb'|I|'-by-\verb'|J|'. 8932Entries outside \verb'A(I,J)' are not accessed and do not take part in the 8933computation. More precisely, assuming the matrix \verb'A' is not transposed, 8934the matrix \verb'T' is defined as follows: 8935 8936 \vspace{-0.1in} 8937 {\footnotesize 8938 \begin{verbatim} 8939 T.matrix = zeros (ni, nj) ; % a matrix of size ni-by-nj 8940 T.pattern = false (ni, nj) ; 8941 for i = 1:ni 8942 for j = 1:nj 8943 if (A (I(i),J(j)).pattern) 8944 T (i,j).matrix = A (I(i),J(j)).matrix ; 8945 T (i,j).pattern = true ; 8946 end 8947 end 8948 end \end{verbatim}} 8949 8950\vspace{-0.1in} 8951If duplicate indices are present in \verb'I' or \verb'J', the above method 8952defines the result in \verb'T'. Duplicates result in the same values of 8953\verb'A' being copied into different places in \verb'T'. 8954See Section~\ref{colon} for a description of the row indices 8955\verb'I' and \verb'ni', and the column indices 8956\verb'J' and \verb'nj'. 8957The final step is ${\bf C \langle M \rangle = C \odot 8958T}$, as described in Section~\ref{accummask}. 8959 8960\paragraph{\bf Performance considerations:} % C=A(I,J) 8961If \verb'A' is not transposed via input descriptor: if \verb'|I|' is small, 8962then it is fastest if \verb'A' is \verb'GxB_BY_ROW'; if 8963\verb'|J|' is small, then it is fastest if \verb'A' is 8964\verb'GxB_BY_COL'. The opposite is true if \verb'A' is transposed. 8965 8966\newpage 8967%------------------------------------------------------------------------------- 8968\subsubsection{{\sf GrB\_Col\_extract:} extract column vector from matrix} 8969%------------------------------------------------------------------------------- 8970\label{extract_column} 8971 8972\begin{mdframed}[userdefinedwidth=6in] 8973{\footnotesize 8974\begin{verbatim} 8975GrB_Info GrB_extract // w<mask> = accum (w, A(I,j)) 8976( 8977 GrB_Vector w, // input/output matrix for results 8978 const GrB_Vector mask, // optional mask for w, unused if NULL 8979 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 8980 const GrB_Matrix A, // first input: matrix A 8981 const GrB_Index *I, // row indices 8982 const GrB_Index ni, // number of row indices 8983 const GrB_Index j, // column index 8984 const GrB_Descriptor desc // descriptor for w, mask, and A 8985) ; 8986\end{verbatim} } \end{mdframed} 8987 8988\verb'GrB_Col_extract' extracts a subvector from a matrix, identical to 8989\verb't = A (I,j)' in MATLAB where \verb'I' is an integer vector of row indices 8990and where \verb'j' is a single column index. The input matrix \verb'A' may be 8991transposed first, via the descriptor, which results in the extraction of a 8992single row \verb'j' from the matrix \verb'A', the result of which is a column 8993vector \verb'w'. The type of \verb't' and \verb'A' are the same. 8994The size of \verb'w' is \verb'|I|'-by-1. 8995 8996See Section~\ref{colon} for a description of the row indices 8997\verb'I' and \verb'ni'. 8998The final step is ${\bf w \langle m 8999\rangle = w \odot t}$, as described in Section~\ref{accummask}, except that 9000all the terms are column vectors instead of matrices. 9001 9002\paragraph{\bf Performance considerations:} % w = A(I,j) 9003If \verb'A' is not transposed: it is fastest if the format of \verb'A' is 9004\verb'GxB_BY_COL'. The opposite is true if \verb'A' is transposed. 9005 9006\newpage 9007%=============================================================================== 9008\subsection{{\sf GxB\_subassign:} submatrix assignment} %======================= 9009%=============================================================================== 9010\label{subassign} 9011 9012The methods described in this section are all variations of the form 9013\verb'C(I,J)=A', which modifies a submatrix of the matrix \verb'C'. All 9014methods can be used in their generic form with the single name 9015\verb'GxB_subassign'. This is reflected in the prototypes. However, to avoid 9016confusion between the different kinds of assignment, the name of the specific 9017function is used when describing each variation. If the discussion applies to 9018all variations, the simple name \verb'GxB_subassign' is used. 9019 9020See Section~\ref{colon} for a description of the row indices 9021\verb'I' and \verb'ni', and the column indices 9022\verb'J' and \verb'nj'. 9023 9024\verb'GxB_subassign' is very similar to \verb'GrB_assign', described in 9025Section~\ref{assign}. The two operations are compared and contrasted in 9026Section~\ref{compare_assign}. For a discussion of how duplicate indices 9027are handled in \verb'I' and \verb'J', see Section~\ref{duplicates}. 9028 9029%------------------------------------------------------------------------------- 9030\subsubsection{{\sf GxB\_Vector\_subassign:} assign to a subvector } 9031%------------------------------------------------------------------------------- 9032\label{subassign_vector} 9033 9034\begin{mdframed}[userdefinedwidth=6in] 9035{\footnotesize 9036\begin{verbatim} 9037GrB_Info GxB_subassign // w(I)<mask> = accum (w(I),u) 9038( 9039 GrB_Vector w, // input/output matrix for results 9040 const GrB_Vector mask, // optional mask for w(I), unused if NULL 9041 const GrB_BinaryOp accum, // optional accum for z=accum(w(I),t) 9042 const GrB_Vector u, // first input: vector u 9043 const GrB_Index *I, // row indices 9044 const GrB_Index ni, // number of row indices 9045 const GrB_Descriptor desc // descriptor for w(I) and mask 9046) ; 9047\end{verbatim} } \end{mdframed} 9048 9049\verb'GxB_Vector_subassign' operates on a subvector \verb'w(I)' of \verb'w', 9050modifying it with the vector \verb'u'. The method is identical to 9051\verb'GxB_Matrix_subassign' described in Section~\ref{subassign_matrix}, where 9052all matrices have a single column each. The \verb'mask' has the same size as 9053\verb'w(I)' and \verb'u'. The only other difference is that the input \verb'u' 9054in this method is not transposed via the \verb'GrB_INP0' descriptor. 9055 9056\newpage 9057%------------------------------------------------------------------------------- 9058\subsubsection{{\sf GxB\_Matrix\_subassign:} assign to a submatrix } 9059%------------------------------------------------------------------------------- 9060\label{subassign_matrix} 9061 9062\begin{mdframed}[userdefinedwidth=6in] 9063{\footnotesize 9064\begin{verbatim} 9065GrB_Info GxB_subassign // C(I,J)<Mask> = accum (C(I,J),A) 9066( 9067 GrB_Matrix C, // input/output matrix for results 9068 const GrB_Matrix Mask, // optional mask for C(I,J), unused if NULL 9069 const GrB_BinaryOp accum, // optional accum for Z=accum(C(I,J),T) 9070 const GrB_Matrix A, // first input: matrix A 9071 const GrB_Index *I, // row indices 9072 const GrB_Index ni, // number of row indices 9073 const GrB_Index *J, // column indices 9074 const GrB_Index nj, // number of column indices 9075 const GrB_Descriptor desc // descriptor for C(I,J), Mask, and A 9076) ; 9077\end{verbatim} } \end{mdframed} 9078 9079\verb'GxB_Matrix_subassign' operates only on a submatrix \verb'S' of \verb'C', 9080modifying it with the matrix \verb'A'. For this operation, the result is not 9081the entire matrix \verb'C', but a submatrix \verb'S=C(I,J)' of \verb'C'. The 9082steps taken are as follows, except that ${\bf A}$ may be optionally transposed 9083via the \verb'GrB_INP0' descriptor option. 9084 9085\vspace{0.1in} 9086\begin{tabular}{lll} 9087\hline 9088Step & GraphBLAS & description \\ 9089 & notation & \\ 9090\hline 90911 & ${\bf S} = {\bf C(I,J)}$ & extract the ${\bf C(I,J)}$ submatrix \\ 90922 & ${\bf S \langle M \rangle} = {\bf S} \odot {\bf A}$ & apply the accumulator/mask to the submatrix ${\bf S}$\\ 90933 & ${\bf C(I,J)}= {\bf S}$ & put the submatrix ${\bf S}$ back into ${\bf C(I,J)}$ \\ 9094\hline 9095\end{tabular} 9096\vspace{0.1in} 9097 9098The accumulator/mask step in Step 2 is the same as for all other GraphBLAS 9099operations, described in Section~\ref{accummask}, except that for 9100\verb'GxB_subassign', it is applied to just the submatrix ${\bf S} = {\bf 9101C(I,J)}$, and thus the \verb'Mask' has the same size as ${\bf A}$, 9102${\bf S}$, and ${\bf C(I,J)}$. 9103 9104The \verb'GxB_subassign' operation is the reverse of matrix extraction: 9105 9106\begin{itemize} 9107\item 9108For submatrix extraction, \verb'GrB_Matrix_extract', 9109the submatrix \verb'A(I,J)' appears on the right-hand side of the assignment, 9110\verb'C=A(I,J)', and entries outside of the submatrix are not accessed and do 9111not take part in the computation. 9112 9113\item 9114For submatrix assignment, \verb'GxB_Matrix_subassign', 9115the submatrix \verb'C(I,J)' appears on the left-hand-side of the assignment, 9116\verb'C(I,J)=A', and entries outside of the submatrix are not accessed and do 9117not take part in the computation. 9118 9119\end{itemize} 9120 9121In both methods, the accumulator and mask modify the submatrix of the 9122assignment; they simply differ on which side of the assignment the submatrix 9123resides on. In both cases, if the \verb'Mask' matrix is present it is the same 9124size as the submatrix: 9125 9126\begin{itemize} 9127 9128\item 9129For submatrix extraction, 9130${\bf C \langle M \rangle = C \odot A(I,J)}$ is computed, 9131where the submatrix is on the right. 9132The mask ${\bf M}$ has the same size as the submatrix ${\bf A(I,J)}$. 9133 9134\item 9135For submatrix assignment, 9136${\bf C(I,J) \langle M \rangle = C(I,J) \odot A}$ is computed, 9137where the submatrix is on the left. 9138The mask ${\bf M}$ has the same size as the submatrix ${\bf C(I,J)}$. 9139 9140\end{itemize} 9141 9142In Step 1, the submatrix \verb'S' is first computed by the 9143\verb'GrB_Matrix_extract' operation, \verb'S=C(I,J)'. 9144 9145Step 2 accumulates the results ${\bf S \langle M \rangle = S \odot T}$, 9146exactly as described in Section~\ref{accummask}, but operating on the submatrix 9147${\bf S}$, not ${\bf C}$, using the optional \verb'Mask' and \verb'accum' 9148operator. The matrix ${\bf T}$ is simply ${\bf T}={\bf A}$, or ${\bf T}={\bf 9149A}^{\sf T}$ if ${\bf A}$ is transposed via the \verb'desc' descriptor, 9150\verb'GrB_INP0'. The \verb'GrB_REPLACE' option in the descriptor clears ${\bf 9151S}$ after computing ${\bf Z = T}$ or ${\bf Z = C \odot T}$, not all of ${\bf 9152C}$ since this operation can only modify the specified submatrix of ${\bf C}$. 9153 9154Finally, Step 3 writes the result (which is the modified submatrix \verb'S' and 9155not all of \verb'C') back into the \verb'C' matrix that contains it, via the 9156assignment \verb'C(I,J)=S', using the reverse operation from the method 9157described for matrix extraction: 9158 9159 {\footnotesize 9160 \begin{verbatim} 9161 for i = 1:ni 9162 for j = 1:nj 9163 if (S (i,j).pattern) 9164 C (I(i),J(j)).matrix = S (i,j).matrix ; 9165 C (I(i),J(j)).pattern = true ; 9166 end 9167 end 9168 end \end{verbatim}} 9169 9170\paragraph{\bf Performance considerations:} % C(I,J) = A 9171If \verb'A' is not transposed: if \verb'|I|' is small, then it is fastest if 9172the format of \verb'C' is \verb'GxB_BY_ROW'; if \verb'|J|' is small, then it is 9173fastest if the format of \verb'C' is \verb'GxB_BY_COL'. The opposite is true 9174if \verb'A' is transposed. 9175 9176\newpage 9177%------------------------------------------------------------------------------- 9178\subsubsection{{\sf GxB\_Col\_subassign:} assign to a sub-column of a matrix} 9179%------------------------------------------------------------------------------- 9180\label{subassign_column} 9181 9182\begin{mdframed}[userdefinedwidth=6in] 9183{\footnotesize 9184\begin{verbatim} 9185GrB_Info GxB_subassign // C(I,j)<mask> = accum (C(I,j),u) 9186( 9187 GrB_Matrix C, // input/output matrix for results 9188 const GrB_Vector mask, // optional mask for C(I,j), unused if NULL 9189 const GrB_BinaryOp accum, // optional accum for z=accum(C(I,j),t) 9190 const GrB_Vector u, // input vector 9191 const GrB_Index *I, // row indices 9192 const GrB_Index ni, // number of row indices 9193 const GrB_Index j, // column index 9194 const GrB_Descriptor desc // descriptor for C(I,j) and mask 9195) ; 9196\end{verbatim} } \end{mdframed} 9197 9198\verb'GxB_Col_subassign' modifies a single sub-column of a matrix \verb'C'. It 9199is the same as \verb'GxB_Matrix_subassign' where the index vector \verb'J[0]=j' 9200is a single column index (and thus \verb'nj=1'), and where all matrices in 9201\verb'GxB_Matrix_subassign' (except \verb'C') consist of a single column. The 9202\verb'mask' vector has the same size as \verb'u' and the sub-column 9203\verb'C(I,j)'. The input descriptor \verb'GrB_INP0' is ignored; the input 9204vector \verb'u' is not transposed. Refer to \verb'GxB_Matrix_subassign' for 9205further details. 9206 9207\paragraph{\bf Performance considerations:} % C(I,j) = u 9208\verb'GxB_Col_subassign' is much faster than \verb'GxB_Row_subassign' if the 9209format of \verb'C' is \verb'GxB_BY_COL'. \verb'GxB_Row_subassign' is much 9210faster than \verb'GxB_Col_subassign' if the format of \verb'C' is 9211\verb'GxB_BY_ROW'. 9212 9213% \newpage 9214%------------------------------------------------------------------------------- 9215\subsubsection{{\sf GxB\_Row\_subassign:} assign to a sub-row of a matrix} 9216%------------------------------------------------------------------------------- 9217\label{subassign_row} 9218 9219\begin{mdframed}[userdefinedwidth=6in] 9220{\footnotesize 9221\begin{verbatim} 9222GrB_Info GxB_subassign // C(i,J)<mask'> = accum (C(i,J),u') 9223( 9224 GrB_Matrix C, // input/output matrix for results 9225 const GrB_Vector mask, // optional mask for C(i,J), unused if NULL 9226 const GrB_BinaryOp accum, // optional accum for z=accum(C(i,J),t) 9227 const GrB_Vector u, // input vector 9228 const GrB_Index i, // row index 9229 const GrB_Index *J, // column indices 9230 const GrB_Index nj, // number of column indices 9231 const GrB_Descriptor desc // descriptor for C(i,J) and mask 9232) ; 9233\end{verbatim} } \end{mdframed} 9234 9235\verb'GxB_Row_subassign' modifies a single sub-row of a matrix \verb'C'. It is 9236the same as \verb'GxB_Matrix_subassign' where the index vector \verb'I[0]=i' is 9237a single row index (and thus \verb'ni=1'), and where all matrices in 9238\verb'GxB_Matrix_subassign' (except \verb'C') consist of a single row. The 9239\verb'mask' vector has the same size as \verb'u' and the sub-column 9240\verb'C(I,j)'. The input descriptor \verb'GrB_INP0' is ignored; the input 9241vector \verb'u' is not transposed. Refer to \verb'GxB_Matrix_subassign' for 9242further details. 9243 9244\paragraph{\bf Performance considerations:} % C(i,J) = u' 9245\verb'GxB_Col_subassign' is much faster than \verb'GxB_Row_subassign' if the 9246format of \verb'C' is \verb'GxB_BY_COL'. \verb'GxB_Row_subassign' is much 9247faster than \verb'GxB_Col_subassign' if the format of \verb'C' is 9248\verb'GxB_BY_ROW'. 9249 9250% \newpage 9251%------------------------------------------------------------------------------- 9252\subsubsection{{\sf GxB\_Vector\_subassign\_$<$type$>$:} assign a scalar to a subvector} 9253%------------------------------------------------------------------------------- 9254\label{subassign_vector_scalar} 9255 9256\begin{mdframed}[userdefinedwidth=6in] 9257{\footnotesize 9258\begin{verbatim} 9259GrB_Info GxB_subassign // w(I)<mask> = accum (w(I),x) 9260( 9261 GrB_Vector w, // input/output vector for results 9262 const GrB_Vector mask, // optional mask for w(I), unused if NULL 9263 const GrB_BinaryOp accum, // optional accum for z=accum(w(I),x) 9264 const <type> x, // scalar to assign to w(I) 9265 const GrB_Index *I, // row indices 9266 const GrB_Index ni, // number of row indices 9267 const GrB_Descriptor desc // descriptor for w(I) and mask 9268) ; 9269\end{verbatim} } \end{mdframed} 9270 9271\verb'GxB_Vector_subassign_<type>' assigns a single scalar to an entire 9272subvector of the vector \verb'w'. The operation is exactly like setting a 9273single entry in an \verb'n'-by-1 matrix, \verb'A(I,0) = x', where the column 9274index for a vector is implicitly \verb'j=0'. For further details of this 9275function, see \verb'GxB_Matrix_subassign_<type>' in 9276Section~\ref{subassign_matrix_scalar}. 9277 9278\newpage 9279%------------------------------------------------------------------------------- 9280\subsubsection{{\sf GxB\_Matrix\_subassign\_$<$type$>$:} assign a scalar to a submatrix} 9281%------------------------------------------------------------------------------- 9282\label{subassign_matrix_scalar} 9283 9284\begin{mdframed}[userdefinedwidth=6in] 9285{\footnotesize 9286\begin{verbatim} 9287GrB_Info GxB_subassign // C(I,J)<Mask> = accum (C(I,J),x) 9288( 9289 GrB_Matrix C, // input/output matrix for results 9290 const GrB_Matrix Mask, // optional mask for C(I,J), unused if NULL 9291 const GrB_BinaryOp accum, // optional accum for Z=accum(C(I,J),x) 9292 const <type> x, // scalar to assign to C(I,J) 9293 const GrB_Index *I, // row indices 9294 const GrB_Index ni, // number of row indices 9295 const GrB_Index *J, // column indices 9296 const GrB_Index nj, // number of column indices 9297 const GrB_Descriptor desc // descriptor for C(I,J) and Mask 9298) ; 9299\end{verbatim} } \end{mdframed} 9300 9301\verb'GxB_Matrix_subassign_<type>' assigns a single scalar to an entire 9302submatrix of \verb'C', like the {\em scalar expansion} \verb'C(I,J)=x' in 9303MATLAB. The scalar \verb'x' is implicitly expanded into a matrix \verb'A' of 9304size \verb'ni' by \verb'nj', and then the matrix \verb'A' is assigned to 9305\verb'C(I,J)' using the same method as in \verb'GxB_Matrix_subassign'. Refer 9306to that function in Section~\ref{subassign_matrix} for further details. 9307For the accumulation step, the scalar \verb'x' is typecasted directly into the 9308type of \verb'C' when the \verb'accum' operator is not applied to it, or into 9309the \verb'ytype' of the \verb'accum' operator, if \verb'accum' is not NULL, for 9310entries that are already present in \verb'C'. 9311 9312The \verb'<type> x' notation is otherwise the same as 9313\verb'GrB_Matrix_setElement' (see Section~\ref{matrix_setElement}). Any value 9314can be passed to this function and its type will be detected, via the 9315\verb'_Generic' feature of ANSI C11. For a user-defined type, \verb'x' is a 9316\verb'void *' pointer that points to a memory space holding a single entry of a 9317scalar that has exactly the same user-defined type as the matrix \verb'C'. 9318This user-defined type must exactly match the user-defined type of \verb'C' 9319since no typecasting is done between user-defined types. 9320 9321If a \verb'void *' pointer is passed in and the type of the underlying scalar 9322does not exactly match the user-defined type of \verb'C', then results are 9323undefined. No error status will be returned since GraphBLAS has no way of 9324catching this error. 9325 9326\paragraph{\bf Performance considerations:} % C(I,J) = scalar 9327If \verb'A' is not transposed: if \verb'|I|' is small, then it is fastest if 9328the format of \verb'C' is \verb'GxB_BY_ROW'; if \verb'|J|' is small, then it is 9329fastest if the format of \verb'C' is \verb'GxB_BY_COL'. The opposite is true 9330if \verb'A' is transposed. 9331 9332\newpage 9333%=============================================================================== 9334\subsection{{\sf GrB\_assign:} submatrix assignment} %========================== 9335%=============================================================================== 9336\label{assign} 9337 9338The methods described in this section are all variations of the form 9339\verb'C(I,J)=A', which modifies a submatrix of the matrix \verb'C'. All 9340methods can be used in their generic form with the single name 9341\verb'GrB_assign'. These methods are very similar to their 9342\verb'GxB_subassign' counterparts in Section~\ref{subassign}. They differ 9343primarily in the size of the \verb'Mask', and how the \verb'GrB_REPLACE' option 9344works. Refer to Section~\ref{compare_assign} for a complete comparison of 9345\verb'GxB_subassign' and \verb'GrB_assign'. 9346 9347See Section~\ref{colon} for a description of 9348\verb'I', \verb'ni', \verb'J', and \verb'nj'. 9349 9350%------------------------------------------------------------------------------- 9351\subsubsection{{\sf GrB\_Vector\_assign:} assign to a subvector } 9352%------------------------------------------------------------------------------- 9353\label{assign_vector} 9354 9355\begin{mdframed}[userdefinedwidth=6in] 9356{\footnotesize 9357\begin{verbatim} 9358GrB_Info GrB_assign // w<mask>(I) = accum (w(I),u) 9359( 9360 GrB_Vector w, // input/output matrix for results 9361 const GrB_Vector mask, // optional mask for w, unused if NULL 9362 const GrB_BinaryOp accum, // optional accum for z=accum(w(I),t) 9363 const GrB_Vector u, // first input: vector u 9364 const GrB_Index *I, // row indices 9365 const GrB_Index ni, // number of row indices 9366 const GrB_Descriptor desc // descriptor for w and mask 9367) ; 9368\end{verbatim} } \end{mdframed} 9369 9370\verb'GrB_Vector_assign' operates on a subvector \verb'w(I)' of \verb'w', 9371modifying it with the vector \verb'u'. The \verb'mask' vector has the same 9372size as \verb'w'. The method is identical to \verb'GrB_Matrix_assign' 9373described in Section~\ref{assign_matrix}, where all matrices have a single 9374column each. The only other difference is that the input \verb'u' in this 9375method is not transposed via the \verb'GrB_INP0' descriptor. 9376 9377\newpage 9378%------------------------------------------------------------------------------- 9379\subsubsection{{\sf GrB\_Matrix\_assign:} assign to a submatrix } 9380%------------------------------------------------------------------------------- 9381\label{assign_matrix} 9382 9383\begin{mdframed}[userdefinedwidth=6in] 9384{\footnotesize 9385\begin{verbatim} 9386GrB_Info GrB_assign // C<Mask>(I,J) = accum (C(I,J),A) 9387( 9388 GrB_Matrix C, // input/output matrix for results 9389 const GrB_Matrix Mask, // optional mask for C, unused if NULL 9390 const GrB_BinaryOp accum, // optional accum for Z=accum(C(I,J),T) 9391 const GrB_Matrix A, // first input: matrix A 9392 const GrB_Index *I, // row indices 9393 const GrB_Index ni, // number of row indices 9394 const GrB_Index *J, // column indices 9395 const GrB_Index nj, // number of column indices 9396 const GrB_Descriptor desc // descriptor for C, Mask, and A 9397) ; 9398\end{verbatim} } \end{mdframed} 9399 9400\verb'GrB_Matrix_assign' operates on a submatrix \verb'S' of \verb'C', 9401modifying it with the matrix \verb'A'. It may also modify all of \verb'C', 9402depending on the input descriptor \verb'desc' and the \verb'Mask'. 9403 9404\vspace{0.1in} 9405\begin{tabular}{lll} 9406\hline 9407Step & GraphBLAS & description \\ 9408 & notation & \\ 9409\hline 94101 & ${\bf S} = {\bf C(I,J)}$ & extract ${\bf C(I,J)}$ submatrix \\ 94112 & ${\bf S} = {\bf S} \odot {\bf A}$ & apply the accumulator (but not the mask) to ${\bf S}$\\ 94123 & ${\bf Z} = {\bf C}$ & make a copy of ${\bf C}$ \\ 94134 & ${\bf Z(I,J)} = {\bf S}$ & put the submatrix into ${\bf Z(I,J)}$ \\ 94145 & ${\bf C \langle M \rangle = Z}$ & apply the mask/replace phase to all of ${\bf C}$ \\ 9415\hline 9416\end{tabular} 9417\vspace{0.1in} 9418 9419In contrast to \verb'GxB_subassign', the \verb'Mask' has the same as \verb'C'. 9420 9421Step 1 extracts the submatrix and then Step 2 applies the accumulator 9422(or ${\bf S}={\bf A}$ if \verb'accum' is \verb'NULL'). The \verb'Mask' is 9423not yet applied. 9424 9425Step 3 makes a copy of the ${\bf C}$ matrix, and then Step 4 writes the 9426submatrix ${\bf S}$ into ${\bf Z}$. This is the same as Step 3 of 9427\verb'GxB_subassign', except that it operates on a temporary matrix ${\bf Z}$. 9428 9429Finally, Step 5 writes ${\bf Z}$ back into ${\bf C}$ via the \verb'Mask', using 9430the Mask/Replace Phase described in Section~\ref{accummask}. If 9431\verb'GrB_REPLACE' is enabled, then all of ${\bf C}$ is cleared prior to 9432writing ${\bf Z}$ via the mask. As a result, the \verb'GrB_REPLACE' option can 9433delete entries outside the ${\bf C(I,J)}$ submatrix. 9434 9435\paragraph{\bf Performance considerations:} % C(I,J) = A 9436If \verb'A' is not transposed: if \verb'|I|' is small, then it is fastest if 9437the format of \verb'C' is \verb'GxB_BY_ROW'; if \verb'|J|' is small, then it is 9438fastest if the format of \verb'C' is \verb'GxB_BY_COL'. The opposite is true 9439if \verb'A' is transposed. 9440 9441\newpage 9442%------------------------------------------------------------------------------- 9443\subsubsection{{\sf GrB\_Col\_assign:} assign to a sub-column of a matrix} 9444%------------------------------------------------------------------------------- 9445\label{assign_column} 9446 9447\begin{mdframed}[userdefinedwidth=6in] 9448{\footnotesize 9449\begin{verbatim} 9450GrB_Info GrB_assign // C<mask>(I,j) = accum (C(I,j),u) 9451( 9452 GrB_Matrix C, // input/output matrix for results 9453 const GrB_Vector mask, // optional mask for C(:,j), unused if NULL 9454 const GrB_BinaryOp accum, // optional accum for z=accum(C(I,j),t) 9455 const GrB_Vector u, // input vector 9456 const GrB_Index *I, // row indices 9457 const GrB_Index ni, // number of row indices 9458 const GrB_Index j, // column index 9459 const GrB_Descriptor desc // descriptor for C(:,j) and mask 9460) ; 9461\end{verbatim} } \end{mdframed} 9462 9463\verb'GrB_Col_assign' modifies a single sub-column of a matrix \verb'C'. It is 9464the same as \verb'GrB_Matrix_assign' where the index vector \verb'J[0]=j' is a 9465single column index, and where all matrices in \verb'GrB_Matrix_assign' (except 9466\verb'C') consist of a single column. 9467 9468Unlike \verb'GrB_Matrix_assign', the \verb'mask' is a vector with the same size 9469as a single column of \verb'C'. 9470 9471The input descriptor \verb'GrB_INP0' is ignored; the input vector \verb'u' is 9472not transposed. Refer to \verb'GrB_Matrix_assign' for further details. 9473 9474\paragraph{\bf Performance considerations:} % C(I,j) = u 9475\verb'GrB_Col_assign' is much faster than \verb'GrB_Row_assign' if the format 9476of \verb'C' is \verb'GxB_BY_COL'. \verb'GrB_Row_assign' is much faster than 9477\verb'GrB_Col_assign' if the format of \verb'C' is \verb'GxB_BY_ROW'. 9478 9479\newpage 9480%------------------------------------------------------------------------------- 9481\subsubsection{{\sf GrB\_Row\_assign:} assign to a sub-row of a matrix} 9482%------------------------------------------------------------------------------- 9483\label{assign_row} 9484 9485\begin{mdframed}[userdefinedwidth=6in] 9486{\footnotesize 9487\begin{verbatim} 9488GrB_Info GrB_assign // C<mask'>(i,J) = accum (C(i,J),u') 9489( 9490 GrB_Matrix C, // input/output matrix for results 9491 const GrB_Vector mask, // optional mask for C(i,:), unused if NULL 9492 const GrB_BinaryOp accum, // optional accum for z=accum(C(i,J),t) 9493 const GrB_Vector u, // input vector 9494 const GrB_Index i, // row index 9495 const GrB_Index *J, // column indices 9496 const GrB_Index nj, // number of column indices 9497 const GrB_Descriptor desc // descriptor for C(i,:) and mask 9498) ; 9499\end{verbatim} } \end{mdframed} 9500 9501\verb'GrB_Row_assign' modifies a single sub-row of a matrix \verb'C'. It is 9502the same as \verb'GrB_Matrix_assign' where the index vector \verb'I[0]=i' is 9503a single row index, and where all matrices in \verb'GrB_Matrix_assign' 9504(except \verb'C') consist of a single row. 9505 9506Unlike \verb'GrB_Matrix_assign', the \verb'mask' is a vector with the same size 9507as a single row of \verb'C'. 9508 9509The input descriptor \verb'GrB_INP0' is ignored; the input vector \verb'u' is 9510not transposed. Refer to \verb'GrB_Matrix_assign' for further details. 9511 9512\paragraph{\bf Performance considerations:} % C(i,J) = u' 9513\verb'GrB_Col_assign' is much faster than \verb'GrB_Row_assign' if the format 9514of \verb'C' is \verb'GxB_BY_COL'. \verb'GrB_Row_assign' is much faster than 9515\verb'GrB_Col_assign' if the format of \verb'C' is \verb'GxB_BY_ROW'. 9516 9517\newpage 9518%------------------------------------------------------------------------------- 9519\subsubsection{{\sf GrB\_Vector\_assign\_$<$type$>$:} assign a scalar to a subvector} 9520%------------------------------------------------------------------------------- 9521\label{assign_vector_scalar} 9522 9523\begin{mdframed}[userdefinedwidth=6in] 9524{\footnotesize 9525\begin{verbatim} 9526GrB_Info GrB_assign // w<mask>(I) = accum (w(I),x) 9527( 9528 GrB_Vector w, // input/output vector for results 9529 const GrB_Vector mask, // optional mask for w, unused if NULL 9530 const GrB_BinaryOp accum, // optional accum for z=accum(w(I),x) 9531 const <type> x, // scalar to assign to w(I) 9532 const GrB_Index *I, // row indices 9533 const GrB_Index ni, // number of row indices 9534 const GrB_Descriptor desc // descriptor for w and mask 9535) ; 9536\end{verbatim} } \end{mdframed} 9537 9538\verb'GrB_Vector_assign_<type>' assigns a single scalar to an entire subvector 9539of the vector \verb'w'. The operation is exactly like setting a single entry 9540in an \verb'n'-by-1 matrix, \verb'A(I,0) = x', where the column index for a 9541vector is implicitly \verb'j=0'. The \verb'mask' vector has the same size as 9542\verb'w'. For further details of this function, see 9543\verb'GrB_Matrix_assign_<type>' in the next section. 9544 9545Following the C API Specification, results are well-defined if \verb'I' 9546contains duplicate indices. Duplicate indices are simply ignored. See 9547Section~\ref{duplicates} for more details. 9548 9549% \newpage 9550%------------------------------------------------------------------------------- 9551\subsubsection{{\sf GrB\_Matrix\_assign\_$<$type$>$:} assign a scalar to a submatrix} 9552%------------------------------------------------------------------------------- 9553\label{assign_matrix_scalar} 9554 9555\begin{mdframed}[userdefinedwidth=6in] 9556{\footnotesize 9557\begin{verbatim} 9558GrB_Info GrB_assign // C<Mask>(I,J) = accum (C(I,J),x) 9559( 9560 GrB_Matrix C, // input/output matrix for results 9561 const GrB_Matrix Mask, // optional mask for C, unused if NULL 9562 const GrB_BinaryOp accum, // optional accum for Z=accum(C(I,J),x) 9563 const <type> x, // scalar to assign to C(I,J) 9564 const GrB_Index *I, // row indices 9565 const GrB_Index ni, // number of row indices 9566 const GrB_Index *J, // column indices 9567 const GrB_Index nj, // number of column indices 9568 const GrB_Descriptor desc // descriptor for C and Mask 9569) ; 9570\end{verbatim} } \end{mdframed} 9571 9572\verb'GrB_Matrix_assign_<type>' assigns a single scalar to an entire 9573submatrix of \verb'C', like the {\em scalar expansion} \verb'C(I,J)=x' in 9574MATLAB. The scalar \verb'x' is implicitly expanded into a matrix \verb'A' of 9575size \verb'ni' by \verb'nj', and then the matrix \verb'A' is assigned to 9576\verb'C(I,J)' using the same method as in \verb'GrB_Matrix_assign'. Refer 9577to that function in Section~\ref{assign_matrix} for further details. 9578 9579The \verb'Mask' has the same size as \verb'C'. 9580 9581For the accumulation step, the scalar \verb'x' is typecasted directly into the 9582type of \verb'C' when the \verb'accum' operator is not applied to it, or into 9583the \verb'ytype' of the \verb'accum' operator, if \verb'accum' is not NULL, for 9584entries that are already present in \verb'C'. 9585 9586The \verb'<type> x' notation is otherwise the same as 9587\verb'GrB_Matrix_setElement' (see Section~\ref{matrix_setElement}). Any value 9588can be passed to this function and its type will be detected, via the 9589\verb'_Generic' feature of ANSI C11. For a user-defined type, \verb'x' is a 9590\verb'void *' pointer that points to a memory space holding a single entry of a 9591scalar that has exactly the same user-defined type as the matrix \verb'C'. 9592This user-defined type must exactly match the user-defined type of \verb'C' 9593since no typecasting is done between user-defined types. 9594 9595If a \verb'void *' pointer is passed in and the type of the underlying scalar 9596does not exactly match the user-defined type of \verb'C', then results are 9597undefined. No error status will be returned since GraphBLAS has no way of 9598catching this error. 9599 9600Following the C API Specification, results are well-defined if \verb'I' or 9601\verb'J' contain duplicate indices. Duplicate indices are simply ignored. See 9602Section~\ref{duplicates} for more details. 9603 9604\paragraph{\bf Performance considerations:} % C(I,J) = scalar 9605If \verb'A' is not transposed: if \verb'|I|' is small, then it is fastest if 9606the format of \verb'C' is \verb'GxB_BY_ROW'; if \verb'|J|' is small, then it is 9607fastest if the format of \verb'C' is \verb'GxB_BY_COL'. The opposite is true 9608if \verb'A' is transposed. 9609 9610\newpage 9611%=============================================================================== 9612\subsection{Duplicate indices in {\sf GrB\_assign} and {\sf GxB\_subassign}} 9613%=============================================================================== 9614\label{duplicates} 9615 9616According to the GraphBLAS C API Specification if the index vectors \verb'I' or 9617\verb'J' contain duplicate indices, the results are undefined for 9618\verb'GrB_Matrix_assign', \verb'GrB_Matrix_assign', \verb'GrB_Col_assign', and 9619\verb'GrB_Row_assign'. Only the scalar assignment operations 9620(\verb'GrB_Matrix_assign_TYPE' and \verb'GrB_Matrix_assign_TYPE') are 9621well-defined when duplicates appear in \verb'I' and \verb'J'. In those two 9622functions, duplicate indices are ignored. 9623 9624As an extension to the specification, SuiteSparse:GraphBLAS provides a 9625definition of how duplicate indices are handled in all cases. If \verb'I' has 9626duplicate indices, they are ignored and the last unique entry in the list is 9627used. When no mask and no accumulator is present, the results are identical to 9628how MATLAB handles duplicate indices in the built-in expression 9629\verb'C(I,J)=A'. Details of how this is done is shown below. 9630 9631{\small 9632\begin{verbatim} 9633 function C = subassign (C, I, J, A) 9634 % submatrix assignment with pre-sort of I and J; and remove duplicates 9635 9636 % delete duplicates from I, keeping the last one seen 9637 [I2 I2k] = sort (I) ; 9638 Idupl = [(I2 (1:end-1) == I2 (2:end)), false] ; 9639 I2 = I2 (~Idupl) ; 9640 I2k = I2k (~Idupl) ; 9641 assert (isequal (I2, unique (I))) 9642 9643 % delete duplicates from J, keeping the last one seen 9644 [J2 J2k] = sort (J) ; 9645 Jdupl = [(J2 (1:end-1) == J2 (2:end)), false] ; 9646 J2 = J2 (~Jdupl) ; 9647 J2k = J2k (~Jdupl) ; 9648 assert (isequal (J2, unique (J))) 9649 9650 % do the submatrix assignment, with no duplicates in I2 or J2 9651 C (I2,J2) = A (I2k,J2k) ; 9652\end{verbatim}} 9653 9654If a mask is present, then it is replaced with \verb'M = M (I2k, J2k)' for 9655\verb'GxB_subassign', or with \verb'M = M (I2, J2)' for \verb'GrB_assign'. 9656If an accumulator operator is present, it is applied after the duplicates 9657are removed, as (for example): 9658 9659{\small 9660\begin{verbatim} 9661 C (I2,J2) = C (I2,J2) + A (I2k,J2k) ; 9662\end{verbatim}} 9663 9664These definitions allow the MATLAB interface to GraphBLAS to return the same 9665results for \verb'C(I,J)=A' for a \verb'GrB' object as they do for built-in 9666MATLAB matrices. They also allow the assignment to be done in parallel. 9667 9668Results are always well-defined in SuiteSparse:GraphBLAS, but they might not be 9669what you expect. For example, suppose the \verb'MIN' operator is being used 9670the following assigment to the vector \verb'x', and suppose \verb'I' contains 9671the entries \verb'[0 0]'. Suppose \verb'x' is initially empty, of length 1, 9672and suppose \verb'y' is a vector of length 2 with the values \verb'[5 7]'. 9673 9674{\small 9675\begin{verbatim} 9676 #include "GraphBLAS.h" 9677 #include <stdio.h> 9678 int main (void) 9679 { 9680 GrB_init (GrB_NONBLOCKING) ; 9681 GrB_Vector x, y ; 9682 GrB_Vector_new (&x, GrB_INT32, 1) ; 9683 GrB_Vector_new (&y, GrB_INT32, 2) ; 9684 GrB_Index I [2] = {0, 0} ; 9685 GrB_Vector_setElement (y, 5, 0) ; 9686 GrB_Vector_setElement (y, 7, 1) ; 9687 GrB_Vector_wait (&y) ; 9688 GxB_print (x, 3) ; 9689 GxB_print (y, 3) ; 9690 GrB_assign (x, NULL, GrB_MIN_INT32, y, I, 2, NULL) ; 9691 GrB_Vector_wait (&y) ; 9692 GxB_print (x, 3) ; 9693 GrB_finalize ( ) ; 9694 } 9695\end{verbatim}} 9696 9697You might (wrongly) expect the result to be the vector \verb'x(0)=5', since 9698two entries seem to be assigned, and the min operator might be expected to 9699take the minimum of the two. This is not how SuiteSparse:GraphBLAS handles 9700duplicates. 9701 9702Instead, the first duplicate index of \verb'I' is discarded 9703(\verb'I [0] = 0', and \verb'y(0)=5'). 9704and only the second entry is used 9705(\verb'I [1] = 0', and \verb'y(1)=7'). 9706The output of the above program is: 9707 9708{\small 9709\begin{verbatim} 9710 9711 1x1 GraphBLAS int32_t vector, sparse by col: 9712 x, no entries 9713 9714 9715 2x1 GraphBLAS int32_t vector, sparse by col: 9716 y, 2 entries 9717 9718 (0,0) 5 9719 (1,0) 7 9720 9721 9722 1x1 GraphBLAS int32_t vector, sparse by col: 9723 x, 1 entry 9724 9725 (0,0) 7 9726 9727\end{verbatim}} 9728 9729You see that the result is \verb'x(0)=7', since the \verb'y(0)=5' entry 9730has been ignored because of the duplicate indices in \verb'I'. 9731 9732\begin{alert} 9733{\bf SPEC:} Providing a well-defined behavior for duplicate 9734indices with matrix and vector assignment is an extension to the spec. 9735The spec only defines the behavior when assigning a scalar into a matrix 9736or vector, and states that duplicate indices otherwise lead to undefined 9737results. 9738\end{alert} 9739 9740 9741\newpage 9742%=============================================================================== 9743\subsection{Comparing {\sf GrB\_assign} and {\sf GxB\_subassign}} %============= 9744%=============================================================================== 9745\label{compare_assign} 9746 9747The \verb'GxB_subassign' and \verb'GrB_assign' operations are very similar, but 9748they differ in two ways: 9749 9750\begin{enumerate} 9751\item {\bf The Mask has a different size:} 9752 The mask in \verb'GxB_subassign' has the same dimensions as \verb'w(I)' for 9753 vectors and \verb'C(I,J)' for matrices. In \verb'GrB_assign', the mask is 9754 the same size as \verb'w' or \verb'C', respectively (except for the row/col 9755 variants). The two masks are related. If \verb'M' is the mask for 9756 \verb'GrB_assign', then \verb'M(I,J)' is the mask for \verb'GxB_subassign'. 9757 If there is no mask, or if \verb'I' and \verb'J' are both \verb'GrB_ALL', 9758 the two masks are the same. 9759 For \verb'GrB_Row_assign' and \verb'GrB_Col_assign', the \verb'mask' vector 9760 is the same size as a row or column of \verb'C', respectively. For the 9761 corresponding \verb'GxB_Row_subassign' and \verb'GxB_Col_subassign' 9762 operations, the \verb'mask' is the same size as the sub-row \verb'C(i,J)' or 9763 subcolumn \verb'C(I,j)', respectively. 9764 9765\item {\bf \verb'GrB_REPLACE' is different:} 9766 They differ in how \verb'C' is affected in areas outside the \verb'C(I,J)' 9767 submatrix. In \verb'GxB_subassign', the \verb'C(I,J)' submatrix is the 9768 only part of \verb'C' that can be modified, and no part of \verb'C' outside 9769 the submatrix is ever modified. In \verb'GrB_assign', it is possible to 9770 delete entries in \verb'C' outside the submatrix, but only in one specific 9771 manner. Suppose the mask \verb'M' is present (or, suppose it is not 9772 present but \verb'GrB_COMP' is true). After (optionally) complementing the 9773 mask, the value of \verb'M(i,j)' can be 0 for some entry outside the 9774 \verb'C(I,J)' submatrix. If the \verb'GrB_REPLACE' descriptor is 9775 true, \verb'GrB_assign' deletes this entry. 9776 9777\end{enumerate} 9778 9779\verb'GxB_subassign' and \verb'GrB_assign' are identical if \verb'GrB_REPLACE' 9780is set to its default value of false, and if the masks happen to be the same. 9781The two masks can be the same in two cases: either the \verb'Mask' input is 9782\verb'NULL' (and it is not complemented via \verb'GrB_COMP'), or \verb'I' and 9783\verb'J' are both \verb'GrB_ALL'. 9784If all these conditions hold, 9785the two algorithms are identical and have the same performance. Otherwise, 9786\verb'GxB_subassign' is much faster than \verb'GrB_assign' when the latter 9787must examine the entire matrix \verb'C' to delete entries (when 9788\verb'GrB_REPLACE' is true), and if it must deal with a much larger \verb'Mask' 9789matrix. However, both methods have specific uses. 9790 9791Consider using \verb'C(I,J)+=F' for many submatrices \verb'F' (for example, 9792when assembling a finite-element matrix). If the \verb'Mask' is meant as a 9793specification for which entries of \verb'C' should appear in the final result, 9794then use \verb'GrB_assign'. 9795 9796If instead the \verb'Mask' is meant to control which entries of the submatrix 9797\verb'C(I,J)' are modified by the finite-element \verb'F', then use 9798\verb'GxB_subassign'. This is particularly useful is the \verb'Mask' is a 9799template that follows along with the finite-element \verb'F', independent of 9800where it is applied to \verb'C'. Using \verb'GrB_assign' would be very 9801difficult in this case since a new \verb'Mask', the same size as \verb'C', 9802would need to be constructed for each finite-element \verb'F'. 9803 9804In GraphBLAS notation, the two methods can be described as follows: 9805 9806\vspace{0.05in} 9807\begin{tabular}{ll} 9808\hline 9809matrix and vector subassign & ${\bf C(I,J) \langle M \rangle} = {\bf C(I,J)} \odot {\bf A}$ \\ 9810matrix and vector assign & ${\bf C \langle M \rangle (I,J)} = {\bf C(I,J)} \odot {\bf A}$ \\ 9811\hline 9812\end{tabular} 9813\vspace{0.05in} 9814 9815This notation does not include the details of the \verb'GrB_COMP' and 9816\verb'GrB_REPLACE' descriptors, but it does illustrate the difference in the 9817\verb'Mask'. In the subassign, \verb'Mask' is the same size as \verb'C(I,J)' 9818and \verb'A'. If \verb'I[0]=i' and \verb'J[0]=j', Then \verb'Mask(0,0)' 9819controls how \verb'C(i,j)' is modified by the subassign, from the value 9820\verb'A(0,0)'. In the assign, \verb'Mask' is the same size as \verb'C', and 9821\verb'Mask(i,j)' controls how \verb'C(i,j)' is modified. 9822 9823The \verb'GxB_subassign' and \verb'GrB_assign' functions have the same 9824signatures; they differ only in how they consider the \verb'Mask' and the 9825\verb'GrB_REPLACE' descriptor 9826 9827Details of each step of the two operations are listed below: 9828 9829\vspace{0.1in} 9830\begin{tabular}{lll} 9831\hline 9832Step & \verb'GrB_Matrix_assign' & \verb'GxB_Matrix_subassign' \\ 9833\hline 98341 & ${\bf S} = {\bf C(I,J)}$ & ${\bf S} = {\bf C(I,J)}$ \\ 98352 & ${\bf S} = {\bf S} \odot {\bf A}$ & ${\bf S \langle M \rangle} = {\bf S} \odot {\bf A}$ \\ 98363 & ${\bf Z} = {\bf C}$ & ${\bf C(I,J)}= {\bf S}$ \\ 98374 & ${\bf Z(I,J)} = {\bf S}$ & \\ 98385 & ${\bf C \langle M \rangle = Z}$ & \\ 9839\hline 9840\end{tabular} 9841\vspace{0.1in} 9842 9843Step 1 is the same. In the Accumulator Phase (Step 2), the expression 9844${\bf S} \odot {\bf A}$, 9845described in Section~\ref{accummask}, is the same in both 9846operations. The result is simply ${\bf A}$ if \verb'accum' is \verb'NULL'. It 9847only applies to the submatrix ${\bf S}$, not the whole matrix. 9848The result ${\bf S} \odot {\bf A}$ is used differently in the Mask/Replace 9849phase. 9850 9851The Mask/Replace Phase, described in Section~\ref{accummask} is different: 9852\begin{itemize} 9853\item 9854 For \verb'GrB_assign' (Step 5), the mask is applied to all of ${\bf 9855 C}$. The mask has the same size as ${\bf C}$. Just prior to making the 9856 assignment via the mask, the \verb'GrB_REPLACE' option can be used to clear 9857 all of ${\bf C}$ first. This is the only way in which entries in ${\bf C}$ that 9858 are outside the ${\bf C(I,J)}$ submatrix can be modified by this operation. 9859 9860\item 9861 For \verb'GxB_subassign' (Step 2b), the mask is applied to just 9862 ${\bf S}$. The mask has the same size as ${\bf C(I,J)}$, ${\bf S}$, and 9863 ${\bf A}$. Just prior to making the assignment via the mask, the 9864 \verb'GrB_REPLACE' option can be used to clear ${\bf S}$ first. No entries 9865 in ${\bf C}$ that are outside the ${\bf C(I,J)}$ can be modified by this 9866 operation. Thus, \verb'GrB_REPLACE' has no effect on entries in ${\bf C}$ 9867 outside the ${\bf C(I,J)}$ submatrix. 9868 9869\end{itemize} 9870 9871The differences between \verb'GrB_assign' and 9872\verb'GxB_subassign' can be seen in Tables~\ref{insubmatrix} and 9873\ref{outsubmatrix}. The first table considers the case when the entry $c_{ij}$ 9874is in the ${\bf C(I,J)}$ submatrix, and it describes what is computed for both 9875\verb'GrB_assign' and \verb'GxB_subassign'. They perform the 9876exact same computation; the only difference is how the value of the mask is 9877specified. Compare Table~\ref{insubmatrix} with Table~\ref{tab:maskaccum} 9878in Section~\ref{sec:maskaccum}. 9879 9880The first column of Table~\ref{insubmatrix} is {\em yes} if \verb'GrB_REPLACE' is enabled, 9881and a dash otherwise. The second column is {\em yes} if an accumulator 9882operator is given, and a dash otherwise. The third column is $c_{ij}$ if the 9883entry is present in ${\bf C}$, and a dash otherwise. The fourth column is 9884$a_{i'j'}$ if the corresponding entry is present in ${\bf A}$, where 9885$i={\bf I}(i')$ and $j={\bf J}(i')$. 9886 9887The {\em mask} column is 1 if the effective value of the mask mask allows ${\bf 9888C}$ to be modified, and 0 otherwise. This is $m_{ij}$ for \verb'GrB_assign', 9889and $m_{i'j'}$ for \verb'GxB_subassign', to reflect the difference in the mask, 9890but this difference is not reflected in the table. The value 1 or 0 is the 9891value of the entry in the mask after it is optionally complemented via the 9892\verb'GrB_COMP' option. 9893 9894Finally, the last column is the action taken in this case. It is left blank if 9895no action is taken, in which case $c_{ij}$ is not modified if present, or not 9896inserted into ${\bf C}$ if not present. 9897 9898\begin{table} 9899{\small 9900\begin{tabular}{lllll|l} 9901\hline 9902repl & accum & ${\bf C}$ & ${\bf A}$ & mask & action taken by \verb'GrB_assign' and \verb'GxB_subassign'\\ 9903\hline 9904 - &- & $c_{ij}$ & $a_{i'j'}$ & 1 & $c_{ij} = a_{i'j'}$, update \\ 9905 - &- & - & $a_{i'j'}$ & 1 & $c_{ij} = a_{i'j'}$, insert \\ 9906 - &- & $c_{ij}$ & - & 1 & delete $c_{ij}$ because $a_{i'j'}$ not present \\ 9907 - &- & - & - & 1 & \\ 9908 - &- & $c_{ij}$ & $a_{i'j'}$ & 0 & \\ 9909 - &- & - & $a_{i'j'}$ & 0 & \\ 9910 - &- & $c_{ij}$ & - & 0 & \\ 9911 - &- & - & - & 0 & \\ 9912\hline 9913 yes&- & $c_{ij}$ & $a_{i'j'}$ & 1 & $c_{ij} = a_{i'j'}$, update \\ 9914 yes&- & - & $a_{i'j'}$ & 1 & $c_{ij} = a_{i'j'}$, insert \\ 9915 yes&- & $c_{ij}$ & - & 1 & delete $c_{ij}$ because $a_{i'j'}$ not present \\ 9916 yes&- & - & - & 1 & \\ 9917 yes&- & $c_{ij}$ & $a_{i'j'}$ & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 9918 yes&- & - & $a_{i'j'}$ & 0 & \\ 9919 yes&- & $c_{ij}$ & - & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 9920 yes&- & - & - & 0 & \\ 9921\hline 9922 - &yes & $c_{ij}$ & $a_{i'j'}$ & 1 & $c_{ij} = c_{ij} \odot a_{i'j'}$, apply accumulator \\ 9923 - &yes & - & $a_{i'j'}$ & 1 & $c_{ij} = a_{i'j'}$, insert \\ 9924 - &yes & $c_{ij}$ & - & 1 & \\ 9925 - &yes & - & - & 1 & \\ 9926 - &yes & $c_{ij}$ & $a_{i'j'}$ & 0 & \\ 9927 - &yes & - & $a_{i'j'}$ & 0 & \\ 9928 - &yes & $c_{ij}$ & - & 0 & \\ 9929 - &yes & - & - & 0 & \\ 9930\hline 9931 yes&yes & $c_{ij}$ & $a_{i'j'}$ & 1 & $c_{ij} = c_{ij} \odot a_{i'j'}$, apply accumulator \\ 9932 yes&yes & - & $a_{i'j'}$ & 1 & $c_{ij} = a_{i'j'}$, insert \\ 9933 yes&yes & $c_{ij}$ & - & 1 & \\ 9934 yes&yes & - & - & 1 & \\ 9935 yes&yes & $c_{ij}$ & $a_{i'j'}$ & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 9936 yes&yes & - & $a_{i'j'}$ & 0 & \\ 9937 yes&yes & $c_{ij}$ & - & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 9938 yes&yes & - & - & 0 & \\ 9939\hline 9940\end{tabular} 9941} 9942\caption{Results of assign and subassign for entries in the ${\bf C(I,J)}$ submatrix \label{insubmatrix}} 9943\end{table} 9944 9945\newpage 9946Table~\ref{outsubmatrix} illustrates how \verb'GrB_assign' and 9947\verb'GxB_subassign' differ for entries outside the submatrix. 9948\verb'GxB_subassign' never modifies any entry outside the ${\bf C(I,J)}$ 9949submatrix, but \verb'GrB_assign' can modify them in two cases listed in 9950Table~\ref{outsubmatrix}. When the \verb'GrB_REPLACE' option is selected, and 9951when the \verb'Mask(i,j)' for an entry $c_{ij}$ is false (or if the 9952\verb'Mask(i,j)' is true and \verb'GrB_COMP' is enabled via the descriptor), 9953then the entry is deleted by \verb'GrB_assign'. 9954 9955The fourth column of Table~\ref{outsubmatrix} differs from 9956Table~\ref{insubmatrix}, since entries in ${\bf A}$ never affect these entries. 9957Instead, for all index pairs outside the $I \times J$ submatrix, ${\bf C}$ and 9958${\bf Z}$ are identical (see Step 3 above). As a result, each section of the 9959table includes just two cases: either $c_{ij}$ is present, or not. This in 9960contrast to Table~\ref{insubmatrix}, where each section must consider four 9961different cases. 9962 9963The \verb'GrB_Row_assign' and \verb'GrB_Col_assign' operations are slightly 9964different. They only affect a single row or column of ${\bf C}$. 9965For \verb'GrB_Row_assign', Table~\ref{outsubmatrix} only applies to entries in 9966the single row \verb'C(i,J)' that are outside the list of indices, \verb'J'. 9967For \verb'GrB_Col_assign', Table~\ref{outsubmatrix} only applies to entries in 9968the single column \verb'C(I,j)' that are outside the list of indices, \verb'I'. 9969 9970\begin{table} 9971{\small 9972\begin{tabular}{lllll|l} 9973\hline 9974repl & accum & ${\bf C}$ & ${\bf C=Z}$ & mask & action taken by \verb'GrB_assign' \\ 9975\hline 9976 - &- & $c_{ij}$ & $c_{ij}$ & 1 & \\ 9977 - &- & - & - & 1 & \\ 9978 - &- & $c_{ij}$ & $c_{ij}$ & 0 & \\ 9979 - &- & - & - & 0 & \\ 9980\hline 9981 yes & - & $c_{ij}$ & $c_{ij}$ & 1 & \\ 9982 yes & - & - & - & 1 & \\ 9983 yes & - & $c_{ij}$ & $c_{ij}$ & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 9984 yes & - & - & - & 0 & \\ 9985\hline 9986 - &yes & $c_{ij}$ & $c_{ij}$ & 1 & \\ 9987 - &yes & - & - & 1 & \\ 9988 - &yes & $c_{ij}$ & $c_{ij}$ & 0 & \\ 9989 - &yes & - & - & 0 & \\ 9990\hline 9991 yes & yes & $c_{ij}$ & $c_{ij}$ & 1 & \\ 9992 yes & yes & - & - & 1 & \\ 9993 yes & yes & $c_{ij}$ & $c_{ij}$ & 0 & delete $c_{ij}$ (because of \verb'GrB_REPLACE') \\ 9994 yes & yes & - & - & 0 & \\ 9995\hline 9996\end{tabular} 9997} 9998\caption{Results of assign for entries outside the 9999${\bf C(I,J)}$ submatrix. Subassign has no effect on these entries. \label{outsubmatrix}} 10000\end{table} 10001 10002%------------------------------------------------------------------------------- 10003\subsubsection{Example} 10004%------------------------------------------------------------------------------- 10005 10006The difference between \verb'GxB_subassign' and \verb'GrB_assign' is 10007illustrated in the following example. Consider the 2-by-2 matrix ${\bf C}$ 10008where all entries are present. 10009 10010\[ 10011{\bf C} = \left[ 10012 \begin{array}{rr} 10013 11 & 12 \\ 10014 21 & 22 \\ 10015 \end{array} 10016 \right] 10017\] 10018 10019Suppose \verb'GrB_REPLACE' is true, and \verb'GrB_COMP' is false. Let the 10020\verb'Mask' be: 10021 10022\[ 10023{\bf M} = \left[ 10024 \begin{array}{rr} 10025 1 & 1 \\ 10026 0 & 1 \\ 10027 \end{array} 10028 \right]. 10029\] 10030 10031Let ${\bf A} = 100$, and let the index sets be ${\bf I}=0$ and ${\bf J}=1$. 10032Consider the computation 10033${\bf C \langle M \rangle} (0,1) = {\bf C}(0,1) + {\bf A}$, 10034using the \verb'GrB_assign' operation. The result is: 10035\[ 10036{\bf C} = \left[ 10037 \begin{array}{rr} 10038 11 & 112 \\ 10039 - & 22 \\ 10040 \end{array} 10041 \right]. 10042\] 10043The $(0,1)$ entry is updated and the $(1,0)$ entry is deleted because 10044its \verb'Mask' is zero. The other two entries are not modified since ${\bf Z} 10045= {\bf C}$ outside the submatrix, and those two values are written back into 10046${\bf C}$ because their \verb'Mask' values are 1. The $(1,0)$ entry is deleted 10047because the entry ${\bf Z}(1,0)=21$ is prevented from being written back into 10048${\bf C}$ since \verb'Mask(1,0)=0'. 10049 10050Now consider the analogous \verb'GxB_subassign' operation. The \verb'Mask' has 10051the same size as ${\bf A}$, namely: 10052\[ 10053{\bf M} = \left[ 10054 \begin{array}{r} 10055 1 \\ 10056 \end{array} 10057 \right]. 10058\] 10059 10060After computing 10061${\bf C} (0,1) {\bf \langle M \rangle} = {\bf C}(0,1) + {\bf A}$, 10062the result is 10063 10064\[ 10065{\bf C} = \left[ 10066 \begin{array}{rr} 10067 11 & 112 \\ 10068 21 & 22 \\ 10069 \end{array} 10070 \right]. 10071\] 10072 10073Only the ${\bf C(I,J)}$ submatrix, the single entry ${\bf C}(0,1)$, is modified 10074by \verb'GxB_subassign'. The entry ${\bf C}(1,0)=21$ is unaffected by 10075\verb'GxB_subassign', but it is deleted by \verb'GrB_assign'. 10076 10077\newpage 10078%------------------------------------------------------------------------------- 10079\subsubsection{Performance of {\sf GxB\_subassign}, {\sf GrB\_assign} 10080and {\sf GrB\_*\_setElement}} 10081%------------------------------------------------------------------------------- 10082 10083When SuiteSparse:GraphBLAS uses non-blocking mode, the modifications to a 10084matrix by \verb'GxB_subassign', \verb'GrB_assign', and \verb'GrB_*_setElement' 10085can postponed, and computed all at once later on. This has a huge impact on 10086performance. 10087 10088A sequence of assignments is fast if their completion can be postponed for as 10089long as possible, or if they do not modify the pattern at all. Modifying the 10090pattern can be costly, but it is fast if non-blocking mode can be fully 10091exploited. 10092 10093Consider a sequence of $t$ submatrix assignments \verb'C(I,J)=C(I,J)+A' to an 10094$n$-by-$n$ matrix \verb'C' where each submatrix \verb'A' has size $a$-by-$a$ 10095with $s$ entries, and where \verb'C' starts with $c$ entries. 10096Assume the matrices are all stored in non-hypersparse form, by row 10097(\verb'GxB_BY_ROW'). 10098 10099If blocking mode is enabled, or if the sequence requires the matrix to be 10100completed after each assignment, each of the $t$ assignments takes $O(a + s 10101\log n)$ time to process the \verb'A' matrix and then $O(n + c + s \log s)$ 10102time to complete \verb'C'. The latter step uses \verb'GrB_*_build' to build an 10103update matrix and then merge it with \verb'C'. This step does not occur if the 10104sequence of assignments does not add new entries to the pattern of \verb'C', 10105however. Assuming in the worst case that the pattern does change, the total 10106time is $O (t \left[ a + s \log n + n + c + s \log s \right] )$. 10107 10108If the sequence can be computed with all updates postponed until the end of the 10109sequence, then the total time is no worse than $O(a + s \log n)$ to process 10110each \verb'A' matrix, for $t$ assignments, and then a single \verb'build' at 10111the end, taking $O(n + c + st \log st)$ time. 10112The total time is $O (t \left [a + s \log n \right] + (n + c + st \log st))$. 10113If no new entries appear in 10114\verb'C' the time drops to $O (t \left [a + s \log n \right])$, and in this 10115case, the time for both methods is the same; both are equally efficient. 10116 10117A few simplifying assumptions are useful to compare these times. Consider a 10118graph of $n$ nodes with $O(n)$ edges, and with a constant bound on the degree 10119of each node. The asymptotic bounds assume a worst-case scenario where 10120\verb'C' has a least some dense rows (thus the $\log n$ terms). If these 10121are not present, if both $t$ and $c$ are $O(n)$, and if $a$ and $s$ are 10122constants, then the total time with blocking mode becomes $O(n^2)$, assuming 10123the pattern of \verb'C' changes at each assignment. This very high for a 10124sparse graph problem. In contrast, the non-blocking time becomes $O(n \log n)$ 10125under these same assumptions, which is asymptotically much faster. 10126 10127\newpage 10128The difference in practice can be very dramatic, since $n$ can be many millions 10129for sparse graphs with $n$ nodes and $O(n)$, which can be handled on a 10130commodity laptop. 10131 10132The following guidelines should be considered when using 10133\verb'GxB_subassign', \verb'GrB_assign' and \verb'GrB_*_setElement'. 10134 10135\begin{enumerate} 10136 10137\item A sequence of assignments that does not modify the pattern at all is 10138fast, taking as little as $\Omega(1)$ time per entry modified. The worst case 10139time complexity is $O(\log n)$ per entry, assuming they all modify a dense 10140row of \verb'C' with \verb'n' entries, which can occur in practice. It is 10141more common, however, that most rows of \verb'C' have a constant number of 10142entries, independent of \verb'n'. No work is ever left pending when the 10143pattern of \verb'C' does not change. 10144 10145\item A sequence of assignments that modifies the entries that already exist in 10146the pattern of a matrix, or adds new entries to the pattern (using the same 10147\verb'accum' operator), but does not delete any entries, is fast. The matrix 10148is not completed until the end of the sequence. 10149 10150\item Similarly, a sequence that modifies existing entries, or deletes them, 10151but does not add new ones, is also fast. This sequence can also repeatedly 10152delete pre-existing entries and then reinstate them and still be fast. The 10153matrix is not completed until the end of the sequence. 10154 10155\item A sequence that mixes assignments of types (2) and (3) above can be 10156costly, since the matrix may need to be completed after each assignment. The 10157time complexity can become quadratic in the worst case. 10158 10159\item However, any single assignment takes no more than $O (a + s \log n + n + 10160c + s \log s )$ time, even including the time for a matrix completion, where 10161\verb'C' is $n$-by-$n$ with $c$ entries and \verb'A' is $a$-by-$a$ with $s$ 10162entries. This time is essentially linear in the size of the matrix \verb'C', 10163if \verb'A' is relatively small and sparse compared with \verb'C'. In this 10164case, $n+c$ are the two dominant terms. 10165 10166\item In general, \verb'GxB_subassign' is faster than \verb'GrB_assign'. 10167If \verb'GrB_REPLACE' is used with \verb'GrB_assign', the entire matrix 10168\verb'C' must be traversed. This is much slower than \verb'GxB_subassign', 10169which only needs to examine the \verb'C(I,J)' submatrix. Furthermore, 10170\verb'GrB_assign' must deal with a much larger \verb'Mask' matrix, whereas 10171\verb'GxB_subassign' has a smaller mask. Since its mask is smaller, 10172\verb'GxB_subassign' takes less time than \verb'GrB_assign' to access the mask. 10173 10174\end{enumerate} 10175 10176% see GraphBLAS/Test/test46.m 10177 10178Submatrix assignment in SuiteSparse:GraphBLAS is extremely efficient, even 10179without considering the advantages of non-blocking mode discussed in 10180Section~\ref{compare_assign}. It can be up to 500x faster than MATLAB 10181R2019b, or even higher depending on the kind of matrix assignment. 10182MATLAB logical indexing (the mask of GraphBLAS) is much faster with 10183GraphBLAS than in MATLAB R2019b; differences of up to 100,000x have been 10184observed. 10185 10186All of the 28 variants (each with their own source code) are either 10187asymptotically optimal, or to within a log factor of being asymptotically 10188optimal. The methods are also fully parallel. For hypersparse matrices, the 10189term $n$ in the expressions in the above discussion is dropped, and is replaced 10190with $h \log h$, at the worst case, where $h << n$ is the number of non-empty 10191columns of a hypersparse matrix stored by column, or the number of non-empty 10192rows of a hypersparse matrix stored by row. In many methods, $n$ is replaced 10193with $h$, not $h \log h$. 10194 10195\newpage 10196%=============================================================================== 10197\subsection{{\sf GrB\_apply:} apply a unary or binary operator} %=============== 10198%=============================================================================== 10199\label{apply} 10200 10201\verb'GrB_apply' is the generic name for 62 specific functions. 10202\verb'GrB_Vector_apply' and \verb'GrB_Matrix_apply' apply a unary operator to 10203the entries of a matrix. \verb'GrB_*_apply_BinaryOp1st*' applies a binary 10204operator where a single scalar is provided as the $x$ input to the binary 10205operator. \verb'GrB_*_apply_BinaryOp2nd*' applies a binary operator where a 10206single scalar is provided as the $y$ input to the binary operator. The generic 10207name appears in the function prototypes, but the specific function name is used 10208when describing each variation. When discussing features that apply to all 10209versions, the simple name \verb'GrB_apply' is used. 10210 10211% \newpage 10212%------------------------------------------------------------------------------- 10213\subsubsection{{\sf GrB\_Vector\_apply:} apply a unary operator to a vector} 10214%------------------------------------------------------------------------------- 10215\label{apply_vector} 10216 10217\begin{mdframed}[userdefinedwidth=6in] 10218{\footnotesize 10219\begin{verbatim} 10220GrB_Info GrB_apply // w<mask> = accum (w, op(u)) 10221( 10222 GrB_Vector w, // input/output vector for results 10223 const GrB_Vector mask, // optional mask for w, unused if NULL 10224 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 10225 const GrB_UnaryOp op, // operator to apply to the entries 10226 const GrB_Vector u, // first input: vector u 10227 const GrB_Descriptor desc // descriptor for w and mask 10228) ; 10229\end{verbatim} } \end{mdframed} 10230 10231\verb'GrB_Vector_apply' applies a unary operator to the entries of a vector, 10232analogous to \verb't = op(u)' in MATLAB except the operator \verb'op' is only 10233applied to entries in the pattern of \verb'u'. Implicit values outside the 10234pattern of \verb'u' are not affected. The entries in \verb'u' are typecasted 10235into the \verb'xtype' of the unary operator. The vector \verb't' has the same 10236type as the \verb'ztype' of the unary operator. The final step is ${\bf w 10237\langle m \rangle = w \odot t}$, as described in Section~\ref{accummask}, 10238except that all the terms are column vectors instead of matrices. 10239 10240\newpage 10241%------------------------------------------------------------------------------- 10242\subsubsection{{\sf GrB\_Matrix\_apply:} apply a unary operator to a matrix} 10243%------------------------------------------------------------------------------- 10244\label{apply_matrix} 10245 10246\begin{mdframed}[userdefinedwidth=6in] 10247{\footnotesize 10248\begin{verbatim} 10249GrB_Info GrB_apply // C<Mask> = accum (C, op(A)) or op(A') 10250( 10251 GrB_Matrix C, // input/output matrix for results 10252 const GrB_Matrix Mask, // optional mask for C, unused if NULL 10253 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 10254 const GrB_UnaryOp op, // operator to apply to the entries 10255 const GrB_Matrix A, // first input: matrix A 10256 const GrB_Descriptor desc // descriptor for C, mask, and A 10257) ; 10258\end{verbatim} } \end{mdframed} 10259 10260\verb'GrB_Matrix_apply' 10261applies a unary operator to the entries of a matrix, analogous to 10262\verb'T = op(A)' in MATLAB except the operator \verb'op' is only applied to 10263entries in the pattern of \verb'A'. Implicit values outside the pattern of 10264\verb'A' are not affected. The input matrix \verb'A' may be transposed first. 10265The entries in \verb'A' are typecasted into the \verb'xtype' of the unary 10266operator. The matrix \verb'T' has the same type as the \verb'ztype' of the 10267unary operator. The final step is ${\bf C \langle M \rangle = C \odot T}$, as 10268described in Section~\ref{accummask}. 10269 10270The built-in \verb'GrB_IDENTITY_'$T$ operators (one for each built-in type $T$) 10271are very useful when combined with this function, enabling it to compute ${\bf 10272C \langle M \rangle = C \odot A}$. This makes \verb'GrB_apply' a direct 10273interface to the accumulator/mask function for both matrices and vectors. 10274The \verb'GrB_IDENTITY_'$T$ operators also provide the fastest stand-alone 10275typecasting methods in SuiteSparse:GraphBLAS, with all $13 \times 13=169$ 10276methods appearing as individual functions, to typecast between any of the 13 10277built-in types. 10278 10279To compute ${\bf C \langle M \rangle = A}$ or ${\bf C \langle M \rangle = C 10280\odot A}$ for user-defined types, the user application would need to define an 10281identity operator for the type. Since GraphBLAS cannot detect that it is an 10282identity operator, it must call the operator to make the full copy \verb'T=A' 10283and apply the operator to each entry of the matrix or vector. 10284 10285The other GraphBLAS operation that provides a direct interface to the 10286accumulator/mask function is \verb'GrB_transpose', which does not require an 10287operator to perform this task. As a result, \verb'GrB_transpose' can be used 10288as an efficient and direct interface to the accumulator/mask function for 10289both built-in and user-defined types. However, it is only available for 10290matrices, not vectors. 10291 10292\newpage 10293%=============================================================================== 10294\subsubsection{{\sf GrB\_Vector\_apply\_BinaryOp1st:} apply a binary operator to a vector; 1st scalar binding} 10295%=============================================================================== 10296\label{vector_apply1st} 10297 10298\begin{mdframed}[userdefinedwidth=6in] 10299{\footnotesize 10300\begin{verbatim} 10301GrB_Info GrB_apply // w<mask> = accum (w, op(x,u)) 10302( 10303 GrB_Vector w, // input/output vector for results 10304 const GrB_Vector mask, // optional mask for w, unused if NULL 10305 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 10306 const GrB_BinaryOp op, // operator to apply to the entries 10307 <type> x, // first input: scalar x 10308 const GrB_Vector u, // second input: vector u 10309 const GrB_Descriptor desc // descriptor for w and mask 10310) ; 10311\end{verbatim} } \end{mdframed} 10312 10313\verb'GrB_Vector_apply_BinaryOp1st_<type>' applies a binary operator 10314$z=f(x,y)$ to a vector, where a scalar $x$ is bound to the first input of the 10315operator. It is otherwise identical to \verb'GrB_Vector_apply'. With no 10316suffix, \verb'GxB_Vector_apply_BinaryOp1st' takes as input a \verb'GxB_Scalar'. 10317 10318%=============================================================================== 10319\subsubsection{{\sf GrB\_Vector\_apply\_BinaryOp2nd:} apply a binary operator to a vector; 2nd scalar binding} 10320%=============================================================================== 10321\label{vector_apply2nd} 10322 10323\begin{mdframed}[userdefinedwidth=6in] 10324{\footnotesize 10325\begin{verbatim} 10326GrB_Info GrB_apply // w<mask> = accum (w, op(u,y)) 10327( 10328 GrB_Vector w, // input/output vector for results 10329 const GrB_Vector mask, // optional mask for w, unused if NULL 10330 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 10331 const GrB_BinaryOp op, // operator to apply to the entries 10332 const GrB_Vector u, // first input: vector u 10333 <type> y, // second input: scalar y 10334 const GrB_Descriptor desc // descriptor for w and mask 10335) ; 10336\end{verbatim} } \end{mdframed} 10337 10338\verb'GrB_Vector_apply_BinaryOp2nd_<type>' applies a binary operator 10339$z=f(x,y)$ to a vector, where a scalar $y$ is bound to the second input of the 10340operator. It is otherwise identical to \verb'GrB_Vector_apply'. With no 10341suffix, \verb'GxB_Vector_apply_BinaryOp2nd' takes as input a \verb'GxB_Scalar'. 10342 10343\newpage 10344%=============================================================================== 10345\subsubsection{{\sf GrB\_Matrix\_apply\_BinaryOp1st:} apply a binary operator to a matrix; 1st scalar binding} 10346%=============================================================================== 10347\label{matrix_apply1st} 10348 10349\begin{mdframed}[userdefinedwidth=6in] 10350{\footnotesize 10351\begin{verbatim} 10352GrB_Info GrB_apply // C<M>=accum(C,op(x,A)) 10353( 10354 GrB_Matrix C, // input/output matrix for results 10355 const GrB_Matrix Mask, // optional mask for C, unused if NULL 10356 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 10357 const GrB_BinaryOp op, // operator to apply to the entries 10358 <type> x, // first input: scalar x 10359 const GrB_Matrix A, // second input: matrix A 10360 const GrB_Descriptor desc // descriptor for C, mask, and A 10361) ; 10362\end{verbatim} } \end{mdframed} 10363 10364\verb'GrB_Matrix_apply_BinaryOp1st_<type>' applies a binary operator 10365$z=f(x,y)$ to a matrix, where a scalar $x$ is bound to the first input of the 10366operator. It is otherwise identical to \verb'GrB_Matrix_apply'. With no 10367suffix, \verb'GxB_Matrix_apply_BinaryOp1st' takes as input a \verb'GxB_Scalar'. 10368To transpose the input matrix, use the \verb'GrB_INP1' descriptor setting. 10369 10370%=============================================================================== 10371\subsubsection{{\sf GrB\_Matrix\_apply\_BinaryOp2nd:} apply a binary operator to a matrix; 2nd scalar binding} 10372%=============================================================================== 10373\label{matrix_apply2nd} 10374 10375\begin{mdframed}[userdefinedwidth=6in] 10376{\footnotesize 10377\begin{verbatim} 10378GrB_Info GrB_apply // C<M>=accum(C,op(A,y)) 10379( 10380 GrB_Matrix C, // input/output matrix for results 10381 const GrB_Matrix Mask, // optional mask for C, unused if NULL 10382 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 10383 const GrB_BinaryOp op, // operator to apply to the entries 10384 const GrB_Matrix A, // first input: matrix A 10385 <type> y, // second input: scalar y 10386 const GrB_Descriptor desc // descriptor for C, mask, and A 10387) ; 10388\end{verbatim} } \end{mdframed} 10389 10390\verb'GrB_Matrix_apply_BinaryOp2nd_<type>' applies a binary operator 10391$z=f(x,y)$ to a matrix, where a scalar $x$ is bound to the second input of the 10392operator. It is otherwise identical to \verb'GrB_Matrix_apply'. With no 10393suffix, \verb'GxB_Matrix_apply_BinaryOp2nd' takes as input a \verb'GxB_Scalar'. 10394To transpose the input matrix, use the \verb'GrB_INP0' descriptor setting. 10395 10396\newpage 10397%=============================================================================== 10398\subsection{{\sf GxB\_select:} apply a select operator} %======================= 10399%=============================================================================== 10400\label{select} 10401 10402The \verb'GxB_select' function is the generic name for two specific functions: 10403\\ \verb'GxB_Vector_select' and \verb'GxB_Matrix_select'. The generic name 10404appears in the function prototypes, but the specific function name is used when 10405describing each variation. When discussing features that apply to both 10406versions, the simple name \verb'GxB_select' is used. 10407 10408% \newpage 10409%------------------------------------------------------------------------------- 10410\subsubsection{{\sf GxB\_Vector\_select:} apply a select operator to a vector} 10411%------------------------------------------------------------------------------- 10412\label{select_vector} 10413 10414\begin{mdframed}[userdefinedwidth=6in] 10415{\footnotesize 10416\begin{verbatim} 10417GrB_Info GxB_select // w<mask> = accum (w, op(u,k)) 10418( 10419 GrB_Vector w, // input/output vector for results 10420 const GrB_Vector mask, // optional mask for w, unused if NULL 10421 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 10422 const GxB_SelectOp op, // operator to apply to the entries 10423 const GrB_Vector u, // first input: vector u 10424 const GxB_Scalar Thunk, // optional input for the select operator 10425 const GrB_Descriptor desc // descriptor for w and mask 10426) ; 10427\end{verbatim} } \end{mdframed} 10428 10429\verb'GxB_Vector_select' applies a select operator to the entries of a vector, 10430analogous to \verb't = u.*op(u)' in MATLAB except the operator \verb'op' is 10431only applied to entries in the pattern of \verb'u'. Implicit values outside 10432the pattern of \verb'u' are not affected. If the operator is not type-generic, 10433the entries in \verb'u' are typecasted into the \verb'xtype' of the select 10434operator. The vector \verb't' has the same type and size as \verb'u'. The 10435final step is ${\bf w \langle m \rangle = w \odot t}$, as described in 10436Section~\ref{accummask}, except that all the terms are column vectors instead 10437of matrices. 10438 10439This operation operates on vectors just as if they were \verb'm'-by-1 matrices, 10440except that GraphBLAS never transposes a vector via the descriptor. The 10441\verb'op' is passed \verb'n=1' as the number of columns. Refer to the next 10442section on \verb'GxB_Matrix_select' for more details. 10443 10444\newpage 10445%------------------------------------------------------------------------------- 10446\subsubsection{{\sf GxB\_Matrix\_select:} apply a select operator to a matrix} 10447%------------------------------------------------------------------------------- 10448\label{select_matrix} 10449 10450\begin{mdframed}[userdefinedwidth=6in] 10451{\footnotesize 10452\begin{verbatim} 10453GrB_Info GxB_select // C<Mask> = accum (C, op(A,k)) or op(A',k) 10454( 10455 GrB_Matrix C, // input/output matrix for results 10456 const GrB_Matrix Mask, // optional mask for C, unused if NULL 10457 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 10458 const GxB_SelectOp op, // operator to apply to the entries 10459 const GrB_Matrix A, // first input: matrix A 10460 const GxB_Scalar Thunk, // optional input for the select operator 10461 const GrB_Descriptor desc // descriptor for C, mask, and A 10462) ; 10463\end{verbatim} } \end{mdframed} 10464 10465\verb'GxB_Matrix_select' applies a select operator to the entries of a matrix, 10466analogous to \verb'T = A .* op(A)' in MATLAB except the operator \verb'op' is 10467only applied to entries in the pattern of \verb'A'. Implicit values outside 10468the pattern of \verb'A' are not affected. The input matrix \verb'A' may be 10469transposed first. If the operator is not type-generic, the entries in \verb'A' 10470are typecasted into the \verb'xtype' of the select operator. The final step is 10471${\bf C \langle M \rangle = C \odot T}$, as described in 10472Section~\ref{accummask}. 10473 10474The matrix \verb'T' has the same size and type as \verb'A' (or the transpose of 10475\verb'A' if the input is transposed via the descriptor). The entries of 10476\verb'T' are a subset of those of \verb'A'. Each entry \verb'A(i,j)' of 10477\verb'A' is passed to the \verb'op', as $z=f(i,j,m,n,a_{ij},\mbox{thunk})$, 10478where \verb'A' is $m$-by-$n$. If \verb'A' is transposed first then the 10479operator is applied to entries in the transposed matrix, \verb"A'". If $z$ is 10480returned as true, then the entry is copied into \verb'T', unchanged. If it 10481returns false, the entry does not appear in \verb'T'. 10482 10483If \verb'Thunk' is not \verb'NULL', it must be a valid \verb'GxB_Scalar'. 10484If it has no entry, it is treated as if it had a single entry equal to zero, 10485for built-in types (not user-defined types). 10486 10487For user-defined select operators, the entry 10488is passed to the user-defined select operator, with no typecasting. 10489Its type must be identical to \verb'ttype' of the select operator. 10490 10491For the \verb'GxB_TRIL', \verb'GxB_TRIU', \verb'GxB_DIAG', and 10492\verb'GxB_OFFDIAG', the \verb'Thunk' parameter may be \verb'NULL', or it may be 10493present but contain no entry. In this case, these operators use the value of 10494\verb'k=0', the main diagonal. If present, the \verb'Thunk' can be any 10495built-in type. The value of this entry is typecasted: 10496\verb'k = (int64_t) Thunk'. The value \verb'k=0' specifies the main 10497diagonal of the matrix, \verb'k=1' is the +1 diagonal (the entries just above 10498the main diagonal), \verb'k=-1' is the -1 diagonal, and so on. 10499 10500For the \verb'GxB_*ZERO' select operators, \verb'Thunk' is ignored, and may be 10501\verb'NULL'. For built-in types, with the \verb'GxB_*THUNK' operators, the 10502value of \verb'Thunk' is typecasted to the same type as the \verb'A' matrix. 10503For user-defined types, \verb'Thunk' is passed to the select operator without 10504typecasting. 10505 10506The action of \verb'GxB_select' with the built-in select operators is described 10507in the table below. The MATLAB analogs are precise for \verb'tril' and 10508\verb'triu', but shorthand for the other operations. The MATLAB \verb'diag' 10509function returns a column with the diagonal, if \verb'A' is a matrix, whereas 10510the matrix \verb'T' in \verb'GxB_select' always has the same size as \verb'A' 10511(or its transpose if the \verb'GrB_INP0' is set to \verb'GrB_TRAN'). In the 10512MATLAB analog column, \verb'diag' is as if it operates like \verb'GxB_select', 10513where \verb'T' is a matrix. 10514 10515The following operators may be used on matrices with a user-defined type: 10516\verb'GxB_TRIL', 10517\verb'GxB_TRIU', 10518\verb'GxB_DIAG', 10519\verb'GxB_OFFIAG', 10520\verb'GxB_NONZERO', 10521\verb'GxB_EQ_ZERO', 10522\verb'GxB_NE_THUNK', 10523and 10524\verb'GxB_EQ_THUNK'. 10525 10526The comparators \verb'GxB_GT_*' \verb'GxB_GE_*' \verb'GxB_LT_*', and 10527\verb'GxB_LE_*' only work for built-in types. All other built-in select 10528operators can be used for any type, both built-in and any user-defined type. 10529 10530{\bf NOTE:} For floating-point values, comparisons with \verb'NaN' always return 10531false. The built-in select operators should not be used with a scalar 10532\verb'thunk' that is equal to \verb'NaN'. For this case, create a user-defined 10533select operator that performs the test with the ANSI C \verb'isnan' function 10534instead. 10535 10536\vspace{0.2in} 10537{\small 10538\begin{tabular}{llp{3in}} 10539\hline 10540GraphBLAS & MATLAB & \\ 10541name & analog & \\ 10542\hline 10543\verb'GxB_TRIL' & \verb'T=tril(A,k)' & 10544 Entries in \verb'T' are the entries on and below the \verb'k'th diagonal of \verb'A'. \\ 10545\verb'GxB_TRIU' & \verb'T=triu(A,k)' & 10546 Entries in \verb'T' are the entries on and above the \verb'k'th diagonal of \verb'A'. \\ 10547\verb'GxB_DIAG' & \verb'T=diag(A,k)' & 10548 Entries in \verb'T' are the entries on the \verb'k'th diagonal of \verb'A'. \\ 10549\verb'GxB_OFFDIAG' & \verb'T=A-diag(A,k)' & 10550 Entries in \verb'T' are all entries not on the \verb'k'th diagonal of \verb'A'. \\ 10551\hline 10552\verb'GxB_NONZERO' & \verb'T=A(A~=0)' & 10553 Entries in \verb'T' are all entries in \verb'A' that have nonzero value. \\ 10554\verb'GxB_EQ_ZERO' & \verb'T=A(A==0)' & 10555 Entries in \verb'T' are all entries in \verb'A' that are equal to zero. \\ 10556\verb'GxB_GT_ZERO' & \verb'T=A(A>0)' & 10557 Entries in \verb'T' are all entries in \verb'A' that are greater than zero. \\ 10558\verb'GxB_GE_ZERO' & \verb'T=A(A<=0)' & 10559 Entries in \verb'T' are all entries in \verb'A' that are greater than or equal to zero. \\ 10560\verb'GxB_LT_ZERO' & \verb'T=A(A<0)' & 10561 Entries in \verb'T' are all entries in \verb'A' that are less than zero. \\ 10562\verb'GxB_LE_ZERO' & \verb'T=A(A<=0)' & 10563 Entries in \verb'T' are all entries in \verb'A' that are less than or equal to zero. \\ 10564\hline 10565\verb'GxB_NE_THUNK' & \verb'T=A(A~=k)' & 10566 Entries in \verb'T' are all entries in \verb'A' that are not equal to \verb'k'. \\ 10567\verb'GxB_EQ_THUNK' & \verb'T=A(A==k)' & 10568 Entries in \verb'T' are all entries in \verb'A' that are equal to \verb'k'. \\ 10569\verb'GxB_GT_THUNK' & \verb'T=A(A>k)' & 10570 Entries in \verb'T' are all entries in \verb'A' that are greater than \verb'k'. \\ 10571\verb'GxB_GE_THUNK' & \verb'T=A(A>=k)' & 10572 Entries in \verb'T' are all entries in \verb'A' that are greater than or equal to \verb'k'. \\ 10573\verb'GxB_LT_THUNK' & \verb'T=A(A<k)' & 10574 Entries in \verb'T' are all entries in \verb'A' that are less than \verb'k'. \\ 10575\verb'GxB_LE_THUNK' & \verb'T=A(A<=k)' & 10576 Entries in \verb'T' are all entries in \verb'A' that are less than or equal to \verb'k'. \\ 10577\hline 10578\end{tabular} 10579} 10580\vspace{0.2in} 10581 10582\newpage 10583%=============================================================================== 10584\subsection{{\sf GrB\_reduce:} reduce to a vector or scalar} %================== 10585%=============================================================================== 10586\label{reduce} 10587 10588The generic function name \verb'GrB_reduce' may be used for all specific 10589functions discussed in this section. When the details of a specific function 10590are discussed, the specific name is used for clarity. 10591 10592%------------------------------------------------------------------------------- 10593\subsubsection{{\sf GrB\_Matrix\_reduce\_Monoid} reduce a matrix to a vector} 10594%------------------------------------------------------------------------------- 10595\label{reduce_to_vector} 10596 10597\begin{mdframed}[userdefinedwidth=6in] 10598{\footnotesize 10599\begin{verbatim} 10600GrB_Info GrB_reduce // w<mask> = accum (w,reduce(A)) 10601( 10602 GrB_Vector w, // input/output vector for results 10603 const GrB_Vector mask, // optional mask for w, unused if NULL 10604 const GrB_BinaryOp accum, // optional accum for z=accum(w,t) 10605 const GrB_Monoid monoid, // reduce monoid for t=reduce(A) 10606 const GrB_Matrix A, // first input: matrix A 10607 const GrB_Descriptor desc // descriptor for w, mask, and A 10608) ; 10609\end{verbatim} } \end{mdframed} 10610 10611\verb'GrB_Matrix_reduce_Monoid' 10612reduces a matrix to a column vector using a monoid, roughly analogous 10613to \verb"t = sum (A')" in MATLAB, in the default case, where \verb't' is a 10614column vector. By default, the method reduces across the rows to 10615obtain a column vector; use \verb'GrB_TRAN' to reduce down the columns. 10616 10617The input matrix \verb'A' may be transposed first. Its entries are then 10618typecast into the type of the \verb'reduce' operator or monoid. The reduction 10619is applied to all entries in \verb'A (i,:)' to produce the scalar \verb't (i)'. 10620This is done without the use of the identity value of the monoid. If the 10621\verb'i'th row \verb'A (i,:)' has no entries, then \verb'(i)' is not an entry 10622in \verb't' and its value is implicit. If \verb'A (i,:)' has a single entry, 10623then that is the result \verb't (i)' and \verb'reduce' is not applied at all 10624for the \verb'i'th row. Otherwise, multiple entries in row \verb'A (i,:)' are 10625reduced via the \verb'reduce' operator or monoid to obtain a single scalar, 10626the result \verb't (i)'. 10627 10628The final step is ${\bf w \langle m \rangle = w \odot t}$, as described 10629in Section~\ref{accummask}, except that all the 10630terms are column vectors instead of matrices. 10631 10632\verb'GrB_reduce' can also be passed a \verb'GrB_BinaryOp' in place of the 10633monoid parameter, but the binary operator must correspond to a known 10634built-in monoid. This provides a limited implementation of 10635\verb'GrB_Matrix_reduce_BinaryOp'. 10636 10637\newpage 10638%------------------------------------------------------------------------------- 10639\subsubsection{{\sf GrB\_Vector\_reduce\_$<$type$>$:} reduce a vector to a scalar} 10640%------------------------------------------------------------------------------- 10641\label{reduce_vector_to_scalar} 10642 10643\begin{mdframed}[userdefinedwidth=6in] 10644{\footnotesize 10645\begin{verbatim} 10646GrB_Info GrB_reduce // c = accum (c, reduce_to_scalar (u)) 10647( 10648 <type> *c, // result scalar 10649 const GrB_BinaryOp accum, // optional accum for c=accum(c,t) 10650 const GrB_Monoid monoid, // monoid to do the reduction 10651 const GrB_Vector u, // vector to reduce 10652 const GrB_Descriptor desc // descriptor (currently unused) 10653) ; 10654\end{verbatim} } \end{mdframed} 10655 10656\verb'GrB_Vector_reduce_<type>' 10657reduces a vector to a scalar, analogous to \verb't = sum (u)' in MATLAB, 10658except that in GraphBLAS any commutative and associative monoid can be used 10659in the reduction. 10660 10661If the vector \verb'u' has no entries, that identity value of the \verb'monoid' 10662is copied into the scalar \verb't'. Otherwise, all of the entries in the 10663vector are reduced to a single scalar using the \verb'monoid'. 10664 10665The scalar type is any of the built-in types, or a user-defined type. In the 10666function signature it is a C type: \verb'bool', \verb'int8_t', ... 10667\verb'float', \verb'double', or \verb'void *' for a user-defined type. 10668The user-defined type must be identical to the type of the vector \verb'u'. 10669This cannot be checked by GraphBLAS and thus results are undefined if the 10670types are not the same. 10671 10672The descriptor is unused, but it appears in case it is needed in future 10673versions of the GraphBLAS API. 10674This function has no mask so its accumulator/mask step differs from the other 10675GraphBLAS operations. It does not use the methods described in 10676Section~\ref{accummask}, but uses the following method instead. 10677 10678If \verb'accum' is \verb'NULL', then the scalar \verb't' is typecast into the 10679type of \verb'c', and \verb'c = t' is the final result. Otherwise, the scalar 10680\verb't' is typecast into the \verb'ytype' of the \verb'accum' operator, and 10681the value of \verb'c' (on input) is typecast into the \verb'xtype' of the 10682\verb'accum' operator. Next, the scalar \verb'z = accum (c,t)' is computed, of 10683the \verb'ztype' of the \verb'accum' operator. Finally, \verb'z' is typecast 10684into the final result, \verb'c'. 10685 10686Since this operation does not have a GraphBLAS input/output object, it 10687cannot return an error string for \verb'GrB_error'. 10688 10689\newpage 10690%------------------------------------------------------------------------------- 10691\subsubsection{{\sf GrB\_Matrix\_reduce\_$<$type$>$:} reduce a matrix to a scalar} 10692%------------------------------------------------------------------------------- 10693\label{reduce_matrix_to_scalar} 10694 10695\begin{mdframed}[userdefinedwidth=6in] 10696{\footnotesize 10697\begin{verbatim} 10698GrB_Info GrB_reduce // c = accum (c, reduce_to_scalar (A)) 10699( 10700 <type> *c, // result scalar 10701 const GrB_BinaryOp accum, // optional accum for c=accum(c,t) 10702 const GrB_Monoid monoid, // monoid to do the reduction 10703 const GrB_Matrix A, // matrix to reduce 10704 const GrB_Descriptor desc // descriptor (currently unused) 10705) ; 10706\end{verbatim} } \end{mdframed} 10707 10708\verb'GrB_Matrix_reduce_<type>' reduces a matrix \verb'A' to a scalar, roughly 10709analogous to \verb't = sum (A (:))' in MATLAB. This function is identical to 10710reducing a vector to a scalar, since the positions of the entries in a matrix 10711or vector have no effect on the result. Refer to the reduction to scalar 10712described in the previous Section~\ref{reduce_vector_to_scalar}. 10713 10714Since this operation does not have a GraphBLAS input/output object, it 10715cannot return an error string for \verb'GrB_error'. 10716 10717\newpage 10718%=============================================================================== 10719\subsection{{\sf GrB\_transpose:} transpose a matrix} %========================= 10720%=============================================================================== 10721\label{transpose} 10722 10723\begin{mdframed}[userdefinedwidth=6in] 10724{\footnotesize 10725\begin{verbatim} 10726GrB_Info GrB_transpose // C<Mask> = accum (C, A') 10727( 10728 GrB_Matrix C, // input/output matrix for results 10729 const GrB_Matrix Mask, // optional mask for C, unused if NULL 10730 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 10731 const GrB_Matrix A, // first input: matrix A 10732 const GrB_Descriptor desc // descriptor for C, Mask, and A 10733) ; 10734\end{verbatim} } \end{mdframed} 10735 10736\verb'GrB_transpose' 10737transposes a matrix \verb'A', just like the array transpose \verb"T = A.'" in 10738MATLAB. The internal result matrix \verb"T = A'" (or merely \verb"T = A" if 10739\verb'A' is transposed via the descriptor) has the same type as \verb'A'. The 10740final step is ${\bf C \langle M \rangle = C \odot T}$, as described in 10741Section~\ref{accummask}, which typecasts \verb'T' as needed and applies the 10742mask and accumulator. 10743 10744To be consistent with the rest of the GraphBLAS API regarding the 10745descriptor, the input matrix \verb'A' may be transposed first. It may seem 10746counter-intuitive, but this has the effect of not doing any transpose at all. 10747As a result, \verb'GrB_transpose' is useful for more than just transposing a 10748matrix. It can be used as a direct interface to the accumulator/mask 10749operation, ${\bf C \langle M \rangle = C \odot A}$. This step also does any 10750typecasting needed, so \verb'GrB_transpose' can be used to typecast a matrix 10751\verb'A' into another matrix \verb'C'. To do this, simply use \verb'NULL' for 10752the \verb'Mask' and \verb'accum', and provide a non-default descriptor 10753\verb'desc' that sets the transpose option: 10754 10755 {\footnotesize 10756 \begin{verbatim} 10757 // C = typecasted copy of A 10758 GrB_Descriptor_set (desc, GrB_INP0, GrB_TRAN) ; 10759 GrB_transpose (C, NULL, NULL, A, desc) ; \end{verbatim}} 10760 10761If the types of \verb'C' and \verb'A' match, 10762then the above two lines of code are the 10763same as \verb'GrB_Matrix_dup (&C, A)', except that for \verb'GrB_transpose' the 10764matrix \verb'C' must already exist and be the right size. If \verb'C' does not 10765exist, the work of \verb'GrB_Matrix_dup' can be replicated with this: 10766 10767 {\footnotesize 10768 \begin{verbatim} 10769 // C = create an exact copy of A, just like GrB_Matrix_dup 10770 GrB_Matrix C ; 10771 GrB_Type type ; 10772 GrB_Index nrows, ncols ; 10773 GrB_Descriptor desc ; 10774 GxB_Matrix_type (&type, A) ; 10775 GrB_Matrix_nrows (&nrows, A) ; 10776 GrB_Matrix_ncols (&ncols, A) ; 10777 GrB_Matrix_new (&C, type, nrows, ncols) ; 10778 GrB_Descriptor_new (&desc) ; 10779 GrB_Descriptor_set (desc, GrB_INP0, GrB_TRAN) ; 10780 GrB_transpose (C, NULL, NULL, A, desc) ; \end{verbatim}} 10781 10782Since the input matrix \verb'A' is transposed by the descriptor, 10783SuiteSparse:Graph\-BLAS does the right thing and does not transpose the matrix 10784at all. Since \verb'T = A' is not typecasted, SuiteSparse:GraphBLAS can 10785construct \verb'T' internally in $O(1)$ time and using no memory at all. This 10786makes \verb'Grb_transpose' a fast and direct interface to the accumulator/mask 10787function in GraphBLAS. 10788 10789This example is of course overkill, since the work can all be done by a 10790single call to the \verb'GrB_Matrix_dup' function. However, the 10791\verb'GrB_Matrix_dup' function can only create \verb'C' as an exact copy of 10792\verb'A', whereas variants of the code above can do many more things with these 10793two matrices. For example, the \verb'type' in the example can be replaced with 10794any other type, perhaps selected from another matrix or from an operator. 10795 10796Consider the following code excerpt, which uses \verb'GrB_transpose' to remove 10797all diagonal entries from a square matrix. It first creates a diagonal 10798\verb'Mask', which is complemented so that ${\bf C \langle \neg M \rangle =A}$ 10799does not modify the diagonal of ${\bf C}$. The \verb'REPLACE' ensures that 10800\verb'C' is cleared first, and then ${\bf C \langle \neg M \rangle = A}$ 10801modifies all entries in ${\bf C}$ where the mask ${\bf M}$ is false. These 10802correspond to all the off-diagonal entries. The descriptor ensures that ${\bf 10803A}$ is not transposed at all. The \verb'Mask' can have any pattern, of course, 10804and wherever it is set true, the corresponding entries in \verb'A' are 10805deleted from the copy \verb'C'. 10806 10807 {\footnotesize 10808 \begin{verbatim} 10809 // remove all diagonal entries from the matrix A 10810 // Mask = speye (n) ; 10811 GrB_Matrix_new (&Mask, GrB_BOOL, n, n) ; 10812 for (int64_t i = 0 ; i < n ; i++) 10813 { 10814 GrB_Matrix_setElement (Mask, (bool) true, i, i) ; 10815 } 10816 // C<~Mask> = A, clearing C first. No transpose. 10817 GrB_Descriptor_new (&desc) ; 10818 GrB_Descriptor_set (desc, GrB_INP0, GrB_TRAN) ; 10819 GrB_Descriptor_set (desc, GrB_MASK, GrB_COMP) ; 10820 GrB_Descriptor_set (desc, GrB_OUTP, GrB_REPLACE) ; 10821 GrB_transpose (A, Mask, NULL, A, desc) ; \end{verbatim}} 10822 10823\newpage 10824%=============================================================================== 10825\subsection{{\sf GrB\_kronecker:} Kronecker product} %========================== 10826%=============================================================================== 10827\label{kron} 10828 10829\begin{mdframed}[userdefinedwidth=6in] 10830{\footnotesize 10831\begin{verbatim} 10832GrB_Info GrB_kronecker // C<Mask> = accum (C, kron(A,B)) 10833( 10834 GrB_Matrix C, // input/output matrix for results 10835 const GrB_Matrix Mask, // optional mask for C, unused if NULL 10836 const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) 10837 const <operator> op, // defines '*' for T=kron(A,B) 10838 const GrB_Matrix A, // first input: matrix A 10839 const GrB_Matrix B, // second input: matrix B 10840 const GrB_Descriptor desc // descriptor for C, Mask, A, and B 10841) ; 10842\end{verbatim} } \end{mdframed} 10843 10844\verb'GrB_kronecker' computes the Kronecker product, 10845${\bf C \langle M \rangle = C \odot \mbox{kron}(A,B)}$ where 10846\[ 10847\mbox{kron}{\bf (A,B)} = 10848\left[ 10849 \begin{array}{ccc} 10850 a_{00} \otimes {\bf B} & \ldots & a_{0,n-1} \otimes {\bf B} \\ 10851 \vdots & \ddots & \vdots \\ 10852 a_{m-1,0} \otimes {\bf B} & \ldots & a_{m-1,n-1} \otimes {\bf B} \\ 10853 \end{array} 10854\right] 10855\] 10856The $\otimes$ operator is defined by the \verb'op' parameter. It is applied in 10857an element-wise fashion (like \verb'GrB_eWiseMult'), where the pattern of the 10858submatrix $a_{ij} \otimes {\bf B}$ is the same as the pattern of ${\bf B}$ if 10859$a_{ij}$ is an entry in the matrix ${\bf A}$, or empty otherwise. The input 10860matrices \verb'A' and \verb'B' can be of any dimension, and both matrices may 10861be transposed first via the descriptor, \verb'desc'. Entries in \verb'A' and 10862\verb'B' are typecast into the input types of the \verb'op'. The matrix 10863\verb'T=kron(A,B)' has the same type as the \verb'ztype' of the binary 10864operator, \verb'op'. The final step is ${\bf C \langle M \rangle = C \odot 10865T}$, as described in Section~\ref{accummask}. 10866 10867The operator \verb'op' may be a \verb'GrB_BinaryOp', a \verb'GrB_Monoid', or a 10868\verb'GrB_Semiring'. In the latter case, the multiplicative operator of 10869the semiring is used. 10870 10871\newpage 10872%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10873\section{Printing GraphBLAS objects} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10875\label{fprint} 10876 10877The ten different objects handled by SuiteSparse:GraphBLAS are all opaque, 10878although nearly all of their contents can be extracted via methods such as 10879\verb'GrB_Matrix_extractTuples', \verb'GrB_Matrix_extractElement', 10880\verb'GxB_Matrix_type', and so on. The GraphBLAS C API has no mechanism for 10881printing all the contents of GraphBLAS objects, but this is helpful for 10882debugging. Ten type-specific methods and two type-generic methods are 10883provided: 10884 10885\vspace{0.2in} 10886{\footnotesize 10887\begin{tabular}{ll} 10888\hline 10889\verb'GxB_Type_fprint' & print and check a \verb'GrB_Type' \\ 10890\verb'GxB_UnaryOp_fprint' & print and check a \verb'GrB_UnaryOp' \\ 10891\verb'GxB_BinaryOp_fprint' & print and check a \verb'GrB_BinaryOp' \\ 10892\verb'GxB_SelectOp_fprint' & print and check a \verb'GxB_SelectOp' \\ 10893\verb'GxB_Monoid_fprint' & print and check a \verb'GrB_Monoid' \\ 10894\verb'GxB_Semiring_fprint' & print and check a \verb'GrB_Semiring' \\ 10895\verb'GxB_Descriptor_fprint' & print and check a \verb'GrB_Descriptor' \\ 10896\verb'GxB_Matrix_fprint' & print and check a \verb'GrB_Matrix' \\ 10897\verb'GxB_Vector_fprint' & print and check a \verb'GrB_Vector' \\ 10898\verb'GxB_Scalar_fprint' & print and check a \verb'GxB_Scalar' \\ 10899\hline 10900\verb'GxB_fprint' & print/check any object to a file \\ 10901\verb'GxB_print' & print/check any object to \verb'stdout' \\ 10902\hline 10903\end{tabular} 10904} 10905\vspace{0.2in} 10906 10907These methods do not modify the status of any object, and thus they 10908cannot return an error string for use by \verb'GrB_error'. 10909 10910If a matrix or vector 10911has not been completed, the pending computations are guaranteed to {\em not} be 10912performed. The reason is simple. It is possible for a bug in the user 10913application (such as accessing memory outside the bounds of an array) to mangle 10914the internal content of a GraphBLAS object, and the \verb'GxB_*print' methods 10915can be helpful tools to track down this bug. If \verb'GxB_*print' attempted to 10916complete any computations prior to printing or checking the contents of the 10917matrix or vector, then further errors could occur, including a segfault. 10918 10919By contrast, GraphBLAS methods and operations that return values into 10920user-provided arrays or variables might finish pending operations before the 10921return these values, and this would change their state. Since they do not 10922change the state of any object, the \verb'GxB_*print' methods provide a useful 10923alternative for debugging, and for a quick understanding of what GraphBLAS is 10924computing while developing a user application. 10925 10926Each of the methods has a parameter of type \verb'GxB_Print_Level' that 10927specifies the amount to print: 10928 10929{\footnotesize 10930\begin{verbatim} 10931typedef enum 10932{ 10933 GxB_SILENT = 0, // nothing is printed, just check the object 10934 GxB_SUMMARY = 1, // print a terse summary 10935 GxB_SHORT = 2, // short description, about 30 entries of a matrix 10936 GxB_COMPLETE = 3, // print the entire contents of the object 10937 GxB_SHORT_VERBOSE = 4, // GxB_SHORT but with "%.15g" for doubles 10938 GxB_COMPLETE_VERBOSE = 5 // GxB_COMPLETE but with "%.15g" for doubles 10939} 10940GxB_Print_Level ; \end{verbatim}} 10941 10942The ten type-specific functions include an additional argument, the 10943\verb'name' string. The \verb'name' is printed at the beginning of the display 10944(assuming the print level is not \verb'GxB_SILENT') so that the object can be 10945more easily identified in the output. For the type-generic methods 10946\verb'GxB_fprint' and \verb'GxB_print', the \verb'name' string is the variable 10947name of the object itself. 10948 10949If the file \verb'f' is \verb'NULL', nothing is printed (\verb'pr' is 10950effectively \verb'GxB_SILENT'). If \verb'name' is \verb'NULL', it is treated 10951as the empty string. These are not error conditions. 10952 10953The methods check their input objects carefully and extensively, even when 10954\verb'pr' is equal to \verb'GxB_SILENT'. The following error codes can be 10955returned: 10956 10957\begin{packed_itemize} 10958\item \verb'GrB_SUCCESS': object is valid 10959\item \verb'GrB_UNINITIALIZED_OBJECT': object is not initialized 10960\item \verb'GrB_INVALID_OBJECT': object is not valid 10961\item \verb'GrB_NULL_POINTER': object is a NULL pointer 10962\item \verb'GrB_INVALID_VALUE': \verb'fprintf' returned an I/O error. 10963\end{packed_itemize} 10964 10965The content of any GraphBLAS object is opaque, and subject to change. As a 10966result, the exact content and format of what is printed is 10967implementation-dependent, and will change from version to version of 10968SuiteSparse:GraphBLAS. Do not attempt to rely on the exact content or format 10969by trying to parse the resulting output via another program. The intent of 10970these functions is to produce a report of an object for visual inspection. If 10971the user application needs to extract content from a GraphBLAS matrix or 10972vector, use \verb'GrB_*_extractTuples' or the import/export methods instead. 10973 10974\newpage 10975%=============================================================================== 10976\subsection{{\sf GxB\_fprint:} Print a GraphBLAS object to a file} %============ 10977%=============================================================================== 10978 10979\begin{mdframed}[userdefinedwidth=6in] 10980{\footnotesize 10981\begin{verbatim} 10982GrB_Info GxB_fprint // print and check a GraphBLAS object 10983( 10984 GrB_<objecttype> object, // object to print and check 10985 GxB_Print_Level pr, // print level 10986 FILE *f // file for output 10987) ; 10988\end{verbatim} } \end{mdframed} 10989 10990The \verb'GxB_fprint' function prints the contents of any of the ten GraphBLAS 10991objects to the file \verb'f'. If \verb'f' is \verb'NULL', the results are 10992printed to \verb'stdout'. For example, to print the entire contents of a 10993matrix \verb'A' to the file \verb'f', use 10994\verb'GxB_fprint (A, GxB_COMPLETE, f)'. 10995 10996%=============================================================================== 10997\subsection{{\sf GxB\_print:} Print a GraphBLAS object to {\sf stdout}} %======= 10998%=============================================================================== 10999\label{gxb_print} 11000 11001\begin{mdframed}[userdefinedwidth=6in] 11002{\footnotesize 11003\begin{verbatim} 11004GrB_Info GxB_print // print and check a GrB_Vector 11005( 11006 GrB_<objecttype> object, // object to print and check 11007 GxB_Print_Level pr // print level 11008) ; 11009\end{verbatim} } \end{mdframed} 11010 11011\verb'GxB_print' is the same as \verb'GxB_fprint', except that it prints the 11012contents of the object to \verb'stdout' instead of a file \verb'f'. For 11013example, to print the entire contents of a matrix \verb'A', use 11014\verb'GxB_print (A, GxB_COMPLETE)'. 11015 11016%=============================================================================== 11017\subsection{{\sf GxB\_Type\_fprint:} Print a {\sf GrB\_Type}} 11018%=============================================================================== 11019 11020\begin{mdframed}[userdefinedwidth=6in] 11021{\footnotesize 11022\begin{verbatim} 11023GrB_Info GxB_Type_fprint // print and check a GrB_Type 11024( 11025 GrB_Type type, // object to print and check 11026 const char *name, // name of the object 11027 GxB_Print_Level pr, // print level 11028 FILE *f // file for output 11029) ; 11030\end{verbatim} } \end{mdframed} 11031 11032For example, \verb'GxB_Type_fprint (GrB_BOOL, "boolean type", GxB_COMPLETE, f)' 11033prints the contents of the \verb'GrB_BOOL' object to the file \verb'f'. 11034 11035\newpage 11036%=============================================================================== 11037\subsection{{\sf GxB\_UnaryOp\_fprint:} Print a {\sf GrB\_UnaryOp}} 11038%=============================================================================== 11039 11040\begin{mdframed}[userdefinedwidth=6in] 11041{\footnotesize 11042\begin{verbatim} 11043GrB_Info GxB_UnaryOp_fprint // print and check a GrB_UnaryOp 11044( 11045 GrB_UnaryOp unaryop, // object to print and check 11046 const char *name, // name of the object 11047 GxB_Print_Level pr, // print level 11048 FILE *f // file for output 11049) ; 11050\end{verbatim} } \end{mdframed} 11051 11052For example, 11053\verb'GxB_UnaryOp_fprint (GrB_LNOT, "not", GxB_COMPLETE, f)' 11054prints the \verb'GrB_LNOT' unary operator to the file \verb'f'. 11055 11056 11057%=============================================================================== 11058\subsection{{\sf GxB\_BinaryOp\_fprint:} Print a {\sf GrB\_BinaryOp}} 11059%=============================================================================== 11060 11061\begin{mdframed}[userdefinedwidth=6in] 11062{\footnotesize 11063\begin{verbatim} 11064GrB_Info GxB_BinaryOp_fprint // print and check a GrB_BinaryOp 11065( 11066 GrB_BinaryOp binaryop, // object to print and check 11067 const char *name, // name of the object 11068 GxB_Print_Level pr, // print level 11069 FILE *f // file for output 11070) ; 11071\end{verbatim} } \end{mdframed} 11072 11073For example, 11074\verb'GxB_BinaryOp_fprint (GrB_PLUS_FP64, "plus", GxB_COMPLETE, f)' prints the 11075\verb'GrB_PLUS_FP64' binary operator to the file \verb'f'. 11076 11077 11078%=============================================================================== 11079\subsection{{\sf GxB\_SelectOp\_fprint:} Print a {\sf GxB\_SelectOp}} 11080%=============================================================================== 11081 11082\begin{mdframed}[userdefinedwidth=6in] 11083{\footnotesize 11084\begin{verbatim} 11085GrB_Info GxB_SelectOp_fprint // print and check a GxB_SelectOp 11086( 11087 GxB_SelectOp selectop, // object to print and check 11088 const char *name, // name of the object 11089 GxB_Print_Level pr, // print level 11090 FILE *f // file for output 11091) ; 11092\end{verbatim} } \end{mdframed} 11093 11094For example, 11095\verb'GxB_SelectOp_fprint (GxB_TRIL, "tril", GxB_COMPLETE, f)' prints the 11096\verb'GxB_TRIL' select operator to the file \verb'f'. 11097 11098\newpage 11099%=============================================================================== 11100\subsection{{\sf GxB\_Monoid\_fprint:} Print a {\sf GrB\_Monoid}} 11101%=============================================================================== 11102 11103\begin{mdframed}[userdefinedwidth=6in] 11104{\footnotesize 11105\begin{verbatim} 11106GrB_Info GxB_Monoid_fprint // print and check a GrB_Monoid 11107( 11108 GrB_Monoid monoid, // object to print and check 11109 const char *name, // name of the object 11110 GxB_Print_Level pr, // print level 11111 FILE *f // file for output 11112) ; 11113\end{verbatim} } \end{mdframed} 11114 11115For example, 11116\verb'GxB_Monoid_fprint (GxB_PLUS_FP64_MONOID, "plus monoid",' 11117\verb'GxB_COMPLETE, f)' 11118prints the predefined \verb'GxB_PLUS_FP64_MONOID' (based on the binary 11119operator \verb'GrB_PLUS_FP64') to the file \verb'f'. 11120 11121%=============================================================================== 11122\subsection{{\sf GxB\_Semiring\_fprint:} Print a {\sf GrB\_Semiring}} 11123%=============================================================================== 11124 11125\begin{mdframed}[userdefinedwidth=6in] 11126{\footnotesize 11127\begin{verbatim} 11128GrB_Info GxB_Semiring_fprint // print and check a GrB_Semiring 11129( 11130 GrB_Semiring semiring, // object to print and check 11131 const char *name, // name of the object 11132 GxB_Print_Level pr, // print level 11133 FILE *f // file for output 11134) ; 11135\end{verbatim} } \end{mdframed} 11136 11137For example, 11138\verb'GxB_Semiring_fprint (GxB_PLUS_TIMES_FP64, "standard",' 11139\verb'GxB_COMPLETE, f)' 11140prints the predefined \verb'GxB_PLUS_TIMES_FP64' semiring to the file \verb'f'. 11141 11142%=============================================================================== 11143\subsection{{\sf GxB\_Descriptor\_fprint:} Print a {\sf GrB\_Descriptor}} 11144%=============================================================================== 11145 11146\begin{mdframed}[userdefinedwidth=6in] 11147{\footnotesize 11148\begin{verbatim} 11149GrB_Info GxB_Descriptor_fprint // print and check a GrB_Descriptor 11150( 11151 GrB_Descriptor descriptor, // object to print and check 11152 const char *name, // name of the object 11153 GxB_Print_Level pr, // print level 11154 FILE *f // file for output 11155) ; 11156\end{verbatim} } \end{mdframed} 11157 11158For example, 11159\verb'GxB_Descriptor_fprint (d, "descriptor", GxB_COMPLETE, f)' 11160prints the descriptor \verb'd' to the file \verb'f'. 11161 11162\newpage 11163%=============================================================================== 11164\subsection{{\sf GxB\_Matrix\_fprint:} Print a {\sf GrB\_Matrix}} 11165%=============================================================================== 11166 11167\begin{mdframed}[userdefinedwidth=6in] 11168{\footnotesize 11169\begin{verbatim} 11170GrB_Info GxB_Matrix_fprint // print and check a GrB_Matrix 11171( 11172 GrB_Matrix A, // object to print and check 11173 const char *name, // name of the object 11174 GxB_Print_Level pr, // print level 11175 FILE *f // file for output 11176) ; 11177\end{verbatim} } \end{mdframed} 11178 11179For example, \verb'GxB_Matrix_fprint (A, "my matrix", GxB_SHORT, f)' 11180prints about 30 entries from the matrix \verb'A' to the file \verb'f'. 11181 11182 11183%=============================================================================== 11184\subsection{{\sf GxB\_Vector\_fprint:} Print a {\sf GrB\_Vector}} 11185%=============================================================================== 11186 11187\begin{mdframed}[userdefinedwidth=6in] 11188{\footnotesize 11189\begin{verbatim} 11190GrB_Info GxB_Vector_fprint // print and check a GrB_Vector 11191( 11192 GrB_Vector v, // object to print and check 11193 const char *name, // name of the object 11194 GxB_Print_Level pr, // print level 11195 FILE *f // file for output 11196) ; 11197\end{verbatim} } \end{mdframed} 11198 11199For example, \verb'GxB_Vector_fprint (v, "my vector", GxB_SHORT, f)' 11200prints about 30 entries from the vector \verb'v' to the file \verb'f'. 11201 11202%=============================================================================== 11203\subsection{{\sf GxB\_Scalar\_fprint:} Print a {\sf GxB\_Scalar}} 11204%=============================================================================== 11205 11206\begin{mdframed}[userdefinedwidth=6in] 11207{\footnotesize 11208\begin{verbatim} 11209GrB_Info GxB_Scalar_fprint // print and check a GrB_Scalar 11210( 11211 GxB_Sclarr s, // object to print and check 11212 const char *name, // name of the object 11213 GxB_Print_Level pr, // print level 11214 FILE *f // file for output 11215) ; 11216\end{verbatim} } \end{mdframed} 11217 11218For example, \verb'GxB_Scalar_fprint (s, "my scalar", GxB_SHORT, f)' 11219prints a short description of the scalar \verb's' to the file \verb'f'. 11220 11221\newpage 11222%=============================================================================== 11223\subsection{Performance and portability considerations} 11224%=============================================================================== 11225 11226Even when the print level is \verb'GxB_SILENT', these methods extensively check 11227the contents of the objects passed to them, which can take some time. They 11228should be considered debugging tools only, not for final use in production. 11229 11230The return value of the \verb'GxB_*print' methods can be relied upon, but the 11231output to the file (or \verb'stdout') can change from version to version. If 11232these methods are eventually added to the GraphBLAS C API Specification, a 11233conforming implementation might never print anything at all, regardless of the 11234\verb'pr' value. This may be essential if the GraphBLAS library is installed 11235in a dedicated device, with no file output, for example. 11236 11237Some implementations may wish to print nothing at all if the matrix is not yet 11238completed, or just an indication that the matrix has pending operations and 11239cannot be printed, when non-blocking mode is employed. In this case, use 11240\verb'GrB_Matrix_wait', \verb'GrB_Vector_wait', or \verb'GxB_Scalar_wait' to 11241finish all pending computations first. If a matrix or vector has pending 11242operations, SuiteSparse:GraphBLAS prints a list of the {\em pending tuples}, 11243which are the entries not yet inserted into the primary data structure. It can 11244also print out entries that remain in the data structure but are awaiting 11245deletion; these are called {\em zombies} in the output report. 11246 11247Most of the rest of the report is self-explanatory. 11248 11249\newpage 11250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11251\section{Examples} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11253\label{examples} 11254 11255\begin{alert} 11256{\bf NOTE:} The programs in the \verb'Demo' folder are not always the fastest 11257methods. They are simple methods for illustration only, not performance. Do 11258not benchmark them. Refer to the latest (draft) \verb'LAGraph' package for the 11259fastest methods. Be sure to use the right combination of package versions 11260between LAGraph and SuiteSparse:GraphBLAS. Contact the author (davis@tamu.edu) 11261if you have any questions about how to properly benchmark LAGraph + 11262SuiteSparse:GraphBLAS. 11263\end{alert} 11264 11265Several examples of how to use GraphBLAS are listed below. They all 11266appear in the \verb'Demo' folder of SuiteSparse:GraphBLAS. 11267 11268\begin{enumerate} 11269\item performing a breadth-first search, 11270\item finding a maximal independent set, 11271\item creating a random matrix, 11272\item creating a finite-element matrix, 11273\item reading a matrix from a file, and 11274\item complex numbers as a user-defined type. 11275\item triangle counting 11276\item PageRank 11277\item matrix import/export 11278\end{enumerate} 11279 11280Additional examples appear in the newly created LAGraph project, currently in 11281progress. 11282 11283%------------------------------------------------------------------------------- 11284\subsection{LAGraph} 11285%------------------------------------------------------------------------------- 11286\label{lagraph} 11287 11288The LAGraph project is a community-wide effort to create graph algorithms based 11289on GraphBLAS (any implementation of the API, not just SuiteSparse: GraphBLAS). 11290Some of the algorithms and utilities in LAGraph are listed in the table below. 11291Many additional algorithms are planned. Refer to 11292\url{https://github.com/GraphBLAS/LAGraph} for a current list of algorithms 11293(the one below will soon be out of date). Most of the functions in the 11294\verb'Demo/' folder in SuiteSparse:GraphBLAS will eventually be translated into 11295algorithms or utilities for LAGraph. 11296 11297To use LAGraph with SuiteSparse:GraphBLAS, place the two folders \verb'LAGraph' 11298and \verb'GraphBLAS' in the same parent directory. This allows the 11299\verb'cmake' script in LAGraph to find the copy of GraphBLAS. Alternatively, 11300the GraphBLAS source could be placed anywhere, as long as 11301\verb'sudo make install' is performed. 11302 11303Build \verb'GraphBLAS' first, then the \verb'LAGraph' library, and then the 11304tests in \verb'LAGraph/Test'. 11305 11306Many of these algorithms are described in \cite{Davis20}. 11307 11308\vspace{0.1in} 11309{\small 11310\begin{tabular}{ll} 11311\hline 11312\hline 11313Algorithms & description \\ 11314\hline 11315\hline 11316\verb'LAGraph_bfs_parent2' & a direction-optimized BFS 11317 \cite{Beamer:2012:DOB,Yang:2018:IPE}, \\ 11318 & typically 2x faster than \verb'bfs5m' \\ 11319\verb'LAGraph_bfs_simple' & a simple BFS (about the same as \verb'bfs5m') \\ 11320\verb'LAGraph_bc_batch' & batched betweenness-centrality \\ 11321\verb'LAGraph_bc' & betweenness-centrality \\ 11322\verb'LAGraph_cdlp' & community detection via label propagation \\ 11323\verb'LAGraph_cc' & connected components \\ 11324\verb'LAGraph_BF_*' & three variants of Bellman-Ford \\ 11325\verb'LAGraph_allktruss' & construct all $k$-trusses \\ 11326\verb'LAGraph_dnn' & sparse deep neural network \cite{DavisAznavehKolodziej19} \\ 11327\verb'LAGraph_ktruss' & construct a $k$-trusses \\ 11328\verb'LAGraph_lcc' & local clustering coefficient \\ 11329\verb'LAGraph_pagerank' & PageRank \\ 11330\verb'LAGraph_pagerank2' & PageRank variant \\ 11331\verb'LAGraph_tricount' & triangle counting \\ 11332\end{tabular}} 11333 11334\vspace{0.1in} 11335{\small 11336\begin{tabular}{ll} 11337\hline 11338\hline 11339Utilities & description \\ 11340\hline 11341\hline 11342\verb'LAGraph_Vector_isall' & tests 2 vectors with a binary operator \\ 11343\verb'LAGraph_Vector_isequal' & tests if 2 vectors are equal \\ 11344\verb'LAGraph_Vector_to_dense' & converts a vector to dense \\ 11345\verb'LAGraph_alloc_global' & types, operators, monoids, and semirings \\ 11346\verb'LAGraph_finalize' & ends LAGraph \\ 11347\verb'LAGraph_free' & wrapper for \verb'free' \\ 11348\verb'LAGraph_free_global' & frees objects created by \verb'_alloc_global'\\ 11349\verb'LAGraph_get_nthreads' & get \# of threads used \\ 11350\verb'LAGraph_grread' & read a binary matrix in Galois format \\ 11351\verb'LAGraph_init' & starts LAGraph \\ 11352\verb'LAGraph_isall' & tests 2 matrices with a binary operator \\ 11353\verb'LAGraph_isequal' & tests if 2 matrices are equal \\ 11354\verb'LAGraph_ispattern' & tests if all entries in a matrix are 1 \\ 11355\verb'LAGraph_malloc' & wrapper for \verb'malloc' \\ 11356\verb'LAGraph_mmread' & read a Matrix Market file \\ 11357\verb'LAGraph_mmwrite' & write a Matrix Market file \\ 11358\verb'LAGraph_pattern' & extracts the pattern of a matrix \\ 11359\verb'LAGraph_prune_diag' & diagonal entries from a matrix \\ 11360\verb'LAGraph_rand' & simple random number generator \\ 11361\verb'LAGraph_rand64' & \verb'int64_t' random number generator \\ 11362\verb'LAGraph_random' & random matrix generator \\ 11363\verb'LAGraph_randx' & \verb'double' random number generator \\ 11364\verb'LAGraph_set_nthreads' & set \# of threads to use \\ 11365\verb'LAGraph_tic' & start a timer \\ 11366\verb'LAGraph_toc' & end a timer \\ 11367\verb'LAGraph_tsvread' & read a TSV file \\ 11368\verb'LAGraph_xinit' & starts LAGraph, with different malloc \\ 11369\verb'LAgraph_1_to_n' & construct the vector \verb'1:n' \\ 11370\verb'GB_*sort*' & sorting for \verb'LAGraph_cdlp' \\ 11371% \verb'LAGraph_internal.h' 11372\end{tabular}} 11373 11374 11375\newpage 11376%------------------------------------------------------------------------------- 11377\subsection{Breadth-first search} 11378%------------------------------------------------------------------------------- 11379\label{bfs} 11380 11381The \verb'bfs' examples in the \verb'Demo' folder provide several examples of 11382how to compute a breadth-first search (BFS) in GraphBLAS. Additional BFS 11383examples are in LAGraph, shown below. The \verb'LAGraph_bfs_simple' function 11384starts at a given source node \verb's' of an undirected graph with \verb'n' 11385nodes. The graph is represented as an \verb'n'-by-\verb'n' matrix, \verb'A', 11386where \verb'A(i,j)' is the edge $(i,j)$. The matrix \verb'A' can have any type 11387(even a user-defined type), since the \verb'PAIR' operator does not access its 11388values. No typecasting will be done. 11389 11390The vector \verb'v' of size \verb'n' holds the level of each node in the BFS, 11391where \verb'v(i)=0' if the node has not yet been seen. This particular value 11392makes \verb'v' useful for another role. It can be used as a Boolean mask, 11393since \verb'0' is \verb'false' and nonzero is \verb'true'. Initially the 11394entire \verb'v' vector is zero. It is initialized as a dense vector, with all 11395entries present, to improve performance (otherwise, it will slowly grow, 11396incrementally, and this will take a lot of time if the number of BFS levels is 11397high). 11398 11399The vector \verb'q' is the set of nodes just discovered at the current level, 11400where \verb'q(i)=true' if node \verb'i' is in the current level. It starts out 11401with just a single entry set to true, \verb'q(s)', the starting node. 11402 11403Each iteration of the BFS consists of three calls to GraphBLAS. The first one 11404uses \verb'q' as a mask. It modifies all positions in \verb'v' where \verb'q' 11405has an entry, setting them all to the current \verb'level'. 11406 11407 {\footnotesize 11408 \begin{verbatim} 11409 // v<q> = level, using vector assign with q as the mask 11410 GrB_assign (v, q, NULL, level, GrB_ALL, n, GrB_DESC_S) ; \end{verbatim}} 11411 11412The next call to GraphBLAS is the heart of the algorithm: 11413 11414 {\footnotesize 11415 \begin{verbatim} 11416 // q<!v> = q ||.&& A ; finds all the unvisited 11417 // successors from current q, using !v as the mask 11418 GrB_vxm (q, v, NULL, GxB_ANY_PAIR_BOOL, q, A, GrB_DESC_RC) ; \end{verbatim}} 11419 11420The vector \verb'q' is all the set of nodes at the current level. Suppose 11421\verb'q(j)' is true, and it has a neighbor \verb'i'. Then \verb'A(i,j)=1', and 11422the dot product of \verb'A(i,:)*q' using the \verb'ANY_PAIR' semiring will use 11423the \verb'PAIR' multiplier on these two terms, \verb'f (A(i,j), q(j))', resulting 11424in a value \verb'1'. The \verb'ANY' monoid will ``sum'' up all the results 11425in this single row \verb'i'; note that the \verb'OR' monoid would compute the 11426same thing. If the result is a column vector \verb't=A*q', 11427then this \verb't(i)' will be true. The vector \verb't' will be true for 11428any node adjacent to any node in the set \verb'q'. 11429 11430Some of these neighbors of the nodes in \verb'q' have already been visited by 11431the BFS, either in the current level or in a prior level. These results must 11432be discarded; what is desired is the set of all nodes \verb'i' for which 11433\verb't(i)' is true, and yet \verb'v(i)' is still zero. 11434 11435Enter the mask. The vector \verb'v' is complemented for use a mask, via the 11436\verb'desc' descriptor. This means that wherever the vector is true, that 11437position in the result is protected and will not be modified by the assignment. 11438Only where \verb'v' is false will the result be modified. This is exactly the 11439desired result, since these represent newly seen nodes for the next level of 11440the BFS. A node \verb'k' already visited will have a nonzero \verb'v(k)', and 11441thus \verb'q(k)' will not be modified by the assignment. 11442 11443The result \verb't' is written back into the vector \verb'q', through the mask, 11444but to do this correctly, another descriptor parameter is used: 11445\verb'GrB_REPLACE'. The vector \verb'q' was used to compute \verb't=A*q', and 11446after using it to compute \verb't', the entire \verb'q' vector needs to be 11447cleared. Only new nodes are desired, for the next level. This is exactly what 11448the \verb'REPLACE' option does. 11449 11450As a result, the vector \verb'q' now contains the set of nodes at the new 11451level of the BFS. It contains all those nodes (and only those nodes) 11452that are neighbors of the prior set and that have not already been seen in 11453any prior level. 11454 11455A single call to \verb'GrB_Vector_nvals' finds how many entries are in the 11456current level. If this is zero, the BFS can terminate. 11457 11458\newpage 11459\begin{mdframed}[userdefinedwidth=6in] 11460{\footnotesize 11461\begin{verbatim} 11462#include "LAGraph_internal.h" 11463#define LAGRAPH_FREE_ALL { GrB_free (&v) ; GrB_free (&q) ; } 11464 11465GrB_Info LAGraph_bfs_simple // push-only BFS 11466( 11467 GrB_Vector *v_output, // v(i) is the BFS level of node i in the graph 11468 GrB_Matrix A, // input graph, treated as if boolean in semiring 11469 GrB_Index source // starting node of the BFS 11470) 11471{ 11472 GrB_Info info ; 11473 GrB_Vector q = NULL ; // nodes visited at each level 11474 GrB_Vector v = NULL ; // result vector 11475 if (v_output == NULL) LAGRAPH_ERROR ("argument missing", GrB_NULL_POINTER) ; 11476 GrB_Index n, nvals ; 11477 GrB_Matrix_nrows (&n, A) ; 11478 // create an empty vector v, and make it dense 11479 GrB_Vector_new (&v, (n > INT32_MAX) ? GrB_INT64 : GrB_INT32, n) ; 11480 GrB_assign (v, NULL, NULL, 0, GrB_ALL, n, NULL) ; 11481 // create a boolean vector q, and set q(source) to true 11482 GrB_Vector_new (&q, GrB_BOOL, n) ; 11483 GrB_Vector_setElement (q, true, source) ; 11484 // BFS traversal and label the nodes 11485 for (int64_t level = 1 ; level <= n ; level++) 11486 { 11487 // v<q> = level 11488 GrB_assign (v, q, NULL, level, GrB_ALL, n, GrB_DESC_S) ; 11489 // break if q is empty 11490 GrB_Vector_nvals (&nvals, q) ; 11491 if (nvals == 0) break ; 11492 // q'<!v> = q'*A 11493 GrB_vxm (q, v, NULL, GxB_ANY_PAIR_BOOL, q, A, GrB_DESC_RC) ; 11494 } 11495 // free workspace and return result 11496 (*v_output) = v ; // return result 11497 v = NULL ; // set to NULL so LAGRAPH_FREE_ALL doesn't free it 11498 LAGRAPH_FREE_ALL ; // free all workspace (except for result v) 11499 return (GrB_SUCCESS) ; 11500} 11501\end{verbatim}} 11502\end{mdframed} 11503 11504\newpage 11505%------------------------------------------------------------------------------- 11506\subsection{Maximal independent set} 11507%------------------------------------------------------------------------------- 11508\label{mis} 11509 11510The {\em maximal independent set} problem is to find a set of nodes $S$ such 11511that no two nodes in $S$ are adjacent to each other (an independent set), and 11512all nodes not in $S$ are adjacent to at least one node in $S$ (and thus $S$ is 11513maximal since it cannot be augmented by any node while remaining an independent 11514set). The \verb'mis' function in the \verb'Demo' folder solves this problem 11515using Luby's method \cite{Luby86}. The key operations in the method are 11516replicated on the next page. 11517 11518The gist of the algorithm is this. In each phase, all candidate nodes are 11519given a random score. If a node has a score higher than all its neighbors, 11520then it is added to the independent set. All new nodes added to the set cause 11521their neighbors to be removed from the set of candidates. The process must be 11522repeated for multiple phases until no new nodes can be added. This is because 11523in one phase, a node \verb'i' might not be added because one of its neighbors 11524\verb'j' has a higher score, yet that neighbor \verb'j' might not be added 11525because one of its neighbors \verb'k' is added to the independent set instead. 11526The node \verb'j' is no longer a candidate and can never be added to the 11527independent set, but node \verb'i' could be added to $S$ in a subsequent phase. 11528 11529The initialization step, before the \verb'while' loop, computes the degree of 11530each node with a \verb'PLUS' reduction. The set of \verb'candidates' is 11531Boolean vector, the \verb'i'th component is true if node \verb'i' is a 11532candidate. A node with no neighbors causes the algorithm to stall, so these 11533nodes are not candidates. Instead, they are immediately added to the 11534independent set, represented by another Boolean vector \verb'iset'. Both steps 11535are done with an \verb'assign', using the \verb'degree' as a mask, except the 11536assignment to \verb'iset' uses the complement of the mask, via the 11537\verb'sr_desc' descriptor. Finally, the \verb'GrB_Vector_nvals' statement 11538counts how many candidates remain. 11539 11540Each phase of Luby's algorithm consists of 11 calls to GraphBLAS operations, 11541all of which are either parallel, or take $O(1)$ time. 11542Not all of them are described here since they are commented in the code itself. 11543The two matrix-vector multiplications are the important parts and also take the 11544most time. They also make interesting use of semirings and masks. The first 11545one computes the largest score of all the neighbors of each node in the 11546candidate set: 11547 11548 {\footnotesize 11549 \begin{verbatim} 11550 // compute the max probability of all neighbors 11551 GrB_vxm (neighbor_max, candidates, NULL, maxFirst, prob, A, r_desc) ; \end{verbatim}} 11552 11553\newpage 11554\begin{mdframed}[userdefinedwidth=6in] 11555{\footnotesize 11556\begin{verbatim} 11557 // compute the degree of each node 11558 GrB_reduce (degrees, NULL, NULL, GrB_PLUS_FP64, A, NULL) ; 11559 11560 // singletons are not candidates; they are added to iset first instead 11561 // candidates[degree != 0] = 1 11562 GrB_assign (candidates, degrees, NULL, true, GrB_ALL, n, NULL); 11563 11564 // add all singletons to iset 11565 // iset[degree == 0] = 1 11566 GrB_assign (iset, degrees, NULL, true, GrB_ALL, n, sr_desc) ; 11567 11568 // Iterate while there are candidates to check. 11569 GrB_Index nvals ; 11570 GrB_Vector_nvals (&nvals, candidates) ; 11571 11572 while (nvals > 0) 11573 { 11574 // sparsify the random number seeds (just keep it for each candidate) 11575 GrB_assign (Seed, candidates, NULL, Seed, GrB_ALL, n, r_desc) ; 11576 // compute a random probability scaled by inverse of degree 11577 prand_xget (X, Seed) ; // two calls to GrB_apply 11578 GrB_eWiseMult (prob, candidates, NULL, set_random, degrees, X, r_desc) ; 11579 // compute the max probability of all neighbors 11580 GrB_vxm (neighbor_max, candidates, NULL, maxFirst, prob, A, r_desc) ; 11581 // select node if its probability is > than all its active neighbors 11582 GrB_eWiseAdd (new_members, NULL,NULL, GrB_GT_FP64, prob, neighbor_max,0); 11583 // add new members to independent set. 11584 GrB_eWiseAdd (iset, NULL, NULL, GrB_LOR, iset, new_members, NULL) ; 11585 // remove new members from set of candidates c = c & !new 11586 GrB_apply (candidates, new_members, NULL, GrB_IDENTITY_BOOL, 11587 candidates, sr_desc) ; 11588 GrB_Vector_nvals (&nvals, candidates) ; 11589 if (nvals == 0) { break ; } // early exit condition 11590 // Neighbors of new members can also be removed from candidates 11591 GrB_vxm (new_neighbors, candidates, NULL, Boolean, 11592 new_members, A, NULL) ; 11593 GrB_apply (candidates, new_neighbors, NULL, GrB_IDENTITY_BOOL, 11594 candidates, sr_desc) ; 11595 GrB_Vector_nvals (&nvals, candidates) ; 11596 } 11597\end{verbatim}} 11598\end{mdframed} 11599 11600\verb'A' is a symmetric Boolean matrix and \verb'prob' is a sparse real vector 11601(of type \verb'FP32'), where \verb'prob(i)' is nonzero only if node \verb'i' is 11602a candidate. The \verb'prob' vector is computed from a random vector computed 11603by a utility function \verb'prand_xget', in the \verb'Demo' folder. It uses 11604two calls to \verb'GrB_apply' to construct \verb'n' random numbers in parallel, 11605using a repeatable pseudo-random number generator. 11606 11607The \verb'maxFirst' semiring uses \verb'z=FIRST(x,y)' as the multiplier 11608operator. The column \verb'A(:,j)' is the adjacency of node \verb'j', and the 11609dot product \verb"prob'*A(:,j)" applies the \verb'FIRST' operator on all 11610entries that appear in the intersection of \verb'prob' and \verb'A(:,j)', where 11611\verb'z=FIRST(prob(i),A(i,j))' which is just \verb'prob(i)' if \verb'A(i,j)' is 11612present. If \verb'A(i,j)' not an explicit entry in the matrix, then this term 11613is not computed and does not take part in the reduction by the \verb'MAX' 11614monoid. 11615 11616Thus, each term \verb'z=FIRST(prob(i),A(i,j))' is the score, \verb'prob(i)', 11617of all neighbors \verb'i' of node \verb'j' that have a score. Node \verb'i' 11618does not have a score if it is not also a candidate and so this is skipped. 11619These terms are then ``summed'' up by taking the maximum score, using 11620\verb'MAX' as the additive monoid. 11621 11622Finally, the results of this matrix-vector multiply are written to the result, 11623\verb'neighbor_max'. The \verb'r_desc' descriptor has the \verb'REPLACE' 11624option enabled. Since \verb'neighbor_max' does not also take part in the 11625computation \verb"prob'*A", it is simply cleared first. Next, is it modified 11626only in those positions \verb'i' where \verb'candidates(i)' is true, using 11627\verb'candidates' as a mask. This sets the \verb'neighbor_max' only for 11628candidate nodes, and leaves the other components of \verb'neighbor_max' as zero 11629(implicit values not in the pattern of the vector). 11630 11631All of the above work is done in a single matrix-vector multiply, with an 11632elegant use of the \verb'maxFirst' semiring coupled with a mask. The 11633matrix-vector multiplication is described above as if it uses dot products of 11634rows of \verb'A' with the column vector \verb'prob', but SuiteSparse:GraphBLAS 11635does not compute it that way. Sparse dot products are much slower the optimal 11636method for multiplying a sparse matrix times a sparse vector. The result is 11637the same, however. 11638 11639The second matrix-vector multiplication is more straight-forward. Once the set 11640of new members in the independent is found, it is used to remove all neighbors 11641of those new members from the set of candidates. 11642 11643The resulting method is very efficient. For the \verb'Freescale2' matrix, the 11644algorithm finds an independent set of size 1.6 million in 1.7 seconds (on the 11645same MacBook Pro referred to in Section~\ref{bfs}, using a single core), taking 11646four iterations of the \verb'while' loop. For comparison, removing its 11647diagonal entries (required for the algorithm to work) takes 0.3 seconds in 11648GraphBLAS (see Section~\ref{transpose}), and simply transposing the matrix 11649takes 0.24 seconds in both MATLAB and GraphBLAS. 11650 11651\newpage 11652%------------------------------------------------------------------------------- 11653\subsection{Creating a random matrix} 11654%------------------------------------------------------------------------------- 11655\label{random} 11656 11657The \verb'random_matrix' function in the \verb'Demo' folder generates a random 11658matrix with a specified dimension and number of entries, either symmetric or 11659unsymmetric, and with or without self-edges (diagonal entries in the matrix). 11660It relies on \verb'simple_rand*' functions in the \verb'Demo' folder to provide 11661a portable random number generator that creates the same sequence on any 11662computer and operating system. 11663 11664\verb'random_matrix' can use one of two methods: \verb'GrB_Matrix_setElement' 11665and \verb'GrB_Matrix_build'. The former method is very simple to use: 11666 11667 {\footnotesize 11668 \begin{verbatim} 11669 GrB_Matrix_new (&A, GrB_FP64, nrows, ncols) ; 11670 for (int64_t k = 0 ; k < ntuples ; k++) 11671 { 11672 GrB_Index i = simple_rand_i ( ) % nrows ; 11673 GrB_Index j = simple_rand_i ( ) % ncols ; 11674 if (no_self_edges && (i == j)) continue ; 11675 double x = simple_rand_x ( ) ; 11676 // A (i,j) = x 11677 GrB_Matrix_setElement (A, x, i, j) ; 11678 if (make_symmetric) 11679 { 11680 // A (j,i) = x 11681 GrB_Matrix_setElement (A, x, j, i) ; 11682 } 11683 } \end{verbatim}} 11684 11685The above code can generate a million-by-million sparse \verb'double' matrix 11686with 200 million entries in 66 seconds (6 seconds of which is the time to 11687generate the random \verb'i', \verb'j', and \verb'x'), including the time 11688to finish all pending computations. The user application does not need to 11689create a list of all the tuples, nor does it need to know how many entries will 11690appear in the matrix. It just starts from an empty matrix and adds them one at 11691a time in arbitrary order. GraphBLAS handles the rest. This method is not 11692feasible in MATLAB. 11693 11694The next method uses \verb'GrB_Matrix_build'. It is more complex to use than 11695\verb'setElement' since it requires the user application to allocate and fill 11696the tuple lists, and it requires knowledge of how many entries will appear in 11697the matrix, or at least a good upper bound, before the matrix is constructed. 11698It is slightly faster, creating the same matrix in 60 seconds, 51 seconds 11699of which is spent in \verb'GrB_Matrix_build'. 11700 11701\newpage 11702 {\footnotesize 11703 \begin{verbatim} 11704 GrB_Index *I, *J ; 11705 double *X ; 11706 int64_t s = ((make_symmetric) ? 2 : 1) * nedges + 1 ; 11707 I = malloc (s * sizeof (GrB_Index)) ; 11708 J = malloc (s * sizeof (GrB_Index)) ; 11709 X = malloc (s * sizeof (double )) ; 11710 if (I == NULL || J == NULL || X == NULL) 11711 { 11712 // out of memory 11713 if (I != NULL) free (I) ; 11714 if (J != NULL) free (J) ; 11715 if (X != NULL) free (X) ; 11716 return (GrB_OUT_OF_MEMORY) ; 11717 } 11718 int64_t ntuples = 0 ; 11719 for (int64_t k = 0 ; k < nedges ; k++) 11720 { 11721 GrB_Index i = simple_rand_i ( ) % nrows ; 11722 GrB_Index j = simple_rand_i ( ) % ncols ; 11723 if (no_self_edges && (i == j)) continue ; 11724 double x = simple_rand_x ( ) ; 11725 // A (i,j) = x 11726 I [ntuples] = i ; 11727 J [ntuples] = j ; 11728 X [ntuples] = x ; 11729 ntuples++ ; 11730 if (make_symmetric) 11731 { 11732 // A (j,i) = x 11733 I [ntuples] = j ; 11734 J [ntuples] = i ; 11735 X [ntuples] = x ; 11736 ntuples++ ; 11737 } 11738 } 11739 GrB_Matrix_build (A, I, J, X, ntuples, GrB_SECOND_FP64) ; \end{verbatim}} 11740 11741The equivalent \verb'sprandsym' function in MATLAB takes 150 seconds, but 11742\verb'sprandsym' uses a much higher-quality random number generator to create 11743the tuples \verb'[I,J,X]'. Considering just the time for 11744\verb'sparse(I,J,X,n,n)' in \verb'sprandsym' (equivalent to 11745\verb'GrB_Matrix_build'), the time is 70 seconds. That is, each of these three 11746methods, \verb'setElement' and \verb'build' in SuiteSparse:GraphBLAS, and 11747\verb'sparse' in MATLAB, are equally fast. 11748 11749\newpage 11750%------------------------------------------------------------------------------- 11751\subsection{Creating a finite-element matrix} 11752%------------------------------------------------------------------------------- 11753\label{fem} 11754 11755Suppose a finite-element matrix is being constructed, with \verb'k=40,000' 11756finite-element matrices, each of size \verb'8'-by-\verb'8'. The following 11757operations (in pseudo-MATLAB notation) are very efficient in 11758SuiteSparse:GraphBLAS. 11759 11760 {\footnotesize 11761 \begin{verbatim} 11762 A = sparse (m,n) ; % create an empty n-by-n sparse GraphBLAS matrix 11763 for i = 1:k 11764 construct a 8-by-8 sparse or dense finite-element F 11765 I and J define where the matrix F is to be added: 11766 I = a list of 8 row indices 11767 J = a list of 8 column indices 11768 % using GrB_assign, with the 'plus' accum operator: 11769 A (I,J) = A (I,J) + F 11770 end \end{verbatim}} 11771 11772If this were done in MATLAB or in GraphBLAS with blocking mode enabled, the 11773computations would be extremely slow. This example is taken from Loren Shure's 11774blog on MATLAB Central, {\em Loren on the Art of MATLAB} \cite{Davis07}, 11775which discusses the built-in \verb'wathen' function. In 11776MATLAB, a far better approach is to construct a list of tuples \verb'[I,J,X]' 11777and to use \verb'sparse(I,J,X,n,n)'. This is identical to creating the same 11778list of tuples in GraphBLAS and using the \verb'GrB_Matrix_build', which is 11779equally fast. The difference in time between using \verb'sparse' or 11780\verb'GrB_Matrix_build', and using submatrix assignment with blocking mode (or 11781in MATLAB which does not have a nonblocking mode) can be extreme. For the 11782example matrix discussed in \cite{Davis07}, using \verb'sparse' instead of 11783submatrix assignment in MATLAB cut the run time of \verb'wathen' from 305 11784seconds down to 1.6 seconds. 11785 11786In SuiteSparse:GraphBLAS, the performance of both methods is essentially 11787identical, and roughly as fast as \verb'sparse' in MATLAB. Inside 11788SuiteSparse:GraphBLAS, \verb'GrB_assign' is doing the same thing. When 11789performing \verb'A(I,J)=A(I,J)+F', if it finds that it cannot quickly insert an 11790update into the \verb'A' matrix, it creates a list of pending tuples to be 11791assembled later on. When the matrix is ready for use in a subsequent 11792GraphBLAS operation (one that normally cannot use a matrix with pending 11793computations), the tuples are assembled all at once via 11794\verb'GrB_Matrix_build'. 11795 11796GraphBLAS operations on other matrices have no effect on when the pending 11797updates of a matrix are completed. Thus, any GraphBLAS method or operation can 11798be used to construct the \verb'F' matrix in the example above, without 11799affecting when the pending updates to \verb'A' are completed. 11800 11801The MATLAB \verb'wathen.m' script is part of Higham's \verb'gallery' of 11802matrices \cite{Higham}. It creates a finite-element matrix with random 11803coefficients for a 2D mesh of size \verb'nx'-by-\verb'ny', a matrix formulation 11804by Wathen \cite{Wathen}. The pattern of the matrix is fixed; just the values 11805are randomized. The GraphBLAS equivalent can use either 11806\verb'GrB_Matrix_build', or \verb'GrB_assign'. Both methods have good 11807performance. The \verb'GrB_Matrix_build' version below is about 15\% to 20\% 11808faster than the MATLAB \verb'wathen.m' function, regardless of the problem 11809size. It uses the identical algorithm as \verb'wathen.m'. 11810 11811 {\footnotesize 11812 \begin{verbatim} 11813 int64_t ntriplets = nx*ny*64 ; 11814 I = malloc (ntriplets * sizeof (int64_t)) ; 11815 J = malloc (ntriplets * sizeof (int64_t)) ; 11816 X = malloc (ntriplets * sizeof (double )) ; 11817 if (I == NULL || J == NULL || X == NULL) 11818 { 11819 FREE_ALL ; 11820 return (GrB_OUT_OF_MEMORY) ; 11821 } 11822 ntriplets = 0 ; 11823 for (int j = 1 ; j <= ny ; j++) 11824 { 11825 for (int i = 1 ; i <= nx ; i++) 11826 { 11827 nn [0] = 3*j*nx + 2*i + 2*j + 1 ; 11828 nn [1] = nn [0] - 1 ; 11829 nn [2] = nn [1] - 1 ; 11830 nn [3] = (3*j-1)*nx + 2*j + i - 1 ; 11831 nn [4] = 3*(j-1)*nx + 2*i + 2*j - 3 ; 11832 nn [5] = nn [4] + 1 ; 11833 nn [6] = nn [5] + 1 ; 11834 nn [7] = nn [3] + 1 ; 11835 for (int krow = 0 ; krow < 8 ; krow++) nn [krow]-- ; 11836 for (int krow = 0 ; krow < 8 ; krow++) 11837 { 11838 for (int kcol = 0 ; kcol < 8 ; kcol++) 11839 { 11840 I [ntriplets] = nn [krow] ; 11841 J [ntriplets] = nn [kcol] ; 11842 X [ntriplets] = em (krow,kcol) ; 11843 ntriplets++ ; 11844 } 11845 } 11846 } 11847 } 11848 // A = sparse (I,J,X,n,n) ; 11849 GrB_Matrix_build (A, I, J, X, ntriplets, GrB_PLUS_FP64) ; \end{verbatim}} 11850 11851The \verb'GrB_assign' version has the advantage of not requiring the 11852user application to construct the tuple list, and is almost as fast as using 11853\verb'GrB_Matrix_build'. The code is more elegant than either the MATLAB 11854\verb'wathen.m' function or its GraphBLAS equivalent above. Its performance is 11855comparable with the other two methods, but slightly slower, being about 5\% 11856slower than the MATLAB \verb'wathen', and 20\% slower than the GraphBLAS 11857method above. 11858 11859 {\footnotesize 11860 \begin{verbatim} 11861 GrB_Matrix_new (&F, GrB_FP64, 8, 8) ; 11862 for (int j = 1 ; j <= ny ; j++) 11863 { 11864 for (int i = 1 ; i <= nx ; i++) 11865 { 11866 nn [0] = 3*j*nx + 2*i + 2*j + 1 ; 11867 nn [1] = nn [0] - 1 ; 11868 nn [2] = nn [1] - 1 ; 11869 nn [3] = (3*j-1)*nx + 2*j + i - 1 ; 11870 nn [4] = 3*(j-1)*nx + 2*i + 2*j - 3 ; 11871 nn [5] = nn [4] + 1 ; 11872 nn [6] = nn [5] + 1 ; 11873 nn [7] = nn [3] + 1 ; 11874 for (int krow = 0 ; krow < 8 ; krow++) nn [krow]-- ; 11875 for (int krow = 0 ; krow < 8 ; krow++) 11876 { 11877 for (int kcol = 0 ; kcol < 8 ; kcol++) 11878 { 11879 // F (krow,kcol) = em (krow, kcol) 11880 GrB_Matrix_setElement (F, em (krow,kcol), krow, kcol) ; 11881 } 11882 } 11883 // A (nn,nn) += F 11884 GrB_assign (A, NULL, GrB_PLUS_FP64, F, nn, 8, nn, 8, NULL) ; 11885 } 11886 } \end{verbatim}} 11887 11888Since there is no \verb'Mask', and since \verb'GrB_REPLACE' is not used, the call 11889to \verb'GrB_assign' in the example above is identical to \verb'GxB_subassign'. 11890Either one can be used, and their performance would be identical. 11891 11892Refer to the \verb'wathen.c' function in the \verb'Demo' folder, which 11893uses GraphBLAS to implement the two methods above, and two additional ones. 11894 11895\newpage 11896%------------------------------------------------------------------------------- 11897\subsection{Reading a matrix from a file} 11898%------------------------------------------------------------------------------- 11899\label{read} 11900 11901See also \verb'LAGraph_mmread' and \verb'LAGraph_mmwrite', which 11902can read and write any matrix in Matrix Market format, and 11903\verb'LAGraph_binread' and \verb'LAGraph_binwrite', which read/write a matrix 11904from a binary file. The binary file I/O functions are much faster than 11905the \verb'read_matrix' function described here, and also much faster than 11906\verb'LAGraph_mmread' and \verb'LAGraph_mmwrite'. 11907 11908The \verb'read_matrix' function in the \verb'Demo' reads in a triplet matrix 11909from a file, one line per entry, and then uses \verb'GrB_Matrix_build' to 11910create the matrix. It creates a second copy with \verb'GrB_Matrix_setElement', 11911just to test that method and compare the run times. A comparison of 11912\verb'build' versus \verb'setElement' has already been discussed in 11913Section~\ref{random}. 11914 11915The function can return the matrix as-is, which may be rectangular or 11916unsymmetric. If an input parameter is set to make the matrix symmetric, 11917\verb'read_matrix' computes \verb"A=(A+A')/2" if \verb'A' is square (turning 11918all directed edges into undirected ones). If \verb'A' is rectangular, it 11919creates a bipartite graph, which is the same as the augmented matrix, 11920\verb"A = [0 A ; A' 0]". 11921If \verb'C' is an \verb'n'-by-\verb'n' matrix, then \verb"C=(C+C')/2" can be 11922computed as follows in GraphBLAS, (the \verb'scale2' function divides an entry 11923by 2): 11924 11925 \vspace{-0.05in} 11926 {\footnotesize 11927 \begin{verbatim} 11928 GrB_Descriptor_new (&dt2) ; 11929 GrB_Descriptor_set (dt2, GrB_INP1, GrB_TRAN) ; 11930 GrB_Matrix_new (&A, GrB_FP64, n, n) ; 11931 GrB_eWiseAdd (A, NULL, NULL, GrB_PLUS_FP64, C, C, dt2) ; // A=C+C' 11932 GrB_free (&C) ; 11933 GrB_Matrix_new (&C, GrB_FP64, n, n) ; 11934 GrB_UnaryOp_new (&scale2_op, scale2, GrB_FP64, GrB_FP64) ; 11935 GrB_apply (C, NULL, NULL, scale2_op, A, NULL) ; // C=A/2 11936 GrB_free (&A) ; 11937 GrB_free (&scale2_op) ; \end{verbatim}} 11938 11939This is of course not nearly as elegant as \verb"A=(A+A')/2" in MATLAB, but 11940with minor changes it can work on any type and use any built-in operators 11941instead of \verb'PLUS', or it can use any user-defined operators and types. 11942The above code in SuiteSparse:GraphBLAS takes 0.60 seconds for the 11943\verb'Freescale2' matrix, slightly slower than MATLAB (0.55 seconds). 11944 11945Constructing the augmented system is more complicated using the GraphBLAS C API 11946Specification since it does not yet have a simple way of specifying a range of 11947row and column indices, as in \verb'A(10:20,30:50)' in MATLAB (\verb'GxB_RANGE' 11948is a SuiteSparse:GraphBLAS extension that is not in the Specification). Using 11949the C API in the Specification, the application must instead build a list of 11950indices first, \verb'I=[10, 11' \verb'...' \verb'20]'. 11951 11952Thus, to compute the MATLAB equivalent of \verb"A = [0 A ; A' 0]", index lists 11953\verb'I' and \verb'J' must first be constructed: 11954 11955 \vspace{-0.05in} 11956 {\footnotesize 11957 \begin{verbatim} 11958 int64_t n = nrows + ncols ; 11959 I = malloc (nrows * sizeof (int64_t)) ; 11960 J = malloc (ncols * sizeof (int64_t)) ; 11961 // I = 0:nrows-1 11962 // J = nrows:n-1 11963 if (I == NULL || J == NULL) 11964 { 11965 if (I != NULL) free (I) ; 11966 if (J != NULL) free (J) ; 11967 return (GrB_OUT_OF_MEMORY) ; 11968 } 11969 for (int64_t k = 0 ; k < nrows ; k++) I [k] = k ; 11970 for (int64_t k = 0 ; k < ncols ; k++) J [k] = k + nrows ; \end{verbatim}} 11971 11972Once the index lists are generated, however, the resulting GraphBLAS operations 11973are fairly straightforward, computing \verb"A=[0 C ; C' 0]". 11974 11975 \vspace{-0.05in} 11976 {\footnotesize 11977 \begin{verbatim} 11978 GrB_Descriptor_new (&dt1) ; 11979 GrB_Descriptor_set (dt1, GrB_INP0, GrB_TRAN) ; 11980 GrB_Matrix_new (&A, GrB_FP64, n, n) ; 11981 // A (nrows:n-1, 0:nrows-1) = C' 11982 GrB_assign (A, NULL, NULL, C, J, ncols, I, nrows, dt1) ; 11983 // A (0:nrows-1, nrows:n-1) = C 11984 GrB_assign (A, NULL, NULL, C, I, nrows, J, ncols, NULL) ; \end{verbatim}} 11985 11986This takes 1.38 seconds for the \verb'Freescale2' matrix, almost as fast as 11987\verb"A=[sparse(m,m) C ; C' sparse(n,n)]" in MATLAB (1.25 seconds). 11988 11989Both calls to \verb'GrB_assign' use no accumulator, so the second one 11990causes the partial matrix \verb"A=[0 0 ; C' 0]" to be built first, followed by 11991the final build of \verb"A=[0 C ; C' 0]". A better method, but not an obvious 11992one, is to use the \verb'GrB_FIRST_FP64' accumulator for both assignments. An 11993accumulator enables SuiteSparse:GraphBLAS to determine that that entries 11994created by the first assignment cannot be deleted by the second, and thus it 11995need not force completion of the pending updates prior to the second 11996assignment. 11997 11998SuiteSparse:GraphBLAS also adds a \verb'GxB_RANGE' mechanism that mimics 11999the MATLAB colon notation. This speeds up the method and simplifies the 12000code the user needs to write to compute \verb"A=[0 C ; C' 0]": 12001 12002 \vspace{-0.05in} 12003 {\footnotesize 12004 \begin{verbatim} 12005 int64_t n = nrows + ncols ; 12006 GrB_Matrix_new (&A, xtype, n, n) ; 12007 GrB_Index I_range [3], J_range [3] ; 12008 I_range [GxB_BEGIN] = 0 ; 12009 I_range [GxB_END ] = nrows-1 ; 12010 J_range [GxB_BEGIN] = nrows ; 12011 J_range [GxB_END ] = ncols+nrows-1 ; 12012 // A (nrows:n-1, 0:nrows-1) += C' 12013 GrB_assign (A, NULL, GrB_FIRST_FP64, // or NULL, 12014 C, J_range, GxB_RANGE, I_range, GxB_RANGE, dt1) ; 12015 // A (0:nrows-1, nrows:n-1) += C 12016 GrB_assign (A, NULL, GrB_FIRST_FP64, // or NULL, 12017 C, I_range, GxB_RANGE, J_range, GxB_RANGE, NULL) ; \end{verbatim}} 12018 12019Any operator will suffice because it is not actually applied. An operator is 12020only applied to the set intersection, and the two assignments do not overlap. 12021If an \verb'accum' operator is used, only the final matrix is built, and the 12022time in GraphBLAS drops slightly to 1.25 seconds. This is a very small 12023improvement because in this particular case, SuiteSparse:GraphBLAS is able to 12024detect that no sorting is required for the first build, and the second one is a 12025simple concatenation. In general, however, allowing GraphBLAS to postpone 12026pending updates can lead to significant reductions in run time. 12027 12028%------------------------------------------------------------------------------- 12029\subsection{PageRank} 12030%------------------------------------------------------------------------------- 12031\label{pagerank} 12032 12033The \verb'Demo' folder contains three methods for computing the PageRank of the 12034nodes of a graph. One uses floating-point arithmetic (\verb'GrB_FP64') and two 12035user-defined unary operators (\verb'dpagerank.c'). The second 12036(\verb'ipagerank.c') is very similar, relying on integer arithmetic instead 12037(\verb'GrB_UINT64'). Neither method include a stopping condition. They simply 12038compute a fixed number of iterations. The third example is more extensive 12039(\verb'dpagerank2.c'), and serves as an example of the power and flexibility of 12040user-defined types, operators, monoids, and semirings. It creates a semiring 12041for the entire PageRank computation. It terminates if the 2-norm of the change 12042in the rank vector \verb'r' is below a threshold. 12043 12044\newpage 12045%------------------------------------------------------------------------------- 12046\subsection{Triangle counting} 12047%------------------------------------------------------------------------------- 12048\label{triangle} 12049 12050A triangle in an undirected graph is a clique of size three: three nodes $i$, 12051$j$, and $k$ that are all pairwise connected. There are many ways of counting 12052the number of triangles in a graph. Let \verb'A' be a symmetric matrix with 12053values 0 and 1, and no diagonal entries; this matrix is the adjacency matrix of 12054the graph. Let \verb'E' be the edge incidence matrix with exactly two 1's per 12055column. A column of \verb'E' with entries in rows \verb'i' and \verb'j' 12056represents the edge $(i,j)$ in the graph, \verb'A(i,j)=1' where \verb'i<j'. 12057Let \verb'L' and \verb'U' be the strictly lower and upper triangular parts of 12058\verb'A', respectively. 12059 12060The methods are listed in the table below. Most of them use a form of masked 12061matrix-matrix multiplication. The methods are implemented in MATLAB in the 12062\verb'tricount.m' file, and in GraphBLAS in the \verb'tricount.c' file, both in 12063the \verb'GraphBLAS/Demo' folder. Refer to the comments in those two files for 12064details and derivations on how these methods work. 12065 12066When the matrix is stored by row, and a mask is present and not complemented, 12067\verb'GrB_INP1' is \verb'GrB_TRAN', and \verb'GrB_INP0' is \verb'GxB_DEFAULT', 12068the SuiteSparse:GraphBLAS implementation of \verb'GrB_mxm' always uses a 12069dot-product formulation. Thus, the ${\bf C \langle L \rangle} = {\bf L}{\bf 12070U}^{\sf T}$ method uses dot products. This provides a mechanism for the 12071end-user to select a masked dot product matrix multiplication method in 12072SuiteSparse:GraphBLAS, which is occasionally faster than the outer product 12073method. The MATLAB form assumes the matrices are stored by column 12074(the only option in MATLAB). 12075 12076Each method is followed by a reduction to a scalar, via \verb'GrB_reduce' in 12077GraphBLAS or by \verb'nnz' or \verb'sum(sum(...))' in MATLAB. 12078 12079\vspace{0.05in} 12080\noindent 12081{\footnotesize 12082\begin{tabular}{lll} 12083\hline 12084method and & in MATLAB & in GraphBLAS \\ 12085citation & & \\ 12086\hline 12087minitri \cite{WolfBerryStark15} & \verb"nnz(A*E==2)/3" 12088 & ${\bf C}={\bf AE}$, then \verb'GrB_apply' \\ 12089Burkhardt \cite{Burkhardt16} & \verb"sum(sum((A^2).*A))/6" 12090 & ${\bf C \langle A \rangle} = {\bf A}^2$ \\ 12091Cohen \cite{AzadBulucGilbert15,Cohen09} & \verb"sum(sum((L*U).*A))/2" 12092 & ${\bf C \langle A \rangle} = {\bf LU}$ \\ 12093Sandia \cite{WolfDeveciBerryHammondRajamanickam17} & \verb"sum(sum((U*U).*U))" 12094 & ${\bf C \langle L \rangle} = {\bf LL}$ (outer product) \\ 12095SandiaDot & \verb"sum(sum((U'*L).*L))" 12096 & ${\bf C \langle U \rangle} = {\bf L}{\bf U}^{\sf T}$ (dot product) \\ 12097Sandia2 & \verb"sum(sum((L*L).*L))" 12098 & ${\bf C \langle U \rangle} = {\bf UU}$ (outer product) \\ 12099\hline 12100\end{tabular} 12101} 12102\vspace{0.05in} 12103 12104In general, the Sandia methods are the fastest of the 6 methods when 12105implemented in GraphBLAS. For full details on the triangle counting and 12106$k$-truss algorithms, and performance results, see \cite{Davis18b}, a copy of 12107which appears in the \verb'SuiteSparse/GraphBLAS/Doc' folder. The code appears 12108in \verb'Extras'. That paper uses an earlier version of SuiteSparse:GraphBLAS 12109in which all matrices are stored by column. 12110 12111\newpage 12112%------------------------------------------------------------------------------- 12113\subsection{User-defined types and operators} 12114%------------------------------------------------------------------------------- 12115\label{user} 12116 12117The \verb'Demo' folder contains two working examples of user-defined types, 12118first discussed in Section~\ref{type_new}: \verb'double complex', and a 12119user-defined \verb'typedef' called \verb'wildtype' with a \verb'struct' 12120containing a string and a 4-by-4 \verb'float' matrix. 12121 12122{\bf Double Complex:} 12123Prior to v3.3, GraphBLAS did not have a native complex type. It now appears as 12124the \verb'GxB_FC64' predefined type, but a complex type can also easily added 12125as a user-defined type. The \verb'Complex_init' function in the 12126\verb'usercomplex.c' file in the \verb'Demo' folder creates the \verb'Complex' 12127type based on the ANSI C11 \verb'double complex' type. 12128It creates a full suite of operators that correspond to every 12129built-in GraphBLAS operator, both binary and unary. In addition, it 12130creates the operators listed in the following table, where $D$ is 12131\verb'double' and $C$ is \verb'Complex'. 12132 12133\vspace{0.1in} 12134{\footnotesize 12135\begin{tabular}{llll} 12136\hline 12137name & types & MATLAB & description \\ 12138 & & equivalent & \\ 12139\hline 12140\verb'Complex_complex' & $D \times D \rightarrow C$ & \verb'z=complex(x,y)' & complex from real and imag. \\ 12141\hline 12142\verb'Complex_conj' & $C \rightarrow C$ & \verb'z=conj(x)' & complex conjugate \\ 12143\verb'Complex_real' & $C \rightarrow D$ & \verb'z=real(x)' & real part \\ 12144\verb'Complex_imag' & $C \rightarrow D$ & \verb'z=imag(x)' & imaginary part \\ 12145\verb'Complex_angle' & $C \rightarrow D$ & \verb'z=angle(x)' & phase angle \\ 12146\verb'Complex_complex_real' & $D \rightarrow C$ & \verb'z=complex(x,0)' & real to complex real \\ 12147\verb'Complex_complex_imag' & $D \rightarrow C$ & \verb'z=complex(0,x)' & real to complex imag. \\ 12148\hline 12149\end{tabular} 12150} 12151 12152The \verb'Complex_init' function creates two monoids (\verb'Complex_add_monoid' 12153and \verb'Complex_times_monoid') and a semiring \verb'Complex_plus_times' that 12154corresponds to the conventional linear algebra for complex matrices. The 12155include file \verb'usercomplex.h' in the \verb'Demo' folder is available so 12156that this user-defined \verb'Complex' type can easily be imported into any 12157other user application. When the user application is done, the 12158\verb'Complex_finalize' function frees the \verb'Complex' type and its 12159operators, monoids, and semiring. 12160NOTE: the \verb'Complex' type is not supported in this Demo in Microsoft 12161Visual Studio. 12162 12163{\bf Struct-based:} 12164In addition, the \verb'wildtype.c' program creates a user-defined 12165\verb'typedef' of a \verb'struct' containing a dense 4-by-4 \verb'float' 12166matrix, and a 64-character string. It constructs an additive monoid that adds 12167two 4-by-4 dense matrices, and a multiplier operator that multiplies two 4-by-4 12168matrices. Each of these 4-by-4 matrices is treated by GraphBLAS as a 12169``scalar'' value, and they can be manipulated in the same way any other 12170GraphBLAS type can be manipulated. The purpose of this type is illustrate the 12171endless possibilities of user-defined types and their use in GraphBLAS. 12172 12173\newpage 12174%------------------------------------------------------------------------------- 12175\subsection{User applications using OpenMP or other threading models} 12176%------------------------------------------------------------------------------- 12177\label{threads} 12178 12179An example demo program (\verb'openmp_demo') is included that illustrates how a 12180multi-threaded user application can use GraphBLAS. 12181 12182The results from the \verb'openmp_demo' program may appear out of order. This 12183is by design, simply to show that the user application is running in parallel. 12184The output of each thread should be the same. In particular, each thread 12185generates an intentional error, and later on prints it with \verb'GrB_error'. 12186It will print its own error, not an error from another thread. When all the 12187threads finish, the leader thread prints out each matrix generated by each 12188thread. 12189 12190GraphBLAS can also be combined with user applications that rely on MPI, the 12191Intel TBB threading library, POSIX pthreads, Microsoft Windows threads, or any 12192other threading library. In all cases, GraphBLAS will be thread safe. 12193 12194\newpage 12195%------------------------------------------------------------------------------- 12196\section{Compiling and Installing SuiteSparse:GraphBLAS} 12197%------------------------------------------------------------------------------- 12198\label{sec:install} 12199 12200%---------------------------------------- 12201\subsection{On Linux and Mac} 12202%---------------------------------------- 12203 12204GraphBLAS makes extensive use of features in the ANSI C11 standard, and thus a 12205C compiler supporting this version of the C standard is required to use 12206all features of GraphBLAS. On the Mac 12207(OS X), \verb'clang' 8.0.0 in \verb'Xcode' version 8.2.1 is sufficient, 12208although earlier versions of \verb'Xcode' may work as well. For the GNU 12209\verb'gcc' compiler, version 4.9 or later is required. For the Intel 12210\verb'icc' compiler, version 18.0 or later is required. Version 2.8.12 or 12211later of \verb'cmake' is required; version 3.0.0 is preferred. 12212 12213If you are using a pre-C11 ANSI C compiler, or Microsoft Visual Studio, 12214then the \verb'_Generic' keyword is not available. SuiteSparse:GraphBLAS 12215will still compile, but you will not have access to polymorphic functions 12216such as \verb'GrB_assign'. You will need to use the non-polymorphic functions 12217instead. 12218 12219\begin{alert} 12220{\bf NOTE:} icc is generally an excellent compiler, but it will generate slower 12221code than gcc for SuiteSparse:GraphBLAS v3.2.0 and later. This is because of 12222how the two compilers treat \verb'#pragma omp atomic' The use of gcc for 12223SuiteSparse:GraphBLAS v3.2.0 and later is recommended. Atomics are slower in 12224icc as compared to gcc. 12225\end{alert} 12226 12227To compile SuiteSparse:GraphBLAS, simply type \verb'make' 12228in the main GraphBLAS folder, which compiles the library. This will be a 12229single-threaded compilation, which will take a long time. To compile in 12230parallel (40 threads for example), use: 12231 12232 {\small 12233 \begin{verbatim} 12234 make JOBS=40 \end{verbatim} } 12235 12236To use a non-default compiler with 4 threads: 12237 12238 {\small 12239 \begin{verbatim} 12240 make CC=icc CXX=icc JOBS=4 \end{verbatim} } 12241 12242After compiling the library, you can compile the demos with 12243\verb'make all' and then \verb'make run'. 12244 12245If \verb'cmake' or \verb'make' fail, it might be that your default compiler 12246does not support ANSI C11. Try another compiler. For example, try one of 12247these options. Go into the \verb'build' directory and type one of these: 12248 12249 {\small 12250 \begin{verbatim} 12251 CC=gcc cmake .. 12252 CC=gcc-6 cmake .. 12253 CC=xlc cmake .. 12254 CC=icc cmake .. \end{verbatim} } 12255 12256You can also do the following in the top-level GraphBLAS folder instead: 12257 12258 {\small 12259 \begin{verbatim} 12260 CC=gcc make 12261 CC=gcc-6 cmake 12262 CC=xlc cmake 12263 CC=icc cmake \end{verbatim} } 12264 12265For faster compilation, you can specify a parallel make. For example, 12266to use 32 parallel jobs and the \verb'gcc' compiler, do the following: 12267 12268 {\small 12269 \begin{verbatim} 12270 JOBS=32 CC=gcc make \end{verbatim} } 12271 12272If you do not have \verb'cmake', refer to Section~\ref{altmake}. 12273 12274%---------------------------------------- 12275\subsection{On Microsoft Windows} 12276\label{sec:windows} 12277%---------------------------------------- 12278 12279SuiteSparse:GraphBLAS is now ported to Microsoft Visual Studio. However, that 12280compiler is not ANSI C11 compliant. As a result, GraphBLAS on Windows will have 12281a few minor limitations. 12282 12283\begin{itemize} 12284\item The MS Visual Studio compiler does not support the \verb'_Generic' 12285keyword, required for the polymorphic GraphBLAS functions. So for example, you 12286will need to use \verb'GrB_Matrix_free' instead of just \verb'GrB_free'. 12287 12288\item Variable-length arrays are not supported, so user-defined 12289types are limited to 128 bytes in size. This can be changed by editing 12290\verb'GB_VLA_MAXSIZE' in \verb'Source/GB_compiler.h', and recompiling 12291SuiteSparse:GraphBLAS. 12292\end{itemize} 12293 12294If you use a recent \verb'gcc' or \verb'icc' compiler on Windows other than the 12295Microsoft Compiler (\verb'cl'), these limitations can be avoided. 12296 12297The following instructions apply to Windows 10, CMake 3.16, and 12298Visual Studio 2019, but may work for earlier versions. 12299 12300\begin{enumerate} 12301 12302\item Install CMake 3.16 or later, if not already installed. 12303 See \url{https://cmake.org/} for details. 12304 12305\item Install Microsoft Visual Studio, if not already installed. 12306 See \url{https://visualstudio.microsoft.com/} for details. 12307 Version 2019 is preferred, but earlier versions may also work. 12308 12309\item Open a terminal window and type this in the 12310 \verb'SuiteSparse/GraphBLAS/build' folder: 12311 12312 \vspace{-0.1in} 12313 {\small 12314 \begin{verbatim} 12315 cmake .. \end{verbatim} } 12316 \vspace{-0.1in} 12317 12318\item The \verb'cmake' command generates many files in 12319 \verb'SuiteSparse/GraphBLAS/build', and the file \verb'graphblas.sln' in 12320 particular. Open the generated \verb'graphblas.sln' file in Visual Studio. 12321 12322\item Optionally: right-click \verb'graphblas' in the left panel (Solution 12323 Explorer) and select properties; then navigate to \verb'Configuration' 12324 \verb'Properties', \verb'C/C++', \verb'General' and change the parameter 12325 \verb'Multiprocessor Compilation' to \verb'Yes (/MP)'. Click \verb'OK'. 12326 This will significantly speed up the compilation of GraphBLAS. 12327 12328\item Select the \verb'Build' menu item at the top of the window and 12329 select \verb'Build Solution'. This should create a folder called 12330 \verb'Release' and place the compiled \verb'graphblas.dll', 12331 \verb'graphblas.lib', and \verb'graphblas.exp' files there. Please be 12332 patient; some files may take a while to compile and sometimes may appear to 12333 be stalled. Just wait. 12334 12335 % Alternatively, type this command in the terminal window: 12336 % {\small 12337 % \begin{verbatim} 12338 % devenv graphblas.sln /build "release|x64" /project graphblas \end{verbatim}} 12339 12340\item Add the \verb'GraphBLAS/build/Release' folder to the Windows System path: 12341 12342 \begin{itemize} 12343 \item Open the \verb'Start Menu' and type \verb'Control Panel'. 12344 \item Select the \verb'Control Panel' app. 12345 \item When the app opens, select \verb'System'. 12346 \item From the top left side of the \verb'System' window, select 12347 \verb'Advanced System Settings'. You may have to authenticate 12348 at this step. 12349 \item The \verb'Systems Properties' window should appear with the 12350 \verb'Advanced' tab selected; 12351 select \verb'Environment Variables'. 12352 \item The \verb'Environment Variables' window displays 2 sections, one for 12353 \verb'User' variables and the other for \verb'System' variables. Under 12354 the \verb'Systems' variable section, scroll to and select \verb'Path', 12355 then select \verb'Edit'. A editor window appears allowing to add, 12356 modify, delete or re-order the parts of the \verb'Path'. 12357 \item Add the full path of the \verb'GraphBLAS\build\Release' folder 12358 (typically starting with \verb'C:\Users\you\'..., where \verb'you' is 12359 your Windows username) to the \verb'Path'. 12360 \item If the above steps do not work, you can instead copy the 12361 \verb'graphblas.*' files from \verb'GraphBLAS\build\Release' into any 12362 existing folder listed in your \verb'Path'. 12363 \end{itemize} 12364 12365\item The \verb'GraphBLAS/Include/GraphBLAS.h' file must be included in user 12366 applications via \verb'#include "GraphBLAS.h"'. This is already done for 12367 you in the MATLAB interface discussed in the next section. 12368 12369\end{enumerate} 12370 12371%---------------------------------------- 12372\subsection{Compiling the MATLAB interface (for MATLAB R2020a and earlier)} 12373%---------------------------------------- 12374\label{gbmake} 12375 12376First, compile the SuiteSparse:GraphBLAS dynamic library 12377(\verb'libgraphblas.so' for Linux, \verb'libgraphblas.dylib' for Mac, 12378or \verb'graphblas.dll' for Windows), as described in the prior two 12379subsections. Next: 12380 12381\begin{enumerate} 12382\item In the MATLAB command window: 12383 12384 {\small 12385 \begin{verbatim} 12386 cd GraphBLAS/GraphBLAS/@GrB/private 12387 gbmake \end{verbatim} } 12388 12389\item Follow the remaining instructions in the 12390 \verb'GraphBLAS/GraphBLAS/README.md' file, to revise your 12391 MATLAB path and \verb'startup.m' file. 12392 12393\item As a quick test, try the MATLAB command \verb'GrB(1)', which 12394 creates and displays a 1-by-1 GraphBLAS matrix. For a longer test, do the 12395 following: 12396 12397 {\small 12398 \begin{verbatim} 12399 cd GraphBLAS/GraphBLAS/test 12400 gbtest \end{verbatim} } 12401 12402\item In Windows, if the tests fail with an error stating that the 12403 mex file is invalid because the module could not be found, it means 12404 that MATLAB could not find the compiled \verb'graphblas.lib', \verb'*.dll' 12405 or \verb'*.exp' files in the \verb'build/Release' folder. This can happen 12406 if your Windows System path is not set properly, or if Windows is not 12407 recognizing the \verb'GraphBLAS/build/Release' folder (see 12408 Section~\ref{sec:windows}) Or, you might have permission to change your 12409 Windows System path. In this case, do the following in the MATLAB Command 12410 \vspace{-0.1in} 12411 Window: 12412 12413 \vspace{-0.1in} 12414 {\small 12415 \begin{verbatim} 12416 cd GraphBLAS/build/Release 12417 GrB(1) \end{verbatim} } 12418 12419 \vspace{-0.1in} 12420 After this step, the GraphBLAS library will be loaded into MATLAB. You may 12421 need to add the above lines in your \verb'Documents/MATLAB/startup.m' file, 12422 so that they are done each time MATLAB starts. You will also need to do 12423 this after \verb'clear all' or \verb'clear mex', since those MATLAB 12424 commands remove all loaded libraries from MATLAB. 12425 12426 You might also get an error ``the specified procedure cannot be found.'' 12427 This can occur if you have upgraded your GraphBLAS library from a prior 12428 version, and some of the compiled files \verb'@GrB/private/*.mex*' 12429 are stale. Try the command \verb'gbmake all' in the MATLAB Command 12430 Window, which forces all of the MATLAB interface to be recompiled. 12431 Or, try deleting all \verb'@GrB/private/*.mex*' files and running 12432 \verb'gbmake' again. 12433 12434\item On Windows, the \verb'casin', \verb'casinf', \verb'casinh', and 12435 \verb'casinhf' functions provided by Microsoft do not return the correct 12436 imaginary part. As a result, \verb'GxB_ASIN_FC32', \verb'GxB_ASIN_FC64' 12437 \verb'GxB_ASINH_FC32', and \verb'GxB_ASINH_FC64' do not work properly on 12438 Windows. This affects the \verb'GrB/asin', \verb'GrB/acsc', 12439 \verb'GrB/asinh', and \verb'GrB/acsch', functions in the MATLAB interface. 12440 See the MATLAB tests bypassed in \verb'gbtest76.m' for details, in the 12441 \newline 12442 \verb'GraphBLAS/GraphBLAS/test' folder. 12443 %% FUTURE: fix asin and acsc on Windows for the complex case. 12444 12445\end{enumerate} 12446 12447%---------------------------------------- 12448\subsection{Compiling the MATLAB interface (for MATLAB R2021a and later)} 12449%---------------------------------------- 12450 12451MATLAB R2021a includes its own copy of SuiteSparse:GraphBLAS v3.3.3, as the 12452file \verb'libmwgraphblas.so', which is used for the built-in \verb'C=A*B' when 12453both \verb'A' and \verb'B' are sparse (see the Release Notes of MATLAB R2021a, 12454which discusses the performance gained in MATLAB by using GraphBLAS). 12455 12456That's great news for the impact of GraphBLAS on MATLAB itself, and the domain 12457of high performance computing in general, but it causes a linking problem when 12458using this MATLAB interface for GraphBLAS. The two use different versions of 12459the same library, and a segfault arises if the MATLAB interface for v5.x tries 12460to link with the older GraphBLAS v3.3.3 library. Likewise, the built-in 12461\verb'C=A*B' causes a segfault if it tries to use the newer GraphBLAS v4.x or 12462v5.x libraries. 12463 12464To resolve this issue, a second GraphBLAS library must be compiled, 12465\verb'libgraphblas_renamed', where the internal symbols are all renamed so they 12466do not conflict with the \verb'libmwgraphblas' library. Then both libraries 12467can co-exist in the same instance of MATLAB. 12468 12469To do this, go to the \verb'GraphBLAS/GraphBLAS' folder, containing the 12470MATLAB interface. That folder contains a \verb'CMakeLists.txt' file to 12471compile the \verb'libgraphblas_renamed' library. See the instructions 12472for how to compile the C library \verb'libgraphblas', and repeat them but 12473using the folder \newline 12474\verb'SuiteSparse/GraphBLAS/GraphBLAS/build' instead of \newline 12475\verb'SuiteSparse/GraphBLAS/build'. 12476 12477This will compile the renamed SuiteSparse:GraphBLAS dynamic library 12478(\verb'libgraphblas_renamed.so' for Linux, \verb'libgraphblas_renamed.dylib' 12479for Mac, or \verb'graphblas_renamed.dll' for Windows). These can be 12480placed in the same system-wide location as the standard \verb'libgraphblas' 12481libraries, such as \verb'/usr/local/lib' for Linux. The two pairs of 12482libraries share the identical \verb'GraphBLAS.h' include file. 12483 12484Next, compile the MATLAB interface as described in Section~\ref{gbmake}. For 12485any instructions in that Section that refer to the \verb'GraphBLAS/build' 12486folder (Linux and Mac) or \verb'GraphBLAS/build/Release' (Windows), use \newline 12487\verb'GraphBLAS/GraphBLAS/build' (Linux and Mac) or \newline 12488\verb'GraphBLAS/GraphBLAS/build/Release' (Windows) instead. 12489 12490The resulting functions for your \verb'@GrB' object will now work just fine; 12491no other changes are needed. You can even use the GraphBLAS mexFunctions 12492compiled in MATLAB R2021a in earlier versions of MATLAB (such as R2020a). 12493 12494%---------------------------------------- 12495\subsection{Default matrix format} 12496%---------------------------------------- 12497 12498By default, SuiteSparse:GraphBLAS stores its matrices by row, using the 12499\verb'GxB_BY_ROW' format. You can change the default at compile time to 12500\verb'GxB_BY_COL' using \verb'cmake -DBYCOL=1'. For example: 12501 12502 {\small 12503 \begin{verbatim} 12504 cmake -DBYCOL=1 .. \end{verbatim} } 12505 12506The user application can also use \verb'GxB_get' and \verb'GxB_set' to set and 12507query the global option (see also Sections~\ref{gxbset} and \ref{gxbget}): 12508 12509 {\small 12510 \begin{verbatim} 12511 GxB_Format_Value s ; 12512 GxB_get (GxB_FORMAT, &s) ; 12513 if (s == GxB_BY_COL) printf ("all new matrices are stored by column\n") ; 12514 else printf ("all new matrices are stored by row\n") ; \end{verbatim} } 12515 12516%---------------------------------------- 12517\subsection{Setting the C flags and using CMake} 12518%---------------------------------------- 12519 12520The above options can also be combined. For example, to use the \verb'gcc' 12521compiler, to change the default format \verb'GxB_FORMAT_DEFAULT' to 12522\verb'GxB_BY_COL', use the following \verb'cmake' command while in the 12523\verb'GraphBLAS/build' directory: 12524 12525 {\small 12526 \begin{verbatim} 12527 CC=gcc cmake -DBYCOL=1 .. \end{verbatim}} 12528 12529\noindent 12530Then do \verb'make' in the \verb'build' directory. If this still fails, see 12531the \verb'CMakeLists.txt' file. You can edit that file to pass 12532compiler-specific options to your compiler. Locate this section in the 12533\verb'CMakeLists.txt' file. Use the \verb'set' command in \verb'cmake', as in 12534the example below, to set the compiler flags you need. 12535 12536 {\small 12537 \begin{verbatim} 12538 # check which compiler is being used. If you need to make 12539 # compiler-specific modifications, here is the place to do it. 12540 if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 12541 # cmake 2.8 workaround: gcc needs to be told to do ANSI C11. 12542 # cmake 3.0 doesn't have this problem. 12543 set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -lm " ) 12544 ... 12545 elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") 12546 ... 12547 elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") 12548 ... 12549 elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") 12550 ... 12551 endif ( ) 12552 \end{verbatim} } 12553 12554To compile SuiteSparse:GraphBLAS without running the demos, use \newline 12555\verb'make library' in the top-level directory, or \verb'make' in the 12556\verb'build' directory. 12557 12558Several compile-time options can be selected by editing the \verb'Source/GB.h' 12559file, but these are meant only for code development of SuiteSparse:GraphBLAS 12560itself, not for end-users of SuiteSparse:GraphBLAS. 12561 12562%---------------------------------------- 12563\subsection{Using a plain makefile} 12564\label{altmake} 12565%---------------------------------------- 12566 12567The \verb'GraphBLAS/alternative' directory contains a simple \verb'Makefile' 12568that can be used to compile SuiteSparse:GraphBLAS. This is a useful option 12569if you do not have the required version of \verb'cmake'. This \verb'Makefile' 12570can even compile the entire library with a C++ compiler, which cannot be 12571done with \verb'CMake'. 12572 12573This alternative \verb'Makefile' does not build the 12574\verb'libgraphblas_renamed.so' library required for MATLAB R2021a (see 12575Section~\ref{R2021a}). This can be done by revising the \verb'Makefile', 12576however: add the \verb'-DGBRENAME=1' flag, and change the library name 12577from \verb'libgraphblas' to \verb'libgraphbas_renamed'. 12578 12579%---------------------------------------- 12580\subsection{Running the Demos} 12581%---------------------------------------- 12582 12583After \verb'make' in the top-level directory to compile the library, type 12584\verb'make run' to run the demos. You can also run the demos after compiling: 12585 12586 {\small 12587 \begin{verbatim} 12588 cd Demo 12589 ./demo \end{verbatim} } 12590 12591The \verb'./demo' command is a script that runs the demos with various input 12592matrices in the \verb'Demo/Matrix' folder. The output of the demos will be 12593compared with expected output files in \verb'Demo/Output'. 12594 12595%---------------------------------------- 12596\subsection{Installing SuiteSparse:GraphBLAS} 12597%---------------------------------------- 12598 12599To install the library (typically in \verb'/usr/local/lib' and 12600\verb'/usr/local/include' for Linux systems), go to the top-level GraphBLAS 12601folder and type: 12602 12603 {\small 12604 \begin{verbatim} 12605 sudo make install \end{verbatim} } 12606 12607%---------------------------------------- 12608\subsection{Running the tests} 12609%---------------------------------------- 12610 12611To run a short test, type \verb'make run' at the top-level \verb'GraphBLAS' 12612folder. This will run all the demos in \verb'GraphBLAS/Demos'. MATLAB is not 12613required. 12614 12615To perform the extensive tests in the \verb'Test' folder, and the statement 12616coverage tests in \verb'Tcov', MATLAB R2017A is required. See the 12617\verb'README.txt' files in those two folders for instructions on how to run the 12618tests. The tests in the \verb'Test' folder have been ported to MATLAB on 12619Linux, MacOS, and Windows. The \verb'Tcov' tests do not work on Windows. The 12620MATLAB interface test (\verb'gbtest') works on all platforms; see the 12621\verb'GraphBLAS/GraphBLAS' folder for more details. 12622 12623%---------------------------------------- 12624\subsection{Cleaning up} 12625%---------------------------------------- 12626 12627To remove all compiled files, type \verb'make' \verb'distclean' in the top-level 12628GraphBLAS folder. 12629 12630%------------------------------------------------------------------------------- 12631\section{About NUMA systems} 12632%------------------------------------------------------------------------------- 12633 12634I have tested this package extensively on multicore single-socket systems, but 12635have not yet optimized it for multi-socket systems with a NUMA architecture. 12636That will be done in a future release. If you publish benchmark comparisons 12637with this package, please state the SuiteSparse:GraphBLAS version, and a caveat 12638if appropriate. If you see significant performance issues when going from a 12639single-socket to multi-socket system, I would like to hear from you so I can 12640look into it. 12641 12642% \newpage 12643%------------------------------------------------------------------------------- 12644\section{Acknowledgments} 12645%------------------------------------------------------------------------------- 12646 12647I would like to thank Jeremy Kepner (MIT Lincoln Laboratory Supercomputing 12648Center), and the GraphBLAS API Committee: Ayd\i n Bulu\c{c} (Lawrence Berkeley 12649National Laboratory), Timothy G. Mattson (Intel Corporation) Scott McMillan 12650(Software Engineering Institute at Carnegie Mellon University), Jos\'e Moreira 12651(IBM Corporation), Carl Yang (UC Davis), and Benjamin Brock (UC Berkeley), for 12652creating the GraphBLAS specification and for patiently answering my many 12653questions while I was implementing it. 12654 12655I would like to thank Tim Mattson and Henry Gabb, Intel, Inc., for their 12656collaboration and for the support of Intel. 12657 12658I would like to thank Joe Eaton for his collaboration on the CUDA kernels 12659(still in progress), and for the support of NVIDIA. 12660 12661I would like to thank Michel Pelletier for his collaboration and work on the 12662pygraphblas interface, and Jim Kitchen and Erik Welch for their work on 12663Anaconda's python interface. 12664 12665I would like to thank John Gilbert (UC Santa Barbara) for our many discussions 12666on GraphBLAS, and for our decades-long conversation and collaboration on sparse 12667matrix computations, and sparse matrices in MATLAB in particular. 12668 12669I would like to thank S\'ebastien Villemot (Debian Developer, 12670\url{http://sebastien.villemot.name}) for helping me with various build issues 12671and other code issues with GraphBLAS (and all of SuiteSparse) for its packaging 12672in Debian Linux. 12673 12674I would like to thank Roi Lipman, Redis Labs (\url{https://redislabs.com}), for 12675our many discussions on GraphBLAS and its use in RedisGraph 12676(\url{https://redislabs.com/redis-enterprise/technology/redisgraph/}), a graph 12677database module for Redis. Based on SuiteSparse:GraphBLAS, RedisGraph is up 12678600x faster than the fastest graph databases ({\footnotesize 12679\url{https://youtu.be/9h3Qco_x0QE} \newline 12680\url{https://redislabs.com/blog/new-redisgraph-1-0-achieves-600x-faster-performance-graph-databases/}}). 12681 12682SuiteSparse:GraphBLAS was developed with support from 12683NVIDIA, Intel, MIT Lincoln Lab, Redis Labs, IBM, 12684and the National Science Foundation (1514406, 1835499). 12685 12686%------------------------------------------------------------------------------- 12687\section{Additional Resources} 12688%------------------------------------------------------------------------------- 12689 12690See \url{http://graphblas.org} for the GraphBLAS community page. See 12691\url{https://github.com/GraphBLAS/GraphBLAS-Pointers} for an up-to-date list of 12692additional resources on GraphBLAS, maintained by G{\'{a}}bor Sz{\'{a}}rnyas. 12693 12694\newpage 12695%------------------------------------------------------------------------------- 12696% References 12697%------------------------------------------------------------------------------- 12698{\small 12699\addcontentsline{toc}{section}{References} 12700\bibliographystyle{annotate} 12701\bibliography{GraphBLAS_UserGuide.bib} 12702} 12703\end{document} 12704