spack简明使用手册

部署spack

下载

release(推荐)

github下载最新的release:github.com/spack/spack…

git

1
2
3
git clone https://github.com/spack/spack.git ~/spack
cd ~/spack
git checkout releases/v0.17

✨tips: github 国内下载慢,百度 github镜像加速站 或 油猴脚本 - github 高速下载

激活

对于超算/lab/hpc等多用户场景,建议将spack本地放在全局/共享目录下

单个普通用户建议放在 ~/.spack/ 或 /opt下

解压下载好的压缩包, 加载环境变量(根据具体情况变更路径):

1
source spack/share/spack/setup-env.sh

可以将此命令写在~/.bashrc/etc/profile中 , 打开终端自动生效

配置

spack 的用户配置文件均在 ~/.spack 下,首次使用 spack 可能没有此目录,使用 3.2 会自动创建

基本配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ spack config get config > ~/.spack/config.yaml
$ spack config get config
config:
install_tree:
root: $spack/opt/spack
projections:
all: ${ARCHITECTURE}/${COMPILERNAME}-${COMPILERVER}/${PACKAGE}-${VERSION}-${HASH}
template_dirs:
- $spack/share/spack/templates
build_stage:
- $tempdir/$user/spack-stage
- $user_cache_path/stage
test_stage: $user_cache_path/test
source_cache: $spack/var/spack/cache
misc_cache: $user_cache_path/cache
connect_timeout: 10
verify_ssl: true
suppress_gpg_warnings: false
install_missing_compilers: false
checksum: true
deprecated: false
dirty: false
build_language: C
locks: true
url_fetch_method: urllib
ccache: false
concretizer: clingo
db_lock_timeout: 3
package_lock_timeout: null
shared_linking: rpath
allow_sgid: true
terminal_title: false
debug: false
build_jobs: 16

解析:

  • install_tree 中 root 为当前用户 软件安装的路径 , projections 为软件路径的命名规范
  • verify_ssl 在install时会校验url的ssl证书,离线环境可以选择关闭(值为 fasle)
  • locks 锁机制: 默认开启,同一用户分别安装相同的软件,只允许有一个进程执行,执行完后,另一个进程将跳过该软件安装;关闭的话,可能制造重复安装,但在某些文件系统的特殊权限限制下,需要关闭,否则会报奇怪的读写错误
  • build_job 安装时默认使用的最大cpu核心数
  • checksum 校验源码包的hash值

编译器

使用spack compiler find将会自动查找本机的所有编译器,生成配置文件~/.spack/linux/compilers.yaml

spack compilers查看添加到配置文件中的编译器

1
2
3
4
5
6
7
8
9
10
11
12
13
$ spack compilers
==> Available compilers
-- clang centos7-x86_64 -----------------------------------------
clang@12.0.1 clang@3.4.2

-- gcc centos7-x86_64 -------------------------------------------
gcc@10.2.0 gcc@8.5.0 gcc@7.5.0 gcc@6.5.0 gcc@4.9.4 gcc@4.8.5

-- intel centos7-x86_64 -----------------------------------------
intel@2021.4.0 intel@19.0.5.281

-- oneapi centos7-x86_64 ----------------------------------------
oneapi@2021.4.0

源码镜像仓库

自建源码镜像仓库

1
$ spack mirror create -d <PATH> --all

一个标准的源码镜像仓库符合以下目录规范:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mirror/
cmake/
cmake-2.8.10.2.tar.gz
dyninst/
dyninst-8.1.1.tgz
dyninst-8.1.2.tgz
libdwarf/
libdwarf-20130126.tar.gz
libdwarf-20130207.tar.gz
libdwarf-20130729.tar.gz
libelf/
libelf-0.8.12.tar.gz
libelf-0.8.13.tar.gz
libunwind/
libunwind-1.1.tar.gz
mpich/
mpich-3.0.4.tar.gz
mvapich2/
mvapich2-1.9.tgz

添加私有源码镜像仓库

1
$ spack mirror add <scope> <path>

生成配置文件~/.spack/linux/mirrors.yaml

例如 添加 一个 在/opt/mirror下的源码镜像仓库,给它取名为haha:

1
spack mirror add haha /opt/mirror

