1 //------------------------------------------------------------------------------
2 // GB_mex_split: C = split (Tiles)
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_split (A, ms, ns)"
13
14 #define FREE_ALL \
15 { \
16 GrB_Matrix_free_(&A) ; \
17 mxFree (Tiles) ; \
18 GB_mx_put_global (true) ; \
19 }
20
21 #define OK(method) \
22 { \
23 info = method ; \
24 if (info != GrB_SUCCESS) \
25 { \
26 printf ("%d at %d\n", info, __LINE__) ; \
27 mexErrMsgTxt ("failed") ; \
28 } \
29 }
30
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])31 void mexFunction
32 (
33 int nargout,
34 mxArray *pargout [ ],
35 int nargin,
36 const mxArray *pargin [ ]
37 )
38 {
39
40 GrB_Info info ;
41 bool malloc_debug = GB_mx_get_global (true) ;
42 GrB_Matrix A = NULL ;
43 GrB_Matrix *Tiles = NULL ;
44
45 // check inputs
46 if (nargout > 1 || nargin != 3)
47 {
48 mexErrMsgTxt ("Usage: " USAGE) ;
49 }
50
51 // get A (shallow copy)
52 A = GB_mx_mxArray_to_Matrix (pargin [0], "A input", false, true) ;
53 if (A == NULL)
54 {
55 FREE_ALL ;
56 mexErrMsgTxt ("A failed") ;
57 }
58
59 // get ms (deep copy)
60 if (mxGetClassID (pargin [1]) != mxDOUBLE_CLASS)
61 {
62 mexErrMsgTxt ("ms must be double") ;
63 }
64 double *ms_double = mxGetDoubles (pargin [1]) ;
65 GrB_Index m = mxGetNumberOfElements (pargin [1]) ;
66 GrB_Index *Tile_nrows = mxMalloc (m * sizeof (GrB_Index)) ;
67 for (int64_t k = 0 ; k < m ; k++)
68 {
69 Tile_nrows [k] = (GrB_Index) (ms_double [k]) ;
70 }
71
72 // get ns (deep copy)
73 if (mxGetClassID (pargin [2]) != mxDOUBLE_CLASS)
74 {
75 mexErrMsgTxt ("ns must be double") ;
76 }
77 double *ns_double = mxGetDoubles (pargin [2]) ;
78 GrB_Index n = mxGetNumberOfElements (pargin [2]) ;
79 GrB_Index *Tile_ncols = mxMalloc (n * sizeof (GrB_Index)) ;
80 for (int64_t k = 0 ; k < n ; k++)
81 {
82 Tile_ncols [k] = (GrB_Index) (ns_double [k]) ;
83 }
84
85 // create Tiles
86 Tiles = mxCalloc (m * n, sizeof (GrB_Matrix)) ;
87
88 // construct the empty Tiles array
89 #define GET_DEEP_COPY \
90 memset (Tiles, 0, m * n * sizeof (GrB_Matrix)) ;
91 #define FREE_DEEP_COPY \
92 for (int64_t k = 0 ; k < m*n ; k++) \
93 { \
94 GrB_Matrix_free (&(Tiles [k])) ; \
95 }
96
97 // Tiles = split (A, ms, ns)
98 METHOD (GxB_Matrix_split (Tiles, m, n, Tile_nrows, Tile_ncols, A, NULL)) ;
99
100 // return C to MATLAB as a cell array and free the GraphBLAS tiles
101 pargout [0] = mxCreateCellMatrix (m, n) ;
102 for (int64_t j = 0 ; j < n ; j++)
103 {
104 for (int64_t i = 0 ; i < m ; i++)
105 {
106 mxArray *T = GB_mx_Matrix_to_mxArray (&(Tiles [i*n+j]),
107 "Tile output", true) ;
108 mxSetCell (pargout [0], i+j*m, T) ;
109 }
110 }
111 FREE_ALL ;
112 }
113
114