File: GrB_objects_UnaryOp.tex

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (368 lines) | stat: -rw-r--r-- 16,633 bytes parent folder | download
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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

\newpage
%===============================================================================
\subsection{GraphBLAS unary operators: {\sf GrB\_UnaryOp}, $z=f(x)$} %==========
%===============================================================================
\label{unaryop}

A unary operator is a scalar function of the form $z=f(x)$.  The domain (type)
of $z$ and $x$ need not be the same.

In the notation in the tables
below, $T$ is any of the 13 built-in types and is a place-holder for
\verb'BOOL', \verb'INT8', \verb'UINT8', ...
\verb'FP32', \verb'FP64', \verb'FC32', or \verb'FC64'.
For example, \verb'GrB_AINV_INT32' is a unary operator that computes
\verb'z=-x' for two values \verb'x' and \verb'z' of type \verb'GrB_INT32'.

The notation $R$ refers to any real type (all but \verb'FC32' and \verb'FC64'),
$I$ refers to any integer type (\verb'INT*' and \verb'UINT*'),
$F$ refers to any real or complex floating point type
(\verb'FP32', \verb'FP64', \verb'FC32', or \verb'FC64'),
$Z$ refers to any complex floating point type
(\verb'FC32' or \verb'FC64'),
and $N$ refers to \verb'INT32' or \verb'INT64'.

The logical negation operator \verb'GrB_LNOT' only works on Boolean types.  The
\verb'GxB_LNOT_'$R$ functions operate on inputs of type $R$, implicitly
typecasting their input to Boolean and returning result of type $R$, with a
value 1 for true and 0 for false.  The operators \verb'GxB_LNOT_BOOL' and
\verb'GrB_LNOT' are identical.