查看已添加的源码镜像仓库

1
2
$ spack mirror list
spack-public https://mirror.spack.io

默认使用 位于美国亚马逊云的 spack公共仓库 mirror.spack.io ,在国内获取 源码/索引 的速度可能会很慢

脚本源

查看当前使用的脚本源

1
2
3
$ spack repo list
==> 1 package repository.
builtin /root/spack/var/spack/repos/builtin

默认使用spack官方的脚本源

添加私有脚本源

一个标准的spack脚本源符合如下的路径规范:

1
2
3
4
5
6
7
$ tree -L /root/spack/var/spack/repos/yeesuan
/root/spack/var/spack/repos/yeesuan
├── packages
│ ├── gromacs
│ │ ├── package.py
│ │ └── __pycache__
└── repo.yaml

其中 repo.yaml 定义了该脚本源的命名空间:

1
2
repo:
namespace: 'yeesuan'

添加该脚本源:

1
$ spack repo add /root/spack/var/spack/repos/yeesuan

modules

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ spack config get modules > ~/.spack/modules
$ spack config get modules
modules:
prefix_inspections:
lib:
- LD_LIBRARY_PATH
lib64:
- LD_LIBRARY_PATH
bin:
- PATH
man:
- MANPATH
share/man:
- MANPATH
share/aclocal:
- ACLOCAL_PATH
lib/pkgconfig:
- PKG_CONFIG_PATH
lib64/pkgconfig:
- PKG_CONFIG_PATH
share/pkgconfig:
- PKG_CONFIG_PATH
? ''
: - CMAKE_PREFIX_PATH

# These are configurations for the module set named "default"
default:
# roots:
# tcl: $spack/share/spack/modules
# lmod: $spack/share/spack/lmod
enable:
- tcl

# Default configurations if lmod is enabled
lmod:
hierarchy:
- mpi

prefix_inspections:定义了声明的环境变量和路径的对应关系

其中defalut中roots的tcl /lmod 定义了 安装软件后,modules 文件的安装位置

自定义packages

spack external find可以添加系统中的软件,为spack 管理 (超算环境不推荐)

1
2
3
4
5
6
7
8
$ spack external find
==> The following specs have been detected on this system and added to /root/.spack/packages.yaml
bash@4.2.46 gawk@4.0.2 krb5@1.15.1 pkg-config@0.27.1 sqlite@3.7.17
bzip2@1.0.6 gcc@4.8.5 llvm@3.4.2 python@2.7.5 tar@1.26
cpio@2.11 git@2.36.0 llvm-doe@3.4.2 python@3.6.8 texinfo@5.1
diffutils@3.3 gmake@3.82 openssh@7.4p1 rsync@3.1.2 xz@5.2.2
file@5.11 go@1.18.1 openssl@1.0.2k-fips rust@1.60.0
findutils@4.5.11 groff@1.22.2 perl@5.16.3 sed@4.2.2

这是我们自定义添加的两块软件:

1
2
3
4
5
6
7
8
9
packages:
cmake:
externals:
- spec: cmake@3.21.4
prefix: /yeesuan/linux-centos7-haswell/gcc-4.8.5/cmake-3.21.4-4q7yowzqqc6x36tsxd2bsgeenwci6iqt
util-linux-uuid:
externals:
- spec: util-linux-uuid@2.36.2
prefix: /yeesuan/linux-centos7-haswell/gcc-4.8.5/util-linux-uuid-2.36.2-psepywix72fmt453hwcmrepmqslrai3a

可以按照上述规范添加自己的软件

基本使用

spack中有什么?

基础命令:spack list

默认返回所有支持spack安装的软件:

1
2
3
4
$ spack list
==> 5969 packages.
3dtk intel-oneapi-inspector pexsi py-pygeos r-parallelmap
3proxy intel-oneapi-ipp pfapack py-pygetwindow r-param helpers

支持通配符查找:

1
2
3
4
5
$ spack list *blas*
==> 18 packages.
blaspp blast-legacy cblas hipblas ncbi-magicblast openblas
blasr blast-plus flexiblas libblastrampoline ncbi-rmblastn rocblas
blasr-libcpp blast2go graphblast liblas netlib-xblas samblaster

查找描述里包含某个关键词:

1
2
3
4
5
6
7
8
9
$ spack list -d physics
==> 46 packages.
albany cradl flecsph herwig3 n2p2 py-openmc sombrero
alps damask freefem herwigpp openmc py-uproot3-methods thepeg
amp datatransferkit geant4 jali pennant pythia6 trilinos
ascent delphes genfit libsakura podio pythia8 yambo
axom exciting hepmc lorene portage r-qvalue
clhep fastjet hepmc3 mcutils precice recola
cp2k flecsi heputils minuit py-espresso rivet

查看软件详细信息

基础命令:spack info <package_name>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
$ spack info vasp
MakefilePackage: vasp

Description:
The Vienna Ab initio Simulation Package (VASP) is a computer program
for atomic scale materials modelling, e.g. electronic structure
calculations and quantum-mechanical molecular dynamics, from first
principles.

Homepage: https://vasp.at

Externally Detectable:
False

Tags:
None

Preferred version:
6.1.1 file:///root/vasp.6.1.1.tgz

Safe versions:
6.1.1 file:///root/vasp.6.1.1.tgz
5.4.4.pl2 file:///root/vasp.5.4.4.pl2.tgz
5.4.4 file:///root/vasp.5.4.4.tgz

Deprecated versions:
None

Variants:
Name [Default] When Allowed values Description
=============== ==== =============== ====================================

cuda [off] -- on, off Enables running on Nvidia GPUs
scalapack [off] -- on, off Enables build with SCALAPACK
vaspsol [off] -- on, off Enable VASPsol implicit solvation model
https://github.com/henniggroup/VASPsol
Installation Phases:
edit build install

Build Dependencies:
blas cuda fftw lapack mpi netlib-scalapack qd rsync

Link Dependencies:
blas cuda fftw lapack mpi netlib-scalapack qd

Run Dependencies:
mpi

Virtual Packages:
None

解析
1.MakefilePackage表示vasp用make构建

其他的,像gromacs 是CMakePackage,表示用cmake构建,fftw 是 Autotools, 流程中需要先configuremake

2.Description: 软件的介绍

3.Homepage:软件官网

4.Preferred version是推荐版本,Safe versions是安全的(经过充分验证的)版本

其中,左侧列是版本号,右侧列是软件的URL地址

spack默认使用 系统命令 curl “下载”软件 ,curl支持的协议有 https/http/file/…. ,上面例子表示默认使用当前路径下的源码包
5.Variants 我翻译为“特性”

第一列为特性的名字,第二列为特性的条件,第三列为特性的值,其中,第一列,变量名后的中括号内,是默认的变量值

6.Installation Phases 表示了该软件安装时的三个步骤

7.Build Dependencies 表示了构建前需要加载的环境

8.Link Dependencies 表示了构建时用到的链接库

9.Run Dependencies 表示了在使用软件时,需要加载的环境

安装软件

基础命令:spack install <package_name>

1
2
3
4
5
6
7
8
9
10
$ spack install zlib
==> Bootstrapping clingo from pre-built binaries
==> Installing zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd
==> No binary for zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd found: installing from source
==> Fetching https://mirror.spack.io/_source-cache/archive/c3/c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1.tar.gz
==> No patches needed for zlib
==> zlib: Executing phase: 'install'
==> zlib: Successfully installed zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd
Fetch: 1.06s. Build: 3.09s. Total: 4.15s.
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd

进阶-高度自定义的安装命令

指定编译器

编译器需要搭配 百分号 “%”,只能跟在软件名后面

例如使用gcc编译器:

1
spack install zlib%gcc

软件名和编译器之间允许有多个空格,所以也可以写成这样:

1
spack install zlib %gcc

一般地,我们的系统中存在多个版本的gcc编译器,所以需要指定使用哪一个版本的编译器:

1
spack install zlib %gcc@6.5.0

需要说明的是,这里的编译器 名称,可能不会和 spack list 中一一对应,

例如,英特尔oneapi的编译器,list表里的名称为 intel-oneapi-compilers, 但spack compilers里则是intel

指定依赖

以2.1为例,vasp的依赖,其中的blas、lapack、netlib-scalapack 这三个数学库在英特尔的mkl库中均有实现,

