cuModuleLoadDataEx игнорирует все параметры

Этот вопрос похож на Параметры cuModuleLoadDataEx но я хотел бы снова поднять эту тему и дополнительно предоставить больше информации.

При загрузке строки PTX с драйвером NV через cuModuleLoadDataEx кажется, что все параметры игнорируются. Я предоставляю полные рабочие примеры, чтобы любой желающий мог прямо и без усилий воспроизвести это. Сначала небольшое ядро ​​PTX (сохраните его как small.ptx), а затем программа C ++, которая загружает ядро ​​PTX.

.version 3.1
.target sm_20, texmode_independent
.address_size 64
.entry main()
{
ret;
}

main.cc

#include<cstdlib>
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<map>
#include "cuda.h"
int main(int argc,char *argv[])
{
CUdevice cuDevice;
CUcontext cuContext;

CUfunction func;
CUresult ret;
CUmodule cuModule;

cuInit(0);

std::cout << "trying to get device 0\n";
ret = cuDeviceGet(&cuDevice, 0);
if (ret != CUDA_SUCCESS) { exit(1);}

std::cout << "trying to create a context\n";
ret = cuCtxCreate(&cuContext, 0, cuDevice);
if (ret != CUDA_SUCCESS) { exit(1);}

std::cout << "loading PTX string from file " << argv[1] << "\n";

std::ifstream ptxfile( argv[1] );
std::stringstream buffer;
buffer << ptxfile.rdbuf();
ptxfile.close();

std::string ptx_kernel = buffer.str();

std::cout << "Loading PTX kernel with driver\n" << ptx_kernel;

const unsigned int jitNumOptions = 3;
CUjit_option *jitOptions = new CUjit_option[jitNumOptions];
void **jitOptVals = new void*[jitNumOptions];

// set up size of compilation log buffer
jitOptions[0] = CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES;
int jitLogBufferSize = 1024*1024;
jitOptVals[0] = (void *)&jitLogBufferSize;

// set up pointer to the compilation log buffer
jitOptions[1] = CU_JIT_INFO_LOG_BUFFER;
char *jitLogBuffer = new char[jitLogBufferSize];
jitOptVals[1] = jitLogBuffer;

// set up wall clock time
jitOptions[2] = CU_JIT_WALL_TIME;
float jitTime = -2.0;
jitOptVals[2] = &jitTime;

ret = cuModuleLoadDataEx( &cuModule , ptx_kernel.c_str() , jitNumOptions, jitOptions, (void **)jitOptVals );
if (ret != CUDA_SUCCESS) { exit(1);}

std::cout << "walltime: " << jitTime << "\n";
std::cout << std::string(jitLogBuffer) << "\n";
}

Сборка (при условии, что CUDA установлен в / usr / local / cuda, я использую CUDA 5.0):

g++ -I/usr/local/cuda/include -L/usr/local/cuda/lib64/ main.cc -o main -lcuda

Если кто-то может извлечь какую-либо разумную информацию из процесса компиляции, это было бы здорово! Документация по API драйвера CUDA, где поясняется cuModuleLoadDataEx (и какие опции он должен принимать) http://docs.nvidia.com/cuda/cuda-driver-api/index.html

Если я запускаю это, журнал пуст и jitTime драйвер NV даже не тронул

./main small.ptx
trying to get device 0
trying to create a context
loading PTX string from file empty.ptx
Loading PTX kernel with driver
.version 3.1
.target sm_20, texmode_independent
.address_size 64
.entry main()
{
ret;
}

walltime: -2

РЕДАКТИРОВАТЬ:

Мне удалось получить время компиляции JIT. Однако, похоже, что драйвер ожидает массив 32-битных значений как OptVals. Не так, как указано в руководстве, как массив указателей (void *) которые в моей системе 64 бит. Итак, это работает:

const unsigned int jitNumOptions = 1;
CUjit_option *jitOptions = new CUjit_option[jitNumOptions];
int *jitOptVals = new int[jitNumOptions];
jitOptions[0] = CU_JIT_WALL_TIME;
// here the call to cuModuleLoadDataEx
std::cout << "walltime: " << (float)jitOptions[0] << "\n";

Я считаю, что невозможно сделать то же самое с массивом void *, Следующий код не работает:

const unsigned int jitNumOptions = 1;
CUjit_option *jitOptions = new CUjit_option[jitNumOptions];
void **jitOptVals = new void*[jitNumOptions];
jitOptions[0] = CU_JIT_WALL_TIME;
// here the call to cuModuleLoadDataEx
// here I also would have a problem casting a 64 bit void * to a float (32 bit)

РЕДАКТИРОВАТЬ

Глядя на время компиляции JIT jitOptVals[0] вводит в заблуждение. Как упоминалось в комментариях, JIT-компилятор кэширует предыдущие трансляции и не будет обновлять время JIT-компиляции, если обнаружит кэшированную компиляцию. Поскольку я искал, изменилось ли это значение или нет, я предположил, что вызов игнорирует все параметры вместе. Что это не так. Работает нормально.

1

Решение

Ваш jitOptVals не должен содержать указателей на ваши значения, вместо этого приведите значения к void*:

// set up size of compilation log buffer
jitOptions[0] = CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES;
int jitLogBufferSize = 1024*1024;
jitOptVals[0] = (void *)jitLogBufferSize;

// set up pointer to the compilation log buffer
jitOptions[1] = CU_JIT_INFO_LOG_BUFFER;
char *jitLogBuffer = new char[jitLogBufferSize];
jitOptVals[1] = jitLogBuffer;

// set up wall clock time
jitOptions[2] = CU_JIT_WALL_TIME;
float jitTime = -2.0;
//Keep jitOptVals[2] empty as it only an Output value:
//jitOptVals[2] = (void*)jitTime;

и после cuModuleLoadDataExвы получите свой jitTime лайк jitTime = (float)jitOptions[2];

4

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

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

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