Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
matrix.cxx
Go to the documentation of this file.
1 /*Copyright (c) 2011, Edgar Solomonik, all rights reserved.*/
2 
3 #include "common.h"
4 #include "world.h"
5 #include "../shared/blas_symbs.h"
6 #include "../shared/lapack_symbs.h"
7 #include <stdlib.h>
8 
9 
10 namespace CTF_int{
11  struct int2
12  {
13  int i[2];
14  int2(int a, int b)
15  {
16  i[0] = a;
17  i[1] = b;
18  }
19  operator const int*() const
20  {
21  return i;
22  }
23  };
24 }
25 
26 
27 namespace CTF {
28  template<typename dtype>
30  nrow = -1;
31  ncol = -1;
32  }
33 
34  template<typename dtype>
36  : Tensor<dtype>(A) {
37  nrow = A.nrow;
38  ncol = A.ncol;
39  symm = A.symm;
40  }
41 
42  template<typename dtype>
44  : Tensor<dtype>(A) {
45  assert(A.order == 2);
46  nrow = A.lens[0];
47  ncol = A.lens[1];
48  switch (A.sym[0]){
49  case NS:
50  symm=NS;
51  break;
52  case SY:
53  symm=SY;
54  break;
55  case AS:
56  symm=AS;
57  break;
58  default:
59  IASSERT(0);
60  break;
61  }
62  }
63 
64 
65  template<typename dtype>
67  int ncol_,
68  World & world_,
69  CTF_int::algstrct const & sr_,
70  char const * name_,
71  int profile_)
72  : Tensor<dtype>(2, false, CTF_int::int2(nrow_, ncol_), CTF_int::int2(NS, NS),
73  world_, sr_, name_, profile_) {
74  nrow = nrow_;
75  ncol = ncol_;
76  symm = NS;
77  }
78 
79  template<typename dtype>
81  int ncol_,
82  int atr_,
83  World & world_,
84  CTF_int::algstrct const & sr_,
85  char const * name_,
86  int profile_)
87  : Tensor<dtype>(2, (atr_&4)>0, CTF_int::int2(nrow_, ncol_), CTF_int::int2(atr_&3, NS),
88  world_, sr_, name_, profile_) {
89  nrow = nrow_;
90  ncol = ncol_;
91  symm = atr_&3;
92  }
93 
94  template<typename dtype>
96  int ncol_,
97  World & world_,
98  char const * name_,
99  int profile_,
100  CTF_int::algstrct const & sr_)
101  : Tensor<dtype>(2, false, CTF_int::int2(nrow_, ncol_), CTF_int::int2(NS, NS),
102  world_, sr_, name_, profile_) {
103  nrow = nrow_;
104  ncol = ncol_;
105  symm = 0;
106  }
107 
108 
109  template<typename dtype>
111  int ncol_,
112  int atr_,
113  World & world_,
114  char const * name_,
115  int profile_,
116  CTF_int::algstrct const & sr_)
117  : Tensor<dtype>(2, (atr_&4)>0, CTF_int::int2(nrow_, ncol_), CTF_int::int2(atr_&3, NS),
118  world_, sr_, name_, profile_) {
119  nrow = nrow_;
120  ncol = ncol_;
121  symm = atr_&3;
122  }
123 
124 
125  template<typename dtype>
127  int ncol_,
128  char const * idx,
129  Idx_Partition const & prl,
130  Idx_Partition const & blk,
131  int atr_,
132  World & world_,
133  CTF_int::algstrct const & sr_,
134  char const * name_,
135  int profile_)
136  : Tensor<dtype>(2, (atr_&4)>0, CTF_int::int2(nrow_, ncol_), CTF_int::int2(atr_&3, NS),
137  world_, idx, prl, blk, name_, profile_, sr_) {
138  nrow = nrow_;
139  ncol = ncol_;
140  symm = atr_&3;
141  }
142 
143  template<typename dtype>
145  int64_t nel;
146  dtype * data = (dtype*)malloc(sizeof(dtype)*nrow*ncol);
147  nel = this->read_all(data,true);
148  if (this->wrld->rank == 0){
149  for (int i=0; i<nrow; i++){
150  for (int j=0; j<ncol; j++){
151  this->sr->print((char*)&(data[j*nrow+i]));
152  if (j!=ncol-1) printf(" ");
153  }
154  printf("\n");
155  }
156  }
157  free(data);
158  }
159 
160  template<typename dtype>
162  int nrow,
163  int ncol,
164  int mb,
165  int nb,
166  int pr,
167  int pc,
168  int rsrc,
169  int csrc,
170  int64_t & nmyr,
171  int64_t & nmyc,
172  Pair<dtype> *& pairs){
173  nmyr = mb*(nrow/mb/pr);
174  if ((nrow/mb)%pr > (rank+pr-rsrc)%pr){
175  nmyr+=mb;
176  }
177  if (((nrow/mb)%pr) == (rank+pr-rsrc)%pr){
178  nmyr+=nrow%mb;
179  }
180  nmyc = nb*(ncol/nb/pc);
181  if ((ncol/nb)%pc > (rank/pr+pc-csrc)%pc){
182  nmyc+=nb;
183  }
184  if (((ncol/nb)%pc) == (rank/pr+pc-csrc)%pc){
185  nmyc+=ncol%nb;
186  }
187  //printf("nrow = %d ncol = %d nmyr = %ld, nmyc = %ld mb = %d nb = %d pr = %d pc = %d\n",nrow,ncol,nmyr,nmyc,mb,nb,pr,pc);
188  pairs = new Pair<dtype>[nmyr*nmyc];
189  int cblk = (rank/pr+pc-csrc)%pc;
190  for (int64_t i=0; i<nmyc; i++){
191  int rblk = (rank+pr-rsrc)%pr;
192  for (int64_t j=0; j<nmyr; j++){
193  pairs[i*nmyr+j].k = (cblk*nb+(i%nb))*nrow+rblk*mb+(j%mb);
194  // pairs[i*nmyr+j].d = *(dtype*)this->sr->addid();
195  //printf("RANK = %d, pairs[%ld].k=%ld\m",rank,i*nmyr+j,pairs[i*nmyr+j].k);
196  if ((j+1)%mb == 0) rblk += pr;
197  }
198  if ((i+1)%nb == 0) cblk += pc;
199  }
200  }
201 
202  template<typename dtype>
204  int nb,
205  int pr,
206  int pc,
207  int rsrc,
208  int csrc,
209  int lda,
210  dtype const * data_){
211  if (mb==1 && nb==1 && nrow%pr==0 && ncol%pc==0 && rsrc==0 && csrc==0){
212  if (this->edge_map[0].np == pr && this->edge_map[1].np == pc){
213  if (lda == nrow/pc){
214  memcpy(this->data, (char*)data_, sizeof(dtype)*this->size);
215  } else {
216  for (int64_t i=0; i<ncol/pc; i++){
217  memcpy(this->data+i*lda*sizeof(dtype),(char*)(data_+i*lda), ((int64_t)nrow)*sizeof(dtype)/pr);
218  }
219  }
220  } else {
221  Matrix<dtype> M(nrow, ncol, mb, nb, pr, pc, rsrc, csrc, lda, data_);
222  (*this)["ab"] = M["ab"];
223  }
224  } else {
225  Pair<dtype> * pairs;
226  int64_t nmyr, nmyc;
227  get_my_kv_pair(this->wrld->rank, nrow, ncol, mb, nb, pr, pc, rsrc, csrc, nmyr, nmyc, pairs);
228 
229  //printf("lda = %d, nmyr =%ld, nmyc=%ld\n",lda,nmyr,nmyc);
230  if (lda == nmyr){
231  for (int64_t i=0; i<nmyr*nmyc; i++){
232  pairs[i].d = data_[i];
233  }
234  } else {
235  for (int64_t i=0; i<nmyc; i++){
236  for (int64_t j=0; j<nmyr; j++){
237  pairs[i*nmyr+j].d = data_[i*lda+j];
238  }
239  }
240  }
241  this->write(nmyr*nmyc, pairs);
242  delete [] pairs;
243  }
244  }
245 
246  template<typename dtype>
248  int nb,
249  int pr,
250  int pc,
251  int rsrc,
252  int csrc,
253  int lda,
254  dtype * data_){
255  //FIXME: (1) can optimize sparse for this case (mapping cyclic), (2) can use permute to avoid sparse redistribution always
256  if (!this->is_sparse && (mb==1 && nb==1 && nrow%pr==0 && ncol%pc==0 && rsrc==0 && csrc==0)){
257  if (this->edge_map[0].np == pr && this->edge_map[1].np == pc){
258  if (lda == nrow/pc){
259  memcpy((char*)data_, this->data, sizeof(dtype)*this->size);
260  } else {
261  for (int64_t i=0; i<ncol/pc; i++){
262  memcpy((char*)(data_+i*lda), this->data+i*lda*sizeof(dtype), nrow*sizeof(dtype)/pr);
263  }
264  }
265  } else {
266  int plens[] = {pr, pc};
267  Partition ip(2, plens);
268  Matrix M(nrow, ncol, "ij", ip["ij"], Idx_Partition(), 0, *this->wrld, *this->sr);
269  M["ab"] = (*this)["ab"];
270  M.read_mat(mb, nb, pr, pc, rsrc, csrc, lda, data_);
271  }
272  } else {
273  Pair<dtype> * pairs;
274  int64_t nmyr, nmyc;
275  get_my_kv_pair(this->wrld->rank, nrow, ncol, mb, nb, pr, pc, rsrc, csrc, nmyr, nmyc, pairs);
276 
277  this->read(nmyr*nmyc, pairs);
278  if (lda == nmyr){
279  for (int64_t i=0; i<nmyr*nmyc; i++){
280  data_[i] = pairs[i].d;
281  //printf("data %ld = %lf\n",i,data_[i]);
282  }
283  } else {
284  for (int64_t i=0; i<nmyc; i++){
285  for (int64_t j=0; j<nmyr; j++){
286  data_[i*lda+j] = pairs[i*nmyr+j].d;
287  //printf("data %ld %ld = %lf\n",i,j,data_[i*lda+j]);
288  }
289  }
290  }
291  delete [] pairs;
292  }
293  }
294 
295  template<typename dtype>
296  void Matrix<dtype>::get_desc(int & ictxt, int *& desc){
297  int pr, pc;
298  pr = this->edge_map[0].calc_phase();
299  pc = this->edge_map[1].calc_phase();
300  IASSERT(this->wrld->np == pr*pc);
301 
302  char C = 'C';
303  int ctxt;
304  IASSERT(this->wrld->comm == MPI_COMM_WORLD);
305  CTF_SCALAPACK::cblacs_get(-1, 0, &ctxt);
307  gw.pr = pr;
308  gw.pc = pc;
309  std::set<CTF_int::grid_wrapper>::iterator s = CTF_int::scalapack_grids.find(gw);
310  if (s != CTF_int::scalapack_grids.end()){
311  ctxt = s->ctxt;
312  } else {
313  CTF_SCALAPACK::cblacs_gridinit(&ctxt, &C, pr, pc);
314  gw.ctxt = ctxt;
315  CTF_int::scalapack_grids.insert(gw);
316  }
317  ictxt = ctxt;
318 
319  desc = (int*)malloc(sizeof(int)*9);
320  desc[0] = 1;
321  desc[1] = ictxt;
322  desc[2] = nrow;
323  desc[3] = ncol;
324  desc[4] = 1;
325  desc[5] = 1;
326  desc[6] = 0;
327  desc[7] = 0;
328  desc[8] = this->pad_edge_len[0]/pr;
329  }
330 
331  template<typename dtype>
332  void Matrix<dtype>::read_mat(int const * desc,
333  dtype * data_){
334  int ictxt = desc[1];
335  int pr, pc, ipr, ipc;
336  CTF_SCALAPACK::cblacs_gridinfo(ictxt, &pr, &pc, &ipr, &ipc);
337  IASSERT(ipr == this->wrld->rank%pr);
338  IASSERT(ipc == this->wrld->rank/pr);
339 
340  read_mat(desc[4],desc[5],pr,pc,desc[6],desc[7],desc[8],data_);
341  }
342 
343  template<typename dtype>
345  int ncol_,
346  int mb,
347  int nb,
348  int pr,
349  int pc,
350  int rsrc,
351  int csrc,
352  int lda,
353  dtype const * data,
354  World & wrld_,
355  CTF_int::algstrct const & sr_,
356  char const * name_,
357  int profile_)
358  : Tensor<dtype>(2, false, CTF_int::int2(nrow_, ncol_), CTF_int::int2(NS, NS),
359  wrld_, sr_, name_, profile_) {
360  nrow = nrow_;
361  ncol = ncol_;
362  symm = NS;
363  write_mat(mb,nb,pr,pc,rsrc,csrc,lda,data);
364  }
365 
366 
367 
368  static inline Idx_Partition get_map_from_desc(int const * desc){
369 
370  int ictxt = desc[1];
371  int pr, pc, ipr, ipc;
372  CTF_SCALAPACK::cblacs_gridinfo(ictxt, &pr, &pc, &ipr, &ipc);
373  return Partition(2,CTF_int::int2(pr, pc))["ij"];
374  }
375 
376  template<typename dtype>
377  Matrix<dtype>::Matrix(int const * desc,
378  dtype const * data_,
379  World & wrld_,
380  CTF_int::algstrct const & sr_,
381  char const * name_,
382  int profile_)
383  : Tensor<dtype>(2, false, CTF_int::int2(desc[2], desc[3]), CTF_int::int2(NS, NS),
384  wrld_, "ij", get_map_from_desc(desc), Idx_Partition(), name_, profile_, sr_) {
385  nrow = desc[2];
386  ncol = desc[3];
387  symm = NS;
388  int ictxt = desc[1];
389  int pr, pc, ipr, ipc;
390  CTF_SCALAPACK::cblacs_gridinfo(ictxt, &pr, &pc, &ipr, &ipc);
391  IASSERT(ipr == wrld_.rank%pr);
392  IASSERT(ipc == wrld_.rank/pr);
393  IASSERT(pr*pc == wrld_.np);
394  //this->set_distribution("ij", Partition(2,CTF_int::int2(pr, pc))["ij"], Idx_Partition());
395  write_mat(desc[4],desc[5],pr,pc,desc[6],desc[7],desc[8],data_);
396  }
397 
398  template <typename dtype>
400  assert(0);
401  return -1;
402  }
403 
404  template <>
405  inline int get_int_fromreal<float>(float r){
406  return (int)r;
407  }
408  template <>
409  inline int get_int_fromreal<double>(double r){
410  return (int)r;
411  }
412  template <>
413  inline int get_int_fromreal<std::complex<float>>(std::complex<float> r){
414  return (int)r.real();
415  }
416  template <>
417  inline int get_int_fromreal<std::complex<double>>(std::complex<double> r){
418  return (int)r.real();
419  }
420 
421 
422 
423 
424  template<typename dtype>
426 
427  int info;
428 
429  int m = this->nrow;
430  int n = this->ncol;
431 
432  int * desca;// = (int*)malloc(9*sizeof(int));
433 
434  int ictxt;
435  this->get_desc(ictxt, desca);
436  dtype * A = (dtype*)malloc(this->size*sizeof(dtype));
437 
438  this->read_mat(desca, A);
439 
440  dtype * tau = (dtype*)malloc(((int64_t)n)*sizeof(dtype));
441  dtype dlwork;
442  CTF_SCALAPACK::pgeqrf<dtype>(m,n,A,1,1,desca,tau,(dtype*)&dlwork,-1,&info);
443  int lwork = get_int_fromreal<dtype>(dlwork);
444  dtype * work = (dtype*)malloc(((int64_t)lwork)*sizeof(dtype));
445  CTF_SCALAPACK::pgeqrf<dtype>(m,n,A,1,1,desca,tau,work,lwork,&info);
446 
447 
448  dtype * dQ = (dtype*)malloc(this->size*sizeof(dtype));
449  memcpy(dQ,A,this->size*sizeof(dtype));
450 
451  Q = Matrix<dtype>(desca, dQ, (*(this->wrld)));
452  if (m==n)
453  R = Matrix<dtype>(Q);
454  else {
455  R = Matrix<dtype>(desca,dQ,*this->wrld,*this->sr);
456  R = R.slice(0,((int64_t)m)*(n-1)+n-1);
457  }
458 
459 
460  free(work);
461  CTF_SCALAPACK::porgqr<dtype>(m,n,n,dQ,1,1,desca,tau,(dtype*)&dlwork,-1,&info);
462  lwork = get_int_fromreal<dtype>(dlwork);
463  work = (dtype*)malloc(((int64_t)lwork)*sizeof(dtype));
464  CTF_SCALAPACK::porgqr<dtype>(m,n,n,dQ,1,1,desca,tau,work,lwork,&info);
465  Q = Matrix<dtype>(desca, dQ, (*(this->wrld)));
466  free(work);
467  free(tau);
468  free(desca);
469  //make upper-tri
470  int syns[] = {SY, NS};
471  Tensor<dtype> tR(R,syns);
472  int nsns[] = {NS, NS};
473  tR = Tensor<dtype>(tR,nsns);
474  R = CTF::Matrix<dtype>(tR);
475  //R["ij"] = R["ji"];
476  free(A);
477  free(dQ);
478  }
479 
480  template<typename dtype>
482 
483  int info;
484 
485  int m = this->nrow;
486  int n = this->ncol;
487  int k = std::min(m,n);
488 
489 
490  int * desca;// = (int*)malloc(9*sizeof(int));
491  int * descu = (int*)malloc(9*sizeof(int));
492  int * descvt = (int*)malloc(9*sizeof(int));
493 
494  int ictxt;
495  this->get_desc(ictxt, desca);
496 
497  int pr, pc;
498  pr = this->edge_map[0].calc_phase();
499  pc = this->edge_map[1].calc_phase();
500  //CTF_SCALAPACK::cdescinit(desca, m, n, 1, 1, 0, 0, ictxt, m/(*(this->wrld)).np, &info);
501  int64_t mpr = m/pr + (m % pr != 0);
502  int64_t kpr = k/pr + (k % pr != 0);
503  int64_t kpc = k/pc + (k % pc != 0);
504  int64_t npc = n/pc + (n % pc != 0);
505 
506  CTF_SCALAPACK::cdescinit(descu, m, k, 1, 1, 0, 0, ictxt, mpr, &info);
507  CTF_SCALAPACK::cdescinit(descvt, k, n, 1, 1, 0, 0, ictxt, kpr, &info);
508 
509  dtype * A = (dtype*)CTF_int::alloc(this->size*sizeof(dtype));
510 
511 
512  dtype * u = (dtype*)CTF_int::alloc(sizeof(dtype)*mpr*kpc);
513  dtype * s = (dtype*)CTF_int::alloc(sizeof(dtype)*k);
514  dtype * vt = (dtype*)CTF_int::alloc(sizeof(dtype)*kpr*npc);
515  this->read_mat(desca, A);
516 
517  int lwork;
518  dtype dlwork;
519  CTF_SCALAPACK::pgesvd<dtype>('V', 'V', m, n, NULL, 1, 1, desca, NULL, NULL, 1, 1, descu, vt, 1, 1, descvt, &dlwork, -1, &info);
520 
521  lwork = get_int_fromreal<dtype>(dlwork);
522  dtype * work = (dtype*)CTF_int::alloc(sizeof(dtype)*((int64_t)lwork));
523 
524  CTF_SCALAPACK::pgesvd<dtype>('V', 'V', m, n, A, 1, 1, desca, s, u, 1, 1, descu, vt, 1, 1, descvt, work, lwork, &info);
525 
526 
527  U = Matrix<dtype>(descu, u, (*(this->wrld)));
528  VT = Matrix<dtype>(descvt, vt, (*(this->wrld)));
529 
530  S = Vector<dtype>(k, (*(this->wrld)));
531  int64_t sc;
532  dtype * s_data = S.get_raw_data(&sc);
533 
534  int phase = S.edge_map[0].calc_phase();
535  if ((int)(this->wrld->rank) < phase){
536  for (int i = S.edge_map[0].calc_phys_rank(S.topo); i < k; i += phase) {
537  s_data[i/phase] = s[i];
538  }
539  }
540  if (rank > 0 && rank < k) {
541  S = S.slice(0, rank-1);
542  U = U.slice(0, rank*((int64_t)m)-1);
543  VT = VT.slice(0, k*((int64_t)n)-(k-rank+1));
544  }
545 
549  CTF_int::cdealloc(vt);
550  free(desca);
551  free(descu);
552  free(descvt);
553  CTF_int::cdealloc(work);
554 
555  }
556 
557 
558 }
void write_mat(int mb, int nb, int pr, int pc, int rsrc, int csrc, int lda, dtype const *data)
writes a nonsymmetric matrix from a block-cyclic initial distribution this is `cheap&#39; if mb=nb=1...
Definition: matrix.cxx:203
int * sym
symmetries among tensor dimensions
void qr(Matrix< dtype > &Q, Matrix< dtype > &R)
Definition: matrix.cxx:425
int calc_phase() const
compute the phase of a mapping
Definition: mapping.cxx:39
dtype d
tensor value associated with index
Definition: tensor.h:34
void cblacs_get(int contxt, int what, int *val)
Matrix class which encapsulates a 2D tensor.
Definition: matrix.h:18
Typ_Idx_Tensor< dtype > i(char const *idx_map)
Definition: tensor.cxx:141
def rank(self)
Definition: core.pyx:312
Tensor< dtype > slice(int const *offsets, int const *ends) const
cuts out a slice (block) of this tensor A[offsets,ends) result will always be fully nonsymmetric ...
Definition: tensor.cxx:643
int * pad_edge_len
padded tensor edge lengths
int i[2]
Definition: matrix.cxx:13
int64_t size
current size of local tensor data chunk (mapping-dependent)
Vector class which encapsulates a 1D tensor.
Definition: vector.h:14
void * alloc(int64_t len)
alloc abstraction
Definition: memcontrol.cxx:365
void read_all(int64_t *npair, dtype **data, bool unpack=false)
collects the entire tensor data on each process (not memory scalable)
Definition: tensor.cxx:377
Definition: common.h:37
int symm
Definition: matrix.h:20
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
void read_mat(int mb, int nb, int pr, int pc, int rsrc, int csrc, int lda, dtype *data)
reads a nonsymmetric matrix into a block-cyclic initial distribution this is `cheap&#39; if mb=nb=1...
Definition: matrix.cxx:247
bool is_sparse
whether only the non-zero elements of the tensor are stored
int order
number of tensor dimensions
int64_t k
key, global index [i1,i2,...] specified as i1+len[0]*i2+...
Definition: tensor.h:31
#define IASSERT(...)
Definition: common.h:74
int ncol
Definition: matrix.h:20
index-value pair used for tensor data input
Definition: tensor.h:28
CTF::World * wrld
distributed processor context on which tensor is defined
int rank
rank of local processor
Definition: world.h:24
int * lens
unpadded tensor edge lengths
void svd(Matrix< dtype > &U, Vector< dtype > &S, Matrix< dtype > &VT, int rank=0)
Definition: matrix.cxx:481
int get_int_fromreal< double >(double r)
Definition: matrix.cxx:409
std::set< grid_wrapper > scalapack_grids
index for ScaLAPACK processor grids
Definition: world.cxx:27
void get_desc(int &ictxt, int *&desc)
get a ScaLAPACK descriptor for this Matrix, will always be in pure cyclic layout
Definition: matrix.cxx:296
algstrct * sr
algstrct on which tensor elements and operations are defined
mapping * edge_map
mappings of each tensor dimension onto topology dimensions
void cblacs_gridinit(int *contxt, char *row, int nprow, int npcol)
int get_int_fromreal(dtype r)
Definition: matrix.cxx:399
int nrow
Definition: matrix.h:20
virtual void print(char const *a, FILE *fp=stdout) const
prints the value
Definition: algstrct.cxx:170
int get_int_fromreal< float >(float r)
Definition: matrix.cxx:405
void get_my_kv_pair(int rank, int nrow, int ncol, int mb, int nb, int pr, int pc, int rsrc, int csrc, int64_t &nmyr, int64_t &nmyc, Pair< dtype > *&pairs)
Definition: matrix.cxx:161
int cdealloc(void *ptr)
free abstraction
Definition: memcontrol.cxx:480
dtype * get_raw_data(int64_t *size) const
gives the raw current local data with padding included
Definition: tensor.cxx:152
algstrct (algebraic structure) defines the elementwise operations computed in each tensor contraction...
Definition: algstrct.h:34
Definition: apsp.cxx:17
char * data
tensor data, either the data or the key-value pairs should exist at any given time ...
an instance of a tensor within a CTF world
Definition: tensor.h:74
Matrix()
default constructor for a matrix
Definition: matrix.cxx:29
void read(int64_t npair, Pair< dtype > *pairs)
Gives the values associated with any set of indices.
Definition: tensor.cxx:246
topology * topo
topology to which the tensor is mapped
Definition: common.h:37
void cdescinit(int *desc, int m, int n, int mb, int nb, int irsrc, int icsrc, int ictxt, int LLD, int *info)
int2(int a, int b)
Definition: matrix.cxx:14
void cblacs_gridinfo(int contxt, int *nprow, int *npcol, int *myprow, int *mypcol)
void print_matrix()
Definition: matrix.cxx:144
Definition: common.h:37
void write(int64_t npair, int64_t const *global_idx, dtype const *data)
writes in values associated with any set of indices The sparse data is defined in coordinate format...
Definition: tensor.cxx:264
int np
number of processors
Definition: world.h:26
MPI_Comm comm
set of processors making up this world
Definition: world.h:22
def np(self)
Definition: core.pyx:315