1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-04-09 21:50:45 +01:00

Hadrons: much simpler reference dependency

This commit is contained in:
Antonin Portelli 2017-12-12 13:08:01 +00:00
parent f9aa39e1c4
commit 64161a8743
20 changed files with 171 additions and 126 deletions

View File

@ -341,81 +341,21 @@ Environment::Size Environment::getTotalSize(void) const
return size; return size;
} }
void Environment::addOwnership(const unsigned int owner, void Environment::freeObject(const unsigned int address)
const unsigned int property)
{ {
if (hasObject(property)) if (hasCreatedObject(address))
{ {
object_[property].owners.insert(owner); LOG(Message) << "Destroying object '" << object_[address].name
} << "'" << std::endl;
else
{
HADRON_ERROR("no object with address " + std::to_string(property));
}
if (hasObject(owner))
{
object_[owner].properties.insert(property);
}
else
{
HADRON_ERROR("no object with address " + std::to_string(owner));
} }
object_[address].size = 0;
object_[address].type = nullptr;
object_[address].data.reset(nullptr);
} }
void Environment::addOwnership(const std::string owner, void Environment::freeObject(const std::string name)
const std::string property)
{ {
addOwnership(getObjectAddress(owner), getObjectAddress(property)); freeObject(getObjectAddress(name));
}
bool Environment::hasOwners(const unsigned int address) const
{
if (hasObject(address))
{
return (!object_[address].owners.empty());
}
else
{
HADRON_ERROR("no object with address " + std::to_string(address));
}
}
bool Environment::hasOwners(const std::string name) const
{
return hasOwners(getObjectAddress(name));
}
bool Environment::freeObject(const unsigned int address)
{
if (!hasOwners(address))
{
if (hasCreatedObject(address))
{
LOG(Message) << "Destroying object '" << object_[address].name
<< "'" << std::endl;
}
for (auto &p: object_[address].properties)
{
object_[p].owners.erase(address);
}
object_[address].size = 0;
object_[address].type = nullptr;
object_[address].owners.clear();
object_[address].properties.clear();
object_[address].data.reset(nullptr);
return true;
}
else
{
return false;
}
}
bool Environment::freeObject(const std::string name)
{
return freeObject(getObjectAddress(name));
} }
void Environment::freeAll(void) void Environment::freeAll(void)

View File

@ -82,7 +82,6 @@ private:
const std::type_info *type{nullptr}; const std::type_info *type{nullptr};
std::string name; std::string name;
int module{-1}; int module{-1};
std::set<unsigned int> owners, properties;
std::unique_ptr<Object> data{nullptr}; std::unique_ptr<Object> data{nullptr};
}; };
public: public:
@ -140,14 +139,8 @@ public:
template <typename T> template <typename T>
bool isObjectOfType(const std::string name) const; bool isObjectOfType(const std::string name) const;
Environment::Size getTotalSize(void) const; Environment::Size getTotalSize(void) const;
void addOwnership(const unsigned int owner, void freeObject(const unsigned int address);
const unsigned int property); void freeObject(const std::string name);
void addOwnership(const std::string owner,
const std::string property);
bool hasOwners(const unsigned int address) const;
bool hasOwners(const std::string name) const;
bool freeObject(const unsigned int address);
bool freeObject(const std::string name);
void freeAll(void); void freeAll(void);
// print environment content // print environment content
void printContent(void) const; void printContent(void) const;
@ -252,15 +245,23 @@ T * Environment::getObject(const unsigned int address) const
{ {
if (hasObject(address)) if (hasObject(address))
{ {
if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get())) if (hasCreatedObject(address))
{ {
return h->getPt(); if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get()))
{
return h->getPt();
}
else
{
HADRON_ERROR("object with address " + std::to_string(address) +
" does not have type '" + typeName(&typeid(T)) +
"' (has type '" + getObjectType(address) + "')");
}
} }
else else
{ {
HADRON_ERROR("object with address " + std::to_string(address) + HADRON_ERROR("object with address " + std::to_string(address) +
" does not have type '" + typeName(&typeid(T)) + " is empty");
"' (has type '" + getObjectType(address) + "')");
} }
} }
else else

