1 //------------------------------------------------------------------------------
2 // GB_mex_concat: C = concat (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_concat (Tiles, type, fmt)"
13
14 #define FREE_ALL \
15 { \
16 if (Tiles != NULL) \
17 { \
18 for (int64_t k = 0 ; k < m*n ; k++) \
19 { \
20 GrB_Matrix_free_(&(Tiles [k])) ; \
21 } \
22 } \
23 mxFree (Tiles) ; \
24 GrB_Matrix_free_(&C) ; \
25 GB_mx_put_global (true) ; \
26 }
27
28 #define OK(method) \
29 { \
30 info = method ; \
31 if (info != GrB_SUCCESS) \
32 { \
33 printf ("%d at %d\n", info, __LINE__) ; \
34 mexErrMsgTxt ("failed") ; \
35 } \
36 }
37
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])38 void mexFunction
39 (
40 int nargout,
41 mxArray *pargout [ ],
42 int nargin,
43 const mxArray *pargin [ ]
44 )
45 {
46
47 GrB_Info info ;
48 bool malloc_debug = GB_mx_get_global (true) ;
49 GrB_Matrix C = NULL ;
50 GrB_Matrix *Tiles = NULL ;
51 int64_t m = 0, n = 0 ;
52
53 // check inputs
54 if (nargout > 1 || nargin < 1 || nargin > 3)
55 {
56 mexErrMsgTxt ("Usage: " USAGE) ;
57 }
58
59 // get Tiles (shallow copy)
60 const mxArray *mxTiles = pargin [0] ;
61 if (!mxIsCell (mxTiles))
62 {
63 FREE_ALL ;
64 mexErrMsgTxt ("Tiles must be a cell array") ;
65 }
66 m = mxGetM (mxTiles) ;
67 n = mxGetN (mxTiles) ;
68 Tiles = mxMalloc (m * n * sizeof (GrB_Matrix)) ;
69 for (int64_t j = 0 ; j < n ; j++)
70 {
71 for (int64_t i = 0 ; i < m ; i++)
72 {
73 // get the Tiles {i,j} matrix.
74 // Tiles is row-major but mxTiles is column-major
75 mxArray *Tile = mxGetCell (mxTiles, i+j*m) ;
76 Tiles [i*n+j] = GB_mx_mxArray_to_Matrix (Tile, "Tile", false, true);
77 }
78 }
79
80 // get the type of C, default is double
81 GrB_Type ctype = GB_mx_string_to_Type (PARGIN (1), GrB_FP64) ;
82
83 // determine the # of rows of C from Tiles {:,0}
84 GrB_Index cnrows = 0 ;
85 for (int64_t i = 0 ; i < m ; i++)
86 {
87 GrB_Index anrows ;
88 OK (GrB_Matrix_nrows (&anrows, Tiles [i*n])) ;
89 cnrows += anrows ;
90 }
91
92 // determine the # of columms of C from Tiles {0,:}
93 GrB_Index cncols = 0 ;
94 for (int64_t j = 0 ; j < n ; j++)
95 {
96 GrB_Index ancols ;
97 OK (GrB_Matrix_ncols (&ancols, Tiles [j])) ;
98 cncols += ancols ;
99 }
100
101 // get the format of C, default is by column
102 int GET_SCALAR (2, int, fmt, GxB_BY_COL) ;
103
104 // construct the empty C
105 #define GET_DEEP_COPY \
106 GrB_Matrix_new (&C, ctype, cnrows, cncols) ; \
107 GxB_Matrix_Option_set_(C, GxB_FORMAT, fmt) ;
108 #define FREE_DEEP_COPY GrB_Matrix_free_(&C) ;
109 GET_DEEP_COPY ;
110
111 // C = concat (Tiles)
112 METHOD (GxB_Matrix_concat (C, Tiles, m, n, NULL)) ;
113
114 // return C to MATLAB as a struct and free the GraphBLAS C
115 pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C output", true) ;
116 FREE_ALL ;
117 }
118
119