1 //------------------------------------------------------------------------------
2 // GB.h: definitions visible only inside GraphBLAS
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 #ifndef GB_H
11 #define GB_H
12
13 //------------------------------------------------------------------------------
14 // definitions that modify GraphBLAS.h
15 //------------------------------------------------------------------------------
16
17 #include "GB_warnings.h"
18 #ifndef MATLAB_MEX_FILE
19 #define GB_LIBRARY
20 #endif
21
22 //------------------------------------------------------------------------------
23 // user-visible GraphBLAS.h
24 //------------------------------------------------------------------------------
25
26 #include "GraphBLAS.h"
27
28 //------------------------------------------------------------------------------
29 // internal #include files
30 //------------------------------------------------------------------------------
31
32 #include "GB_prefix.h"
33 #include "GB_dev.h"
34 #include "GB_defaults.h"
35 #include "GB_compiler.h"
36 #include "GB_coverage.h"
37 #include "GB_index.h"
38 #include "GB_cplusplus.h"
39 #include "GB_Global.h"
40 #include "GB_printf.h"
41 #include "GB_assert.h"
42 #include "GB_opaque.h"
43 #include "GB_casting.h"
44 #include "GB_math.h"
45 #include "GB_bitwise.h"
46 #include "GB_binary_search.h"
47 #include "GB_check.h"
48 #include "GB_nnz.h"
49 #include "GB_zombie.h"
50 #include "GB_partition.h"
51 #include "GB_omp.h"
52 #include "GB_context.h"
53 #include "GB_memory.h"
54 #include "GB_werk.h"
55 #include "GB_log2.h"
56
57 //------------------------------------------------------------------------------
58 // more internal definitions
59 //------------------------------------------------------------------------------
60
61 int64_t GB_Pending_n // return # of pending tuples in A
62 (
63 GrB_Matrix A
64 ) ;
65
66 // A is nrows-by-ncols, in either CSR or CSC format
67 #define GB_NROWS(A) ((A)->is_csc ? (A)->vlen : (A)->vdim)
68 #define GB_NCOLS(A) ((A)->is_csc ? (A)->vdim : (A)->vlen)
69
70 // The internal content of a GrB_Matrix and GrB_Vector are identical, and
71 // inside SuiteSparse:GraphBLAS, they can be typecasted between each other.
72 // This typecasting feature should not be done in user code, however, since it
73 // is not supported in the API. All GrB_Vector objects can be safely
74 // typecasted into a GrB_Matrix, but not the other way around. The GrB_Vector
75 // object is more restrictive. The GB_VECTOR_OK(v) macro defines the content
76 // that all GrB_Vector objects must have.
77
78 // GB_VECTOR_OK(v) is used mainly for assertions, but also to determine when it
79 // is safe to typecast an n-by-1 GrB_Matrix (in standard CSC format) into a
80 // GrB_Vector. This is not done in the main SuiteSparse:GraphBLAS library, but
81 // in the GraphBLAS/Test directory only. The macro is also used in
82 // GB_Vector_check, to ensure the content of a GrB_Vector is valid.
83
84 #define GB_VECTOR_OK(v) \
85 ( \
86 ((v) != NULL) && \
87 ((v)->is_csc == true) && \
88 ((v)->plen == 1 || (v)->plen == -1) && \
89 ((v)->vdim == 1) && \
90 ((v)->nvec == 1) && \
91 ((v)->h == NULL) \
92 )
93
94 // A GxB_Vector is a GrB_Vector of length 1
95 #define GB_SCALAR_OK(v) (GB_VECTOR_OK(v) && ((v)->vlen == 1))
96
97 //------------------------------------------------------------------------------
98 // aliased and shallow objects
99 //------------------------------------------------------------------------------
100
101 // GraphBLAS allows all inputs to all user-accessible objects to be aliased, as
102 // in GrB_mxm (C, C, accum, C, C, ...), which is valid. Internal routines are
103 // more restrictive.
104
105 // GB_aliased also checks the content of A and B
106 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
107 bool GB_aliased // determine if A and B are aliased
108 (
109 GrB_Matrix A, // input A matrix
110 GrB_Matrix B // input B matrix
111 ) ;
112
113 // matrices returned to the user are never shallow; internal matrices may be
114 GB_PUBLIC // used by the MATLAB interface
115 bool GB_is_shallow // true if any component of A is shallow
116 (
117 GrB_Matrix A // matrix to query
118 ) ;
119
120 //------------------------------------------------------------------------------
121 // internal GraphBLAS functions
122 //------------------------------------------------------------------------------
123
124 GrB_Info GB_init // start up GraphBLAS
125 (
126 const GrB_Mode mode, // blocking or non-blocking mode
127
128 // pointers to memory management functions
129 void * (* malloc_function ) (size_t),
130 void * (* calloc_function ) (size_t, size_t),
131 void * (* realloc_function ) (void *, size_t),
132 void (* free_function ) (void *),
133 bool malloc_is_thread_safe,
134
135 bool caller_is_GxB_cuda_init, // true for GxB_cuda_init only
136
137 GB_Context Context // from GrB_init or GxB_init
138 ) ;
139
140 typedef enum // input parameter to GB_new and GB_new_bix
141 {
142 GB_Ap_calloc, // 0: calloc A->p, malloc A->h if hypersparse
143 GB_Ap_malloc, // 1: malloc A->p, malloc A->h if hypersparse
144 GB_Ap_null // 2: do not allocate A->p or A->h
145 }
146 GB_Ap_code ;
147
148 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
149 GrB_Info GB_new // create matrix, except for indices & values
150 (
151 GrB_Matrix *Ahandle, // handle of matrix to create
152 const bool A_static_header, // true if Ahandle is statically allocated
153 const GrB_Type type, // matrix type
154 const int64_t vlen, // length of each vector
155 const int64_t vdim, // number of vectors
156 const GB_Ap_code Ap_option, // allocate A->p and A->h, or leave NULL
157 const bool is_csc, // true if CSC, false if CSR
158 const int sparsity, // hyper, sparse, bitmap, full, or
159 // auto (hyper + sparse)
160 const float hyper_switch, // A->hyper_switch, ignored if auto
161 const int64_t plen, // size of A->p and A->h, if A hypersparse.
162 // Ignored if A is not hypersparse.
163 GB_Context Context
164 ) ;
165
166 GrB_Info GB_new_bix // create a new matrix, incl. A->b, A->i, A->x
167 (
168 GrB_Matrix *Ahandle, // output matrix to create
169 const bool A_static_header, // true if Ahandle is statically allocated
170 const GrB_Type type, // type of output matrix
171 const int64_t vlen, // length of each vector
172 const int64_t vdim, // number of vectors
173 const GB_Ap_code Ap_option, // allocate A->p and A->h, or leave NULL
174 const bool is_csc, // true if CSC, false if CSR
175 const int sparsity, // hyper, sparse, bitmap, full, or auto
176 const bool bitmap_calloc, // if true, calloc A->b, otherwise use malloc
177 const float hyper_switch, // A->hyper_switch, unless auto
178 const int64_t plen, // size of A->p and A->h, if hypersparse
179 const int64_t anz, // number of nonzeros the matrix must hold
180 const bool numeric, // if true, allocate A->x, else A->x is NULL
181 GB_Context Context
182 ) ;
183
184 GrB_Info GB_hyper_realloc
185 (
186 GrB_Matrix A, // matrix with hyperlist to reallocate
187 int64_t plen_new, // new size of A->p and A->h
188 GB_Context Context
189 ) ;
190
191 GrB_Info GB_clear // clear a matrix, type and dimensions unchanged
192 (
193 GrB_Matrix A, // matrix to clear
194 GB_Context Context
195 ) ;
196
197 GrB_Info GB_dup // make an exact copy of a matrix
198 (
199 GrB_Matrix *Chandle, // handle of output matrix to create
200 const GrB_Matrix A, // input matrix to copy
201 GB_Context Context
202 ) ;
203
204 GrB_Info GB_dup2 // make an exact copy of a matrix
205 (
206 GrB_Matrix *Chandle, // handle of output matrix to create
207 const GrB_Matrix A, // input matrix to copy
208 const bool numeric, // if true, duplicate the numeric values
209 const GrB_Type ctype, // type of C, if numeric is false
210 GB_Context Context
211 ) ;
212
213 void GB_memcpy // parallel memcpy
214 (
215 void *dest, // destination
216 const void *src, // source
217 size_t n, // # of bytes to copy
218 int nthreads // # of threads to use
219 ) ;
220
221 void GB_memset // parallel memset
222 (
223 void *dest, // destination
224 const int c, // value to to set
225 size_t n, // # of bytes to set
226 int nthreads // # of threads to use
227 ) ;
228
229 GrB_Info GB_nvals // get the number of entries in a matrix
230 (
231 GrB_Index *nvals, // matrix has nvals entries
232 const GrB_Matrix A, // matrix to query
233 GB_Context Context
234 ) ;
235
236 GrB_Info GB_matvec_type // get the type of a matrix
237 (
238 GrB_Type *type, // returns the type of the matrix
239 const GrB_Matrix A, // matrix to query
240 GB_Context Context
241 ) ;
242
243 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
244 GrB_Info GB_bix_alloc // allocate A->b, A->i, and A->x space in a matrix
245 (
246 GrB_Matrix A, // matrix to allocate space for
247 const GrB_Index nzmax, // number of entries the matrix can hold
248 const bool is_bitmap, // if true, allocate A->b, otherwise A->b is NULL
249 const bool bitmap_calloc, // if true, calloc A->b, otherwise use malloc
250 const bool is_sparse, // if true, allocate A->i, otherwise A->i is NULL
251 const bool numeric, // if true, allocate A->x, otherwise A->x is NULL
252 GB_Context Context
253 ) ;
254
255 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
256 GrB_Info GB_ix_realloc // reallocate space in a matrix
257 (
258 GrB_Matrix A, // matrix to allocate space for
259 const int64_t nzmax_new, // new number of entries the matrix can hold
260 const bool numeric, // if true, reallocate A->x, else A->x is NULL
261 GB_Context Context
262 ) ;
263
264 GrB_Info GB_ix_resize // resize a matrix
265 (
266 GrB_Matrix A, // matrix to resize (sparse/hyper, not full/bitmap)
267 const int64_t anz_new, // required new nnz(A)
268 GB_Context Context
269 ) ;
270
271 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
272 void GB_bix_free // free A->b, A->i, and A->x of a matrix
273 (
274 GrB_Matrix A // matrix with content to free
275 ) ;
276
277 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
278 void GB_ph_free // free A->p and A->h of a matrix
279 (
280 GrB_Matrix A // matrix with content to free
281 ) ;
282
283 void GB_phbix_free // free all content of a matrix
284 (
285 GrB_Matrix A // matrix with content to free
286 ) ;
287
288 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
289 bool GB_Type_compatible // check if two types can be typecast
290 (
291 const GrB_Type atype,
292 const GrB_Type btype
293 ) ;
294
295 //------------------------------------------------------------------------------
296 // GB_code_compatible: return true if domains are compatible
297 //------------------------------------------------------------------------------
298
299 // Two domains are compatible for typecasting between them if both are built-in
300 // types (of any kind) or if both are the same user-defined type. This
301 // function does not have the type itself, but just the code. If the types are
302 // available, GB_Type_compatible should be called instead.
303
GB_code_compatible(const GB_Type_code acode,const GB_Type_code bcode)304 static inline bool GB_code_compatible // true if two types can be typecast
305 (
306 const GB_Type_code acode, // type code of a
307 const GB_Type_code bcode // type code of b
308 )
309 {
310
311 bool a_user = (acode == GB_UDT_code) ;
312 bool b_user = (bcode == GB_UDT_code) ;
313
314 if (a_user || b_user)
315 {
316 // both a and b must be user-defined. They should be the same
317 // user-defined type, but the caller does not have the actual type,
318 // just the code.
319 return (a_user && b_user) ;
320 }
321 else
322 {
323 // any built-in domain is compatible with any other built-in domain
324 return (true) ;
325 }
326 }
327
328
329 //------------------------------------------------------------------------------
330 // GB_task_struct: parallel task descriptor
331 //------------------------------------------------------------------------------
332
333 // The element-wise computations (GB_add, GB_emult, and GB_mask) compute
334 // C(:,j)<M(:,j)> = op (A (:,j), B(:,j)). They are parallelized by slicing the
335 // work into tasks, described by the GB_task_struct.
336
337 // There are two kinds of tasks. For a coarse task, kfirst <= klast, and the
338 // task computes all vectors in C(:,kfirst:klast), inclusive. None of the
339 // vectors are sliced and computed by other tasks. For a fine task, klast is
340 // -1. The task computes part of the single vector C(:,kfirst). It starts at
341 // pA in Ai,Ax, at pB in Bi,Bx, and (if M is present) at pM in Mi,Mx. It
342 // computes C(:,kfirst), starting at pC in Ci,Cx.
343
344 // GB_subref also uses the TaskList. It has 12 kinds of fine tasks,
345 // corresponding to each of the 12 methods used in GB_subref_template. For
346 // those fine tasks, method = -TaskList [taskid].klast defines the method to
347 // use.
348
349 // The GB_subassign functions use the TaskList, in many different ways.
350
351 typedef struct // task descriptor
352 {
353 int64_t kfirst ; // C(:,kfirst) is the first vector in this task.
354 int64_t klast ; // C(:,klast) is the last vector in this task.
355 int64_t pC ; // fine task starts at Ci, Cx [pC]
356 int64_t pC_end ; // fine task ends at Ci, Cx [pC_end-1]
357 int64_t pM ; // fine task starts at Mi, Mx [pM]
358 int64_t pM_end ; // fine task ends at Mi, Mx [pM_end-1]
359 int64_t pA ; // fine task starts at Ai, Ax [pA]
360 int64_t pA_end ; // fine task ends at Ai, Ax [pA_end-1]
361 int64_t pB ; // fine task starts at Bi, Bx [pB]
362 int64_t pB_end ; // fine task ends at Bi, Bx [pB_end-1]
363 int64_t len ; // fine task handles a subvector of this length
364 }
365 GB_task_struct ;
366
367 // GB_REALLOC_TASK_WERK: Allocate or reallocate the TaskList so that it can
368 // hold at least ntasks. Double the size if it's too small.
369
370 #define GB_REALLOC_TASK_WERK(TaskList,ntasks,max_ntasks) \
371 { \
372 if ((ntasks) >= max_ntasks) \
373 { \
374 bool ok ; \
375 int nold = (max_ntasks == 0) ? 0 : (max_ntasks + 1) ; \
376 int nnew = 2 * (ntasks) + 1 ; \
377 GB_REALLOC_WERK (TaskList, nnew, nold, GB_task_struct, \
378 &TaskList_size, &ok, NULL) ; \
379 if (!ok) \
380 { \
381 /* out of memory */ \
382 GB_FREE_ALL ; \
383 return (GrB_OUT_OF_MEMORY) ; \
384 } \
385 for (int t = nold ; t < nnew ; t++) \
386 { \
387 TaskList [t].kfirst = -1 ; \
388 TaskList [t].klast = INT64_MIN ; \
389 TaskList [t].pA = INT64_MIN ; \
390 TaskList [t].pA_end = INT64_MIN ; \
391 TaskList [t].pB = INT64_MIN ; \
392 TaskList [t].pB_end = INT64_MIN ; \
393 TaskList [t].pC = INT64_MIN ; \
394 TaskList [t].pC_end = INT64_MIN ; \
395 TaskList [t].pM = INT64_MIN ; \
396 TaskList [t].pM_end = INT64_MIN ; \
397 TaskList [t].len = INT64_MIN ; \
398 } \
399 max_ntasks = 2 * (ntasks) ; \
400 } \
401 ASSERT ((ntasks) < max_ntasks) ; \
402 }
403
404 GrB_Info GB_ewise_slice
405 (
406 // output:
407 GB_task_struct **p_TaskList, // array of structs
408 size_t *p_TaskList_size, // size of TaskList
409 int *p_ntasks, // # of tasks constructed
410 int *p_nthreads, // # of threads for eWise operation
411 // input:
412 const int64_t Cnvec, // # of vectors of C
413 const int64_t *restrict Ch, // vectors of C, if hypersparse
414 const int64_t *restrict C_to_M, // mapping of C to M
415 const int64_t *restrict C_to_A, // mapping of C to A
416 const int64_t *restrict C_to_B, // mapping of C to B
417 bool Ch_is_Mh, // if true, then Ch == Mh; GB_add only
418 const GrB_Matrix M, // mask matrix to slice (optional)
419 const GrB_Matrix A, // matrix to slice
420 const GrB_Matrix B, // matrix to slice
421 GB_Context Context
422 ) ;
423
424 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
425 void GB_slice_vector
426 (
427 // output: return i, pA, and pB
428 int64_t *p_i, // work starts at A(i,kA) and B(i,kB)
429 int64_t *p_pM, // M(i:end,kM) starts at pM
430 int64_t *p_pA, // A(i:end,kA) starts at pA
431 int64_t *p_pB, // B(i:end,kB) starts at pB
432 // input:
433 const int64_t pM_start, // M(:,kM) starts at pM_start in Mi,Mx
434 const int64_t pM_end, // M(:,kM) ends at pM_end-1 in Mi,Mx
435 const int64_t *restrict Mi, // indices of M (or NULL)
436 const int64_t pA_start, // A(:,kA) starts at pA_start in Ai,Ax
437 const int64_t pA_end, // A(:,kA) ends at pA_end-1 in Ai,Ax
438 const int64_t *restrict Ai, // indices of A
439 const int64_t pB_start, // B(:,kB) starts at pB_start in Bi,Bx
440 const int64_t pB_end, // B(:,kB) ends at pB_end-1 in Bi,Bx
441 const int64_t *restrict Bi, // indices of B
442 const int64_t vlen, // A->vlen and B->vlen
443 const double target_work // target work
444 ) ;
445
446 void GB_task_cumsum
447 (
448 int64_t *Cp, // size Cnvec+1
449 const int64_t Cnvec,
450 int64_t *Cnvec_nonempty, // # of non-empty vectors in C
451 GB_task_struct *restrict TaskList, // array of structs
452 const int ntasks, // # of tasks
453 const int nthreads, // # of threads
454 GB_Context Context
455 ) ;
456
457 //------------------------------------------------------------------------------
458 // GB_GET_VECTOR: get the content of a vector for a coarse/fine task
459 //------------------------------------------------------------------------------
460
461 #define GB_GET_VECTOR(pX_start, pX_fini, pX, pX_end, Xp, kX, Xvlen) \
462 int64_t pX_start, pX_fini ; \
463 if (fine_task) \
464 { \
465 /* A fine task operates on a slice of X(:,k) */ \
466 pX_start = TaskList [taskid].pX ; \
467 pX_fini = TaskList [taskid].pX_end ; \
468 } \
469 else \
470 { \
471 /* vectors are never sliced for a coarse task */ \
472 pX_start = GBP (Xp, kX, Xvlen) ; \
473 pX_fini = GBP (Xp, kX+1, Xvlen) ; \
474 }
475
476 //------------------------------------------------------------------------------
477
478 GrB_Info GB_transplant // transplant one matrix into another
479 (
480 GrB_Matrix C, // output matrix to overwrite with A
481 const GrB_Type ctype, // new type of C
482 GrB_Matrix *Ahandle, // input matrix to copy from and free
483 GB_Context Context
484 ) ;
485
486 GrB_Info GB_transplant_conform // transplant and conform hypersparsity
487 (
488 GrB_Matrix C, // destination matrix to transplant into
489 GrB_Type ctype, // type to cast into
490 GrB_Matrix *Thandle, // source matrix
491 GB_Context Context
492 ) ;
493
494 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
495 size_t GB_code_size // return the size of a type, given its code
496 (
497 const GB_Type_code code, // input code of the type to find the size of
498 const size_t usize // known size of user-defined type
499 ) ;
500
501 void GB_Matrix_free // free a matrix
502 (
503 GrB_Matrix *Ahandle // handle of matrix to free
504 ) ;
505
506 //------------------------------------------------------------------------------
507
508 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
509 GrB_Type GB_code_type // return the GrB_Type corresponding to the code
510 (
511 const GB_Type_code code, // type code to convert
512 const GrB_Type type // user type if code is GB_UDT_code
513 ) ;
514
515 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
516 void GB_pslice // slice Ap
517 (
518 int64_t *restrict Slice, // size ntasks+1
519 const int64_t *restrict Ap, // array size n+1 (NULL if full or bitmap)
520 const int64_t n,
521 const int ntasks, // # of tasks
522 const bool perfectly_balanced
523 ) ;
524
525 void GB_eslice
526 (
527 // output:
528 int64_t *Slice, // array of size ntasks+1
529 // input:
530 int64_t e, // number items to partition amongst the tasks
531 const int ntasks // # of tasks
532 ) ;
533
534 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
535 void GB_cumsum // cumulative sum of an array
536 (
537 int64_t *restrict count, // size n+1, input/output
538 const int64_t n,
539 int64_t *restrict kresult, // return k, if needed by the caller
540 int nthreads,
541 GB_Context Context
542 ) ;
543
544 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
545 GrB_Info GB_Descriptor_get // get the contents of a descriptor
546 (
547 const GrB_Descriptor desc, // descriptor to query, may be NULL
548 bool *C_replace, // if true replace C before C<M>=Z
549 bool *Mask_comp, // if true use logical negation of M
550 bool *Mask_struct, // if true use the structure of M
551 bool *In0_transpose, // if true transpose first input
552 bool *In1_transpose, // if true transpose second input
553 GrB_Desc_Value *AxB_method, // method for C=A*B
554 int *do_sort, // if nonzero, sort in GrB_mxm
555 GB_Context Context
556 ) ;
557
558 GrB_Info GB_compatible // SUCCESS if all is OK, *_MISMATCH otherwise
559 (
560 const GrB_Type ctype, // the type of C (matrix or scalar)
561 const GrB_Matrix C, // the output matrix C; NULL if C is a scalar
562 const GrB_Matrix M, // optional mask, NULL if no mask
563 const bool Mask_struct, // true if M is structural
564 const GrB_BinaryOp accum, // C<M> = accum(C,T) is computed
565 const GrB_Type ttype, // type of T
566 GB_Context Context
567 ) ;
568
569 GrB_Info GB_Mask_compatible // check type and dimensions of mask
570 (
571 const GrB_Matrix M, // mask to check
572 const bool Mask_struct, // true if M is structural
573 const GrB_Matrix C, // C<M>= ...
574 const GrB_Index nrows, // size of output if C is NULL (see GB*assign)
575 const GrB_Index ncols,
576 GB_Context Context
577 ) ;
578
579 GrB_Info GB_BinaryOp_compatible // check for domain mismatch
580 (
581 const GrB_BinaryOp op, // binary operator to check
582 const GrB_Type ctype, // C must be compatible with op->ztype
583 const GrB_Type atype, // A must be compatible with op->xtype
584 const GrB_Type btype, // B must be compatible with op->ytype
585 const GB_Type_code bcode, // B may not have a type, just a code
586 GB_Context Context
587 ) ;
588
589 GB_PUBLIC // accessed by the MATLAB interface only
590 bool GB_Index_multiply // true if ok, false if overflow
591 (
592 GrB_Index *restrict c, // c = a*b, or zero if overflow occurs
593 const int64_t a,
594 const int64_t b
595 ) ;
596
597 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
598 bool GB_size_t_multiply // true if ok, false if overflow
599 (
600 size_t *c, // c = a*b, or zero if overflow occurs
601 const size_t a,
602 const size_t b
603 ) ;
604
605 GrB_Info GB_extract_vector_list // extract vector list from a matrix
606 (
607 // output:
608 int64_t *restrict J, // size nnz(A) or more
609 // input:
610 const GrB_Matrix A,
611 GB_Context Context
612 ) ;
613
614 GrB_Info GB_extractTuples // extract all tuples from a matrix
615 (
616 GrB_Index *I_out, // array for returning row indices of tuples
617 GrB_Index *J_out, // array for returning col indices of tuples
618 void *X, // array for returning values of tuples
619 GrB_Index *p_nvals, // I,J,X size on input; # tuples on output
620 const GB_Type_code xcode, // type of array X
621 const GrB_Matrix A, // matrix to extract tuples from
622 GB_Context Context
623 ) ;
624
625 GrB_Info GB_Monoid_new // create a monoid
626 (
627 GrB_Monoid *monoid, // handle of monoid to create
628 GrB_BinaryOp op, // binary operator of the monoid
629 const void *identity, // identity value
630 const void *terminal, // terminal value, if any (may be NULL)
631 const GB_Type_code idcode, // identity and terminal type code
632 GB_Context Context
633 ) ;
634
635 GrB_Info GB_Semiring_new // create a semiring
636 (
637 GrB_Semiring semiring, // semiring to create
638 GrB_Monoid add, // additive monoid of the semiring
639 GrB_BinaryOp multiply // multiply operator of the semiring
640 ) ;
641
642 //------------------------------------------------------------------------------
643
644 GrB_Info GB_setElement // set a single entry, C(row,col) = scalar
645 (
646 GrB_Matrix C, // matrix to modify
647 void *scalar, // scalar to set
648 const GrB_Index row, // row index
649 const GrB_Index col, // column index
650 const GB_Type_code scalar_code, // type of the scalar
651 GB_Context Context
652 ) ;
653
654 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
655 GrB_Info GB_block // apply all pending computations if blocking mode enabled
656 (
657 GrB_Matrix A,
658 GB_Context Context
659 ) ;
660
661 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
662 bool GB_op_is_second // return true if op is SECOND, of the right type
663 (
664 GrB_BinaryOp op,
665 GrB_Type type
666 ) ;
667
668
669 //------------------------------------------------------------------------------
670
671 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
672 char *GB_code_string // return a static string for a type name
673 (
674 const GB_Type_code code // code to convert to string
675 ) ;
676
677 GrB_Info GB_resize // change the size of a matrix
678 (
679 GrB_Matrix A, // matrix to modify
680 const GrB_Index nrows_new, // new number of rows in matrix
681 const GrB_Index ncols_new, // new number of columns in matrix
682 GB_Context Context
683 ) ;
684
685 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
686 int64_t GB_nvec_nonempty // return # of non-empty vectors
687 (
688 const GrB_Matrix A, // input matrix to examine
689 GB_Context Context
690 ) ;
691
692 GrB_Info GB_conform_hyper // conform a matrix to sparse/hypersparse
693 (
694 GrB_Matrix A, // matrix to conform
695 GB_Context Context
696 ) ;
697
698 GrB_Info GB_hyper_prune
699 (
700 // output, not allocated on input:
701 int64_t *restrict *p_Ap, size_t *p_Ap_size, // size nvec+1
702 int64_t *restrict *p_Ah, size_t *p_Ah_size, // size nvec
703 int64_t *p_nvec, // # of vectors, all nonempty
704 // input, not modified
705 const int64_t *Ap_old, // size nvec_old+1
706 const int64_t *Ah_old, // size nvec_old
707 const int64_t nvec_old, // original number of vectors
708 GB_Context Context
709 ) ;
710
711 GrB_Info GB_hypermatrix_prune
712 (
713 GrB_Matrix A, // matrix to prune
714 GB_Context Context
715 ) ;
716
717 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
718 void GB_cast_array // typecast an array
719 (
720 GB_void *Cx, // output array
721 const GB_Type_code code1, // type code for Cx
722 GB_void *Ax, // input array
723 const GB_Type_code code2, // type code for Ax
724 const int8_t *restrict Ab, // bitmap for Ax
725 const size_t user_size, // size of Ax and Cx if user-defined
726 const int64_t anz, // number of entries in Cx and Ax
727 const int nthreads // number of threads to use
728 ) ;
729
730 //------------------------------------------------------------------------------
731 // boiler plate macros for checking inputs and returning if an error occurs
732 //------------------------------------------------------------------------------
733
734 // Functions use these macros to check/get their inputs and return an error
735 // if something has gone wrong.
736
737 #define GB_OK(method) \
738 { \
739 info = method ; \
740 if (info != GrB_SUCCESS) \
741 { \
742 GB_FREE_ALL ; \
743 return (info) ; \
744 } \
745 }
746
747 // check if a required arg is NULL
748 #define GB_RETURN_IF_NULL(arg) \
749 if ((arg) == NULL) \
750 { \
751 /* the required arg is NULL */ \
752 return (GrB_NULL_POINTER) ; \
753 }
754
755 // arg may be NULL, but if non-NULL then it must be initialized
756 #define GB_RETURN_IF_FAULTY(arg) \
757 if ((arg) != NULL && (arg)->magic != GB_MAGIC) \
758 { \
759 if ((arg)->magic == GB_MAGIC2) \
760 { \
761 /* optional arg is not NULL, but invalid */ \
762 return (GrB_INVALID_OBJECT) ; \
763 } \
764 else \
765 { \
766 /* optional arg is not NULL, but not initialized */ \
767 return (GrB_UNINITIALIZED_OBJECT) ; \
768 } \
769 }
770
771 // arg must not be NULL, and it must be initialized
772 #define GB_RETURN_IF_NULL_OR_FAULTY(arg) \
773 GB_RETURN_IF_NULL (arg) ; \
774 GB_RETURN_IF_FAULTY (arg) ;
775
776 // positional ops not supported for use as accum operators
777 #define GB_RETURN_IF_FAULTY_OR_POSITIONAL(accum) \
778 { \
779 GB_RETURN_IF_FAULTY (accum) ; \
780 if (GB_OP_IS_POSITIONAL (accum)) \
781 { \
782 GB_ERROR (GrB_DOMAIN_MISMATCH, \
783 "Positional op z=%s(x,y) not supported as accum\n", \
784 accum->name) ; \
785 } \
786 }
787
788 // check the descriptor and extract its contents; also copies
789 // nthreads_max and chunk from the descriptor to the Context
790 #define GB_GET_DESCRIPTOR(info,desc,dout,dmc,dms,d0,d1,dalgo,dsort) \
791 GrB_Info info ; \
792 bool dout, dmc, dms, d0, d1 ; \
793 int dsort ; \
794 GrB_Desc_Value dalgo ; \
795 /* if desc is NULL then defaults are used. This is OK */ \
796 info = GB_Descriptor_get (desc, &dout, &dmc, &dms, &d0, &d1, &dalgo, \
797 &dsort, Context) ; \
798 if (info != GrB_SUCCESS) \
799 { \
800 /* desc not NULL, but uninitialized or an invalid object */ \
801 return (info) ; \
802 }
803
804 // C<M>=Z ignores Z if an empty mask is complemented, or if M is full,
805 // structural and complemented, so return from the method without computing
806 // anything. Clear C if replace option is true.
807 #define GB_RETURN_IF_QUICK_MASK(C, C_replace, M, Mask_comp, Mask_struct) \
808 if (Mask_comp && (M == NULL || (GB_IS_FULL (M) && Mask_struct))) \
809 { \
810 /* C<!NULL>=NULL since result does not depend on computing Z */ \
811 return (C_replace ? GB_clear (C, Context) : GrB_SUCCESS) ; \
812 }
813
814 // GB_MASK_VERY_SPARSE is true if C<M>=A+B, C<M>=A.*B or C<M>=accum(C,T) is
815 // being computed, and the mask M is very sparse compared with A and B.
816 #define GB_MASK_VERY_SPARSE(alpha,M,A,B) \
817 ((alpha) * GB_NNZ (M) < GB_NNZ (A) + GB_NNZ (B))
818
819 //------------------------------------------------------------------------------
820 // Pending upddate and zombies
821 //------------------------------------------------------------------------------
822
823 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
824 GrB_Info GB_Matrix_wait // finish all pending computations
825 (
826 GrB_Matrix A, // matrix with pending computations
827 const char *name, // name of the matrix
828 GB_Context Context
829 ) ;
830
831 GrB_Info GB_unjumble // unjumble a matrix
832 (
833 GrB_Matrix A, // matrix to unjumble
834 GB_Context Context
835 ) ;
836
837 // true if a matrix has pending tuples
838 #define GB_PENDING(A) ((A) != NULL && (A)->Pending != NULL)
839
840 // true if a matrix is allowed to have pending tuples
841 #define GB_PENDING_OK(A) (GB_PENDING (A) || !GB_PENDING (A))
842
843 // true if a matrix has zombies
844 #define GB_ZOMBIES(A) ((A) != NULL && (A)->nzombies > 0)
845
846 // true if a matrix is allowed to have zombies
847 #define GB_ZOMBIES_OK(A) (((A) == NULL) || ((A) != NULL && (A)->nzombies >= 0))
848
849 // true if a matrix has pending tuples or zombies
850 #define GB_PENDING_OR_ZOMBIES(A) (GB_PENDING (A) || GB_ZOMBIES (A))
851
852 // true if a matrix is jumbled
853 #define GB_JUMBLED(A) ((A) != NULL && (A)->jumbled)
854
855 // true if a matrix is allowed to be jumbled
856 #define GB_JUMBLED_OK(A) (GB_JUMBLED (A) || !GB_JUMBLED (A))
857
858 // true if a matrix has pending tuples, zombies, or is jumbled
859 #define GB_ANY_PENDING_WORK(A) \
860 (GB_PENDING (A) || GB_ZOMBIES (A) || GB_JUMBLED (A))
861
862 // wait if condition holds
863 #define GB_WAIT_IF(condition,A,name) \
864 { \
865 if (condition) \
866 { \
867 GrB_Info info ; \
868 GB_OK (GB_Matrix_wait ((GrB_Matrix) A, name, Context)) ; \
869 } \
870 }
871
872 // do all pending work: zombies, pending tuples, and unjumble
873 #define GB_MATRIX_WAIT(A) GB_WAIT_IF (GB_ANY_PENDING_WORK (A), A, GB_STR (A))
874
875 // do all pending work if pending tuples; zombies and jumbled are OK
876 #define GB_MATRIX_WAIT_IF_PENDING(A) GB_WAIT_IF (GB_PENDING (A), A, GB_STR (A))
877
878 // delete zombies and assemble any pending tuples; jumbled is O
879 #define GB_MATRIX_WAIT_IF_PENDING_OR_ZOMBIES(A) \
880 GB_WAIT_IF (GB_PENDING_OR_ZOMBIES (A), A, GB_STR (A))
881
882 // ensure A is not jumbled
883 #define GB_MATRIX_WAIT_IF_JUMBLED(A) GB_WAIT_IF (GB_JUMBLED (A), A, GB_STR (A))
884
885 // true if a matrix has no entries; zombies OK
886 #define GB_IS_EMPTY(A) ((GB_NNZ (A) == 0) && !GB_PENDING (A))
887
888 //------------------------------------------------------------------------------
889
890 #include "GB_convert.h"
891 #include "GB_ops.h"
892
893 //------------------------------------------------------------------------------
894 // CUDA (DRAFT: in progress)
895 //------------------------------------------------------------------------------
896
897 #include "GB_cuda_gateway.h"
898
899 #endif
900
901