从Python和环境变量调用OpenMP C库

从Python和环境变量调用OpenMP C库,python,c,openmp,ctypes,Python,C,Openmp,Ctypes,我想从Python调用一些OpenMP程序,更改线程的数量(OMP\u NUM\u threads)及其绑定(OMP\u PLACES,OMP\u PROC\u BIND)。我写了这个程序: import os from ctypes import cdll lib = cdll.LoadLibrary("/home/fayard/Desktop/libf.so") nb_socket = 2 nb_core_per_socket = 14 nb_thread_per_core = 2 n

我想从Python调用一些OpenMP程序,更改线程的数量(
OMP\u NUM\u threads
)及其绑定(
OMP\u PLACES
OMP\u PROC\u BIND
)。我写了这个程序:

import os
from ctypes import cdll

lib = cdll.LoadLibrary("/home/fayard/Desktop/libf.so")

nb_socket = 2
nb_core_per_socket = 14
nb_thread_per_core = 2

n = nb_socket * nb_core_per_socket * nb_thread_per_core

for nb_thread in range(1, n + 1):
    os.environ['OMP_NUM_THREADS'] = str(nb_thread)
    print("nb_thread: {}, omp_get_num_threads: {}".format(
        nb_thread, lib.num_threads()))
OpenMP库如下所示:

#include <omp.h>

extern "C" {

int num_threads() {
  int ans;
#pragma omp parallel
  {
#pragma omp single
    ans = omp_get_num_threads();
  }

  return ans;
}

}
当我运行
python program.py
时,我得到:

nb_thread: 1, omp_get_num_threads: 56
...
nb_thread: 56, omp_get_num_threads: 56
这不是我想要的!我还意识到,当使用具有完全相同参数的英特尔编译器编译时,我得到:

nb_thread: 1, omp_get_num_threads: 1
...
nb_thread: 56, omp_get_num_threads: 1

有什么想法吗?

环境变量只控制内部控制变量的初始设置

[OpenMP 4.5]4。环境变量

程序启动后对环境变量的修改,即使是由程序本身修改,也会被OpenMP实现忽略。但是,在执行OpenMP程序期间,可以使用适当的指令子句或OpenMP API例程修改某些ICV的设置

您可以围绕
omp\u set\u num\u threads
编写一个小包装器,但是不能动态更改绑定

不幸的是,没有清洁的解决方案。另一种方法是使用
子流程运行实际的程序,而不是加载库,但这样您就有了一个不同的接口

如果必须使用共享库并控制动态绑定,则可以在python调用的共享库中手动使用
sched_setaffinity


gcc和intel运行时行为不同的原因可能是因为您在加载库后设置了环境变量,并且它们的初始化方式不同。

谢谢。我想,我必须启动一个程序,并从文本文件中获取结果。
nb_thread: 1, omp_get_num_threads: 1
...
nb_thread: 56, omp_get_num_threads: 1