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