Skip to content

update MotionCor2 easyblock to consider to locations for built binary#2541

Merged
akesandgren merged 5 commits intoeasybuilders:developfrom
stefan-wolfsheimer:motioncor2
Sep 30, 2021
Merged

update MotionCor2 easyblock to consider to locations for built binary#2541
akesandgren merged 5 commits intoeasybuilders:developfrom
stefan-wolfsheimer:motioncor2

Conversation

@stefan-wolfsheimer
Copy link
Copy Markdown
Contributor

No description provided.

@stefan-wolfsheimer
Copy link
Copy Markdown
Contributor Author

boegel
boegel previously requested changes Aug 13, 2021
Comment thread easybuild/easyblocks/m/motioncor2.py Outdated
@staticmethod
def extra_options(extra_vars=None):
extra = {
'skip_rpath_check': [False, "Skip rpath check", None],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would clarify the help string a bit here, and maybe also rename to skip_rpath_sanity_check

"Skip RPATH sanity check"

@stefan-wolfsheimer Can you clarify why you need this option, in which context?

Comment thread easybuild/easyblocks/m/motioncor2.py Outdated
else:
raise EasyBuildError(
"Found multiple, or no, matching MotionCor2 binary named %s*" % self.motioncor2_bin
"Found multiple, or no, matching MotionCor2 binary named %s" % pattern
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stefan-wolfsheimer This is clearly wrong, since there is no variable named pattern....
You probably still want to use self.motioncor2_bin like it was before (and leave the * in place too)?

if (LooseVersion(self.version) >= LooseVersion("1.4")):
matches = glob.glob(os.path.join(self.builddir, '%s*' % self.motioncor2_bin))
pattern1 = os.path.join(self.builddir, '%s*' % self.motioncor2_bin)
pattern2 = os.path.join(self.builddir,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this deserves a comment: it seems like you're expecting to find the binary either directly in the build directory, or in a subdirectory named <name>_<version>?

Do you have any idea in which case it's in a subdirectory exactly?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried to build MotionCor2 and the binary is in a subdirectory in the zipball distributed on https://emcore.ucsf.edu/ucsf-software. As far as I can tell this has changed since v1.4.0, for older version the binary was not in a subdirectory.

Copy link
Copy Markdown
Contributor

@akesandgren akesandgren Sep 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.4.2 doesn't have a subdir so this needs more specified version checking. Or does that handle both at once?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hum right... However 1.4.0 does have a subdirectory.
Then I would say @stefan-wolfsheimer was right checking both directly in the build directory and in the subdirectory.

Comment thread easybuild/easyblocks/m/motioncor2.py Outdated
if not os.path.isfile(fp):
raise EasyBuildError("File not installed {}".format(fp))
if not self.cfg.get('skip_rpath_check', False):
super(EB_MotionCor2, self).sanity_check_step(custom_paths)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an easier way to only skip the RPATH sanity check:

def sanity_check_rpath(self, *args, **kwargs):
    """Custom implementation of RPATH sanity check: allow skipping via skip_rpath_sanity_check."""
    if self.cfg.get('skip_rpath_sanity_check', False):
        self.log.info("Skipping RPATH sanity check, as specified via 'skip_rpath_sanity_check'...")
    else:
        super(EB_MotionCor2, self).sanity_check_rpath(*args, **kwargs)

Then you don't have to partially replicate the sanity check for files yourself either...

And maybe we should make skip_rpath_sanity_check a general easyconfig parameter in framework instead?

@boegel boegel added this to the 4.x milestone Aug 13, 2021
if (LooseVersion(self.version) >= LooseVersion("1.4")):
matches = glob.glob(os.path.join(self.builddir, '%s*' % self.motioncor2_bin))
pattern1 = os.path.join(self.builddir, '%s*' % self.motioncor2_bin)
pattern2 = os.path.join(self.builddir,
Copy link
Copy Markdown
Contributor

@akesandgren akesandgren Sep 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.4.2 doesn't have a subdir so this needs more specified version checking. Or does that handle both at once?

Comment thread easybuild/easyblocks/m/motioncor2.py Outdated

if (LooseVersion(self.version) >= LooseVersion("1.4")):
matches = glob.glob(os.path.join(self.builddir, '%s*' % self.motioncor2_bin))
matches = glob.glob(os.path.join(self.builddir, '%s_%s' % (self.name, self.version), '%s*' % self.motioncor2_bin))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now wrong for 1.4.2

Comment thread easybuild/easyblocks/m/motioncor2.py Outdated
else:
raise EasyBuildError(
"Found multiple, or no, matching MotionCor2 binary named %s*" % self.motioncor2_bin
"Found multiple, or no, matching MotionCor2 binary named %s or %s" % (pattern1, patter2)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And once again, please do not change this.

@MaximeMoge
Copy link
Copy Markdown

I hope the latest commit answers all comments :)

  • I added a comment to clarify why we look for the binary both directly in the builddir and in a subdirectory.
  • I reverted the unnecessary change pointed out by akesandgren

super(EB_MotionCor2, self).sanity_check_step(custom_paths)

def sanity_check_rpath(self, *args, **kwargs):
"""Custom implementation of RPATH sanity check: allow skipping via skip_rpath_sanity_check."""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comment on why we need to skip the rpath check

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually looking at this again I think this is a workaround for a broader issue with RPATH for binary installs, and it is not the right approach:

  • we use RPATH on our supercomputer at SURF, and we usually fix the issues with binary install by customizing the easyconfig (or adding hooks) to run patchelf commands to add the missing rpaths in the binary.
  • this is an issue for all binary installs. Ideally, the rpath check in the case of binary install would also automatically fix the missing rpaths using patchelf. However patchelf cannot be used in the easyblock as it is not necessarily available on the system. So we have to do it at the easyconfig level.
  • In the case of the current PR, this custom sanity_check_rpath is in my opinion not the right solution. In fact this is a binary install, and the EB_MotionCor2 class should derive from the PackedBinary class instead of directly from the EasyBlock class. Since PackedBinary skips the rpath check, that would remove the need for a custom sanity_check_rpath.

A real fix for binary installs using RPATH should in my opinion be implemented in the Binary class rather than in software specific easyblocks, so we should not change the sanity_check_rpath at this level.

@akesandgren: my suggestion is to make EB_MotionCor2 derive from PackedBinary instead of EasyBlock, and remove the custom sanity_check_rpath completely. Does that sound good to you?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, I need to check what PackedBinary does. Probably won't have time the coming days/week

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets consider that in a separate PR.

@akesandgren
Copy link
Copy Markdown
Contributor

Test report by @akesandgren

Overview of tested easyconfigs (in order)

  • SUCCESS MotionCor2-1.2.6-GCCcore-8.2.0.eb
  • SUCCESS MotionCor2-1.3.2-GCCcore-8.3.0.eb
  • SUCCESS MotionCor2-1.3.1-GCCcore-8.3.0.eb
  • SUCCESS MotionCor2-1.4.2-GCCcore-10.2.0.eb
  • SUCCESS MotionCor2-1.4.4-GCCcore-10.3.0.eb

Build succeeded for 5 out of 5 (5 easyconfigs in total)
b-an02.hpc2n.umu.se - Linux Ubuntu 20.04, x86_64, Intel(R) Xeon(R) CPU E5-2690 v4 @ 2.60GHz, Python 3.8.10
See https://gist.github.com/ec2f81b499e93a103361b656bbec6fef for a full test report.

@casparvl
Copy link
Copy Markdown
Contributor

casparvl commented Sep 30, 2021

@akesandgren which MotionCor2-1.4.4-GCCcore-10.3.0.eb did you use? Because the one from easybuilders/easybuild-easyconfigs#13716 still has CUDAcore, which should be replaced with CUDA? Or did you just make that change manually in order to be able to test the block?

In fact, I agree with Maxime Moge that it may make more sense to derive from PackedBinary. There is actually a more fundamental question how to deal with an installation if EASYBUILD_RPATH is set in case of binary installs that might also be interesting to @boegel and @ocaisa from an EESSI point of view. Should the necessary libraries be RPATHed in using something like patchelf? Should they not be RPATHed and the RPATH step be skipped? The latter is what PackedBinary does now. Regardless of what we decide, I think we should implement that behaviour in PackedBinary (and friends).

Anyway, having MotionCor2 derive from PackedBinary, we at least get any solution we decide upon later :)

@akesandgren
Copy link
Copy Markdown
Contributor

akesandgren commented Sep 30, 2021

I used my own which is a copy of the old 1.4.2 but with the required changes for use in 10.3.0 toolchain and deps updated accordingly. I.e. one that does not explicitly call unzip -j in the source section.

@akesandgren
Copy link
Copy Markdown
Contributor

@casparvl Yes, using PackedBinary is probably a good idea, but as I said before, lets leave that to a separate PR.

@akesandgren
Copy link
Copy Markdown
Contributor

Going in, thanks @stefan-wolfsheimer!

@akesandgren akesandgren merged commit 0eb903a into easybuilders:develop Sep 30, 2021
@boegel boegel changed the title preparation for MotionCor2 1.4.4 update MotionCor2 easyblock to consider to locations for built binary Oct 13, 2021
Flamefire added a commit to Flamefire/easybuild-easyblocks that referenced this pull request Feb 9, 2023
Partial revert of easybuilders#2541:
Do not modify `cfg['configopts']` but simply read them and pass the
combined result to `run_cmd`.

This fixes an issue with templating while iterating over e.g. multiple Pythons
and also avoids keeping values in configopts over multiple iterations/builds.

Fixes easybuilders#2881
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.

5 participants