-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parsing compiler name & version from Spack environment to include in the performance log file #262
Changes from 7 commits
3d72c50
323ae11
b4f3658
8ba7561
b79f781
7b5e51e
7a02712
f696cd5
dd066c1
51c5713
49f2286
4850d38
aed6bc2
5ac953f
878aa5e
493c7bf
3559fec
57767c7
c17b12e
7c871e5
9fbc4f1
cbcaeeb
2e46df8
1177f71
1272d8c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -10,8 +10,8 @@ | |||
from reframe.core.exceptions import BuildSystemError | ||||
from reframe.core.logging import getlogger | ||||
from reframe.utility.osext import run_command | ||||
|
||||
|
||||
import reframe.utility.osext as osext | ||||
import reframe.utility.sanity as sn | ||||
SYSFILE = 'systems/sysinfo.json' # interpreted relative to jupyter root | ||||
|
||||
def get_jupyter_root(): | ||||
|
@@ -243,6 +243,10 @@ def identify_build_environment(current_partition): | |||
class SpackTest(rfm.RegressionTest): | ||||
build_system = 'Spack' | ||||
spack_spec = variable(str, value='', loggable=True) | ||||
spack_variants = variable(str, value='', loggable=True) | ||||
compiler_version = variable(str, value='', loggable=True) | ||||
compiler_name = variable(str, value='', loggable=True) | ||||
spack_mpi = variable(str, value='', loggable=True) | ||||
|
||||
@run_before('compile') | ||||
def setup_spack_environment(self): | ||||
|
@@ -267,11 +271,38 @@ def setup_spack_environment(self): | |||
f'(cd {cp_dir}; find . \( -name "spack.yaml" -o -name "compilers.yaml" -o -name "packages.yaml" \) -print0 | xargs -0 tar cf - | tar -C {dest} -xvf -)', | ||||
f'spack -e {self.build_system.environment} config add "config:install_tree:root:{env_dir}/opt"', | ||||
] | ||||
|
||||
# else f"{d[key].value}" if isinstance(d[key].value, bool) for boolean with "True" instead of True | ||||
cmd_spack_variants = 'from spack import environment; d = environment.active_environment().spec_lists["specs"].specs[0].variants.dict; keys = list(d.keys());values = {key: ([d[key].value[i] for i in range(len(d[key].value))] if isinstance(d[key].value, tuple) else d[key].value) for key in keys};print(values)' | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In all these commands, you extract only the first package from the spec with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
it is a bit confusing. When you execute the following command :
The If you try something like :
They won't work, so afaik ReFrame allows multiple runs with tag but with only a single spack_spec to be specified for each run, that's why I am using specs[0]. If it is possible to run multiple spack_specs at the same time then it would be great to learn and change the PR accordingly since it would be handy for our tests too 🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's not multiple specs, but multiple packages inside the one spec, see eg.
Do I get this right @giordano? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Almost, they are two distinct top-level specs in one environment. But the point is that, as I had already explained in the second point of the caveats section of #251 (comment), you can't assume there's exactly 1 top-level spec in the environment, which is what you're doing when you do
ilectra marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
cmd_spec_mpi = 'from spack import environment;print(environment.active_environment().spec_lists["specs"].specs[0]["mpi"]) if "mpi" in environment.active_environment().spec_lists["specs"].specs[0] else "" ' | ||||
cmd_compiler_name = 'from spack import environment; print(environment.active_environment().spec_lists["specs"].specs[0].compiler.name)' | ||||
# Although we could provide several versions of compiler, reframe only executes with the first version | ||||
cmd_compiler_version = 'from spack import environment;environment.active_environment().spec_lists["specs"].specs[0].compiler.versions[0]' | ||||
self.postrun_cmds.append(f'echo "compiler_name: $(spack -e {self.build_system.environment} python -c \'{cmd_compiler_name}\')"') | ||||
self.postrun_cmds.append(f'echo "compiler_version: $(spack -e {self.build_system.environment} python -c \'{cmd_compiler_version}\')"') | ||||
self.postrun_cmds.append(f'echo "spack_spec_variants: $(spack -e {self.build_system.environment} python -c \'{cmd_spack_variants}\')"') | ||||
self.postrun_cmds.append(f'echo "MPI: $(spack -e {self.build_system.environment} python -c \'{cmd_spec_mpi}\')"') | ||||
|
||||
# Keep the `spack.lock` file in the output directory so that the Spack | ||||
# environment can be faithfully reproduced later. | ||||
self.keep_files.append(os.path.realpath(os.path.join(self.build_system.environment, 'spack.lock'))) | ||||
|
||||
@run_after('run') | ||||
def get_compiler_name(self): | ||||
with osext.change_dir(self.stagedir): | ||||
self.compiler_name = sn.extractsingle(r'compiler_name: \s*(\S+)', self.stdout, 1).evaluate() | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to do this as a two step process? (write out the information to stdout before compilation and then read it from stdout after running) Is there a way to do it in one go, at the right time for ReFrame? |
||||
@run_after('run') | ||||
def get_compiler_version(self): | ||||
with osext.change_dir(self.stagedir): | ||||
self.compiler_version = sn.extractsingle(r'compiler_version: \s*(.*)', self.stdout, 1).evaluate() | ||||
@run_after('run') | ||||
def get_full_variants(self): | ||||
with osext.change_dir(self.stagedir): | ||||
self.spack_variants = sn.extractsingle(r'spack_spec_variants: \s*(.*)', self.stdout, 1).evaluate() | ||||
@run_after('run') | ||||
def get_spec_mpi(self): | ||||
with osext.change_dir(self.stagedir): | ||||
self.spack_mpi = sn.extractsingle(r'MPI: \s*(.*)', self.stdout, 1).evaluate() | ||||
|
||||
@run_before('compile') | ||||
def setup_build_system(self): | ||||
# The `self.spack_spec` attribute is the user-facing and loggable | ||||
|
@@ -301,6 +332,7 @@ def setup_build_job_num_cpus(self): | |||
self.build_job.num_cpus_per_task = min(16, self.current_partition.processor.num_cpus) | ||||
|
||||
|
||||
|
||||
if __name__ == '__main__': | ||||
|
||||
#v = get_sysinfo(sys.argv[-1]) | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -759,6 +759,10 @@ def spack_root_to_path(): | |
'%(check_environ)s|' | ||
'%(check_extra_resources)s|' | ||
'%(check_env_vars)s|' | ||
'%(check_compiler_name)s|' | ||
'%(check_compiler_version)s|' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't you also want the variant fished out of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, seems like not needed anymore since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then maybe we should export the whole variant? And users of each app can choose to use it and unpack it or not. |
||
'%(check_spack_variants)s|' | ||
'%(check_spack_mpi)s|' | ||
'%(check_tags)s' | ||
), | ||
'format_perfvars': ( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the whole variant string broken down into keys automatically or as one string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually.... If this contains the compiler name and version as well, do we still need the separate variables and commands to fish them out? Can we let the post-processing unpack it into separate columns instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it would be better to keep variants and compiler information separate since compiler name and version is always available but some applications won't even have a variant at all maybe and spack_spec as a string is available in the columns as a whole anyway.