我正在开发一个项目,需要使用Clang将OpenMP卸载到Nvidia GPU。我可以按照here提到的说明安装Clang来支持卸载。
系统规范
但问题是当我执行一个示例程序来测试OpenMP到Nvidia GPU时,目标区域的一部分往往在GPU中运行,然后同一目标区域开始在主机中执行。
请在此处找到示例程序,这是一个小的C程序,用于乘以2个矩阵。
#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);
}
该程序使用
编写clang -fopenmp -fopenmp-targets=nvptx64-nvidia-cuda 3mm.c -o 3mmgpu
声称目标区域在主机和目标设备中都在执行的主要原因是由于命令行的输出。
首先,团队0和团队1显示每个团队960个,后来的迭代为每个团队提供2个线程(我的处理器是4个核心处理器,每个核心能够处理2个硬件级别线程。)。
我还尝试用nvprof执行fat二进制文件,以验证GPU中是否正在执行任何操作。
分析结果如下。
实际上我无法理解目标区域发生的事情。为什么目标区域正在主机和目标设备中执行。
答案 0 :(得分:1)
我发布了问题的答案,因为我终于能够弄清楚代码中出了什么问题。问题是目标设备崩溃中的卸载区域,因为我错误地将数据映射到GPU。我只映射了指针而没有在GPU中分配内存。因此,当GPU执行崩溃时,执行将在主机中发生。
感谢@Alexey Bataev指出这一点。