所以安装vasp时可以指定使用mkl,搭配 “^”

1
spack install vasp ^intel-mkl

2020之后的mkl库的包名发生了变化,我们指定适合用2021.4.0版本的

1
spack install vasp ^intel-oneapi-mkl@2021.4.0

我们的cc编译器也想用intel的icc, 版本号和mkl相同

1
spack install vasp %intel@2021.4.0 ^intel-oneapi-mkl@2021.4.0

特性

仍以2.1为例,官方提供的vasp有一个叫vaspsol的特性,它是vasp的一个扩展包,默认关闭状态,如果想开启此特性,需要搭配“+”使用

1
spack install vasp +vaspsol

mpich的特性pmi的值有多个,默认为mpi

1
pmi [pmi]            --      off, pmi, pmi2, pmix    PMI interface.

我们想全都使用,则使用“=”表达,以英文小写逗号“,”分隔不同的值

1
spack install mpich mpi=pmi,pmi2,pmix

mpich的特性fortran的值默认时开启状态,我们不想使用它,搭配波浪线

1
spack install mpich ~fortran

多线程

构建时可以指定使用的最大cpu核心数,在install后面 加入 -j 参数, 后接核心数

1
spack install -j 64 vasp

✨tips: 可以通过系统命令 nproc 查询到最大核心数 ,也可以写成变量的形式

综合

以安装gcc6.5.0为例,使用系统自带的gcc4.8.5编译,需要开启几乎全部的特性,其中的go使用1.16版本

1
spack install -j 64 -y gcc@6.5.0 %gcc@4.8.5 +binutils+bootstrap+piclibs+strip languages=ada,c,c++,fortran,go,java,jit,lto,objc,obj-c++ ^go@1.16

✨tips: 其中的 “-y”可以默认选择一些软件的提示性的编译选项或其他选项

卸载软件

基础命令:spakc uninstall <package_name>

1
2
3
4
5
6
7
8
9
10
11
12
13
$ spack uninstall autoconf
==> Error: autoconf matches multiple packages:

-- linux-centos7-cascadelake / gcc@10.2.0 -----------------------
kwq2zrg autoconf@2.69

-- linux-centos7-skylake_avx512 / gcc@6.5.0 ---------------------
2vv3qa2 autoconf@2.69

==> Error: You can either:
a) use a more specific spec, or
b) specify the spec by its hash (e.g. `spack uninstall /hash`), or
c) use `spack uninstall --all` to uninstall ALL matching specs.

像上面,卸载报错,我们可以指定编译器:

1
spack uninstall autoconf %gcc@6.5.0

方便地,使用其hash值:

1
spack uninstall /2vv3qa2

默认卸载全部autoconf:

1
spack uninstall --all autoconf

有时候,卸载该软件也需要卸载其依赖:

1
spack uninstall -d <package_name>

查找已安装的软件

基础命令:spack find

1
2
3
4
5
6
7
8
9
10
11
$ spack find
==> 805 installed packages
-- linux-centos7-cascadelake / gcc@10.2.0 -----------------------
boost@1.77.0 intel-oneapi-mpi@2021.4.0 python@3.8.12
bzip2@1.0.8 libbsd@0.11.3 readline@8.1
cereal@1.3.0 libffi@3.3 sqlite@3.36.0

-- linux-centos7-cascadelake / intel@19.0.5.281 -----------------
abinit@9.4.2 intel-mpi@2019.5.281 parmetis@4.0.3
amg@1.2 intel-tbb@2020.3 parmetis@4.0.3
...

指定包名

1
2
3
4
5
6
7
$ spack find vasp
==> 2 installed packages
-- linux-centos7-cascadelake / intel@19.0.5.281 -----------------
vasp@5.4.4

-- linux-centos7-cascadelake / intel@2021.4.0 -------------------
vasp@6.1.0

指定编译器

1
2
3
4
$ spack find vasp %intel@2021.4.0
==> 1 installed package
-- linux-centos7-cascadelake / intel@2021.4.0 -------------------
vasp@6.1.0

指定版本号

1
2
3
4
$ spack find vasp@5.4.4
==> 1 installed package
-- linux-centos7-cascadelake / intel@19.0.5.281 -----------------
vasp@5.4.4

