Commit 190255e8 authored by Mintz, Tiffany's avatar Mintz, Tiffany
Browse files

Merge branch 'master' of https://code.ornl.gov/qci/exatn

parents d1d48be6 203a3385
/** ExaTN::Numerics: Numerical server
REVISION: 2019/05/31
REVISION: 2019/06/06
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "num_server.hpp"
#include "assert.h"
namespace exatn{
namespace numerics{
NumServer::NumServer()
{
scopes_.push(std::pair<std::string,ScopeId>{"GLOBAL",0}); //GLOBAL scope 0 is automatically open
}
void NumServer::registerTensorMethod(std::shared_ptr<TensorMethod<Identifiable>> method)
{
ext_methods_.insert({method->name(),method});
auto res = ext_methods_.insert({method->name(),method});
if(!(std::get<1>(res))) std::cout << "#ERROR(NumServer::registerTensorMethod): Method already exists: " <<
method->name() << std::endl;
assert(std::get<1>(res));
return;
}
......@@ -23,7 +33,9 @@ std::shared_ptr<TensorMethod<Identifiable>> NumServer::getTensorMethod(const std
void NumServer::registerExternalData(const std::string & tag, std::shared_ptr<BytePacket> packet)
{
ext_data_.insert({tag,packet});
auto res = ext_data_.insert({tag,packet});
if(!(std::get<1>(res))) std::cout << "#ERROR(NumServer::registerExternalData): Data already exists: " << tag << std::endl;
assert(std::get<1>(res));
return;
}
......@@ -35,59 +47,129 @@ std::shared_ptr<BytePacket> NumServer::getExternalData(const std::string & tag)
ScopeId NumServer::openScope(const std::string & scope_name)
{
//`Finish
return 0;
assert(scope_name.length() > 0);
ScopeId new_scope_id = scopes_.size();
scopes_.push(std::pair<std::string,ScopeId>{scope_name,new_scope_id});
return new_scope_id;
}
ScopeId NumServer::closeScope()
{
auto prev_scope = scopes_.top();
const auto & prev_scope = scopes_.top();
ScopeId prev_scope_id = std::get<1>(prev_scope);
scopes_.pop();
return prev_scope;
return prev_scope_id;
}
SpaceId NumServer::createVectorSpace(const std::string & space_name, DimExtent space_dim,
const VectorSpace ** space_ptr)
{
//`Finish
return 0;
assert(space_name.length() > 0);
SpaceId space_id = space_register_.registerSpace(std::make_shared<VectorSpace>(space_dim,space_name));
if(space_ptr != nullptr) *space_ptr = space_register_.getSpace(space_id);
return space_id;
}
void NumServer::destroyVectorSpace(const std::string & space_name)
{
assert(false);
//`Finish
return;
}
void NumServer::destroyVectorSpace(SpaceId space_id)
{
assert(false);
//`Finish
return;
}
const VectorSpace * NumServer::getVectorSpace(const std::string & space_name) const
{
return space_register_.getSpace(space_name);
}
SubspaceId NumServer::createSubspace(const std::string & subspace_name,
const std::string & space_name,
const std::pair<DimOffset,DimOffset> bounds,
std::pair<DimOffset,DimOffset> bounds,
const Subspace ** subspace_ptr)
{
//`Finish
return 0;
assert(subspace_name.length() > 0 && space_name.length() > 0);
const VectorSpace * space = space_register_.getSpace(space_name);
assert(space != nullptr);
SubspaceId subspace_id = space_register_.registerSubspace(std::make_shared<Subspace>(space,bounds,subspace_name));
if(subspace_ptr != nullptr) *subspace_ptr = space_register_.getSubspace(space_name,subspace_name);
auto res = subname2id_.insert({subspace_name,space->getRegisteredId()});
if(!(res.second)) std::cout << "#ERROR(NumServer::createSubspace): Subspace already exists: " << subspace_name << std::endl;
assert(res.second);
return subspace_id;
}
void NumServer::destroySubspace(const std::string & subspace_name)
{
assert(false);
//`Finish
return;
}
void NumServer::destroySubspace(SubspaceId subspace_id)
{
assert(false);
//`Finish
return;
}
const Subspace * NumServer::getSubspace(const std::string & subspace_name) const
{
assert(subspace_name.length() > 0);
auto it = subname2id_.find(subspace_name);
if(it == subname2id_.end()) std::cout << "#ERROR(NumServer::getSubspace): Subspace not found: " << subspace_name << std::endl;
assert(it != subname2id_.end());
SpaceId space_id = (*it).second;
const VectorSpace * space = space_register_.getSpace(space_id);
assert(space != nullptr);
const std::string & space_name = space->getName();
assert(space_name.length() > 0);
return space_register_.getSubspace(space_name,subspace_name);
}
int NumServer::submit(std::shared_ptr<TensorOperation> operation)
{
assert(false);
//`Finish
return 0;
}
int NumServer::submit(std::shared_ptr<TensorNetwork> network)
{
assert(false);
//`Finish
return 0;
}
bool NumServer::sync(const Tensor & tensor, bool wait)
{
assert(false);
//`Finish
return false;
}
bool NumServer::sync(TensorOperation & operation, bool wait)
{
if(operation.getNumOperands() > 0) return this->sync(*(operation.getTensorOperand(0)),wait);
return true;
}
bool NumServer::sync(TensorNetwork & network, bool wait)
{
assert(false);
//`Finish
return false;
}
} //namespace numerics
} //namespace exatn
/** ExaTN::Numerics: Numerical server
REVISION: 2019/05/31
REVISION: 2019/06/06
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
/** Rationale:
(a) Numerical server provides basic tensor network processing functionality:
+ Opening/closing TAProL scopes (top scope 0 "GLOBAL" is open automatically);
+ Creation/destruction of named vector spaces and their named subspaces;
+ Registration/retrieval of external data (class BytePacket);
+ Registration/retrieval of external tensor methods (class TensorMethod);
+ Submission for processing of individual tensor operations or tensor networks.
(b) Processing of individual tensor operations or tensor networks has asynchronous semantics:
Submit TensorOperation/TensorNetwork for processing, then synchronize on the tensor-result.
Processing of a tensor operation means evaluating the output tensor operand (#0).
Processing of a tensor network means evaluating the output tensor (#0).
Synchronization of processing of a tensor operation or tensor network
means ensuring that the tensor-result (output tensor) has been fully computed.
**/
#ifndef EXATN_NUMERICS_NUM_SERVER_HPP_
#define EXATN_NUMERICS_NUM_SERVER_HPP_
......@@ -31,7 +46,7 @@ class NumServer{
public:
NumServer() = default;
NumServer();
NumServer(const NumServer &) = delete;
NumServer & operator=(const NumServer &) = delete;
NumServer(NumServer &&) noexcept = default;
......@@ -68,18 +83,42 @@ public:
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
/** Returns a non-owning pointer to a previosuly registered vector space,
including the anonymous vector space. **/
const VectorSpace * getVectorSpace(const std::string & space_name) const;
/** Creates a named subspace of a named vector space,
returns its registered id, and, optionally, a non-owning pointer to it. **/
SubspaceId createSubspace(const std::string & subspace_name, //in: subspace name
const std::string & space_name, //in: containing vector space name
const std::pair<DimOffset,DimOffset> bounds, //in: range of basis vectors defining the created subspace: [
const Subspace ** subspace_ptr = nullptr); //out: non-owning pointer to the created subspace
SubspaceId createSubspace(const std::string & subspace_name, //in: subspace name
const std::string & space_name, //in: containing vector space name
std::pair<DimOffset,DimOffset> bounds, //in: range of basis vectors defining the created subspace
const Subspace ** subspace_ptr = nullptr); //out: non-owning pointer to the created subspace
/** Destroys a previously created named subspace. **/
/** Destroys a previously created named subspace of a named vector space. **/
void destroySubspace(const std::string & subspace_name); //in: name of the subspace to destroy
void destroySubspace(SubspaceId subspace_id);
/** Returns a non-owning pointer to a previosuly registered named subspace
of a previously registered named vector space. **/
const Subspace * getSubspace(const std::string & subspace_name) const;
/** Submits an individual tensor operation for processing. **/
int submit(std::shared_ptr<TensorOperation> operation);
/** Submits a tensor network for processing (evaluating the tensor-result). **/
int submit(std::shared_ptr<TensorNetwork> network);
/** Synchronizes all tensor operations on a given tensor. **/
bool sync(const Tensor & tensor,
bool wait = false);
/** Synchronizes execution of a specific tensor operation. **/
bool sync(TensorOperation & operation,
bool wait = false);
/** Synchronizes execution of a specific tensor network. **/
bool sync(TensorNetwork & network,
bool wait = false);
private:
SpaceRegister space_register_; //register of vector spaces and their named subspaces
......@@ -88,7 +127,7 @@ private:
std::map<std::string,std::shared_ptr<TensorMethod<Identifiable>>> ext_methods_; //external tensor methods
std::map<std::string,std::shared_ptr<BytePacket>> ext_data_; //external data
std::stack<ScopeId> scopes_; //TAProL scope stack
std::stack<std::pair<std::string,ScopeId>> scopes_; //TAProL scope stack: {Scope name, Scope Id}
};
......
/** ExaTN::Numerics: Register of vector spaces and their subspaces
REVISION: 2019/05/31
REVISION: 2019/06/06
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -108,6 +108,29 @@ const VectorSpace * SpaceRegister::getSpace(const std::string & name) const
}
}
SubspaceId SpaceRegister::registerSubspace(std::shared_ptr<Subspace> subspace)
{
const VectorSpace * space = subspace->getVectorSpace();
assert(space != nullptr);
SpaceId space_id = space->getRegisteredId();
assert(space_id != SOME_SPACE && space_id < spaces_.size());
SubspaceRegister & subspace_register = spaces_[space_id].subspaces_;
return subspace_register.registerSubspace(subspace);
}
const Subspace * SpaceRegister::getSubspace(const std::string & space_name,
const std::string & subspace_name) const
{
assert(space_name.length() > 0 && subspace_name.length() > 0);
auto it = name2id_.find(space_name);
if(it == name2id_.end()) std::cout << "#ERROR(SpaceRegister::registerSubspace): Space not found: " << space_name << std::endl;
assert(it != name2id_.end());
SpaceId space_id = (*it).second;
assert(space_id != SOME_SPACE && space_id < spaces_.size());
const SubspaceRegister & subspace_register = spaces_[space_id].subspaces_;
return subspace_register.getSubspace(subspace_name);
}
} //namespace numerics
} //namespace exatn
/** ExaTN::Numerics: Register of vector spaces and their subspaces
REVISION: 2019/06/03
REVISION: 2019/06/06
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -121,6 +121,16 @@ public:
/** Returns a non-owning pointer to a stored vector space by its symbolic name. **/
const VectorSpace * getSpace(const std::string & name) const;
/** Registers a named subspace of a named vector space and returns its registered id.
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);
/** Returns a non-owning pointer to a registerd subspace of a registered vector space. **/
const Subspace * getSubspace(const std::string & space_name,
const std::string & subspace_name) const;
private:
std::vector<SpaceRegEntry> spaces_; //registered vector spaces
......
/** ExaTN::Numerics: Space Basis
REVISION: 2019/05/27
REVISION: 2019/06/06
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -82,6 +82,12 @@ subspace_name_(""), id_(UNREG_SUBSPACE)
assert(lower_bound_ <= upper_bound_ && upper_bound_ < vector_space_->getDimension());
}
Subspace::Subspace(const VectorSpace * vector_space,
std::pair<DimOffset,DimOffset> bounds):
Subspace(vector_space,std::get<0>(bounds),std::get<1>(bounds))
{
}
Subspace::Subspace(const VectorSpace * vector_space,
DimOffset lower_bound,
DimOffset upper_bound,
......@@ -92,6 +98,13 @@ subspace_name_(subspace_name), id_(UNREG_SUBSPACE)
assert(lower_bound_ <= upper_bound_ && upper_bound_ < vector_space_->getDimension());
}
Subspace::Subspace(const VectorSpace * vector_space,
std::pair<DimOffset,DimOffset> bounds,
const std::string & subspace_name):
Subspace(vector_space,std::get<0>(bounds),std::get<1>(bounds),subspace_name)
{
}
void Subspace::printIt() const
{
if(subspace_name_.length() > 0){
......
/** ExaTN::Numerics: Spaces/Subspaces
REVISION: 2019/05/27
REVISION: 2019/06/06
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -88,11 +88,16 @@ public:
Subspace(const VectorSpace * vector_space,
DimOffset lower_bound,
DimOffset upper_bound);
Subspace(const VectorSpace * vector_space,
std::pair<DimOffset,DimOffset> bounds);
/** Named subspace of a vector space defined by a subrange of basis vectors. **/
Subspace(const VectorSpace * vector_space,
DimOffset lower_bound,
DimOffset upper_bound,
const std::string & subspace_name);
Subspace(const VectorSpace * vector_space,
std::pair<DimOffset,DimOffset> bounds,
const std::string & subspace_name);
Subspace(const Subspace & subspace) = default;
Subspace & operator=(const Subspace & subspace) = default;
......
/** ExaTN::Numerics: Tensor
REVISION: 2018/12/18
REVISION: 2019/06/05
Copyright (C) 2018-2018 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2018 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -76,6 +76,11 @@ std::pair<SpaceId,SubspaceId> Tensor::getDimSpaceAttr(unsigned int dim_id) const
return signature_.getDimSpaceAttr(dim_id);
}
std::size_t Tensor::getTensorId() const
{
return reinterpret_cast<std::size_t>(this);
}
} //namespace numerics
} //namespace exatn
/** ExaTN::Numerics: Abstract Tensor
REVISION: 2019/05/27
REVISION: 2019/06/05
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -102,6 +102,9 @@ public:
SubspaceId getDimSubspaceId(unsigned int dim_id) const;
std::pair<SpaceId,SubspaceId> getDimSpaceAttr(unsigned int dim_id) const;
/** Get the unique integer tensor id. **/
std::size_t getTensorId() const;
private:
std::string name_; //tensor name
......
/** ExaTN: Tensor basic types and parameters
REVISION: 2019/05/31
REVISION: 2019/06/05
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......
/** ExaTN::Numerics: Tensor connected to other tensors inside a tensor network
REVISION: 2019/05/31
REVISION: 2019/06/03
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_connected.hpp"
#include <iostream>
namespace exatn{
namespace numerics{
......@@ -15,6 +17,16 @@ TensorConn::TensorConn(std::shared_ptr<Tensor> tensor, unsigned int id, const st
{
}
void TensorConn::printIt() const
{
std::cout << id_ << ": ";
tensor_->printIt();
std::cout << ": { ";
for(const auto & leg: legs_) leg.printIt();
std::cout << " }" << std::endl;
return;
}
std::shared_ptr<Tensor> TensorConn::getTensor()
{
return tensor_;
......
/** ExaTN::Numerics: Tensor connected to other tensors in a tensor network
REVISION: 2019/05/31
REVISION: 2019/06/03
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -44,6 +44,9 @@ public:
TensorConn & operator=(TensorConn &&) noexcept = default;
virtual ~TensorConn() = default;
/** Prints. **/
void printIt() const;
/** Returns a co-owned pointer to the tensor. **/
std::shared_ptr<Tensor> getTensor();
......
/** ExaTN::Numerics: Tensor operation
REVISION: 2019/05/31
REVISION: 2019/06/05
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_operation.hpp"
#include <iostream>
namespace exatn{
namespace numerics{
......@@ -17,6 +19,23 @@ TensorOperation::TensorOperation(TensorOpCode opcode, unsigned int num_operands,
operands_.reserve(num_operands);
}
void TensorOperation::printIt() const
{
std::cout << "TensorOperation(" << static_cast<int>(opcode_) << "){" << std::endl;
if(pattern_.length() > 0) std::cout << " " << pattern_ << std::endl;
for(const auto & tensor: operands_){
std::cout << " ";
tensor->printIt();
std::cout << std::endl;
}
for(const auto & scalar: scalars_){
std::cout << " " << scalar;
}
if(scalars_.size() > 0) std::cout << std::endl;
std::cout << "}" << std::endl;
return;
}
unsigned int TensorOperation::getNumOperands() const
{
return num_operands_;
......@@ -27,6 +46,11 @@ unsigned int TensorOperation::getNumOperandsSet() const
return static_cast<unsigned int>(operands_.size());
}
std::size_t TensorOperation::getTensorOperandId(unsigned int op_num)
{
return ((this->getTensorOperand(op_num)).get())->getTensorId();
}
std::shared_ptr<Tensor> TensorOperation::getTensorOperand(unsigned int op_num)
{
if(op_num < operands_.size()) return operands_[op_num];
......
/** ExaTN::Numerics: Tensor operation
REVISION: 2019/06/03
REVISION: 2019/06/05
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -41,12 +41,18 @@ public:
/** Returns TRUE iff the tensor operation is fully set. **/
virtual bool isSet() const = 0;
/** Prints. **/
virtual void printIt() const;
/** Returns the number of tensor operands required for the tensor operation. **/
unsigned int getNumOperands() const;
/** Returns the number of tensor operands set. **/
unsigned int getNumOperandsSet() const;
/** Returns a unique integer tensor operand identifier. **/
std::size_t getTensorOperandId(unsigned int op_num);
/** 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);
......
/** ExaTN::Numerics: Tensor shape
REVISION: 2019/05/27
REVISION: 2019/06/05
Copyright (C) 2018-2018 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2018 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -72,7 +72,7 @@ extents_(extents.size())
}
int i = 0;
for(const auto & extent: extents) extents_[i++] = DimExtent{extent};
for(const auto & extent: extents) extents_[i++] = static_cast<DimExtent>(extent);
}
template<typename T>
......
......@@ -11,21 +11,21 @@ using namespace exatn::numerics;
TEST(NumericsTester, checkSimple)
{
{
TensorSignature signa{std::pair<SpaceId, SubspaceId>(1, 5),
std::pair<SpaceId, SubspaceId>(SOME_SPACE, 13)};
TensorSignature signa{std::pair<SpaceId,SubspaceId>(1,5),
std::pair<SpaceId,SubspaceId>(SOME_SPACE,13)};
std::cout << signa.getRank() << " " << signa.getDimSpaceId(0) << " "
<< signa.getDimSubspaceId(1) << " "
<< std::get<0>(signa.getDimSpaceAttr(1)) << std::endl;
signa.printIt();
std::cout << std::endl;
TensorShape shape{61, 32};
TensorShape shape{61,32};
std::cout << shape.getRank() << " " << shape.getDimExtent(0) << " "
<< shape.getDimExtent(1) << std::endl;
shape.printIt();
std::cout << std::endl;
TensorLeg leg{1, 4};
TensorLeg leg{1,4};
leg.printIt();
std::cout << std::endl;
}
......@@ -33,7 +33,39 @@ TEST(NumericsTester, checkSimple)
TEST(NumericsTester, checkNumServer)
{
NumServer num_server;
const VectorSpace * space1;
auto space1_id = num_server.createVectorSpace("Space1",1024,&space1);
space1->printIt();
std::cout << std::endl;
const VectorSpace * space2;
auto space2_id = num_server.createVectorSpace("Space2",2048,&space2);
space2->printIt();
std::cout << std::endl;