ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
scheduler.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * ALPS MPS DMRG Project
4  *
5  * Copyright (C) 2013 Institute for Theoretical Physics, ETH Zurich
6  * 2013-2013 by Michele Dolfi <dolfim@phys.ethz.ch>
7  *
8  * This software is part of the ALPS Applications, published under the ALPS
9  * Application License; you can use, redistribute it and/or modify it under
10  * the terms of the license, either version 1 or (at your option) any later
11  * version.
12  *
13  * You should have received a copy of the ALPS Application License along with
14  * the ALPS Applications; see the file LICENSE.txt. If not, the license is also
15  * available from http://alps.comp-phys.org/.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  *
25  *****************************************************************************/
26 
27 #include "libpscan/scheduler.hpp"
28 #include "libpscan/run_sim.hpp"
29 
31 
32 #include <alps/parser/parser.h>
33 #include <alps/parser/xslt_path.h>
34 #include <alps/parser/xmlstream.h>
35 
36 #include <boost/filesystem/fstream.hpp>
37 #include <iostream>
38 
40 : stop_callback(opt.time_limit)
41 {
42  outfilepath = opt.jobfilename;
43  infilepath = opt.jobfilename;
44 
45  infilepath = boost::filesystem::absolute(infilepath);
46  outfilepath = boost::filesystem::absolute(outfilepath);
47 
48  if (!opt.jobfilename.empty())
49  parse_job_file(infilepath);
50 }
51 
52 void Scheduler::parse_job_file(const boost::filesystem::path& filename)
53 {
54  boost::filesystem::ifstream infile(filename);
55  alps::XMLTag tag = alps::parse_tag(infile, true);
56  if (tag.name != "JOB")
57  boost::throw_exception(std::runtime_error("missing <JOB> element in jobfile"));
58  tag = alps::parse_tag(infile);
59  if (tag.name == "OUTPUT") {
60  if(tag.attributes["file"] != "")
61  outfilepath = boost::filesystem::absolute(boost::filesystem::path(tag.attributes["file"]), filename.parent_path());
62  else
63  boost::throw_exception(std::runtime_error("missing 'file' attribute in <OUTPUT> element in jobfile"));
64  tag = alps::parse_tag(infile);
65  if (tag.name == "/OUTPUT")
66  tag = alps::parse_tag(infile);
67  }
68 
69  while (tag.name == "TASK") {
70  TaskDescriptor task;
71  if (tag.attributes["status"] == "" || tag.attributes["status"] == "new")
72  task.status = TaskNotStarted;
73  else if (tag.attributes["status"] == "running")
74  task.status = TaskHalted;
75  else if (tag.attributes["status"] == "finished")
76  task.status = TaskFinished;
77  else
78  boost::throw_exception(std::runtime_error("illegal status attribute in <TASK> element in jobfile"));
79 
80  tag = alps::parse_tag(infile);
81  if (tag.name == "INPUT") {
82  task.in = boost::filesystem::path(tag.attributes["file"]);
83  if (task.in.empty())
84  boost::throw_exception(std::runtime_error("missing 'file' attribute in <INPUT> element in jobfile"));
85  tag = alps::parse_tag(infile);
86  if (tag.name == "/INPUT")
87  tag = alps::parse_tag(infile);
88  }
89  else
90  boost::throw_exception(std::runtime_error("missing <INPUT> element in jobfile"));
91 
92  if (tag.name == "OUTPUT") {
93  task.out = boost::filesystem::path(tag.attributes["file"]);
94  if (task.out.empty())
95  boost::throw_exception(std::runtime_error("missing 'file' attribute in <OUTPUT> element in jobfile"));
96  tag = alps::parse_tag(infile);
97  if (tag.name == "/OUTPUT")
98  tag = alps::parse_tag(infile);
99  }
100  if (task.out.empty())
101  task.out = task.in;
102  task.in = boost::filesystem::absolute(task.in, filename.parent_path());
103  task.out = boost::filesystem::absolute(task.out, filename.parent_path());
104  if (tag.name != "/TASK")
105  boost::throw_exception(std::runtime_error("missing </TASK> tag in jobfile"));
106  tag = alps::parse_tag(infile);
107  tasks.push_back(task);
108  }
109  if (tag.name != "/JOB")
110  boost::throw_exception(std::runtime_error("missing </JOB> tag in jobfile"));
111 }
112 
113 
114 void Scheduler::checkpoint_status() const
115 {
116  bool make_backup = boost::filesystem::exists(outfilepath);
117  boost::filesystem::path filename = outfilepath;
118  boost::filesystem::path dir = outfilepath.parent_path();
119  if (make_backup)
120  filename = dir / (filename.filename().string() + ".bak");
121  { // scope for out
122  alps::oxstream out(filename);
123 
124  out << alps::header("UTF-8") << alps::stylesheet(alps::xslt_path("ALPS.xsl"));
125  out << alps::start_tag("JOB")
126  << alps::xml_namespace("xsi","http://www.w3.org/2001/XMLSchema-instance")
127  << alps::attribute("xsi:noNamespaceSchemaLocation",
128  "http://xml.comp-phys.org/2003/8/job.xsd");
129 
130  for (unsigned int i=0; i<tasks.size(); i++) {
131  std::string status;
132  if (tasks[i].status == TaskFinished)
133  status = "finished";
134  else if (tasks[i].status == TaskNotStarted)
135  status = "new";
136  else // TaskRunning or TaskHalted
137  status = "running";
138 
139  if (tasks[i].status == TaskNotStarted && !boost::filesystem::exists(tasks[i].out))
140  copy(tasks[i].in, tasks[i].out);
141 
142  out << alps::start_tag("TASK") << alps::attribute("status", status)
143  << alps::start_tag("INPUT")
144  << alps::attribute("file", tasks[i].out.string())
145  << alps::end_tag() << alps::end_tag();
146  }
147  out << alps::end_tag("JOB");
148  }
149  if (make_backup) {
150  boost::filesystem::remove(outfilepath);
151  boost::filesystem::rename(filename, outfilepath);
152  }
153 }
154 
155 
157 {
158  // do all Tasks
159  try {
160  for(unsigned int i=0; i<tasks.size(); i++) {
161  boost::chrono::high_resolution_clock::time_point t0 = boost::chrono::high_resolution_clock::now();
162  double time_left = stop_callback.time_left().count();
163  if (stop_callback.valid() && time_left < 0)
164  throw dmrg::time_limit();
165 
166  if (tasks[i].status == TaskFinished)
167  std::cout << "Task " << i+1 << " finished." << std::endl;
168  else if (tasks[i].status == TaskNotStarted || tasks[i].status == TaskRunning ||
169  tasks[i].status == TaskHalted) {
170 
171  tasks[i].status = TaskRunning;
172  std::cout << "Running task " << i+1 << "." << std::endl;
173  if (!boost::filesystem::exists(tasks[i].out))
174  copy(tasks[i].in, tasks[i].out);
175 
176  /// Start task
177  run_sim(tasks[i].in, tasks[i].out, time_left);
178  tasks[i].status = TaskFinished;
179  }
180  else
181  boost::throw_exception( std::logic_error("illegal Task status"));
182 
183  boost::chrono::high_resolution_clock::time_point t1 = boost::chrono::high_resolution_clock::now();
184  std::cout << "This task took " << boost::chrono::duration<double>(t1-t0) << "." << std::endl;
185  checkpoint_status();
186  }
187  std::cout << "Finished with everything." << std::endl;
188  } catch (dmrg::time_limit const& e) {
189  std::cout << "Time limit exceeded." << std::endl;
190  checkpoint_status();
191  }
192 }
boost::chrono::duration< double > time_left() const
TaskStatusFlag status
Definition: scheduler.hpp:39
boost::filesystem::path jobfilename
Definition: options.hpp:48
boost::filesystem::path in
Definition: scheduler.hpp:40
boost::filesystem::path out
Definition: scheduler.hpp:41
Scheduler(const Options &)
Definition: scheduler.cpp:39
void run()
Definition: scheduler.cpp:156
parameter scans scheduler
bool valid() const
run one parameter set
void run_sim(const boost::filesystem::path &infile, const boost::filesystem::path &outfile, bool write_xml=false, double time_limit=-1.)
Definition: run_measure.cpp:36