计算化学公社

标题: 私用小电脑WSL2装RockyLinux10虚拟机,及LMod管理OpenMPI-4.1.8, ORCA-6.1.1等的笔记 [打印本页]

作者
Author:
Uus/pMeC6H4-/キ    时间: 7 day ago
标题: 私用小电脑WSL2装RockyLinux10虚拟机,及LMod管理OpenMPI-4.1.8, ORCA-6.1.1等的笔记
本帖最后由 Uus/pMeC6H4-/キ 于 2026-1-16 16:05 编辑

私用小电脑WSL2装RockyLinux10虚拟机,及LMod管理OpenMPI-4.1.8, ORCA-6.1.1等的笔记


一、前言

本帖记录给像我头像这样的一台普通自用 Windows 11 办公笔记本电脑上往 WSL2 导入 Rocky Linux 10 创建新的虚拟机,并在其内配备 LMod 与安装 OpenMPI-4.1.8, ORCA-6.1.1, Miniforge 的过程,主要目的在于熟悉 LMod 管理环境的操作。需声明几点:

二、 WSL2 及 Rocky Linux 10 的准备

该部分主要参考链接:

确认电脑满足 WSL 的运行要求后,留出足够的硬盘空间并创建新的空文件夹,比如 D:\RockyLinux10 ,作为导入虚拟机后虚拟硬盘 ext4.vhdx 以及一个 ico 图标文件的位置。该文件夹不宜放置其他文件,以免需要 wsl --unregister 取消注册虚拟机并删除虚拟硬盘时一同被移除。

打开命令行 Command Prompt (快捷键 win+r 输入 cmd 打开的那个),输入命令 wsl --install 安装(若之前没用过)或 wsl --update 更新(若之前用过)。此时开始菜单里有两个相关程序,一个 WSL 一个 WSL Settings ;打开 WSL Settings 并在“内存和处理器”栏设置分配给虚拟机的逻辑处理器数和内存大小、在“文件系统”栏设置分配给虚拟机的硬盘大小。

从 Rocky Linux 官网上下载面向 WSL 的镜像文件 Rocky-10-WSL-Base.latest.x86_64.wsl ,比如放在 D:\Downloads 处,然后在命令行输入:
  1. wsl --install --from-file D:\Downloads\Rocky-10-WSL-Base.latest.x86_64.wsl --location D:\RockyLinux10 --name RockyLinux10 --vhd-size 256GB --fixed-vhd
复制代码
此处的选项各有用意:
此时会花一些时间高速写入硬盘,进度条走完自动进入该虚拟机的 Linux 系统并提示输入 Linux 用户名,例如
  1. 正在安装: D:\Downloads\Rocky-10-WSL-Base.latest.x86_64.wsl
  2. 已成功安装分发。可以通过 “wsl.exe -d RockyLinux10” 启动它
  3. 正在启动 RockyLinux10...
  4. Please create a default user account. The username does not need to match your Windows username.
  5. For more information visit: https://aka.ms/wslusers
  6. Enter new UNIX username: twilight
  7. Your user has been created, is included in the wheel group, and can use sudo without a password.
  8. To set a password for your user, run 'sudo passwd twilight'
复制代码
这就正常创建了一个名为 twilight 且默认无密码也有 sudo 权限的用户(但在 /opt 或 /etc 等根目录执行命令时仍需把 sudo 打出来)。当前目录与执行 wsl --install 指令时的目录一致,如在 C:\Users\{username} 执行后在虚拟机里相应的 /mnt/c/Users/{username} 目录下,用 cd 切换工作目录的指令(如 cd ~ 回到用户的家目录 /home/twilight 等)也可以使用了 。

然后是常规的 dnf 包管理,虽然列表中部分项目已安装有但完整贴出来方便检查,其中安装的 gcc, g++, gfortran 为 14.3.1 版:
  1. dnf list
  2. sudo dnf install -y epel-release
  3. sudo dnf install -y lua* \
  4.   tcl* \
  5.   autoconf \
  6.   automake \
  7.   bzip2 \
  8.   ca-certificates \
  9.   diffutils \
  10.   g++ \
  11.   gcc \
  12.   gfortran \
  13.   git \
  14.   less \
  15.   libtool \
  16.   make \
  17.   nano \
  18.   patch \
  19.   perl-open \
  20.   perl-FindBin \
  21.   pkg-config \
  22.   python3 \
  23.   unzip \
  24.   vim-common \
  25.   wget \
  26.   which \
  27.   xz \
  28.   zlib-devel
