Skip to content
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

2021-01 cyrush workarounds and tweaks #46

Merged
merged 18 commits into from
Mar 17, 2021
Merged

Conversation

cyrush
Copy link
Member

@cyrush cyrush commented Jan 23, 2021

This branch includes:

  1. A workaround to get back to point where the host config is generated in the prefix dir (place created host config in --prefix dir #44)
  2. Addition of a -j option to control build jobs (override what is presented in configs for more control)
  3. Addition of a json file option to control (spack spec is hard to read vs previous non verbose output #45)

WIP.
I don't expect us to merge as is. Need a better solution for #44, we should discuss.

Note: I am using this branch to allow me to move forward with updating uberenv for conduit.

uberenv.py Outdated
@@ -814,9 +842,15 @@ def install(self):
print("[install complete!]")
# otherwise we are in the "only dependencies" case and the host-config
# file has to be copied from the do-be-deleted spack-build dir.
# -------
# NOTE: USING DEV BUILD, there is no `spack-build` dir
Copy link
Member

Choose a reason for hiding this comment

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

@cyrush yes there is a spack-build dir, it is created as the source top dir.
The role of dev-build is to use the local version of the sources, that's why it is convenient: the host-config gets generated next to the local version of the source (in src/spack-build).
Then, uberenv moves the host-config file from src/spack-build to src, and removes src/spack-build.
If I understand correctly, that's where is becomes a problem for you: you may have several host-config files there.

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct. Overall, I want to avoid creating or deleting directories anywhere other than the prefix.

If things are limited to the prefix, I can avoid surprises.

Copy link
Member Author

@cyrush cyrush Jan 27, 2021

Choose a reason for hiding this comment

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

I though I checked to see if the spack-build was created for my case, and I didn't see evidence it happened (maybe b/c it was deleted before I could check) but I thought I put in echos to see if ubrerenv saw it. I can double check when I am back working on this.

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed this comment, not sure if its still an issue but it relates to a path I am not testing.

uberenv.py Outdated
if not self.use_install:
install_cmd = "spack/bin/spack "
if self.opts["ignore_ssl_errors"]:
install_cmd += "-k "
if not self.opts["install"]:
install_cmd += "dev-build --quiet -d {0} ".format(self.pkg_src_dir)
if self.uberenv_package_name:
# fake package path
Copy link
Member

@white238 white238 Mar 10, 2021

Choose a reason for hiding this comment

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

This isnt always a fake package. This would also be helpful for installing an actual package that exists. Or am i missing something?

Like if i was in serac and wanted to build axom in their setup.

Though I'm not sure why this is toggling dev-build vs install.

Copy link
Member Author

Choose a reason for hiding this comment

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

if uberenv_package_name exists, it doesn't use the dev build logic. that pretty much it

Copy link
Member Author

Choose a reason for hiding this comment

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

I added self.use_dev_build as a better way of identifying the logic

uberenv.py Outdated
@@ -150,6 +150,11 @@ def parse_args():
dest="package_name",
default=None,
help="override the default package name")
# overrides uberenv_package_name
parser.add_option("--uberenv-package-name",
Copy link
Member

Choose a reason for hiding this comment

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

How is this different from --package-name that already exists?

Copy link
Member Author

Choose a reason for hiding this comment

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

its presence triggers non dev build for the "non install" case (like ancient ubrerenv)

Copy link
Member

Choose a reason for hiding this comment

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

--force-spack-install?

then you would end up with spack --package-name=fakepackage --force-spack-install or just spack --force-spack-install which would end up with default package for the project.

My concern is how is a user supposed to know the difference between:

spack --package-name=foo
spack --uberenv-package-name=foo

without digging into the code.

Copy link
Member Author

@cyrush cyrush Mar 11, 2021

Choose a reason for hiding this comment

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

Better names are certainly welcome.

I think this will be set only in the json file for the most part.

use case is to have uberenv work out of the box to build tpls when the --install option is not passed.

Having the option only be in the json file might be another option?

Copy link
Member

Choose a reason for hiding this comment

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

Engage-Cyrus-Mode? =)

Copy link
Member

Choose a reason for hiding this comment

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

I don't fully understand the use case, but I agree with @white238 that this should either not be exposed to the command line or have a better name.

In either event, I think it needs to be better explained.

Copy link
Member Author

Choose a reason for hiding this comment

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

I am fine with removing this as an option from the command line.

Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

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

@cyrush -- I think I get the general idea, but I am not sure I understand what the exact problem is and how this solves it.

The logic here seems like it can get pretty hairy and difficult to maintain.

Is the problem that you want to control where the host-config gets generated?
If so, would it be simpler to have spack generate the host-config to its build/scratch directory
and allow uberenv to specify where we want to copy this file? (with a reasonable default)?

Or is there a different issue that I'm missing?

uberenv.py Outdated
@@ -150,6 +150,11 @@ def parse_args():
dest="package_name",
default=None,
help="override the default package name")
# overrides uberenv_package_name
parser.add_option("--uberenv-package-name",
Copy link
Member

Choose a reason for hiding this comment

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

I don't fully understand the use case, but I agree with @white238 that this should either not be exposed to the command line or have a better name.

In either event, I think it needs to be better explained.

@@ -170,6 +175,12 @@ def parse_args():
default=pjoin(uberenv_script_dir(),"project.json"),
help="uberenv project settings json file")

