Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
csr.cxx
Go to the documentation of this file.
1 #include "csr.h"
2 #include "../contraction/ctr_comm.h"
3 #include "../shared/util.h"
4 
5 #define ALIGN 256
6 
7 namespace CTF_int {
8  int64_t get_csr_size(int64_t nnz, int nrow_, int val_size){
9  int offset = 4*sizeof(int64_t);
10  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
11  offset += nnz*val_size;
12  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
13  offset += (nrow_+1)*sizeof(int);
14  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
15  offset += sizeof(int)*nnz;
16  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
17  return offset;
18  }
19 
20  CSR_Matrix::CSR_Matrix(int64_t nnz, int nrow_, int ncol, accumulatable const * sr){
21  ASSERT(ALIGN >= 16);
22  int64_t size = get_csr_size(nnz, nrow_, sr->el_size);
23  all_data = (char*)alloc(size);
24  ((int64_t*)all_data)[0] = nnz;
25  ((int64_t*)all_data)[1] = sr->el_size;
26  ((int64_t*)all_data)[2] = (int64_t)nrow_;
27  ((int64_t*)all_data)[3] = ncol;
28  sr->init_shell(nnz,this->vals());
29  }
30 
31  CSR_Matrix::CSR_Matrix(char * all_data_){
32  ASSERT(ALIGN >= 16);
33  all_data = all_data_;
34  }
35 
36  CSR_Matrix::CSR_Matrix(COO_Matrix const & coom, int nrow_, int ncol, algstrct const * sr, char * data, bool init_data){
37  ASSERT(ALIGN >= 16);
38  int64_t nz = coom.nnz();
39  int64_t v_sz = coom.val_size();
40  int const * coo_rs = coom.rows();
41  int const * coo_cs = coom.cols();
42  char const * vs = coom.vals();
43  /*if (nz >= 2){
44  printf("herecsr\n");
45  sr->print(vs);
46  sr->print(vs+v_sz);
47  }*/
48 
49  int64_t size = get_csr_size(nz, nrow_, v_sz);
50  if (data == NULL)
51  all_data = (char*)alloc(size);
52  else
53  all_data = data;
54 
55  ((int64_t*)all_data)[0] = nz;
56  ((int64_t*)all_data)[1] = v_sz;
57  ((int64_t*)all_data)[2] = (int64_t)nrow_;
58  ((int64_t*)all_data)[3] = ncol;
59 
60  char * csr_vs = vals();
61  int * csr_ja = JA();
62  int * csr_ia = IA();
63 
64  if (init_data){
65  sr->init_shell(nz, csr_vs);
66  }
67  //memcpy(csr_vs, vs, nz*v_sz);
68  //memset(csr_ja
69 
70  sr->coo_to_csr(nz, nrow_, csr_vs, csr_ja, csr_ia, vs, coo_rs, coo_cs);
71 /* for (int i=0; i<nrow_; i++){
72  printf("csr_ja[%d] = %d\n",i,csr_ja[i]);
73  }
74  for (int i=0; i<nz; i++){
75  printf("csr_ia[%d] = %d\n",i,csr_ia[i]);
76  }*/
77 
78  }
79 
80  int64_t CSR_Matrix::nnz() const {
81  return ((int64_t*)all_data)[0];
82  }
83 
84  int CSR_Matrix::val_size() const {
85  return ((int64_t*)all_data)[1];
86  }
87 
88 
89  int64_t CSR_Matrix::size() const {
90  return get_csr_size(nnz(),nrow(),val_size());
91  }
92 
93  int CSR_Matrix::nrow() const {
94  return ((int64_t*)all_data)[2];
95  }
96 
97  int CSR_Matrix::ncol() const {
98  return ((int64_t*)all_data)[3];
99  }
100 
101  char * CSR_Matrix::vals() const {
102  int offset = 4*sizeof(int64_t);
103  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
104  return all_data + offset;
105  }
106 
107  int * CSR_Matrix::IA() const {
108  int64_t n = this->nnz();
109  int v_sz = this->val_size();
110 
111  int offset = 4*sizeof(int64_t);
112  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
113  offset += n*v_sz;
114  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
115 
116  return (int*)(all_data + offset);
117  }
118 
119  int * CSR_Matrix::JA() const {
120  int64_t n = this->nnz();
121  int64_t nr = this->nrow();
122  int v_sz = this->val_size();
123 
124  int offset = 4*sizeof(int64_t);
125  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
126  offset += n*v_sz;
127  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
128  offset += (nr+1)*sizeof(int);
129  if (offset % ALIGN != 0) offset += ALIGN-(offset%ALIGN);
130  //return (int*)(all_data + n*v_sz+(nr+1)*sizeof(int)+3*sizeof(int64_t));
131  return (int*)(all_data + offset);
132  }
133 
134  void CSR_Matrix::csrmm(char const * A, algstrct const * sr_A, int m, int n, int k, char const * alpha, char const * B, algstrct const * sr_B, char const * beta, char * C, algstrct const * sr_C, bivar_function const * func, bool do_offload){
135  if (func != NULL && func->has_off_gemm && do_offload){
136  assert(sr_C->isequal(beta, sr_C->mulid()));
137  assert(alpha == NULL || sr_C->isequal(alpha, sr_C->mulid()));
138  func->coffload_csrmm(m,n,k,A,B,C);
139  } else {
140  CSR_Matrix cA((char*)A);
141  int64_t nz = cA.nnz();
142  int const * ja = cA.JA();
143  int const * ia = cA.IA();
144  char const * vs = cA.vals();
145  if (func != NULL){
146  assert(sr_C->isequal(beta, sr_C->mulid()));
147  assert(alpha == NULL || sr_C->isequal(alpha, sr_C->mulid()));
148  func->ccsrmm(m,n,k,vs,ja,ia,nz,B,C,sr_C);
149  } else {
150  ASSERT(sr_B->el_size == sr_A->el_size);
151  ASSERT(sr_C->el_size == sr_A->el_size);
152  assert(!do_offload);
153  sr_C->csrmm(m,n,k,alpha,vs,ja,ia,nz,B,beta,C,func);
154  }
155  }
156  }
157 
158  void CSR_Matrix::csrmultd(char const * A, algstrct const * sr_A, int m, int n, int k, char const * alpha, char const * B, algstrct const * sr_B, char const * beta, char * C, algstrct const * sr_C, bivar_function const * func, bool do_offload){
159  if (func != NULL && func->has_off_gemm && do_offload){
160  assert(0);
161  assert(sr_C->isequal(beta, sr_C->mulid()));
162  assert(alpha == NULL || sr_C->isequal(alpha, sr_C->mulid()));
163  } else {
164  CSR_Matrix cA((char*)A);
165  int64_t nzA = cA.nnz();
166  int const * jA = cA.JA();
167  int const * iA = cA.IA();
168  char const * vsA = cA.vals();
169  CSR_Matrix cB((char*)B);
170  int64_t nzB = cB.nnz();
171  int const * jB = cB.JA();
172  int const * iB = cB.IA();
173  char const * vsB = cB.vals();
174  if (func != NULL){
175  assert(sr_C->isequal(beta, sr_C->mulid()));
176  assert(alpha == NULL || sr_C->isequal(alpha, sr_C->mulid()));
177  func->ccsrmultd(m,n,k,vsA,jA,iA,nzA,vsB,jB,iB,nzB,C,sr_C);
178  } else {
179  ASSERT(sr_B->el_size == sr_A->el_size);
180  ASSERT(sr_C->el_size == sr_A->el_size);
181  assert(!do_offload);
182  sr_C->csrmultd(m,n,k,alpha,vsA,jA,iA,nzA,vsB,jB,iB,nzB,beta,C);
183  }
184  }
185 
186  }
187 
188  void CSR_Matrix::csrmultcsr(char const * A, algstrct const * sr_A, int m, int n, int k, char const * alpha, char const * B, algstrct const * sr_B, char const * beta, char *& C, algstrct const * sr_C, bivar_function const * func, bool do_offload){
189  if (func != NULL && func->has_off_gemm && do_offload){
190  assert(0);
191  assert(sr_C->isequal(beta, sr_C->mulid()));
192  assert(alpha == NULL || sr_C->isequal(alpha, sr_C->mulid()));
193  } else {
194  CSR_Matrix cA((char*)A);
195  int64_t nzA = cA.nnz();
196  int const * jA = cA.JA();
197  int const * iA = cA.IA();
198  char const * vsA = cA.vals();
199  CSR_Matrix cB((char*)B);
200  int64_t nzB = cB.nnz();
201  int const * jB = cB.JA();
202  int const * iB = cB.IA();
203  char const * vsB = cB.vals();
204  if (func != NULL){
205  assert(sr_C->isequal(beta, sr_C->mulid()));
206  assert(alpha == NULL || sr_C->isequal(alpha, sr_C->mulid()));
207  func->ccsrmultcsr(m,n,k,vsA,jA,iA,nzA,vsB,jB,iB,nzB,C,sr_C);
208  } else {
209  ASSERT(sr_B->el_size == sr_A->el_size);
210  ASSERT(sr_C->el_size == sr_A->el_size);
211  assert(!do_offload);
212  sr_C->csrmultcsr(m,n,k,alpha,vsA,jA,iA,nzA,vsB,jB,iB,nzB,beta,C);
213  }
214  }
215 
216 
217  }
218 
219  void CSR_Matrix::partition(int s, char ** parts_buffer, CSR_Matrix ** parts){
220  int part_nnz[s], part_nrows[s];
221  int m = nrow();
222  int v_sz = val_size();
223  char * org_vals = vals();
224  int * org_ia = IA();
225  int * org_ja = JA();
226  for (int i=0; i<s; i++){
227  part_nnz[i] = 0;
228  part_nrows[i] = 0;
229  }
230  for (int i=0; i<m; i++){
231  part_nrows[i%s]++;
232  part_nnz[i%s]+=org_ia[i+1]-org_ia[i];
233  }
234  int64_t tot_sz = 0;
235  for (int i=0; i<s; i++){
236  tot_sz += get_csr_size(part_nnz[i], part_nrows[i], v_sz);
237  }
238  alloc_ptr(tot_sz, (void**)parts_buffer);
239  char * part_data = *parts_buffer;
240  for (int i=0; i<s; i++){
241  ((int64_t*)part_data)[0] = part_nnz[i];
242  ((int64_t*)part_data)[1] = v_sz;
243  ((int64_t*)part_data)[2] = part_nrows[i];
244  ((int64_t*)part_data)[3] = ncol();
245  parts[i] = new CSR_Matrix(part_data);
246  char * pvals = parts[i]->vals();
247  int * pja = parts[i]->JA();
248  int * pia = parts[i]->IA();
249  pia[0] = 1;
250  for (int j=i, k=0; j<m; j+=s, k++){
251  memcpy(pvals+(pia[k]-1)*v_sz, org_vals+(org_ia[j]-1)*v_sz, (org_ia[j+1]-org_ia[j])*v_sz);
252  memcpy(pja+(pia[k]-1), org_ja+(org_ia[j]-1), (org_ia[j+1]-org_ia[j])*sizeof(int));
253  pia[k+1] = pia[k]+org_ia[j+1]-org_ia[j];
254  }
255  part_data += get_csr_size(part_nnz[i], part_nrows[i], v_sz);
256  }
257  }
258 
259  CSR_Matrix::CSR_Matrix(char * const * smnds, int s){
260  CSR_Matrix * csrs[s];
261  int64_t tot_nnz=0, tot_nrow=0;
262  for (int i=0; i<s; i++){
263  csrs[i] = new CSR_Matrix(smnds[i]);
264  tot_nnz += csrs[i]->nnz();
265  tot_nrow += csrs[i]->nrow();
266  }
267  int64_t v_sz = csrs[0]->val_size();
268  int64_t tot_ncol = csrs[0]->ncol();
269  all_data = (char*)alloc(get_csr_size(tot_nnz, tot_nrow, v_sz));
270  ((int64_t*)all_data)[0] = tot_nnz;
271  ((int64_t*)all_data)[1] = v_sz;
272  ((int64_t*)all_data)[2] = tot_nrow;
273  ((int64_t*)all_data)[3] = tot_ncol;
274 
275  char * csr_vs = vals();
276  int * csr_ja = JA();
277  int * csr_ia = IA();
278 
279  csr_ia[0] = 1;
280 
281  for (int i=0; i<tot_nrow; i++){
282  int ipart = i%s;
283  int const * pja = csrs[ipart]->JA();
284  int const * pia = csrs[ipart]->IA();
285  int i_nnz = pia[i/s+1]-pia[i/s];
286  memcpy(csr_vs+(csr_ia[i]-1)*v_sz,
287  csrs[ipart]->vals()+(pia[i/s]-1)*v_sz,
288  i_nnz*v_sz);
289  memcpy(csr_ja+(csr_ia[i]-1),
290  pja+(pia[i/s]-1),
291  i_nnz*sizeof(int));
292  csr_ia[i+1] = csr_ia[i]+i_nnz;
293  }
294  for (int i=0; i<s; i++){
295  delete csrs[i];
296  }
297  }
298 
299  void CSR_Matrix::print(algstrct const * sr){
300  char * csr_vs = vals();
301  int * csr_ja = JA();
302  int * csr_ia = IA();
303  int irow= 0;
304  int v_sz = val_size();
305  int64_t nz = nnz();
306  printf("CSR Matrix has %ld nonzeros %d rows %d cols\n", nz, nrow(), ncol());
307  for (int64_t i=0; i<nz; i++){
308  while (i>=csr_ia[irow+1]-1) irow++;
309  printf("[%d,%d] ",irow,csr_ja[i]);
310  sr->print(csr_vs+v_sz*i);
311  printf("\n");
312  }
313 
314  }
315 
317  int const * JA,
318  int const * IA,
319  int const * JB,
320  int const * IB,
321  int i,
322  int * has_col){
323  for (int j=0; j<IA[i+1]-IA[i]; j++){
324  int row_B = JA[IA[i]+j-1]-1;
325  for (int k=0; k<IB[row_B+1]-IB[row_B]; k++){
326  int idx_B = IB[row_B]+k-1;
327  has_col[JB[idx_B]-1] = 1;
328  }
329  }
330  }
331 
332  char * CSR_Matrix::csr_add(char * cA, char * cB, accumulatable const * adder){
334  CSR_Matrix A(cA);
335  CSR_Matrix B(cB);
336 
337  int el_size = A.val_size();
338 
339  char const * vA = A.vals();
340  int const * JA = A.JA();
341  int const * IA = A.IA();
342  int nrow = A.nrow();
343  char const * vB = B.vals();
344  int const * JB = B.JA();
345  int const * IB = B.IA();
346  ASSERT(nrow == B.nrow());
347  int ncol = std::max(A.ncol(),B.ncol());
348  int * IC = (int*)alloc(sizeof(int)*(nrow+1));
349  int * has_col = (int*)alloc(sizeof(int)*ncol);
350  IC[0] = 1;
351  for (int i=0; i<nrow; i++){
352  memset(has_col, 0, sizeof(int)*ncol);
353  IC[i+1] = IC[i];
354  for (int j=0; j<IA[i+1]-IA[i]; j++){
355  has_col[JA[IA[i]+j-1]-1] = 1;
356  }
357  for (int j=0; j<IB[i+1]-IB[i]; j++){
358  has_col[JB[IB[i]+j-1]-1] = 1;
359  }
360  for (int j=0; j<ncol; j++){
361  IC[i+1] += has_col[j];
362  }
363  }
364  CSR_Matrix C(IC[nrow]-1, nrow, ncol, adder);
365  char * vC = C.vals();
366  int * JC = C.JA();
367  memcpy(C.IA(), IC, sizeof(int)*(nrow+1));
368  cdealloc(IC);
369  IC = C.IA();
370  int64_t * rev_col = (int64_t*)alloc(sizeof(int64_t)*ncol);
371  for (int i=0; i<nrow; i++){
372  memset(has_col, 0, sizeof(int)*ncol);
373  for (int j=0; j<IA[i+1]-IA[i]; j++){
374  has_col[JA[IA[i]+j-1]-1] = 1;
375  }
376  for (int j=0; j<IB[i+1]-IB[i]; j++){
377  has_col[JB[IB[i]+j-1]-1] = 1;
378  }
379  int vs = 0;
380  for (int j=0; j<ncol; j++){
381  if (has_col[j]){
382  JC[IC[i]+vs-1] = j+1;
383  //FIXME:: overflow?
384  rev_col[j] = (IC[i]+vs-1)*el_size;
385  vs++;
386  }
387  }
388  memset(has_col, 0, sizeof(int)*ncol);
389  for (int j=0; j<IA[i+1]-IA[i]; j++){
390  int idx_A = IA[i]+j-1;
391  memcpy(vC+rev_col[JA[idx_A]-1],vA+idx_A*el_size,el_size);
392  has_col[JA[idx_A]-1] = 1;
393  }
394  for (int j=0; j<IB[i+1]-IB[i]; j++){
395  int idx_B = IB[i]+j-1;
396  if (has_col[JB[idx_B]-1])
397  adder->accum(vB+idx_B*el_size,vC+rev_col[JB[idx_B]-1]);
398  else
399  memcpy(vC+rev_col[JB[idx_B]-1],vB+idx_B*el_size,el_size);
400  }
401  }
402  cdealloc(has_col);
403  cdealloc(rev_col);
404  /*printf("nnz C is %ld\n", C.nnz());
405  printf("%d %d %d\n",C.IA()[0],C.IA()[1],C.IA()[2]);
406  printf("%d %d\n",C.JA()[0],C.JA()[1]);
407  printf("%lf %lf\n",((double*)C.vals())[0],((double*)C.vals())[1]);*/
409 
410  return C.all_data;
411  }
412 
413 }
virtual void csrmultd(int m, int n, int k, char const *alpha, char const *A, int const *JA, int const *IA, int64_t nnz_A, char const *B, int const *JB, int const *IB, int64_t nnz_B, char const *beta, char *C) const
sparse version of gemm using CSR format for A and B
Definition: algstrct.cxx:714
int * rows() const
retrieves pointer to array row indices of each value
Definition: coo.cxx:61
int * IA() const
retrieves prefix sum of number of nonzeros for each row (of size nrow()+1) out of all_data ...
Definition: csr.cxx:107
virtual bool isequal(char const *a, char const *b) const
returns true if algstrct elements a and b are equal
Definition: algstrct.cxx:340
virtual void ccsrmultcsr(int m, int n, int k, char const *A, int const *JA, int const *IA, int nnz_A, char const *B, int const *JB, int const *IB, int nnz_B, char *&C_CSR, algstrct const *sr_C) const
Definition: ctr_comm.h:135
static char * csr_add(char *cA, char *cB, accumulatable const *adder)
Definition: csr.cxx:332
#define ASSERT(...)
Definition: util.h:88
void * alloc(int64_t len)
alloc abstraction
Definition: memcontrol.cxx:365
virtual void accum(char const *a, char *b) const
b+=a
Definition: algstrct.h:19
untyped internal class for triply-typed bivariate function
Definition: ctr_comm.h:16
static void csrmultcsr(char const *A, algstrct const *sr_A, int m, int n, int k, char const *alpha, char const *B, algstrct const *sr_B, char const *beta, char *&C, algstrct const *sr_C, bivar_function const *func, bool do_offload)
computes C = beta*C + func(alpha*A*B) where A, B, and C are CSR_Matrices, while C is dense ...
Definition: csr.cxx:188
static void compute_has_col(int const *JA, int const *IA, int const *JB, int const *IB, int i, int *has_col)
Definition: csr.cxx:316
int ncol() const
retrieves number of columns out of all_data
Definition: csr.cxx:97
void print(algstrct const *sr)
outputs matrix data to stdout, intended for debugging
Definition: csr.cxx:299
virtual void coffload_csrmm(int m, int n, int k, char const *all_data, char const *B, char *C) const
Definition: ctr_comm.h:150
int * cols() const
retrieves pointer to array of column indices for each value
Definition: coo.cxx:68
int64_t nnz() const
retrieves number of nonzeros out of all_data
Definition: coo.cxx:45
int * JA() const
retrieves column indices of each value in vals stored in sorted form by row
Definition: csr.cxx:119
int64_t nnz() const
retrieves number of nonzeros out of all_data
Definition: csr.cxx:80
serialized matrix in coordinate format, meaning three arrays of dimension nnz are stored...
Definition: coo.h:14
#define ALIGN
Definition: csr.cxx:5
abstract class that knows how to add
Definition: algstrct.h:13
int alloc_ptr(int64_t len, void **const ptr)
alloc abstraction
Definition: memcontrol.cxx:320
abstraction for a serialized sparse matrix stored in column-sparse-row (CSR) layout ...
Definition: csr.h:22
virtual void csrmm(int m, int n, int k, char const *alpha, char const *A, int const *JA, int const *IA, int64_t nnz_A, char const *B, char const *beta, char *C, bivar_function const *func) const
sparse version of gemm using CSR format for A
Definition: algstrct.cxx:708
#define TAU_FSTOP(ARG)
Definition: util.h:281
virtual void ccsrmultd(int m, int n, int k, char const *A, int const *JA, int const *IA, int nnz_A, char const *B, int const *JB, int const *IB, int nnz_B, char *C, algstrct const *sr_C) const
Definition: ctr_comm.h:120
#define TAU_FSTART(ARG)
Definition: util.h:280
virtual void print(char const *a, FILE *fp=stdout) const
prints the value
Definition: algstrct.cxx:170
virtual void ccsrmm(int m, int n, int k, char const *A, int const *JA, int const *IA, int64_t nnz_A, char const *B, char *C, algstrct const *sr_C) const
Definition: ctr_comm.h:108
int nrow() const
retrieves number of rows out of all_data
Definition: csr.cxx:93
int val_size() const
retrieves matrix entry size out of all_data
Definition: coo.cxx:49
char * all_data
serialized buffer containing all info, index, and values related to matrix
Definition: csr.h:25
char * vals() const
retrieves array of values out of all_data
Definition: csr.cxx:101
int el_size
size of each element of algstrct in bytes
Definition: algstrct.h:16
static void csrmm(char const *A, algstrct const *sr_A, int m, int n, int k, char const *alpha, char const *B, algstrct const *sr_B, char const *beta, char *C, algstrct const *sr_C, bivar_function const *func, bool do_offload)
computes C = beta*C + func(alpha*A*B) where A is a CSR_Matrix, while B and C are dense ...
Definition: csr.cxx:134
int cdealloc(void *ptr)
free abstraction
Definition: memcontrol.cxx:480
algstrct (algebraic structure) defines the elementwise operations computed in each tensor contraction...
Definition: algstrct.h:34
int64_t get_csr_size(int64_t nnz, int nrow_, int val_size)
computes the size of a serialized CSR matrix
Definition: csr.cxx:8
void partition(int s, char **parts_buffer, CSR_Matrix **parts)
splits CSR matrix into s submatrices (returned) corresponding to subsets of rows, all parts allocated...
Definition: csr.cxx:219
virtual void csrmultcsr(int m, int n, int k, char const *alpha, char const *A, int const *JA, int const *IA, int64_t nnz_A, char const *B, int const *JB, int const *IB, int64_t nnz_B, char const *beta, char *&C_CSR) const
Definition: algstrct.cxx:733
int val_size() const
retrieves matrix entry size out of all_data
Definition: csr.cxx:84
virtual void coo_to_csr(int64_t nz, int nrow, char *csr_vs, int *csr_cs, int *csr_rs, char const *coo_vs, int const *coo_rs, int const *coo_cs) const
converts coordinate sparse matrix layout to CSR layout
Definition: algstrct.cxx:350
virtual void init_shell(int64_t n, char *arr) const
initialize n objects to zero
Definition: algstrct.h:26
int64_t size() const
retrieves buffer size out of all_data
Definition: csr.cxx:89
static void csrmultd(char const *A, algstrct const *sr_A, int m, int n, int k, char const *alpha, char const *B, algstrct const *sr_B, char const *beta, char *C, algstrct const *sr_C, bivar_function const *func, bool do_offload)
computes C = beta*C + func(alpha*A*B) where A and B are CSR_Matrices, while C is dense ...
Definition: csr.cxx:158
virtual char const * mulid() const
identity element for multiplication i.e. 1
Definition: algstrct.cxx:93
char * vals() const
retrieves pointer to array of values out of all_data
Definition: coo.cxx:57