1 //------------------------------------------------------------------------------
2 // GB_mex_about2: more basic tests
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 // Test lots of random stuff. The function otherwise serves no purpose.
11
12 #include "GB_mex.h"
13 #include "GB_mex_errors.h"
14 #include "GB_ij.h"
15
16 #define USAGE "GB_mex_about2"
17
18 typedef struct
19 {
20 int gunk [16] ;
21 }
22 wild ;
23
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])24 void mexFunction
25 (
26 int nargout,
27 mxArray *pargout [ ],
28 int nargin,
29 const mxArray *pargin [ ]
30 )
31 {
32
33 GrB_Info info ;
34 GrB_Matrix A = NULL, B = NULL, C = NULL ;
35 GxB_Scalar scalar = NULL ;
36 GrB_Vector victor = NULL ;
37 GrB_Descriptor desc = NULL ;
38 GrB_Type Wild = NULL ;
39 char *err ;
40
41 //--------------------------------------------------------------------------
42 // startup GraphBLAS
43 //--------------------------------------------------------------------------
44
45 bool malloc_debug = GB_mx_get_global (true) ;
46 FILE *f = fopen ("errlog3.txt", "w") ;
47 int expected = GrB_SUCCESS ;
48
49 //--------------------------------------------------------------------------
50 // test removeElement/setElement when jumbled
51 //--------------------------------------------------------------------------
52
53 OK (GrB_Matrix_new (&A, GrB_INT32, 10, 10)) ;
54 OK (GrB_Vector_new (&victor, GrB_INT32, 10)) ;
55 OK (GxB_Vector_Option_set_(victor, GxB_BITMAP_SWITCH, 2.0)) ;
56 OK (GxB_Scalar_new (&scalar, GrB_INT32)) ;
57
58 OK (GxB_Matrix_fprint (A, "A before set", 3, NULL)) ;
59 OK (GrB_Matrix_setElement_INT32 (A, 314159, 0, 0)) ;
60 OK (GxB_Matrix_fprint (A, "A after set", 3, NULL)) ;
61 A->jumbled = true ;
62 OK (GrB_Matrix_removeElement (A, 0, 0)) ;
63 OK (GxB_Matrix_fprint (A, "A after remove", 3, NULL)) ;
64 A->jumbled = true ;
65 OK (GrB_Matrix_setElement_INT32 (A, 99099, 0, 0)) ;
66 OK (GxB_Matrix_fprint (A, "A after set again", 3, NULL)) ;
67
68 OK (GxB_Vector_fprint (victor, "victor before set", 3, NULL)) ;
69 OK (GrB_Vector_setElement_INT32 (victor, 44, 0)) ;
70 OK (GxB_Vector_fprint (victor, "victor after set", 3, NULL)) ;
71 victor->jumbled = true ;
72 OK (GrB_Vector_removeElement (victor, 0)) ;
73 OK (GxB_Vector_fprint (victor, "victor remove set", 3, NULL)) ;
74 victor->jumbled = true ;
75 OK (GrB_Vector_setElement_INT32 (victor, 88, 0)) ;
76 OK (GxB_Vector_fprint (victor, "victor after set again", 3, NULL)) ;
77
78 OK (GxB_Scalar_fprint (scalar, "scalar before set", 3, NULL)) ;
79 OK (GxB_Scalar_setElement_INT32 (scalar, 404)) ;
80 OK (GxB_Scalar_fprint (scalar, "scalar after set", 3, NULL)) ;
81 int i = 0 ;
82 OK (GxB_Scalar_extractElement_INT32 (&i, scalar)) ;
83 CHECK (i == 404) ;
84 OK (GxB_Scalar_fprint (scalar, "scalar after extract", 3, NULL)) ;
85 OK (GrB_Matrix_removeElement ((GrB_Matrix) scalar, 0, 0)) ;
86 OK (GxB_Scalar_fprint (scalar, "scalar after remove", 3, NULL)) ;
87 i = 777 ;
88 expected = GrB_NO_VALUE ;
89 ERR (GxB_Scalar_extractElement_INT32 (&i, scalar)) ;
90 CHECK (i == 777) ;
91
92 // force a zombie into the scalar
93 OK (GxB_Scalar_setElement_INT32 (scalar, 707)) ;
94 OK (GxB_Scalar_wait (&scalar)) ;
95 OK (GxB_Scalar_fprint (scalar, "scalar after wait", 3, NULL)) ;
96 OK (GxB_Matrix_Option_set (scalar, GxB_SPARSITY_CONTROL, GxB_SPARSE)) ;
97 CHECK (scalar->i != NULL) ;
98 scalar->i [0] = GB_FLIP (0) ;
99 scalar->nzombies = 1 ;
100 OK (GxB_Scalar_fprint (scalar, "scalar with zombie", 3, NULL)) ;
101 expected = GrB_NO_VALUE ;
102 ERR (GxB_Scalar_extractElement_INT32 (&i, scalar)) ;
103 OK (GxB_Scalar_fprint (scalar, "scalar after extract", 3, NULL)) ;
104 CHECK (i == 777) ;
105
106 GrB_Vector_free_(&victor) ;
107 GrB_Matrix_free_(&A) ;
108 GxB_Scalar_free_(&scalar) ;
109
110 //--------------------------------------------------------------------------
111 // builtin comparators not defined for complex types
112 //--------------------------------------------------------------------------
113
114 int n = 10 ;
115 OK (GrB_Matrix_new (&A, GxB_FC32, n, n)) ;
116 OK (GxB_Matrix_Option_set_(A, GxB_SPARSITY_CONTROL, GxB_SPARSE)) ;
117
118 OK (GrB_Matrix_new (&C, GxB_FC32, n, n)) ;
119 OK (GxB_Scalar_new (&scalar, GxB_FC32)) ;
120 expected = GrB_DOMAIN_MISMATCH ;
121 ERR (GxB_Matrix_select (C, NULL, NULL, GxB_LT_THUNK, A, scalar, NULL)) ;
122 char *message = NULL ;
123 OK (GrB_Matrix_error (&message, C)) ;
124 printf ("expected error: %s\n", message) ;
125 GrB_Matrix_free_(&C) ;
126 GxB_Scalar_free_(&scalar) ;
127
128 //--------------------------------------------------------------------------
129 // GB_pslice
130 //--------------------------------------------------------------------------
131
132 int64_t Slice [30] ;
133 GB_pslice (Slice, A->p, n, 2, true) ;
134 CHECK (Slice [0] == 0) ;
135
136 int64_t Ap [11] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ;
137 GB_pslice (Slice, Ap, 10, 10, false) ;
138 printf ("Slice: ") ;
139 for (int k = 0 ; k <= 10 ; k++) printf (" %ld", Slice [k]) ;
140 printf ("\n") ;
141
142 GrB_Matrix_free_(&A) ;
143
144 //--------------------------------------------------------------------------
145 // GrB_Matrix_check
146 //--------------------------------------------------------------------------
147
148 double bswitch = 1 ;
149 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
150 OK (GxB_Matrix_Option_set_(A, GxB_BITMAP_SWITCH, 0.125)) ;
151 OK (GxB_Matrix_Option_get_(A, GxB_BITMAP_SWITCH, &bswitch)) ;
152 CHECK (fabsf (bswitch - 0.125) < 1e-5) ;
153
154 OK (GxB_Matrix_Option_set_(A, GxB_SPARSITY_CONTROL, GxB_SPARSE)) ;
155 OK (GrB_Matrix_assign_INT32 (A, NULL, NULL, 3, GrB_ALL, n, GrB_ALL, n,
156 NULL)) ;
157 OK (GrB_Matrix_wait (&A)) ;
158 OK (GxB_Matrix_fprint (A, "valid matrix", GxB_SHORT, NULL)) ;
159 // mangle the matrix
160 GB_FREE (&(A->p), A->p_size) ;
161 GB_FREE (&(A->x), A->x_size) ;
162 expected = GrB_INVALID_OBJECT ;
163 ERR (GxB_Matrix_fprint (A, "invalid sparse matrix", GxB_SHORT, NULL)) ;
164 GrB_Matrix_free_(&A) ;
165
166 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
167 A->sparsity = 999 ;
168 ERR (GxB_Matrix_fprint (A, "invalid sparsity control", GxB_SHORT, NULL)) ;
169 GrB_Matrix_free_(&A) ;
170
171 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
172 OK (GrB_Matrix_assign_INT32 (A, NULL, NULL, 3, GrB_ALL, n, GrB_ALL, n,
173 NULL)) ;
174 OK (GrB_Matrix_wait (&A)) ;
175
176 A->jumbled = true ;
177 ERR (GxB_Matrix_fprint (A, "full matrix cannot be jumbled", GxB_SHORT,
178 NULL)) ;
179
180 A->jumbled = false ;
181 A->plen = 999 ;
182 ERR (GxB_Matrix_fprint (A, "invalid full matrix", GxB_SHORT, NULL)) ;
183
184 A->plen = -1 ;
185 A->nzombies = 1 ;
186 ERR (GxB_Matrix_fprint (A, "full matrix cannot have zombies",
187 GxB_SHORT, NULL)) ;
188 A->nzombies = 0 ;
189 CHECK (GB_Pending_alloc (&(A->Pending), GrB_INT32, NULL, true, 4)) ;
190 ERR (GxB_Matrix_fprint (A, "full matrix cannot have pending tuples",
191 GxB_SHORT, NULL)) ;
192 GrB_Matrix_free_(&A) ;
193
194 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
195 OK (GxB_Matrix_Option_set_(A, GxB_SPARSITY_CONTROL, GxB_BITMAP)) ;
196 A->plen = 999 ;
197 ERR (GxB_Matrix_fprint (A, "invalid bitmap", GxB_SHORT, NULL)) ;
198
199 A->plen = -1 ;
200 A->b [0] = 1 ;
201 ERR (GxB_Matrix_fprint (A, "invalid bitmap", GxB_SUMMARY, NULL)) ;
202 GrB_Matrix_free_(&A) ;
203
204 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
205 OK (GxB_Matrix_Option_set_(A, GxB_SPARSITY_CONTROL, GxB_BITMAP)) ;
206 OK (GrB_Matrix_setElement_INT32 (A, 12345, 0, 0)) ;
207 OK (GxB_Matrix_fprint (A, "valid matrix", GxB_SHORT, NULL)) ;
208 A->b [0] = 3 ;
209 ERR (GxB_Matrix_fprint (A, "invalid bitmap", GxB_SHORT, NULL)) ;
210 GrB_Matrix_free_(&A) ;
211
212 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
213 A->nvec_nonempty = 2 ;
214 ERR (GxB_Matrix_fprint (A, "invalid nvec_nonempty", GxB_SHORT, NULL)) ;
215 GrB_Matrix_free_(&A) ;
216
217 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
218 OK (GrB_Matrix_setElement_INT32 (A, 12345, 0, 0)) ;
219 OK (GxB_Matrix_fprint (A, "valid matrix with 1 pending", GxB_SHORT, NULL)) ;
220 A->Pending->size = 900 ;
221 ERR (GxB_Matrix_fprint (A, "invalid pending type", GxB_SHORT, NULL)) ;
222 GrB_Matrix_free_(&A) ;
223
224 //--------------------------------------------------------------------------
225 // lo:stride:hi with stride of zero
226 //--------------------------------------------------------------------------
227
228 OK (GxB_Global_Option_set_(GxB_BURBLE, true)) ;
229 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
230 GrB_Index I [3] = { 1, 1, 0 } ;
231 OK (GrB_Matrix_new (&C, GrB_INT32, n, 0)) ;
232 OK (GrB_Matrix_extract_(C, NULL, NULL, A, GrB_ALL, n, I, GxB_STRIDE,
233 NULL)) ;
234 OK (GxB_Matrix_fprint (C, "C = A (:,1:0:1)", GxB_COMPLETE, NULL)) ;
235 GrB_Matrix_free_(&C) ;
236 OK (GrB_Matrix_new (&C, GrB_INT32, 0, n)) ;
237 OK (GrB_Matrix_extract_(C, NULL, NULL, A, I, GxB_STRIDE, GrB_ALL, n,
238 NULL)) ;
239 OK (GxB_Matrix_fprint (C, "C = A (1:0:1,:)", GxB_COMPLETE, NULL)) ;
240 GrB_Matrix_free_(&C) ;
241 GrB_Matrix_free_(&A) ;
242 OK (GxB_Global_Option_set_(GxB_BURBLE, false)) ;
243
244 int64_t Icolon [3] = { 1, 1, 0 } ;
245 CHECK (!GB_ij_is_in_list (NULL, 0, 0, GB_STRIDE, Icolon)) ;
246
247 //--------------------------------------------------------------------------
248 // GB_aliased
249 //--------------------------------------------------------------------------
250
251 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
252 OK (GrB_Matrix_setElement_INT32 (A, 12345, 0, 0)) ;
253 OK (GrB_Matrix_dup (&C, A)) ;
254 CHECK (!GB_aliased (A, C)) ;
255 GB_FREE (&(C->p), C->p_size) ;
256 C->p = A->p ;
257 C->p_shallow = true ;
258 CHECK (GB_aliased (A, C)) ;
259 C->p = NULL ;
260 C->p_shallow = false ;
261 CHECK (!GB_aliased (A, C)) ;
262 GB_FREE (&(C->i), C->i_size) ;
263 C->i = A->i ;
264 C->i_shallow = true ;
265 CHECK (GB_aliased (A, C)) ;
266 C->i = NULL ;
267 C->i_shallow = false ;
268 GrB_Matrix_free_(&A) ;
269 GrB_Matrix_free_(&C) ;
270
271 //--------------------------------------------------------------------------
272 // GrB_apply with empty scalar
273 //--------------------------------------------------------------------------
274
275 OK (GxB_Scalar_new (&scalar, GrB_INT32)) ;
276 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
277 OK (GrB_Matrix_new (&C, GrB_INT32, n, n)) ;
278 expected = GrB_INVALID_VALUE ;
279 ERR (GxB_Matrix_apply_BinaryOp2nd (C, NULL, NULL, GrB_PLUS_INT32, A,
280 scalar, NULL)) ;
281 OK (GrB_Matrix_error (&message, C)) ;
282 printf ("expected error: %s\n", message) ;
283 GrB_Matrix_free_(&A) ;
284 GrB_Matrix_free_(&C) ;
285 GxB_Scalar_free_(&scalar) ;
286
287 //--------------------------------------------------------------------------
288 // invalid descriptor
289 //--------------------------------------------------------------------------
290
291 int method ;
292 OK (GrB_Descriptor_new (&desc)) ;
293 OK (GxB_Descriptor_fprint (desc, "descriptor", GxB_COMPLETE, NULL)) ;
294
295 OK (GxB_Desc_get (NULL, GxB_AxB_METHOD, &method)) ;
296 CHECK (method == GxB_DEFAULT) ;
297 OK (GxB_Desc_set (desc, GxB_AxB_METHOD, GxB_AxB_GUSTAVSON)) ;
298 OK (GxB_Descriptor_fprint (desc, "descriptor", GxB_COMPLETE, NULL)) ;
299 OK (GxB_Desc_get (desc, GxB_AxB_METHOD, &method)) ;
300 CHECK (method == GxB_AxB_GUSTAVSON) ;
301
302 desc->mask = GrB_REPLACE ;
303 expected = GrB_INVALID_OBJECT ;
304 ERR (GxB_Descriptor_fprint (desc, "invalid", GxB_COMPLETE, NULL)) ;
305 OK (GrB_Descriptor_free (&desc)) ;
306
307 //--------------------------------------------------------------------------
308 // GrB_build an empty matrix
309 //--------------------------------------------------------------------------
310
311 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
312 OK (GrB_Matrix_build_INT32 (A, I, I, I, 0, GrB_PLUS_INT32)) ;
313 OK (GxB_Matrix_fprint (A, "empty", GxB_COMPLETE, NULL)) ;
314 CHECK (!GB_is_shallow (A)) ;
315 GrB_Matrix_free_(&A) ;
316
317 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
318 expected = GrB_DOMAIN_MISMATCH ;
319 ERR (GrB_Matrix_build_INT32 (A, I, I, I, 0, GxB_FIRSTI_INT32)) ;
320 OK (GrB_Matrix_error (&message, A)) ;
321 printf ("expected error: %s\n", message) ;
322 GrB_Matrix_free_(&A) ;
323
324 //--------------------------------------------------------------------------
325 // reduce with positional op
326 //--------------------------------------------------------------------------
327
328 OK (GrB_Matrix_new (&A, GrB_INT32, n, n)) ;
329 OK (GrB_Vector_new (&victor, GrB_INT32, n)) ;
330 OK (GxB_Vector_Option_get_(victor, GxB_BITMAP_SWITCH, &bswitch)) ;
331 printf ("vector bitmap switch: %g\n\n", bswitch) ;
332
333 expected = GrB_DOMAIN_MISMATCH ;
334 ERR (GrB_Matrix_reduce_BinaryOp (victor, NULL, NULL, GxB_FIRSTI_INT32,
335 A, NULL)) ;
336 OK (GrB_Matrix_error (&message, victor)) ;
337 printf ("error expected: %s\n", message) ;
338 GrB_Matrix_free_(&A) ;
339 GrB_Vector_free_(&victor) ;
340
341 //--------------------------------------------------------------------------
342 // GrB_init
343 //--------------------------------------------------------------------------
344
345 expected = GrB_INVALID_VALUE ;
346 ERR (GrB_init (GrB_BLOCKING)) ;
347
348 //--------------------------------------------------------------------------
349 // jumbled user-defined matrix
350 //--------------------------------------------------------------------------
351
352 wild ww, w2 ;
353 n = 3 ;
354 memset (ww.gunk, 13, 16 * sizeof (int)) ;
355 OK (GrB_Type_new (&Wild, sizeof (wild))) ;
356 OK (GrB_Matrix_new (&C, Wild, n, n)) ;
357 OK (GxB_Matrix_Option_set (C, GxB_SPARSITY_CONTROL, GxB_SPARSE)) ;
358 OK (GrB_Matrix_assign_UDT (C, NULL, NULL, &ww, GrB_ALL, n, GrB_ALL, n,
359 NULL)) ;
360 OK (GxB_Matrix_fprint (C, "wild matrix", GxB_SHORT, NULL)) ;
361
362 // jumble the matrix
363 C->jumbled = true ;
364 C->i [0] = 1 ;
365 C->i [1] = 0 ;
366 OK (GxB_Matrix_fprint (C, "wild matrix jumbled", GxB_SHORT, NULL)) ;
367
368 // unjumble the matrix
369 OK (GrB_Matrix_wait (&C)) ;
370 OK (GxB_Matrix_fprint (C, "wild matrix unjumbled", GxB_SHORT, NULL)) ;
371
372 GrB_Matrix_free_(&C) ;
373
374 //--------------------------------------------------------------------------
375 // malloc/realloc wrappers
376 //--------------------------------------------------------------------------
377
378 size_t nbytes ;
379 bool ok = false ;
380 int *p = GB_malloc_memory (4, sizeof (int), &nbytes) ;
381 CHECK (p != NULL) ;
382 p = GB_realloc_memory (1024*1024, 4, sizeof (int), p, &nbytes, &ok, NULL) ;
383 CHECK (p != NULL) ;
384 CHECK (ok) ;
385 p = GB_realloc_memory (4, 4, GxB_INDEX_MAX + 1, p, &nbytes, &ok, NULL) ;
386 CHECK (!ok) ;
387 GB_free_memory (&p, nbytes) ;
388
389 //--------------------------------------------------------------------------
390 // try to import a huge full matrix (this will fail):
391 //--------------------------------------------------------------------------
392
393 GrB_Matrix X = NULL ;
394 info = GxB_Matrix_import_FullC (&X, GrB_FP32, GxB_INDEX_MAX, GxB_INDEX_MAX,
395 NULL, UINT64_MAX, false, NULL) ;
396 if (info != GrB_INVALID_VALUE || X != NULL) mexErrMsgTxt ("huge fail1") ;
397
398 GrB_Index nhuge = (((GrB_Index) 2) << 50) ;
399 info = GxB_Matrix_import_BitmapC (&X, GrB_FP32, nhuge, nhuge,
400 NULL, NULL, 0, 0, false, 0, NULL) ;
401 if (info != GrB_INVALID_VALUE || X != NULL) mexErrMsgTxt ("huge fail5") ;
402
403 // try to convert a huge sparse matrix to bitmap (this will fail too):
404 info = GrB_Matrix_new (&X, GrB_FP32, nhuge, nhuge) ;
405 if (info != GrB_SUCCESS) mexErrMsgTxt ("huge fail2") ;
406 info = GxB_Matrix_Option_set_(X, GxB_SPARSITY_CONTROL, GxB_BITMAP) ;
407 if (info != GrB_OUT_OF_MEMORY) mexErrMsgTxt ("huge fail3") ;
408 info = GB_convert_to_full (X) ;
409 if (info != GrB_OUT_OF_MEMORY) mexErrMsgTxt ("huge fail4") ;
410 GrB_Matrix_free (&X) ;
411
412 //--------------------------------------------------------------------------
413 // hypermatrix prune
414 //--------------------------------------------------------------------------
415
416 OK (GrB_Matrix_new (&C, GrB_FP32, GxB_INDEX_MAX, GxB_INDEX_MAX)) ;
417 OK (GrB_Matrix_setElement_FP32 (C, (double) 3, 0, 0)) ;
418 OK (GrB_Matrix_wait (&C)) ;
419 OK (GxB_Matrix_fprint (C, "huge matrix", GxB_SHORT, NULL)) ;
420 C->nvec_nonempty = -1 ;
421 OK (GB_hypermatrix_prune (C, NULL)) ;
422 CHECK (C->nvec_nonempty == 1) ;
423 GrB_Matrix_free (&C) ;
424
425 //--------------------------------------------------------------------------
426 // vector option set/get
427 //--------------------------------------------------------------------------
428
429 OK (GrB_Vector_new (&victor, GrB_FP32, 10)) ;
430 OK (GxB_Vector_Option_set (victor, GxB_BITMAP_SWITCH, (double) 4.5)) ;
431 double bitmap_switch = 8 ;
432 OK (GxB_Vector_Option_get (victor, GxB_BITMAP_SWITCH, &bitmap_switch)) ;
433 CHECK (bitmap_switch == 4.5) ;
434 GrB_Vector_free (&victor) ;
435
436 //--------------------------------------------------------------------------
437 // vector transpose
438 //--------------------------------------------------------------------------
439
440 #define FREE_ALL ;
441 #define GET_DEEP_COPY ;
442 #define FREE_DEEP_COPY ;
443 OK (GrB_Matrix_new (&C, GrB_FP32, 100, 1)) ;
444 OK (GrB_Matrix_setElement_FP32 (C, (double) 3, 0, 0)) ;
445 OK (GrB_Matrix_wait (&C)) ;
446 X = NULL ;
447 METHOD (GB_transpose (&X, NULL, true, C, NULL, NULL, NULL, false, NULL)) ;
448 OK (GxB_Matrix_fprint (X, "row", GxB_SHORT, NULL)) ;
449 GrB_Matrix Z = NULL ;
450 OK (GrB_Matrix_dup (&Z, X)) ;
451 GrB_Matrix_free (&C) ;
452 METHOD (GB_transpose (&C, NULL, true, Z, NULL, NULL, NULL, false, NULL)) ;
453 OK (GxB_Matrix_fprint (C, "col", GxB_SHORT, NULL)) ;
454 GrB_Matrix_free (&Z) ;
455 GrB_Matrix_free (&X) ;
456 GrB_Matrix_free (&C) ;
457
458 //--------------------------------------------------------------------------
459 // split/concat for user-defined types
460 //--------------------------------------------------------------------------
461
462 printf ("\n ======================== split/concat tests: ") ;
463 int sparsity [4] ;
464 sparsity [0] = GxB_HYPERSPARSE ;
465 sparsity [1] = GxB_SPARSE ;
466 sparsity [2] = GxB_BITMAP ;
467 sparsity [3] = GxB_FULL ;
468 GrB_Matrix Tiles [4] ;
469 memset (Tiles, 0, 4 * sizeof (GrB_Matrix)) ;
470 n = 20 ;
471 GrB_Index Tile_nrows [2] = { 5, 15 } ;
472 GrB_Index Tile_ncols [2] = { 12, 8 } ;
473
474 for (int k = 0 ; k <= 3 ; k++)
475 {
476 for (int k2 = 0 ; k2 <= 1 ; k2++)
477 {
478 OK (GrB_Matrix_new (&C, Wild, n, n)) ;
479 OK (GxB_Matrix_Option_set (C, GxB_SPARSITY_CONTROL, sparsity [k])) ;
480 if (k2 == 0)
481 {
482 // C(:,:) = ww
483 OK (GrB_Matrix_assign_UDT (C, NULL, NULL, &ww, GrB_ALL,
484 n, GrB_ALL, n, NULL)) ;
485 }
486 else
487 {
488 // C = diagonal matrix
489 for (int64_t kk = 0 ; kk < 20 ; kk++)
490 {
491 OK (GrB_Matrix_setElement_UDT (C, &ww, kk, kk)) ;
492 }
493 }
494 // split C into 4 matrices
495 OK (GxB_Matrix_split (Tiles, 2, 2, Tile_nrows, Tile_ncols, C,
496 NULL)) ;
497 // concatenate the 4 matrices back in X
498 OK (GrB_Matrix_new (&X, Wild, n, n)) ;
499 OK (GxB_Matrix_Option_set (X, GxB_SPARSITY_CONTROL, sparsity [k])) ;
500 OK (GxB_Matrix_concat (X, Tiles, 2, 2, NULL)) ;
501 // ensure C and X are the same (just use a brute force method)
502 for (int64_t i = 0 ; i < n ; i++)
503 {
504 for (int64_t j = 0 ; j < n ; j++)
505 {
506 wild wc, wx ;
507 int infoc = GrB_Matrix_extractElement_UDT (&wc, C, i, j) ;
508 int infox = GrB_Matrix_extractElement_UDT (&wx, X, i, j) ;
509 CHECK (infoc == GrB_SUCCESS || infoc == GrB_NO_VALUE) ;
510 CHECK (infoc == infox) ;
511 if (infoc == GrB_SUCCESS)
512 {
513 for (int kk = 0 ; kk < 16 ; kk++)
514 {
515 CHECK (wc.gunk [kk] == wx.gunk [kk]) ;
516 }
517 }
518 }
519 }
520 GrB_Matrix_free (&X) ;
521 GrB_Matrix_free (&C) ;
522
523 expected = GrB_DOMAIN_MISMATCH ;
524 OK (GrB_Matrix_new (&X, GrB_FP32, n, n)) ;
525 ERR (GxB_Matrix_concat (X, Tiles, 2, 2, NULL)) ;
526 OK (GrB_Matrix_error (&err, X)) ;
527 printf ("expected error: %s\n", err) ;
528 GrB_Matrix_free (&X) ;
529
530 expected = GrB_DIMENSION_MISMATCH ;
531 OK (GrB_Matrix_new (&X, Wild, 100, 100)) ;
532 ERR (GxB_Matrix_concat (X, Tiles, 2, 2, NULL)) ;
533 OK (GrB_Matrix_error (&err, X)) ;
534 printf ("expected error: %s\n", err) ;
535 GrB_Matrix_free (&X) ;
536
537 OK (GrB_Matrix_new (&X, Wild, n, n)) ;
538 GrB_Matrix_free (&(Tiles [3])) ;
539 OK (GrB_Matrix_new (&(Tiles [3]), Wild, 15, 100)) ;
540 ERR (GxB_Matrix_concat (X, Tiles, 2, 2, NULL)) ;
541 GxB_print (X, 3) ;
542 OK (GrB_Matrix_error (&err, X)) ;
543 printf ("expected error: %s\n", err) ;
544 GrB_Matrix_free (&(Tiles [3])) ;
545
546 OK (GrB_Matrix_new (&(Tiles [3]), Wild, 100, 8)) ;
547 ERR (GxB_Matrix_concat (X, Tiles, 2, 2, NULL)) ;
548 OK (GrB_Matrix_error (&err, X)) ;
549 printf ("expected error: %s\n", err) ;
550
551 for (int kk = 0 ; kk < 4 ; kk++)
552 {
553 GrB_Matrix_free (&(Tiles [kk])) ;
554 }
555
556 expected = GrB_NULL_POINTER ;
557 ERR (GxB_Matrix_concat (X, Tiles, 2, 2, NULL)) ;
558 GrB_Matrix_free (&X) ;
559 }
560 }
561
562 //--------------------------------------------------------------------------
563 // split/concat error handling
564 //--------------------------------------------------------------------------
565
566 expected = GrB_INVALID_VALUE ;
567 OK (GrB_Matrix_new (&C, GrB_FP32, n, n)) ;
568 ERR (GxB_Matrix_split (Tiles, 0, 0, Tile_nrows, Tile_ncols, C, NULL)) ;
569 ERR (GxB_Matrix_concat (C, Tiles, 0, 0, NULL)) ;
570 GrB_Matrix_free (&C) ;
571
572 expected = GrB_DIMENSION_MISMATCH ;
573 OK (GrB_Matrix_new (&C, GrB_FP32, n, n)) ;
574 Tile_nrows [0] = -1 ;
575 ERR (GxB_Matrix_split (Tiles, 2, 2, Tile_nrows, Tile_ncols, C, NULL)) ;
576 Tile_nrows [0] = 1 ;
577 ERR (GxB_Matrix_split (Tiles, 2, 2, Tile_nrows, Tile_ncols, C, NULL)) ;
578 Tile_nrows [0] = 5 ;
579 Tile_ncols [0] = -1 ;
580 ERR (GxB_Matrix_split (Tiles, 2, 2, Tile_nrows, Tile_ncols, C, NULL)) ;
581 Tile_ncols [0] = 1 ;
582 ERR (GxB_Matrix_split (Tiles, 2, 2, Tile_nrows, Tile_ncols, C, NULL)) ;
583 GrB_Matrix_free (&C) ;
584
585 //--------------------------------------------------------------------------
586 // C<C,struct> = scalar
587 //--------------------------------------------------------------------------
588
589 printf ("\n\ntesting C<C,struct> = scalar for user-defined type:\n") ;
590 OK (GxB_Global_Option_set (GxB_BURBLE, true)) ;
591 OK (GrB_Matrix_new (&C, Wild, n, n)) ;
592 memset (ww.gunk, 0, 16 * sizeof (int)) ;
593 memset (w2.gunk, 1, 16 * sizeof (int)) ;
594 for (int64_t kk = 0 ; kk < 16 ; kk++)
595 {
596 w2.gunk [kk] = kk ;
597 }
598 for (int64_t kk = 0 ; kk < 20 ; kk++)
599 {
600 OK (GrB_Matrix_setElement_UDT (C, &ww, kk, kk)) ;
601 }
602 OK (GrB_Matrix_wait (&C)) ;
603 info = GrB_Matrix_assign_UDT (C, C, NULL, &w2, GrB_ALL, 20, GrB_ALL, 20,
604 GrB_DESC_S) ;
605 wild w3 ;
606
607 for (int64_t kk = 0 ; kk < 20 ; kk++)
608 {
609 memset (w3.gunk, 9, 16 * sizeof (int)) ;
610 info = (GrB_Matrix_extractElement_UDT (&w3, C, kk, kk)) ;
611 CHECK (info == GrB_SUCCESS) ;
612 for (int64_t t = 0 ; t < 16 ; t++)
613 {
614 CHECK (w3.gunk [t] == t) ;
615 }
616 }
617 GrB_Matrix_free (&C) ;
618 OK (GxB_Global_Option_set (GxB_BURBLE, false)) ;
619
620 //--------------------------------------------------------------------------
621 // GxB_Matrix_diag and GxB_Vector_diag error handling
622 //--------------------------------------------------------------------------
623
624 expected = GrB_DIMENSION_MISMATCH ;
625
626 OK (GrB_Matrix_new (&C, GrB_FP32, 10, 20)) ;
627 OK (GrB_Vector_new (&victor, GrB_FP32, 10)) ;
628 ERR (GxB_Matrix_diag (C, victor, 0, NULL)) ;
629 OK (GrB_Matrix_error (&err, C)) ;
630 printf ("expected error: %s\n", err) ;
631 GrB_Matrix_free (&C) ;
632
633 OK (GrB_Matrix_new (&C, GrB_FP32, 5, 5)) ;
634 ERR (GxB_Matrix_diag (C, victor, 0, NULL)) ;
635 OK (GrB_Matrix_error (&err, C)) ;
636 printf ("expected error: %s\n", err) ;
637 ERR (GxB_Vector_diag (victor, C, 0, NULL)) ;
638 OK (GrB_Vector_error (&err, victor)) ;
639 printf ("expected error: %s\n", err) ;
640 GrB_Matrix_free (&C) ;
641
642 expected = GrB_DOMAIN_MISMATCH ;
643
644 OK (GrB_Matrix_new (&C, Wild, 10, 10)) ;
645 ERR (GxB_Matrix_diag (C, victor, 0, NULL)) ;
646 OK (GrB_Matrix_error (&err, C)) ;
647 printf ("expected error: %s\n", err) ;
648 ERR (GxB_Vector_diag (victor, C, 0, NULL)) ;
649 OK (GrB_Vector_error (&err, victor)) ;
650 printf ("expected error: %s\n", err) ;
651 GrB_Matrix_free (&C) ;
652 GrB_Vector_free (&victor) ;
653
654 //--------------------------------------------------------------------------
655 // wrapup
656 //--------------------------------------------------------------------------
657
658 GrB_Type_free_(&Wild) ;
659 GB_mx_put_global (true) ;
660 fclose (f) ;
661 printf ("\nAll errors printed above were expected.\n") ;
662 printf ("GB_mex_about2: all tests passed\n\n") ;
663 }
664
665