\vspace{0.2in}
{\footnotesize
\begin{tabular}{|llll|}
\hline
\multicolumn{4}{|c|}{Unary operators for all types} \\
\hline
GraphBLAS name          & types (domains)   & $z=f(x)$      & description \\
\hline
\verb'GxB_ONE_'$T$      & $T \rightarrow T$ & $z = 1$       & one \\
\verb'GrB_IDENTITY_'$T$ & $T \rightarrow T$ & $z = x$       & identity \\
\verb'GrB_AINV_'$T$     & $T \rightarrow T$ & $z = -x$      & additive inverse \\
\verb'GrB_MINV_'$T$     & $T \rightarrow T$ & $z = 1/x$     & multiplicative inverse \\
\hline
\end{tabular}

\vspace{0.2in}
\begin{tabular}{|llll|}
\hline
\multicolumn{4}{|c|}{Unary operators for real and integer types} \\
\hline
GraphBLAS name          & types (domains)   & $z=f(x)$      & description \\
\hline
\verb'GrB_ABS_'$T$      & $R \rightarrow R$ & $z = |x|$     & absolute value \\
\verb'GrB_LNOT'         & \verb'bool'
                          $\rightarrow$
                          \verb'bool'       & $z = \lnot x$ & logical negation \\
\verb'GxB_LNOT_'$R$     & $R \rightarrow R$ & $z = \lnot (x \ne 0)$ & logical negation \\
\verb'GrB_BNOT_'$I$     & $I \rightarrow I$ & $z = \lnot x$ & bitwise negation \\
\hline
\end{tabular}

\vspace{0.2in}
\begin{tabular}{|llll|}
\hline
\multicolumn{4}{|c|}{Index-based unary operators for any type (including user-defined)} \\
\hline
GraphBLAS name            & types (domains)   & $z=f(a_{ij})$      & description \\
\hline
\verb'GxB_POSITIONI_'$N$  & $ \rightarrow N$  & $z = i$       & row index (0-based) \\
\verb'GxB_POSITIONI1_'$N$ & $ \rightarrow N$  & $z = i+1$     & row index (1-based) \\
\verb'GxB_POSITIONJ_'$N$  & $ \rightarrow N$  & $z = j$       & column index (0-based) \\
\verb'GxB_POSITIONJ1_'$N$ & $ \rightarrow N$  & $z = j+1$     & column index (1-based) \\
\hline
\end{tabular}
\vspace{0.2in}

\begin{tabular}{|llll|}
\hline
\multicolumn{4}{|c|}{Unary operators for floating-point types (real and complex)} \\
\hline
GraphBLAS name          & types (domains)   & $z=f(x)$      & description \\
\hline
\verb'GxB_SQRT_'$F$     & $F \rightarrow F$ & $z = \sqrt(x)$       & square root \\
\verb'GxB_LOG_'$F$      & $F \rightarrow F$ & $z = \log_e(x)$      & natural logarithm \\
\verb'GxB_EXP_'$F$      & $F \rightarrow F$ & $z = e^x$            & natural exponent \\
\hline
\verb'GxB_LOG10_'$F$    & $F \rightarrow F$ & $z = \log_{10}(x)$   & base-10 logarithm \\
\verb'GxB_LOG2_'$F$     & $F \rightarrow F$ & $z = \log_2(x)$      & base-2 logarithm \\
\verb'GxB_EXP2_'$F$     & $F \rightarrow F$ & $z = 2^x$            & base-2 exponent \\
\hline
\verb'GxB_EXPM1_'$F$    & $F \rightarrow F$ & $z = e^x - 1$        & natural exponent - 1 \\
\verb'GxB_LOG1P_'$F$    & $F \rightarrow F$ & $z = \log(x+1)$      & natural log of $x+1$ \\
\hline
\verb'GxB_SIN_'$F$      & $F \rightarrow F$ & $z = \sin(x)$        & sine \\
\verb'GxB_COS_'$F$      & $F \rightarrow F$ & $z = \cos(x)$        & cosine \\
\verb'GxB_TAN_'$F$      & $F \rightarrow F$ & $z = \tan(x)$        & tangent \\
\hline
\verb'GxB_ASIN_'$F$     & $F \rightarrow F$ & $z = \sin^{-1}(x)$        & inverse sine \\
\verb'GxB_ACOS_'$F$     & $F \rightarrow F$ & $z = \cos^{-1}(x)$        & inverse cosine \\
\verb'GxB_ATAN_'$F$     & $F \rightarrow F$ & $z = \tan^{-1}(x)$        & inverse tangent \\
\hline
\verb'GxB_SINH_'$F$     & $F \rightarrow F$ & $z = \sinh(x)$        & hyperbolic sine \\
\verb'GxB_COSH_'$F$     & $F \rightarrow F$ & $z = \cosh(x)$        & hyperbolic cosine \\
\verb'GxB_TANH_'$F$     & $F \rightarrow F$ & $z = \tanh(x)$        & hyperbolic tangent \\
\hline
\verb'GxB_ASINH_'$F$    & $F \rightarrow F$ & $z = \sinh^{-1}(x)$        & inverse hyperbolic sine \\
\verb'GxB_ACOSH_'$F$    & $F \rightarrow F$ & $z = \cosh^{-1}(x)$        & inverse hyperbolic cosine \\
\verb'GxB_ATANH_'$F$    & $F \rightarrow F$ & $z = \tanh^{-1}(x)$        & inverse hyperbolic tangent \\
\hline
\verb'GxB_SIGNUM_'$F$   & $F \rightarrow F$ & $z = \sgn(x)$                 & sign, or signum function \\
\verb'GxB_CEIL_'$F$     & $F \rightarrow F$ & $z = \lceil x \rceil $       & ceiling function \\
\verb'GxB_FLOOR_'$F$    & $F \rightarrow F$ & $z = \lfloor x \rfloor $     & floor function \\
\verb'GxB_ROUND_'$F$    & $F \rightarrow F$ & $z = \mbox{round}(x)$        & round to nearest \\
\verb'GxB_TRUNC_'$F$    & $F \rightarrow F$ & $z = \mbox{trunc}(x)$        & round towards zero \\
\hline
\verb'GxB_ISINF_'$F$    & $F \rightarrow $ \verb'bool' & $z = \mbox{isinf}(x)$ & true if $\pm \infty$ \\
\verb'GxB_ISNAN_'$F$    & $F \rightarrow $ \verb'bool' & $z = \mbox{isnan}(x)$ & true if \verb'NaN' \\
\verb'GxB_ISFINITE_'$F$ & $F \rightarrow $ \verb'bool' & $z = \mbox{isfinite}(x)$ & true if finite \\
\hline
\end{tabular}
\vspace{0.2in}

\begin{tabular}{|llll|}
\hline
\multicolumn{4}{|c|}{Unary operators for floating-point types (real only)} \\
\hline
GraphBLAS name          & types (domains)   & $z=f(x)$      & description \\
\hline
\verb'GxB_LGAMMA_'$R$   & $R \rightarrow R$ & $z = \log(|\Gamma (x)|)$  & log of gamma function \\
\verb'GxB_TGAMMA_'$R$   & $R \rightarrow R$ & $z = \Gamma(x)$        & gamma function \\
\verb'GxB_ERF_'$R$      & $R \rightarrow R$ & $z = \erf(x)$          & error function \\
\verb'GxB_ERFC_'$R$     & $R \rightarrow R$ & $z = \erfc(x)$         & complimentary error function \\
\verb'GxB_CBRT_'$R$     & $R \rightarrow R$ & $z = x^{1/3}$          & cube root \\
\hline
\verb'GxB_FREXPX_'$R$   & $R \rightarrow R$ & $z = \mbox{frexpx}(x)$  & normalized fraction \\
\verb'GxB_FREXPE_'$R$   & $R \rightarrow R$ & $z = \mbox{frexpe}(x)$  & normalized exponent \\
\hline
\end{tabular}
\vspace{0.2in}

\begin{tabular}{|llll|}
\hline
\multicolumn{4}{|c|}{Unary operators for complex types} \\
\hline
GraphBLAS name          & types (domains)   & $z=f(x)$      & description \\
\hline
\verb'GxB_CONJ_'$Z$    & $Z \rightarrow Z$ & $z = \overline{x}$     & complex conjugate \\
\verb'GxB_ABS_'$Z$     & $Z \rightarrow F$ & $z = |x|$              & absolute value \\
\verb'GxB_CREAL_'$Z$   & $Z \rightarrow F$ & $z = \mbox{real}(x)$   & real part \\
\verb'GxB_CIMAG_'$Z$   & $Z \rightarrow F$ & $z = \mbox{imag}(x)$   & imaginary part \\
\verb'GxB_CARG_'$Z$    & $Z \rightarrow F$ & $z = \mbox{carg}(x)$   & angle \\
\hline
\end{tabular}
}
\vspace{0.2in}

