1 //------------------------------------------------------------------------------
2 // gbsplit: matrix split
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: GPL-3.0-or-later
7
8 //------------------------------------------------------------------------------
9
10 // gbsplit is an interface to GxB_Matrix_split.
11
12 // Usage:
13
14 // C = gbsplit (A, m, n, desc)
15
16 // where C is a 2D cell array of matrices.
17
18 #include "gb_matlab.h"
19
20 #define USAGE "usage: C = GrB.split (A, m, n, desc)"
21
22 //------------------------------------------------------------------------------
23 // gb_get_tilesizes: get a list of integers
24 //------------------------------------------------------------------------------
25
gb_get_tilesizes(mxArray * mxList,GrB_Index * len)26 static inline GrB_Index *gb_get_tilesizes (mxArray *mxList, GrB_Index *len)
27 {
28 int64_t n = mxGetNumberOfElements (mxList) ;
29 (*len) = (GrB_Index) n ;
30 mxClassID class = mxGetClassID (mxList) ;
31 GrB_Index *List = mxMalloc (n * sizeof (GrB_Index)) ;
32 if (class == mxINT64_CLASS)
33 {
34 int64_t *p = mxGetInt64s (mxList) ;
35 memcpy (List, p, n * sizeof (int64_t)) ;
36 }
37 else if (class == mxUINT64_CLASS)
38 {
39 int64_t *p = mxGetUint64s (mxList) ;
40 memcpy (List, p, n * sizeof (int64_t)) ;
41 }
42 else if (class == mxDOUBLE_CLASS)
43 {
44 double *p = mxGetDoubles (mxList) ;
45 for (int64_t k = 0 ; k < n ; k++)
46 {
47 List [k] = (GrB_Index) p [k] ;
48 CHECK_ERROR ((double) List [k] != p [k],
49 "dimensions must be integer") ;
50 }
51 }
52 else
53 {
54 ERROR ("unsupported type") ;
55 }
56 return (List) ;
57 }
58
59 //------------------------------------------------------------------------------
60 // gbsplit mexFunction
61 //------------------------------------------------------------------------------
62
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])63 void mexFunction
64 (
65 int nargout,
66 mxArray *pargout [ ],
67 int nargin,
68 const mxArray *pargin [ ]
69 )
70 {
71
72 //--------------------------------------------------------------------------
73 // check inputs
74 //--------------------------------------------------------------------------
75
76 gb_usage ((nargin == 3 || nargin == 4) && nargout <= 2, USAGE) ;
77
78 //--------------------------------------------------------------------------
79 // find the arguments
80 //--------------------------------------------------------------------------
81
82 mxArray *Matrix [4], *String [2], *Cell [2] ;
83 base_enum_t base ;
84 kind_enum_t kind ;
85 GxB_Format_Value fmt ;
86 int nmatrices, nstrings, ncells, sparsity ;
87 GrB_Descriptor desc ;
88 gb_get_mxargs (nargin, pargin, USAGE, Matrix, &nmatrices, String, &nstrings,
89 Cell, &ncells, &desc, &base, &kind, &fmt, &sparsity) ;
90
91 CHECK_ERROR (nmatrices != 3 || nstrings > 0 || ncells > 0, USAGE) ;
92
93 //--------------------------------------------------------------------------
94 // get the input matrix A, Tile_nrows, and Tile_ncols
95 //--------------------------------------------------------------------------
96
97 GrB_Matrix A = gb_get_shallow (Matrix [0]) ;
98 GrB_Index m, n ;
99 GrB_Index *Tile_nrows = gb_get_tilesizes (Matrix [1], &m) ;
100 GrB_Index *Tile_ncols = gb_get_tilesizes (Matrix [2], &n) ;
101 GrB_Matrix *Tiles = mxMalloc (m * n * sizeof (GrB_Matrix)) ;
102
103 //--------------------------------------------------------------------------
104 // Tiles = split (A)
105 //--------------------------------------------------------------------------
106
107 OK (GxB_Matrix_split (Tiles, m, n, Tile_nrows, Tile_ncols, A, desc)) ;
108
109 //--------------------------------------------------------------------------
110 // convert the Tiles array to a MATLAB cell array
111 //--------------------------------------------------------------------------
112
113 mxArray *C = mxCreateCellMatrix (m, n) ;
114 for (int64_t i = 0 ; i < m ; i++)
115 {
116 for (int64_t j = 0 ; j < n ; j++)
117 {
118 // Tiles is in row-major form and C is in column-major form
119 mxSetCell (C, i+j*m, gb_export (&Tiles [i*n+j], kind)) ;
120 }
121 }
122
123 //--------------------------------------------------------------------------
124 // free workspace and shallow copies
125 //--------------------------------------------------------------------------
126
127 OK (GrB_Matrix_free (&A)) ;
128 OK (GrB_Descriptor_free (&desc)) ;
129 mxFree (Tiles) ;
130 mxFree (Tile_nrows) ;
131 mxFree (Tile_ncols) ;
132
133 //--------------------------------------------------------------------------
134 // export the output cell array C back to MATLAB
135 //--------------------------------------------------------------------------
136
137 pargout [0] = C ;
138 pargout [1] = mxCreateDoubleScalar (kind) ;
139 GB_WRAPUP ;
140 }
141
142