我正在尝试使用OpenMP卸载为Nvidia GPU编译一个简单的测试问题。我使用gcc和nvptx-none目标。我已经用spack安装了gcc+nvptx包(或者我自己用nvptx-tools编译了gcc-13,结果是一样的)。在链接过程中,我得到错误:
unresolved symbol _fputwc_r
collect2: error: ld returned 1 exit status
mkoffload: fatal error: x86_64-pc-linux-gnu-accel-nvptx-none-gcc returned 1 exit status
compilation terminated.
lto-wrapper: fatal error: /path/to/spack/opt/spack/linux-centos8-x86_64_v3/gcc-13.0.0/gcc-12.2.0-6olbpwbs53cquwnpsvrmuxprmaofwjtk/libexec/gcc/x86_64-pc-linux-gnu/12.2.0//accel/nvptx-none/mkoffload returned 1 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
使用-fno-stack-protector
编译,如推荐的here或here,并不能缓解这个问题。-fno-lto
可以,但卸载不起作用。不同的优化标志没有区别。
使用的ld
看起来是系统安装。spack安装在spack/linux-centos8-x86_64_v3/gcc-13.0.0/gcc-12.2.0-6olbpwbs53cquwnpsvrmuxprmaofwjtk/nvptx-none
中提供了另一个ld,但spack通常不会将其添加到PATH中。我猜这是有原因的,因为包含它会导致
as: unrecognized option '--64'
nvptx-as: missing .version directive at start of file '/tmp/cc9YfveM.s'``
这是链接器的问题,还是其他问题?问题只发生在实际包含并行for循环时,只是设置#pragma omp target
不会。设备实际上被识别,并且根据OpenMP在设备上运行此杂注中的代码,只要不存在并行区域,就会产生上述错误。
其他信息:系统是Rocky Linux release 8.7 (Green Obsidian)
我执行的测试程序是基于OpenMP测试程序。它的完整代码是:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
void saxpy(float a, float* x, float* y, int sz) {
#pragma omp target teams distribute parallel for simd \
num_teams(3) map(to:x[0:sz]) map(tofrom:y[0:sz])
for (int i = 0; i < sz; i++) {
if (omp_is_initial_device()) {
printf("Running on host\n");
} else {
int nthreads= omp_get_num_threads();
int nteams= omp_get_num_teams();
printf("Running on device with %d teams (fixed) in total and %d threads in each team\n",nteams,nthreads);
}
fprintf(stdout, "Thread %d %i\n", omp_get_thread_num(), i );
y[i] = a * x[i] + y[i];
}
}
int main(int argc, char** argv) {
float a = 2.0;
int sz = 16;
float *x = calloc( sz, sizeof *x );
float *y = calloc( sz, sizeof *y );
//Set values
int num_devices = omp_get_num_devices();
printf("Number of available devices %d\n", num_devices);
saxpy( a, x, y, sz );
return 0;
}
我试着用
gcc -O0 -fopenmp -foffload=nvptx-none -o mintest mintest.c
或者具有上述标志。
1条答案
按热度按时间xlpyo6sf1#
我猜问题是GCC无法处理GPU上运行的代码区域内的
printf
。GPU通常不擅长任何形式的I/O发生,因此您应该避免在卸载的代码区域内调用printf
,read
,write
等。如果你想检测代码是在GPU设备上还是在主机上运行,那么你可以使用这样的模式:
代码的作用是:
target
)master
),并在那里使用并行区域map(from:on_device)
返回测试结果