从我的 python 脚本在集群上加载环境模块
Loading environment modules on a cluster from my python script
我需要向服务器提交 python 作业。虽然它是 运行ning,但我需要在它 运行 时加载和卸载模块,因为它调用了多个程序,每个程序都有不同的依赖项,这些依赖项会发生冲突,即 gcc 与 intel。
之前有人问过这个问题,但在这种情况下答案对我不起作用
Loading environment modules within a python script
loading-environment-modules-within-a-python-script
我试过使用以下
import subprocess as sub
cmd = 'module load intel/2016.4'
p = sub.Popen(cmd, shell=True, stderr = sub.STDOUT, stdout = sub.PIPE).communicate()[0]
print(p.decode()) # this simply outputs to screen
并且,输出显示模块已切换。
Lmod is automatically replacing "gcc/5.4.0" with "intel/2016.4".
Due to MODULEPATH changes, the following have been reloaded:
1) openmpi/2.1.1
但是,当我从终端执行 'module list' 时,模块没有切换。 gcc/5.4.0
仍在加载中。此外,需要 intel/2016.4
的程序无法 运行。例如,稍后我希望能够使用需要 intel/2016.4
的 gromacs 版本,但它失败了。
我有点困惑,因为我认为我可以通过 Popen 使用 bash 命令,而 'module load' 是一个 bash 命令。我不想编写 bash 脚本来执行此操作,在我的脚本中还有很多其他事情用 python 比 bash 更方便。
我最近 运行 喜欢这个。一个简单的解决方法是在你想要的命令之前包含依赖项,并用分号分隔它们
cmd = 'module load intel/2016.4; "gromacs command"'
p = sub.Popen(cmd, shell=True, stderr = sub.STDOUT, stdout = sub.PIPE).communicate()[0]
其中 "gromacs command" 表示您通常会调用 gromacs。
intel/2016.4
不会在模块列表中显示为已加载,如果您在 运行 脚本之后检查,但 gromacs 将 运行 从您的 python 脚本中使用 intel/2016.4
,这就是你想要的。
大多数环境模块实现都有一个非常方便的 Python 初始化脚本。对于 lmod
,它在 $LMOD_DIR/../init
中并命名为 env_modules_python.py
。所以你可以这样做:
$ export PYTHONPATH=${PYTHONPATH}:$LMOD_DIR/../init
$ python
Python 2.7.5 (default, Jul 13 2018, 13:06:57)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from env_modules_python import module
然后您可以从那里直接在 Python 中 运行 任何 'module' 命令。
>>> module('list')
Currently Loaded Modules:
[...]
3) StdEnv (H)
4) GCCcore/6.4.0 (H)
5) binutils/2.28-GCCcore-6.4.0 (H)
[...]
它将修改 Python 脚本的环境,并且该环境将传播到子 shell。
>>> import os
>>> os.system("which icc")
which: no icc in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin)
256
>>> module("load intel")
>>> os.system("which icc")
/opt/[...]/icc/2017.4.196-GCC-6.4.0-2.28/compilers_and_libraries_2017.4.196/linux/bin/intel64/icc
0
它与 Popen
相同:
>>> import subprocess as sub
>>> cmd='which icc'
>>> p = sub.Popen(cmd, shell=True, stderr = sub.STDOUT, stdout = sub.PIPE).communicate()[0]
>>> print(p.decode())
/opt/[...]icc/2017.4.196-GCC-6.4.0-2.28/compilers_and_libraries_2017.4.196/linux/bin/intel64/icc
我需要向服务器提交 python 作业。虽然它是 运行ning,但我需要在它 运行 时加载和卸载模块,因为它调用了多个程序,每个程序都有不同的依赖项,这些依赖项会发生冲突,即 gcc 与 intel。
之前有人问过这个问题,但在这种情况下答案对我不起作用
Loading environment modules within a python script
loading-environment-modules-within-a-python-script
我试过使用以下
import subprocess as sub
cmd = 'module load intel/2016.4'
p = sub.Popen(cmd, shell=True, stderr = sub.STDOUT, stdout = sub.PIPE).communicate()[0]
print(p.decode()) # this simply outputs to screen
并且,输出显示模块已切换。
Lmod is automatically replacing "gcc/5.4.0" with "intel/2016.4".
Due to MODULEPATH changes, the following have been reloaded:
1) openmpi/2.1.1
但是,当我从终端执行 'module list' 时,模块没有切换。 gcc/5.4.0
仍在加载中。此外,需要 intel/2016.4
的程序无法 运行。例如,稍后我希望能够使用需要 intel/2016.4
的 gromacs 版本,但它失败了。
我有点困惑,因为我认为我可以通过 Popen 使用 bash 命令,而 'module load' 是一个 bash 命令。我不想编写 bash 脚本来执行此操作,在我的脚本中还有很多其他事情用 python 比 bash 更方便。
我最近 运行 喜欢这个。一个简单的解决方法是在你想要的命令之前包含依赖项,并用分号分隔它们
cmd = 'module load intel/2016.4; "gromacs command"'
p = sub.Popen(cmd, shell=True, stderr = sub.STDOUT, stdout = sub.PIPE).communicate()[0]
其中 "gromacs command" 表示您通常会调用 gromacs。
intel/2016.4
不会在模块列表中显示为已加载,如果您在 运行 脚本之后检查,但 gromacs 将 运行 从您的 python 脚本中使用 intel/2016.4
,这就是你想要的。
大多数环境模块实现都有一个非常方便的 Python 初始化脚本。对于 lmod
,它在 $LMOD_DIR/../init
中并命名为 env_modules_python.py
。所以你可以这样做:
$ export PYTHONPATH=${PYTHONPATH}:$LMOD_DIR/../init
$ python
Python 2.7.5 (default, Jul 13 2018, 13:06:57)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from env_modules_python import module
然后您可以从那里直接在 Python 中 运行 任何 'module' 命令。
>>> module('list')
Currently Loaded Modules:
[...]
3) StdEnv (H)
4) GCCcore/6.4.0 (H)
5) binutils/2.28-GCCcore-6.4.0 (H)
[...]
它将修改 Python 脚本的环境,并且该环境将传播到子 shell。
>>> import os
>>> os.system("which icc")
which: no icc in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin)
256
>>> module("load intel")
>>> os.system("which icc")
/opt/[...]/icc/2017.4.196-GCC-6.4.0-2.28/compilers_and_libraries_2017.4.196/linux/bin/intel64/icc
0
它与 Popen
相同:
>>> import subprocess as sub
>>> cmd='which icc'
>>> p = sub.Popen(cmd, shell=True, stderr = sub.STDOUT, stdout = sub.PIPE).communicate()[0]
>>> print(p.decode())
/opt/[...]icc/2017.4.196-GCC-6.4.0-2.28/compilers_and_libraries_2017.4.196/linux/bin/intel64/icc