Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
functions.h
Go to the documentation of this file.
1 #ifndef __FUNCTIONS_H__
2 #define __FUNCTIONS_H__
3 
4 #include "../scaling/scaling.h"
5 #include "../summation/summation.h"
6 #include "../contraction/contraction.h"
7 
8 
9 namespace CTF {
10 
17  class Idx_Tensor;
18 
22  template<typename dtype=double>
24  public:
28  //dtype (*f)(dtype);
29  std::function<void(dtype&)> f;
30 
35  Endomorphism(std::function<void(dtype&)> f_){ f = f_; }
40 
46  void apply_f(char * a) const { f(((dtype*)a)[0]); }
47  };
48 
49 
54  template<typename dtype_A=double, typename dtype_B=dtype_A>
56  public:
60  //dtype_B (*f)(dtype_A);
61  std::function<dtype_B(dtype_A)> f;
62 
67  Univar_Function(std::function<dtype_B(dtype_A)> f_){ f = f_; }
68 
69 
75  void apply_f(char const * a, char * b) const { ((dtype_B*)b)[0]=f(((dtype_A*)a)[0]); }
76 
83  void acc_f(char const * a, char * b, CTF_int::algstrct const * sr_B) const {
84  dtype_B tb=f(((dtype_A*)a)[0]);
85  sr_B->add(b, (char const *)&tb, b);
86  }
87 
88  };
89 
90 
95  template<typename dtype_A=double, typename dtype_B=dtype_A>
97  public:
101  //void (*f)(dtype_A, dtype_B &);
102  std::function<void(dtype_A, dtype_B &)> f;
103 
108  Univar_Transform(std::function<void(dtype_A, dtype_B &)> f_){ f = f_; }
109 
110 
116  void apply_f(char const * a, char * b) const { acc_f(a,b,NULL); }
117 
124  void acc_f(char const * a, char * b, CTF_int::algstrct const * sr_B) const {
125  f(((dtype_A*)a)[0], ((dtype_B*)b)[0]);
126  }
127 
128  bool is_accumulator() const { return true; }
129  };
130 
131 
136  template<typename dtype_A=double, typename dtype_B=dtype_A, typename dtype_C=dtype_A>
138  public:
142  //dtype_C (*f)(dtype_A, dtype_B);
143  std::function<dtype_C (dtype_A, dtype_B)> f;
144 
149  Bivar_Function(std::function<dtype_C (dtype_A, dtype_B)> f_)
150  : CTF_int::bivar_function(){
151  f=f_; commutative=0;
152  }
153 
159  Bivar_Function(std::function<dtype_C (dtype_A, dtype_B)> f_,
160  bool is_comm)
161  : CTF_int::bivar_function(is_comm){
162  f=f_;
163  }
164 
168  Bivar_Function();
169 
170 
177  void apply_f(char const * a, char const * b, char * c) const {
178  ((dtype_C*)c)[0] = f(((dtype_A const*)a)[0],((dtype_B const*)b)[0]);
179  }
180 
188  void acc_f(char const * a, char const * b, char * c, CTF_int::algstrct const * sr_C) const {
189  dtype_C tmp;
190  tmp = f(((dtype_A const*)a)[0],((dtype_B const*)b)[0]);
191  sr_C->add(c, (char const *)&tmp, c);
192  }
193 
194 
195  // FIXME: below kernels replicate code from src/interface/semiring.h
196  void csrmm(int m,
197  int n,
198  int k,
199  dtype_A const * A,
200  int const * JA,
201  int const * IA,
202  int64_t nnz_A,
203  dtype_B const * B,
204  dtype_C * C,
205  CTF_int::algstrct const * sr_C) const {
206  //TAU_FSTART(3type_csrmm);
207  #ifdef _OPENMP
208  #pragma omp parallel for
209  #endif
210  for (int row_A=0; row_A<m; row_A++){
211  #ifdef _OPENMP
212  #pragma omp parallel for
213  #endif
214  for (int col_B=0; col_B<n; col_B++){
215  for (int i_A=IA[row_A]-1; i_A<IA[row_A+1]-1; i_A++){
216  int col_A = JA[i_A]-1;
217  dtype_C tmp = f(A[i_A],B[col_B*k+col_A]);
218  sr_C->add((char const *)&C[col_B*m+row_A],(char const*)&tmp,(char *)&C[col_B*m+row_A]);
219 
220  }
221  }
222  }
223  //TAU_FSTOP(3type_csrmm);
224  }
225 
226 
227  void csrmultd
228  (int m,
229  int n,
230  int k,
231  dtype_A const * A,
232  int const * JA,
233  int const * IA,
234  int nnz_A,
235  dtype_B const * B,
236  int const * JB,
237  int const * IB,
238  int nnz_B,
239  dtype_C * C,
240  CTF_int::algstrct const * sr_C) const {
241  #ifdef _OPENMP
242  #pragma omp parallel for
243  #endif
244  for (int row_A=0; row_A<m; row_A++){
245  for (int i_A=IA[row_A]-1; i_A<IA[row_A+1]-1; i_A++){
246  int row_B = JA[i_A]-1; //=col_A
247  for (int i_B=IB[row_B]-1; i_B<IB[row_B+1]-1; i_B++){
248  int col_B = JB[i_B]-1;
249  dtype_C tmp = f(A[i_A],B[i_B]);
250  sr_C->add((char const*)&C[col_B*m+row_A],(char const*)&tmp,(char *)&C[col_B*m+row_A]);
251  }
252  }
253  }
254  }
255 
256 
257  void csrmultcsr
258  (int m,
259  int n,
260  int k,
261  dtype_A const * A,
262  int const * JA,
263  int const * IA,
264  int nnz_A,
265  dtype_B const * B,
266  int const * JB,
267  int const * IB,
268  int nnz_B,
269  char *& C_CSR,
270  CTF_int::algstrct const * sr_C) const {
271  int * IC = (int*)CTF_int::alloc(sizeof(int)*(m+1));
272  int * has_col = (int*)CTF_int::alloc(sizeof(int)*n);
273  IC[0] = 1;
274  for (int i=0; i<m; i++){
275  memset(has_col, 0, sizeof(int)*n);
276  IC[i+1] = IC[i];
277  CTF_int::CSR_Matrix::compute_has_col(JA, IA, JB, IB, i, has_col);
278  for (int j=0; j<n; j++){
279  IC[i+1] += has_col[j];
280  }
281  }
282  CTF_int::CSR_Matrix C(IC[m]-1, m, n, sr_C);
283  dtype_C * vC = (dtype_C*)C.vals();
284  int * JC = C.JA();
285  memcpy(C.IA(), IC, sizeof(int)*(m+1));
286  CTF_int::cdealloc(IC);
287  IC = C.IA();
288  int64_t * rev_col = (int64_t*)CTF_int::alloc(sizeof(int64_t)*n);
289  for (int i=0; i<m; i++){
290  memset(has_col, 0, sizeof(int)*n);
291  CTF_int::CSR_Matrix::compute_has_col(JA, IA, JB, IB, i, has_col);
292  int vs = 0;
293  for (int j=0; j<n; j++){
294  if (has_col[j]){
295  JC[IC[i]+vs-1] = j+1;
296  rev_col[j] = IC[i]+vs-1;
297  vs++;
298  }
299  }
300  memset(has_col, 0, sizeof(int)*n);
301  for (int j=0; j<IA[i+1]-IA[i]; j++){
302  int row_B = JA[IA[i]+j-1]-1;
303  int idx_A = IA[i]+j-1;
304  for (int l=0; l<IB[row_B+1]-IB[row_B]; l++){
305  int idx_B = IB[row_B]+l-1;
306  if (has_col[JB[idx_B]-1]){
307  dtype_C tmp = f(A[idx_A],B[idx_B]);
308  sr_C->add((char const *)&vC[rev_col[JB[idx_B]-1]], (char const *)&tmp, (char *)&vC[rev_col[JB[idx_B]-1]]);
309  } else {
310  vC[rev_col[JB[idx_B]-1]] = f(A[idx_A],B[idx_B]);
311  }
312  has_col[JB[idx_B]-1] = 1;
313  }
314  }
315  }
316  CTF_int::CSR_Matrix C_in(C_CSR);
317  if (C_CSR == NULL || C_in.nnz() == 0){
318  C_CSR = C.all_data;
319  } else {
320  char * ans = CTF_int::CSR_Matrix::csr_add(C_CSR, C.all_data, sr_C);
322  C_CSR = ans;
323  }
324  CTF_int::cdealloc(has_col);
325  CTF_int::cdealloc(rev_col);
326  }
327 
328  void ccsrmm(int m,
329  int n,
330  int k,
331  char const * A,
332  int const * JA,
333  int const * IA,
334  int64_t nnz_A,
335  char const * B,
336  char * C,
337  CTF_int::algstrct const * sr_C) const {
338  csrmm(m,n,k,(dtype_A const *)A,JA,IA,nnz_A,(dtype_B const *)B, (dtype_C *)C, sr_C);
339  }
340 
341  void ccsrmultd
342  (int m,
343  int n,
344  int k,
345  char const * A,
346  int const * JA,
347  int const * IA,
348  int nnz_A,
349  char const * B,
350  int const * JB,
351  int const * IB,
352  int nnz_B,
353  char * C,
354  CTF_int::algstrct const * sr_C) const {
355  csrmultd(m,n,k,(dtype_A const *)A,JA,IA,nnz_A,(dtype_B const *)B,JB,IB,nnz_B,(dtype_C *)C,sr_C);
356  }
357 
358  void ccsrmultcsr
359  (int m,
360  int n,
361  int k,
362  char const * A,
363  int const * JA,
364  int const * IA,
365  int nnz_A,
366  char const * B,
367  int const * JB,
368  int const * IB,
369  int nnz_B,
370  char *& C_CSR,
371  CTF_int::algstrct const * sr_C) const {
372  csrmultcsr(m,n,k,(dtype_A const *)A,JA,IA,nnz_A,(dtype_B const *)B, JB, IB, nnz_B, C_CSR, sr_C);
373  }
374 
375 
376 
377 
378  };
379 
384  template<typename dtype_A=double, typename dtype_B=dtype_A, typename dtype_C=dtype_A>
386  public:
390  //void (*f)(dtype_A, dtype_B &);
391  std::function<void(dtype_A, dtype_B, dtype_C &)> f;
392 
397  Bivar_Transform(std::function<void(dtype_A, dtype_B, dtype_C &)> f_)
398  : CTF_int::bivar_function() {
399  f = f_;
400  }
401 
407  Bivar_Transform(std::function<void(dtype_A, dtype_B, dtype_C &)> f_,
408  bool is_comm)
409  : CTF_int::bivar_function(is_comm){
410  f=f_;
411  }
412 
420  void acc_f(char const * a, char const * b, char * c, CTF_int::algstrct const * sr_B) const {
421  f(((dtype_A*)a)[0], ((dtype_B*)b)[0], ((dtype_C*)c)[0]);
422  }
423 
430  void apply_f(char const * a, char const * b, char * c) const { acc_f(a,b,c,NULL); }
431 
432 
433  bool is_accumulator() const { return true; }
434 
435  };
436 
437 
438 
439 
440  template<typename dtype_A=double, typename dtype_B=dtype_A, typename dtype_C=dtype_A>
441  class Function {
442  public:
443  bool is_univar;
445  bool is_bivar;
447 
448  Function(std::function<dtype_B(dtype_A)> f_){
449  is_univar = true;
450  is_bivar = false;
451  univar = new Univar_Function<dtype_A, dtype_B>(f_);
452  }
453 
454 
455  Function(std::function<dtype_C(dtype_A,dtype_B)> f_, bool is_comm=false){
456  is_univar = false;
457  is_bivar = true;
458  bivar = new Bivar_Function<dtype_A, dtype_B, dtype_C>(f_,is_comm);
459  }
460 
462  assert(is_univar);
463  return univar->operator()(A);
464  }
465 
467  assert(is_bivar);
468  return bivar->operator()(A,B);
469  }
470 
472  assert(is_univar);
473  return *univar;
474  }
475 
477  assert(is_bivar);
478  return *bivar;
479  }
480 
482  if (is_univar) delete(univar);
483  if (is_bivar) delete(bivar);
484  }
485  };
486 
487  template<typename dtype_A=double, typename dtype_B=dtype_A, typename dtype_C=dtype_A>
488  class Transform {
489  public:
490  bool is_endo;
492  bool is_univar;
494  bool is_bivar;
496 
497  Transform(std::function<void(dtype_A&)> f_){
498  is_endo = true;
499  is_univar = false;
500  is_bivar = false;
501  endo = new Endomorphism<dtype_A>(f_);
502  }
503 
504  Transform(std::function<void(dtype_A, dtype_B&)> f_){
505  is_endo = false;
506  is_univar = true;
507  is_bivar = false;
508  univar = new Univar_Transform<dtype_A, dtype_B>(f_);
509  }
510 
511  Transform(std::function<void(dtype_A, dtype_B, dtype_C&)> f_){
512  is_endo = false;
513  is_univar = false;
514  is_bivar = true;
516  }
517 
518 
520  if (is_endo) delete endo;
521  if (is_univar) delete univar;
522  if (is_bivar) delete bivar;
523  }
524 
525  void operator()(CTF_int::Term const & A) const {
526  assert(is_endo);
527  endo->operator()(A);
528  }
529 
530  void operator()(CTF_int::Term const & A, CTF_int::Term const & B) const {
531  assert(is_univar);
532  univar->operator()(A,B);
533  }
534 
535  void operator()(CTF_int::Term const & A, CTF_int::Term const & B, CTF_int::Term const & C) const {
536  assert(is_bivar);
537  bivar->operator()(A,B,C);
538  }
539 
541  assert(is_bivar);
542  return *bivar;
543  }
544 
546  assert(is_univar);
547  return *univar;
548  }
549 
551  assert(is_endo);
552  return *endo;
553  }
554 
555  bool is_accumulator() const { return true; }
556  };
557 
561 }
562 
563 #endif
564 
CTF_int::Unifun_Term operator()(CTF_int::Term const &A) const
Definition: functions.h:461
a term is an abstract object representing some expression of tensors
Definition: term.h:33
std::function< dtype_C(dtype_A, dtype_B)> f
function signature for element-wise multiplication, compute C=f(A,B)
Definition: functions.h:143
Bivar_Function(std::function< dtype_C(dtype_A, dtype_B)> f_)
constructor takes function pointers to compute C=f(A,B);
Definition: functions.h:149
custom scalar function on tensor: e.g. A["ij"] = f(A["ij"])
Definition: functions.h:23
void csrmm(int m, int n, int k, dtype_A const *A, int const *JA, int const *IA, int64_t nnz_A, dtype_B const *B, dtype_C *C, CTF_int::algstrct const *sr_C) const
Definition: functions.h:196
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
Endomorphism()
default constructor
Definition: functions.h:39
void operator()(CTF_int::Term const &A) const
Definition: functions.h:525
void acc_f(char const *a, char *b, CTF_int::algstrct const *sr_B) const
compute f(a,b)
Definition: functions.h:124
untyped internal class for singly-typed single variable function (Endomorphism)
Definition: sym_seq_scl.h:12
Univar_Transform(std::function< void(dtype_A, dtype_B &)> f_)
constructor takes function pointers to compute B=f(A));
Definition: functions.h:108
static char * csr_add(char *cA, char *cB, accumulatable const *adder)
Definition: csr.cxx:332
void apply_f(char *a) const
apply function f to value stored at a
Definition: functions.h:46
Endomorphism< dtype_A > * endo
Definition: functions.h:491
int bivar_function(int n, World &dw)
Bivar_Transform(std::function< void(dtype_A, dtype_B, dtype_C &)> f_, bool is_comm)
constructor takes function pointers to compute C=f(A,B);
Definition: functions.h:407
void * alloc(int64_t len)
alloc abstraction
Definition: memcontrol.cxx:365
custom bivariate function on two tensors: e.g. C["ij"] = f(A["ik"],B["kj"])
Definition: functions.h:137
untyped internal class for doubly-typed univariate function
Definition: sum_tsr.h:14
std::function< void(dtype &)> f
function signature for element-wise operation a=f(a)
Definition: functions.h:29
untyped internal class for triply-typed bivariate function
Definition: ctr_comm.h:16
Bivar_Function(std::function< dtype_C(dtype_A, dtype_B)> f_, bool is_comm)
constructor takes function pointers to compute C=f(A,B);
Definition: functions.h:159
Univar_Function< dtype_A, dtype_B > * univar
Definition: functions.h:444
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
custom function f : X -> Y to be applied to tensor elemetns: e.g. B["ij"] = f(A["ij"]) ...
Definition: functions.h:55
void operator()(CTF_int::Term const &A, CTF_int::Term const &B, CTF_int::Term const &C) const
Definition: functions.h:535
Univar_Function(std::function< dtype_B(dtype_A)> f_)
constructor takes function pointers to compute B=f(A));
Definition: functions.h:67
void acc_f(char const *a, char const *b, char *c, CTF_int::algstrct const *sr_B) const
compute f(a,b)
Definition: functions.h:420
custom function f : (X * Y * Z) -> Z applied on three tensors as contraction: e.g. f(A["ij"],B["ij"],C["ij"])
Definition: functions.h:385
Endomorphism(std::function< void(dtype &)> f_)
constructor takes function pointer
Definition: functions.h:35
Bivar_Transform(std::function< void(dtype_A, dtype_B, dtype_C &)> f_)
constructor takes function pointers to compute B=f(A));
Definition: functions.h:397
int * JA() const
retrieves column indices of each value in vals stored in sorted form by row
Definition: csr.cxx:119
Transform(std::function< void(dtype_A, dtype_B, dtype_C &)> f_)
Definition: functions.h:511
void acc_f(char const *a, char const *b, char *c, CTF_int::algstrct const *sr_C) const
compute c = c+ f(a,b)
Definition: functions.h:188
void operator()(CTF_int::Term const &A, CTF_int::Term const &B) const
Definition: functions.h:530
int64_t nnz() const
retrieves number of nonzeros out of all_data
Definition: csr.cxx:80
bool is_accumulator() const
Definition: functions.h:555
void acc_f(char const *a, char *b, CTF_int::algstrct const *sr_B) const
compute b = b+f(a)
Definition: functions.h:83
abstraction for a serialized sparse matrix stored in column-sparse-row (CSR) layout ...
Definition: csr.h:22
std::function< dtype_B(dtype_A)> f
function signature for element-wise multiplication, compute b=f(a)
Definition: functions.h:61
Univar_Transform< dtype_A, dtype_B > * univar
Definition: functions.h:493
Bivar_Function< dtype_A, dtype_B, dtype_C > * bivar
Definition: functions.h:446
Function(std::function< dtype_B(dtype_A)> f_)
Definition: functions.h:448
bool is_univar
Definition: functions.h:443
Transform(std::function< void(dtype_A &)> f_)
Definition: functions.h:497
void apply_f(char const *a, char *b) const
apply function f to value stored at a, for an accumulator, this is the same as acc_f below ...
Definition: functions.h:116
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
virtual void add(char const *a, char const *b, char *c) const
c = a+b
Definition: algstrct.cxx:109
bool is_accumulator() const
Definition: functions.h:128
Transform(std::function< void(dtype_A, dtype_B &)> f_)
Definition: functions.h:504
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
Definition: apsp.cxx:17
bool is_accumulator() const
Definition: functions.h:433
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, CTF_int::algstrct const *sr_C) const
Definition: functions.h:328
void apply_f(char const *a, char const *b, char *c) const
apply function f to value stored at a, for an accumulator, this is the same as acc_f below ...
Definition: functions.h:430
CTF_int::Bifun_Term operator()(CTF_int::Term const &A, CTF_int::Term const &B) const
Definition: functions.h:466
std::function< void(dtype_A, dtype_B, dtype_C &)> f
function signature for element-wise multiplication, compute b=f(a)
Definition: functions.h:391
void apply_f(char const *a, char const *b, char *c) const
compute c = f(a,b)
Definition: functions.h:177
Bivar_Transform< dtype_A, dtype_B, dtype_C > * bivar
Definition: functions.h:495
Function(std::function< dtype_C(dtype_A, dtype_B)> f_, bool is_comm=false)
Definition: functions.h:455
void apply_f(char const *a, char *b) const
apply function f to value stored at a
Definition: functions.h:75
custom function f : (X * Y) -> X applied on two tensors as summation: e.g. B["ij"] = f(A["ij"]...
Definition: functions.h:96
std::function< void(dtype_A, dtype_B &)> f
function signature for element-wise multiplication, compute b=f(a)
Definition: functions.h:102