Cuda 在主机和目标设备中执行的OpenMP卸载目标区域

Cuda 在主机和目标设备中执行的OpenMP卸载目标区域,cuda,clang,openmp,nvidia,offloading,Cuda,Clang,Openmp,Nvidia,Offloading,我正在从事一个项目,该项目需要使用Clang将OpenMP卸载到Nvidia GPU。我能够按照上面提到的说明安装Clang以支持卸载 系统规范 操作系统-Ubuntu 16.04 LTS 叮当声-版本4.00 处理器-英特尔(R)核心(TM)i7-4700MQ CPU Cuda-版本-9.0 英伟达GPU-GeForce 740M(sm_能力-35) 但问题是,当我执行一个示例程序来测试OpenMP到Nvidia GPU时,部分目标区域倾向于在GPU中运行,然后相同的目标区域开始在主机中执

我正在从事一个项目,该项目需要使用Clang将OpenMP卸载到Nvidia GPU。我能够按照上面提到的说明安装Clang以支持卸载

系统规范

  • 操作系统-Ubuntu 16.04 LTS
  • 叮当声-版本4.00
  • 处理器-英特尔(R)核心(TM)i7-4700MQ CPU
  • Cuda-版本-9.0
  • 英伟达GPU-GeForce 740M(sm_能力-35)
但问题是,当我执行一个示例程序来测试OpenMP到Nvidia GPU时,部分目标区域倾向于在GPU中运行,然后相同的目标区域开始在主机中执行

请在这里找到示例程序,这是一个写为2个矩阵相乘的小C程序

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>

/* Problem size. */
# define N 1920

void init_array(float* A, float* B)
{
    int i, j;
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            A[i*N + j] = ((float) i*j) / N;
        }
    }

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            B[i*N + j] = ((float) i*(j+1)) / N;
        }
    }
}
void  mm_kernel(float *A, float *B, float *E)
{

    #pragma omp target data map(to:A) map(to:B) map(alloc:E)
{
    #pragma omp target
    #pragma omp teams distribute num_teams(4)
        for (int i = 0; i < N; i++)
  {
        printf("Team %d Thread %d Number of threads %d \n", omp_get_team_num() ,omp_get_thread_num(),omp_get_num_threads());
        #pragma omp  parallel for
        for (int j = 0; j < N; j++)
    {
            E[i*N + j] = 0.0;
            for(int k = 0; k < N; k++)
            {
                E[i*N + j] = E[i*N + j] + A[i*N + k] * B[j*N+k];
            }
    }
    }
  }
    }

int main(){
  double t_start, t_end;

    float* A;
    float* B;
    float* E;

    A = (float*)malloc(N*N*sizeof(float));
    B = (float*)malloc(N*N*sizeof(float));
    E = (float*)malloc(N*N*sizeof(float));
    init_array(A, B); //initialize Matrix A and B

    t_start = omp_get_wtime();
    mm_kernel(A,B,E);
    t_end = omp_get_wtime();

    printf("Time spent %lf\n",t_end-t_start );
    free(A);
    free(B);
    free(E);
}
声称目标区域同时在主机和目标设备中执行的主要原因是来自命令行的输出

在第一个团队0和团队1中,每个团队显示960个线程,随后的迭代为每个团队提供2个线程(我的处理器是4核处理器,每个核心能够处理2个硬件级线程)

我还尝试使用nvprof执行fat二进制文件,以验证GPU中是否正在执行任何操作

分析结果如下


事实上,我无法理解目标地区正在发生什么。为什么在主机和目标设备中都执行目标区域。

我发布了问题的答案,因为我终于能够找出代码中的错误。问题是目标设备崩溃中的卸载区域,因为我错误地将数据映射到GPU。我只映射了指针,没有在GPU中分配内存。因此,当GPU执行崩溃时,执行在主机中发生


谢谢@Alexey Bataev指出这一点。

请不要发布屏幕截图而不是文本复制粘贴。我还没有设法让Clang ykt编译。我试过Ubuntu 17.10,但它说它不支持GCC6或更多。然后我尝试了使用Ubuntu16.04的VitualBox,结果出现了不同的错误。我在这上面花了太多时间。你是如何建立它的?@Zboson我跟踪了这些链接,然后。除了链接1中给出的cmake构建选项外,还可能需要额外的构建选项来指定链接2中提到的GCC和G++路径。默认情况下,如果不指定目标,它将生成所有内置目标。在这种情况下,您可以使用-DLLVM_TARGETS_TO_BUILD自定义您的目标。请注意,此行为将被更改。如果卸载成功,但执行失败,我们要做的是停止应用程序的执行。只有卸载尝试未成功时,才能执行主机代码(!)
clang -fopenmp -fopenmp-targets=nvptx64-nvidia-cuda 3mm.c -o 3mmgpu