复制代码

在继续虚拟机内的操作前,还有几件 Windows 主机的可选事项:

成功部署 Rocky Linux 系统后可以安装软件了。

三、 LMod 的安装

该部分主要参考链接:

很多程序需在特定环境下读取环境变量运行,传统的编辑 ~/.bashrc 或 /etc/profile 修改环境的方式不便于实时切换、解决冲突,而 Environment Module 以模块化管理的思路解决该问题。此处采用基于 Lua 语言的 LMod 实现。安装 LMod 除了按其文档所说的编译,也可以直接用 dnf 安装:
  1. sudo dnf install -y Lmod
复制代码
安装完毕退出并重新启动虚拟机,运行下述指令检查安装情况,如能看到相关信息则安装成功:
  1. echo $LMOD_CMD
  2. echo $MODULEPATH
  3. module help
复制代码

目前 modulefiles 的目录 /etc/modulefiles 尚为空白,后续安装每个程序时再逐渐填充,一般是以程序名用 mkdir 创建目录、以版本号与环境命名 modulefile ,如以 GNU 14.3.1 编译器编译的 OpenMPI 4.1.8 会放在 /etc/modulefiles/openmpi 目录下并命名为 4.1.8-gnu14.3.1.lua 这样。若想在 /etc/modulefiles 之外增加放 modulefile 的目录,可以用 module use 添加其路径到识别范围,不过此处不需要。

四、OpenMPI 4.1.8与ORCA 6.1.1的安装
该部分主要参考链接:

本帖的写作动机之一,就是注意到上个月新发布的 Linux 版 ORCA 6.1.1 动态链接库要求用 OpenMPI 4.1.8 而不是 OpenMPI 5 这点。在等到 ORCA 更新得支持 OpenMPI 5 之前,旧版与新版 MPI 的共存与管理自然可以用 modulefiles 处理。

根据社长的博文,下载 openmpi-4.1.8.tar.bz2 并解压、配置、编译到 /opt/openmpi418 目录。在 /opt 目录下操作需用 sudo 权限,另外用 tee 备份输出到屏幕的信息方便出问题时检查(不过这里顺利完成了),所以实际使用的命令稍微长一点:
  1. sudo ./configure --prefix=/opt/openmpi418 2>&1 | sudo tee configuring.log
  2. sudo make all install 2>&1 | sudo tee making.log
复制代码

原始教程需要编辑 .bashrc 添加环境变量,但在用 modulefiles 管理环境时不用也不该这么做,而是写一个 modulefile 来设置。将下述文件保存为 /etc/modulefiles/openmpi 目录下的 4.1.8-gnu14.3.1.lua 文件:
  1. whatis("OpenMPI-4.1.8")
  2. family("mpi")
  3. help([[
  4. OpenMPI 4.1.8 built with GNU compilers (version 14.3.1)
  5. ]])

  6. prepend_path("PATH","/opt/openmpi418/bin" )
  7. prepend_path("LD_LIBRARY_PATH","/opt/openmpi418/lib")
  8. setenv("OMPI_ALLOW_RUN_AS_ROOT", "1")
  9. setenv("OMPI_ALLOW_RUN_AS_ROOT_CONFIRM", "1")
复制代码
其中 whatis() 是模块的名称,可以用 module whatis 指令看到; family() 是模块的类别名,设定类别后一次只能加载一个该类别的模块,避免了冲突; help([[]]) 是模块的提示信息,可以用 module help 看到;整个 modulefile 的内容可以用 module show 看到。路径类的环境变量,如 $PATH 和 $LD_LIBRARY_PATH 等,在基于 lua 语言的 modulefile 中是以 prepend_path() 添加的,默认照常以冒号 : 为分隔符、添加到变量的最前端以便优先调用;非路径类的环境变量,比如 OpenMPI 以 root 用户运行需要的 OMPI_ALLOW_RUN_AS_ROOT 等,以 setenv() 修改。在 module load 时这些修改自然生效,而在 module unload 时又会解除,一来一回不会涉及任何 .bashrc 之类 shell 脚本。

