|
| 1 | +//------------------------------------------------------------------------------ |
| 2 | +// binsparse_matrix.h: a matrix data structure for the C binding of binsparse |
| 3 | +//------------------------------------------------------------------------------ |
| 4 | + |
| 5 | +// draft by Tim Davis |
| 6 | + |
| 7 | +// I propose that we create a single object, the binsparse_c_matrix, or |
| 8 | +// bc_matrix for short, to hold any matrix for the C bindings of the binsparse |
| 9 | +// package. |
| 10 | + |
| 11 | +// Name space: binsparse_c_*? bc_*? I'm open to suggestions. For brevity |
| 12 | +// I'm assuming bc_* for now. |
| 13 | + |
| 14 | +#ifndef BINSPARSE_MATRIX_H |
| 15 | +#define BINSPARSE_MATRIX_H |
| 16 | +#include <stdint.h> |
| 17 | +#include <stddef.h> |
| 18 | +#include <stdbool.h> |
| 19 | + |
| 20 | +//------------------------------------------------------------------------------ |
| 21 | +// type codes |
| 22 | +//------------------------------------------------------------------------------ |
| 23 | + |
| 24 | +// The bc_matrix can hold data types that correspond to the primary C built-in |
| 25 | +// types, with a placeholder for future user-defined types. |
| 26 | + |
| 27 | +typedef enum |
| 28 | +{ |
| 29 | + bc_type_none = 0, // no type; values array is NULL (maybe?) |
| 30 | + bc_type_bool = 1, // bool, assume sizeof(bool) == 1, as uint8_t |
| 31 | + bc_type_uint8 = 2, // uint8_t |
| 32 | + bc_type_uint16 = 3, // uint16_t |
| 33 | + bc_type_uint32 = 4, // uint32_t |
| 34 | + bc_type_uint64 = 5, // uint64_t |
| 35 | + bc_type_int8 = 6, // int8_t |
| 36 | + bc_type_int16 = 7, // int16_t |
| 37 | + bc_type_int32 = 8, // int32_t |
| 38 | + bc_type_int64 = 9, // int64_t |
| 39 | + bc_type_fp32 = 10, // float |
| 40 | + bc_type_fp64 = 11, // double |
| 41 | + bc_type_fc32 = 12, // float complex |
| 42 | + bc_type_fc64 = 13, // double complex |
| 43 | + bc_type_user = 14, // user-defined type |
| 44 | +} |
| 45 | +bc_type_code ; |
| 46 | + |
| 47 | +//------------------------------------------------------------------------------ |
| 48 | +// the bc_matrix: a sparse matrix or vector of any type |
| 49 | +//------------------------------------------------------------------------------ |
| 50 | + |
| 51 | +// Each dimension k of a given n-D matrix can be in one of four formats, |
| 52 | +// listed in increasing order of sparsity: |
| 53 | +// |
| 54 | +// Index some entries present, pointer[k] NULL, index[k] non-NULL |
| 55 | +// indices need not be |
| 56 | +// in order, nor unique |
| 57 | +// |
| 58 | +// Hyper some entries present, pointer[k] non-NULL, index[k] non-NULL |
| 59 | +// indices must be in |
| 60 | +// order and unique. |
| 61 | +// pointer [k] has size npointer [k]+1 |
| 62 | +// index [k] has size npointer [k] |
| 63 | +// |
| 64 | +// Sparse all entries present, pointer[k] non-NULL, index[k] NULL |
| 65 | +// pointer [k] has size of |
| 66 | +// dimension [axis_order[k]]+1. |
| 67 | +// |
| 68 | +// Full all entries present, pointer[k] NULL, index[k] NULL |
| 69 | + |
| 70 | +// The matrix format is determined by the presence of pointer [0:rank-1] |
| 71 | +// and index [0:rank-1]. |
| 72 | + |
| 73 | +// Common formats |
| 74 | + |
| 75 | +// rank = 0: a scalar, no arrays present. nvals = 0 or 1 |
| 76 | + |
| 77 | +// rank = 1: a 1-D vector of dimension n |
| 78 | +// |
| 79 | +// axis_order = { 0 } |
| 80 | +// dimension = { n } |
| 81 | +// |
| 82 | +// sparse vector (COO-style): Format is (Index) |
| 83 | +// pointer [0] = NULL |
| 84 | +// index [0] = [list of nvals indices] |
| 85 | +// values [0] = [list of nvals values], or size 1 if iso |
| 86 | +// in_order [0] = true if indices in ascending order, false otherwise |
| 87 | +// |
| 88 | +// full vector: Format is (Full) |
| 89 | +// pointer [0] = NULL |
| 90 | +// index [0] = NULL |
| 91 | +// values [0] = size n, or size 1 if iso |
| 92 | +// in_order [0] = true |
| 93 | + |
| 94 | +// rank = 2: a 2-D matrix of dimension m-by-n |
| 95 | +// |
| 96 | +// axis_order = { 0, 1 } if stored by-row |
| 97 | +// axis_order = { 1, 0 } if stored by-column |
| 98 | +// dimension = { m, n } |
| 99 | +// |
| 100 | +// COO: Format is (Index, Index) |
| 101 | +// |
| 102 | +// pointer [0] = NULL |
| 103 | +// pointer [1] = NULL |
| 104 | +// index [0] = row indices if by-row, col indices if by-col, size nvals |
| 105 | +// index [1] = col indices if by-row, row indices if by-col, size nvals |
| 106 | +// values [0] = values, size nvals |
| 107 | +// in_order [0] = true if index [0] in ascending order, false otherwise |
| 108 | +// in_order [1] = true if index [1] in ascending order, false otherwise |
| 109 | +// |
| 110 | +// CSR: Format is (Sparse, Index) |
| 111 | +// |
| 112 | +// axis_order = { 0, 1 }, stored by-row |
| 113 | +// pointer [0] = non-NULL, of size m+1 |
| 114 | +// pointer [1] = NULL |
| 115 | +// index [0] = NULL |
| 116 | +// index [1] = col indices, size nvals |
| 117 | +// in_order [0] = true |
| 118 | +// in_order [1] = true if index [1] in ascending order, false otherwise |
| 119 | +// values: size nvals |
| 120 | +// |
| 121 | +// CSC: Format is (Sparse, Index) |
| 122 | +// |
| 123 | +// axis_order = { 1, 0 }, stored by-row |
| 124 | +// pointer [0] = non-NULL, of size n+1 |
| 125 | +// pointer [1] = NULL |
| 126 | +// index [0] = NULL |
| 127 | +// index [1] = col indices, size nvals |
| 128 | +// in_order [0] = true |
| 129 | +// in_order [1] = true if index [1] in ascending order, false otherwise |
| 130 | +// values: size nvals, or 1 if iso |
| 131 | +// |
| 132 | +// DCSR (hypersparse by-row): Format is (Hyper, Index) |
| 133 | +// |
| 134 | +// axis_order = { 0, 1 }, stored by-row |
| 135 | +// pointer [0] = non-NULL, of size npointer [0]+1 |
| 136 | +// pointer [1] = NULL |
| 137 | +// index [0] = non-NULL, of size npointer [0] |
| 138 | +// index [1] = col indices, size nvals |
| 139 | +// in_order [0] = true |
| 140 | +// in_order [1] = true if index [1] in ascending order, false otherwise |
| 141 | +// values: size nvals, or 1 if iso |
| 142 | +// |
| 143 | +// DCSC format (hypersparse by-col): Format is (Hyper, Index) |
| 144 | +// |
| 145 | +// axis_order = { 1, 0 }, stored by-col |
| 146 | +// pointer [0] = non-NULL, of size npointer [0]+1 |
| 147 | +// pointer [1] = NULL |
| 148 | +// index [0] = non-NULL, of size npointer [0] |
| 149 | +// index [1] = row indices, size nvals |
| 150 | +// in_order [0] = true |
| 151 | +// in_order [1] = true if index [1] in ascending order, false otherwise |
| 152 | +// values: size nvals, or 1 if iso |
| 153 | +// |
| 154 | +// full format (held by row): Format is (Full, Full) |
| 155 | +// |
| 156 | +// axis_order = { 0, 1 }, stored by-row |
| 157 | +// pointer [0] = NULL |
| 158 | +// pointer [1] = NULL |
| 159 | +// index [0] = NULL |
| 160 | +// index [1] = NULL |
| 161 | +// in_order [0] = true |
| 162 | +// in_order [1] = true |
| 163 | +// values: size nvals = m*n, or 1 if iso |
| 164 | +// |
| 165 | +// full format (held by col): Format is (Full, Full) |
| 166 | +// |
| 167 | +// axis_order = { 1, 0 }, stored by-col |
| 168 | +// pointer [0] = NULL |
| 169 | +// pointer [1] = NULL |
| 170 | +// index [0] = NULL |
| 171 | +// index [1] = NULL |
| 172 | +// in_order [0] = true |
| 173 | +// in_order [1] = true |
| 174 | +// values: size nvals = m*n, or 1 if iso |
| 175 | +// |
| 176 | +// Hyper-Full format (held by row: each row is either full or all empty) |
| 177 | +// Format is (Hyper, Full) |
| 178 | +// |
| 179 | +// axis_order = { 0, 1 }, stored by-row |
| 180 | +// pointer [0] = non-NULL, of size npointer [0]+1 |
| 181 | +// pointer [1] = NULL |
| 182 | +// index [0] = non-NULL, of size npointer [0] |
| 183 | +// index [1] = NULL |
| 184 | +// values: size nvals = npointer [0]*n, or 1 if iso |
| 185 | +// |
| 186 | +// Hyper-Full format (held by col: each col is either full or all empty) |
| 187 | +// Format is (Hyper, Full) |
| 188 | +// |
| 189 | +// axis_order = { 1, 0 }, stored by-col |
| 190 | +// pointer [0] = non-NULL, of size npointer [0]+1 |
| 191 | +// pointer [1] = NULL |
| 192 | +// index [0] = non-NULL, of size npointer [0] |
| 193 | +// index [1] = NULL |
| 194 | +// values: size nvals = m * npointer [0], or 1 if iso |
| 195 | +// |
| 196 | +// bitmap format: held as two full bc_matrices with same dimension and |
| 197 | +// axis_order. The first matrix ('bitmap' pattern) is always bool. |
| 198 | +// The second full matrix holds the values. |
| 199 | +// Format of both bc_matrices is (Full, Full) |
| 200 | + |
| 201 | +// rank = 3? |
| 202 | +// |
| 203 | +// describe some for future extensions |
| 204 | + |
| 205 | +#define KMAX 32 // maximum rank allowed. Is 32 too large? |
| 206 | + // should each of the KMAX-sized arrays be dynamically allocated? |
| 207 | + // With KMAX of 32, this struct is 1688 bytes in size. |
| 208 | + |
| 209 | +typedef struct |
| 210 | +{ |
| 211 | + |
| 212 | + // basic information: dimensions, type, and format |
| 213 | + |
| 214 | + int64_t magic ; // for detecting uninitialized objects |
| 215 | + |
| 216 | + size_t header_size ; // allocated size of this bc_matrix_struct, |
| 217 | + // in bytes |
| 218 | + |
| 219 | + int rank ; // 0 to KMAX. 0: scalar, 1:vector, 2:matrix, |
| 220 | + // 3: 3D tensor, etc. |
| 221 | + |
| 222 | + bc_type_code pointer_type ; // matrix 'pointer' type (any integer type) |
| 223 | + |
| 224 | + bc_type_code index_type ; // matrix index type (any integer type) |
| 225 | + |
| 226 | + bc_type_code value_type ; // matrix value type (bool, int8, ...). |
| 227 | + |
| 228 | + bool iso_valued ; // if true, all entries have the same value, |
| 229 | + // and thus only values [0] is used. |
| 230 | + |
| 231 | + size_t type_size ; // sizeof (value type), that is, sizeof (bool), |
| 232 | + // sizeof (int8), ... Allows extension to |
| 233 | + // user-defined types. |
| 234 | + |
| 235 | + uint8_t axis_order [KMAX] ; // axis ordering, only 0..rank-1 are used; |
| 236 | + // a permutation of 0:rank-1 |
| 237 | + |
| 238 | + uint64_t dimension [KMAX] ; // size of each dimension of the matrix |
| 239 | + |
| 240 | + bool in_order [KMAX] ; // in_order [k] is true if the kth axis appears |
| 241 | + // in strictly ascending order |
| 242 | + |
| 243 | + char *json_string ; // metadata (may be NULL). Allows future |
| 244 | + // extension to user-defined types, with a json |
| 245 | + // string. |
| 246 | + size_t json_string_size ; // allocated size of json_string, in bytes |
| 247 | + |
| 248 | + // matrix content |
| 249 | + |
| 250 | + void *pointer [KMAX] ; // set of pointers, of type pointer_type |
| 251 | + uint64_t npointer [KMAX] ; // pointer [k] has npointer [k]+1 entries |
| 252 | + size_t pointer_size [KMAX] ;// allocated size of each pointer[k] array |
| 253 | + |
| 254 | + void *index [KMAX] ; // array of indices, of type index_type |
| 255 | + size_t index_size [KMAX] ; // allocated size of each index[k] array |
| 256 | + |
| 257 | + void *values ; // array of values, of type value_type |
| 258 | + // size 1 if iso, at least size nvals otherwise |
| 259 | + size_t values_size ; // allocated size of values array, in bytes |
| 260 | + uint64_t nvals ; // # of values present |
| 261 | + |
| 262 | +} |
| 263 | +bc_matrix_struct ; |
| 264 | + |
| 265 | +// a bc_matrix is a pointer to the bc_matrix_struct shown above |
| 266 | +typedef bc_matrix_struct *bc_matrix ; |
| 267 | + |
| 268 | +#endif |
| 269 | + |
0 commit comments