Commit bae3f8ba authored by Dmitry I. Lyakh's avatar Dmitry I. Lyakh

Implementing generate_contraction_pattern() ...

parent ed56551e
/** ExaTN::Numerics: Abstract Tensor
REVISION: 2019/07/22
REVISION: 2019/09/11
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -82,6 +82,8 @@ public:
Tensor(const std::string & name); //tensor name
/** Create a tensor by contracting two other tensors.
The vector of tensor legs specifies the tensor contraction pattern:
contraction[] describes dimensions of both input tensors,
first left tensor dimensions, then right tensor dimensions:
contraction.size() = left_rank + right_rank;
Output tensor id = 0;
Left input tensor id = 1;
......
/** ExaTN::Numerics: Tensor network
REVISION: 2019/09/09
REVISION: 2019/09/11
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -239,6 +239,14 @@ std::shared_ptr<Tensor> TensorNetwork::getTensor(unsigned int tensor_id)
}
const std::vector<TensorLeg> * TensorNetwork::getTensorConnections(unsigned int tensor_id)
{
auto it = tensors_.find(tensor_id);
if(it == tensors_.end()) return nullptr;
return &((it->second).getTensorLegs());
}
bool TensorNetwork::finalize(bool check_validity)
{
if(finalized_ == 0){
......@@ -767,6 +775,11 @@ bool TensorNetwork::mergeTensors(unsigned int left_id, unsigned int right_id, un
}
}
assert(res_mode == num_uncontracted);
//Generate symbolic contraction pattern if needed:
if(contr_pattern != nullptr){
auto generated = generate_contraction_pattern(pattern,left_tensor_rank,right_tensor_rank,*contr_pattern);
assert(generated);
}
//Append the tensor result:
tensors_.emplace(std::make_pair(
result_id,
......@@ -877,33 +890,39 @@ std::list<std::shared_ptr<TensorOperation>> & TensorNetwork::getOperationList(co
for(auto contr = contraction_seq_.cbegin(); contr != contraction_seq_.cend(); ++contr){
auto tensor1 = net.getTensor(contr->left_id);
auto tensor2 = net.getTensor(contr->right_id);
//`Get index pattern for tensor contraction
auto merged = net.mergeTensors(contr->left_id,contr->right_id,contr->result_id);
std::string contr_pattern;
auto merged = net.mergeTensors(contr->left_id,contr->right_id,contr->result_id,&contr_pattern);
assert(merged);
auto tensor0 = net.getTensor(contr->result_id);
auto op = tensor_op_factory.createTensorOp(TensorOpCode::CONTRACT);
op->setTensorOperand(tensor0);
op->setTensorOperand(tensor1);
op->setTensorOperand(tensor2);
op->setIndexPattern("`Replace with generated index pattern");
op->setIndexPattern(contr_pattern);
assert(op->isSet());
operations_.emplace_back(std::shared_ptr<TensorOperation>(std::move(op)));
}
}else{ //one input tensor: Single addition
std::shared_ptr<Tensor> tensor0(nullptr);
std::shared_ptr<Tensor> tensor1(nullptr);
unsigned int left_tensor_id = 0;
for(auto iter = this->begin(); iter != this->end(); ++iter){
if(iter->first == 0){
tensor0 = this->getTensor(iter->first);
}else{
tensor1 = this->getTensor(iter->first);
left_tensor_id = iter->first;
}
}
auto op = tensor_op_factory.createTensorOp(TensorOpCode::ADD);
op->setTensorOperand(tensor0);
op->setTensorOperand(tensor1);
//`Get index pattern for tensor addition
op->setIndexPattern("`Replace with generated index pattern");
const auto * tensor1_legs = this->getTensorConnections(left_tensor_id);
assert(tensor1_legs != nullptr);
std::string contr_pattern;
auto generated = generate_contraction_pattern(*tensor1_legs,tensor1_legs->size(),0,contr_pattern);
assert(generated);
op->setIndexPattern(contr_pattern);
assert(op->isSet());
operations_.emplace_back(std::shared_ptr<TensorOperation>(std::move(op)));
}
......
/** ExaTN::Numerics: Tensor network
REVISION: 2019/09/09
REVISION: 2019/09/11
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -124,6 +124,9 @@ public:
If not found, returns nullptr. **/
std::shared_ptr<Tensor> getTensor(unsigned int tensor_id);
/** Get tensor connections. **/
const std::vector<TensorLeg> * getTensorConnections(unsigned int tensor_id);
/** Begin iterator **/
inline Iterator begin() {return tensors_.begin();}
/** End iterator **/
......
/** ExaTN: Numerics: Symbolic tensor processing
REVISION: 2019/08/07
REVISION: 2019/09/11
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_symbol.hpp"
#include <cassert>
namespace exatn{
bool parse_tensor(const std::string & tensor, //in: tensor as a string
......@@ -128,4 +130,33 @@ bool parse_tensor_network(const std::string & network, //in: tensor netwo
return true;
}
bool generate_contraction_pattern(const std::vector<numerics::TensorLeg> & pattern,
unsigned int left_tensor_rank,
unsigned int right_tensor_rank,
std::string & symb_pattern)
{
assert(pattern.size() == left_tensor_rank + right_tensor_rank);
symb_pattern.clear();
if(pattern.empty()){
symb_pattern = "D()+=L()*R()";
}else{
unsigned int dest_tensor_rank = 0;
for(const auto & leg: pattern){
if(leg.getTensorId() == 0) ++dest_tensor_rank;
}
symb_pattern.append("D(");
for(unsigned int i = 0; i < dest_tensor_rank; ++i){
symb_pattern.append("u"+std::to_string(i)+",");
}
symb_pattern.replace(symb_pattern.size()-1,1,")");
unsigned int nums[right_tensor_rank];
symb_pattern.append("+=L(");
for(unsigned int i = 0; i < left_tensor_rank; ++i){
}
}
return true;
}
} //namespace exatn
/** ExaTN: Numerics: Symbolic tensor processing
REVISION: 2019/08/07
REVISION: 2019/09/11
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle)
......@@ -34,6 +34,7 @@ Rationale:
#define EXATN_TENSOR_SYMBOL_HPP_
#include "tensor_basic.hpp"
#include "tensor_leg.hpp"
#include <string>
#include <vector>
......@@ -125,6 +126,20 @@ bool parse_tensor(const std::string & tensor, //in: tensor as a string
bool parse_tensor_network(const std::string & network, //in: tensor network as a string
std::vector<std::string> & tensors); //out: parsed (symbolic) tensors
/** Generates symbolic tensor contraction pattern from the digital tensor
contraction pattern used by the contraction-based Tensor constructor:
pattern[0..m-1] describes connectivity of dimensions of the left contracted tensor,
pattern[m..m+n-1] decribes connectivity of dimensions of the right contracted tensor,
where m and n are the ranks of the left and right contracted tensors, respectively.
pattern[x] is a TensorLeg specifying the dimension of another tensor the described
dimension is connected to, where the result tensor is tensor 0 while the left and
right contracted tensors are tensors 1 and 2, respectively.
**/
bool generate_contraction_pattern(const std::vector<numerics::TensorLeg> & pattern,
unsigned int left_tensor_rank,
unsigned int right_tensor_rank,
std::string & symb_pattern);
} //namespace exatn
#endif //EXATN_TENSOR_SYMBOL_HPP_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment