mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-03 21:44:33 +00:00 
			
		
		
		
	Hadrons: better organisation of the VM
This commit is contained in:
		@@ -94,8 +94,6 @@ void Application::run(void)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    vm().printContent();
 | 
					    vm().printContent();
 | 
				
			||||||
    env().printContent();
 | 
					    env().printContent();
 | 
				
			||||||
    //vm().checkGraph();
 | 
					 | 
				
			||||||
    vm().memoryProfile();
 | 
					 | 
				
			||||||
    if (!scheduled_)
 | 
					    if (!scheduled_)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        schedule();
 | 
					        schedule();
 | 
				
			||||||
@@ -185,11 +183,11 @@ GeneticScheduler<unsigned int>::ObjFunc memPeak = \
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Application::schedule(void)
 | 
					void Application::schedule(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DEFINE_MEMPEAK;
 | 
					    //DEFINE_MEMPEAK;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // build module dependency graph
 | 
					    // build module dependency graph
 | 
				
			||||||
    LOG(Message) << "Building module graph..." << std::endl;
 | 
					    LOG(Message) << "Building module graph..." << std::endl;
 | 
				
			||||||
    auto graph = vm().makeModuleGraph();
 | 
					    auto graph = vm().getModuleGraph();
 | 
				
			||||||
    LOG(Debug) << "Module graph:" << std::endl;
 | 
					    LOG(Debug) << "Module graph:" << std::endl;
 | 
				
			||||||
    LOG(Debug) << graph << std::endl;
 | 
					    LOG(Debug) << graph << std::endl;
 | 
				
			||||||
    auto con = graph.getConnectedComponents();
 | 
					    auto con = graph.getConnectedComponents();
 | 
				
			||||||
@@ -276,7 +274,7 @@ void Application::saveSchedule(const std::string filename)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Application::loadSchedule(const std::string filename)
 | 
					void Application::loadSchedule(const std::string filename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DEFINE_MEMPEAK;
 | 
					    //DEFINE_MEMPEAK;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    TextReader               reader(filename);
 | 
					    TextReader               reader(filename);
 | 
				
			||||||
    std::vector<std::string> program;
 | 
					    std::vector<std::string> program;
 | 
				
			||||||
@@ -290,7 +288,7 @@ void Application::loadSchedule(const std::string filename)
 | 
				
			|||||||
        program_.push_back(vm().getModuleAddress(name));
 | 
					        program_.push_back(vm().getModuleAddress(name));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    scheduled_ = true;
 | 
					    scheduled_ = true;
 | 
				
			||||||
    memPeak_   = memPeak(program_);
 | 
					    //memPeak_   = memPeak(program_);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Application::printSchedule(void)
 | 
					void Application::printSchedule(void)
 | 
				
			||||||
@@ -323,16 +321,3 @@ void Application::configLoop(void)
 | 
				
			|||||||
    LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
 | 
					    LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
 | 
				
			||||||
    env().freeAll();
 | 
					    env().freeAll();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// memory profile //////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
void Application::memoryProfile(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    auto graph   = vm().makeModuleGraph();
 | 
					 | 
				
			||||||
    auto program = graph.topoSort();
 | 
					 | 
				
			||||||
    bool msg;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    msg = HadronsLogMessage.isActive();
 | 
					 | 
				
			||||||
    HadronsLogMessage.Active(false);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    HadronsLogMessage.Active(msg);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,8 +102,6 @@ private:
 | 
				
			|||||||
    DEFINE_ENV_ALIAS;
 | 
					    DEFINE_ENV_ALIAS;
 | 
				
			||||||
    // virtual machine shortcut
 | 
					    // virtual machine shortcut
 | 
				
			||||||
    DEFINE_VM_ALIAS;
 | 
					    DEFINE_VM_ALIAS;
 | 
				
			||||||
    // memory profile
 | 
					 | 
				
			||||||
    void memoryProfile(void);
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    long unsigned int         locVol_;
 | 
					    long unsigned int         locVol_;
 | 
				
			||||||
    std::string               parameterFileName_{""};
 | 
					    std::string               parameterFileName_{""};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,8 +58,5 @@ std::string ModuleBase::getRegisteredName(void)
 | 
				
			|||||||
void ModuleBase::operator()(void)
 | 
					void ModuleBase::operator()(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    setup();
 | 
					    setup();
 | 
				
			||||||
    if (!vm().isDryRun())
 | 
					    execute();
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        execute();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,27 +36,6 @@ using namespace Hadrons;
 | 
				
			|||||||
/******************************************************************************
 | 
					/******************************************************************************
 | 
				
			||||||
 *                      VirtualMachine implementation                         *
 | 
					 *                      VirtualMachine implementation                         *
 | 
				
			||||||
 ******************************************************************************/
 | 
					 ******************************************************************************/
 | 
				
			||||||
// dry run /////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
void VirtualMachine::dryRun(const bool isDry)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    dryRun_ = isDry;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool VirtualMachine::isDryRun(void) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return dryRun_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void VirtualMachine::memoryProfile(const bool doMemoryProfile)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    memoryProfile_ = doMemoryProfile;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool VirtualMachine::doMemoryProfile(void) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return memoryProfile_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// trajectory counter //////////////////////////////////////////////////////////
 | 
					// trajectory counter //////////////////////////////////////////////////////////
 | 
				
			||||||
void VirtualMachine::setTrajectory(const unsigned int traj)
 | 
					void VirtualMachine::setTrajectory(const unsigned int traj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -259,40 +238,192 @@ bool VirtualMachine::hasModule(const std::string name) const
 | 
				
			|||||||
    return (moduleAddress_.find(name) != moduleAddress_.end());
 | 
					    return (moduleAddress_.find(name) != moduleAddress_.end());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Graph<unsigned int> VirtualMachine::makeModuleGraph(void) const
 | 
					// print VM content ////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					void VirtualMachine::printContent(void) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Graph<unsigned int> moduleGraph;
 | 
					    LOG(Debug) << "Modules: " << std::endl;
 | 
				
			||||||
 | 
					    for (unsigned int i = 0; i < module_.size(); ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOG(Debug) << std::setw(4) << i << ": "
 | 
				
			||||||
 | 
					                   << getModuleName(i) << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// module graph ////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					Graph<unsigned int> VirtualMachine::getModuleGraph(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (graphOutdated_)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        makeModuleGraph();
 | 
				
			||||||
 | 
					        graphOutdated_ = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return graph_;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::makeModuleGraph(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Graph<unsigned int> graph;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // create vertices
 | 
					    // create vertices
 | 
				
			||||||
    for (unsigned int m = 0; m < module_.size(); ++m)
 | 
					    for (unsigned int m = 0; m < module_.size(); ++m)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        moduleGraph.addVertex(m);
 | 
					        graph.addVertex(m);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // create edges
 | 
					    // create edges
 | 
				
			||||||
    for (unsigned int m = 0; m < module_.size(); ++m)
 | 
					    for (unsigned int m = 0; m < module_.size(); ++m)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for (auto &in: module_[m].input)
 | 
					        for (auto &in: module_[m].input)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            moduleGraph.addEdge(env().getObjectModule(in), m);
 | 
					            graph.addEdge(env().getObjectModule(in), m);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    graph_ = graph;
 | 
				
			||||||
    return moduleGraph;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// general execution ///////////////////////////////////////////////////////////
 | 
					// memory profile //////////////////////////////////////////////////////////////
 | 
				
			||||||
#define BIG_SEP "==============="
 | 
					const VirtualMachine::MemoryProfile & VirtualMachine::getMemoryProfile(void)
 | 
				
			||||||
#define SEP     "---------------"
 | 
					 | 
				
			||||||
#define MEM_MSG(size) sizeString(size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VirtualMachine::Size
 | 
					 | 
				
			||||||
VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Size                                memPeak = 0, sizeBefore, sizeAfter;
 | 
					    if (memoryProfileOutdated_)
 | 
				
			||||||
    std::vector<std::set<unsigned int>> freeProg;
 | 
					    {
 | 
				
			||||||
 | 
					        makeMemoryProfile();
 | 
				
			||||||
 | 
					        memoryProfileOutdated_ = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return profile_;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::makeMemoryProfile(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool protect = env().objectsProtected();
 | 
				
			||||||
 | 
					    bool hmsg    = HadronsLogMessage.isActive();
 | 
				
			||||||
 | 
					    bool gmsg    = GridLogMessage.isActive();
 | 
				
			||||||
 | 
					    bool err     = HadronsLogError.isActive();
 | 
				
			||||||
 | 
					    auto program = getModuleGraph().topoSort();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resetProfile();
 | 
				
			||||||
 | 
					    profile_.module.resize(getNModule());
 | 
				
			||||||
 | 
					    env().protectObjects(false);
 | 
				
			||||||
 | 
					    GridLogMessage.Active(false);
 | 
				
			||||||
 | 
					    HadronsLogMessage.Active(false);
 | 
				
			||||||
 | 
					    HadronsLogError.Active(false);
 | 
				
			||||||
 | 
					    for (auto it = program.rbegin(); it != program.rend(); ++it) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        auto a = *it;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (profile_.module[a].empty())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LOG(Debug) << "Profiling memory for module '" << module_[a].name
 | 
				
			||||||
 | 
					                       << "' (" << a << ")..." << std::endl;
 | 
				
			||||||
 | 
					            memoryProfile(a);
 | 
				
			||||||
 | 
					            env().freeAll();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    env().protectObjects(protect);
 | 
				
			||||||
 | 
					    GridLogMessage.Active(gmsg);
 | 
				
			||||||
 | 
					    HadronsLogMessage.Active(hmsg);
 | 
				
			||||||
 | 
					    HadronsLogError.Active(err);
 | 
				
			||||||
 | 
					    LOG(Debug) << "Memory profile:" << std::endl;
 | 
				
			||||||
 | 
					    LOG(Debug) << "----------------" << std::endl;
 | 
				
			||||||
 | 
					    for (unsigned int a = 0; a < profile_.module.size(); ++a)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOG(Debug) << getModuleName(a) << " (" << a << ")" << std::endl;
 | 
				
			||||||
 | 
					        for (auto &o: profile_.module[a])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LOG(Debug) << "|__ " << env().getObjectName(o.first) << " ("
 | 
				
			||||||
 | 
					                       << sizeString(o.second) << ")" << std::endl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        LOG(Debug) << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    LOG(Debug) << "----------------" << std::endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::resetProfile(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    profile_.module.clear();
 | 
				
			||||||
 | 
					    profile_.object.clear();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::resizeProfile(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (env().getMaxAddress() > profile_.object.size())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MemoryPrint empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        empty.size   = 0;
 | 
				
			||||||
 | 
					        empty.module = -1;
 | 
				
			||||||
 | 
					        profile_.object.resize(env().getMaxAddress(), empty);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::updateProfile(const unsigned int address)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    resizeProfile();
 | 
				
			||||||
 | 
					    for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (env().hasCreatedObject(a) and (profile_.object[a].module == -1))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            profile_.object[a].size     = env().getObjectSize(a);
 | 
				
			||||||
 | 
					            profile_.object[a].module   = address;
 | 
				
			||||||
 | 
					            profile_.module[address][a] = profile_.object[a].size;
 | 
				
			||||||
 | 
					            if (env().getObjectModule(a) < 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                env().setObjectModule(a, address);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::cleanEnvironment(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    resizeProfile();
 | 
				
			||||||
 | 
					    for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (env().hasCreatedObject(a) and (profile_.object[a].module == -1))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            env().freeObject(a);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::memoryProfile(const unsigned int address)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    auto m = getModule(address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LOG(Debug) << "Setting up module '" << m->getName() 
 | 
				
			||||||
 | 
					               << "' (" << address << ")..." << std::endl;
 | 
				
			||||||
 | 
					    try
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        m->setup();
 | 
				
			||||||
 | 
					        updateProfile(address);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch (Exceptions::Definition &)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cleanEnvironment();
 | 
				
			||||||
 | 
					        for (auto &in: m->getInput())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            memoryProfile(env().getObjectModule(in));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (auto &ref: m->getReference())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            memoryProfile(env().getObjectModule(ref));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        m->setup();
 | 
				
			||||||
 | 
					        updateProfile(address);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::memoryProfile(const std::string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memoryProfile(getModuleAddress(name));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// garbage collector ///////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					VirtualMachine::GarbageSchedule  
 | 
				
			||||||
 | 
					VirtualMachine::makeGarbageSchedule(const std::vector<unsigned int> &p) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GarbageSchedule freeProg;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // build garbage collection schedule
 | 
					 | 
				
			||||||
    LOG(Debug) << "Building garbage collection schedule..." << std::endl;
 | 
					 | 
				
			||||||
    freeProg.resize(p.size());
 | 
					    freeProg.resize(p.size());
 | 
				
			||||||
    for (unsigned int i = 0; i < env().getMaxAddress(); ++i)
 | 
					    for (unsigned int i = 0; i < env().getMaxAddress(); ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -310,34 +441,42 @@ VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return freeProg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// general execution ///////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					#define BIG_SEP "==============="
 | 
				
			||||||
 | 
					#define SEP     "---------------"
 | 
				
			||||||
 | 
					#define MEM_MSG(size) sizeString(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VirtualMachine::executeProgram(const std::vector<unsigned int> &p) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Size            memPeak = 0, sizeBefore, sizeAfter;
 | 
				
			||||||
 | 
					    GarbageSchedule freeProg;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // build garbage collection schedule
 | 
				
			||||||
 | 
					    LOG(Debug) << "Building garbage collection schedule..." << std::endl;
 | 
				
			||||||
 | 
					    freeProg = makeGarbageSchedule(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // program execution
 | 
					    // program execution
 | 
				
			||||||
    LOG(Debug) << "Executing program..." << std::endl;
 | 
					    LOG(Debug) << "Executing program..." << std::endl;
 | 
				
			||||||
    for (unsigned int i = 0; i < p.size(); ++i)
 | 
					    for (unsigned int i = 0; i < p.size(); ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // execute module
 | 
					        // execute module
 | 
				
			||||||
        if (!isDryRun())
 | 
					        LOG(Message) << SEP << " Measurement step " << i + 1 << "/"
 | 
				
			||||||
        {
 | 
					                        << p.size() << " (module '" << module_[p[i]].name
 | 
				
			||||||
            LOG(Message) << SEP << " Measurement step " << i+1 << "/"
 | 
					                        << "') " << SEP << std::endl;
 | 
				
			||||||
                         << p.size() << " (module '" << module_[p[i]].name
 | 
					 | 
				
			||||||
                         << "') " << SEP << std::endl;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        (*module_[p[i]].data)();
 | 
					        (*module_[p[i]].data)();
 | 
				
			||||||
        sizeBefore = env().getTotalSize();
 | 
					        sizeBefore = env().getTotalSize();
 | 
				
			||||||
        // print used memory after execution
 | 
					        // print used memory after execution
 | 
				
			||||||
        if (!isDryRun())
 | 
					        LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
 | 
				
			||||||
        {
 | 
					                     << std::endl;
 | 
				
			||||||
            LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
 | 
					 | 
				
			||||||
                         << std::endl;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (sizeBefore > memPeak)
 | 
					        if (sizeBefore > memPeak)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            memPeak = sizeBefore;
 | 
					            memPeak = sizeBefore;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // garbage collection for step i
 | 
					        // garbage collection for step i
 | 
				
			||||||
        if (!isDryRun())
 | 
					        LOG(Message) << "Garbage collection..." << std::endl;
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            LOG(Message) << "Garbage collection..." << std::endl;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for (auto &j: freeProg[i])
 | 
					        for (auto &j: freeProg[i])
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            env().freeObject(j);
 | 
					            env().freeObject(j);
 | 
				
			||||||
@@ -352,25 +491,20 @@ VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // print used memory after garbage collection if necessary
 | 
					        // print used memory after garbage collection if necessary
 | 
				
			||||||
        if (!isDryRun())
 | 
					        sizeAfter = env().getTotalSize();
 | 
				
			||||||
 | 
					        if (sizeBefore != sizeAfter)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            sizeAfter = env().getTotalSize();
 | 
					            LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
 | 
				
			||||||
            if (sizeBefore != sizeAfter)
 | 
					                            << std::endl;
 | 
				
			||||||
            {
 | 
					        }
 | 
				
			||||||
                LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
 | 
					        else
 | 
				
			||||||
                             << std::endl;
 | 
					        {
 | 
				
			||||||
            }
 | 
					            LOG(Message) << "Nothing to free" << std::endl;
 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                LOG(Message) << "Nothing to free" << std::endl;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    return memPeak;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VirtualMachine::Size VirtualMachine::executeProgram(const std::vector<std::string> &p)
 | 
					void VirtualMachine::executeProgram(const std::vector<std::string> &p) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    std::vector<unsigned int> pAddress;
 | 
					    std::vector<unsigned int> pAddress;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -378,138 +512,5 @@ VirtualMachine::Size VirtualMachine::executeProgram(const std::vector<std::strin
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        pAddress.push_back(getModuleAddress(n));
 | 
					        pAddress.push_back(getModuleAddress(n));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    executeProgram(pAddress);
 | 
				
			||||||
    return executeProgram(pAddress);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// print VM content ////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
void VirtualMachine::printContent(void) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    LOG(Debug) << "Modules: " << std::endl;
 | 
					 | 
				
			||||||
    for (unsigned int i = 0; i < module_.size(); ++i)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        LOG(Debug) << std::setw(4) << i << ": "
 | 
					 | 
				
			||||||
                   << getModuleName(i) << std::endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// memory profile //////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
VirtualMachine::MemoryProfile VirtualMachine::memoryProfile(void) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bool          protect = env().objectsProtected();
 | 
					 | 
				
			||||||
    bool          hmsg    = HadronsLogMessage.isActive();
 | 
					 | 
				
			||||||
    bool          gmsg    = GridLogMessage.isActive();
 | 
					 | 
				
			||||||
    bool          err     = HadronsLogError.isActive();
 | 
					 | 
				
			||||||
    MemoryProfile profile;
 | 
					 | 
				
			||||||
    auto          program = makeModuleGraph().topoSort();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    profile.module.resize(getNModule());
 | 
					 | 
				
			||||||
    env().protectObjects(false);
 | 
					 | 
				
			||||||
    GridLogMessage.Active(false);
 | 
					 | 
				
			||||||
    HadronsLogMessage.Active(false);
 | 
					 | 
				
			||||||
    HadronsLogError.Active(false);
 | 
					 | 
				
			||||||
    for (auto it = program.rbegin(); it != program.rend(); ++it) 
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        auto a = *it;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (profile.module[a].empty())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            LOG(Debug) << "Profiling memory for module '" << module_[a].name
 | 
					 | 
				
			||||||
                       << "' (" << a << ")..." << std::endl;
 | 
					 | 
				
			||||||
            memoryProfile(profile, a);
 | 
					 | 
				
			||||||
            env().freeAll();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    env().protectObjects(protect);
 | 
					 | 
				
			||||||
    GridLogMessage.Active(gmsg);
 | 
					 | 
				
			||||||
    HadronsLogMessage.Active(hmsg);
 | 
					 | 
				
			||||||
    HadronsLogError.Active(err);
 | 
					 | 
				
			||||||
    LOG(Debug) << "Memory profile:" << std::endl;
 | 
					 | 
				
			||||||
    LOG(Debug) << "----------------" << std::endl;
 | 
					 | 
				
			||||||
    for (unsigned int a = 0; a < profile.module.size(); ++a)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        LOG(Debug) << getModuleName(a) << " (" << a << ")" << std::endl;
 | 
					 | 
				
			||||||
        for (auto &o: profile.module[a])
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            LOG(Debug) << "|__ " << env().getObjectName(o.first) << " ("
 | 
					 | 
				
			||||||
                       << sizeString(o.second) << ")" << std::endl;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        LOG(Debug) << std::endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    LOG(Debug) << "----------------" << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return profile;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void VirtualMachine::resizeProfile(MemoryProfile &profile) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env().getMaxAddress() > profile.object.size())
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        MemoryPrint empty;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        empty.size   = 0;
 | 
					 | 
				
			||||||
        empty.module = -1;
 | 
					 | 
				
			||||||
        profile.object.resize(env().getMaxAddress(), empty);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void VirtualMachine::updateProfile(MemoryProfile &profile, 
 | 
					 | 
				
			||||||
                                   const unsigned int address) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    resizeProfile(profile);
 | 
					 | 
				
			||||||
    for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (env().hasCreatedObject(a) and (profile.object[a].module == -1))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            profile.object[a].size     = env().getObjectSize(a);
 | 
					 | 
				
			||||||
            profile.object[a].module   = address;
 | 
					 | 
				
			||||||
            profile.module[address][a] = profile.object[a].size;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void VirtualMachine::cleanEnvironment(MemoryProfile &profile) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    resizeProfile(profile);
 | 
					 | 
				
			||||||
    for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (env().hasCreatedObject(a) and (profile.object[a].module == -1))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            env().freeObject(a);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void VirtualMachine::memoryProfile(MemoryProfile &profile, 
 | 
					 | 
				
			||||||
                                   const unsigned int address) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    auto m = getModule(address);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    LOG(Debug) << "Setting up module '" << m->getName() << "' (" << address << ")..." << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    try
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        m->setup();
 | 
					 | 
				
			||||||
        updateProfile(profile, address);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    catch (Exceptions::Definition &)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        cleanEnvironment(profile);
 | 
					 | 
				
			||||||
        for (auto &in: m->getInput())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            memoryProfile(profile, env().getObjectModule(in));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for (auto &ref: m->getReference())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            memoryProfile(profile, env().getObjectModule(ref));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        m->setup();
 | 
					 | 
				
			||||||
        updateProfile(profile, address);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void VirtualMachine::memoryProfile(MemoryProfile &profile,
 | 
					 | 
				
			||||||
                                   const std::string name) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    memoryProfile(profile, getModuleAddress(name));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,8 +51,9 @@ class VirtualMachine
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    SINGLETON_DEFCTOR(VirtualMachine);
 | 
					    SINGLETON_DEFCTOR(VirtualMachine);
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    typedef SITE_SIZE_TYPE                             Size;
 | 
					    typedef SITE_SIZE_TYPE                       Size;
 | 
				
			||||||
    typedef std::unique_ptr<ModuleBase>                ModPt;
 | 
					    typedef std::unique_ptr<ModuleBase>          ModPt;
 | 
				
			||||||
 | 
					    typedef  std::vector<std::set<unsigned int>> GarbageSchedule;
 | 
				
			||||||
    struct MemoryPrint
 | 
					    struct MemoryPrint
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Size         size;
 | 
					        Size         size;
 | 
				
			||||||
@@ -73,11 +74,6 @@ private:
 | 
				
			|||||||
        size_t                    maxAllocated;
 | 
					        size_t                    maxAllocated;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    // dry run
 | 
					 | 
				
			||||||
    void                dryRun(const bool isDry);
 | 
					 | 
				
			||||||
    bool                isDryRun(void) const;
 | 
					 | 
				
			||||||
    void                memoryProfile(const bool doMemoryProfile);
 | 
					 | 
				
			||||||
    bool                doMemoryProfile(void) const;
 | 
					 | 
				
			||||||
    // trajectory counter
 | 
					    // trajectory counter
 | 
				
			||||||
    void                setTrajectory(const unsigned int traj);
 | 
					    void                setTrajectory(const unsigned int traj);
 | 
				
			||||||
    unsigned int        getTrajectory(void) const;
 | 
					    unsigned int        getTrajectory(void) const;
 | 
				
			||||||
@@ -106,32 +102,47 @@ public:
 | 
				
			|||||||
    std::string         getModuleNamespace(const std::string name) const;
 | 
					    std::string         getModuleNamespace(const std::string name) const;
 | 
				
			||||||
    bool                hasModule(const unsigned int address) const;
 | 
					    bool                hasModule(const unsigned int address) const;
 | 
				
			||||||
    bool                hasModule(const std::string name) const;
 | 
					    bool                hasModule(const std::string name) const;
 | 
				
			||||||
    Graph<unsigned int> makeModuleGraph(void) const;
 | 
					 | 
				
			||||||
    void                checkGraph(void) const;
 | 
					 | 
				
			||||||
    // print VM content
 | 
					    // print VM content
 | 
				
			||||||
    void                printContent(void) const;
 | 
					    void                printContent(void) const;
 | 
				
			||||||
 | 
					    // module graph (could be a const reference if topoSort was const)
 | 
				
			||||||
 | 
					    Graph<unsigned int> getModuleGraph(void);
 | 
				
			||||||
    // memory profile
 | 
					    // memory profile
 | 
				
			||||||
    MemoryProfile       memoryProfile(void) const;
 | 
					    const MemoryProfile &getMemoryProfile(void);
 | 
				
			||||||
 | 
					    // garbage collector
 | 
				
			||||||
 | 
					    GarbageSchedule     makeGarbageSchedule(const std::vector<unsigned int> &p) const;
 | 
				
			||||||
 | 
					    // high-water memory function
 | 
				
			||||||
 | 
					    Size                memoryNeeded(const std::vector<unsigned int> &p,
 | 
				
			||||||
 | 
					                                     const GarbageSchedule &g);
 | 
				
			||||||
 | 
					    Size                memoryNeeded(const std::vector<unsigned int> &p);
 | 
				
			||||||
    // general execution
 | 
					    // general execution
 | 
				
			||||||
    Size                executeProgram(const std::vector<unsigned int> &p);
 | 
					    void                executeProgram(const std::vector<unsigned int> &p) const;
 | 
				
			||||||
    Size                executeProgram(const std::vector<std::string> &p);
 | 
					    void                executeProgram(const std::vector<std::string> &p) const;
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    // environment shortcut
 | 
					    // environment shortcut
 | 
				
			||||||
    DEFINE_ENV_ALIAS;
 | 
					    DEFINE_ENV_ALIAS;
 | 
				
			||||||
 | 
					    // module graph
 | 
				
			||||||
 | 
					    void makeModuleGraph(void);
 | 
				
			||||||
    // memory profile
 | 
					    // memory profile
 | 
				
			||||||
    void resizeProfile(MemoryProfile &profile) const;
 | 
					    void makeMemoryProfile(void);
 | 
				
			||||||
    void updateProfile(MemoryProfile &profile, const unsigned int address) const;
 | 
					    void resetProfile(void);
 | 
				
			||||||
    void cleanEnvironment(MemoryProfile &profile) const;
 | 
					    void resizeProfile(void);
 | 
				
			||||||
    void memoryProfile(MemoryProfile &profile, const std::string name) const;
 | 
					    void updateProfile(const unsigned int address);
 | 
				
			||||||
    void memoryProfile(MemoryProfile &profile, const unsigned int address) const;
 | 
					    void cleanEnvironment(void);
 | 
				
			||||||
 | 
					    void memoryProfile(const std::string name);
 | 
				
			||||||
 | 
					    void memoryProfile(const unsigned int address);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    // general
 | 
					    // general
 | 
				
			||||||
    bool                                dryRun_{false}, memoryProfile_{false};
 | 
					 | 
				
			||||||
    unsigned int                        traj_;
 | 
					    unsigned int                        traj_;
 | 
				
			||||||
    // module and related maps
 | 
					    // module and related maps
 | 
				
			||||||
    std::vector<ModuleInfo>             module_;
 | 
					    std::vector<ModuleInfo>             module_;
 | 
				
			||||||
    std::map<std::string, unsigned int> moduleAddress_;
 | 
					    std::map<std::string, unsigned int> moduleAddress_;
 | 
				
			||||||
    std::string                         currentModule_{""};
 | 
					    std::string                         currentModule_{""};
 | 
				
			||||||
 | 
					    // module graph
 | 
				
			||||||
 | 
					    bool                                graphOutdated_{true};
 | 
				
			||||||
 | 
					    Graph<unsigned int>                 graph_;
 | 
				
			||||||
 | 
					    // memory profile
 | 
				
			||||||
 | 
					    bool                                memoryProfileOutdated_{true};
 | 
				
			||||||
 | 
					    MemoryProfile                       profile_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************
 | 
					/******************************************************************************
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user