Non-Source Dependency Management¶
In the AWS EC2 F1 setup, in Setting up your Manager Instance, we quickly copy-pasted the contents
of scripts/machine-launch-script.sh
into the EC2 Management Console and
that script installed many dependencies that FireSim needs using
Conda, a platform-agnostic package
manager, specifically using packages from the conda-forge community
(or in the case of Setting up your Manager Instance, we ran scripts/machine-launch-script.sh
).
In many situations, you may not need to know anything about conda
. By default, the
machine-launch-script.sh
installs conda
into /opt/conda
and all of the FireSim dependencies into
a ‘named environment’ firesim
at /opt/conda/envs/firesim
.
machine-launch-setup.sh
also adds the required setup to the system-wide /etc/profile.d/conda.sh
init script to add
/opt/conda/envs/firesim/bin
to everyone’s path.
However, the script is also flexible. For example, if you do not have root access, you can specify
an alternate install location with the --prefix
option to machine-launch-script.sh
. The only requirement
is that you are able to write into the install location. See machine-launch-script.sh --help
for more details.
Warning
To run a simulation on a F1 FPGA , FireSim currently requires that
you are able to act as root via sudo
.
However, you can do many things without having root, like Building Your Own Hardware Designs (FireSim Amazon FPGA Images), meta-simulation of a FireSim system using Verilator or even developing new features in FireSim.
Updating a Package Version¶
If you need a newer version of package, the most expedient method to see whether there
is a newer version available on conda-forge is to run conda update <package-name>
. If you are lucky,
and the dependencies of the package you want to update are simple, you’ll see output that looks something like
this:
bash-4.2$ conda update moto
Collecting package metadata (current_repodata.json): done
Solving environment: done
## Package Plan ##
environment location: /opt/conda
added / updated specs:
- moto
The following NEW packages will be INSTALLED:
graphql-core conda-forge/noarch::graphql-core-3.2.0-pyhd8ed1ab_0
The following packages will be UPDATED:
moto 2.2.19-pyhd8ed1ab_0 --> 3.1.0-pyhd8ed1ab_0
Proceed ([y]/n)?
The addition of graphql-core
makes sense because the diff of moto’s setup.py between
2.2.19 and 3.1.0
shows it was clearly added as a new dependence.
And this output tells us that latest version of moto
available is 3.1.0. Now, you might be tempted to
hit <<Enter>>
and move forward with your life.
Attention
However, it is always a better idea to modify the version in machine-launch-script.sh
so that:
#. you remember to commit and share the new version requirement.
#. you are providing a complete set of requirements for conda
to solve. There is a subtle difference between installing everything you need in a single conda install vs incrementally installing one or two packages at a time because the version constraints are not maintained between conda invocations. (NOTE: certain packages like Python are implicitly pinned at environment creation and will only be updated if explicitly requested .)
So, modify machine-launch-script.sh
with the updated version of moto
, and run it. If you’d like to see what
machine-launch-script.sh
will do before actually making changes to your environment, feel free to give it the --dry-run
option, look at the output and then run again without --dry-run
.
In this case, when you are finished, you can run conda list --revisions
and you should see output
like the following
bash-4.2$ conda list --revisions
2022-03-15 19:21:10 (rev 0)
+_libgcc_mutex-0.1 (conda-forge/linux-64)
+_openmp_mutex-4.5 (conda-forge/linux-64)
+_sysroot_linux-64_curr_repodata_hack-3 (conda-forge/noarch)
+alsa-lib-1.2.3 (conda-forge/linux-64)
+appdirs-1.4.4 (conda-forge/noarch)
+argcomplete-1.12.3 (conda-forge/noarch)
... many packages elided for this example ...
+xxhash-0.8.0 (conda-forge/linux-64)
+xz-5.2.5 (conda-forge/linux-64)
+yaml-0.2.5 (conda-forge/linux-64)
+zipp-3.7.0 (conda-forge/noarch)
+zlib-1.2.11 (conda-forge/linux-64)
+zstd-1.5.2 (conda-forge/linux-64)
2022-03-15 19:34:06 (rev 1)
moto {2.2.19 (conda-forge/noarch) -> 3.1.0 (conda-forge/noarch)}
This shows you that the first time machine-launch-script.sh
was run, it created ‘revision’ 0 of the environment with
many packages. After updating the version of moto
and rerunning, ‘revision’ 1 was created by updating the version
of moto
. At any time, you can revert your Conda environment back to an older ‘revision’ using conda install -revision <n>
Multiple Environments¶
In the example above, we only wanted to update a single package and it was fairly straightforward – it only updated that package and installed a new dependency. However, what if we’re making a larger change and we think we might need to have both sets of tools around for awhile?
In this case, make use of the --env <name>
option of machine-launch-script.sh
. By giving a descriptive
name with that option, you will create another ‘environment’. You can see a listing of available environments
by running conda env list
to get output similar to:
bash-4.2$ conda env list
# conda environments:
#
base /opt/conda
firesim /opt/conda/envs/firesim
doc_writing * /opt/conda/envs/doc_writing
In the output above, you can see that I had the ‘base’ environment that is created when you install conda
as well as
the firesim
environment that machine-launch-script.sh
creates by default. I also created a ‘doc_writing’ environment
to show some of the examples pasted earlier.
You can also see that ‘doc_writing’ has an asterisk next to it, indicating that it is the currently ‘activated’ environment.
To switch to a different environment, I could conda activate <name>
e.g. conda activate firesim
By default, machine-launch-script.sh
installs the requirements into ‘firesim’ and runs conda init
to ensure that the
‘firesim’ environment is activated at login.
Adding a New Dependency¶
Look for what you need in this order:
The existing conda-forge packages list. Keep in mind that since
conda
spans several domains, the package name may not be exactly the same as a name from PyPI or one of the system package managers.Adding a conda-forge recipe. If you do this, let the firesim@googlegroups.com mailing list know so that we can help get the addition merged.
PyPI (for Python packages). While it is possible to install packages with pip into a
conda
environment, there are caveats. In short, you’re less likely to create a mess if you use only Conda to manage the requirements and dependencies in your environment.System packages as a last resort. It’s very difficult to have the same tools on different platforms when they are being built and shipped by different systems and organizations. That being said, in a pinch, you can find a section for platform-specific setup in
machine-launch-script.sh
.As a super last resort, add code to
machine-launch-script.sh
orbuild-setup.sh
that installs whatever you need and during your PR, we’ll help you migrate to one of the other options above.
Building From Source¶
If you find that a package is missing an optional feature, consider looking up it’s ‘feedstock’ (aka recipe) repo in The existing conda-forge packages list. and submitting an issue or PR to the ‘feedstock’ repo.
If you instead need to enable debugging or possibly actively hack on the source of a package:
Find the feedstock repo in the feedstock-list
Clone the feedstock repo and modify
recipe/build.sh
(orrecipe/meta.yaml
if there isn’t a build script)python build-locally.py
to build using the conda-forge docker container If the build is successful, you will have an installableconda
package inbuild_artifacts/linux-64
that can be installed usingconda install -c ./build_artifacts <packagename>
. If the build is not successful, you can add the--debug
switch topython build-locally.py
and that will drop you into an interactive shell in the container. To find the build directory and activate the correct environment, just follow the instructions from the message that looks like:################################################################################ Build and/or host environments created for debugging. To enter a debugging environment: cd /Users/UserName/miniconda3/conda-bld/debug_1542385789430/work && source /Users/UserName/miniconda3/conda-bld/debug_1542385789430/work/build_env_setup.sh To run your build, you might want to start with running the conda_build.sh file. ################################################################################
If you are developing a Python package, it is usually easiest to install all dependencies using conda
and then install
your package in ‘development mode’ using pip install -e <path to clone>
(and making sure that you are using pip
from your environment).
Running Conda with sudo¶
tl;dr;
run Conda like this when using sudo
:
sudo -E $CONDA_EXE <remaining options to conda>
If you look closely at machine-launch-script.sh
, you will notice that it always uses the full path
to $CONDA_EXE
. This is because /etc/sudoers
typically doesn’t bless our custom install prefix of /opt/conda
in the secure_path
.
You also probably want to include the -E
option to sudo
(or more specifically
--preserve-env=CONDA_DEFAULT_ENV
) so that the default choice for the environment to modify
is preserved in the sudo environment.
Running things from your Conda environment with sudo¶
If you are running other commands using sudo (perhaps to run something under gdb), remember, the secure_path
does not include the Conda environment by default and you will need to specify the full path to what you want to run,
or in some cases, it is easiest to wrap what you want to run in a full login shell invocation like:
sudo /bin/bash -l -c "<command to run as root>"
The -l
option to bash
ensures that the default Conda environment is fully activated. In the rare case that
you are using a non-default named environment, you will want to activate it before running your command:
sudo /bin/bash -l -c "conda activate <myenv> && <command to run as root>"