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

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

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

/*
 *            Copyright 2009-2017 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.
 *
 */


#include <votca/xtp/jobapplication.h>
#include <votca/xtp/jobcalculatorfactory.h>
#include <votca/xtp/version.h>
#include <boost/format.hpp>

namespace votca { namespace xtp {

JobApplication::JobApplication() {
    JobCalculatorfactory::RegisterAll();
}


void JobApplication::Initialize(void) {
    XtpApplication::Initialize();

    JobCalculatorfactory::RegisterAll();

    namespace propt = boost::program_options;

    AddProgramOptions() ("file,f", propt::value<std::string>(),
        "  sqlite state file, *.sql");
    AddProgramOptions() ("first-frame,i", propt::value<int>()->default_value(1),
        "  start from this frame");
    AddProgramOptions() ("nframes,n", propt::value<int>()->default_value(1),
        "  number of frames to process");
    AddProgramOptions() ("nthreads,t", propt::value<int>()->default_value(1),
        "  number of threads to create");
    AddProgramOptions() ("save,s", propt::value<int>()->default_value(1),
        "  whether or not to save changes to state file");
    AddProgramOptions() ("restart,r", propt::value<std::string>()->default_value(""),
        "  restart pattern: 'host(pc1:234) stat(FAILED)'");
    AddProgramOptions() ("cache,c", propt::value<int>()->default_value(8),
        "  assigns jobs in blocks of this size");
    AddProgramOptions() ("jobs,j", propt::value<std::string>()->default_value("run"),
        "  task(s) to perform: input, run, import");
    AddProgramOptions() ("maxjobs,m", propt::value<int>()->default_value(-1),
        "  maximum number of jobs to process (-1 = inf)");
}


bool JobApplication::EvaluateOptions(void) {
    CheckRequired("options", "Please provide an xml file with calculator options");
    CheckRequired("file", "Please provide the state file");
    
    std::string jobstr = _op_vm["jobs"].as<std::string>();
    _generate_input = jobstr.find("write") != std::string::npos;
    _run = jobstr.find("run") != std::string::npos;
    _import = jobstr.find("read") != std::string::npos;
    
    return true;
}


void JobApplication::Run() {
    std::string name = ProgramName();
    if (VersionString() != "") name = name + ", version " + VersionString();
    HelpTextHeader(name);

    load_property_from_xml(_options, _op_vm["options"].as<std::string>());

    // EVALUATE OPTIONS
    int nThreads = OptionsMap()["nthreads"].as<int>();
    int nframes = OptionsMap()["nframes"].as<int>();
    int fframe = OptionsMap()["first-frame"].as<int>();
    if (fframe-- == 0) throw std::runtime_error("ERROR: First frame is 0, counting "
                                           "in VOTCA::XTP starts from 1.");
    int  save = OptionsMap()["save"].as<int>();

    // STATESAVER & PROGRESS OBSERVER
    std::string statefile = OptionsMap()["file"].as<std::string>();
    StateSaverSQLite statsav;
    statsav.Open(_top, statefile);    

    ProgObserver< std::vector<Job*>, Job*, Job::JobResult > progObs
        = ProgObserver< std::vector<Job*>, Job*, Job::JobResult >();
    progObs.InitCmdLineOpts(OptionsMap());
    
    // INITIALIZE & RUN CALCULATORS
    std::cout << "Initializing calculators " << std::endl;
    BeginEvaluate(nThreads, &progObs);

    int frameId = -1;
    int framesDone = 0;
    while (statsav.NextFrame() && framesDone < nframes) {
        frameId += 1;
        if (frameId < fframe) continue;
        std::cout << "Evaluating frame " << _top.getDatabaseId() << std::endl;
        EvaluateFrame();
        if (save == 1) { statsav.WriteFrame(); }
        else { std::cout << "Changes have not been written to state file." << std::endl; }
        framesDone += 1;
    }
    
    if (framesDone == 0)
        std::cout << "Input requires first frame = " << fframe+1 << ", # frames = " 
             << nframes << " => No frames processed.";
    
    statsav.Close();
    EndEvaluate();

}




void JobApplication::AddCalculator(JobCalculator* calculator) {
    _calculators.push_back(calculator);
}


void JobApplication::BeginEvaluate(int nThreads = 1, 
        ProgObserver< std::vector<Job*>, Job*, Job::JobResult > *obs = NULL) {

    for (JobCalculator* calculator:_calculators) {
        std::cout << "... " << calculator->Identify() << " ";
        calculator->setnThreads(nThreads);
        calculator->setProgObserver(obs);
        calculator->Initialize(&_options);  
        std::cout << std::endl;
    }
}

bool JobApplication::EvaluateFrame() {
    for (JobCalculator* calculator:_calculators) {
        std::cout << "... " << calculator->Identify() << " " << std::flush;
        if (_generate_input) calculator->WriteJobFile(&_top);
        if (_run) calculator->EvaluateFrame(&_top);
        if (_import) calculator->ReadJobFile(&_top);
        std::cout << std::endl;
    }
    return true;
}

void JobApplication::EndEvaluate() {
   for (JobCalculator* calculator:_calculators) {
        calculator->EndEvaluate(&_top);
    }
}

}}