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