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