接着同样下载 orca_6_1_1_linux_x86-64_shared_openmpi418_avx2.tar.xz 并解压,然后写个 modulefile 保存为 /etc/modulefiles/orca 目录下的 6.1.1-openmpi4.1.8.lua 文件:
  1. whatis("ORCA-6.1.1")
  2. family("orca")
  3. help([[
  4. ORCA 6.1.1 dynamically linked against OpenMPI 4.1.8
  5. ]])

  6. load("openmpi/4.1.8-gnu14.3.1")
  7. prepend_path("PATH","/opt/orca_6_1_1_linux_x86-64_shared_openmpi418_avx2" )
  8. prepend_path("LD_LIBRARY_PATH","/opt/orca_6_1_1_linux_x86-64_shared_openmpi418_avx2")
  9. execute {cmd="alias orca6=$(which orca)", modeA={"load"}}
  10. execute {cmd="unalias orca6", modeA={"unload"}}
复制代码
这里 load() 函数要求无论之前是否加载有 openmpi/4.1.8-gnu14.3.1 模块,在加载 ORCA 6.1.1 的模块之前必先加载之。用完 ORCA 6.1.1 而卸载其模块时, OpenMPI 4.1.8 的模块也会一并卸载。最后两行的 execute {} 要求在完成所有变量设定后执行 shell 命令,此处在加载时用 alias 设定 orca6 为 which 查到的可执行文件的完整路径、卸载时用 unalias 取消之。

用 module avail 检查识别到的 modulefiles 可见上述文件均成功添加:
  1. module avail

  2. -------------------------------------------------- /etc/modulefiles ---------------------------------------------------
  3.    openmpi/4.1.8-gnu14.3.1    orca/6.1.1-openmpi4.1.8
  4. ...[omitted]
复制代码
并且加载模块后测试 ORCA 6.1.1 可见运行符合预期。

五、 Miniforge 的安装
该部分主要参考链接:

Miniforge 是一个面向 conda-forge 等开源频道的轻量包管理器,没有经典的 Anaconda 那样比较微妙的协议问题。此处以其为例展示已有 shell 脚本需要 source 时,用 LMod 自带工具转换为 lua 语法 modulefile 的方法。安装 Miniforge 需要去 github 库 https://github.com/conda-forge/miniforge 下载安装脚本,比如直接用 wget 或 curl 指令下载 Miniforge3-25.11.0-1-Linux-x86_64.sh 的操作:
  1. sudo wget "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
  2. sha256sum Miniforge3-25.11.0-1-$(uname)-$(uname -m).sh
复制代码
其中 $(uname) 返回字符串 Linux 代表系统, $(uname -m) 返回 x86_64 代表 CPU 架构。下载后 sha256sum 的结果与发行页面给出的 sha256 匹配,说明文件完整正确。然后以 batch mode 安装,用 -p 选项把安装路径从对 twilight 来说默认的 /home/twilight/miniforge3 改成 /opt/miniforge3 ,完整的帮助可用 -h 选项查看:
  1. sudo bash Miniforge3-25.11.0-1-$(uname)-$(uname -m).sh -b -p /opt/miniforge3
复制代码
如果根据 Miniforge 原始的教程,使用前需要 source 的 shell 脚本在安装路径下的 /etc/profile.d 里,用 less 翻阅可见它们比较长:
  1. less /opt/miniforge3/etc/profile.d/conda.sh
  2. less /opt/miniforge3/etc/profile.d/mamba.sh
复制代码
(此处 less 是一个分页阅读文件的工具,非常适合代替 cat 或 vi 的查看功能。)用 LMod 的 sh_to_modulefile 工具处理之:
  1. $LMOD_DIR/sh_to_modulefile /opt/miniforge3/etc/profile.d/conda.sh
