diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 07f52f93..30a01736 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,13 +21,13 @@ jobs: python-version: [3.8, 3.9, 3.12] spack-version: [0.21.2, develop] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Checkout Spack - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: spack/spack ref: ${{ matrix.spack-verions }} @@ -49,13 +49,13 @@ jobs: matrix: python-version: [3.9] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Checkout Spack - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: spack/spack path: spack @@ -80,13 +80,13 @@ jobs: python-version: [3.8, 3.9] spack-version: [0.21.2, develop] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Checkout Spack - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: spack/spack ref: ${{ matrix.spack-verions }} diff --git a/.gitignore b/.gitignore index 4d6e326d..b87f8be7 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ __pycache__ Configuring .tmp/ *.swp +*.DS_* diff --git a/check.py b/check.py index b0631076..fc41e2a7 100644 --- a/check.py +++ b/check.py @@ -6,16 +6,18 @@ # for more details. """ -a script to make sure minimum requirements for spack-manager +a script to make sure minimum requirements for spack-manager are met. - python@3.8 or higher """ import sys + def check_spack_manager_requirements(): - if sys.version_info < (3,8): + if sys.version_info < (3, 8): raise ValueError("Spack-Manager requires Python 3.8 or higher.") + if __name__ == "__main__": check_spack_manager_requirements() diff --git a/docs/ProfilePyramids.png b/docs/ProfilePyramids.png new file mode 100644 index 00000000..505a5330 Binary files /dev/null and b/docs/ProfilePyramids.png differ diff --git a/docs/Spack-To-Applications.png b/docs/Spack-To-Applications.png new file mode 100644 index 00000000..53ab5fd8 Binary files /dev/null and b/docs/Spack-To-Applications.png differ diff --git a/docs/conf.py b/docs/conf.py index 66d648e4..d561fd4b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,42 +1,37 @@ -extensions = ['myst_parser'] +extensions = ["myst_parser"] myst_heading_anchors = 3 -templates_path = ['_templates'] -master_doc = 'index' -project = u'Spack-Manager' -copyright = u'Phil Sakievich' -author = u'Phil Sakievich' -version = u'0.1' -release = u'0.1' -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] -pygments_style = 'sphinx' +templates_path = ["_templates"] +master_doc = "index" +project = "Spack-Manager" +copyright = "Phil Sakievich" +author = "Phil Sakievich" +version = "0.1" +release = "0.1" +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +pygments_style = "sphinx" todo_include_todos = False numfig = True -numfig_format = {'figure': '%s', 'table': '%s', 'code-block': '%s'} -html_theme = 'sphinx_rtd_theme' +numfig_format = {"figure": "%s", "table": "%s", "code-block": "%s"} +html_theme = "sphinx_rtd_theme" html_static_path = [] -html_theme_options = { - 'navigation_depth': 3 -} +html_theme_options = {"navigation_depth": 5} html_show_sourcelink = True html_show_copyright = False -htmlhelp_basename = 'spack-manager-doc' -latex_elements = { -} +htmlhelp_basename = "spack-manager-doc" +latex_elements = {} latex_documents = [ - (master_doc, 'spack-manager.tex', u'Spack-Manager Documentation', - author, 'manual'), -] -man_pages = [ - (master_doc, 'spack-manager', u'Spack-Manager Documentation', - [author], 1) + (master_doc, "spack-manager.tex", "Spack-Manager Documentation", author, "manual") ] +man_pages = [(master_doc, "spack-manager", "Spack-Manager Documentation", [author], 1)] texinfo_documents = [ - (master_doc, 'spack-manager', u'Spack-Manager Documentation', - author, 'Spack-Manager', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "spack-manager", + "Spack-Manager Documentation", + author, + "Spack-Manager", + "One line description of project.", + "Miscellaneous", + ) ] -source_suffix = { - '.rst': 'restructuredtext', - '.txt': 'markdown', - '.md': 'markdown', -} +source_suffix = {".rst": "restructuredtext", ".txt": "markdown", ".md": "markdown"} diff --git a/docs/general/ApplicationSpace.png b/docs/general/ApplicationSpace.png new file mode 100644 index 00000000..15059d82 Binary files /dev/null and b/docs/general/ApplicationSpace.png differ diff --git a/docs/general/FAQ.md b/docs/general/FAQ.md deleted file mode 100644 index c88bc8cc..00000000 --- a/docs/general/FAQ.md +++ /dev/null @@ -1,139 +0,0 @@ -# Frequently Asked Questions: - -## How do I setup and build custom branches of `amr-wind` and `openfast` together? -A simple script below is the minimum commands you need. -It is highly encouraged that users with this question review [Developers: What you need to know about Spack](https://sandialabs.github.io/spack-manager/user_profiles/developers/developer_spack_minimum.html). -A detailed guide explaining many of the other questions you are likely to encounter can be found in the [Quick-Start: Developer Workflow](https://sandialabs.github.io/spack-manager/user_profiles/developers/developer_workflow.html) -documentation. -```console -quick-create -n build-based-on-FAQ -s amr-wind+openfast -spack manager develop -rb https://github.com/[your fork]/amr-wind [your feature branch name] amr-wind@main -spack manager develop -rb https://github.com/[your fork]/openfast [your feature branch name] openfast@master -spack install -``` - -## What should I do if Spack Keeps failing to clone code for me on Eagle? -Eagle's default version of Git is very old and fails to do many operations. -To fix the cloning issue please make sure you have a more recent version of Git in your path. -Adding the following lines to your `bashrc` will fix the issue. -```bash -source /nopt/nrel/ecom/hpacf/env.sh -module load git -``` - -This is the minimum set of commands we've found to remove the problem. -The suggested modules to load are: -```bash -# HPACF Environment -source /nopt/nrel/ecom/hpacf/env.sh -module load gcc/9.3.0 -module load binutils -module load git -module load python -``` - -## How do I build for GPU's? -If you are using a machine with a profile in Spack-Manager simply add `+cuda` or `+rocm` to your current specs. -If you are on an unsupported machine you will need to add the device architecture as well. -`spack info [spec]` will show you the options for this, and further questions will need to be addressed with your -system administrator. - -## I'm getting lots of weird Spack errors, what should I do? -If you have multiple Spack instances or have recently updated spack things can get a little mangled. -For example if you have used Spack in the past or have more than one instance then both pull configs -from the `~/.spack` directory. -This is a common source of user issues. -Please try the `sm-clean` function (available after `source $SPACK_MANAGER/start.sh`) and see if it solves your issue. -If this doesn't work then raise/create an issue on slack/github and we will help you figure it out. - -## What is Clingo and why is Spack saying it is __bootstrapping__ it? - -[Clingo](https://potassco.org/clingo/) is a powerful answer-set solver that Spack uses to solve your software dependency DAG -during concretization. -Spack first tries to bootstrap the install from pre-built binaries to avoid making you build Clingo -and all of it's dependencies when you use a new instance of Spack. -If you wish to build it yourself, or are having issues with the bootstrap process you can run `spack bootstrap disable`. -There are several options here which you can learn about by running `spack bootstrap --help`. -Further information about bootstrapping can be found in the Spack documentation. - -## What are the ^ in the specs? -^ characters in a spec such as `nalu-wind ^trilinos` are spec delimiters. Using this character allows you to specify the details of dependencies of the root spec. So `nalu-wind ^trilinos build_type=Debug` is saying I want to build `nalu-wind` and I want the build of Trilinos to be a debug build. - -## How do I turn on an optional dependency for my software? -In Spack all optional build features are called varinats. You can see what variants are available for any package (piece of software) by running the `spack info` command. For example to build `amr-wind` with `openfast` you can see what the syntax is by typing: -`spack info amr-wind` and under the variants you will see `openfast`. -So make your spec `amr-wind+openfast` and it will put `openfast` in the DAG and link/build for you. - -## Where is my build directory/where is my install directory? -Spack manages directories by using hashes. This is not convenient for just looking at things and knowing what they are, but it is very efficient for keeping things organized. You can find the location of build/install with `spack location -b [spec]` for a build or `spack location -i [spec]` for the install. Similarly, you can navigate to any directory with `spack cd -b [spec]` or `spack cd -i [spec]`. - -## How do I run tests after building the software? -The first thing to understand is that Spack is going to build your software in a different environment than your active shell. To run a command in this environment you can use `spack build-env [spec] [command]` and the `[command]` will be exectued for you in the build environment (don't forget to [navigate to the build directory](#where-is-my-build-directorywhere-is-my-install-directory) first!). -Spack-Manager also provides a convenience function `build-env-dive [spec]` which will navigate to the build directory for you and launch a sub-shell using the build environment. You will need to type `exit` to get back to your original shell when you are done. The former is recommended for one-off commands, and the latter if you have a lot of commands to run in the environment. - -Please note that -``` -spack build-env nalu-wind ctest -R ablNeutral -``` -and -``` -build-env-dive nalu-wind -ctest -R ablNeutral -exit -``` -are equivalent. - -> **Note**: When running the tests through `ctest`, it is the developer's responsibility to ensure that the gold files, located in `${SPACK_MANAGER}/golds/current`, have been populated. This can typically be done by copying the gold files from `${SPACK_MANAGER}/golds/tmp` (generated from an initial `ctest` run). For example, populating the gold files for Nalu-Wind for Linux entails: -``` -cp -r ${SPACK_MANAGER}/tmp/nalu-wind/Linux ${SPACK_MANAGER}/golds/current/nalu-wind/ -``` - -## Should I worry about _Warning: included configuration files should be updated manually_? -No, this is just a warning from Spack saying it won't automatically update the custom files we've created -for dialing in machine specific data for your environment `include.yaml` or the list of externals we're using -to provide pre-compiled binaries for you to link against `externals.yaml`. - -## Should I worry abour _Warning: the original concretizer is currently being used._? -No, we are using the original concretizer when you use externals from snapshots as a stop gap until -the Spack team fixes a bug for us. - -## How do I use the executables I built in my development environment? -You need to activate the environment `quick-activate`, and then call `spack load [package]`. -This will load the binaries you need into your `$PATH`. -``` -# Example -quick-activate $SPACK_MANAGER/environments/exawind -spack load amr-wind -mpirun -np 20 amr_wind -i [foo] -``` - -## What to do about _Error: Couldn't find patch for package exawind.hdf5_? -Please let us know if you see this. We are trying to make sure you don't see it. -To get rid of the error run `spack clean -m` - -## I'm getting an error saying there is a missing variant? _Error: variant [foo] not found ..._ -Typically this means your Spack submodule is out of date. To check run -``` -cd $SPACK_MANAGER -git status -``` -If you see `spack` in there then you need to re-sync the submodule. `git submodule update` etc - -## Permissions issues on NREL's Eagle machine: __[Errno 13] Permission denied:__ -To build successfully on Eagle, in general you want the following in your `.bashrc` to avoid issues with `tmp` directories: -``` -mkdir -p /scratch/${USER}/.tmp && export TMPDIR=/scratch/${USER}/.tmp -``` - -## How do I compile faster using a parallel DAG? -The `spack install` command gives you parallel builds inside each `make` command. However, further parallelism can be had on large DAGs by invoking concurrent `spack install` commands. Spack will find parallelism within the DAG and build any packages it can simultaneously using file locks. You can do this in bash with the following command: -``` -for i in {1..4}; do nice spack install & done; wait -``` -If you have really large DAGs, it's even possible to use `srun` on multiple nodes for the install process. - -Another newer method for this in Spack is to use depfiles where Spack can generate standard makefiles which can expose the DAG parallelism. More documentation on this can be found [here](https://spack.readthedocs.io/en/latest/environments.html#generating-depfiles-from-environments). In summary, once you have an environment concretized you can generate a makefile and replace the `spack install` with a `make` command as such: -``` -spack -e . env depfile -o Makefile -make -j8 -``` diff --git a/docs/general/Spack-Manager-Org.png b/docs/general/Spack-Manager-Org.png new file mode 100644 index 00000000..85506102 Binary files /dev/null and b/docs/general/Spack-Manager-Org.png differ diff --git a/docs/general/application-workflow.png b/docs/general/application-workflow.png new file mode 100644 index 00000000..23faf2c6 Binary files /dev/null and b/docs/general/application-workflow.png differ diff --git a/docs/general/spack_manager_structure.md b/docs/general/spack_manager_structure.md deleted file mode 100644 index 81c8b5b1..00000000 --- a/docs/general/spack_manager_structure.md +++ /dev/null @@ -1,30 +0,0 @@ -# Spack-Manager Structure - -Spack-Manager is a Spack extension that provides a way for software applications -to configure their usage of spack. -The code of Spack-Manager is independent of each individual application and each -application code needs to configure a Spack-Manager `Project` to tell Spack-Manager how to work -with their application. - -A `Project` at its core is simply a collection of [spack configuration files](https://spack.readthedocs.io/en/latest/configuration.html), -and [spack package repositories](https://spack.readthedocs.io/en/latest/repositories.html). -A few other optional hooks will be discussed below. - -The configuration files in a `Project` are organized based on the configuration bifurcations that the projects supports. -These are called `Machines` based on the guiding principle that spack configurations typically have to be -changed when the machine/system is changed. - -`Projects` can be registered with Spack-Manager by adding them to the `spack-manager.yaml` configuration file. -This file lives in the Spack-Manager directory and controls settings for `Spack-Manager` and the `Projects` that -are registered. - -``` yaml -spack-manager: - projects: - - /path/to/project_a - default_view: False - - $HOME/project_b -``` - -Additional data about this file can be found at *TBD*. -Information on configuring a new `Project` can be found in the system administrator profile documentation (add link). diff --git a/docs/general/spack_manager_structure.rst b/docs/general/spack_manager_structure.rst new file mode 100644 index 00000000..ac0ed1d2 --- /dev/null +++ b/docs/general/spack_manager_structure.rst @@ -0,0 +1,49 @@ +Spack-Manager Structure +======================= + +Spack-Manager is a Spack extension that provides a way for software applications +to configure their usage of spack. + +.. figure:: ./application-workflow.png + :width: 100% + + An example of generalized infrastructure requirements that are common across HPC and scientific computing applications. Spack-Manager's goal is to empower these types of infrastructures while still allowing application teams to drive the details. + +The code of Spack-Manager is independent of each individual application and each +application code needs to configure a Spack-Manager `Project` to tell Spack-Manager how to work +with their application. + +.. figure:: ./Spack-Manager-Org.png + :width: 50% + + Spack-Manager is designed to provide an abstraction that can support multiple application teams. Each team develops a Project that can be registered with an instance of Spack-Manager. + +A `Project` at its core is simply a collection of `spack configuration files`_ and `spack package repositories`_. +A few other optional hooks will be discussed below. + +The configuration files in a `Project` are organized based on the configuration bifurcations that the projects supports. +These are called `Machines` based on the guiding principle that spack configurations typically have to be +changed when the machine/system is changed. + +`Projects` can be registered with Spack-Manager by adding them to the `spack-manager.yaml` configuration file. +This file lives in the Spack-Manager directory and controls settings for `Spack-Manager` and the `Projects` that +are registered. + +.. code-block:: yaml + + spack-manager: + projects: + - /path/to/project_a + default_view: False + - $HOME/project_b + +Information on configuring a new `Project` can be found in the system administrator profile documentation `here`_. + +.. figure:: ./ApplicationSpace.png + :width: 100% + + The end goal of many code application and DevOps teams is to efficiently span the space of platform permutations and project variations. + +.. _spack configuration files: https://spack.readthedocs.io/en/latest/configuration.html +.. _spack package repositories: https://spack.readthedocs.io/en/latest/repositories.html +.. _here: https://sandialabs.github.io/spack-manager/user_profiles/system_admins/creating_a_project.html diff --git a/docs/index.rst b/docs/index.rst index 020f024b..9cdc794b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,6 +10,13 @@ A given software project typically has multiple configurations across many machi Spack-Manager is quite literal in its name, in that it provides a way to manage and organize these configurations across multiple machines, and multiple projets. +.. figure:: ./Spack-To-Applications.png + :width: 75% + + Spack is serving the package management needs of thousands of software packages. + However, individual application teams wish to harness the power of Spack for their individual applications specific needs. + This naturally leads to redundant, similar workflows. + The intent of this project is to maintain as thin of a buffer as possible between software packages and Spack, and to be pushing ideas and workflow improvements back to Spack on a regular basis to reduce the code that is maintained here. As such we do not try to fully mask Spack's workflow or commands from users, but rather expose them at a level appropriate for the user type. @@ -24,6 +31,11 @@ decreases as the user becomes further removed from the build process. The three - Code developers (some basics about Spack are required, but much of the workflow can be scripted away) - Analysts (zero exposure to Spack) +.. figure:: ./ProfilePyramids.png + :width: 70% + + Population size of each profile is inverserly proportional to the Spack knowledge required for their roles + Separate documentation exists for each of these user profiles. .. toctree:: @@ -55,5 +67,4 @@ Additional details about the philosophy, and general knowledge can be found in t .. toctree:: :maxdepth: 3 - general/FAQ general/general diff --git a/docs/user_profiles/developers/developer_workflow.md b/docs/user_profiles/developers/developer_workflow.md index 25c3c401..8bf1c989 100644 --- a/docs/user_profiles/developers/developer_workflow.md +++ b/docs/user_profiles/developers/developer_workflow.md @@ -22,9 +22,12 @@ and it should also be on a filesytem that is accesible where you plan to run the ```console git clone --recursive git@github.com:sandialabs/spack-manager.git ``` -In order for Spack-Manager to work you need to define the `SPACK_MANAGER` environment variable, -and it should provide the absolute path to your Spack-Manager directory. To have access to the -commands we will use in this tutorial you need to source `$SPACK_MANAGER/start.sh`. +For the purpose of this documentaiton we will define a `SPACK_MANAGER` environment variable, +and it should provide the absolute path to your Spack-Manager directory. +Spack-Manager also provides a `spack manager location` command which will provide an absolute path +to the Spack-Manager source directory. +To have access to the +commands we will use in this tutorial you need to source `$SPACK_MANAGER/scripts/quick_commands.sh`. This script enables all the shell functions in Spack-Manager but it does not activate Spack. We do this to allow you to add these lines to your `bash_profile` without any penalty since sourcing Spack adds an unacceptable level of overhead for standard shell spawning, @@ -32,7 +35,7 @@ since sourcing Spack adds an unacceptable level of overhead for standard shell s ```console # These lines can be added to your bash_profile export SPACK_MANAGER=$(pwd)/spack-manager -source $SPACK_MANAGER/start.sh +source $SPACK_MANAGER/scripts/quick_commands.sh ``` ## Creating an Environment @@ -44,7 +47,6 @@ They all exit the process of setting up an environment at different points in th | Step | quick-create | quick-create-dev | quick-develop | |:-----|:------------:|:----------------:|:-------------:| -| spack-start | x | x | x | | Create an environment | x | x | x| | Activate an environment | x | x | x | | Add root specs | x | x | x| @@ -59,7 +61,6 @@ To see the options for the command we can run it with the `--help` command. ```console quick-create-dev -h -+ spack-start ************************************************************* HELP MESSAGE: quick-create-dev sets up a developer environment @@ -81,7 +82,7 @@ optional arguments: -h, --help show this help message and exit -m MACHINE, --machine MACHINE Machine to match configs - -n NAME, --name NAME Name of directory to copy files that will be in $SPACK_MANAGER/environments + -n NAME, --name NAME Name of directory for environment (managed environment) -s SPEC [SPEC ...], --spec SPEC [SPEC ...] Specs to populate the environment with -y YAML, --yaml YAML Reference spack.yaml to copy to directory @@ -100,7 +101,7 @@ plan to develop in from the spec list in the command above. Please note that the (`amr-wind`) and the version from spack (`main`), and that **that the version is not necessarily the same thing as the branch**. This is covered in the [things developers need to know about Spack](https://sandialabs.github.io/spack-manager/user_profiles/developers/developer_spack_minimum.html) for those needing a refresher. -The `-n` flag can be replaced with `-d` if we want to setup an environment in a different location than `$SPACK_MANAGER/environments` (see the help message above). +The `-n` flag can be replaced with `-d` if we want to setup an environment in a different location than `spack:config:environments_root` (see the [spack documentation](https://spack.readthedocs.io/en/latest/config_yaml.html#spack-settings-config-yaml) for help on configuring custom managed spack environment locaitons). The `quick-create-dev` command will execute all the stages in the table above including cloning the repos from github for the software. These clones of the source code default to the environment directory you specified with the `-d` or `-n` flags. If we wish to work off specific branches then we can use `git add remote`, `git fetch` and `git checkout` to get the branches we want @@ -141,7 +142,6 @@ git clone --recursive --branch main git@github.com:Exawind/exawind-driver.git ex git clone --recursive --branch master git@github.com:Exawind/nalu-wind.git git clone --recursive --branch main git@github.com:Exawind/amr-wind.git quick-create-dev -s exawind@main amr-wind@main nalu-wind@master -+ spack-start + spack manager create-dev-env -s exawind@master amr-wind@main nalu-wind@master ==> Configuring spec exawind@master for development at path exawind ==> Warning: included configuration files should be updated manually [files=include.yaml] @@ -179,6 +179,10 @@ If they are newer than the install time then it will trigger an incremental buil Any changes you make in a dependency will also trigger a rebuild of the upstream software too. In this environment if you make a change in `amr-wind` it will also trigger a rebuild of the `exawind` package as well. +If you wish to just do a quick incremental build you can use the `spack manager make` command: +```console +spack manager make amr-wind -j=16 +``` ## Running Tests and Coming Back @@ -186,6 +190,10 @@ To run tests in a one off manner you can use the `spack build-env` command to ru This is further documented [here](https://sandialabs.github.io/spack-manager/user_profiles/developers/snapshot_workflow.html#running). We also have a function `build-env-dive` which is a beta feature that launches this same subshell in your terminal and dives into it. It is further documented [here](https://sandialabs.github.io/spack-manager/user_profiles/developers/useful_commands.html#build-env-dive). +Finally, if a `test` target is implementd for your software you can use `spack manager make` +```console +spack manager make --args="test -j16" amr-wind +``` If you wish to come back to an environment later, or in a new shell you can just run ```console diff --git a/docs/user_profiles/developers/developers.rst b/docs/user_profiles/developers/developers.rst index b201ea84..c6377d32 100644 --- a/docs/user_profiles/developers/developers.rst +++ b/docs/user_profiles/developers/developers.rst @@ -13,4 +13,3 @@ This documentation is to help understand the basic requirements and workflow for useful_commands advanced_topics snapshot_workflow - external diff --git a/docs/user_profiles/developers/external.md b/docs/user_profiles/developers/external.md deleted file mode 100644 index 491eafc7..00000000 --- a/docs/user_profiles/developers/external.md +++ /dev/null @@ -1,26 +0,0 @@ -# Externals and snapshots - -One of the prominent and unique features of Spack-Manager is the ability for developers to automatically link against binaries -that were created in a snapshot of builds, or even between individual developer environments. -This feature is enabled through Spack's external specification for packages, and is automated with the `spack manager external` command. - -Spack has several ways of reusing previous builds, and sharing binaries. -The major ways of doing this are: - -- Re-using packages in the current Spack database: Standard operation and through the `--reuse` flag -- Buildcaches: Indpepndent binary caches that can be hosted on webservers and filesystems -- Upstreams: Chaining Spack installations so that the installed packages in the upstream versions are usable and read-only downstream -- Externals: Manually specifying the path or module for a known installation of software - -All of these options were evaluated during the inception of Spack-Manager, but the first three were discarded for the same fundamental reason: -the control over which software you get is not stricitly yours. -For all three cases you must rely on the concretizer to pick a compatible software installation for you. -Externals are the only way to take explicit control and force Spack to use libraries from a specific location of your choosing. - -## How is an external defined - -## CMD: `spack manager external` - -## How to use `spack manager external` to share binares with others - -## Relationship with Spack-Manager snapshots \ No newline at end of file diff --git a/docs/user_profiles/developers/snapshot_workflow.md b/docs/user_profiles/developers/snapshot_workflow.md index d5b7eb7b..ae12828d 100644 --- a/docs/user_profiles/developers/snapshot_workflow.md +++ b/docs/user_profiles/developers/snapshot_workflow.md @@ -1,5 +1,9 @@ # Snapshot Developer Workflow Example +**WARNING:** This documentation is fairly specific to ExaWind and has not been generalized for an arbitrary `Spack-Manager` project. +THe information is still useful. However, you may not translate directly or be able to follow along. + + In this tutorial we will look at how to setup a developer workflow using snapshots if they are provided on your machine. ## Setup diff --git a/docs/user_profiles/developers/useful_commands.md b/docs/user_profiles/developers/useful_commands.md index 280215cd..08c5a2a0 100644 --- a/docs/user_profiles/developers/useful_commands.md +++ b/docs/user_profiles/developers/useful_commands.md @@ -5,7 +5,7 @@ Using these commands (along with familiarization with the [spack.yaml](https://s In practice many of these commands are redundant and unneccesary for standard development workflows. To assist with your workflow we've pre-scripted these commands in a set of _quick-commands_. -These commands are available in your shell once you've sourced `$SPACK_MANAGER/start.sh`, and provide a drop off point in the workflows based on your needs. +These commands are available in your shell once you've sourced `$SPACK_MANAGER/scripts/quick_commands.sh`, and provide a drop off point in the workflows based on your needs. All of the _quick-commands_ will echo all the calls to spack (pre-pended with a `+ ` ) so you can see what is being called and can reproduce them execution outside these scripts as needed. Information on these commands are provided below. @@ -17,20 +17,18 @@ For a quick reference: the commands that are anticipated to be the most commonly ## Environment setup process As a reminder, the complete, granular list of steps to setup an environment after sourcing `$SPACK_MANAGER/start.sh` are: -1. `spack-start`: activate Spack in your current shell -2. `spack manager create-env`: create an environment -3. `spack env activate`: activate the environment you created -4. `spack add`: add root specs to the environment -5. `spack manager develop`: setup the source code you want to edit and configure the environment to use that code -6. `spack manager external`: optional step to link your environment against pre-built binaries -7. `spack concretize`: solve the dependency graph for your environment -8. `spack install`: build the software +1. `spack manager create-env`: create an environment +2. `spack env activate`: activate the environment you created +3. `spack add`: add root specs to the environment +4. `spack manager develop`: setup the source code you want to edit and configure the environment to use that code +5. `spack manager external`: optional step to link your environment against pre-built binaries +6. `spack concretize`: solve the dependency graph for your environment +7. `spack install`: build the software ## Environment loading process The complete, granular list of steps to re-use an environment after sourcing `$SPACK_MANAGER/start.sh` are: -1. `spack-start`: load Spack in your current shell -2. `spack env activate`: activate an environment -3. `spack build env [package] [commands]` or `spack cd -b [spec] && bash -rcfile ../spack-build-env.txt`: run a command in the build environment or dive into the build environment in a subshell +1. `spack env activate`: activate an environment +2. `spack build env [package] [commands]` or `spack cd -b [spec] && bash -rcfile ../spack-build-env.txt`: run a command in the build environment or dive into the build environment in a subshell ## Environment setup commands The following commands are the convenience functions for setting up a development environment. diff --git a/docs/user_profiles/system_admins/creating_a_project.md b/docs/user_profiles/system_admins/creating_a_project.md index aee6d4f0..e4779aae 100644 --- a/docs/user_profiles/system_admins/creating_a_project.md +++ b/docs/user_profiles/system_admins/creating_a_project.md @@ -7,7 +7,7 @@ If a pre-configred project exists then it simply has to be add to the Spack-Mana This section will demonstrate the process of setting up a Spack-Manager project from scratch using the [ExaWind application](https://github.com/Exawind/). This is just an example that is not going to be kept up-to-date for Exawind since it is a living, independent project. -The actual ExaWind configuration can be found at `TODO: Link`. +The actual ExaWind configuration can be found [here](https://github.com/Exawind/exawind-manager/). ## Creating a Project from Scratch diff --git a/install.py b/install.py index bbd91178..9886274e 100755 --- a/install.py +++ b/install.py @@ -12,20 +12,26 @@ """ import argparse -import llnl.util.tty as tty -import os -import spack.main import importlib.util +import os import sys -spec = importlib.util.spec_from_file_location("check", os.path.join(os.path.dirname(sys.argv[0]), "check.py")) +import llnl.util.tty as tty + +import spack.main + +spec = importlib.util.spec_from_file_location( + "check", os.path.join(os.path.dirname(sys.argv[0]), "check.py") +) check = importlib.util.module_from_spec(spec) sys.modules["check"] = check spec.loader.exec_module(check) parser = argparse.ArgumentParser() parser.add_argument("-s", "--scope", required=False, help="Spack scope to register spack-manager") -parser.add_argument("--test", action='store_true', help="Don't actually install but test installation process") +parser.add_argument( + "--test", action="store_true", help="Don't actually install but test installation process" +) if __name__ == "__main__": args = parser.parse_args() diff --git a/manager/cmd/manager.py b/manager/cmd/manager.py index 87101a94..a5c17775 100644 --- a/manager/cmd/manager.py +++ b/manager/cmd/manager.py @@ -16,6 +16,7 @@ import spack.extensions.manager.manager_cmds.include as include import spack.extensions.manager.manager_cmds.location as location import spack.extensions.manager.manager_cmds.pin as pin +import spack.extensions.manager.manager_cmds.make as make # import spack.extensions.manager.manager_cmds.snapshot as snapshot @@ -45,6 +46,8 @@ def setup_parser(subparser): include.add_command(sp, _subcommands) location.add_command(sp, _subcommands) pin.add_command(sp, _subcommands) + make.add_command(sp, _subcommands) + # pin.add_command(sp, _subcommands) # snapshot.add_command(sp, _subcommands) diff --git a/manager/manager_cmds/find_machine.py b/manager/manager_cmds/find_machine.py index af663ba8..505686ea 100644 --- a/manager/manager_cmds/find_machine.py +++ b/manager/manager_cmds/find_machine.py @@ -5,6 +5,8 @@ # This software is released under the BSD 3-clause license. See LICENSE file # for more details. +import os + import spack.extensions.manager.projects as m_proj @@ -45,10 +47,11 @@ def find_machine(verbose=False, projects=m_proj.get_projects()): def find_machine_cmd(parser, args): + projects = m_proj.get_projects(args.project) if args.list: print("Project:\t Machine:\t Detected: (+/-)") print("-" * 60) - for project in m_proj.get_projects(args.project): + for project in projects: for machine in project.machines: print( "{proj} \t {machine} \t {detected}".format( @@ -58,7 +61,16 @@ def find_machine_cmd(parser, args): ) ) return - find_machine(verbose=True, projects=m_proj.get_projects(args.project)) + elif args.config: + project, machine = find_machine(verbose=False, projects=projects) + if not project or machine == "NOT-FOUND": + return + else: + path = os.path.join(project.config_path, machine) + print(path) + return path + else: + find_machine(verbose=True, projects=projects) def setup_parser_args(sub_parser): @@ -71,6 +83,13 @@ def setup_parser_args(sub_parser): "index of the project" ), ) + sub_parser.add_argument( + "-c", + "--config", + action="store_true", + required=False, + help="location of the machine specific configs", + ) sub_parser.add_argument( "-l", diff --git a/manager/manager_cmds/make.py b/manager/manager_cmds/make.py new file mode 100644 index 00000000..9e90653a --- /dev/null +++ b/manager/manager_cmds/make.py @@ -0,0 +1,94 @@ +# Copyright (c) 2022, National Technology & Engineering Solutions of Sandia, +# LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +# Government retains certain rights in this software. +# +# This software is released under the BSD 3-clause license. See LICENSE file +# for more details. + +import os + +import llnl.util.tty as tty +from llnl.util.filesystem import working_dir + +import spack.build_environment as build_environment +import spack.builder +import spack.cmd +import spack.paths +from spack.util.executable import Executable + +""" +This was originally implemented by Tim Fuller @tjfulle +With his permission it is being published in the spack manager +subset of commands +""" +description = "make SPEC directly with `make` or `ninja`" +section = "manager" +level = "short" + + +def setup_parser(parser): + parser.add_argument( + "spec", metavar="SPEC", nargs="+", help="Spack package to build (must be a develop spec)" + ) + build_args = parser.add_mutually_exclusive_group() + build_args.add_argument( + "--args", + "-a", + default="", + required=False, + help="Additional arguments to pass to make as a string i.e. `--args='test -j16'`", + ) + build_args.add_argument( + "-j", + type=int, + required=False, + help="number of ranks to build with (specialized implementation of --args)", + ) + + +def make(parser, args): + env = spack.cmd.require_active_env(cmd_name="make") + specs = spack.cmd.parse_specs(args.spec) + if args.j: + extra_make_args = [f"-j{args.j}"] + else: + extra_make_args = args.args.split() + if not specs: + tty.die("You must supply a spec.") + if len(specs) != 1: + tty.die("Too many specs. Supply only one.") + spec = env.matching_spec(specs[0]) + if spec is None: + tty.die(f"{specs[0]}: spec not found in environment") + elif not spec.is_develop: + tty.die(f"{specs[0]}: must be a develop spec") + pkg = spec.package + builder = spack.builder.create(pkg) + if hasattr(builder, "build_directory"): + build_directory = os.path.normpath(os.path.join(pkg.stage.path, builder.build_directory)) + else: + build_directory = pkg.stage.source_path + try: + build_environment.setup_package(spec.package, False, "build") + except TypeError: + build_environment.setup_package(spec.package, False) + + if not os.path.isdir(build_directory): + tty.die( + ( + "Build directory does not exist. " + "Please run `spack install` to ensure the build is " + "configured properly" + ) + ) + + with working_dir(build_directory): + make_program = "ninja" if os.path.exists("build.ninja") else "make" + make = Executable(make_program) + make(*extra_make_args) + + +def add_command(parser, command_dict): + subparser = parser.add_parser("make", help=description) + setup_parser(subparser) + command_dict["make"] = make diff --git a/scripts/platform_configure_tool.py b/scripts/platform_configure_tool.py new file mode 100755 index 00000000..b65f5d96 --- /dev/null +++ b/scripts/platform_configure_tool.py @@ -0,0 +1,49 @@ +#! /usr/bin/env spack-python +import argparse +import os +import pathlib + +import spack.main +import spack.util.spack_yaml as syaml +from spack.util.module_cmd import module + +parser = argparse.ArgumentParser() +parser.add_argument("input", help="input file describing what to configure") +output_types = parser.add_mutually_exclusive_group(required=True) +output_types.add_argument("--output", help="location where the configs should get written") +output_types.add_argument("--scope", help="spack scope where the configs should get written") + +args = parser.parse_args() + +input_path = pathlib.PurePath(args.input) +if args.output: + output_path = pathlib.PurePath(args.output) + os.environ["SPACK_USER_CONFIG_PATH"] = str(output_path) + scope = "user" +else: + scope = args.scope + +exe_env = os.environ.copy() + +with open(input_path, "r") as f: + manifest = syaml.load(f) + +compiler = spack.main.SpackCommand("compiler", subprocess=True) +external_cmd = spack.main.SpackCommand("external", subprocess=True) + +if "compilers" in manifest: + for c in manifest["compilers"]: + module("load", c) + print(compiler("find", "--scope", scope, env=exe_env)) + module("unload", c) + +if "externals" in manifest: + print(external_cmd("find", "--scope", scope, *manifest["externals"], env=exe_env)) + +if "modules" in manifest: + for entry in manifest["modules"]: + m = entry["module"] + p = entry["packages"] + module("load", m) + print(external_cmd("find", "--scope", scope, *p, env=exe_env)) + module("unload", m) diff --git a/tests/test_find_machine.py b/tests/test_find_machine.py index 0fba26eb..53391d3c 100644 --- a/tests/test_find_machine.py +++ b/tests/test_find_machine.py @@ -35,3 +35,11 @@ def test_find_machine_filters_on_project(mock_manager_config_path): assert "moonlight" in out out = mgr_cmd("find-machine", "--project", "project_b", "--list") assert "moonlight" not in out + + +def test_find_machine_config_points_to_path(on_moonlight): + assert manager.config_path != manager._default_config_path + assert find_machine.machine_defined("moonlight") + out = mgr_cmd("find-machine", "--config") + assert "moonlight" in out + assert os.path.isdir(out.strip()) diff --git a/tests/test_make.py b/tests/test_make.py new file mode 100644 index 00000000..4df5ce67 --- /dev/null +++ b/tests/test_make.py @@ -0,0 +1,26 @@ +# Copyright (c) 2022, National Technology & Engineering Solutions of Sandia, +# LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +# Government retains certain rights in this software. +# +# This software is released under the BSD 3-clause license. See LICENSE file +# for more details. + +import pytest + +import spack.environment as ev +import spack.extensions +import spack.main + +env = spack.main.SpackCommand("env") +manager = spack.main.SpackCommand("manager") +add = spack.main.SpackCommand("add") + + +@pytest.mark.usefixtures("mutable_mock_env_path_wh_manager", "mock_packages", "mock_fetch") +def test_spackManagerMakeRequiresDevelopSpec(): + env("create", "test") + with ev.read("test"): + add("mpich") + with pytest.raises(spack.main.SpackCommandError): + out = manager("make", "mpich") + assert "must be a develop spec" in str(out)