# option to explicitly set the number of build jobs
Copy link
Member

Choose a reason for hiding this comment

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

👍

uberenv.py Outdated
try:
setting_value = self.project_opts[setting]
except (KeyError):
print("ERROR: '{0}' must at least be defined in project.json".format(setting))
raise
if optional:
Copy link
Member

Choose a reason for hiding this comment

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

Am I reading this right?

It tries to get the setting from project_opts (which is read in from project.json), and if it is not there (KeyError)
then it throws an error when the setting is optional but returns None when it it not optional?

Should it instead be:

Suggested change
if optional:
if not optional:

Copy link
Member

Choose a reason for hiding this comment

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

Since this behavior is a bit complex, can you please add a docstring to explain what this is supposed to do?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe the issue is about what optional is modifying.
Is it saying that:

  • having it in self.project_opts is optional
  • having it in self.opts is optional
  • having it in both of these is optional

Copy link
Member Author

Choose a reason for hiding this comment

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

my logic was wrong. (note this is still WIP)

I was surprised that many things are required in the json file, even though they may not be applicable. Like:

pacakge_final_phase

We have a check in the logic that applies it:

                if self.pkg_final_phase:
                    install_cmd += "-u {0} ".format(self.pkg_final_phase)

But you can't actually run uberenv unless it is there is a json file entry.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks @cyrush -- I agree that we should have sensible defaults, when applicable, to reduce the necessary entries in the project.json file

uberenv.py Outdated
if self.pkg_final_phase:
install_cmd += "-u {0} ".format(self.pkg_final_phase)
else:
install_cmd += "install "
if self.opts["build_jobs"]:
Copy link
Member

Choose a reason for hiding this comment

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

It's a bit hard to see how this all lines up w/in github, but it seems that these two lines appear in both branches:

    if self.opts["build_jobs"]:
        install_cmd += "-j {0}".format(self.opts["build_jobs"])

It so, and if the order of command line args don't matter, they should be pulled out one level

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch, i'll refactor

@cyrush
Copy link
Member Author

cyrush commented Mar 11, 2021

For context: I took several passes are using the dev build, including trying to inject fine grained control of the generated host config location, but I was not able to get parity with the original "uberenv fake" package approach.

The goal for the fake package is support is to retain the workflow driving the setup of all the TPLs required for development when uberenv is invoked with no args (relying on the project json file) and to also support deployment with install.

uberenv_package_name is the original json entry for uberenv, so I stuck with that.

The "uberenv fake" package helps in the following ways:

  1. Semantics of the fake package are just like any other spack package. Having a successfully installed fake package that we can query is helpful, we can look at things in the .spack dir to solve mysteries. We can actually uninstall the fake package on or way to re-gen the host config, etc.

  2. Following best practices for Spack proper, the default variants don't line up with what we need out of the box for development. With the fake package, we can make different choices (docs on, python on, etc) and support development out of the box. Consistent out of the box is very important -- we do development in ephemeral places (containers and scratch spaces) and have to bootstrap our dev env all the time.

  3. The host config lives with the install in the prefix dir (and in the spack installed fake package dir). It is never written outside of the prefix or the spack stage area. This is really important for both development and deployment. I typically use between 2 and 4 uberenv prefix dirs per project (replicated across several projects). My CMake work flow is basically "use this ubrerenv prefix dir" via using the host config inside. If I delete or move the my uberenv dirs I don't have to hunt down files elsewhere. Self contained greatly simplifies things.

Draw backs of the fake package approach:

  1. Inheritance isn't really inheritance in spack, you can tangle with some meta programming magic or confusing variant tweaking to get a good state.

  2. Some times it downloads things needlessly.

Since I have used the fake package approach for many years, the downsides are a known quantity. As I upgrade I am interested in vcpkg support and future spack env support, but dev build doesn't help me keep my current workflow.

I am not against folks using the dev build approach if that works for their dev workflow, but I would like to be to restore the fake package workflow, given it has been successful since the beginning of uberenv.

