Python中库函数(用Fortran编写)可用的线程数是多少?

2024-10-05 10:07:11 发布

您现在位置:Python中文网/ 问答频道 /正文

问题摘要: 自定义Python库PYFEAST(https://github.com/empter/PYFEAST)是一个库,允许用户调用Fortran FEAST库(https://arxiv.org/pdf/2002.04807.pdf),它可以有效地解决大规模矩阵上的特征值和特征向量问题。在GitHub上可用的配置中,假定FEAST是使用Intel MKL库编译的,因此在PYFEAST的setup.py文件(https://github.com/empter/PYFEAST/blob/master/cython_feast/setup.py)中,额外的链接参数包括各种Intel MKL库。这是一个问题,因为英特尔MKL(https://en.wikipedia.org/wiki/Math_Kernel_Library)内置了跛行AMD功能,由于英特尔在最新版本中删除了某些调试命令,因此无法再轻易绕过该功能。我的目标是通过使用LAPACK和BLAS或OpenBLAS库,重新编写FEAT的编译命令,并修改PYFEAST setup.py文件,使其与处理器无关。这是可行的,但是PYFEAST setup.py文件生成的FEAST Python库没有并行化,因此在处理大型数组时运行速度慢得令人无法接受。如果可能的话,我想知道我需要在compile/make命令以及setup.py文件中更改什么,以使最终的Python库以最大可用线程数运行。我知道这是可能的,因为当Jupyter Notebook调用SciPy eigensolver时,SciPy eigensolver.linalg会自动并行到系统可用的最大线程数。此外,根据PyFeat的作者,使用Intel MKL制作的版本在从Jupyter笔记本调用时也会自动并行到系统上可用的最大线程数

迄今为止采取的步骤: 为了在不使用Intel MKL的情况下编译FEAST(文档中未提供示例,请参见https://arxiv.org/pdf/2002.04807.pdf的第6页),我需要使用以下命令:

make F90=gfortran MPI=mpich MKL=no feast

此命令(在带有FEAST makefile的目录中运行时)创建FEAST库libfeast.a,并且当feast参数替换为pfeast时,还可以创建库libpfeast.a。正如您在上面的命令中所看到的,我使用MPICH进行并行化,使用gfortran作为FORTRAN编译器

接下来,我编译Python库。然而,为了在没有“英特尔MKL”的情况下做到这一点,我再次需要对代码进行一些修改。对ext_modules=[Extension(...)]的这些修改如下:(使用OpenBLAS)

Extension("feast",
              sources=["feast.pyx"],
              include_dirs=[numpy.get_include(),"../../../FEAST/FEAST/4.0/include"],
              library_dirs=["../../../FEAST/FEAST/4.0/lib/x64","../../../../../usr/lib/x86_64-linux-gnu"],
              libraries=["feast","openblas"],
              extra_link_args=['-lopenblas','-lgomp','-lpthread','-lm','-ldl','-lgfortran'],
              extra_compile_args=['-lopenblas','-lgomp','-lpthread','-lm','-ldl'],
              extra_objects=['../../../../../usr/lib/x86_64-linux-gnu/libopenblas.a']
              )

有关目录库引用的更改是由于我的FEAST版本与PYFEAST作者的安装方式不同。要准确理解我所更改的内容,请参阅原始代码here。我还添加了参数extra_compile_args=[...]extra_objects=[...],出于某种原因,为了让PYFEAST在没有英特尔MKL库的情况下工作,这些参数是必需的(请解释原因)。在完成所有这些并运行命令python3 setup.py build_ext install之后,我成功地生成了与python兼容的程序库。请注意,我没有对feast.pyx进行任何更改,它是setup.py文件构建库feast.pyx file source code的Cython文件

在编译完库之后,我开始在Jupyter笔记本上测试它。首先,我复制了FEAST用户指南中helloworld.f90示例中的数组,然后使用python命令运行FEAST特征解算器

obj=feast.HSolver(S,M0=4,Em=0.1,Ex=5.0,which=0)
obj.setfpm(cp=16,eps=14,ml=3,it=1)

这工作做得很好然而,当我试图找到更大矩阵的特征值时,结果发现FEAST函数只在一个线程上运行 我不清楚为什么会发生这种情况。尽管在处理稀疏矩阵时,FEAST代码存在一些问题(请参见第7 FEAST User Guide页顶部),但我认为这些问题不应阻止在没有英特尔MKL的情况下编译的FEAST库的并行化。根据作者的说法,当从Jupyter笔记本调用时,Intel MKL版本会自动并行到所有可用线程,就像scipy.linalg!我试过fJupyter Notebook中用于设置OpenBLAS或mpich线程数的以下命令:(这些命令都没有改变FEAST函数在调用时的执行方式)

  • os.environ["OMP_NUM_THREADS"]=12
  • os.environ["OPENBLAS_NUM_THREADS"]=12
  • !export OMP_NUM_THREADS=12
  • !export OPENBLAS_NUM_THREADS=12

结论:我不知道为什么我的PYFEAST版本在调用时没有并行化,它避免了使用Intel MKL。我知道其他使用LAPACK和BLAS(如scipy.linalg)的特征解算器程序在从Jupyter笔记本调用时会自动并行,我想知道为什么以及如何重现这种行为。我编写FEAST或PYFEAST的方式有问题吗?请让我知道你的想法。在这一点上,我只是想让这项工作,只是为了给英特尔一个隐喻性的中指。谢谢你的帮助


Tags: 文件pyhttps命令版本setup情况jupyter

热门问题