Codebase list votca-xtp / b08fa64d-b91e-48a0-b185-c4ba9579a74a/main src / libxtp / job.cc
b08fa64d-b91e-48a0-b185-c4ba9579a74a/main

Tree @b08fa64d-b91e-48a0-b185-c4ba9579a74a/main (Download .tar.gz)

job.cc @b08fa64d-b91e-48a0-b185-c4ba9579a74a/mainraw · history · blame

/*
 *            Copyright 2009-2019 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 <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <votca/tools/propertyiomanipulator.h>
#include <votca/xtp/job.h>

namespace votca {
namespace xtp {
using boost::format;
Job::Job(const tools::Property &prop) {

  // DEFINED BY USER
  _id = prop.get("id").as<Index>();
  _tag = prop.get("tag").as<std::string>();
  _input = prop.get("input");
  if (prop.exists("status")) {
    _status = ConvertStatus(prop.get("status").as<std::string>());
  } else {
    _status = AVAILABLE;
  }

  // GENERATED DURING RUNTIME
  if (prop.exists("host")) {
    _host = prop.get("host").as<std::string>();
    _has_host = true;
  }
  if (prop.exists("time")) {
    _time = prop.get("time").as<std::string>();
    _has_time = true;
  }
  if (prop.exists("output")) {
    _output = prop.get("output");
    _has_output = true;
  }
  if (prop.exists("error")) {
    _error = prop.get("error").as<std::string>();
    _has_error = true;
  }
}

Job::Job(Index id, const std::string &tag, const tools::Property &input,
         JobStatus status) {

  _id = id;
  _tag = tag;
  _input = input.get("input");
  _status = status;
}

std::string Job::ConvertStatus(JobStatus status) const {

  std::string converted;
  switch (status) {
    case AVAILABLE:
      converted = "AVAILABLE";
      break;
    case ASSIGNED:
      converted = "ASSIGNED";
      break;
    case FAILED:
      converted = "FAILED";
      break;
    case COMPLETE:
      converted = "COMPLETE";
      break;
    default:
      throw std::runtime_error("Incomprehensible status (enum)");
  }
  return converted;
}

Job::JobStatus Job::ConvertStatus(std::string status) const {
  JobStatus converted;
  if (status == "AVAILABLE") {
    converted = AVAILABLE;
  } else if (status == "ASSIGNED") {
    converted = ASSIGNED;
  } else if (status == "FAILED") {
    converted = FAILED;
  } else if (status == "COMPLETE") {
    converted = COMPLETE;
  } else {
    throw std::runtime_error("Incomprehensible status: " + status);
  }
  return converted;
}

void Job::Reset() {
  _output = tools::Property();
  _has_output = false;
  _error = "";
  _has_error = false;
  return;
}

void Job::ToStream(std::ofstream &ofs) const {

  tools::PropertyIOManipulator iomXML(tools::PropertyIOManipulator::XML, 0,
                                      "\t\t");
  std::string tab = "\t";
  ofs << tab << "<job>\n";
  ofs << tab << tab << (format("<id>%1$d</id>\n") % _id).str();
  ofs << tab << tab << (format("<tag>%1$s</tag>\n") % _tag).str();
  ofs << iomXML << _input;
  ofs << tab << tab
      << (format("<status>%1$s</status>\n") % ConvertStatus(_status)).str();

  if (_has_host) {
    ofs << tab << tab << (format("<host>%1$s</host>\n") % _host).str();
  }
  if (_has_time) {
    ofs << tab << tab << (format("<time>%1$s</time>\n") % _time).str();
  }
  if (_has_output) {
    ofs << iomXML << _output;
  }
  if (_has_error) {
    ofs << tab << tab << (format("<error>%1$s</error>\n") % _error).str();
  }
  ofs << tab << "</job>\n";
  return;
}

void Job::UpdateFrom(const Job &ext) {
  _status = ext.getStatus();
  if (ext.hasHost()) {
    _has_host = true;
    _host = ext.getHost();
  }
  if (ext.hasTime()) {
    _has_time = true;
    _time = ext.getTime();
  }
  if (ext.hasOutput()) {
    _has_output = true;
    _output = ext.getOutput();
  }
  if (ext.hasError()) {
    _has_error = true;
    _error = ext.getError();
  }
  return;
}

void Job::UpdateFromResult(const JobResult &res) {
  _status = res.getStatus();
  if (res.hasOutput()) {
    _output = res.getOutput();
    _has_output = true;
  }
  if (res.hasError()) {
    _error = res.getError();
    _has_error = true;
  }
  _attemptsCount++;
  return;
}

std::vector<Job> LOAD_JOBS(const std::string &job_file) {

  tools::Property xml;
  xml.LoadFromXML(job_file);

  std::vector<tools::Property *> jobProps = xml.Select("jobs.job");
  std::vector<Job> jobs;
  jobs.reserve(jobProps.size());
  for (tools::Property *prop : jobProps) {
    jobs.push_back(Job(*prop));
  }

  return jobs;
}

void WRITE_JOBS(const std::vector<Job> &jobs, const std::string &job_file) {
  std::ofstream ofs;
  ofs.open(job_file, std::ofstream::out);
  if (!ofs.is_open()) {
    throw std::runtime_error("Bad file handle: " + job_file);
  }
  ofs << "<jobs>" << std::endl;
  for (auto &job : jobs) {
    job.ToStream(ofs);
  }
  ofs << "</jobs>" << std::endl;

  ofs.close();
  return;
}

void UPDATE_JOBS(const std::vector<Job> &from, std::vector<Job> &to,
                 const std::string &thisHost) {
  std::vector<Job>::iterator it_int;
  std::vector<Job>::const_iterator it_ext;

  if (to.size() != from.size()) {
    throw std::runtime_error("Progress file out of sync (::size), abort.");
  }

  for (it_int = to.begin(), it_ext = from.begin(); it_int != to.end();
       ++it_int, ++it_ext) {
    Job &job_int = *it_int;
    const Job &job_ext = *it_ext;
    if (job_int.getId() != job_ext.getId()) {
      throw std::runtime_error("Progress file out of sync (::id), abort.");
    }
    if (job_ext.hasHost() && job_ext.getHost() != thisHost) {
      job_int.UpdateFrom(job_ext);
    }
  }

  return;
}

}  // namespace xtp
}  // namespace votca