1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
|
\newpage
%===============================================================================
\subsection{GraphBLAS IndexUnaryOp operators: {\sf GrB\_IndexUnaryOp}} %========
%===============================================================================
\label{idxunop}
An index-unary operator is a scalar function of the form
$z=f(a_{ij},i,j,y)$ that is applied to the entries $a_{ij}$ of an
$m$-by-$n$ matrix. It can be used in \verb'GrB_apply' (Section~\ref{apply}) or
in \verb'GrB_select' (Section~\ref{select}) to select entries from a matrix or
vector.
The signature of the index-unary function \verb'f' is as follows:
{\footnotesize
\begin{verbatim}
void f
(
void *z, // output value z, of type ztype
const void *x, // input value x of type xtype; value of v(i) or A(i,j)
GrB_Index i, // row index of A(i,j)
GrB_Index j, // column index of A(i,j), or zero for v(i)
const void *y // input scalar y of type ytype
) ; \end{verbatim}}
The following built-in operators are available. Operators that do not depend
on the value of \verb'A(i,j)' can be used on any matrix or vector, including
those of user-defined type. In the table, \verb'y' is a
scalar whose type matches the suffix of the operator. The \verb'VALUEEQ' and
\verb'VALUENE' operators are defined for any built-in type. The other
\verb'VALUE' operators are defined only for real (not complex) built-in types.
Any index computations are done in \verb'int64_t' arithmetic; the result is
typecasted to \verb'int32_t' for the \verb'*INDEX_INT32' operators.
\vspace{0.2in}
\noindent
{\footnotesize
\begin{tabular}{lll}
\hline
GraphBLAS name & MATLAB/Octave & description \\
& analog & \\
\hline
\verb'GrB_ROWINDEX_INT32' & \verb'z=i+y' & row index of \verb'A(i,j)', as int32 \\
\verb'GrB_ROWINDEX_INT64' & \verb'z=i+y' & row index of \verb'A(i,j)', as int64 \\
\verb'GrB_COLINDEX_INT32' & \verb'z=j+y' & column index of \verb'A(i,j)', as int32 \\
\verb'GrB_COLINDEX_INT64' & \verb'z=j+y' & column index of \verb'A(i,j)', as int64 \\
\verb'GrB_DIAGINDEX_INT32' & \verb'z=j-(i+y)' & column diagonal index of \verb'A(i,j)', as int32 \\
\verb'GrB_DIAGINDEX_INT64' & \verb'z=j-(i+y)' & column diagonal index of \verb'A(i,j)', as int64 \\
\hline
\verb'GrB_TRIL' & \verb'z=(j<=(i+y))' & true for entries on or below the \verb'y'th diagonal \\
\verb'GrB_TRIU' & \verb'z=(j>=(i+y))' & true for entries on or above the \verb'y'th diagonal \\
\verb'GrB_DIAG' & \verb'z=(j==(i+y))' & true for entries on the \verb'y'th diagonal \\
\verb'GrB_OFFDIAG' & \verb'z=(j!=(i+y))' & true for entries not on the \verb'y'th diagonal \\
\verb'GrB_COLLE' & \verb'z=(j<=y)' & true for entries in columns 0 to \verb'y' \\
\verb'GrB_COLGT' & \verb'z=(j>y)' & true for entries in columns \verb'y+1' and above \\
\verb'GrB_ROWLE' & \verb'z=(i<=y)' & true for entries in rows 0 to \verb'y' \\
\verb'GrB_ROWGT' & \verb'z=(i>y)' & true for entries in rows \verb'y+1' and above \\
\hline
\verb'GrB_VALUENE_T' & \verb'z=(aij!=y)' & true if \verb'A(i,j)' is not equal to \verb'y'\\
\verb'GrB_VALUEEQ_T' & \verb'z=(aij==y)' & true if \verb'A(i,j)' is equal to \verb'y'\\
\verb'GrB_VALUEGT_T' & \verb'z=(aij>y)' & true if \verb'A(i,j)' is greater than \verb'y' \\
\verb'GrB_VALUEGE_T' & \verb'z=(aij>=y)' & true if \verb'A(i,j)' is greater than or equal to \verb'y' \\
\verb'GrB_VALUELT_T' & \verb'z=(aij<y)' & true if \verb'A(i,j)' is less than \verb'y' \\
\verb'GrB_VALUELE_T' & \verb'z=(aij<=y)' & true if \verb'A(i,j)' is less than or equal to \verb'y' \\
%
\hline
\end{tabular}
}
\vspace{0.2in}
The following methods operate on the \verb'GrB_IndexUnaryOp' object:
\vspace{0.1in}
\noindent
{\footnotesize
\begin{tabular}{lll}
\hline
GraphBLAS function & purpose & Section \\
\hline
\verb'GrB_IndexUnaryOp_new' & create a user-defined index-unary operator & \ref{idxunop_new} \\
\verb'GxB_IndexUnaryOp_new' & create a named user-defined index-unary operator & \ref{idxunop_new_named} \\
\verb'GrB_IndexUnaryOp_wait' & wait for a user-defined index-unary operator & \ref{idxunop_wait} \\
\verb'GrB_IndexUnaryOp_free' & free a user-defined index-unary operator & \ref{idxunop_free} \\
\verb'GrB_get' & get properties of an operator & \ref{get_set_idxunop} \\
\verb'GrB_set' & set the operator name/definition & \ref{get_set_idxunop} \\
\hline
\end{tabular}
}
\vspace{0.1in}
\newpage
%-------------------------------------------------------------------------------
\subsubsection{{\sf GrB\_IndexUnaryOp\_new:} create a user-defined index-unary operator}
%-------------------------------------------------------------------------------
\label{idxunop_new}
\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GrB_IndexUnaryOp_new // create a new user-defined IndexUnary op
(
GrB_IndexUnaryOp *op, // handle for the new IndexUnary operator
void *function, // pointer to IndexUnary function
GrB_Type ztype, // type of output z
GrB_Type xtype, // type of input x (the A(i,j) entry)
GrB_Type ytype // type of scalar input y
) ;
\end{verbatim} }\end{mdframed}
\verb'GrB_IndexUnaryOp_new' creates a new index-unary operator. The new operator is
returned in the \verb'op' handle, which must not be \verb'NULL' on input.
On output, its contents contains a pointer to the new index-unary operator.
The \verb'function' argument to \verb'GrB_IndexUnaryOp_new' is a pointer to a
user-defined function whose signature is given at the beginning of
Section~\ref{idxunop}. Given the properties of an entry $a_{ij}$ in a
matrix, the \verb'function' should return \verb'z' as \verb'true' if the entry
should be kept in the output of \verb'GrB_select', or \verb'false' if it should
not appear in the output. If the return value is not \verb'GrB_BOOL',
it is typecasted to \verb'GrB_BOOL' by \verb'GrB_select'.
The type \verb'xtype' is the GraphBLAS type of the input $x$ of the
user-defined function $z=f(x,i,j,y)$, which is used for the
entry \verb'A(i,j)' of a matrix or \verb'v(i)' of a vector. The type may be
built-in or user-defined.
The type \verb'ytype' is the GraphBLAS type of the scalar input $y$ of the
user-defined function $z=f(x,i,j,y)$. The type may be built-in
or user-defined.
\newpage
%-------------------------------------------------------------------------------
\subsubsection{{\sf GxB\_IndexUnaryOp\_new:} create a named user-defined index-unary operator}
%-------------------------------------------------------------------------------
\label{idxunop_new_named}
\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GxB_IndexUnaryOp_new // create a named user-created IndexUnaryOp
(
GrB_IndexUnaryOp *op, // handle for the new IndexUnary operator
GxB_index_unary_function function, // pointer to index_unary function
GrB_Type ztype, // type of output z
GrB_Type xtype, // type of input x
GrB_Type ytype, // type of scalar input y
const char *idxop_name, // name of the user function
const char *idxop_defn // definition of the user function
) ;
\end{verbatim} }\end{mdframed}
Creates a named \verb'GrB_IndexUnaryOp'. Only the first 127 characters of
\verb'idxop_name' are used. The \verb'ixdop_defn' is a string containing the
entire function itself.
The two strings \verb'idxop_name' and \verb'idxop_defn' are optional, but are
required to enable the JIT compilation of kernels that use this operator.
The strings can also be set the \verb'GrB_set' after the operator is created
with \verb'GrB_IndexUnaryOp_new'. For example:
{\footnotesize
\begin{verbatim}
void banded_idx
(
bool *z,
const int64_t *x, // unused
int64_t i,
int64_t j,
const int64_t *thunk
)
{
// d = abs (j-i)
int64_t d = j-i ;
if (d < 0) d = -d ;
(*z) = (d <= *thunk) ;
}
#define BANDED_IDX_DEFN \
"void banded_idx \n" \
"( \n" \
" bool *z, \n" \
" const int64_t *x, // unused \n" \
" int64_t i, \n" \
" int64_t j, \n" \
" const int64_t *thunk \n" \
") \n" \
"{ \n" \
" int64_t d = j-i ; \n" \
" if (d < 0) d = -d ; \n" \
" (*z) = (d <= *thunk) ; \n" \
"}"
GxB_IndexUnaryOp_new (&Banded,
(GxB_index_unary_function) banded_idx,
GrB_BOOL, GrB_INT64, GrB_INT64,
"banded_idx", BANDED_IDX_DEFN)) ;\end{verbatim}}
If JIT compilation is enabled, or if the corresponding JIT kernel has been
copied into the \verb'PreJIT' folder, the \verb'function' may be \verb'NULL'.
In this case, a JIT kernel is compiled that contains just the user-defined
function. If the JIT is disabled and the \verb'function' is \verb'NULL', this
method returns \verb'GrB_NULL_POINTER'.
The above example is identical to the following usage
except that \verb'GrB_IndexUnaryOp_new' requires a non-NULL function pointer.
The \verb'banded_idx' function is defined the same as above.
{\footnotesize
\begin{verbatim}
void banded_idx ... see above
#define BANDED_IDX_DEFN ... see above
GrB_IndexUnaryOp_new (&Banded,
(GxB_index_unary_function) banded_idx,
GrB_BOOL, GrB_INT64, GrB_INT64) ;
GrB_set (Banded, "banded_idx", GxB_JIT_C_NAME)) ;
GrB_set (Banded, BANDED_IDX_DEFN, GxB_JIT_C_DEFINITION)) ;\end{verbatim}}
%-------------------------------------------------------------------------------
\subsubsection{{\sf GrB\_IndexUnaryOp\_wait:} wait for an index-unary operator}
%-------------------------------------------------------------------------------
\label{idxunop_wait}
\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GrB_wait // wait for a user-defined binary operator
(
GrB_IndexUnaryOp op, // index-unary operator to wait for
int mode // GrB_COMPLETE or GrB_MATERIALIZE
) ;
\end{verbatim}
}\end{mdframed}
After creating a user-defined index-unary operator, a GraphBLAS library may choose
to exploit non-blocking mode to delay its creation. Currently,
SuiteSparse:GraphBLAS currently does nothing except to ensure that the
\verb'op' is valid.
\newpage
%-------------------------------------------------------------------------------
\subsubsection{{\sf GrB\_IndexUnaryOp\_free:} free a user-defined index-unary operator}
%-------------------------------------------------------------------------------
\label{idxunop_free}
\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GrB_free // free a user-created index-unary operator
(
GrB_IndexUnaryOp *op // handle of IndexUnary to free
) ;
\end{verbatim}
}\end{mdframed}
\verb'GrB_IndexUnaryOp_free' frees a user-defined index-unary operator. Either usage:
{\small
\begin{verbatim}
GrB_IndexUnaryOp_free (&op) ;
GrB_free (&op) ; \end{verbatim}}
\noindent
frees the \verb'op' and sets \verb'op' to \verb'NULL'. It safely
does nothing if passed a \verb'NULL' handle, or if \verb'op == NULL' on
input. It does nothing at all if passed a built-in index-unary operator.
|