Commit ff996614 authored by Dmitry I. Lyakh's avatar Dmitry I. Lyakh
Browse files

Revised Tensor ownership in TensorConnected, TensorOperation,

and TensorNetwork: Now Tensor is co-owned in this aggregate
data structures.
parent c24c4043
/** ExaTN::Numerics: General client header
REVISION: 2019/05/02
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -12,10 +12,10 @@ Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
(c) Any unregistered subspace of any named vector space has id = UNREG_SUBSPACE = max(uint64_t).
(d) Every explicitly registered (named) vector space has an automatically registered full
subspace (=space) under the same (space) name with id = FULL_SUBSPACE = 0.
(e) Every registered non-trivial subspace of any named vector space has id:
(e) Every registered non-trivial named subspace of any named vector space has id:
0 < id < max(uint64_t).
(f) A subspace of the anonymous vector space is defined by the
base offset (first basis vector) and its dimension.
base offset (first basis vector belonging to it) and its dimension.
2. Index labels:
(a) Any registered subspace can be assigned a symbolic index label serving as a placeholder for it;
any index label can only refer to a single registered (named) subspace it is associated with.
......@@ -49,7 +49,7 @@ SpaceId createVectorSpace(const std::string & space_name, //in: vecto
DimExtent space_dim, //in: vector space dimension
const VectorSpace ** space_ptr = nullptr); //out: non-owning pointer to the created vector space
/** Destroys a previously created vector space. **/
/** Destroys a previously created named vector space. **/
void destroyVectorSpace(const std::string & space_name); //in: name of the vector space to destroy
void destroyVectorSpace(SpaceId space_id); //in: id of the vector space to destroy
......@@ -60,7 +60,7 @@ SubspaceId createSubspace(const std::string & subspace_name, //in: sub
const std::pair<DimOffset,DimOffset> bounds, //in: range of basis vectors defining the created subspace: [lower:upper]
const Subspace ** subspace_ptr = nullptr); //out: non-owning pointer to the created subspace
/** Destroys a previously created subspace. **/
/** Destroys a previously created named subspace. **/
void destroySubspace(const std::string & subspace_name); //in: name of the subspace to destroy
void destroySubspace(SubspaceId subspace_id); //in: id of the subspace to destroy
......
/** ExaTN::Numerics: Register of vector spaces and their subspaces
REVISION: 2019/05/02
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -14,18 +14,13 @@ namespace exatn{
namespace numerics{
SubspaceRegEntry::SubspaceRegEntry(std::shared_ptr<Subspace> & subspace):
subspace_(subspace)
{
}
SubspaceRegEntry::SubspaceRegEntry(std::shared_ptr<Subspace> && subspace):
SubspaceRegEntry::SubspaceRegEntry(std::shared_ptr<Subspace> subspace):
subspace_(subspace)
{
}
SubspaceId SubspaceRegister::registerSubspace(std::shared_ptr<Subspace> & subspace)
SubspaceId SubspaceRegister::registerSubspace(std::shared_ptr<Subspace> subspace)
{
SubspaceId id = subspace->getRegisteredId();
if(id == UNREG_SUBSPACE){ //previously unregistered
......@@ -44,26 +39,6 @@ SubspaceId SubspaceRegister::registerSubspace(std::shared_ptr<Subspace> & subspa
return id;
}
SubspaceId SubspaceRegister::registerSubspace(std::shared_ptr<Subspace> && subspace)
{
SubspaceId id = subspace->getRegisteredId();
if(id == UNREG_SUBSPACE){ //previously unregistered
const std::string & subspace_name = subspace->getName();
assert(subspace_name.length() > 0); //only named subspaces can be registered
id = subspaces_.size(); //new registered subspace id (>0)
bool unique = name2id_.insert({subspace_name,id}).second;
if(unique){
subspace->resetRegisteredId(id);
subspaces_.emplace_back(SubspaceRegEntry(subspace)); //subspace register shares ownership of the stored subspace
}else{
std::cout << "WARNING: Attempt to register a subspace with an already registered name: " << subspace_name << std::endl;
return UNREG_SUBSPACE; //subspace with this name already exists, subspace cannot be registered
}
}
return id;
}
const Subspace * SubspaceRegister::getSubspace(SubspaceId id) const
{
if(id >= subspaces_.size()) return nullptr;
......@@ -78,25 +53,13 @@ const Subspace * SubspaceRegister::getSubspace(const std::string & name) const
}
SpaceRegEntry::SpaceRegEntry(std::shared_ptr<VectorSpace> & space):
space_(space)
{
DimOffset lower = 0;
DimOffset upper = lower + space_->getDimension() - 1;
const std::string & space_name = space_->getName();
if(space_name.length() > 0){
SubspaceId id = subspaces_.registerSubspace(std::make_shared<Subspace>(space_.get(),lower,upper,space_name)); //register the full space as its trivial subspace under the same name
assert(id == FULL_SUBSPACE); //=0
}
}
SpaceRegEntry::SpaceRegEntry(std::shared_ptr<VectorSpace> && space):
SpaceRegEntry::SpaceRegEntry(std::shared_ptr<VectorSpace> space):
space_(space)
{
DimOffset lower = 0;
DimOffset upper = lower + space_->getDimension() - 1;
const std::string & space_name = space_->getName();
if(space_name.length() > 0){
if(space_name.length() > 0){ //a trivial (full) subspace will be registered for named spaces under the same (space) name
DimOffset lower = 0;
DimOffset upper = lower + space_->getDimension() - 1;
SubspaceId id = subspaces_.registerSubspace(std::make_shared<Subspace>(space_.get(),lower,upper,space_name)); //register the full space as its trivial subspace under the same name
assert(id == FULL_SUBSPACE); //=0
}
......@@ -106,10 +69,10 @@ SpaceRegEntry::SpaceRegEntry(std::shared_ptr<VectorSpace> && space):
SpaceRegister::SpaceRegister()
{
static_assert(SOME_SPACE == 0, "#FATAL(exatn::numerics::SpaceRegister): Predefined SOME_SPACE space id is not equal 0!");
spaces_.emplace_back(SpaceRegEntry(std::make_shared<VectorSpace>(MAX_SPACE_DIM))); //Space 0 (SOME_SPACE) is an unnamed abstract space of maximal dimension
spaces_.emplace_back(SpaceRegEntry(std::make_shared<VectorSpace>(MAX_SPACE_DIM))); //Space 0 (SOME_SPACE) is an anonymous abstract space of maximal dimension
}
SpaceId SpaceRegister::registerSpace(std::shared_ptr<VectorSpace> & space)
SpaceId SpaceRegister::registerSpace(std::shared_ptr<VectorSpace> space)
{
SpaceId id = space->getRegisteredId();
if(id == SOME_SPACE){ //previously unregistered
......@@ -128,26 +91,6 @@ SpaceId SpaceRegister::registerSpace(std::shared_ptr<VectorSpace> & space)
return id;
}
SpaceId SpaceRegister::registerSpace(std::shared_ptr<VectorSpace> && space)
{
SpaceId id = space->getRegisteredId();
if(id == SOME_SPACE){ //previously unregistered
const std::string & space_name = space->getName();
assert(space_name.length() > 0); //only named spaces can be registered explicitly
id = spaces_.size(); //new registered space id (>0)
bool unique = name2id_.insert({space_name,id}).second;
if(unique){
space->resetRegisteredId(id);
spaces_.emplace_back(SpaceRegEntry(space)); //space register shares ownership of the stored vector space
}else{
std::cout << "WARNING: Attempt to register a vector space with an already registered name: " << space_name << std::endl;
return SOME_SPACE; //space with this name already exists, space cannot be registered
}
}
return id;
}
const VectorSpace * SpaceRegister::getSpace(SpaceId id) const
{
if(id >= spaces_.size()) return nullptr;
......@@ -160,7 +103,7 @@ const VectorSpace * SpaceRegister::getSpace(const std::string & name) const
auto it = name2id_.find(name);
if(it == name2id_.end()) return nullptr;
return spaces_[it->second].space_.get();
}else{ //unnamed vector space (space 0 = SOME_SPACE)
}else{ //unnamed (anonymous) vector space (space 0 = SOME_SPACE)
return spaces_[0].space_.get();
}
}
......
/** ExaTN::Numerics: Register of vector spaces and their subspaces
REVISION: 2019/05/27
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -33,8 +33,7 @@ namespace numerics{
class SubspaceRegEntry{
public:
SubspaceRegEntry(std::shared_ptr<Subspace> & subspace);
SubspaceRegEntry(std::shared_ptr<Subspace> && subspace);
SubspaceRegEntry(std::shared_ptr<Subspace> subspace);
SubspaceRegEntry(const SubspaceRegEntry &) = default;
SubspaceRegEntry & operator=(const SubspaceRegEntry &) = default;
......@@ -65,8 +64,7 @@ public:
If the subspace has already been registered before, returns its existing id.
Returned id = UNREG_SUBSPACE means that another subspace with the same name
has already been registered before. **/
SubspaceId registerSubspace(std::shared_ptr<Subspace> & subspace);
SubspaceId registerSubspace(std::shared_ptr<Subspace> && subspace);
SubspaceId registerSubspace(std::shared_ptr<Subspace> subspace);
/** Returns a non-owning pointer to a stored subspace by its id. **/
const Subspace * getSubspace(SubspaceId id) const;
......@@ -83,8 +81,7 @@ private:
class SpaceRegEntry{
public:
SpaceRegEntry(std::shared_ptr<VectorSpace> & space);
SpaceRegEntry(std::shared_ptr<VectorSpace> && space);
SpaceRegEntry(std::shared_ptr<VectorSpace> space);
SpaceRegEntry(const SpaceRegEntry &) = delete;
SpaceRegEntry & operator=(const SpaceRegEntry &) = delete;
......@@ -117,8 +114,7 @@ public:
Returned id = SOME_SPACE indicates an attempt to register a named
vector space when another vector space has already been registered
under the same name. **/
SpaceId registerSpace(std::shared_ptr<VectorSpace> & space);
SpaceId registerSpace(std::shared_ptr<VectorSpace> && space);
SpaceId registerSpace(std::shared_ptr<VectorSpace> space);
/** Returns a non-owning pointer to a stored vector space by its id. **/
const VectorSpace * getSpace(SpaceId id) const;
......
/** ExaTN: Tensor basic types and parameters
REVISION: 2019/05/27
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -33,6 +33,15 @@ enum class LegDirection{
OUTWARD //outward direction
};
enum class TensorOpCode{
NOOP, //no operation
CREATE, //tensor creation
DESTROY, //tensor destruction
TRANSFORM, //tensor transformation/initialization
ADD, //tensor addition
CONTRACT //tensor contraction
};
} //namespace exatn
#endif //EXATN_NUMERICS_TENSOR_BASIC_HPP_
/** ExaTN::Numerics: Tensor connected to other tensors inside a tensor network
REVISION: 2019/05/27
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -10,12 +10,12 @@ namespace exatn{
namespace numerics{
TensorConn::TensorConn(const Tensor * tensor, unsigned int id, const std::vector<TensorLeg> & legs):
TensorConn::TensorConn(std::shared_ptr<Tensor> tensor, unsigned int id, const std::vector<TensorLeg> & legs):
tensor_(tensor), id_(id), legs_(legs)
{
}
const Tensor * TensorConn::getTensor() const
std::shared_ptr<Tensor> TensorConn::getTensor()
{
return tensor_;
}
......
/** ExaTN::Numerics: Tensor connected to other tensors in a tensor network
REVISION: 2019/05/27
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
/** Rationale:
(a) A tensor inside a tensor network is generally connected
to other tensors in that network via so-called tensor legs,
each tensor leg is associated with its own tensor dimension.
to other tensors in that network via so-called tensor legs;
each tensor leg is associated with a specific tensor dimension.
(b) Each tensor leg specifies a connection of a given tensor dimension
to some dimension (or dimensions) in another tensor (or tensors) in
the same tensor network. Thus, tensor legs can be binary, ternary, etc.,
......@@ -23,6 +23,7 @@ Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_leg.hpp"
#include "tensor.hpp"
#include <memory>
#include <vector>
namespace exatn{
......@@ -33,9 +34,9 @@ class TensorConn{
public:
/** Constructs a connected tensor inside a tensor network. **/
TensorConn(const Tensor * tensor, //non-owning pointer to the tensor
unsigned int id, //tensor id in the tensor network
const std::vector<TensorLeg> & legs); //tensor legs: Connections to other tensors in the tensor network
TensorConn(std::shared_ptr<Tensor> tensor, //in: co-owned pointer to the tensor
unsigned int id, //in: tensor id in the tensor network
const std::vector<TensorLeg> & legs); //in: tensor legs: Connections to other tensors in the tensor network
TensorConn(const TensorConn &) = default;
TensorConn & operator=(const TensorConn &) = default;
......@@ -43,8 +44,8 @@ public:
TensorConn & operator=(TensorConn &&) noexcept = default;
virtual ~TensorConn() = default;
/** Returns a non-owning pointer to the tensor. **/
const Tensor * getTensor() const;
/** Returns a co-owned pointer to the tensor. **/
std::shared_ptr<Tensor> getTensor();
/** Returns the tensor id. **/
unsigned int getTensorId() const;
......@@ -57,9 +58,9 @@ public:
private:
const Tensor * tensor_; //non-owning pointer to the tensor
unsigned int id_; //tensor id in the tensor network
std::vector<TensorLeg> legs_; //tensor legs: Connections to other tensors
std::shared_ptr<Tensor> tensor_; //co-owned pointer to the tensor
unsigned int id_; //tensor id in the tensor network
std::vector<TensorLeg> legs_; //tensor legs: Connections to other tensors
};
......
/** ExaTN::Numerics: Tensor network
REVISION: 2019/05/27
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -23,6 +23,12 @@ Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_basic.hpp"
#include "tensor_connected.hpp"
#include "tensor_operation.hpp"
#include "tensor_op_create.hpp"
#include "tensor_op_destroy.hpp"
#include "tensor_op_transform.hpp"
#include "tensor_op_add.hpp"
#include "tensor_op_contract.hpp"
#include <unordered_map>
......
/** ExaTN::Numerics: Tensor operation: Adds a tensor to another tensor
REVISION: 2019/05/30
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -11,7 +11,7 @@ namespace exatn{
namespace numerics{
TensorOpAdd::TensorOpAdd():
TensorOperation(2,1)
TensorOperation(TensorOpCode::ADD,2,1)
{
this->setScalar(0,std::complex<double>{1.0,0.0}); //default alpha prefactor
}
......
/** ExaTN::Numerics: Tensor operation: Contracts two tensors and accumulates the result into another tensor
REVISION: 2019/05/30
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -11,7 +11,7 @@ namespace exatn{
namespace numerics{
TensorOpContract::TensorOpContract():
TensorOperation(3,2)
TensorOperation(TensorOpCode::CONTRACT,3,2)
{
this->setScalar(0,std::complex<double>{1.0,0.0}); //default alpha prefactor
this->setScalar(1,std::complex<double>{1.0,0.0}); //default beta prefactor (accumulative)
......
/** ExaTN::Numerics: Tensor operation: Creates a tensor
REVISION: 2019/05/30
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -11,7 +11,7 @@ namespace exatn{
namespace numerics{
TensorOpCreate::TensorOpCreate():
TensorOperation(1,0)
TensorOperation(TensorOpCode::CREATE,1,0)
{
}
......
/** ExaTN::Numerics: Tensor operation: Destroys a tensor
REVISION: 2019/05/30
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -11,7 +11,7 @@ namespace exatn{
namespace numerics{
TensorOpDestroy::TensorOpDestroy():
TensorOperation(1,0)
TensorOperation(TensorOpCode::DESTROY,1,0)
{
}
......
/** ExaTN::Numerics: Tensor operation: Transforms/initializes a tensor
REVISION: 2019/05/30
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -11,7 +11,7 @@ namespace exatn{
namespace numerics{
TensorOpTransform::TensorOpTransform():
TensorOperation(1,1)
TensorOperation(TensorOpCode::TRANSFORM,1,1)
{
this->setScalar(0,std::complex<double>{0.0,0.0}); //default numerical initialization value
}
......
/** ExaTN::Numerics: Tensor operation
REVISION: 2019/05/30
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -10,8 +10,9 @@ namespace exatn{
namespace numerics{
TensorOperation::TensorOperation(unsigned int num_operands, unsigned int num_scalars):
num_operands_(num_operands), num_scalars_(num_scalars), scalars_(num_scalars,std::complex<double>{0.0,0.0})
TensorOperation::TensorOperation(TensorOpCode opcode, unsigned int num_operands, unsigned int num_scalars):
num_operands_(num_operands), num_scalars_(num_scalars), opcode_(opcode),
scalars_(num_scalars,std::complex<double>{0.0,0.0})
{
operands_.reserve(num_operands);
}
......@@ -26,17 +27,17 @@ unsigned int TensorOperation::getNumOperandsSet() const
return static_cast<unsigned int>(operands_.size());
}
const Tensor * TensorOperation::getTensorOperand(unsigned int op_num) const
std::shared_ptr<Tensor> TensorOperation::getTensorOperand(unsigned int op_num)
{
if(op_num < operands_.size()) return operands_[op_num];
return nullptr;
return std::shared_ptr<Tensor>(nullptr);
}
void TensorOperation::setTensorOperand(const Tensor * tensor)
void TensorOperation::setTensorOperand(std::shared_ptr<Tensor> tensor)
{
assert(tensor != nullptr);
assert(tensor);
assert(operands_.size() < num_operands_);
operands_.push_back(tensor);
operands_.emplace_back(tensor);
return;
}
......
/** ExaTN::Numerics: Tensor operation
REVISION: 2019/05/30
REVISION: 2019/05/31
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -14,6 +14,7 @@ Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_basic.hpp"
#include "tensor.hpp"
#include <memory>
#include <string>
#include <vector>
#include <complex>
......@@ -22,12 +23,13 @@ namespace exatn{
namespace numerics{
class TensorOperation{
class TensorOperation{ //abstract
public:
/** Constructs a yet undefined tensor operation with
the specified number of tensor/scalar arguments. **/
TensorOperation(unsigned int num_operands, //required number of tensor operands
TensorOperation(TensorOpCode opcode, //tensor operation code
unsigned int num_operands, //required number of tensor operands
unsigned int num_scalars); //required number of scalar operands
TensorOperation(const TensorOperation &) = default;
......@@ -45,11 +47,11 @@ public:
/** Returns the number of tensor operands set. **/
unsigned int getNumOperandsSet() const;
/** Returns a non-owning pointer to a specific tensor operand, or nullptr if not set. **/
const Tensor * getTensorOperand(unsigned int op_num) const;
/** Returns a co-owned pointer to a specific tensor operand, or nullptr if not yet set. **/
std::shared_ptr<Tensor> getTensorOperand(unsigned int op_num);
/** Sets the next tensor operand. **/
void setTensorOperand(const Tensor * tensor);
void setTensorOperand(std::shared_ptr<Tensor> tensor);
/** Returns the number of scalar arguments required for the tensor operation. **/
unsigned int getNumScalars() const;
......@@ -60,7 +62,7 @@ public:
/** Returns a specific scalar argument. **/
std::complex<double> getScalar(unsigned int scalar_num) const;
/** Sets the next scalar argument. **/
/** Sets a specific scalar argument. **/
void setScalar(unsigned int scalar_num,
const std::complex<double> scalar);
......@@ -74,10 +76,11 @@ public:
protected:
std::string pattern_; //symbolic index pattern
std::vector<const Tensor *> operands_; //tensor operands (non-owning pointers)
std::vector<std::shared_ptr<Tensor>> operands_; //tensor operands (non-owning pointers)
std::vector<std::complex<double>> scalars_; //additional scalars (prefactors)
unsigned int num_operands_; //number of required tensor operands
unsigned int num_scalars_; //number of required scalar arguments
TensorOpCode opcode_; //tensor operation code
};
......
Supports Markdown
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