support depends_on "load" statements in generated modules via --module-depends-on and module_depends_on easyconfig parameter#2391
Conversation
Also clean up the Lua generator for this a bit and fix the ignores of the unloads.
We need to bump the minimum Lmod with TCL depends-on to 7.6.1. It's then easiest to just not care about 7.6.0, and make 7.6.1 the minimum supported Lmod for depends_on.
47f3fa3 to
acf8cd1
Compare
|
Ah Travis can't download env modules 4.0: we'll try again later then... |
|
@bartoldeman Seems like SourceForge was having trouble for a while, seems to be fixed now, I've re-triggered the tests. |
|
@bartoldeman Please sync with current |
| 'moduleforceunload': [False, 'Force unload of all modules when loading the extension', MODULES], | ||
| 'moduleloadnoconflict': [False, "Don't check for conflicts, unload other versions instead ", MODULES], | ||
| 'recursive_module_unload': [False, 'Recursive unload of all dependencies when unloading module', MODULES], | ||
| 'recursive_module_unload_depends_on' : [False, 'Use depends_on (Lmod 7.6.1+) for dependencies in generated module', MODULES], |
There was a problem hiding this comment.
@bartoldeman Do you think we need this both as configuration option (--recursive-module-unload-depends-on) as well as an easyconfig parameter (recursive_module_unload_depends_on)?
What use case do you see for latter, i.e. selectively enabling the use of depends_on rather than setting it in the global configuration?
There was a problem hiding this comment.
i will check... this simply mirrors recursive_module_unload.
If I check the history it looks like the people in Juelich wanted to only have recursive unloading enabled for toolchain modules, and not for other modules, to avoid loadstorms. I will double check how depends_on behaves for us on toolchain modules (we hide them but obviously easybuild uses them itself).
| None, 'store', None), | ||
| 'recursive-module-unload': ("Enable generating of modules that unload recursively.", | ||
| None, 'store_true', False), | ||
| 'recursive-module-unload-depends-on': ("Use depends_on (Lmod 7.6.1+) for dependencies in all generated modules.", |
There was a problem hiding this comment.
Should this just be use-depends-on, and then have the help message clarify that this implies that it makes unloading of modules recursive?
| lmod_depends_on_min = '7.6.1' | ||
| if self.COMMAND in MODULE_VERSION_CACHE: | ||
| self.version = MODULE_VERSION_CACHE[self.COMMAND] | ||
| self.has_depends_on = (isinstance(self, Lmod) and |
There was a problem hiding this comment.
I'd go with supports_depends_on rather than has_depends_on
supports_depends_on should be set to False in ModulesTool.__init__
and then in Lmod.__init__ it should be set based on the Lmod version after the super call (don't use isinstance(self, Lmod))
|
|
||
| MODULE_VERSION_CACHE[self.COMMAND] = self.version | ||
| self.has_depends_on = (isinstance(self, Lmod) and | ||
| StrictVersion(self.version) >= StrictVersion(lmod_depends_on_min)) |
There was a problem hiding this comment.
You're setting this twice (but it should be moved to the Lmod class anyway)
| # include load statements for retained dependencies | ||
| recursive_unload = self.cfg['recursive_module_unload'] | ||
| if self.cfg['recursive_module_unload_depends_on']: | ||
| recursive_unload = 'depends_on' |
There was a problem hiding this comment.
rather than introducing a magic value for the recursive_unload named argument of load_module, why not add a new named argument use_depends_on?
There was a problem hiding this comment.
Also, you should take the build_option into account here (rather than in load_module)?
| load_template = self.LOAD_TEMPLATE | ||
| # Lmod 7.6.1+ supports depends-on which does this most nicely: | ||
| if (build_option('recursive_mod_unload_depends_on') or | ||
| recursive_unload == 'depends_on') and modules_tool().has_depends_on: |
There was a problem hiding this comment.
if depends_on is requested but not supported (supports_depends_on is False), then we should get an error rather than silently ignoring that request?
There was a problem hiding this comment.
Taking into account the above, this should become something like:
load_template = self.LOAD_TEMPLATE
if use_depends_on:
if modules_tool().supports_depends_on:
load_template = self.LOAD_TEMPLATE_DEPENDS_ON
else:
raise EasyBuildError("depends_on statements in generated module are not supported by modules tool")| self.assertFalse(is_loaded_regex.search(toy_module_txt), "Recursive unloading is used: %s" % toy_module_txt) | ||
| lastargs = ['--recursive-module-unload'] | ||
| if self.modtool.has_depends_on: | ||
| lastargs.append(lastargs[0]+'-depends-on') |
There was a problem hiding this comment.
We should not stop testing --recursive-module-unload with recent Lmod versions?
There was a problem hiding this comment.
With this change it tests both, but I renamed the option now.
|
I addressed all comments I believe, except for the easyconfig parameter. I'll double-check depends_on behaviour in toolchain modules before I remove that (see my comment in the review). |
|
One could argue that since #2316 the depends_on() seems to work ok. I get funny module lists if I load foss after iomkl but that could be fixed by using e.g. |
| 'moduleclass': ['base', 'Module class to be used for this software', MODULES], | ||
| 'moduleforceunload': [False, 'Force unload of all modules when loading the extension', MODULES], | ||
| 'moduleloadnoconflict': [False, "Don't check for conflicts, unload other versions instead ", MODULES], | ||
| 'module_use_depends_on' : [False, 'Use depends_on (Lmod 7.6.1+) for dependencies in generated module ' |
There was a problem hiding this comment.
@bartoldeman I would avoid module_use, since that has a particular meaning (not at all related to depends_on).
How about module_depends_on or use_depends_on?
| 'check_osdeps': not cmdline_options.ignore_osdeps, | ||
| 'dry_run': cmdline_options.dry_run or cmdline_options.dry_run_short, | ||
| 'recursive_mod_unload': cmdline_options.recursive_module_unload, | ||
| 'mod_use_depends_on': cmdline_options.module_use_depends_on, |
There was a problem hiding this comment.
same here, avoid mod(ule)_use, since it has a very particular meaning
| body.append(load_template) | ||
|
|
||
| if (build_option('recursive_mod_unload') or recursive_unload or | ||
| load_template == self.LOAD_TEMPLATE_DEPENDS_ON): |
There was a problem hiding this comment.
no need to wrap this across two lines? looks confusing imho...
| else: | ||
| load_guard = 'isloaded("%(mod_name)s")' | ||
| load_statement = [self.conditional_statement(load_guard, '\n'.join(body), negative=True)] | ||
| if build_option('recursive_mod_unload') or recursive_unload: |
There was a problem hiding this comment.
No, it really needs to be else: because of the common load_statement = statement at the bottom.
There was a problem hiding this comment.
OK, I overlooked that indeed, thanks or clarifying
| 'module-naming-scheme': ("Module naming scheme to use", None, 'store', DEFAULT_MNS), | ||
| 'module-syntax': ("Syntax to be used for module files", 'choice', 'store', DEFAULT_MODULE_SYNTAX, | ||
| sorted(avail_module_generators().keys())), | ||
| 'module-use-depends-on': ("Use depends_on (Lmod 7.6.1+) for dependencies in all generated modules " |
There was a problem hiding this comment.
same here, I'd go with either --module-depends-on or --use-depends-on
| ]) | ||
| self.assertEqual(expected, self.modgen.load_module("mod_name", use_depends_on=True)) | ||
| init_config(build_options={'mod_use_depends_on': 'True'}) | ||
| self.assertEqual(expected, self.modgen.load_module("mod_name")) |
There was a problem hiding this comment.
also check the other case, with self.assertErrorRegex?
|
lgtm, thanks for the effort @bartoldeman! |
edit: see http://lmod.readthedocs.io/en/latest/098_dependent_modules.html