我需要将python作业提交到服务器。在运行时,我需要在运行时加载和卸载模块,因为它调用了多个程序,每个程序具有不同的依赖项,即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
但是,当我从终端执行“模块列表”时,模块尚未切换。 gcc/5.4.0
仍在加载。另外,要求intel/2016.4
的程序无法运行。例如,稍后,我希望能够使用需要intel/2016.4
且无法运行的gromacs版本。
我有点困惑,因为我认为我可以通过Popen使用bash命令,而“模块加载”是bash命令。我不想编写bash脚本来执行此操作,在脚本中使用python比bash更方便地完成了很多其他事情。
答案 0 :(得分:2)
大多数环境模块实现都有一个非常方便的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('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
答案 1 :(得分:1)
我最近遇到了这个问题。解决此问题的一种简单方法是在所需命令之前包含依赖项,并用分号分隔它们
cmd = 'module load intel/2016.4; "gromacs command"'
p = sub.Popen(cmd, shell=True, stderr = sub.STDOUT, stdout = sub.PIPE).communicate()[0]
其中,“ gromacs命令”表示您通常将其称为gromacs。
intel/2016.4
不会在模块列表中显示为已加载,如果您在运行脚本后进行检查,但是gromacs将使用您想要的intel/2016.4
从python脚本内部运行。