复制代码
转换产生的 setenv(), prepend_path(), set_shell_function() 等即输出到屏幕了。为了实际产生 modulefile 并添加帮助信息,需要重定向输出到文件,其中利用了 lua 语法以 -- 标记注释、 printf 需要 -- 把剩余内容原样传入避免被当成选项的特性:
  1. printf "whatis(%s)\n" ""Miniforge3-25.11.0-1"" > 25.11.0-1.lua
  2. printf "family(%s)\n" ""conda"" >> 25.11.0-1.lua
  3. printf "help([[\n%s\n%s\n%s\n]])\n\n" \
  4. "Modulefile converted by sh_to_modulefile from the following scripts:" \
  5. "/opt/miniforge3/etc/profile.d/conda.sh" \
  6. "/opt/miniforge3/etc/profile.d/mamba.sh" >> 25.11.0-1.lua
  7. printf -- "-- start of section for conda --\n" >> 25.11.0-1.lua
  8. $LMOD_DIR/sh_to_modulefile /opt/miniforge3/etc/profile.d/conda.sh >> 25.11.0-1.lua
  9. printf -- "-- end of section for conda --\n\n" >> 25.11.0-1.lua
  10. printf -- "-- start of section for mamba --\n" >> 25.11.0-1.lua
  11. $LMOD_DIR/sh_to_modulefile /opt/miniforge3/etc/profile.d/mamba.sh >> 25.11.0-1.lua
  12. printf -- "-- end of section for mamba --\n" >> 25.11.0-1.lua
复制代码
所得的文件大概长这样:
  1. whatis("Miniforge3-25.11.0-1")
  2. family("conda")
  3. help([[
  4. Modulefile converted by sh_to_modulefile from the following scripts:
  5. /opt/miniforge3/etc/profile.d/conda.sh
  6. /opt/miniforge3/etc/profile.d/mamba.sh
  7. ]])

  8. -- start of section for conda --
  9. setenv("CONDA_EXE","/opt/miniforge3/bin/conda")
  10. setenv("CONDA_PYTHON_EXE","/opt/miniforge3/bin/python")
  11. ...
  12. -- end of section for conda --

  13. ...
复制代码
把这个 25.11.0-1.lua 移入 /etc/modulefiles/miniforge3 就完成了。这个 modulefile 只管加载或卸载 miniforge3 本身,至于 miniforge3 里的环境,当然得在加载模块后管理。

五、小结
以上就是从 WSL2 虚拟机与 Rocky Linux 10 系统的部署到 LMod 管理依赖的介绍。养成用 module 管理环境的习惯后,处理 GNU 编译器和 Intel 编译器的抉择、为适应某些老代码而有意降低编译器版本等问题会更轻松。未来可以挑战把 CP2K 2026.1 的工具链做成 modulefiles 形式,以让其中的 OpenMPI 5 能与 ORCA 6.1.1 用的 OpenMPI 4.1.8 共存,预计 setup 文件拆分与 modulefile 编写会比较复杂。


作者
Author:
Daniel_Arndt    时间: 6 day ago
我一般不用C:\Users\{username}\.wslconfig,而是通过WSL里面/etc/wsl.conf文件来设置一些东西。
作者
Author:
Uus/pMeC6H4-/キ    时间: 5 day ago
本帖最后由 Uus/pMeC6H4-/キ 于 2026-1-23 00:58 编辑

尝试给本帖部署的 Rocky Linux 10 系统安装 GaussView 6.1.1 (与我之前在另一帖用的压缩包一致)时仍可能遇到缺少依赖库的问题,然而 dnf install 装了一大堆新的包试图补齐依赖库的话,所有文字均显示为实心方块,颇有看机密文件的风格……
(, 下载次数 Times of downloads: 0)

复制粘贴文字下来看倒是正常的,估计还是某个和 Qt 引擎或字体渲染相关的显示问题。export QT_GRAPHICSSYSTEM="native"不能解决,gv -debug或先export QT_DEBUG_PLUGINS=1再启动gv也无法在命令行输出中找到故障的相关线索。

