1 //------------------------------------------------------------------------------
2 // gb_matlab.h: definitions for MATLAB interface for SuiteSparse:GraphBLAS
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: GPL-3.0-or-later
7
8 //------------------------------------------------------------------------------
9
10 // This MATLAB interface depends heavily on internal details of the
11 // SuiteSparse:GraphBLAS library. Thus, GB.h is #include'd, not just
12 // GraphBLAS.h.
13
14 #ifndef GB_MATLAB_H
15 #define GB_MATLAB_H
16
17 #include "GB_matlab_helper.h"
18 #include "mex.h"
19 #include <ctype.h>
20
21 //------------------------------------------------------------------------------
22 // error handling and test coverage
23 //------------------------------------------------------------------------------
24
25 #ifdef GBCOV
26 #define GBCOV_MAX 1000
27 extern int64_t gbcov [GBCOV_MAX] ;
28 extern int gbcov_max ;
29 void gbcov_get (void) ;
30 void gbcov_put (void) ;
31 #define GB_COV_PUT gbcov_put ( )
32 #else
33 #define GB_COV_PUT
34 #endif
35
36 #define GB_WRAPUP \
37 { \
38 GB_COV_PUT ; \
39 if (GB_Global_memtable_n ( ) != 0) \
40 { \
41 printf ("GrB memory leak!\n") ; \
42 GB_Global_memtable_dump ( ) ; \
43 mexErrMsgIdAndTxt ("GrB:error", "memory leak") ; \
44 } \
45 }
46
47 #define ERROR2(message, arg) \
48 { \
49 GB_COV_PUT ; \
50 mexErrMsgIdAndTxt ("GrB:error", message, arg) ; \
51 }
52
53 #define ERROR(message) \
54 { \
55 GB_COV_PUT ; \
56 mexErrMsgIdAndTxt ("GrB:error", message) ; \
57 }
58
59 #define CHECK_ERROR(error,message) if (error) ERROR (message) ;
60
61 #define OK(method) CHECK_ERROR ((method) != GrB_SUCCESS, "GrB:error") ;
62
63 #define OK1(C,method) \
64 { \
65 if ((method) != GrB_SUCCESS) \
66 { \
67 char *message ; \
68 GrB_Matrix_error (&message, C) ; \
69 ERROR (message) ; \
70 } \
71 }
72
73 //------------------------------------------------------------------------------
74 // basic macros
75 //------------------------------------------------------------------------------
76
77 // MATCH(s,t) compares two strings and returns true if equal
78 #define MATCH(s,t) (strcmp(s,t) == 0)
79
80 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
81
82 // largest integer representable as a double
83 #define FLINTMAX (((int64_t) 1) << 53)
84
85 //------------------------------------------------------------------------------
86 // typedefs
87 //------------------------------------------------------------------------------
88
89 typedef enum // output of GrB.methods
90 {
91 KIND_GRB = 0, // return a MATLAB struct containing a GrB_Matrix
92 KIND_SPARSE = 1, // return a MATLAB sparse matrix
93 KIND_FULL = 2, // return a MATLAB full matrix
94 KIND_MATLAB = 3 // return a MATLAB sparse or full matrix (full if all
95 // entries present, sparse otherwise)
96 }
97 kind_enum_t ;
98
99 // [I,J,X] = GrB.extracttuples (A, desc) can return I and J in three ways:
100 //
101 // one-based double: just like [I,J,X] = find (A)
102 // one-based int64: I and J are one-based, just as in MATLAB, but
103 // are int64.
104 // zero-based int64: I and J are zero-based, and int64. This is meant
105 // for internal use in GrB methods, but it is also
106 // the
107 //
108 // The descriptor is also used for GrB.build, GrB.extract, GrB.assign, and
109 // GrB.subassign. In that case, the type is determined by the input arrays I
110 // and J.
111 //
112 // desc.base can be one of several strings:
113 //
114 // 'default' the default is used
115 // 'zero-based' the type is always int64
116 // 'one-based' the type is inferred from the inputs I and J
117 // 'one-based int' the type is int64, and one-based
118 // 'one-based double' the type is double, and one-based
119 //
120 // Note that there is no option for zero-based double.
121
122 typedef enum // type of indices
123 {
124 BASE_DEFAULT = 0, // The type is determined automatically. It is
125 // BASE_1_DOUBLE, unless the dimensions are
126 // too big for a flint (max(size(A)) > flintmax). In
127 // that case, BASE_1_INT64 is used.
128 BASE_0_INT64 = 1, // indices are returned as zero-based int64 values
129 BASE_1_INT64 = 2, // indices are returned as one-based int64
130 BASE_1_DOUBLE = 3 // this is the typical default: one-based double
131 }
132 base_enum_t ;
133
134 //------------------------------------------------------------------------------
135 // gb_double_to_integer: convert a double to int64_t and check conversion
136 //------------------------------------------------------------------------------
137
gb_double_to_integer(double x)138 static inline int64_t gb_double_to_integer (double x)
139 {
140 int64_t i = (int64_t) x ;
141 CHECK_ERROR (x != (double) i, "index must be integer") ;
142 return (i) ;
143 }
144
145 //------------------------------------------------------------------------------
146 // function prototypes
147 //------------------------------------------------------------------------------
148
149 GrB_Type gb_mxarray_type // return the GrB_Type of a MATLAB matrix
150 (
151 const mxArray *X
152 ) ;
153
154 GrB_Type gb_mxstring_to_type // return the GrB_Type from a MATLAB string
155 (
156 const mxArray *S // MATLAB mxArray containing a string
157 ) ;
158
159 void gb_mxstring_to_string // copy a MATLAB string into a C string
160 (
161 char *string, // size at least maxlen+1
162 const size_t maxlen, // length of string
163 const mxArray *S, // MATLAB mxArray containing a string
164 const char *name // name of the mxArray
165 ) ;
166
167 GrB_Matrix gb_get_shallow // return a shallow copy of MATLAB sparse matrix
168 (
169 const mxArray *X
170 ) ;
171
172 GrB_Matrix gb_get_deep // return a deep GrB_Matrix copy of a MATLAB X
173 (
174 const mxArray *X // input MATLAB matrix (sparse or struct)
175 ) ;
176
177 GrB_Type gb_type_to_mxstring // return the MATLAB string from a GrB_Type
178 (
179 const GrB_Type type
180 ) ;
181
182 GrB_Matrix gb_typecast // C = (type) A, where C is deep
183 (
184 GrB_Matrix A, // may be shallow
185 GrB_Type type, // if NULL, copy but do not typecast
186 GxB_Format_Value fmt, // format of C
187 int sparsity // sparsity control for C, if 0 use A
188 ) ;
189
190 GrB_Matrix gb_new // create and empty matrix C
191 (
192 GrB_Type type, // type of C
193 GrB_Index nrows, // # of rows
194 GrB_Index ncols, // # of rows
195 GxB_Format_Value fmt, // requested format
196 int sparsity // sparsity control for C, 0 for default
197 ) ;
198
199 void gb_abort ( void ) ; // failure
200
201 int gb_flush ( void ) ; // flush mexPrintf output to MATLAB Command Window
202
203 void gb_usage // check usage and make sure GxB_init has been called
204 (
205 bool ok, // if false, then usage is not correct
206 const char *message // error message if usage is not correct
207 ) ;
208
209 void gb_find_dot // find 1st and 2nd dot ('.') in a string
210 (
211 int32_t position [2], // positions of one or two dots
212 const char *s // null-terminated string to search
213 ) ;
214
215 GrB_Type gb_string_to_type // return the GrB_Type from a string
216 (
217 const char *classname
218 ) ;
219
220 GrB_UnaryOp gb_mxstring_to_unop // return unary operator from a string
221 (
222 const mxArray *mxstring, // MATLAB string
223 const GrB_Type default_type // default type if not in the string
224 ) ;
225
226 GrB_UnaryOp gb_string_to_unop // return unary operator from a string
227 (
228 char *opstring, // string defining the operator
229 const GrB_Type default_type // default type if not in the string
230 ) ;
231
232 GrB_UnaryOp gb_string_and_type_to_unop // return op from string and type
233 (
234 const char *op_name, // name of the operator, as a string
235 const GrB_Type type, // type of the x,y inputs to the operator
236 const bool type_not_given // true if no type present in the string
237 ) ;
238
239 GrB_BinaryOp gb_mxstring_to_binop // return binary operator from a string
240 (
241 const mxArray *mxstring, // MATLAB string
242 const GrB_Type atype, // type of A
243 const GrB_Type btype // type of B
244 ) ;
245
246 GrB_BinaryOp gb_string_to_binop // return binary operator from a string
247 (
248 char *opstring, // string defining the operator
249 const GrB_Type atype, // type of A
250 const GrB_Type btype // type of B
251 ) ;
252
253 GrB_BinaryOp gb_string_and_type_to_binop // return op from string and type
254 (
255 const char *op_name, // name of the operator, as a string
256 const GrB_Type type, // type of the x,y inputs to the operator
257 const bool type_not_given // true if no type present in the string
258 ) ;
259
260 GrB_Semiring gb_mxstring_to_semiring // return semiring from a string
261 (
262 const mxArray *mxstring, // MATLAB string
263 const GrB_Type atype, // type of A
264 const GrB_Type btype // type of B
265 ) ;
266
267 GrB_Semiring gb_string_to_semiring // return a semiring from a string
268 (
269 char *semiring_string, // string defining the semiring
270 const GrB_Type atype, // type of A
271 const GrB_Type btype // type of B
272 ) ;
273
274 GrB_Semiring gb_semiring // built-in semiring, or NULL if error
275 (
276 const GrB_BinaryOp add, // add operator
277 const GrB_BinaryOp mult // multiply operator
278 ) ;
279
280 GrB_Descriptor gb_mxarray_to_descriptor // new descriptor, or NULL if none
281 (
282 const mxArray *desc_matlab, // MATLAB struct with possible descriptor
283 kind_enum_t *kind, // GrB, sparse, or full
284 GxB_Format_Value *fmt, // by row or by col
285 int *sparsity, // hypersparse/sparse/bitmap/full
286 base_enum_t *base // 0-based int, 1-based int, or 1-based double
287 ) ;
288
289 GrB_Matrix gb_expand_to_full // C = full (A), and typecast
290 (
291 const GrB_Matrix A, // input matrix to expand to full
292 GrB_Type type, // type of C, if NULL use the type of A
293 GxB_Format_Value fmt, // format of C
294 GrB_Matrix id // identity value, use zero if NULL
295 ) ;
296
297 mxArray *gb_export_to_mxstruct // return exported MATLAB struct G
298 (
299 GrB_Matrix *A_handle // matrix to export; freed on output
300 ) ;
301
302 mxArray *gb_export_to_mxsparse // return exported MATLAB sparse matrix S
303 (
304 GrB_Matrix *A_handle // matrix to export; freed on output
305 ) ;
306
307 mxArray *gb_export_to_mxfull // return exported MATLAB full matrix F
308 (
309 void **X_handle, // pointer to array to export
310 const GrB_Index nrows, // dimensions of F
311 const GrB_Index ncols,
312 GrB_Type type // type of the array
313 ) ;
314
315 mxArray *gb_export // return the exported MATLAB matrix or struct
316 (
317 GrB_Matrix *C_handle, // GrB_Matrix to export and free
318 kind_enum_t kind // GrB, sparse, or full
319 ) ;
320
321 GxB_SelectOp gb_string_to_selectop // return select operator from a string
322 (
323 char *opstring // string defining the operator
324 ) ;
325
326 GxB_SelectOp gb_mxstring_to_selectop // return select operator from a string
327 (
328 const mxArray *mxstring // MATLAB string
329 ) ;
330
331 bool gb_mxarray_is_scalar // true if MATLAB array is a scalar
332 (
333 const mxArray *S
334 ) ;
335
336 bool gb_mxarray_is_empty // true if MATLAB array is NULL, or 2D and 0-by-0
337 (
338 const mxArray *S
339 ) ;
340
341 void gb_mxfree // mxFree wrapper
342 (
343 void **p_handle // handle to pointer to be freed
344 ) ;
345
346 int64_t *gb_mxarray_to_list // return List of integers
347 (
348 const mxArray *mxList, // list to extract
349 base_enum_t base, // input is zero-based or one-based
350 bool *allocated, // true if output list was allocated
351 int64_t *len, // length of list
352 int64_t *List_max // max entry in the list, if computed
353 ) ;
354
355 GrB_Index *gb_mxcell_to_index // return index list I
356 (
357 const mxArray *I_cell, // MATLAB cell array
358 base_enum_t base, // I is one-based or zero-based
359 const GrB_Index n, // dimension of matrix being indexed
360 bool *I_allocated, // true if output array I is allocated
361 GrB_Index *ni // length (I)
362 ) ;
363
364 GrB_BinaryOp gb_first_binop // return GrB_FIRST_[type] operator
365 (
366 const GrB_Type type
367 ) ;
368
369 GrB_Monoid gb_binop_to_monoid // return monoid from a binary op
370 (
371 GrB_BinaryOp op
372 ) ;
373
374 GrB_Monoid gb_string_to_monoid // return monoid from a string
375 (
376 char *opstring, // string defining the operator
377 const GrB_Type type // default type if not in the string
378 ) ;
379
380 GrB_Monoid gb_mxstring_to_monoid // return monoid from a string
381 (
382 const mxArray *mxstring, // MATLAB string
383 const GrB_Type type // default type if not in the string
384 ) ;
385
386 bool gb_mxstring_to_format // true if a valid format is found
387 (
388 // input
389 const mxArray *mxformat, // MATLAB string, 'by row' or 'by col'
390 // output
391 GxB_Format_Value *fmt,
392 int *sparsity
393 ) ;
394
395 void gb_matrix_assign_scalar
396 (
397 GrB_Matrix C, // C can be of any type
398 const GrB_Matrix M,
399 const GrB_BinaryOp accum,
400 const GrB_Matrix A,
401 const GrB_Index *I,
402 const GrB_Index ni,
403 const GrB_Index *J,
404 const GrB_Index nj,
405 const GrB_Descriptor desc,
406 bool do_subassign // true: use GxB_subassign, false: GrB_assign
407 ) ;
408
409 void gb_assign // gbassign or gbsubassign mexFunctions
410 (
411 int nargout, // # output arguments for mexFunction
412 mxArray *pargout [ ], // output arguments for mexFunction
413 int nargin, // # input arguments for mexFunction
414 const mxArray *pargin [ ], // input arguments for mexFunction
415 bool do_subassign, // true: do subassign, false: do assign
416 const char *usage // usage string to print if error
417 ) ;
418
419 GrB_Matrix gb_by_col // return the matrix by column
420 (
421 GrB_Matrix *A_copy_handle, // copy made of A, stored by column, or NULL
422 GrB_Matrix A_input // input matrix, by row or column
423 ) ;
424
425 GxB_Format_Value gb_default_format // GxB_BY_ROW or GxB_BY_COL
426 (
427 GrB_Index nrows, // row vectors are stored by row
428 GrB_Index ncols // column vectors are stored by column
429 ) ;
430
431 bool gb_is_vector // true if A is a row or column vector
432 (
433 GrB_Matrix A // GrB_Matrix to query
434 ) ;
435
436 GxB_Format_Value gb_get_format // GxB_BY_ROW or GxB_BY_COL
437 (
438 GrB_Index cnrows, // C is cnrows-by-cncols
439 GrB_Index cncols,
440 GrB_Matrix A, // may be NULL
441 GrB_Matrix B, // may be NULL
442 GxB_Format_Value fmt_descriptor // may be GxB_NO_FORMAT
443 ) ;
444
445 GxB_Format_Value gb_get_sparsity // 1 to 15
446 (
447 GrB_Matrix A, // may be NULL
448 GrB_Matrix B, // may be NULL
449 int sparsity_default // may be 0
450 ) ;
451
452 bool gb_is_equal // true if A == B, false if A ~= B
453 (
454 GrB_Matrix A,
455 GrB_Matrix B
456 ) ;
457
458 bool gb_is_all // true if op (A,B) is all true, false otherwise
459 (
460 GrB_Matrix A,
461 GrB_Matrix B,
462 GrB_BinaryOp op
463 ) ;
464
465 bool gb_isnan32 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
466 bool gb_isnan64 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
467 bool gb_isnotnan32 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
468 bool gb_isnotnan64 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
469 bool gb_isnanfc32 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
470 bool gb_isnanfc64 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
471 bool gb_isnotnanfc32 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
472 bool gb_isnotnanfc64 (GrB_Index i, GrB_Index j, const void *x, const void *b) ;
473
474 void gb_get_mxargs
475 (
476 // input:
477 int nargin, // # input arguments for mexFunction
478 const mxArray *pargin [ ], // input arguments for mexFunction
479 const char *usage, // usage to print, if too many args appear
480 // output:
481 const mxArray *Matrix [4], // matrix arguments
482 int *nmatrices, // # of matrix arguments
483 const mxArray *String [2], // string arguments
484 int *nstrings, // # of string arguments
485 const mxArray *Cell [2], // cell array arguments
486 int *ncells, // # of cell array arguments
487 GrB_Descriptor *desc, // last argument is always the descriptor
488 base_enum_t *base, // desc.base
489 kind_enum_t *kind, // desc.kind
490 GxB_Format_Value *fmt, // desc.format : by row or by col
491 int *sparsity // desc.format : hypersparse/sparse/bitmap/full
492 ) ;
493
494 int64_t gb_norm_kind (const mxArray *arg) ;
495
496 double gb_norm // compute norm (A,kind)
497 (
498 GrB_Matrix A,
499 int64_t norm_kind // 0, 1, 2, INT64_MAX, or INT64_MIN
500 ) ;
501
502 GrB_Type gb_default_type // return the default type to use
503 (
504 const GrB_Type atype, // type of the A matrix
505 const GrB_Type btype // type of the B matrix
506 ) ;
507
508 bool gb_is_integer (const GrB_Type type) ;
509
510 bool gb_is_float (const GrB_Type type) ;
511
512 GrB_BinaryOp gb_round_binop (const GrB_Type type) ;
513
514 mxArray *gb_mxclass_to_mxstring (mxClassID class, bool is_complex) ;
515
516 #endif
517
518