Codebase list votca-xtp / debian/1.5-1 src / libxtp / parallelxjobcalc.cc
debian/1.5-1

Tree @debian/1.5-1 (Download .tar.gz)

parallelxjobcalc.cc @debian/1.5-1raw · history · blame

/*
 *            Copyright 2009-2018 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *              http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/// For an earlier history see ctp repo commit 77795ea591b29e664153f9404c8655ba28dc14e9

#include <votca/xtp/parallelxjobcalc.h>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>

using boost::format;

namespace votca { namespace xtp {

    
template<typename JobContainer, typename pJob, typename rJob> 
bool ParallelXJobCalc<JobContainer,pJob,rJob>::EvaluateFrame(Topology *top) {    
   
    // RIGIDIFY TOPOLOGY (=> LOCAL FRAMES)
    if (!top->isRigid()) {
        bool isRigid = top->Rigidify();
        if (!isRigid) { return 0; }
    }
    else std::cout << std::endl << "... ... System is already rigidified." << std::flush;
    
    // CONVERT THREADS INTO SUBTHREADS IF BENEFICIAL
    if (_XJobs.size() < _nThreads && false) {
        _subthreads = (_nThreads - _XJobs.size()) / _XJobs.size() + 1;
        _nThreads   = _XJobs.size();

        std::cout << std::endl << "... ... "
             << "Converted threads into subthreads to increase efficiency: "
             << "NT = " << _nThreads << ", NST = " << _subthreads
             << std::flush;
    }

    // INITIALIZE PROGRESS OBSERVER
    std::string progFile = _jobfile;
    assert(_jobfile != "__NOFILE__");    
    JobOperator* master = new JobOperator(-1, top, this);    
    master->getLogger()->setReportLevel(logDEBUG);
    master->getLogger()->setMultithreading(true);
    master->getLogger()->setPreface(logINFO,    "\nMST INF");
    master->getLogger()->setPreface(logERROR,   "\nMST ERR");
    master->getLogger()->setPreface(logWARNING, "\nMST WAR");
    master->getLogger()->setPreface(logDEBUG,   "\nMST DBG");    
    _progObs->InitFromProgFile(progFile, master);

    // PRE-PROCESS (OVERWRITTEN IN CHILD OBJECT)
    this->PreProcess(top);
    
    // CREATE + EXECUTE THREADS (XJOB HANDLERS)
    std::vector<JobOperator*> jobOps;

    for (unsigned int id = 0; id < _nThreads; id++) {
        JobOperator *newOp = new JobOperator(id, top, this);
        jobOps.push_back(newOp);
    }
    
    for (unsigned int id = 0; id < _nThreads; ++id) {
        CustomizeLogger(jobOps[id]);
    }

    for (unsigned int id = 0; id < _nThreads; id++) {
        jobOps[id]->InitData(top);
    }

    if (!_maverick) std::cout << std::endl; // REQUIRED FOR PROGRESS BAR IN OBSERVER
    
    for (unsigned int id = 0; id < _nThreads; id++) {
        jobOps[id]->Start();
    }

    for (unsigned int id = 0; id < _nThreads; id++) {
        jobOps[id]->WaitDone();
    }
    
    if (!_maverick)
    for (unsigned int id = 0; id < _nThreads; id++) {
        std::cout << std::endl << *(jobOps[id]->getLogger()) << std::flush;
    }

    for (unsigned int id = 0; id < _nThreads; id++) {
        delete jobOps[id];
    }    

    jobOps.clear();

	// SYNC REMAINING COMPLETE JOBS
	_progObs->SyncWithProgFile(master);
    
    // POST-PROCESS (OVERWRITTEN IN CHILD OBJECT)
    this->PostProcess(top);
    
    return true;
}


template<typename JobContainer, typename pJob, typename rJob>
void ParallelXJobCalc<JobContainer,pJob,rJob>::JobOperator::Run(void) {

    while (true) {
        _job = _master->_progObs->RequestNextJob(this);

        if (_job == NULL) { break; }
        else { 
            rJob res = this->_master->EvalJob(_top, _job, this);
            this->_master->_progObs->ReportJobDone(_job, &res, this);
        }
    }
}

template<typename JobContainer, typename pJob, typename rJob>
void ParallelXJobCalc<JobContainer,pJob,rJob>::CustomizeLogger(QMThread *thread) {
    
    // CONFIGURE LOGGER
    Logger* log = thread->getLogger();
    log->setReportLevel(logDEBUG);
    log->setMultithreading(_maverick);

    log->setPreface(logINFO,    (format("\nT%1$02d INF ...") % thread->getId()).str());
    log->setPreface(logERROR,   (format("\nT%1$02d ERR ...") % thread->getId()).str());
    log->setPreface(logWARNING, (format("\nT%1$02d WAR ...") % thread->getId()).str());
    log->setPreface(logDEBUG,   (format("\nT%1$02d DBG ...") % thread->getId()).str());        
}

// REGISTER PARALLEL CALCULATORS
template class ParallelXJobCalc< std::vector<Job*>, Job*, Job::JobResult >;

}}