编辑:该问题已解决,问题并不出在缺库上,也不是调 GaussView Preferences 里 Display format 或者 Font 能解决的,而是和字体文件有关。

ProFont 网站下载了 ProFont ttf tweaked 的压缩包,解压并提取出其中的 .ttf 文件,以 root 用户移到 /usr/share/fonts 目录下,再按这页 Red Hat 文档以 root 用户运行 fc-cache -f /usr/share/fonts 命令,然后 GaussView 就能显示字体了。但 Preferences 里的 Font 默认用的还是 Sans Serif 而非 ProFont ,所以我不确定上面涉及补充文件的步骤是不是最简单的解决方法,有少许可能运行 fc-cache 才是关键。把字号调到16以后看着还可以。

(, 下载次数 Times of downloads: 0)

作者
Author:
Uus/pMeC6H4-/キ    时间: 5 hour ago
好奇一下,最近几天这帖的浏览量增加得出乎意料地快,是有谁在其他地方转了个指向这帖的链接吗?

有关 Gaussian/GaussView 再说一点,比如装到 /opt 下平时配备环境的习惯大概会编辑 ~/.bashrc 添加这样的指令
  1. export g16root=/opt
  2. export GAUSS_SCRDIR=/opt/g16/scratch
  3. export GAUSS_MEMDEF=25600MB
  4. source /opt/g16/bsd/g16.profile
复制代码
其中最后一行 source 的 g16.profile 文件也是一个 shell 脚本。但在写 modulefile 用 LMod 做版本管理时不能简单改成 modulefile 里的 execute {cmd="source /opt/g16/bsd/g16.profile", modeA={"load"}} 指令,因为这样加载完再卸载会残留设置;实测用上面提到的 sh_to_modulefile 外部工具或者 modulefile 里的 source_sh 指令都会报错。这种情况下,有必要 less /opt/g16/bsd/g16.profile 查看文件,综合考虑所有设置对环境变量的影响,再自行翻译成 lua 语法的 modulefile 指令。

比如,看到 g16.profile 前面几行是这样的
  1. gr=$HOME
  2. if [ "$g16root" ]
  3.   then gr=$g16root
  4.   fi
  5. export GAUSS_EXEDIR="$gr/g16/bsd:$gr/g16"
  6. ...
复制代码
那么对应的 modulefile 里,包括上面几个设置的语句为
  1. local gr = "/opt"
  2. setenv("g16root", gr)
  3. setenv("GAUSS_SCRDIR", pathJoin(gr, "g16/scratch"))
  4. setenv("GAUSS_MEMDEF", "25600MB")
  5. local gauss_exedir = pathJoin(gr, "g16/bsd") .. ":" .. pathJoin(gr, "g16")
  6. setenv("GAUSS_EXEDIR", gauss_exedir)
  7. ...
复制代码
此处利用了 lua 语法中定义局部字符串变量和用 .. 表示 concatenation 的特性,以及 LMod 的 pathJoin 函数拼凑路径。

又比如, g16.profile 里有这样的分支语句
  1. if [ "$PATH" ]; then
  2.   export PATH="$PATH:$gr/gauopen:$GAUSS_EXEDIR"
  3. else
  4.   export PATH="$gr/gauopen:$GAUSS_EXEDIR"
  5.   fi
复制代码
显然这就是添加 PATH 的过程,在 LMod 里只需要一行
  1. append_path("PATH", pathJoin(gr, "gauopen") .. ":" .. gauss_exedir)
复制代码

特别注意,append_path 把新的路径加到变量末尾, prepend_path 把新的路径加到变量前头,在执行程序从 $PATH 搜索路径时是从前到后找、优先按前面找到的用,所以必须结合新路径的优先度考虑该用哪个。对于 WSL 的虚拟机而言,由于 $PATH 末尾包含了 Windows 系统的路径,所以应当改用 prepend_path 的写法。
  1. prepend_path("PATH", pathJoin(gr, "gauopen") .. ":" .. gauss_exedir)
复制代码






欢迎光临 计算化学公社 (http://bbs.keinsci.com/) Powered by Discuz! X3.3