cuModuleGetFunction возвращает не найдено

Я хочу скомпилировать ядра CUDA с помощью JIT-компилятора nvrtc, чтобы повысить производительность моего приложения (поэтому у меня увеличено количество выборок команд, но я сохраняю множественный доступ к массиву).

Функции выглядит, например, вот так и генерируется моим генератором функций (не так важно):

extern "C" __device__ void GetSumOfBranches(double* branches, double* outSum)
{
double sum = (branches[38])+(-branches[334])+(-branches[398])+(-branches[411]);
*outSum = sum;
}

Я компилирую код выше с помощью следующей функции:

CUfunction* FunctionGenerator::CreateFunction(const char* programText)
{
// When I comment this statement out the output of the PTX file is changing
// what is the reson?!
// Bug?
std::string savedString = std::string(programText);nvrtcProgram prog;
nvrtcCreateProgram(&prog, programText, "GetSumOfBranches.cu", 0, NULL, NULL);

const char *opts[] = {"--gpu-architecture=compute_52", "--fmad=false"};
nvrtcCompileProgram(prog, 2, opts);

// Obtain compilation log from the program.
size_t logSize;
nvrtcGetProgramLogSize(prog, &logSize);
char *log = new char[logSize];
nvrtcGetProgramLog(prog, log);
// Obtain PTX from the program.
size_t ptxSize;
nvrtcGetPTXSize(prog, &ptxSize);
char *ptx = new char[ptxSize];
nvrtcGetPTX(prog, ptx);

printf("%s", ptx);

CUdevice cuDevice;
CUcontext context;
CUmodule module;
CUfunction* kernel;
kernel = (CUfunction*)malloc(sizeof(CUfunction));
cuInit(0);
cuDeviceGet(&cuDevice, 0);
cuCtxCreate(&context, 0, cuDevice);
auto resultLoad = cuModuleLoadDataEx(&module, ptx, 0, 0, 0);
auto resultGetF = cuModuleGetFunction(kernel, module, "GetSumOfBranches");
return kernel;
}

Все работает кроме этого cuModuleGetFunction возвращается CUDA_ERROR_NOT_FOUND, Эта ошибка происходит потому, что GetSumOfBranches не может быть найден в файле PTX.

Однако выход printf("%s", ptx); это:

// Generated by NVIDIA NVVM Compiler
//
// Compiler Build ID: CL-19856038
// Cuda compilation tools, release 7.5, V7.5.17
// Based on LLVM 3.4svn
//

.version 4.3
.target sm_52
.address_size 64

// .globl   GetSumOfBranches

.visible .func GetSumOfBranches(
.param .b64 GetSumOfBranches_param_0,
.param .b64 GetSumOfBranches_param_1
)
{
.reg .f64   %fd<8>;
.reg .b64   %rd<3>;ld.param.u64    %rd1, [GetSumOfBranches_param_0];
ld.param.u64    %rd2, [GetSumOfBranches_param_1];
ld.f64  %fd1, [%rd1+304];
ld.f64  %fd2, [%rd1+2672];
sub.rn.f64  %fd3, %fd1, %fd2;
ld.f64  %fd4, [%rd1+3184];
sub.rn.f64  %fd5, %fd3, %fd4;
ld.f64  %fd6, [%rd1+3288];
sub.rn.f64  %fd7, %fd5, %fd6;
st.f64  [%rd2], %fd7;
ret;
}

По моему мнению все нормально и GetSumOfBranches может быть найден cuModuleGetFunction, Можете ли вы объяснить мне, почему?

Второй вопрос

когда я перехитрил std::string savedString = std::string(programText); тогда вывод PTX просто:

// Generated by NVIDIA NVVM Compiler
//
// Compiler Build ID: CL-19856038
// Cuda compilation tools, release 7.5, V7.5.17
// Based on LLVM 3.4svn
//

.version 4.3
.target sm_52
.address_size 64

и это странно, потому что savedString не используется вообще …

0

Решение

То, что вы пытаетесь сделать, не поддерживается. API-интерфейсы управления модулями на стороне хоста и формат ELF устройства не предоставляют __device__ только функции __global__ функции, которые можно вызывать через API запуска ядра.

Вы можете скомпилировать функции устройства априори или во время выполнения и связать их с ядрами способом JIT, а также можете извлечь эти ядра и вызвать их. Но это все, что вы можете сделать.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]