Commit 3d2dfc7f authored by Dmitry I. Lyakh's avatar Dmitry I. Lyakh

Introduced tensor slicing and slice insertion operations with the TAL-SH implementation.

parent 89e122c1
Pipeline #91615 passed with stage
in 4 minutes and 52 seconds
/** ExaTN::Numerics: Numerical server
REVISION: 2020/02/27
REVISION: 2020/02/28
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -28,6 +28,7 @@ NumServer::NumServer(MPI_Comm communicator,
{
int mpi_error = MPI_Comm_size(communicator,&num_processes_); assert(mpi_error == MPI_SUCCESS);
mpi_error = MPI_Comm_rank(communicator,&process_rank_); assert(mpi_error == MPI_SUCCESS);
space_register_ = getSpaceRegister(); assert(space_register_);
tensor_op_factory_ = TensorOpFactory::get();
scopes_.push(std::pair<std::string,ScopeId>{"GLOBAL",0}); //GLOBAL scope 0 is automatically open (top scope)
tensor_rt_->openScope("GLOBAL");
......@@ -39,6 +40,7 @@ NumServer::NumServer(const std::string & graph_executor_name,
tensor_rt_(std::make_shared<runtime::TensorRuntime>(graph_executor_name,node_executor_name))
{
num_processes_ = 1; process_rank_ = 0;
space_register_ = getSpaceRegister(); assert(space_register_);
tensor_op_factory_ = TensorOpFactory::get();
scopes_.push(std::pair<std::string,ScopeId>{"GLOBAL",0}); //GLOBAL scope 0 is automatically open (top scope)
tensor_rt_->openScope("GLOBAL");
......@@ -142,8 +144,8 @@ SpaceId NumServer::createVectorSpace(const std::string & space_name, DimExtent s
const VectorSpace ** space_ptr)
{
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);
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;
}
......@@ -163,7 +165,7 @@ void NumServer::destroyVectorSpace(SpaceId space_id)
const VectorSpace * NumServer::getVectorSpace(const std::string & space_name) const
{
return space_register_.getSpace(space_name);
return space_register_->getSpace(space_name);
}
......@@ -173,10 +175,10 @@ SubspaceId NumServer::createSubspace(const std::string & subspace_name,
const Subspace ** subspace_ptr)
{
assert(subspace_name.length() > 0 && space_name.length() > 0);
const VectorSpace * space = space_register_.getSpace(space_name);
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);
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);
......@@ -204,11 +206,11 @@ const Subspace * NumServer::getSubspace(const std::string & subspace_name) const
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);
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);
return space_register_->getSubspace(space_name,subspace_name);
}
bool NumServer::submit(std::shared_ptr<TensorOperation> operation)
......
/** ExaTN::Numerics: Numerical server
REVISION: 2020/02/27
REVISION: 2020/02/28
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -349,7 +349,7 @@ private:
void destroyOrphanedTensors();
numerics::SpaceRegister space_register_; //register of vector spaces and their named subspaces
std::shared_ptr<numerics::SpaceRegister> space_register_; //register of vector spaces and their named subspaces
std::unordered_map<std::string,SpaceId> subname2id_; //maps a subspace name to its parental vector space id
std::unordered_map<std::string,std::shared_ptr<Tensor>> tensors_; //registered tensors (by CREATE operation)
......
......@@ -16,6 +16,8 @@ add_library(${LIBRARY_NAME}
tensor_op_create.cpp
tensor_op_destroy.cpp
tensor_op_transform.cpp
tensor_op_slice.cpp
tensor_op_insert.cpp
tensor_op_add.cpp
tensor_op_contract.cpp
tensor_op_factory.cpp
......
/** ExaTN::Numerics: Register of vector spaces and their subspaces
REVISION: 2019/06/06
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
#include "space_register.hpp"
#include <iostream>
#include "assert.h"
#include <cassert>
namespace exatn{
//Register of vector spaces and their subspaces (singleton):
std::shared_ptr<numerics::SpaceRegister> space_register {nullptr};
namespace numerics{
SubspaceRegEntry::SubspaceRegEntry(std::shared_ptr<Subspace> subspace):
......@@ -133,4 +136,10 @@ const Subspace * SpaceRegister::getSubspace(const std::string & space_name,
} //namespace numerics
std::shared_ptr<numerics::SpaceRegister> getSpaceRegister()
{
if(!space_register) space_register = std::make_shared<numerics::SpaceRegister>();
return space_register;
}
} //namespace exatn
/** ExaTN::Numerics: Register of vector spaces and their subspaces
REVISION: 2019/06/06
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
/** Rationale:
(a) Any unregistered vector space has id = SOME_SPACE = 0 (anonymous vector space).
......@@ -139,6 +139,9 @@ private:
} //namespace numerics
/** Returns the global register of vector spaces and subspaces. **/
std::shared_ptr<numerics::SpaceRegister> getSpaceRegister();
} //namespace exatn
#endif //EXATN_NUMERICS_SPACE_REGISTER_HPP_
/** ExaTN: Tensor basic types and parameters
REVISION: 2019/09/01
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
#ifndef EXATN_NUMERICS_TENSOR_BASIC_HPP_
#define EXATN_NUMERICS_TENSOR_BASIC_HPP_
......@@ -40,8 +40,12 @@ enum class TensorOpCode{
CREATE, //tensor creation
DESTROY, //tensor destruction
TRANSFORM, //tensor transformation/initialization
SLICE, //tensor slicing
INSERT, //tensor insertion
ADD, //tensor addition
CONTRACT //tensor contraction
CONTRACT, //tensor contraction
BROADCAST, //tensor broadcast (parallel execution only)
ALLREDUCE //tensor allreduce (parallel execution only)
};
enum class TensorElementType{
......
/** ExaTN::Numerics: Tensor operation factory
REVISION: 2019/09/10
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_op_factory.hpp"
......@@ -15,6 +15,8 @@ TensorOpFactory::TensorOpFactory()
registerTensorOp(TensorOpCode::CREATE,&TensorOpCreate::createNew);
registerTensorOp(TensorOpCode::DESTROY,&TensorOpDestroy::createNew);
registerTensorOp(TensorOpCode::TRANSFORM,&TensorOpTransform::createNew);
registerTensorOp(TensorOpCode::SLICE,&TensorOpSlice::createNew);
registerTensorOp(TensorOpCode::INSERT,&TensorOpInsert::createNew);
registerTensorOp(TensorOpCode::ADD,&TensorOpAdd::createNew);
registerTensorOp(TensorOpCode::CONTRACT,&TensorOpContract::createNew);
}
......
/** ExaTN::Numerics: Tensor operation factory
REVISION: 2019/09/10
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
/** Rationale:
(a) Creates new tensor operations of desired kind.
......@@ -16,6 +16,8 @@ Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle) **/
#include "tensor_op_create.hpp"
#include "tensor_op_destroy.hpp"
#include "tensor_op_transform.hpp"
#include "tensor_op_slice.hpp"
#include "tensor_op_insert.hpp"
#include "tensor_op_add.hpp"
#include "tensor_op_contract.hpp"
......
/** ExaTN::Numerics: Tensor operation: Inserts a slice into a tensor
REVISION: 2020/02/28
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
#include "exatn_service.hpp"
#include "tensor_op_insert.hpp"
#include "tensor_node_executor.hpp"
namespace exatn{
namespace numerics{
TensorOpInsert::TensorOpInsert():
TensorOperation(TensorOpCode::INSERT,2,0)
{
}
bool TensorOpInsert::isSet() const
{
return (this->getNumOperandsSet() == this->getNumOperands());
}
int TensorOpInsert::accept(runtime::TensorNodeExecutor & node_executor,
runtime::TensorOpExecHandle * exec_handle)
{
return node_executor.execute(*this,exec_handle);
}
std::unique_ptr<TensorOperation> TensorOpInsert::createNew()
{
return std::unique_ptr<TensorOperation>(new TensorOpInsert());
}
} //namespace numerics
} //namespace exatn
/** ExaTN::Numerics: Tensor operation: Inserts a slice into a tensor
REVISION: 2020/02/28
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
/** Rationale:
(a) Inserts a slice into a tensor inside the processing backend.
**/
#ifndef EXATN_NUMERICS_TENSOR_OP_INSERT_HPP_
#define EXATN_NUMERICS_TENSOR_OP_INSERT_HPP_
#include "tensor_basic.hpp"
#include "tensor_operation.hpp"
namespace exatn{
namespace numerics{
class TensorOpInsert: public TensorOperation{
public:
TensorOpInsert();
TensorOpInsert(const TensorOpInsert &) = default;
TensorOpInsert & operator=(const TensorOpInsert &) = default;
TensorOpInsert(TensorOpInsert &&) noexcept = default;
TensorOpInsert & operator=(TensorOpInsert &&) noexcept = default;
virtual ~TensorOpInsert() = default;
/** Returns TRUE iff the tensor operation is fully set. **/
virtual bool isSet() const override;
/** Accepts tensor node executor which will execute this tensor operation. **/
virtual int accept(runtime::TensorNodeExecutor & node_executor,
runtime::TensorOpExecHandle * exec_handle) override;
/** Create a new polymorphic instance of this subclass. **/
static std::unique_ptr<TensorOperation> createNew();
private:
};
} //namespace numerics
} //namespace exatn
#endif //EXATN_NUMERICS_TENSOR_OP_INSERT_HPP_
/** ExaTN::Numerics: Tensor operation: Extracts a slice from a tensor
REVISION: 2020/02/28
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
#include "exatn_service.hpp"
#include "tensor_op_slice.hpp"
#include "tensor_node_executor.hpp"
namespace exatn{
namespace numerics{
TensorOpSlice::TensorOpSlice():
TensorOperation(TensorOpCode::SLICE,2,0)
{
}
bool TensorOpSlice::isSet() const
{
return (this->getNumOperandsSet() == this->getNumOperands());
}
int TensorOpSlice::accept(runtime::TensorNodeExecutor & node_executor,
runtime::TensorOpExecHandle * exec_handle)
{
return node_executor.execute(*this,exec_handle);
}
std::unique_ptr<TensorOperation> TensorOpSlice::createNew()
{
return std::unique_ptr<TensorOperation>(new TensorOpSlice());
}
} //namespace numerics
} //namespace exatn
/** ExaTN::Numerics: Tensor operation: Extracts a slice from a tensor
REVISION: 2020/02/28
Copyright (C) 2018-2020 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle) **/
/** Rationale:
(a) Extracts a slice from a tensor inside the processing backend.
**/
#ifndef EXATN_NUMERICS_TENSOR_OP_SLICE_HPP_
#define EXATN_NUMERICS_TENSOR_OP_SLICE_HPP_
#include "tensor_basic.hpp"
#include "tensor_operation.hpp"
namespace exatn{
namespace numerics{
class TensorOpSlice: public TensorOperation{
public:
TensorOpSlice();
TensorOpSlice(const TensorOpSlice &) = default;
TensorOpSlice & operator=(const TensorOpSlice &) = default;
TensorOpSlice(TensorOpSlice &&) noexcept = default;
TensorOpSlice & operator=(TensorOpSlice &&) noexcept = default;
virtual ~TensorOpSlice() = default;
/** Returns TRUE iff the tensor operation is fully set. **/
virtual bool isSet() const override;
/** Accepts tensor node executor which will execute this tensor operation. **/
virtual int accept(runtime::TensorNodeExecutor & node_executor,
runtime::TensorOpExecHandle * exec_handle) override;
/** Create a new polymorphic instance of this subclass. **/
static std::unique_ptr<TensorOperation> createNew();
private:
};
} //namespace numerics
} //namespace exatn
#endif //EXATN_NUMERICS_TENSOR_OP_SLICE_HPP_
/** ExaTN:: Tensor Runtime: Tensor graph node executor: Exatensor
REVISION: 2019/10/04
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle)
Copyright (C) 2018-2020 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle)
**/
#include "node_executor_exatensor.hpp"
......@@ -40,6 +40,22 @@ int ExatensorNodeExecutor::execute(numerics::TensorOpTransform & op,
}
int ExatensorNodeExecutor::execute(numerics::TensorOpSlice & op,
TensorOpExecHandle * exec_handle)
{
//`Implement
return 0;
}
int ExatensorNodeExecutor::execute(numerics::TensorOpInsert & op,
TensorOpExecHandle * exec_handle)
{
//`Implement
return 0;
}
int ExatensorNodeExecutor::execute(numerics::TensorOpAdd & op,
TensorOpExecHandle * exec_handle)
{
......
/** ExaTN:: Tensor Runtime: Tensor graph node executor: Exatensor
REVISION: 2019/10/04
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle)
Copyright (C) 2018-2020 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle)
Rationale:
......@@ -37,6 +37,10 @@ public:
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpTransform & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpSlice & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpInsert & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpAdd & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpContract & op,
......
/** ExaTN:: Tensor Runtime: Tensor graph node executor: Talsh
REVISION: 2019/10/07
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle)
Copyright (C) 2018-2020 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle)
**/
#include "node_executor_talsh.hpp"
......@@ -122,6 +122,118 @@ int TalshNodeExecutor::execute(numerics::TensorOpTransform & op,
}
int TalshNodeExecutor::execute(numerics::TensorOpSlice & op,
TensorOpExecHandle * exec_handle)
{
assert(op.isSet());
const auto & tensor0 = *(op.getTensorOperand(0));
const auto tensor0_hash = tensor0.getTensorHash();
auto tens0_pos = tensors_.find(tensor0_hash);
if(tens0_pos == tensors_.end()){
std::cout << "#ERROR(exatn::runtime::node_executor_talsh): SLICE: Tensor operand 0 not found: " << std::endl;
op.printIt();
assert(false);
}
auto & tens0 = *(tens0_pos->second);
const auto & tensor1 = *(op.getTensorOperand(1));
const auto tensor1_hash = tensor1.getTensorHash();
auto tens1_pos = tensors_.find(tensor1_hash);
if(tens1_pos == tensors_.end()){
std::cout << "#ERROR(exatn::runtime::node_executor_talsh): SLICE: Tensor operand 1 not found: " << std::endl;
op.printIt();
assert(false);
}
auto & tens1 = *(tens1_pos->second);
*exec_handle = op.getId();
auto task_res = tasks_.emplace(std::make_pair(*exec_handle,
std::make_shared<talsh::TensorTask>()));
if(!task_res.second){
std::cout << "#ERROR(exatn::runtime::node_executor_talsh): SLICE: Attempt to execute the same operation twice: " << std::endl;
op.printIt();
assert(false);
}
const auto & slice_signature = tensor0.getSignature();
const auto slice_rank = slice_signature.getRank();
std::vector<int> offsets(slice_rank);
for(unsigned int i = 0; i < slice_rank; ++i){
auto space_id = slice_signature.getDimSpaceId(i);
auto subspace_id = slice_signature.getDimSubspaceId(i);
if(space_id == SOME_SPACE){
offsets[i] = static_cast<int>(subspace_id);
}else{
const auto * space = getSpaceRegister()->getSpace(space_id);
assert(false); //`finish
}
}
auto error_code = tens1.extractSlice((task_res.first)->second.get(),
tens0,
offsets,
DEV_HOST,0);
return error_code;
}
int TalshNodeExecutor::execute(numerics::TensorOpInsert & op,
TensorOpExecHandle * exec_handle)
{
assert(op.isSet());
const auto & tensor0 = *(op.getTensorOperand(0));
const auto tensor0_hash = tensor0.getTensorHash();
auto tens0_pos = tensors_.find(tensor0_hash);
if(tens0_pos == tensors_.end()){
std::cout << "#ERROR(exatn::runtime::node_executor_talsh): INSERT: Tensor operand 0 not found: " << std::endl;
op.printIt();
assert(false);
}
auto & tens0 = *(tens0_pos->second);
const auto & tensor1 = *(op.getTensorOperand(1));
const auto tensor1_hash = tensor1.getTensorHash();
auto tens1_pos = tensors_.find(tensor1_hash);
if(tens1_pos == tensors_.end()){
std::cout << "#ERROR(exatn::runtime::node_executor_talsh): INSERT: Tensor operand 1 not found: " << std::endl;
op.printIt();
assert(false);
}
auto & tens1 = *(tens1_pos->second);
*exec_handle = op.getId();
auto task_res = tasks_.emplace(std::make_pair(*exec_handle,
std::make_shared<talsh::TensorTask>()));
if(!task_res.second){
std::cout << "#ERROR(exatn::runtime::node_executor_talsh): INSERT: Attempt to execute the same operation twice: " << std::endl;
op.printIt();
assert(false);
}
const auto & slice_signature = tensor1.getSignature();
const auto slice_rank = slice_signature.getRank();
std::vector<int> offsets(slice_rank);
for(unsigned int i = 0; i < slice_rank; ++i){
auto space_id = slice_signature.getDimSpaceId(i);
auto subspace_id = slice_signature.getDimSubspaceId(i);
if(space_id == SOME_SPACE){
offsets[i] = static_cast<int>(subspace_id);
}else{
const auto * space = getSpaceRegister()->getSpace(space_id);
assert(false); //`finish
}
}
auto error_code = tens0.insertSlice((task_res.first)->second.get(),
tens1,
offsets,
DEV_HOST,0);
return error_code;
}
int TalshNodeExecutor::execute(numerics::TensorOpAdd & op,
TensorOpExecHandle * exec_handle)
{
......
/** ExaTN:: Tensor Runtime: Tensor graph node executor: Talsh
REVISION: 2019/10/07
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle)
Copyright (C) 2018-2020 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle)
Rationale:
......@@ -41,6 +41,10 @@ public:
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpTransform & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpSlice & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpInsert & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpAdd & op,
TensorOpExecHandle * exec_handle) override;
int execute(numerics::TensorOpContract & op,
......
/** ExaTN:: Tensor Runtime: Tensor graph node executor
REVISION: 2019/10/04
REVISION: 2020/02/28
Copyright (C) 2018-2019 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2019 Oak Ridge National Laboratory (UT-Battelle)
Copyright (C) 2018-2020 Dmitry Lyakh, Tiffany Mintz, Alex McCaskey
Copyright (C) 2018-2020 Oak Ridge National Laboratory (UT-Battelle)
Rationale:
(a) Tensor node executor provides actual implementation of registered
......@@ -22,6 +22,7 @@ Rationale:
#include "tensor_op_factory.hpp"
#include "tensor.hpp"
#include "space_register.hpp"
#include <vector>
#include <memory>
......@@ -52,6 +53,10 @@ public:
TensorOpExecHandle * exec_handle) = 0;
virtual int execute(numerics::TensorOpTransform & op,
TensorOpExecHandle * exec_handle) = 0;
virtual int execute(numerics::TensorOpSlice & op,
TensorOpExecHandle * exec_handle) = 0;
virtual int execute(numerics::TensorOpInsert & op,
TensorOpExecHandle * exec_handle) = 0;
virtual int execute(numerics::TensorOpAdd & op,
TensorOpExecHandle * exec_handle) = 0;
virtual int execute(numerics::TensorOpContract & op,
......
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