5 #include "../tensor/algstrct.h"     6 #include "../summation/summation.h"     7 #include "../contraction/contraction.h"   123                              std::vector<char> out_inds,
   124                              bool create_dummy=
false){
   126     int * len_C, * sym_C;
   129     int num_out_inds = (int)out_inds.size(); 
   130     idx_C = (
char*)
alloc(
sizeof(
char)*num_out_inds);
   131     sym_C = (
int*)
alloc(
sizeof(
int)*num_out_inds);
   132     len_C = (
int*)
alloc(
sizeof(
int)*num_out_inds);
   135     for (j=0; j<num_out_inds; j++){
   140         if (A.
idx_map[i] == out_inds[j]){
   143           if (sym_prev != -1) sym_prev = 
NS;
   144           else if (i>0 && order_C>0 && A.
idx_map[i-1] == idx_C[order_C-1]) sym_prev = A.
parent->
sym[i-1];
   150           if (B.
idx_map[i] == out_inds[j]){
   153             if (sym_prev != 
NS && i>0 && order_C>0 && B.
idx_map[i-1] == idx_C[order_C-1]) sym_prev = B.
parent->
sym[i-1];
   160         idx_C[order_C] = out_inds[j];
   161         len_C[order_C] = len;
   205     sr->safecopy(
scale,sr->mulid());
   216   void Term::mult_scl(
char const * mulscl){
   235     if (trm.operands[1]->scale == NULL)
   237     sr->safeaddinv(A.
scale, trm.operands[1]->scale);
   241   void Term::operator=(
CTF::Idx_Tensor const & B){ this->execute(this->get_uniq_inds()) = B; }
   242   void Term::operator=(
Term const & B){ this->execute(this->get_uniq_inds()) = B; }
   245   void Term::operator*=(
Term const & B){ this->execute(this->get_uniq_inds()) *= B; }
   247   void Term::operator=(
double scl){ this->execute(this->get_uniq_inds()) = 
Idx_Tensor(sr,scl); }
   250   void Term::operator*=(
double scl){ this->execute(this->get_uniq_inds()) *= 
Idx_Tensor(sr,scl); }
   252   void Term::operator=(int64_t 
scl){ this->execute(this->get_uniq_inds()) = 
Idx_Tensor(sr,scl); }
   255   void Term::operator*=(int64_t 
scl){ this->execute(this->get_uniq_inds()) *= 
Idx_Tensor(sr,scl); }
   256   void Term::operator=(
int scl){ this->execute(this->get_uniq_inds()) = 
Idx_Tensor(sr,(int64_t)scl); }
   259   void Term::operator*=(
int scl){ this->execute(this->get_uniq_inds()) *= 
Idx_Tensor(sr,(int64_t)scl); }
   286   Term::operator float ()
 const {
   289     float dbl = ((
float*)ts.
data)[0];
   295   Term::operator double ()
 const {
   299     double dbl = ((
double*)ts.
data)[0];
   314   Term::operator int ()
 const {
   317     int dbl = ((
int*)ts.
data)[0];
   323   Term::operator int64_t ()
 const {
   326     int64_t dbl = ((int64_t*)ts.
data)[0];
   352     for (
int i=0; i<(int)
operands.size(); i++){
   361       std::map<tensor*, tensor*>* remap) : 
Term(other.
sr) {
   363     for (
int i=0; i<(int)other.
operands.size(); i++){
   394     std::vector< Term* > tmp_ops;
   395     for (
int i=0; i<(int)
operands.size(); i++){
   398     while (tmp_ops.size() > 1){
   399       Term * pop_A = tmp_ops.back();
   401       Term * pop_B = tmp_ops.back();
   412       tmp_ops.push_back(intm);
   423     std::set<char> uniq_inds;
   424     std::set<Idx_Tensor*, tensor_name_less > inputs;
   425     for (
int j=0; j<(int)operands.size(); j++){
   426       operands[j]->get_inputs(&inputs);
   428     for (std::set<Idx_Tensor*>::iterator j=inputs.begin(); j!=inputs.end(); j++){
   429       if ((*j)->parent != NULL){
   430         for (
int k=0; k<(*j)->parent->order; k++){
   431           uniq_inds.insert((*j)->idx_map[k]);
   435     for (
int j=0; j<(int)out_inds.size(); j++){
   436       uniq_inds.insert(out_inds[j]);
   438     return std::vector<char>(uniq_inds.begin(), uniq_inds.end());
   449     std::vector< Term* > tmp_ops;
   450     for (
int i=0; i<(int)
operands.size(); i++){
   453     while (tmp_ops.size() > 1){
   454       Term * pop_A = tmp_ops.back();
   456       Term * pop_B = tmp_ops.back();
   468       tmp_ops.push_back(intm);
   497     for (
int i=0; i<(int)
operands.size(); i++){
   498       operands[i]->get_inputs(inputs_set);
   505     for (
int i=0; i<(int)
operands.size(); i++){
   517     for (
int i=0; i<(int)
operands.size(); i++){
   526     for (
int i=0; i<(int)
operands.size(); i++){
   543       std::map<tensor*, tensor*>* remap) : 
Term(other.
sr) {
   545     for (
int i=0; i<(int)other.
operands.size(); i++){
   564     std::vector< Term* > tmp_ops;
   565     for (
int i=0; i<(int)operands.size(); i++){
   566       tmp_ops.push_back(operands[i]->
clone());
   568     while (tmp_ops.size() > terms_to_leave){
   569       Term * pop_A = tmp_ops.back();
   572       std::vector<char> out_inds_A = 
det_uniq_inds(tmp_ops, out_inds);
   573       Term * pop_B = tmp_ops.back();
   575       tmp_ops.push_back(pop_A);
   576       std::vector<char> out_inds_B = 
det_uniq_inds(tmp_ops, out_inds);
   587       if (op_A->
parent == NULL) {
   589         tmp_ops.push_back(op_B->
clone());
   590       } 
else if (op_B->
parent == NULL) {
   592         tmp_ops.push_back(op_A->
clone());
   606         tmp_ops.push_back(intm);
   618     char * tscale = NULL;
   622       assert(tmp_ops.size() == 2);
   623       Term * pop_B = tmp_ops.back();
   626       std::vector<char> out_inds_B = 
det_uniq_inds(tmp_ops, out_inds);
   627       Term * pop_A = tmp_ops.back();
   629       tmp_ops.push_back(pop_B);
   630       std::vector<char> out_inds_A = 
det_uniq_inds(tmp_ops, out_inds);
   642       } 
else if (op_A.
parent == NULL){
   646       } 
else if (op_B.
parent == NULL){
   656       if (tscale != NULL) 
cdealloc(tscale);
   665     char * tscale = NULL;
   671     if (tscale != NULL) 
cdealloc(tscale);
   682       assert(tmp_ops.size() == 2);
   683       Term * pop_B = tmp_ops.back();
   686       std::vector<char> out_inds_B = 
det_uniq_inds(tmp_ops, out_inds);
   687       Term * pop_A = tmp_ops.back();
   689       tmp_ops.push_back(pop_B);
   690       std::vector<char> out_inds_A = 
det_uniq_inds(tmp_ops, out_inds);
   697       } 
else if (op_A.
parent == NULL){
   701       } 
else if (op_B.
parent == NULL){
   720     return tmp_ops[0]->estimate_time(cost, out_inds);
   728     for (
int i=0; i<(int)
operands.size(); i++){
   729       operands[i]->get_inputs(inputs_set);
   759     if (A == NULL && B != NULL) {
   761     } 
else if (A == NULL || B == NULL) {
 a term is an abstract object representing some expression of tensors 
CTF_int::algstrct const * get_double_ring()
void operator-=(Term const &B)
Sum_Term operator+(Term const &A) const 
constructs a new term by addition of two terms 
void get_inputs(std::set< CTF::Idx_Tensor *, tensor_name_less > *inputs_set) const 
appends the tensors this depends on to the input set 
CTF_int::CommData cdt
communicator data for MPI comm defining this world 
virtual void execute(CTF::Idx_Tensor output) const  =0
evalues the expression, which just scales by default 
int * sym
symmetries among tensor dimensions 
void execute()
run contraction 
virtual algstrct * clone() const  =0
''copy constructor'' 
void get_inputs(std::set< CTF::Idx_Tensor *, tensor_name_less > *inputs_set) const 
appends the tensors this depends on to the input set 
double estimate_time(CTF::Idx_Tensor output) const 
estimates the cost of a sum term 
Contract_Term operator*(Term const &A) const 
override contraction to grow vector rather than create recursive terms 
void safecopy(char *&a, char const *b) const 
copies element b to element a, , with checks for NULL and alloc as necessary 
CTF::World * where_am_i() const 
negates term 
void execute(bool run_diag=false)
run summation 
Sum_Term(Term *B, Term *A)
creates sum term for B+A 
std::vector< char > get_uniq_inds() const 
find list of unique indices that are involved in this term 
void * alloc(int64_t len)
alloc abstraction 
void operator<<(CTF_int::Term const &B)
Term * clone(std::map< tensor *, tensor * > *remap=NULL) const 
base classes must implement this copy function to retrieve pointer 
an instance of the CTF library (world) on a MPI communicator 
virtual void safemul(char const *a, char const *b, char *&c) const 
c = a*b, with NULL treated as mulid 
bool is_sparse
whether only the non-zero elements of the tensor are stored 
int order
number of tensor dimensions 
void operator-=(int64_t &d, CTF_int::Term const &tsr)
CTF::World * where_am_i() const 
negates term 
double estimate_time()
predicts execution time in seconds using performance models 
CTF::World * wrld
distributed processor context on which tensor is defined 
std::vector< Term * > operands
double estimate_time(CTF::Idx_Tensor output) const 
estimates the cost of a contract term 
std::vector< char > get_uniq_inds() const 
find list of unique indices that are involved in this term 
class for execution distributed contraction of tensors 
int * lens
unpadded tensor edge lengths 
virtual Term * clone(std::map< tensor *, tensor * > *remap=NULL) const  =0
base classes must implement this copy function to retrieve pointer 
Contract_Term(Term *B, Term *A)
creates sum term for B+A 
CTF_int::algstrct const * get_int_ring()
void execute(CTF::Idx_Tensor output) const 
evalues the expression by summing operands into output 
algstrct * sr
algstrct on which tensor elements and operations are defined 
CTF_int::Term * clone(std::map< CTF_int::tensor *, CTF_int::tensor * > *remap=NULL) const 
base classes must implement this copy function to retrieve pointer 
double estimate_time()
predicts execution time in seconds using performance models 
CTF_int::algstrct const * get_int64_t_ring()
void bcast(void *buf, int64_t count, MPI_Datatype mdtype, int root)
broadcast, same interface as MPI_Bcast, but excluding the comm 
std::vector< char > det_uniq_inds(std::vector< Term * > const operands, std::vector< char > const out_inds)
virtual double estimate_time(CTF::Idx_Tensor output) const  =0
estimates the cost of a contraction/sum/.. term 
CTF_int::algstrct const * get_float_ring()
CTF_int::Contract_Term operator*(double const &d, CTF_int::Term const &tsr)
double estimate_time(Idx_Tensor output) const 
estimates the cost of a contraction 
std::vector< char > get_uniq_inds() const 
find list of unique indices that are involved in this term 
void operator+=(Term const &B)
int cdealloc(void *ptr)
free abstraction 
Idx_Tensor execute(std::vector< char > out_inds) const 
evalues the expression to produce an intermediate with all expression indices remaining ...
Term * clone(std::map< tensor *, tensor * > *remap=NULL) const 
base classes must implement this copy function to retrieve pointer 
algstrct (algebraic structure) defines the elementwise operations computed in each tensor contraction...
char * data
tensor data, either the data or the key-value pairs should exist at any given time ...
internal distributed tensor class 
void operator+=(int64_t &d, CTF_int::Term const &tsr)
std::vector< Term * > contract_down_terms(algstrct *sr, char *tscale, std::vector< Term * > operands, std::vector< char > out_inds, int terms_to_leave, bool est_time=false, double *cost=NULL)
bool operator()(CTF::Idx_Tensor *A, CTF::Idx_Tensor *B)
class for execution distributed summation of tensors 
An experession representing a contraction of a set of tensors contained in operands. 
virtual void safeaddinv(char const *a, char *&b) const 
b = -a, with checks for NULL and alloc as necessary 
virtual char const * mulid() const 
identity element for multiplication i.e. 1 
a tensor with an index map associated with it (necessary for overloaded operators) ...
void execute(CTF::Idx_Tensor output) const 
override execution to to contract operands and add them to output 
std::vector< Term * > operands
char * name
name given to tensor 
Idx_Tensor * get_full_intm(Idx_Tensor &A, Idx_Tensor &B, std::vector< char > out_inds, bool create_dummy=false)