OpenMPCD
Run.py
1 from .Configuration import Configuration
2 
3 import enum
4 import yaml
5 
6 class Run:
7  """
8  Represents a run of OpenMPCD, and its results.
9  """
10 
11  class RunState(enum.Enum):
12  """
13  Enumerates the state of a run.
14 
15  Possible states:
16  * `Ready`, if the run is ready for execution or job
17  submission,
18  * `Submitted`, if the run has been submitted to the job
19  scheduler,
20  * `Running`, if the run is currently being executed,
21  * `Completed`, if the run has finished executing.
22  """
23 
24  Ready = 1
25  Submitted = 2
26  Running = 3
27  Completed = 4
28 
29  def __str__(self):
30  return self.name
31 
32 
33 
34  def __init__(self, rundir, pathTranslatorsServerToLocal = []):
35  """
36  The constructor.
37 
38  @param[in] rundir
39  The directory the run is saved in.
40  @param[in] pathTranslatorsServerToLocal
41  A list of functions that translate server paths to local
42  ones.
43  """
44 
45  self.rundir = rundir
46 
47  self.pathTranslatorsServerToLocal = pathTranslatorsServerToLocal
48 
49  self.config = None
50 
51 
52  def getPath(self):
53  """
54  Returns the rundir path.
55  """
56 
57  return self.rundir
58 
59 
60  def getIdentifier(self):
61  """
62  Returns a string that can be used to identify this particular run.
63 
64  @throw Exception Throws if `self.getState() != self.RunState.Completed`.
65  """
66 
67  if self.getState() != self.RunState.Completed:
68  raise Exception("Run not yet completed")
69 
70  configHash = self._getSHA256ByFilePath(self.rundir + "/config.txt")
71  revision = open(self.rundir + "/git-revision").read()
72  metadataHash = self._getSHA256ByFilePath(self.rundir + "/metadata.txt")
73  seed = open(self.rundir + "/rngSeed.txt").read()
74 
75  assert revision.count("\n") == 0
76  assert seed.count("\n") == 0
77 
78  return configHash + ":" + revision + ":" + metadataHash + ":" + seed
79 
80 
81  def getState(self):
82  """
83  Returns the run state as an instance of `RunState`.
84  """
85 
86  import glob
87  import os.path
88 
89  if not os.path.isfile(self.rundir + "/config.txt"):
90  raise Exception("No configuration file found")
91 
92  if os.path.isfile(self.rundir + "/metadata.txt"):
93  return self.RunState.Completed
94 
95  if glob.glob(self.rundir + "/input/srun-*.out"):
96  return self.RunState.Running
97 
98  if self.hasParentRun():
99  return self._getParentRun().getState()
100 
101  if os.path.exists(self.rundir + "/input/jobid"):
102  return self.RunState.Submitted
103 
104  if os.path.isfile(self.rundir + "/input/job.slrm"):
105  return self.RunState.Ready
106 
107  raise Exception(self.rundir + " does not seem to be a rundir")
108 
109 
110  def hasParentRun(self):
111  """
112  Returns whether this run has been executed by a job script in another
113  run.
114  """
115 
116  import os.path
117 
118  return os.path.isfile(self.rundir + "/input/parent-job-path.txt")
119 
120 
121  def getJobBatchSize(self):
122  """
123  Returns the number of runs that run in parallel on this job.
124  """
125 
126  topRun = self._getParentRun()
127 
128  ret = 0
129  with open(topRun.getPath() + "/input/job.slrm", "r") as jobfile:
130  for line in jobfile:
131  if line.startswith("srun"):
132  ret += 1
133 
134  assert ret > 0
135 
136  return ret
137 
138 
139  def getConfiguration(self):
140  """
141  Returns the configuration instance for this run.
142  """
143 
144  if self.config is None:
145  self.config = Configuration(self.rundir + "/config.txt")
146 
147  return self.config
148 
149 
150  def getNumberOfCompletedSweeps(self):
151  """
152  Returns the number of sweeps that have been performed after the warmup
153  phase, as configured in `mpc.warmupSteps`, or `0` if the run has not
154  yet completed.
155  """
156 
157  import os.path
158 
159  metadataPath = self.rundir + "/metadata.txt"
160 
161  if not os.path.isfile(metadataPath):
162  return 0
163 
164  config = yaml.safe_load(open(metadataPath, "r"))
165  return config["numberOfCompletedSweeps"]
166 
167 
168  def _getSHA256ByFilePath(self, path):
169  """
170  Returns the SHA256 hash of the file at `path`, as a string of
171  hexadecimal digits (with lowercase letters).
172  """
173 
174  import hashlib
175 
176  return hashlib.sha256(open(path, "r").read()).hexdigest()
177 
178 
179  def _applyPathTranslatorsServerToLocal(self, s):
180  """
181  Applies all path translators in `self.pathTranslatorsServerToLocal` on
182  the given string, and returns the result.
183  """
184 
185  ret = s
186  for translator in self.pathTranslatorsServerToLocal:
187  ret = translator(ret)
188 
189  return ret
190 
191 
192  def _getParentRun(self):
193  """
194  For runs that are part of a job that runs multiple executions in
195  parallel, return the run that contains the job script; otherwise, return
196  this run.
197  """
198 
199  if self.hasParentRun():
200  with open(self.rundir + "/input/parent-job-path.txt", "r") as f:
201  rundir = self._applyPathTranslatorsServerToLocal(f.read())
202  parentRun = Run(rundir)
203  return parentRun
204 
205  return self
206 
207 
MPCDAnalysis.Run.Run.getPath
def getPath(self)
Definition: Run.py:59
MPCDAnalysis.Run.Run.getJobBatchSize
def getJobBatchSize(self)
Definition: Run.py:132
MPCDAnalysis.Run.Run._applyPathTranslatorsServerToLocal
def _applyPathTranslatorsServerToLocal(self, s)
Definition: Run.py:195
MPCDAnalysis.Run.Run.getConfiguration
def getConfiguration(self)
Definition: Run.py:151
MPCDAnalysis.Run.Run.rundir
rundir
Definition: Run.py:48
MPCDAnalysis.Run.Run.__init__
def __init__(self, rundir, pathTranslatorsServerToLocal=[])
Definition: Run.py:46
MPCDAnalysis.Run.Run.getIdentifier
def getIdentifier(self)
Definition: Run.py:70
MPCDAnalysis.Run.Run._getSHA256ByFilePath
def _getSHA256ByFilePath(self, path)
Definition: Run.py:183
MPCDAnalysis.Run.Run
Definition: Run.py:10
MPCDAnalysis.Run.Run.RunState
Definition: Run.py:24
MPCDAnalysis.Run.Run.hasParentRun
def hasParentRun(self)
Definition: Run.py:121
MPCDAnalysis.Configuration.Configuration
Definition: Configuration.py:7
MPCDAnalysis.Run.Run.getState
def getState(self)
Definition: Run.py:90
MPCDAnalysis.Run.Run.config
config
Definition: Run.py:52
MPCDAnalysis.Run.Run.getNumberOfCompletedSweeps
def getNumberOfCompletedSweeps(self)
Definition: Run.py:165
MPCDAnalysis.Run.Run.pathTranslatorsServerToLocal
pathTranslatorsServerToLocal
Definition: Run.py:50
MPCDAnalysis.Run.Run._getParentRun
def _getParentRun(self)
Definition: Run.py:210