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)