Я экспериментирую с созданием простого приложения из пары исходных файлов .cu и очень простой основной C ++, которая вызывает функцию из одного из файлов .cu.Я делаю общую библиотеку (файл .so) из скомпилированных файлов .cu.Я обнаружил, что все собирается без проблем, но когда я пытаюсь запустить приложение, я получаю ошибку неопределенного символа компоновщика с искаженным именем функции .cu, которую я вызываю из main ().Если вместо этого я создаю статическую библиотеку, мое приложение работает нормально.Вот созданный мной make-файл:
.PHONY: clean
NVCCFLAGS = -std=c++11 --compiler-options '-fPIC'
CXXFLAGS = -std=c++11
HLIB = libhello.a
SHLIB = libhello.so
CUDA_OBJECTS = bridge.o add.o
all: driver
%.o :: %.cu
nvcc -o $@ $(NVCCFLAGS) -c -I. $<
%.o :: %.cpp
c++ $(CXXFLAGS) -o $@ -c -I. $<
$(HLIB): $(CUDA_OBJECTS)
ar rcs $@ $^
$(SHLIB): $(CUDA_OBJECTS)
nvcc $(NVCCFLAGS) --shared -o $@ $^
#driver : driver.o $(HLIB)
# c++ -std=c++11 -fPIC -o $@ driver.o -L. -lhello -L/usr/local/cuda-10.1/targets/x86_64-linux/lib -lcudart
driver : driver.o $(SHLIB)
c++ -std=c++11 -fPIC -o $@ driver.o -L. -lhello
clean:
-rm -f driver *.o *.so *.a
Вот различные исходные файлы, которые make-файл принимает в качестве фуража.add.cu:
__global__ void add(int n, int* a, int* b, int* c) {
int index = threadIdx.x;
int stride = blockDim.x;
for (int ii = index; ii < n; ii += stride) {
c[ii] = a[ii] + b[ii];
}
}
add.h:
extern __global__ void add(int n, int* a, int* b, int* c);
bridge.cu:
#include <iostream>
#include "add.h"
void bridge() {
int N = 1 << 16;
int blockSize = 256;
int numBlocks = (N + blockSize - 1)/blockSize;
int* a;
int* b;
int* c;
cudaMallocManaged(&a, N*sizeof(int));
cudaMallocManaged(&b, N*sizeof(int));
cudaMallocManaged(&c, N*sizeof(int));
for (int ii = 0; ii < N; ii++) {
a[ii] = ii;
b[ii] = 2*ii;
}
add<<<numBlocks, blockSize>>>(N, a, b, c);
cudaDeviceSynchronize();
for (int ii = 0; ii < N; ii++) {
std::cout << a[ii] << " + " << b[ii] << " = " << c[ii] << std::endl;
}
cudaFree(a);
cudaFree(b);
cudaFree(c);
}
bridge.h:
extern void bridge();
driver.cpp:
#include "bridge.h"
int main() {
bridge();
return 0;
}
Я очень новичок в cuda, поэтому я ожидаю, что именно здесь я делаю что-то не так.Я немного поиграл с использованием объявлений extern "C", но это, кажется, просто перемещает ошибку "undefined symbol" со времени выполнения на время сборки.
Я знаком с различными способами, которыми можно завершитьс неопределенным символом, и я упомянул различные эксперименты, которые я уже провел (статическое связывание, объявления extern "C"), которые заставляют меня думать, что эта проблема не решается предложенным дублирующим вопросом.
Мой неразрешенный символ - _Z6bridgev
Мне кажется, что компоновщик должен иметь возможность разрешить символ.Если я могу использовать nm на driver.o, я вижу:
0000000000000000 T main
U _Z6bridgev
И если я запускаю nm на libhello.so, я вижу:
0000000000006e56 T _Z6bridgev