查看软件的特征值

1
2
3
4
5
6
7
$ spack find -l openmpi
==> 2 installed packages
-- linux-centos7-haswell / gcc@4.8.5 ----------------------------
pt2putc openmpi@4.1.1

-- linux-centos7-skylake_avx512 / gcc@6.5.0 ---------------------
tchnk2v openmpi@4.1.1

✨tips: 1.spack支持使用/<hash_value>的方式替代<package_name>,hash_vaule支持长写(完整 )和短写(前面3到7个字符) 2.可以使用 -L 查看完整的特征值

查看软件的特征值和依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ spack find -l -d openmpi
==> 2 installed packages
-- linux-centos7-haswell / gcc@4.8.5 ----------------------------
pt2putc openmpi@4.1.1
y5iroad hwloc@2.6.0
bmzkyfq libpciaccess@0.16
xkbs7ll libxml2@2.9.12
rpsecj5 libiconv@1.16
e6cbjcd xz@5.2.5
z6uqlxn zlib@1.2.11
ez4gk67 ncurses@6.2
owe3cjs libevent@2.1.12
jwr4s44 openssl@1.1.1l
2hfxs5z numactl@2.0.14
tjk74sh openssh@8.7p1
ugfkpjd libedit@3.1-20210216

查看软件的路径

1
2
3
4
5
6
7
spack find -p openmpi
==> 2 installed packages
-- linux-centos7-haswell / gcc@4.8.5 ----------------------------
openmpi@4.1.1 /yeesuan495/.spack/software/linux-centos7-haswell/gcc-4.8.5/openmpi-4.1.1-pt2putcrv2o53naxpesk3rsb4xl44pqa

-- linux-centos7-skylake_avx512 / gcc@6.5.0 ---------------------
openmpi@4.1.1 /yeesuan495/.spack/software/linux-centos7-skylake_avx512/gcc-6.5.0/openmpi-4.1.1-tchnk2vf4iskpfkh7giwurtmyipwmjma

location (建议用find -p)

location 命令也可以定位软件的路径

1
2
$ spack location -i openmpi%gcc@4.8.5
/yeesuan495/.spack/software/linux-centos7-haswell/gcc-4.8.5/openmpi-4.1.1-pt2putcrv2o53naxpesk3rsb4xl44pqa

cd 进入软件根目录

1
2
$ spack cd -i openmpi%gcc@4.8.5
[yxxxx@xxxx openmpi-4.1.1-pt2putcrv2o53naxpesk3rsb4xl44pqa]$

查看软件的命名空间

1
2
3
4
5
6
7
8
9
10
$ spack find -N mpich
==> 1 installed package
-- linux-centos7-skylake_avx512 / gcc@6.5.0 ---------------------
local.mpich@3.4.2

$ spack find -N xz
==> 3 installed packages
-- linux-centos7-cascadelake / gcc@10.2.0 -----------------------
builtin.xz@5.2.5
...

使用软件

基础命令:

加载软件环境变量 spack load <package_name>

卸载软件环境变量 spack unload <package_name>

查看已加载的依赖

1
2
3
4
5
$ spack find --loaded
==> 4 loaded packages
-- linux-centos7-cascadelake / intel@2021.4.0 -------------------
fftw@3.3.10 intel-oneapi-mpi@2021.4.0
intel-oneapi-mkl@2021.4.0 intel-oneapi-tbb@2021.4.0

仅加载软件本身或它的依赖

仅软件本身:

1
spack load --only package <package_name>

仅依赖:

1
spack load --only dependencies <package_name>

查看加载软件的所有环境变量

1
spack load --sh <package_name>

指定参数加载环境变量

指定版本号spack load <package_name>@<package_version>

指定编译器spack load <package_name> %<compiler_name>@<compiler_version>

指定用到的依赖/特性spack load <package_name> ^<dependency_name>

指定命名空间spack load <scope>.<package_name>

上述加载方式都可以组合使用

使用hash值 : spack load /<hash_value>

✨tips: 有时候我们查到的软件版本号和编译器甚至命名空间都一样,它将很难区分

通常,使用spack find -l -d <package_name> 可以打印多个“相同”的软件的依赖详情,我们选择其中一个的hash值加载