View File

@ -430,7 +430,7 @@ std::vector<T> Graph<T>::getAdjacentVertices(const T &value) const
{ {
return ((e.first == value) or (e.second == value)); return ((e.first == value) or (e.second == value));
}; };
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred); auto eIt = std::find_if(edgeSet_.begin(), edgeSet_.end(), pred);
while (eIt != edgeSet_.end()) while (eIt != edgeSet_.end())
{ {
@ -442,7 +442,7 @@ std::vector<T> Graph<T>::getAdjacentVertices(const T &value) const
{ {
adjacentVertex.push_back((*eIt).first); adjacentVertex.push_back((*eIt).first);
} }
eIt = find_if(++eIt, edgeSet_.end(), pred); eIt = std::find_if(++eIt, edgeSet_.end(), pred);
} }
return adjacentVertex; return adjacentVertex;
@ -458,12 +458,12 @@ std::vector<T> Graph<T>::getChildren(const T &value) const
{ {
return (e.first == value); return (e.first == value);
}; };
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred); auto eIt = std::find_if(edgeSet_.begin(), edgeSet_.end(), pred);
while (eIt != edgeSet_.end()) while (eIt != edgeSet_.end())
{ {
child.push_back((*eIt).second); child.push_back((*eIt).second);
eIt = find_if(++eIt, edgeSet_.end(), pred); eIt = std::find_if(++eIt, edgeSet_.end(), pred);
} }
return child; return child;
@ -479,12 +479,12 @@ std::vector<T> Graph<T>::getParents(const T &value) const
{ {
return (e.second == value); return (e.second == value);
}; };
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred); auto eIt = std::find_if(edgeSet_.begin(), edgeSet_.end(), pred);
while (eIt != edgeSet_.end()) while (eIt != edgeSet_.end())
{ {
parent.push_back((*eIt).first); parent.push_back((*eIt).first);
eIt = find_if(++eIt, edgeSet_.end(), pred); eIt = std::find_if(++eIt, edgeSet_.end(), pred);
} }
return parent; return parent;

View File

@ -155,6 +155,7 @@ public:
virtual std::string getRegisteredName(void); virtual std::string getRegisteredName(void);
// dependencies/products // dependencies/products
virtual std::vector<std::string> getInput(void) = 0; virtual std::vector<std::string> getInput(void) = 0;
virtual std::vector<std::string> getReference(void) = 0;
virtual std::vector<std::string> getOutput(void) = 0; virtual std::vector<std::string> getOutput(void) = 0;
// parse parameters // parse parameters
virtual void parseParameters(XmlReader &reader, const std::string name) = 0; virtual void parseParameters(XmlReader &reader, const std::string name) = 0;

View File