Built-in index-based unary operators return the row or column index of an entry.  For a
matrix $z=f(a_{ij})$ returns $z = i$ or $z = j$, or +1 for 1-based indices.
The latter is useful in the MATLAB/Octave interface, where row and column indices are
1-based.  When applied to a vector, $j$ is always zero, and $i$ is the index in
the vector.  These built-in unary operators come in two types: \verb'INT32' and
\verb'INT64', which is the type of the output, $z$.  The functions are agnostic
to the type of their inputs; they only depend on the position of the entries,
not their values.
User-defined index-based operators cannot be defined by \verb'GrB_UnaryOp_new';
use \verb'GrB_IndexUnaryOp_new' instead; see Section~\ref{idxunop}.

\verb'GxB_FREXPX' and \verb'GxB_FREXPE' return the mantissa and exponent,
respectively, from the C11 \verb'frexp' function.  The exponent is
returned as a floating-point value, not an integer.

The operators \verb'GxB_EXPM1_FC*' and \verb'GxB_LOG1P_FC*' for complex
types are currently not accurate.  They will be revised in a future version.

The functions \verb'casin', \verb'casinf', \verb'casinh', and \verb'casinhf'
provided by Microsoft Visual Studio for computing $\sin^{-1}(x)$ and
$\sinh^{-1}(x)$ when $x$ is complex do not compute the correct result.  Thus,
the unary operators \verb'GxB_ASIN_FC32', \verb'GxB_ASIN_FC64'
\verb'GxB_ASINH_FC32', and \verb'GxB_ASINH_FC64' do not work properly if the MS
Visual Studio compiler is used.  These functions work properly if the gcc, icc,
or clang compilers are used on Linux or MacOS.

Integer division by zero normally terminates an application, but this is
avoided in SuiteSparse:GraphBLAS.  For details, see the binary
\verb'GrB_DIV_'$T$ operators.

\begin{alert}
{\bf SPEC:} The definition of integer division by zero is an extension to the
specification.
\end{alert}

The next sections define the following methods for the \verb'GrB_UnaryOp'
object:

\vspace{0.1in}
{\footnotesize
\noindent
\begin{tabular}{lll}
\hline
GraphBLAS function   & purpose                                      & Section \\
\hline
\verb'GrB_UnaryOp_new'   & create a user-defined unary operator         & \ref{unaryop_new} \\
\verb'GxB_UnaryOp_new'   & create a named user-defined unary operator   & \ref{unaryop_new_named} \\
\verb'GrB_UnaryOp_wait'  & wait for a user-defined unary operator       & \ref{unaryop_wait} \\
\verb'GrB_UnaryOp_free'  & free a user-defined unary operator   & \ref{unaryop_free} \\
\verb'GrB_get'           & get properties of an operator    & \ref{get_set_unop} \\
\verb'GrB_set'           & set the operator name/definition & \ref{get_set_unop} \\
\hline
\end{tabular}
}
\vspace{0.1in}

% \newpage
%-------------------------------------------------------------------------------
\subsubsection{{\sf GrB\_UnaryOp\_new:} create a user-defined unary operator}
%-------------------------------------------------------------------------------
\label{unaryop_new}

\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GrB_UnaryOp_new            // create a new user-defined unary operator
(
    GrB_UnaryOp *unaryop,           // handle for the new unary operator
    void *function,                 // pointer to the unary function
    GrB_Type ztype,                 // type of output z
    GrB_Type xtype                  // type of input x
) ;
\end{verbatim} }\end{mdframed}

\verb'GrB_UnaryOp_new' creates a new unary operator.  The new operator is
returned in the \verb'unaryop' handle, which must not be \verb'NULL' on input.
On output, its contents contains a pointer to the new unary operator.

