Skip to content

Conversation

@vkarak
Copy link
Contributor

@vkarak vkarak commented Oct 8, 2019

This PR introduces two major enhancements.

Lazy evaluation of the job-related attributes

The job associated with the test is only minimally created inside setup(). Any attributes related to its run configuration (e.g., num_tasks, num_tasks_per_node etc.) are set when preparing the job script and just before launching the test. This change required that these attributes become writeable in Job's interface.

This enhancement allows you to set the num_tasks of a test based on the current partition or the environment in a cleaner way anytime after setup. For example:

@rfm.run_before('run')
def set_num_tasks(self):
    if self.current_partition.fullname == 'foo:part':
        self.num_tasks = 8
    else:
        self.num_tasks = 4

In case of flexible tests, the test's num_tasks attribute is set to the actual number of tasks assigned to it, after the test has been launched. This eliminates the need of defining a separate sanity function to retrieve the number of tasks:

# old way, but still valid

def __init__(self):
    self.sanity_patterns = sn.assert_eq(sn.count(sth), self.num_tasks_assigned)

@sn.sanity_function
@property 
def num_tasks_assigned(self):
    return self.job.num_tasks    # or now simply self.num_tasks

# new way

@rfm.run_before('sanity')
def set_sanity(self):
    self.sanity_patterns = sn.assert_eq(sn.count(sth), self.num_tasks)

Re-evaluate the test's environment whenever needed

The mechanism of loading environments has changed completely. Environment objects are now really immutable: they are just placeholders for modules and environment variables. They don't carry any state. Responsible for loading environments is the load(*environs) free function. This function returns a tuple consisting of an environment snapshot just before loading environs and the commands needed to load the environments. There is no explicit mechanism for unloading an environment as in the past. Instead, an environment or a set of environments are implicitly unloaded by restoring the environment snapshot returned by the load() function.

There is also the emit_load_commands(*environs) function, which essentially loads environs, restores the original environment and returns the required load commands. In the past this was accomplished by the _setup_environ() method of RegressionTest and the internal state of the Environment. Now, every time emit_load_commands(*environs) is called, all the environments will be loaded and the command sequence will be recorded. In addition to that, we construct a new user environment (from self.modules and self.variables) before the build and run phase of the pipeline. This allows a user to define different compilation and running environments. An example follows:

@rfm.run_before('run')
def set_num_threads(self):
    self.variables = {'OMP_NUM_THREADS': '16'}

This will define OMP_NUM_THREADS only inside the generated job script and not in the build phase.

Due to this feature, this PR fixes #58.

Vasileios Karakasis added 2 commits October 5, 2019 22:43
- This allows to set them from their `RegressionTest` counterparts just before
  the run phase, allowing as a result user tests to set these variables late
  enough.
- `RegressionTest`'s `num_tasks` are now set again from the job in case of
  flexible tests.
- `Environment` class is now really immutable and does not carry any logic about
  loading the environment.
- Environments are loaded by a free function that takes care of the actual load
  details and the necessary shell instructions needed to load the environment.
- Unloading an environment is not explicitly supported. It is supported though
  through environment snapshots. The `load()` function returns a snapshot of the
  environment before loading the current one. The users can restore this
  snapshot to effectively unload the environment.
- Framework was adapted to use the new environment API.
- An important change is also that the test's user environment (i.e., modules
  and variables) are re-read every time that they are needed (i.e., at the build
  time and at the run time). This now allows to have different environments for
  compilation and running.
@vkarak vkarak added this to the Upcoming sprint milestone Oct 8, 2019
@vkarak vkarak requested review from teojgo and victorusu October 8, 2019 19:57
@vkarak vkarak self-assigned this Oct 8, 2019
- Use custom equality function for environment functions that ignores the order
  of the variables.
- Provide some fixes to `SequenceView` and `MappingView`
- Provide an `__str__` and `__repr__` to `SequenceView` and `MappingView`
@victorusu
Copy link
Contributor

@jenkins-cscs retest this please

@victorusu
Copy link
Contributor

victorusu commented Oct 10, 2019

@jenkins-cscs retry all

@codecov-io
Copy link

Codecov Report

Merging #961 into master will increase coverage by 0.18%.
The diff coverage is 85.98%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #961      +/-   ##
==========================================
+ Coverage   91.67%   91.86%   +0.18%     
==========================================
  Files          80       80              
  Lines       10575    10481      -94     
==========================================
- Hits         9695     9628      -67     
+ Misses        880      853      -27
Impacted Files Coverage Δ
unittests/test_pipeline.py 96.71% <ø> (-0.01%) ⬇️
unittests/test_modules.py 83.17% <100%> (ø) ⬆️
reframe/core/schedulers/__init__.py 95.58% <100%> (-0.22%) ⬇️
unittests/test_schedulers.py 96.85% <100%> (ø) ⬆️
reframe/core/schedulers/pbs.py 65.88% <100%> (ø) ⬆️
unittests/test_cli.py 93.27% <100%> (ø) ⬆️
reframe/frontend/executors/policies.py 97.04% <100%> (ø) ⬆️
reframe/core/schedulers/local.py 98.87% <100%> (ø) ⬆️
reframe/frontend/cli.py 80.38% <100%> (+0.06%) ⬆️
reframe/frontend/executors/__init__.py 98.23% <100%> (ø) ⬆️
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9832a6b...8d91579. Read the comment docs.

@vkarak vkarak merged commit 169ab2d into reframe-hpc:master Oct 10, 2019
@vkarak vkarak deleted the feat/eval-vars-when-needed branch October 10, 2019 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for different compilation and running environments

4 participants