使用OpenMP拆分LAPACK调用

使用OpenMP拆分LAPACK调用,openmp,lapack,Openmp,Lapack,我正在编写一个代码调优例程,其中一部分执行两个矩阵乘法,可以同时执行。目前,我在第一个DGEMM上调用DGEMM(来自英特尔的MKL库),然后在第二个DGEMM上调用。每次调用都会使用我机器上的所有12个内核。我希望它同时执行两个DGEMM例程,每个都使用6个内核。我觉得这是一件简单的事情,但我无法找到/理解如何实现这一点。我遇到的主要问题是OpenMP必须从一个线程调用DGEMM例程,但每次调用都可以使用6。哪个指令最适合这种情况?它需要嵌套的pragma吗 因此,作为一个更一般的说明,我如何

我正在编写一个代码调优例程,其中一部分执行两个矩阵乘法,可以同时执行。目前,我在第一个DGEMM上调用DGEMM(来自英特尔的MKL库),然后在第二个DGEMM上调用。每次调用都会使用我机器上的所有12个内核。我希望它同时执行两个DGEMM例程,每个都使用6个内核。我觉得这是一件简单的事情,但我无法找到/理解如何实现这一点。我遇到的主要问题是OpenMP必须从一个线程调用DGEMM例程,但每次调用都可以使用6。哪个指令最适合这种情况?它需要嵌套的pragma吗

因此,作为一个更一般的说明,我如何将(在我的例子中是12个)内核划分为多个集合,然后从一个使用集合中所有线程的线程运行例程


谢谢

您可以做的最接近的事情是让一个OpenMP并行区域与一个由两个线程组成的团队一起执行,然后从每个线程调用MKL。您必须在MKL中启用嵌套并行(通过禁用动态线程),将MKL线程数固定为6,并且必须使用英特尔编译器套件编译代码。MKL本身是使用OpenMP线程化的,但它是Intel的OpenMP运行时。如果您碰巧使用了另一个编译器,例如GCC,其OpenMP运行时可能与Intel的不兼容

由于您没有指定语言,我提供了两个示例—一个是Fortran语言,另一个是C/C++:

Fortran:

call mkl_set_num_threads(6)
call mkl_set_dynamic(0)

!$omp parallel sections num_threads(2)
!$omp section
   call dgemm(...)
!$omp end section
!$omp section
   call dgemm(...)
!$omp end section
!$omp end parallel sections
C/C++:

mkl_set_num_threads(6);
mkl_set_dynamic(0);

#pragma omp parallel sections num_threads(2)
{
    #pragma omp section
    {
        cblas_dgemm(...)
    }
    #pragma omp section
    {
        cblas_dgemm(...)
    }
}
一般来说,您不能为MKL创建线程子集(至少根据我目前的理解)。每个DGEMM调用将使用全局指定数量的MKL线程。请注意,MKL操作可能会针对CPU的缓存大小进行调整,并行执行两个矩阵乘法可能没有好处。如果您有一个NUMA系统,它有两个六核CPU,每个CPU都有自己的内存控制器(我怀疑这是您的情况),那么您可能会这样做,但您必须注意数据的放置位置,并且还必须启用线程到核心的绑定(固定)