The two types \verb'xtype' and \verb'ztype' are the GraphBLAS types of the
input $x$ and output $z$ of the user-defined function $z=f(x)$.  These types
may be built-in types or user-defined types, in any combination.  The two types
need not be the same, but they must be previously defined before passing them
to \verb'GrB_UnaryOp_new'.

The \verb'function' argument to \verb'GrB_UnaryOp_new' is a pointer to a
user-defined function with the following signature:

    {\footnotesize
    \begin{verbatim}
    void (*f) (void *z, const void *x) ; \end{verbatim} }

When the function \verb'f' is called, the arguments \verb'z' and \verb'x' are
passed as \verb'(void *)' pointers, but they will be pointers to values of the
correct type, defined by \verb'ztype' and \verb'xtype', respectively, when the
operator was created.

{\bf NOTE:}
The pointers passed to a user-defined operator may not be unique.  That is, the
user function may be called with multiple pointers that point to the same
space, such as when \verb'z=f(z,y)' is to be computed by a binary operator, or
\verb'z=f(z)' for a unary operator.  Any parameters passed to the user-callable
function may be aliased to each other.

\newpage
%-------------------------------------------------------------------------------
\subsubsection{{\sf GxB\_UnaryOp\_new:} create a named user-defined unary operator}
%-------------------------------------------------------------------------------
\label{unaryop_new_named}

\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GxB_UnaryOp_new            // create a new user-defined unary operator
(
    GrB_UnaryOp *unaryop,           // handle for the new unary operator
    GxB_unary_function function,    // pointer to the unary function
    GrB_Type ztype,                 // type of output z
    GrB_Type xtype,                 // type of input x
    const char *unop_name,          // name of the user function
    const char *unop_defn           // definition of the user function
) ;
\end{verbatim} }\end{mdframed}

Creates a named \verb'GrB_UnaryOp'.  Only the first 127 characters of
\verb'unop_name' are used.  The \verb'unop_defn' is a string containing the
entire function itself.  For example:

    {\footnotesize
    \begin{verbatim}
    void square (double *z, double *x) { (*z) = (*x) * (*x) ; } ;
    ...
    GrB_Type Square ;
    GxB_UnaryOp_new (&Square, square, GrB_FP64, GrB_FP64, "square",
        "void square (double *z, double *x) { (*z) = (*x) * (*x) ; } ;") ;
    \end{verbatim}}

The two strings \verb'unop_name' and \verb'unop_defn' are optional, but are
required to enable the JIT compilation of kernels that use this operator.

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_UnaryOp_new' requires a non-NULL function pointer.

    {\footnotesize
    \begin{verbatim}
    void square (double *z, double *x) { (*z) = (*x) * (*x) ; } ;
    ...
    GrB_Type Square ;
    GrB_UnaryOp_new (&Square, square, GrB_FP64, GrB_FP64) ;
    GrB_set (Square, "square", GxB_JIT_C_NAME) ;
    GrB_set (Square, "void square (double *z, double *x) { (*z) = (*x) * (*x) ; } ;",
        GxB_JIT_C_DEFINITION) ; \end{verbatim}}

% \newpage
%-------------------------------------------------------------------------------
\subsubsection{{\sf GrB\_UnaryOp\_wait:} wait for a unary operator}
%-------------------------------------------------------------------------------
\label{unaryop_wait}

\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GrB_wait               // wait for a user-defined unary operator
(
    GrB_UnaryOp unaryop,        // unary operator to wait for
    int mode                    // GrB_COMPLETE or GrB_MATERIALIZE
) ;
\end{verbatim}
}\end{mdframed}

After creating a user-defined 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'unaryop' is valid.

% \newpage
%-------------------------------------------------------------------------------
\subsubsection{{\sf GrB\_UnaryOp\_free:} free a user-defined unary operator}
%-------------------------------------------------------------------------------
\label{unaryop_free}

\begin{mdframed}[userdefinedwidth=6in]
{\footnotesize
\begin{verbatim}
GrB_Info GrB_free                   // free a user-created unary operator
(
    GrB_UnaryOp *unaryop            // handle of unary operator to free
) ;
\end{verbatim}
}\end{mdframed}

\verb'GrB_UnaryOp_free' frees a user-defined unary operator.
Either usage:

    {\small
    \begin{verbatim}
    GrB_UnaryOp_free (&unaryop) ;
    GrB_free (&unaryop) ; \end{verbatim}}

\noindent
frees the \verb'unaryop' and sets \verb'unaryop' to \verb'NULL'.
It safely does nothing if passed a \verb'NULL'
handle, or if \verb'unaryop == NULL' on input.
It does nothing at all if passed a built-in unary operator.