1 //------------------------------------------------------------------------------
2 // GB_mex_export: test import/export
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 #include "GB_mex.h"
11 
12 #define USAGE "C = GB_mex_export (C, format, hyper, csc, dump, clear_nvec)"
13 
14 // If Ap, Ah, etc are exported, then they are not NULL and not in the global
15 // memtable.  If they are not exported, they are NULL, and are part of the
16 // matrix, and in the global memtable.
17 
18 #define FREE_WORK                                               \
19 {                                                               \
20     GrB_Matrix_free_(&C) ;                                      \
21     REMOVE (Ap) ; if (Ap != NULL) mxFree (Ap) ; Ap = NULL ;     \
22     REMOVE (Ah) ; if (Ah != NULL) mxFree (Ah) ; Ah = NULL ;     \
23     REMOVE (Ai) ; if (Ai != NULL) mxFree (Ai) ; Ai = NULL ;     \
24     REMOVE (Aj) ; if (Aj != NULL) mxFree (Aj) ; Aj = NULL ;     \
25     REMOVE (Ax) ; if (Ax != NULL) mxFree (Ax) ; Ax = NULL ;     \
26 }
27 
28 #define FREE_ALL                                                \
29 {                                                               \
30     FREE_WORK ;                                                 \
31     GB_mx_put_global (true) ;                                   \
32 }
33 
34 #define OK(method)                      \
35 {                                       \
36     info = method ;                     \
37     if (info != GrB_SUCCESS)            \
38     {                                   \
39         if (dump) printf ("method fail %d: %d\n", __LINE__, info) ; \
40         FREE_WORK ;                     \
41         return (info) ;                 \
42     }                                   \
43 }
44 
45 GrB_Vector v = NULL ;
46 GrB_Matrix C = NULL ;
47 GrB_Index *Ap = NULL ;
48 GrB_Index *Ah = NULL ;
49 GrB_Index *Ai = NULL ;
50 GrB_Index *Aj = NULL ;
51 GrB_Index nrows = 0 ;
52 GrB_Index ncols = 0 ;
53 GrB_Index nvals = 0 ;
54 GrB_Index nvec = 0 ;
55 GrB_Index Ai_size = 0 ;
56 GrB_Index Ax_size = 0 ;
57 bool is_uniform = false ;
58 GrB_Index Ap_size = 0 ;
59 GrB_Index Aj_size = 0 ;
60 GrB_Index Ah_size = 0 ;
61 int64_t ignore = -1 ;
62 char *Ax = NULL ;
63 int format = 0 ;
64 bool jumbled = false ;
65 bool is_hyper = false ;
66 bool clear_nvec = false ;
67 bool is_csc = true ;
68 GrB_Info info = GrB_SUCCESS ;
69 GrB_Descriptor desc = NULL ;
70 bool dump = true ;
71 GrB_Type type = NULL ;
72 size_t asize = 0 ;
73 GrB_Info import_export (void) ;
74 GrB_Info import_export2 (void) ;
75 
76 //------------------------------------------------------------------------------
77 
import_export()78 GrB_Info import_export ( )
79 {
80 
81     OK (GB_Matrix_check (C, "C to export", GB0, stdout)) ;
82 
83     //--------------------------------------------------------------------------
84     // export/import a vector
85     //--------------------------------------------------------------------------
86 
87     if (GB_VECTOR_OK (C))
88     {
89         OK (GxB_Vector_export_CSC ((GrB_Vector *) (&C), &type, &nrows,
90             &Ai, &Ax, &Ai_size, &Ax_size, &is_uniform,
91             &nvals, &jumbled, desc)) ;
92 
93         OK (GxB_Type_size (&asize, type)) ;
94 
95         if (dump)
96         {
97             printf ("export standard CSC vector: %llu-by-1, nvals %llu:\n",
98                 nrows, nvals) ;
99             OK (GB_Type_check (type, "type", GxB_SUMMARY, stdout)) ;
100             GB_Type_code code = type->code ;
101 
102             for (int64_t p = 0 ; p < nvals ; p++)
103             {
104                 printf ("  row %llu value ", Ai [p]) ;
105                 GB_code_check (code, Ax + (is_uniform ? 0:p)*asize, 5, stdout) ;
106                 printf ("\n") ;
107             }
108         }
109 
110         OK (GxB_Vector_import_CSC ((GrB_Vector *) (&C), type, nrows,
111             &Ai, &Ax, Ai_size, Ax_size, is_uniform, nvals, jumbled, desc)) ;
112 
113         return (GrB_SUCCESS) ;
114     }
115 
116     //--------------------------------------------------------------------------
117     // export/import a matrix
118     //--------------------------------------------------------------------------
119 
120     switch (format)
121     {
122 
123         //----------------------------------------------------------------------
124         case 0 :
125         //----------------------------------------------------------------------
126 
127             OK (GxB_Matrix_export_CSR (&C, &type, &nrows, &ncols,
128                     &Ap, &Aj, &Ax, &Ap_size, &Aj_size, &Ax_size, &is_uniform,
129                     &jumbled, desc)) ;
130 
131             OK (GxB_Type_size (&asize, type)) ;
132             nvec = nrows ;
133 
134             if (dump)
135             {
136                 printf ("\nexport standard CSR: %llu-by-%llu, Ax_size %llu:\n",
137                     nrows, ncols, Ax_size) ;
138                 OK (GB_Type_check (type, "type", GxB_SUMMARY, stdout));
139                 GB_Type_code code = type->code ;
140 
141                 for (int64_t i = 0 ; i < nrows ; i++)
142                 {
143                     printf ("Row %lld\n", i) ;
144                     for (int64_t p = Ap [i] ; p < Ap [i+1] ; p++)
145                     {
146                         printf ("  col %llu value ", Aj [p]) ;
147                         GB_code_check (code, Ax + (is_uniform ? 0:p)*asize,
148                             5, stdout) ;
149                         printf ("\n") ;
150                     }
151                 }
152             }
153 
154             OK (GxB_Matrix_import_CSR (&C, type, nrows, ncols,
155                 &Ap, &Aj, &Ax, Ap_size, Aj_size, Ax_size, is_uniform,
156                 jumbled, desc)) ;
157 
158             OK (GB_Matrix_check (C, "C reimported",
159                 dump ? GxB_COMPLETE : GxB_SILENT, stdout)) ;
160             break ;
161 
162         //----------------------------------------------------------------------
163         case 1 :
164         //----------------------------------------------------------------------
165 
166             OK (GxB_Matrix_export_CSC (&C, &type, &nrows, &ncols,
167                     &Ap, &Ai, &Ax, &Ap_size, &Ai_size, &Ax_size, &is_uniform,
168                     &jumbled, desc)) ;
169 
170             nvec = ncols ;
171             OK (GxB_Type_size (&asize, type)) ;
172 
173             if (dump)
174             {
175                 printf ("\nexport standard CSC: %llu-by-%llu, Ax_size %llu:\n",
176                     nrows, ncols, Ax_size) ;
177                 OK (GB_Type_check (type, "type", GxB_SUMMARY, stdout));
178                 GB_Type_code code = type->code ;
179 
180                 for (int64_t j = 0 ; j < ncols ; j++)
181                 {
182                     printf ("Col %lld\n", j) ;
183                     for (int64_t p = Ap [j] ; p < Ap [j+1] ; p++)
184                     {
185                         printf ("  row %llu value ", Ai [p]) ;
186                         GB_code_check (code, Ax + (is_uniform ? 0:p)*asize,
187                             5, stdout) ;
188                         printf ("\n") ;
189                     }
190                 }
191             }
192 
193             OK (GxB_Matrix_import_CSC (&C, type, nrows, ncols,
194                 &Ap, &Ai, &Ax, Ap_size, Ai_size, Ax_size, is_uniform,
195                 jumbled, desc)) ;
196 
197             OK (GB_Matrix_check (C, "C reimported",
198                 dump ? GxB_COMPLETE : GxB_SILENT, stdout)) ;
199             break ;
200 
201         //----------------------------------------------------------------------
202         case 2 :
203         //----------------------------------------------------------------------
204 
205             OK (GxB_Matrix_export_HyperCSR (&C, &type, &nrows, &ncols,
206                 &Ap, &Ah, &Aj, &Ax,
207                 &Ap_size, &Ah_size, &Aj_size, &Ax_size, &is_uniform,
208                 &nvec, &jumbled, desc)) ;
209 
210             OK (GxB_Type_size (&asize, type)) ;
211 
212             if (dump)
213             {
214                 printf ("\nexport hyper CSR: %llu-by-%llu, Ax_size %llu, "
215                     "nvec %llu:\n", nrows, ncols, Ax_size, nvec) ;
216                 OK (GB_Type_check (type, "type", GxB_SUMMARY, stdout));
217                 GB_Type_code code = type->code ;
218 
219                 for (int64_t k = 0 ; k < nvec ; k++)
220                 {
221                     int64_t i = Ah [k] ;
222                     printf ("Row %lld\n", i) ;
223                     for (int64_t p = Ap [k] ; p < Ap [k+1] ; p++)
224                     {
225                         printf ("  col %llu value ", Aj [p]) ;
226                         GB_code_check (code, Ax + (is_uniform ? 0:p)*asize,
227                             5, stdout) ;
228                         printf ("\n") ;
229                     }
230                 }
231             }
232 
233             OK (GxB_Matrix_import_HyperCSR (&C, type, nrows, ncols,
234                 &Ap, &Ah, &Aj, &Ax,
235                 Ap_size, Ah_size, Aj_size, Ax_size, is_uniform,
236                 nvec, jumbled, desc)) ;
237 
238             OK (GB_Matrix_check (C, "C reimported",
239                 dump ? GxB_COMPLETE : GxB_SILENT, stdout));
240             break ;
241 
242         //----------------------------------------------------------------------
243         case 3 :
244         //----------------------------------------------------------------------
245 
246             OK (GxB_Matrix_export_HyperCSC (&C, &type, &nrows, &ncols,
247                 &Ap, &Ah, &Ai, &Ax,
248                 &Ap_size, &Ah_size, &Ai_size, &Ax_size, &is_uniform,
249                 &nvec, &jumbled, desc)) ;
250 
251             OK (GxB_Type_size (&asize, type)) ;
252 
253             if (dump)
254             {
255                 printf ("export hyper CSC: %llu-by-%llu, Ax_size %llu, "
256                     "c %llu:\n", nrows, ncols, Ax_size, nvec) ;
257                 OK (GB_Type_check (type, "type", GxB_SUMMARY, stdout));
258                 GB_Type_code code = type->code ;
259 
260                 for (int64_t k = 0 ; k < nvec ; k++)
261                 {
262                     int64_t j = Ah [k] ;
263                     printf ("Col %lld\n", j) ;
264                     for (int64_t p = Ap [k] ; p < Ap [k+1] ; p++)
265                     {
266                         printf ("  row %llu value ", Ai [p]) ;
267                         GB_code_check (code, Ax + (is_uniform ? 0:p)*asize,
268                             5, stdout) ;
269                         printf ("\n") ;
270                     }
271                 }
272             }
273 
274             OK (GxB_Matrix_import_HyperCSC (&C, type, nrows, ncols,
275                 &Ap, &Ah, &Ai, &Ax,
276                 Ap_size, Ah_size, Ai_size, Ax_size, is_uniform,
277                 nvec, jumbled, desc)) ;
278 
279             OK (GB_Matrix_check (C, "C reimported",
280                 dump ? GxB_COMPLETE : GxB_SILENT, stdout)) ;
281             break ;
282 
283         //----------------------------------------------------------------------
284         default :
285         //----------------------------------------------------------------------
286 
287             mexErrMsgTxt ("bad format") ;
288             break ;
289     }
290     return (GrB_SUCCESS) ;
291 }
292 
293 //------------------------------------------------------------------------------
294 
import_export2(void)295 GrB_Info import_export2 (void)
296 {
297     OK (import_export ( )) ;
298     OK (import_export ( )) ;
299     return (GrB_SUCCESS) ;
300 }
301 
302 //------------------------------------------------------------------------------
303 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])304 void mexFunction
305 (
306     int nargout,
307     mxArray *pargout [ ],
308     int nargin,
309     const mxArray *pargin [ ]
310 )
311 {
312 
313     bool malloc_debug = GB_mx_get_global (true) ;
314 
315     // check inputs
316     if (nargout > 1 || nargin < 1 || nargin > 6)
317     {
318         mexErrMsgTxt ("Usage: " USAGE) ;
319     }
320 
321     // get format for import/export
322     GET_SCALAR (1, int, format, 0) ;
323 
324     // get hyper flag
325     GET_SCALAR (2, bool, is_hyper, false) ;
326 
327     // get csc flag
328     GET_SCALAR (3, bool, is_csc, true) ;
329 
330     // get dump flag
331     GET_SCALAR (4, bool, dump, false) ;
332 
333     // get clear_nvec flag
334     GET_SCALAR (5, bool, clear_nvec, false) ;
335 
336     // get C (make a deep copy)
337     #define GET_DEEP_COPY \
338     {                                                                       \
339         C = GB_mx_mxArray_to_Matrix (pargin [0], "C input", true, true) ;   \
340         if (!is_csc)                                                        \
341         {                                                                   \
342             /* convert C to CSR */                                          \
343             GB_transpose (NULL, NULL, false, C, /* in_place_A */            \
344                 NULL, NULL, NULL, false, NULL) ;                            \
345         }                                                                   \
346         if (is_hyper && !GB_IS_FULL (C))                                    \
347         {                                                                   \
348             /* convert C to hypersparse */                                  \
349             GB_convert_sparse_to_hyper (C, NULL) ;                          \
350         }                                                                   \
351     }
352     #define FREE_DEEP_COPY GrB_Matrix_free_(&C) ;
353     GET_DEEP_COPY ;
354     if (C == NULL)
355     {
356         FREE_ALL ;
357         mexErrMsgTxt ("C failed") ;
358     }
359 
360     // import/export
361     METHOD (import_export2 ( )) ;
362 
363     // return C to MATLAB
364     pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C export/import", false) ;
365 
366     FREE_ALL ;
367 }
368 
369