1 //------------------------------------------------------------------------------
2 // GB_mex_export_import: export and then reimport a matrix
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 // format:
11 //  0: standard CSR
12 //  1: standard CSC
13 //  3: hyper CSR
14 //  4: hyper CSC
15 
16 #include "GB_mex.h"
17 
18 #define USAGE "C = GB_mex_export_import (A, format_matrix, format_export)"
19 
20 #define FREE_WORK                                               \
21 {                                                               \
22     REMOVE (Cp) ; if (Cp != NULL) mxFree (Cp) ; Cp = NULL ;     \
23     REMOVE (Ch) ; if (Ch != NULL) mxFree (Ch) ; Ch = NULL ;     \
24     REMOVE (Cb) ; if (Cb != NULL) mxFree (Cb) ; Cb = NULL ;     \
25     REMOVE (Ci) ; if (Ci != NULL) mxFree (Ci) ; Ci = NULL ;     \
26     REMOVE (Cx) ; if (Cx != NULL) mxFree (Cx) ; Cx = NULL ;     \
27     GrB_Matrix_free_(&C) ;                                      \
28 }
29 
30 #define FREE_ALL                        \
31 {                                       \
32     FREE_WORK ;                         \
33     GrB_Matrix_free_(&A) ;              \
34     GB_mx_put_global (true) ;           \
35 }
36 
37 #define OK(method)                              \
38 {                                               \
39     info = method ;                             \
40     if (info != GrB_SUCCESS)                    \
41     {                                           \
42         FREE_WORK ;                             \
43         return (info) ;                         \
44     }                                           \
45 }
46 
47 GrB_Matrix A = NULL ;
48 GrB_Matrix C = NULL ;
49 GrB_Index *Cp = NULL, *Ch = NULL, *Ci = NULL ;
50 GB_void *Cx = NULL ;
51 int8_t *Cb = NULL ;
52 GB_Context Context = NULL ;
53 GrB_Index nvec = 0, nvals = 0, nrows = 0, ncols = 0 ;
54 
55 GrB_Index Cp_size = 0 ;
56 GrB_Index Ch_size = 0 ;
57 GrB_Index Cb_size = 0 ;
58 GrB_Index Ci_size = 0 ;
59 GrB_Index Cx_size = 0 ;
60 bool is_uniform = false ;
61 
62 int64_t ignore = -1 ;
63 bool jumbled = false ;
64 GrB_Type type = NULL ;
65 GrB_Info info = GrB_SUCCESS ;
66 
67 GrB_Info export_import ( int format_matrix, int format_export) ;
68 GrB_Info vector_export_import ( int format_matrix, int format_export) ;
69 
70 //------------------------------------------------------------------------------
71 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])72 void mexFunction
73 (
74     int nargout,
75     mxArray *pargout [ ],
76     int nargin,
77     const mxArray *pargin [ ]
78 )
79 {
80 
81     bool malloc_debug = GB_mx_get_global (true) ;
82 
83     // check inputs
84     if (nargout > 1 || nargin != 3)
85     {
86         mexErrMsgTxt ("Usage: " USAGE) ;
87     }
88 
89     // get A (shallow copy)
90     {
91         A = GB_mx_mxArray_to_Matrix (pargin [0], "A input", false, true) ;
92         if (A == NULL)
93         {
94             FREE_ALL ;
95             mexErrMsgTxt ("A failed") ;
96         }
97     }
98 
99     // get matrix format (1 to 8, and -1 to -8)
100     int GET_SCALAR (1, int, format_matrix, 0) ;
101     bool do_matrix = (format_matrix > 0) ;
102     if (format_matrix < 0)
103     {
104         format_matrix = -format_matrix ;
105     }
106 
107     // get export/import format (0 to 11)
108     int GET_SCALAR (2, int, format_export, 0) ;
109 
110     #define GET_DEEP_COPY   GrB_Matrix_dup (&C, A) ;
111     #define FREE_DEEP_COPY  GrB_Matrix_free (&C) ;
112 
113     // C = deep copy of A
114     GET_DEEP_COPY ;
115 
116     // convert matrix, export, then import
117     if (do_matrix)
118     {
119         METHOD (export_import (format_matrix, format_export)) ;
120     }
121 
122     FREE_DEEP_COPY ;
123     GET_DEEP_COPY ;
124 
125     // convert vector, export, then import, if C can be cast as a GrB_Vector
126     if (GB_VECTOR_OK (C))
127     {
128         METHOD (vector_export_import (format_matrix, format_export)) ;
129     }
130 
131     // return C to MATLAB as a struct and free the GraphBLAS C
132     pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C output", true) ;
133     FREE_ALL ;
134 }
135 
136 
137 
138 //------------------------------------------------------------------------------
139 
export_import(int format_matrix,int format_export)140 GrB_Info export_import
141 (
142     int format_matrix,
143     int format_export
144 )
145 {
146 
147     //--------------------------------------------------------------------------
148     // convert C to the requested format
149     //--------------------------------------------------------------------------
150 
151     switch (format_matrix)
152     {
153 
154         //----------------------------------------------------------------------
155         case 1 :    // standard CSR
156         //----------------------------------------------------------------------
157 
158             OK (GxB_Matrix_Option_set_(C, GxB_HYPER_SWITCH, GxB_NEVER_HYPER)) ;
159             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL, GxB_SPARSE)) ;
160             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_ROW)) ;
161             break ;
162 
163         //----------------------------------------------------------------------
164         case 2 :    // standard CSC
165         //----------------------------------------------------------------------
166 
167             OK (GxB_Matrix_Option_set_(C, GxB_HYPER_SWITCH, GxB_NEVER_HYPER)) ;
168             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL, GxB_SPARSE)) ;
169             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_COL)) ;
170             break ;
171 
172         //----------------------------------------------------------------------
173         case 3 :    // hypersparse CSR
174         //----------------------------------------------------------------------
175 
176             OK (GxB_Matrix_Option_set_(C, GxB_HYPER_SWITCH, GxB_ALWAYS_HYPER)) ;
177             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL,
178                 GxB_HYPERSPARSE)) ;
179             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_ROW)) ;
180             break ;
181 
182         //----------------------------------------------------------------------
183         case 4 :    // hypersparse CSC
184         //----------------------------------------------------------------------
185 
186             OK (GxB_Matrix_Option_set_(C, GxB_HYPER_SWITCH, GxB_ALWAYS_HYPER)) ;
187             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL,
188                 GxB_HYPERSPARSE)) ;
189             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_COL)) ;
190             break ;
191 
192         //----------------------------------------------------------------------
193         case 5 :    // bitmapR
194         //----------------------------------------------------------------------
195 
196             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL, GxB_BITMAP)) ;
197             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_ROW)) ;
198             break ;
199 
200         //----------------------------------------------------------------------
201         case 6 :    // bitmapC
202         //----------------------------------------------------------------------
203 
204             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL, GxB_BITMAP)) ;
205             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_COL)) ;
206             break ;
207 
208         //----------------------------------------------------------------------
209         case 7 :    // FullR
210         //----------------------------------------------------------------------
211 
212             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL, GxB_FULL)) ;
213             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_ROW)) ;
214             break ;
215 
216         //----------------------------------------------------------------------
217         case 8 :    // FullC
218         //----------------------------------------------------------------------
219 
220             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL, GxB_FULL)) ;
221             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_COL)) ;
222             break ;
223 
224         //----------------------------------------------------------------------
225         case 9 :    // to control == 11, then bitmap
226         //----------------------------------------------------------------------
227 
228             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL, GxB_BITMAP)) ;
229             OK (GxB_Matrix_Option_set_(C, GxB_SPARSITY_CONTROL,
230                GxB_HYPERSPARSE + GxB_SPARSE + GxB_FULL)) ;
231             OK (GxB_Matrix_Option_set_(C, GxB_FORMAT, GxB_BY_COL)) ;
232             break ;
233 
234         default : mexErrMsgTxt ("invalid mtx format") ;
235     }
236 
237     //--------------------------------------------------------------------------
238     // export then import
239     //--------------------------------------------------------------------------
240 
241     switch (format_export)
242     {
243 
244         //----------------------------------------------------------------------
245         case 0 :    // standard CSR
246         //----------------------------------------------------------------------
247 
248             OK (GxB_Matrix_export_CSR (&C, &type, &nrows, &ncols,
249                 &Cp, &Ci, &Cx, &Cp_size, &Ci_size, &Cx_size, &is_uniform,
250                 &jumbled, NULL)) ;
251 
252             OK (GxB_Matrix_import_CSR (&C, type, nrows, ncols,
253                 &Cp, &Ci, &Cx, Cp_size, Ci_size, Cx_size, is_uniform,
254                 jumbled, NULL)) ;
255 
256             break ;
257 
258         //----------------------------------------------------------------------
259         case 1 :    // standard CSC
260         //----------------------------------------------------------------------
261 
262             OK (GxB_Matrix_export_CSC (&C, &type, &nrows, &ncols,
263                 &Cp, &Ci, &Cx, &Cp_size, &Ci_size, &Cx_size, &is_uniform,
264                 &jumbled, NULL)) ;
265 
266             OK (GxB_Matrix_import_CSC (&C, type, nrows, ncols,
267                 &Cp, &Ci, &Cx, Cp_size, Ci_size, Cx_size, is_uniform,
268                 jumbled, NULL)) ;
269 
270             break ;
271 
272         //----------------------------------------------------------------------
273         case 2 :    // hypersparse CSR
274         //----------------------------------------------------------------------
275 
276             OK (GxB_Matrix_export_HyperCSR (&C, &type, &nrows, &ncols,
277                 &Cp, &Ch, &Ci, &Cx,
278                 &Cp_size, &Ch_size, &Ci_size, &Cx_size, &is_uniform,
279                 &nvec, &jumbled, NULL)) ;
280 
281             OK (GxB_Matrix_import_HyperCSR (&C, type, nrows, ncols,
282                 &Cp, &Ch, &Ci, &Cx,
283                 Cp_size, Ch_size, Ci_size, Cx_size, is_uniform,
284                 nvec, jumbled, NULL)) ;
285 
286             break ;
287 
288         //----------------------------------------------------------------------
289         case 3 :    // hypersparse CSC
290         //----------------------------------------------------------------------
291 
292             OK (GxB_Matrix_export_HyperCSC (&C, &type, &nrows, &ncols,
293                 &Cp, &Ch, &Ci, &Cx,
294                 &Cp_size, &Ch_size, &Ci_size, &Cx_size, &is_uniform,
295                 &nvec, &jumbled, NULL)) ;
296 
297             OK (GxB_Matrix_import_HyperCSC (&C, type, nrows, ncols,
298                 &Cp, &Ch, &Ci, &Cx,
299                 Cp_size, Ch_size, Ci_size, Cx_size, is_uniform,
300                 nvec, jumbled, NULL)) ;
301 
302             break ;
303 
304         //----------------------------------------------------------------------
305         case 4 :    // bitmapR
306         //----------------------------------------------------------------------
307 
308             OK (GxB_Matrix_export_BitmapR (&C, &type, &nrows, &ncols,
309                 &Cb, &Cx, &Cb_size, &Cx_size, &is_uniform, &nvals, NULL)) ;
310 
311             OK (GxB_Matrix_import_BitmapR (&C, type, nrows, ncols,
312                 &Cb, &Cx, Cb_size, Cx_size, is_uniform, nvals, NULL)) ;
313 
314             break ;
315 
316         //----------------------------------------------------------------------
317         case 5 :    // bitmapC
318         //----------------------------------------------------------------------
319 
320             OK (GxB_Matrix_export_BitmapC (&C, &type, &nrows, &ncols,
321                 &Cb, &Cx, &Cb_size, &Cx_size, &is_uniform, &nvals, NULL)) ;
322 
323             OK (GxB_Matrix_import_BitmapC (&C, type, nrows, ncols,
324                 &Cb, &Cx, Cb_size, Cx_size, is_uniform, nvals, NULL)) ;
325 
326             break ;
327 
328         //----------------------------------------------------------------------
329         case 6 :    // FullR
330         //----------------------------------------------------------------------
331 
332             OK (GxB_Matrix_export_FullR (&C, &type, &nrows, &ncols,
333                 &Cx, &Cx_size, &is_uniform, NULL)) ;
334 
335             OK (GxB_Matrix_import_FullR (&C, type, nrows, ncols,
336                 &Cx, Cx_size, is_uniform, NULL)) ;
337 
338             break ;
339 
340         //----------------------------------------------------------------------
341         case 7 :    // FullC
342         //----------------------------------------------------------------------
343 
344             OK (GxB_Matrix_export_FullC (&C, &type, &nrows, &ncols,
345                 &Cx, &Cx_size, &is_uniform, NULL)) ;
346 
347             OK (GxB_Matrix_import_FullC (&C, type, nrows, ncols,
348                 &Cx, Cx_size, is_uniform, NULL)) ;
349 
350             break ;
351 
352         //----------------------------------------------------------------------
353         case 8 :    // standard CSR, not jumbled
354         //----------------------------------------------------------------------
355 
356             OK (GxB_Matrix_export_CSR (&C, &type, &nrows, &ncols,
357                 &Cp, &Ci, &Cx, &Cp_size, &Ci_size, &Cx_size, &is_uniform,
358                 NULL, NULL)) ;
359 
360             OK (GxB_Matrix_import_CSR (&C, type, nrows, ncols,
361                 &Cp, &Ci, &Cx, Cp_size, Ci_size, Cx_size, is_uniform,
362                 false, NULL)) ;
363 
364             break ;
365 
366         //----------------------------------------------------------------------
367         case 9 :    // standard CSC, not jumbled
368         //----------------------------------------------------------------------
369 
370             OK (GxB_Matrix_export_CSC (&C, &type, &nrows, &ncols,
371                 &Cp, &Ci, &Cx, &Cp_size, &Ci_size, &Cx_size, &is_uniform,
372                 NULL, NULL)) ;
373 
374             OK (GxB_Matrix_import_CSC (&C, type, nrows, ncols,
375                 &Cp, &Ci, &Cx, Cp_size, Ci_size, Cx_size, is_uniform,
376                 false, NULL)) ;
377 
378             break ;
379 
380         //----------------------------------------------------------------------
381         case 10 :    // hypersparse CSR, not jumbled
382         //----------------------------------------------------------------------
383 
384             OK (GxB_Matrix_export_HyperCSR (&C, &type, &nrows, &ncols,
385                 &Cp, &Ch, &Ci, &Cx,
386                 &Cp_size, &Ch_size, &Ci_size, &Cx_size, &is_uniform,
387                 &nvec, NULL, NULL)) ;
388 
389             OK (GxB_Matrix_import_HyperCSR (&C, type, nrows, ncols,
390                 &Cp, &Ch, &Ci, &Cx,
391                 Cp_size, Ch_size, Ci_size, Cx_size, is_uniform,
392                 nvec, false, NULL)) ;
393 
394             break ;
395 
396         //----------------------------------------------------------------------
397         case 11 :    // hypersparse CSC, not jumbled
398         //----------------------------------------------------------------------
399 
400             OK (GxB_Matrix_export_HyperCSC (&C, &type, &nrows, &ncols,
401                 &Cp, &Ch, &Ci, &Cx,
402                 &Cp_size, &Ch_size, &Ci_size, &Cx_size, &is_uniform,
403                 &nvec, NULL, NULL)) ;
404 
405             OK (GxB_Matrix_import_HyperCSC (&C, type, nrows, ncols,
406                 &Cp, &Ch, &Ci, &Cx,
407                 Cp_size, Ch_size, Ci_size, Cx_size, is_uniform,
408                 nvec, false, NULL)) ;
409 
410             break ;
411 
412 
413         default : mexErrMsgTxt ("invalid export format") ;
414     }
415 
416     return (GrB_SUCCESS) ;
417 }
418 
419 //------------------------------------------------------------------------------
420 
vector_export_import(int format_matrix,int format_export)421 GrB_Info vector_export_import
422 (
423     int format_matrix,
424     int format_export
425 )
426 {
427 
428     //--------------------------------------------------------------------------
429     // convert C as a vector to the requested format, if available
430     //--------------------------------------------------------------------------
431 
432     switch (format_matrix)
433     {
434 
435         //----------------------------------------------------------------------
436         case 1 :    // standard CSR
437         //----------------------------------------------------------------------
438 
439             return (GrB_SUCCESS) ;
440 
441         //----------------------------------------------------------------------
442         case 2 :    // standard CSC
443         //----------------------------------------------------------------------
444 
445             OK (GxB_Vector_Option_set_((GrB_Vector) C,
446                 GxB_SPARSITY_CONTROL, GxB_SPARSE)) ;
447             break ;
448 
449         //----------------------------------------------------------------------
450         case 3 :    // hypersparse CSR
451         //----------------------------------------------------------------------
452 
453             return (GrB_SUCCESS) ;
454 
455         //----------------------------------------------------------------------
456         case 4 :    // hypersparse CSC (will be sparse, not hypersparse)
457         //----------------------------------------------------------------------
458 
459             OK (GxB_Vector_Option_set_((GrB_Vector) C,
460                 GxB_SPARSITY_CONTROL, GxB_HYPERSPARSE)) ;
461             break ;
462 
463         //----------------------------------------------------------------------
464         case 5 :    // bitmapR
465         //----------------------------------------------------------------------
466 
467             return (GrB_SUCCESS) ;
468 
469         //----------------------------------------------------------------------
470         case 6 :    // bitmapC
471         case 9 :    // bitmapC
472         //----------------------------------------------------------------------
473 
474             OK (GxB_Vector_Option_set_((GrB_Vector) C,
475                 GxB_SPARSITY_CONTROL, GxB_BITMAP)) ;
476             break ;
477 
478         //----------------------------------------------------------------------
479         case 7 :    // FullR
480         //----------------------------------------------------------------------
481 
482             return (GrB_SUCCESS) ;
483 
484         //----------------------------------------------------------------------
485         case 8 :    // FullC
486         //----------------------------------------------------------------------
487 
488             OK (GxB_Vector_Option_set_((GrB_Vector) C,
489                 GxB_SPARSITY_CONTROL, GxB_FULL)) ;
490             break ;
491 
492         default : mexErrMsgTxt ("invalid format") ;
493     }
494 
495     //--------------------------------------------------------------------------
496     // export then import
497     //--------------------------------------------------------------------------
498 
499     switch (format_export)
500     {
501 
502         //----------------------------------------------------------------------
503         case 0 :    // standard CSR
504         //----------------------------------------------------------------------
505 
506             return (GrB_SUCCESS) ;
507 
508         //----------------------------------------------------------------------
509         case 1 :    // standard CSC
510         //----------------------------------------------------------------------
511 
512             OK (GxB_Vector_export_CSC ((GrB_Vector *) &C, &type, &nrows,
513                 &Ci, &Cx, &Ci_size, &Cx_size, &is_uniform,
514                 &nvals, &jumbled, NULL)) ;
515 
516             OK (GxB_Vector_import_CSC ((GrB_Vector *) &C, type, nrows,
517                 &Ci, &Cx, Ci_size, Cx_size, is_uniform,
518                 nvals, jumbled, NULL)) ;
519 
520             break ;
521 
522         //----------------------------------------------------------------------
523         case 2 :    // hypersparse CSR
524         //----------------------------------------------------------------------
525 
526             return (GrB_SUCCESS) ;
527 
528         //----------------------------------------------------------------------
529         case 3 :    // hypersparse CSC
530         //----------------------------------------------------------------------
531 
532             return (GrB_SUCCESS) ;
533 
534         //----------------------------------------------------------------------
535         case 4 :    // bitmapR
536         //----------------------------------------------------------------------
537 
538             return (GrB_SUCCESS) ;
539 
540         //----------------------------------------------------------------------
541         case 5 :    // bitmapC
542         //----------------------------------------------------------------------
543 
544             OK (GxB_Vector_export_Bitmap ((GrB_Vector *) &C, &type, &nrows,
545                 &Cb, &Cx, &Cb_size, &Cx_size, &is_uniform, &nvals, NULL)) ;
546 
547             OK (GxB_Vector_import_Bitmap ((GrB_Vector *) &C, type, nrows,
548                 &Cb, &Cx, Cb_size, Cx_size, is_uniform, nvals, NULL)) ;
549 
550             break ;
551 
552         //----------------------------------------------------------------------
553         case 6 :    // FullR
554         //----------------------------------------------------------------------
555 
556             return (GrB_SUCCESS) ;
557 
558         //----------------------------------------------------------------------
559         case 7 :    // FullC
560         //----------------------------------------------------------------------
561 
562             OK (GxB_Vector_export_Full ((GrB_Vector *) &C, &type, &nrows,
563                 &Cx, &Cx_size, &is_uniform, NULL)) ;
564 
565             OK (GxB_Vector_import_Full ((GrB_Vector *) &C, type, nrows,
566                 &Cx, Cx_size, is_uniform, NULL)) ;
567 
568             break ;
569 
570         //----------------------------------------------------------------------
571         case 8 :    // standard CSR, not jumbled
572         //----------------------------------------------------------------------
573 
574             return (GrB_SUCCESS) ;
575 
576         //----------------------------------------------------------------------
577         case 9 :    // standard CSC, not jumbled
578         //----------------------------------------------------------------------
579 
580             OK (GxB_Vector_export_CSC ((GrB_Vector *) &C, &type, &nrows,
581                 &Ci, &Cx, &Ci_size, &Cx_size, &is_uniform,
582                 &nvals, NULL, NULL)) ;
583 
584             OK (GxB_Vector_import_CSC ((GrB_Vector *) &C, type, nrows,
585                 &Ci, &Cx, Ci_size, Cx_size, is_uniform,
586                 nvals, false, NULL)) ;
587 
588             break ;
589 
590         //----------------------------------------------------------------------
591         case 10 :    // hypersparse CSR, not jumbled
592         //----------------------------------------------------------------------
593 
594             return (GrB_SUCCESS) ;
595 
596         //----------------------------------------------------------------------
597         case 11 :    // hypersparse CSC, not jumbled
598         //----------------------------------------------------------------------
599 
600             return (GrB_SUCCESS) ;
601 
602         default : mexErrMsgTxt ("invalid format") ;
603     }
604 
605     return (GrB_SUCCESS) ;
606 }
607 
608