@ -64,6 +64,7 @@ public:
virtual ~TDWF(void) = default; virtual ~TDWF(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
protected: protected:
// setup // setup
@ -92,6 +93,14 @@ std::vector<std::string> TDWF<FImpl>::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> TDWF<FImpl>::getReference(void)
{
std::vector<std::string> ref = {};
return ref;
}
template <typename FImpl> template <typename FImpl>
std::vector<std::string> TDWF<FImpl>::getOutput(void) std::vector<std::string> TDWF<FImpl>::getOutput(void)
{ {

View File

@ -62,6 +62,7 @@ public:
virtual ~TWilson(void) = default; virtual ~TWilson(void) = default;
// dependencies/products // dependencies/products
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
protected: protected:
// setup // setup
@ -90,6 +91,14 @@ std::vector<std::string> TWilson<FImpl>::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> TWilson<FImpl>::getReference(void)
{
std::vector<std::string> ref = {};
return ref;
}
template <typename FImpl> template <typename FImpl>
std::vector<std::string> TWilson<FImpl>::getOutput(void) std::vector<std::string> TWilson<FImpl>::getOutput(void)
{ {

View File

@ -95,6 +95,7 @@ public:
virtual ~TMeson(void) = default; virtual ~TMeson(void) = default;
// dependencies/products // dependencies/products
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
virtual void parseGammaString(std::vector<GammaPair> &gammaList); virtual void parseGammaString(std::vector<GammaPair> &gammaList);
protected: protected:
@ -122,6 +123,14 @@ std::vector<std::string> TMeson<FImpl1, FImpl2>::getInput(void)
return input; return input;
} }
template <typename FImpl1, typename FImpl2>
std::vector<std::string> TMeson<FImpl1, FImpl2>::getReference(void)
{
std::vector<std::string> ref = {};
return ref;
}
template <typename FImpl1, typename FImpl2> template <typename FImpl1, typename FImpl2>
std::vector<std::string> TMeson<FImpl1, FImpl2>::getOutput(void) std::vector<std::string> TMeson<FImpl1, FImpl2>::getOutput(void)
{ {

View File

@ -84,6 +84,7 @@ public:
virtual ~TGaugeProp(void) = default; virtual ~TGaugeProp(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
protected: protected:
// setup // setup
@ -115,6 +116,14 @@ std::vector<std::string> TGaugeProp<FImpl>::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> TGaugeProp<FImpl>::getReference(void)
{
std::vector<std::string> ref = {};
return ref;
}
template <typename FImpl> template <typename FImpl>
std::vector<std::string> TGaugeProp<FImpl>::getOutput(void) std::vector<std::string> TGaugeProp<FImpl>::getOutput(void)
{ {

View File

@ -47,6 +47,13 @@ std::vector<std::string> TUnit::getInput(void)
return std::vector<std::string>(); return std::vector<std::string>();
} }
std::vector<std::string> TUnit::getReference(void)
{
std::vector<std::string> ref = {};
return ref;
}
std::vector<std::string> TUnit::getOutput(void) std::vector<std::string> TUnit::getOutput(void)
{ {
std::vector<std::string> out = {getName()}; std::vector<std::string> out = {getName()};

View File

@ -50,6 +50,7 @@ public:
virtual ~TUnit(void) = default; virtual ~TUnit(void) = default;
// dependencies/products // dependencies/products
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
protected: protected:
// setup // setup

View File

@ -60,6 +60,7 @@ public:
virtual ~TPoint(void) = default; virtual ~TPoint(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
protected: protected:
// setup // setup
@ -93,6 +94,14 @@ std::vector<std::string> TPoint<FImpl>::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> TPoint<FImpl>::getReference(void)
{
std::vector<std::string> ref = {};
return ref;
}
template <typename FImpl> template <typename FImpl>
std::vector<std::string> TPoint<FImpl>::getOutput(void) std::vector<std::string> TPoint<FImpl>::getOutput(void)
{ {

View File

@ -61,6 +61,7 @@ public:
virtual ~TRBPrecCG(void) = default; virtual ~TRBPrecCG(void) = default;
// dependencies/products // dependencies/products
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
protected: protected:
// setup // setup
@ -84,11 +85,19 @@ TRBPrecCG<FImpl>::TRBPrecCG(const std::string name)
template <typename FImpl> template <typename FImpl>
std::vector<std::string> TRBPrecCG<FImpl>::getInput(void) std::vector<std::string> TRBPrecCG<FImpl>::getInput(void)
{ {
std::vector<std::string> in = {par().action}; std::vector<std::string> in = {};
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> TRBPrecCG<FImpl>::getReference(void)
{
std::vector<std::string> ref = {par().action};
return ref;
}
template <typename FImpl> template <typename FImpl>
std::vector<std::string> TRBPrecCG<FImpl>::getOutput(void) std::vector<std::string> TRBPrecCG<FImpl>::getOutput(void)
{ {
@ -115,7 +124,6 @@ void TRBPrecCG<FImpl>::setup(void)
schurSolver(mat, source, sol); schurSolver(mat, source, sol);
}; };
envCreate(SolverFn, getName(), Ls, solver); envCreate(SolverFn, getName(), Ls, solver);
env().addOwnership(getName(), par().action);
} }
// execution /////////////////////////////////////////////////////////////////// // execution ///////////////////////////////////////////////////////////////////

View File

@ -71,6 +71,7 @@ public:
virtual ~TPoint(void) = default; virtual ~TPoint(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
protected: protected:
// setup // setup
@ -100,6 +101,14 @@ std::vector<std::string> TPoint<FImpl>::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> TPoint<FImpl>::getReference(void)
{
std::vector<std::string> ref = {};
return ref;
}
template <typename FImpl> template <typename FImpl>
std::vector<std::string> TPoint<FImpl>::getOutput(void) std::vector<std::string> TPoint<FImpl>::getOutput(void)
{ {

View File

@ -19,6 +19,14 @@ std::vector<std::string> T___FILEBASENAME___::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> T___FILEBASENAME___::getReference(void)
{
std::vector<std::string> in = {};
return in;
}
std::vector<std::string> T___FILEBASENAME___::getOutput(void) std::vector<std::string> T___FILEBASENAME___::getOutput(void)
{ {
std::vector<std::string> out = {getName()}; std::vector<std::string> out = {getName()};

View File

@ -26,6 +26,7 @@ public:
virtual ~T___FILEBASENAME___(void) = default; virtual ~T___FILEBASENAME___(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
// setup // setup
virtual void setup(void); virtual void setup(void);

View File

@ -20,6 +20,14 @@ std::vector<std::string> T___FILEBASENAME___::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> T___FILEBASENAME___::getReference(void)
{
std::vector<std::string> in = {};
return in;
}
std::vector<std::string> T___FILEBASENAME___::getOutput(void) std::vector<std::string> T___FILEBASENAME___::getOutput(void)
{ {
std::vector<std::string> out = {getName()}; std::vector<std::string> out = {getName()};

View File

@ -28,6 +28,7 @@ public:
virtual ~T___FILEBASENAME___(void) = default; virtual ~T___FILEBASENAME___(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
// setup // setup
virtual void setup(void); virtual void setup(void);

View File

@ -27,6 +27,7 @@ public:
virtual ~T___FILEBASENAME___(void) = default; virtual ~T___FILEBASENAME___(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
// setup // setup
virtual void setup(void); virtual void setup(void);

View File

@ -29,6 +29,7 @@ public:
virtual ~T___FILEBASENAME___(void) = default; virtual ~T___FILEBASENAME___(void) = default;
// dependency relation // dependency relation
virtual std::vector<std::string> getInput(void); virtual std::vector<std::string> getInput(void);
virtual std::vector<std::string> getReference(void);
virtual std::vector<std::string> getOutput(void); virtual std::vector<std::string> getOutput(void);
// setup // setup
virtual void setup(void); virtual void setup(void);
@ -56,6 +57,14 @@ std::vector<std::string> T___FILEBASENAME___<FImpl>::getInput(void)
return in; return in;
} }
template <typename FImpl>
std::vector<std::string> T___FILEBASENAME___<FImpl>::getReference(void)
{
std::vector<std::string> in = {};
return in;
}
template <typename FImpl> template <typename FImpl>
std::vector<std::string> T___FILEBASENAME___<FImpl>::getOutput(void) std::vector<std::string> T___FILEBASENAME___<FImpl>::getOutput(void)
{ {

View File

@ -82,8 +82,7 @@ void VirtualMachine::pushModule(VirtualMachine::ModPt &pt)
m.data = std::move(pt); m.data = std::move(pt);
m.type = typeIdPt(*m.data.get()); m.type = typeIdPt(*m.data.get());
m.name = name; m.name = name;
auto input = m.data->getInput(); for (auto &in: m.data->getInput())
for (auto &in: input)
{ {
if (!env().hasObject(in)) if (!env().hasObject(in))
{ {
@ -91,11 +90,18 @@ void VirtualMachine::pushModule(VirtualMachine::ModPt &pt)
} }
m.input.push_back(env().getObjectAddress(in)); m.input.push_back(env().getObjectAddress(in));
} }
auto output = m.data->getOutput(); for (auto &ref: m.data->getReference())
{
if (!env().hasObject(ref))
{
env().addObject(ref , -1);
}
m.input.push_back(env().getObjectAddress(ref));
}
module_.push_back(std::move(m)); module_.push_back(std::move(m));
address = static_cast<unsigned int>(module_.size() - 1); address = static_cast<unsigned int>(module_.size() - 1);
moduleAddress_[name] = address; moduleAddress_[name] = address;
for (auto &out: output) for (auto &out: getModule(address)->getOutput())
{ {
if (!env().hasObject(out)) if (!env().hasObject(out))
{ {
@ -114,6 +120,25 @@ void VirtualMachine::pushModule(VirtualMachine::ModPt &pt)
+ module_[env().getObjectModule(out)].name + module_[env().getObjectModule(out)].name
+ "' (while pushing module '" + name + "')"); + "' (while pushing module '" + name + "')");
} }
if (getModule(address)->getReference().size() > 0)
{
auto pred = [this, out](const ModuleInfo &n)
{
auto &in = n.input;
auto it = std::find(in.begin(), in.end(), env().getObjectAddress(out));
return (it != in.end());
};
auto it = std::find_if(module_.begin(), module_.end(), pred);
while (it != module_.end())
{
for (auto &ref: getModule(address)->getReference())
{
it->input.push_back(env().getObjectAddress(ref));
}
it = std::find_if(++it, module_.end(), pred);
}
}
} }
} }
} }
@ -225,12 +250,17 @@ Graph<unsigned int> VirtualMachine::makeModuleGraph(void) const
{ {
Graph<unsigned int> moduleGraph; Graph<unsigned int> moduleGraph;
for (unsigned int i = 0; i < module_.size(); ++i) // create vertices
for (unsigned int m = 0; m < module_.size(); ++m)
{ {
moduleGraph.addVertex(i); moduleGraph.addVertex(m);
for (auto &j: module_[i].input) }
// create edges
for (unsigned int m = 0; m < module_.size(); ++m)
{
for (auto &in: module_[m].input)
{ {
moduleGraph.addEdge(env().getObjectModule(j), i); moduleGraph.addEdge(env().getObjectModule(in), m);
} }
} }
@ -258,7 +288,6 @@ VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
{ {
Size memPeak = 0, sizeBefore, sizeAfter; Size memPeak = 0, sizeBefore, sizeAfter;
std::vector<std::set<unsigned int>> freeProg; std::vector<std::set<unsigned int>> freeProg;
bool continueCollect, nothingFreed;
// build garbage collection schedule // build garbage collection schedule
LOG(Debug) << "Building garbage collection schedule..." << std::endl; LOG(Debug) << "Building garbage collection schedule..." << std::endl;
@ -307,25 +336,10 @@ VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
{ {
LOG(Message) << "Garbage collection..." << std::endl; LOG(Message) << "Garbage collection..." << std::endl;
} }
nothingFreed = true; for (auto &j: freeProg[i])
do
{ {
continueCollect = false; env().freeObject(j);
auto toFree = freeProg[i]; }
for (auto &j: toFree)
{
// continue garbage collection while there are still
// objects without owners
continueCollect = continueCollect or !env().hasOwners(j);
if(env().freeObject(j))
{
// if an object has been freed, remove it from
// the garbage collection schedule
freeProg[i].erase(j);
nothingFreed = false;
}
}
} while (continueCollect);
// free temporaries // free temporaries
for (unsigned int i = 0; i < env().getMaxAddress(); ++i) for (unsigned int i = 0; i < env().getMaxAddress(); ++i)
{ {
@ -335,15 +349,6 @@ VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
env().freeObject(i); env().freeObject(i);
} }
} }
// any remaining objects in step i garbage collection schedule
// is scheduled for step i + 1
if (i + 1 < p.size())
{
for (auto &j: freeProg[i])
{
freeProg[i + 1].insert(j);
}
}
// print used memory after garbage collection if necessary // print used memory after garbage collection if necessary
if (!isDryRun()) if (!isDryRun())
{ {