问题
我正在尝试使用OpenACC和cuRAND库生成随机数。我有一段简单的代码(只是尝试一些事情),基本上是pgi cuRAND示例(/ opt / pgi / linux86-64 / 2018 / examples / CUDA-Libraries / cuRAND)的副本。
问题是我遇到错误:undefined reference to ``__pgicudalib_curandInitXORWOW'
和undefined reference to ``__pgicudalib_curandUniformXORWOW'
。
这些在openacc_curand.h文件中声明:
#define curand_init __pgicudalib_curandInitXORWOW
#define curand_uniform __pgicudalib_curandUniformXORWOW
#pragma acc routine(__pgicudalib_curandInitXORWOW) seq
extern void __pgicudalib_curandInitXORWOW(unsigned long long, unsigned long long, unsigned long long, curandStateXORWOW_t *);
#pragma acc routine(__pgicudalib_curandUniformXORWOW) seq
extern float __pgicudalib_curandUniformXORWOW(curandStateXORWOW_t *);
这是源代码: openacc-test.cpp
#include <openacc.h>
#include <array>
#include "openacc_curand.h"
constexpr int SIZE = 16;
std::array<float, SIZE> data;
float* d_data;
void init(int x){
for(int i = 0; i < SIZE; ++i){
data[i] = x;
}
}
void print(){
printf("Host: [");
for(int i = 0; i < SIZE; ++i){
printf("data: %.5f; ", data[i]);
}
printf("]\n");
}
void do_stuff_on_gpu(){
unsigned long long seed;
unsigned long long seq;
unsigned long long offset;
curandState_t state;
#pragma acc parallel deviceptr(d_data) private(state)
{
seed = 12345ULL;
seq = 0ULL;
offset = 0ULL;
curand_init(seed, seq, offset, &state);
#pragma acc loop seq
for(int i = 0; i < SIZE; ++i){
d_data[i] = curand_uniform(&state);
}
}
}
int main(int argc, char** argv) {
d_data = static_cast<float*>(acc_malloc(SIZE * sizeof(float)));
init(42.17f);
print();
acc_map_data( data.data(), d_data, SIZE * sizeof(float));
acc_update_device(data.data(), SIZE * sizeof(float));
do_stuff_on_gpu();
print();
acc_update_self(data.data(), SIZE * sizeof(float));
print();
acc_free(d_data);
return EXIT_SUCCESS;
}
这是cmake文件:
cmake_minimum_required(VERSION 3.10)
project(openacc-test VERSION 1.0.0 LANGUAGES CXX)
SET( CMAKE_CXX_FLAGS_DEV "-g -O0 -Minfo=accel -ta=tesla,nollvm -Mcudalib=curand" )
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
find_package(OpenACC REQUIRED)
add_executable(openacc-test ${PROJECT_SOURCE_DIR}/src/openacc-test.cpp)
target_compile_features(openacc-test PRIVATE cxx_std_14)
target_include_directories(openacc-test PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_compile_options(openacc-test PRIVATE ${OpenACC_CXX_FLAGS})
target_link_libraries(openacc-test PRIVATE ${OpenACC_CXX_FLAGS} -lcurand -L/opt/pgi/linux86-64/2018/cuda/10.0/lib64)
然后我从构建文件夹中构建它:
cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Dev -D CMAKE_CXX_COMPILER=pgc++ ../ && \
make openacc-test && \
bin/openacc-test
由于存在未定义的参考错误,我猜链接过程出了点问题。我为pgi使用了-ta=tesla,nollvm -Mcudalib=curand
标志,并手动设置了cuda库-lcurand -L/opt/pgi/linux86-64/2018/cuda/10.0/lib64
的路径。我还尝试了CMake中的findCuda模块和nativa Cuda支持,但两者似乎都无效。知道这里有什么问题吗?
修改: 根据Mat的答案修复了语法,但是错误仍然存在。
如果从命令行构建,则会得到以下输出:
pgc++ -v -fast -ta=tesla:nollvm --c++11 -Minfo=accel openacc-test.cpp
Export PGI_CURR_CUDA_HOME=/opt/pgi/linux86-64/2018/cuda/10.0
Export PGI=/opt/pgi
/opt/pgi/linux86-64/18.10/bin/pggpp1 --llalign -Dunix -D__unix -D__unix__ -Dlinux -D__linux -D__linux__ -D__NO_MATH_INLINES -D__LP64__ -D__x86_64 -D__x86_64__ -D__LONG_MAX__=9223372036854775807L '-D__SIZE_TYPE__=unsigned long int' '-D__PTRDIFF_TYPE__=long int' -D__extension__= -D__amd_64__amd64__ -D__k8 -D__k8__ -D__SSE__ -D__MMX__ -D__SSE2__ -D__SSE3__ -D__SSE4A__ -D__ABM__ -D__PGI -D_GNU_SOURCE -D_PGCG_SOURCE -I- -I/opt/pgi/linux86-64/18.10/include-gcc70 -I/opt/pgi/linux86-64/18.10/include -I/usr/include/c++/7 -I/usr/include/x86_64-linux-gnu/c++/7 -I/usr/include/c++/7/backward -I/usr/lib/gcc/x86_64-linux-gnu/7/include -I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed -I/usr/include/x86_64-linux-gnu -I/usr/include -I/opt/pgi/linux86-64/2018/cuda/10.0/include -D_ACCEL=201003 -D_OPENACC=201711 -D__CUDA_API_VERSION=10000 -DPGI_TESLA_TARGET --preinclude _cplus_preinclude.h --preinclude_macros _cplus_macros.h --gnu_version=70300 -D__pgnu_vsn=70300 --accel --preinclude openacc_predef.h --c++11 -q -o /tmp/pgc++-YTc9tfiZkMv.il openacc-test.cpp
/opt/pgi/linux86-64/18.10/bin/pggpp2 openacc-test.cpp -opt 2 -x 119 0xa10000 -x 122 0x40 -x 123 0x1000 -x 127 4 -x 127 17 -x 19 0x400000 -x 28 0x40000 -x 120 0x10000000 -x 70 0x8000 -x 122 1 -x 125 0x20000 -quad -vect 56 -y 34 16 -x 34 0x8 -x 32 6291456 -y 19 8 -y 35 0 -x 42 0x30 -x 39 0x40 -x 199 10 -x 39 0x80 -x 59 4 -tp shanghai -x 120 0x1000 -astype 0 -x 121 1 -fn openacc-test.cpp -il /tmp/pgc++-YTc9tfiZkMv.il -x 117 0x600 -x 123 0x80000000 -x 123 4 -x 119 0x20 -def __pgnu_vsn=70300 -autoinl 10 -x 168 400 -x 174 128000 -x 14 0x200000 -x 46 4 -x 14 0x400000 -x 120 0x200000 -x 70 0x40000000 -x 164 0x800000 -accel tesla -x 180 0x4000400 -x 121 0xc00 -x 186 0x80 -x 163 0x1 -x 186 0x80000 -cudaver 10000 -x 194 0x40000 -y 189 0x10 -cudaroot /opt/pgi/linux86-64/2018/cuda/10.0 -x 176 0x100 -cudacap 60 -x 189 0x8000 -y 163 0xc0000000 -y 189 0x4000000 -cudaroot /opt/pgi/linux86-64/2018/cuda/10.0 -x 9 1 -x 42 0x14200000 -x 72 0x1 -x 136 0x11 -quad -x 119 0x10000000 -x 129 0x40000000 -x 129 2 -x 164 0x1000 -x 0 0x1000000 -x 2 0x100000 -x 0 0x2000000 -x 161 16384 -x 162 16384 -gnuvsn 70300 -x 69 0x200 -cmdline '+pgc++ /tmp/pgc++-YTc9tfiZkMv.il -v -fast -Mvect=sse -Mcache_align -Mflushz -Mpre -ta=tesla:nollvm --c++11 -Minfo=accel' -asm /tmp/pgc++3YTcLZpe7Hgh.s
do_stuff_on_gpu():
93, Accelerator kernel generated
Generating Tesla code
99, #pragma acc loop seq
93, CUDA shared memory used for state
/opt/pgi/linux86-64/18.10/bin/pgnvd -dcuda /opt/pgi/linux86-64/2018/cuda/10.0 -reloc /tmp/pgacc62TcUtvwk7F_.gpu -computecap=60 -ptx /tmp/pgaccA2Tco99QQ3zu.ptx -o /tmp/pgaccQ2Tc_MT360Ow.bin -ftz -cuda10000
/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h(444): error: identifier "nullptr" is undefined
/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h(444): error: expected a ";"
/usr/include/x86_64-linux-gnu/c++/7/bits/c++config.h(235): error: expected a ";"
/usr/include/c++/7/bits/exception.h(63): error: expected a ";"
/usr/include/c++/7/bits/exception.h(69): error: expected a ";"
/usr/include/c++/7/exception(49): error: expected a ";"
/usr/include/c++/7/exception(57): error: expected a ";"
/usr/include/c++/7/exception(67): error: expected a "{"
/usr/include/c++/7/bits/cxxabi_init_exception.h(63): error: expected a "{"
/usr/include/c++/7/typeinfo(99): error: expected a ";"
/usr/include/c++/7/typeinfo(187): error: not a class or struct name
/usr/include/c++/7/typeinfo(190): error: expected a ";"
/usr/include/c++/7/typeinfo(197): error: expected a ";"
/usr/include/c++/7/typeinfo(204): error: not a class or struct name
/usr/include/c++/7/typeinfo(207): error: expected a ";"
/usr/include/c++/7/typeinfo(214): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(63): error: function "__cxxabiv1::std::current_exception" returns incomplete type "__cxxabiv1::std::__exception_ptr::exception_ptr"
/usr/include/c++/7/bits/exception_ptr.h(63): error: expected a "{"
/usr/include/c++/7/bits/exception_ptr.h(73): error: namespace "__cxxabiv1::std" has no member "rethrow_exception"
/usr/include/c++/7/bits/exception_ptr.h(83): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(85): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(86): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(88): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(90): error: declaration is incompatible with previous "__cxxabiv1::std::current_exception"
(63): here
/usr/include/c++/7/bits/exception_ptr.h(90): error: use of a local type to declare a function
/usr/include/c++/7/bits/exception_ptr.h(90): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(91): error: use of a local type to declare a function
/usr/include/c++/7/bits/exception_ptr.h(93): error: namespace "__cxxabiv1::std" has no member "make_exception_ptr"
/usr/include/c++/7/bits/exception_ptr.h(93): error: a template friend declaration cannot be declared in a local class
/usr/include/c++/7/bits/exception_ptr.h(93): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(96): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(98): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(101): error: incomplete type is not allowed
/usr/include/c++/7/bits/exception_ptr.h(101): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(122): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(132): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(149): error: use of a local type to declare a function
/usr/include/c++/7/bits/exception_ptr.h(150): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(153): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(158): error: use of a local type to declare a function
/usr/include/c++/7/bits/exception_ptr.h(159): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(162): error: use of a local type to declare a function
/usr/include/c++/7/bits/exception_ptr.h(163): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(166): error: use of a local type to declare a function
/usr/include/c++/7/bits/exception_ptr.h(167): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(179): error: expected a ";"
/usr/include/c++/7/bits/exception_ptr.h(220): error: expected a ";"
/usr/include/c++/7/bits/move.h(46): error: identifier "constexpr" is undefined
/usr/include/c++/7/bits/move.h(46): error: "_Tp" is not a function or static data member
/usr/include/c++/7/bits/move.h(51): error: expected a ";"
/usr/include/c++/7/type_traits(71): error: identifier "constexpr" is undefined
/usr/include/c++/7/type_traits(71): error: template parameter "_Tp" may not be redeclared in this scope
/usr/include/c++/7/type_traits(71): error: expected a ";"
/usr/include/c++/7/type_traits(72): error: member "__cxxabiv1::std::integral_constant<_Tp, __v>::_Tp" is not a type name
/usr/include/c++/7/type_traits(73): error: member "__cxxabiv1::std::integral_constant<_Tp, __v>::_Tp" is not a type name
/usr/include/c++/7/type_traits(74): error: identifier "constexpr" is undefined
/usr/include/c++/7/type_traits(74): error: expected a ";"
/usr/include/c++/7/type_traits(84): error: identifier "constexpr" is undefined
/usr/include/c++/7/type_traits(84): error: "_Tp" is not a function or static data member
/usr/include/c++/7/type_traits(93): error: expected a declaration
/usr/include/c++/7/type_traits(93): error: expected a ";"
/usr/include/c++/7/type_traits(126): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(154): error: __bool_constant is not a template
/usr/include/c++/7/type_traits(154): error: not a class or struct name
/usr/include/c++/7/type_traits(245): error: identifier "char16_t" is undefined
/usr/include/c++/7/type_traits(249): error: identifier "char32_t" is undefined
/usr/include/c++/7/type_traits(249): error: class "__cxxabiv1::std::__is_integral_helper<<error-type>>" has already been defined
/usr/include/c++/7/type_traits(362): error: namespace "__cxxabiv1::std" has no member "size_t"
/usr/include/c++/7/type_traits(463): error: expected a ">"
/usr/include/c++/7/type_traits(467): error: expected a ">"
/usr/include/c++/7/type_traits(475): error: expected a ">"
/usr/include/c++/7/type_traits(479): error: expected a ">"
/usr/include/c++/7/type_traits(487): error: expected a ">"
/usr/include/c++/7/type_traits(491): error: expected a ">"
/usr/include/c++/7/type_traits(499): error: expected a ">"
/usr/include/c++/7/type_traits(503): error: expected a ">"
/usr/include/c++/7/type_traits(511): error: expected a ">"
/usr/include/c++/7/type_traits(515): error: expected a ">"
/usr/include/c++/7/type_traits(523): error: expected a ">"
/usr/include/c++/7/type_traits(527): error: expected a ">"
/usr/include/c++/7/type_traits(535): error: expected a ">"
/usr/include/c++/7/type_traits(539): error: expected a ">"
/usr/include/c++/7/type_traits(547): error: expected a ">"
/usr/include/c++/7/type_traits(551): error: expected a ">"
/usr/include/c++/7/type_traits(561): error: namespace "__cxxabiv1::std" has no member "nullptr_t"
/usr/include/c++/7/type_traits(582): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(588): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(595): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(602): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(612): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(638): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(748): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(762): error: expected a ";"
/usr/include/c++/7/type_traits(777): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
/usr/include/c++/7/type_traits(787): error: expected a ")"
/usr/include/c++/7/type_traits(798): error: an explicit template argument list is not allowed on this declaration
/usr/include/c++/7/type_traits(798): error: expected a type specifier
/usr/include/c++/7/type_traits(798): error: function returning function is not allowed
/usr/include/c++/7/type_traits(798): error: expected a ";"
/usr/include/c++/7/type_traits(804): error: space required between adjacent ">" delimiters of nested template argument lists (">>" is the right shift operator)
Error limit reached.
100 errors detected in the compilation of "/tmp/pgnvdP3Tc7ZGSTVCf.ii".
Compilation terminated.
PGCC-F-0155-Compiler failed to translate accelerator region (see -Minfo messages): Device compiler exited with error status code (openacc-test.cpp: 1)
PGCC/x86 Linux 18.10-1: compilation aborted
pgc++-Fatal-cpp2 completed with exit code 1
Unlinking /tmp/pgc++-YTc9tfiZkMv.il
Unlinking /tmp/pgc++3YTcLZpe7Hgh.s
Unlinking /tmp/pgc++VYTcnqU9SlJ_.ll
答案 0 :(得分:3)
未定义的引用实际上来自主机代码。问题是您在平行区域周围缺少括号,因此仅卸载了该行,即“种子= 12345UL”。
要解决:
void do_stuff_on_gpu(){
unsigned long long seed;
unsigned long long seq;
unsigned long long offset;
curandState_t state;
#pragma acc parallel deviceptr(d_data) private(state)
{ // << Add here
seed = 12345ULL;
seq = 0ULL;
offset = 0ULL;
curand_init(seed, seq, offset, &state);
#pragma acc loop seq
for(int i = 0; i < SIZE; ++i){
d_data[i] = curand_uniform(&state);
}
} // << Add here
}
% pgc++ -fast -ta=tesla:nollvm --c++11 test.cpp -Minfo=accel
do_stuff_on_gpu():
29, Generating Tesla code
36, #pragma acc loop seq
29, CUDA shared memory used for state
答案 1 :(得分:2)
第二个错误实际上与第一个错误无关,需要一些细节来解释。
PGI有两个后端设备代码生成路径,即LLVM和CUDA(nollvm),默认路径是LLVM。从设备代码调用cuRAND是少数需要CUDA后端的情况之一,因为curand设备代码包含在需要内联的CUDA头文件中。不幸的是,我们还没有从LLVM路径执行此操作的方法。
通常,当您看到类似第二个错误的错误时,这是由于没有适当的语言标志而编译C ++ 14(或C ++ 11/17)代码引起的。这里的问题是PGI驱动程序没有将正确的语言标志传递给CUDA后端编译器(cicc)。因为我已经安装了GNU 4.8.5,所以它对我有用,因此默认情况下C ++ 11不处于启用状态。但是,您正在使用启用了C ++ 14的GNU 7,但是由于我们没有将``--c ++ 14”传递给cicc,因此会出现错误。
我已经填写了一个问题报告(TPR#26979)来跟踪此问题,并要求我们的工程师在使用较新的GNU版本时传递适当的语言标记。
作为一种解决方法,我们可以更新PGI的配置文件(pgnvdrc),以便您可以通过环境变量传递正确的标志。在您的PGI安装中,找到文件“ $ PGI / linux86-64 / 18.10 / bin / pgnvdrc”并进行以下两行更改:
% diff -u pgnvdrc.org pgnvdrc
--- pgnvdrc.org 2019-03-14 13:12:45.232168580 -0700
+++ pgnvdrc 2019-03-14 13:12:57.026220144 -0700
@@ -18,6 +18,8 @@
variable LDLIB is environment(LD_LIBRARY_PATH);
variable NEWLDLIB is default($LDLIB);
+variable CICCFLAG is environment(CICCFLAG);
+
variable DYLDLIB is environment(DYLD_LIBRARY_PATH);
variable NEWDYLDLIB is default($DYLDLIB);
@@ -547,6 +549,7 @@
set(out3=$if($CUPTXFILE,$CUPTXFILE,$if($KEEPTEMP,$basename($input).ptx,$tempfile(ptx))))
arguments(
-arch $COMPCAP -m$CUWIDTH -ftz=$FTZ -prec_div=$NOFASTMATH -prec_sqrt=$NOFASTMATH -fmad=$USEFMA
+ $CICCFLAG
$if($RELOC,--device-c)
$NVVMARGS -O$CUOPT $input -o $out3
$ifn($index($CUDAVERSION,7.5,8.0),-w)
接下来,设置环境变量“ CICCFLAG =-c ++ 14”并重新编译。
在这里,我已经更新了18.10编译器以使用GNU 7.2。我可以重新创建该错误,但是在设置了CICCFLAG之后,代码可以正确编译。
% pgc++ -fast -ta=tesla:nollvm --c++14 openacc-test.cpp
/home/sw/thirdparty/gcc/gcc-7.2.0/linux86-64/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/stddef.h(444): error: identifier "nullptr" is undefined
/home/sw/thirdparty/gcc/gcc-7.2.0/linux86-64/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/stddef.h(444): error: expected a ";"
/home/sw/thirdparty/gcc/gcc-7.2.0/linux86-64/include/c++/7.2.0/x86_64-pc-linux-gnu/bits/c++config.h(235): error: expected a ";"
... more errors ...
% setenv CICCFLAG "--c++14"
% pgc++ -fast -ta=tesla:nollvm --c++14 -Minfo=accel openacc-test.cpp
do_stuff_on_gpu():
30, Accelerator kernel generated
Generating Tesla code
36, #pragma acc loop seq
30, CUDA shared memory used for state
% a.out
Host: [data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; ]
Host: [data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; data: 42.00000; ]
Host: [data: 0.29890; data: 0.38100; data: 0.28855; data: 0.40197; data: 0.74258; data: 0.26742; data: 0.35657; data: 0.70735; data: 0.55123; data: 0.72577; data: 0.64131; data: 0.48502; data: 0.09711; data: 0.14655; data: 0.15180; data: 0.35960; ]