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

Implemented exatn::dereplicateTensor


Signed-off-by: default avatarDmitry I. Lyakh <quant4me@gmail.com>
parent c4f6394a
Pipeline #167501 failed with stage
in 5 minutes and 49 seconds
/** ExaTN::Numerics: General client header (free function API)
REVISION: 2021/09/29
REVISION: 2021/09/30
Copyright (C) 2018-2021 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2021 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -523,6 +523,26 @@ inline bool replicateTensorSync(const ProcessGroup & process_group, //in: chosen
{return numericalServer->replicateTensorSync(process_group,name,root_process_rank);}
/** Shrinks the domain of existence of a given tensor to a single process. **/
inline bool dereplicateTensor(const std::string & name, //in: tensor name
int root_process_rank) //in: local rank of the chosen process
{return numericalServer->dereplicateTensor(name,root_process_rank);}
inline bool dereplicateTensorSync(const std::string & name, //in: tensor name
int root_process_rank) //in: local rank of the chosen process
{return numericalServer->dereplicateTensorSync(name,root_process_rank);}
inline bool dereplicateTensor(const ProcessGroup & process_group, //in: chosen group of MPI processes
const std::string & name, //in: tensor name
int root_process_rank) //in: local rank of the chosen process
{return numericalServer->dereplicateTensor(process_group,name,root_process_rank);}
inline bool dereplicateTensorSync(const ProcessGroup & process_group, //in: chosen group of MPI processes
const std::string & name, //in: tensor name
int root_process_rank) //in: local rank of the chosen process
{return numericalServer->dereplicateTensorSync(process_group,name,root_process_rank);}
/** Broadcast a tensor among all MPI processes within a given process group,
which defaults to all MPI processes. This function is needed when
a tensor is updated in an operation submitted to a subset of MPI processes
......
/** ExaTN::Numerics: Numerical server
REVISION: 2021/09/29
REVISION: 2021/09/30
Copyright (C) 2018-2021 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2021 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -1851,6 +1851,92 @@ bool NumServer::replicateTensorSync(const ProcessGroup & process_group, const st
return broadcastTensorSync(process_group,name,root_process_rank);
}
bool NumServer::dereplicateTensor(const std::string & name, int root_process_rank)
{
return dereplicateTensor(getDefaultProcessGroup(),name,root_process_rank);
}
bool NumServer::dereplicateTensorSync(const std::string & name, int root_process_rank)
{
return dereplicateTensorSync(getDefaultProcessGroup(),name,root_process_rank);
}
bool NumServer::dereplicateTensor(const ProcessGroup & process_group, const std::string & name, int root_process_rank)
{
unsigned int local_rank; //local process rank within the process group
if(!process_group.rankIsIn(process_rank_,&local_rank)) return true; //process is not in the group: Do nothing
auto iter = tensors_.find(name);
if(iter != tensors_.end()){
if(getTensorProcessGroup(name).isCongruentTo(process_group)){
if(!iter->second->isComposite()){
auto tensor_mapper = getTensorMapper(process_group);
auto num_deleted = tensor_comms_.erase(name);
if(local_rank == root_process_rank){
auto saved = tensor_comms_.emplace(std::make_pair(name,getCurrentProcessGroup()));
assert(saved.second);
}else{
std::shared_ptr<TensorOperation> op = tensor_op_factory_->createTensorOp(TensorOpCode::DESTROY);
op->setTensorOperand(iter->second);
auto submitted = submit(op,tensor_mapper);
assert(submitted);
}
}else{
std::cout << "#ERROR(exatn::NumServer::dereplicateTensor): Unable to dereplicate composite tensors like tensor "
<< name << std::endl;
assert(false);
}
}else{
std::cout << "#ERROR(exatn::NumServer::dereplicateTensor): Domain of existence of tensor " << name
<< " does not match the provided execution process group!" << std::endl;
assert(false);
}
}else{
std::cout << "#ERROR(exatn::NumServer::dereplicateTensor): Tensor " << name << " not found!" << std::endl;
assert(false);
}
return true;
}
bool NumServer::dereplicateTensorSync(const ProcessGroup & process_group, const std::string & name, int root_process_rank)
{
unsigned int local_rank; //local process rank within the process group
if(!process_group.rankIsIn(process_rank_,&local_rank)) return true; //process is not in the group: Do nothing
auto iter = tensors_.find(name);
if(iter != tensors_.end()){
if(getTensorProcessGroup(name).isCongruentTo(process_group)){
if(!iter->second->isComposite()){
auto tensor_mapper = getTensorMapper(process_group);
auto num_deleted = tensor_comms_.erase(name);
if(local_rank == root_process_rank){
auto saved = tensor_comms_.emplace(std::make_pair(name,getCurrentProcessGroup()));
assert(saved.second);
}else{
std::shared_ptr<TensorOperation> op = tensor_op_factory_->createTensorOp(TensorOpCode::DESTROY);
op->setTensorOperand(iter->second);
auto submitted = submit(op,tensor_mapper);
if(submitted) submitted = sync(*op);
assert(submitted);
}
#ifdef MPI_ENABLED
auto synced = sync(process_group);
#endif
}else{
std::cout << "#ERROR(exatn::NumServer::dereplicateTensorSync): Unable to dereplicate composite tensors like tensor "
<< name << std::endl;
assert(false);
}
}else{
std::cout << "#ERROR(exatn::NumServer::dereplicateTensorSync): Domain of existence of tensor " << name
<< " does not match the provided execution process group!" << std::endl;
assert(false);
}
}else{
std::cout << "#ERROR(exatn::NumServer::dereplicateTensorSync): Tensor " << name << " not found!" << std::endl;
assert(false);
}
return true;
}
bool NumServer::broadcastTensor(const std::string & name, int root_process_rank)
{
return broadcastTensor(getDefaultProcessGroup(),name,root_process_rank);
......
/** ExaTN::Numerics: Numerical server
REVISION: 2021/09/29
REVISION: 2021/09/30
Copyright (C) 2018-2021 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2021 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -698,6 +698,21 @@ public:
const std::string & name, //in: tensor name
int root_process_rank); //in: local rank of the root process within the given process group
/** Shrinks the domain of existence of a given tensor to a single process. **/
bool dereplicateTensor(const std::string & name, //in: tensor name
int root_process_rank); //in: local rank of the chosen process
bool dereplicateTensorSync(const std::string & name, //in: tensor name
int root_process_rank); //in: local rank of the chosen process
bool dereplicateTensor(const ProcessGroup & process_group, //in: chosen group of MPI processes
const std::string & name, //in: tensor name
int root_process_rank); //in: local rank of the chose process
bool dereplicateTensorSync(const ProcessGroup & process_group, //in: chosen group of MPI processes
const std::string & name, //in: tensor name
int root_process_rank); //in: local rank of the chosen process
/** Broadcast a tensor among all MPI processes within a given process group,
which defaults to all MPI processes. This function is needed when
a tensor is updated in an operation submitted to a subset of MPI processes
......
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