@@ -286,10 +286,20 @@ class ParallelArrayContext(object):
286286 ... # rank = session.rank
287287 ... # The local context object knows where it fits in the global array.
288288 ... rank = context.rank
289- ... output_path = os.path.join(context.workdir_list[rank], 'traj.trr')
290- ... assert(os.path.exists(output_path))
291- ... print('Worker {} produced {}'.format(rank, output_path))
289+ ... output = work[0]['traj.trr']
292290 ...
291+ >>> output_path = str(output.extract())
292+ >>> assert(os.path.exists(output_path))
293+
294+ When the session is created to run the workflow, a uniquely named directory is created in the filesystem to be the
295+ session's working directory. This directory name is available in the attribute `context.path`. Each
296+ operation on each rank has its own subdirectory. In the example above, the directory for MD artifacts for each of
297+ the two ranks used can be accessed through `work.path[0]` and `work.path[1]`. Artifacts in each path can be accessed
298+ as dictionary keys. E.g. `work.path[0]['traj.trr']`.
299+
300+ Note that these attributes are proxy objects that may not exist at the time they are referenced with this syntax.
301+ To force the artifacts to be made available locally, use the `extract` method. The string representation of the
302+ returned object is a valid local absolute filename.
293303
294304 Implementation notes:
295305
@@ -479,7 +489,17 @@ def add_operation(self, namespace, operation, get_builder):
479489 def __load_tpr (self , element ):
480490 """Implement the gromacs.load_tpr operation.
481491
482- Updates the minimum width of the workflow parallelism. Does not add any API object to the graph.
492+ File paths are taken to be relative to the session directory. Helper functions implemented for the Context
493+ should make sure to copy files into place or to ensure that the files are expected outputs of other operations.
494+ If the element has other elements listed in `depends` then the working directories of those elements are used
495+ to replace occurrences of the element names in the tpr filename arguments, using a forward slash (`/`) to separate
496+ the part of the string naming an element and the part of the string naming a relative file path.
497+
498+ Absolute filenames are not allowed, as they imply relation to an element named with a null string, which we
499+ would not want to respect even if it existed.
500+
501+ Updates the minimum width of the workflow parallelism. This operation is fused with the MD operation and does
502+ not add any API object to the graph.
483503 """
484504 class Builder (object ):
485505 def __init__ (self , tpr_list ):
@@ -578,17 +598,15 @@ def done():
578598 def __enter__ (self ):
579599 """Implement Python context manager protocol, producing a Session for the specified work in this Context.
580600
601+ A session directory is created (if not yet present) with a unique key for the work specification. This prevents
602+ different work specifications from getting mixed in the same output directory. Each element in the work has its
603+ own subdirectory or subdirectories (one per worker) to hold artifacts and checkpoint information. The
604+
581605 Returns:
582606 Session object the can be run and/or inspected.
583607
584608 Additional API operations are possible while the Session is active. When used as a Python context manager,
585609 the Context will close the Session at the end of the `with` block by calling `__exit__`.
586-
587- Note: this is probably where we will have to process the work specification to determine whether we
588- have appropriate resources (such as sufficiently wide parallelism). Until we have a better Session
589- abstraction, this means the clean approach should take two passes to first build a DAG and then
590- instantiate objects to perform the work. In the first implementation, we kind of muddle things into
591- a single pass.
592610 """
593611 import numpy
594612 try :
0 commit comments