@cyrush
Copy link
Member Author

cyrush commented Mar 15, 2021

also resolves:

#47

@cyrush
Copy link
Member Author

cyrush commented Mar 15, 2021

@kennyweiss @white238
the non dev build (legacy) path is now only triggered by theuberenv_package_name json entry, there is no command line arg. Is that sufficiently hidden to move forward?

@white238
Copy link
Member

Is there something else uberenv_package_name does than just force install vs dev-build? If so why not have the option be a boolean that does just that? (will look over PR after I eat my food)

@cyrush
Copy link
Member Author

cyrush commented Mar 15, 2021

it specifies overridden package name uberenv-mypackage

@cyrush
Copy link
Member Author

cyrush commented Mar 16, 2021

refactored input options to provide a build-mode arg and build_mode json entry.

These options allow us to hand a specific build mode string down to the ubrerenv instances.

refactored spack instance logic to route this into self.build_mode with dev-build being the default.

Supported for spack are, dev-build, uberenv-pkg, and install. With this change folks can easily choose between dev build or uberenv pkg, via the json file, overridden by the command line arg.

uberenv.py Outdated
dest="build_mode",
default=None,
help="set mode used to build third party dependencies "
"(spack options: 'dev-build' 'uberenv-pkg')")
Copy link
Member

Choose a reason for hiding this comment

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

@cyrush -- a comment that you posted indicates that install is also an option. Should it be added to this help line as well?

Copy link
Member

Choose a reason for hiding this comment

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

This seems like a much cleaner way to expose this functionality!

Copy link
Member

Choose a reason for hiding this comment

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

Looking through the code, it appears that install will be used if one does not set --build-mode,
so, perhaps the help should indicate that?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's actually more complex than that :-(

The default build_mode should effectively be dev-build

The reason why it's complex has to do with the logic for command line args vs json overrides.

There is no one place for defaults, if you add a default in the command line arg def -- it will always override the json key (which isn't what we want).

Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

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

Thanks @cyrush -- this is a lot cleaner than the previous version.

I think the logic for setting up the type of build is getting too complex and hard to follow, so we should consider if we can refactor that in the future.

It will be really helpful to have some automated CI tests on the uberenv user codes to support that refactor (as @adrienbernede is planning)

uberenv.py Outdated
dest="build_mode",
default=None,
help="set mode used to build third party dependencies "
"(spack options: 'dev-build' 'uberenv-pkg')")
Copy link
Member

Choose a reason for hiding this comment

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

Looking through the code, it appears that install will be used if one does not set --build-mode,
so, perhaps the help should indicate that?

uberenv.py Outdated
raise
if not optional:
print("ERROR: '{0}' must at least be defined in project.json".format(setting))
raise
else:
Copy link
Member Author

Choose a reason for hiding this comment

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

i think this else needs to go

@adrienbernede
Copy link
Member

Thanks @cyrush -- this is a lot cleaner than the previous version.

I think the logic for setting up the type of build is getting too complex and hard to follow, so we should consider if we can refactor that in the future.

It will be really helpful to have some automated CI tests on the uberenv user codes to support that refactor (as @adrienbernede is planning)

There is a CI setup for Uberenv. It triggers a pipeline in both Serac and Conduit to check compatibility with the new Uberenv script. Watch me...

@adrienbernede
Copy link
Member

LGTM

@adrienbernede
Copy link
Member

And it will fail miserably for various reasons :(

@cyrush
Copy link
Member Author

cyrush commented Mar 17, 2021

@adrienbernede is there any good info to pull from the gitlab tests?
I'd like to get this in, but I want to make sure this doesn't break anything in serac.

@adrienbernede
Copy link
Member

The problem in Serac is that I just don't have access to their bank. Although I think they were OK with granting me access.

@adrienbernede
Copy link
Member

I'll see if I can get this to work.

@adrienbernede
Copy link
Member

I can confirm that this does not break Serac CI.

@cyrush
Copy link
Member Author

cyrush commented Mar 17, 2021

thanks @adrienbernede !

uberenv.py Outdated
@@ -151,6 +151,14 @@ def parse_args():
default=None,
help="override the default package name")

# uberenv tpl build mode
parser.add_option("--build-mode",
Copy link
Member

Choose a reason for hiding this comment

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

spack-build-mode?

Copy link
Member Author

Choose a reason for hiding this comment

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

i made this change

uberenv.py Show resolved Hide resolved
spack_dir = self.dest_spack
cmd = pjoin(spack_dir,"bin","spack")
cmd += " python "
cmd += '-c "import sys; print(sys.executable);"'
Copy link
Member

Choose a reason for hiding this comment

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

👍

uberenv.py Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants