2013-06-12 3 views
1

이 질문은 cuModuleLoadDataEx options과 유사하지만 주제를 다시 가져오고 추가 정보를 제공해 드리고자합니다.cuModuleLoadDataEx가 모든 옵션을 무시합니다.

cu 드라이버가있는 cuXoduleLoadDataEx를 사용하여 PTX 문자열을로드하면 모든 옵션이 모두 무시되는 것 같습니다. 관심있는 모든 사람이 직접적으로 노력할 수 있도록 전체 작업 예제를 제공합니다. 먼저 작은 PTX 커널 (small.ptx로 저장)을 누른 다음 PTX 커널을로드하는 C++ 프로그램.

.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"; 
} 

빌드 (/ usr/지방/CUDA에서, 내가 CUDA 5.0을 사용 CUDA가 설치된 가정) :

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

사람이 추출 할 수있는 경우

위대한 것입니다 컴파일 과정에서 모든 합리적인 정보!

./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 
: cuModuleLoadDataEx 내가 이것을 실행하면 로그가 비어 있고 jitTime는 심지어 NV 드라이버에 감동되지 않은 http://docs.nvidia.com/cuda/cuda-driver-api/index.html

설명 (그리고이 동의하도록되어있는 옵션) CUDA 드라이버 API의 문서

편집 :

나는 JIT 컴파일 타임을 얻을 수 있었다. 그러나 드라이버가 OptVals로 32 비트 값의 배열을 기대하는 것 같습니다. 수동으로 포인터 (void *)의 배열로 내 시스템 64 비트에 명시된 바와 같이. 그래서,이 작품 : 나는 void *의 배열과 동일한 작업을 수행하는 것이 불가능하다고 생각

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"; 

. JIT를 컴파일 시간 jitOptVals[0] 보면

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 컴파일러는 이전 변환을 캐시하고 캐시 된 컴파일을 발견하면 JIT 컴파일 시간을 업데이트하지 않습니다. 이 값이 변경되었는지 아닌지 여부를 알기 때문에 호출이 옵션을 모두 무시한다고 가정합니다. 그렇지 않습니다. 괜찮아.

답변

4

당신의 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 후, 당신이 대답에 대한 jitTimejitTime = (float)jitOptions[2]; 같은

+0

감사를 얻을! 나는 64 비트 시스템에있다. 컴파일러는 float를 void *로 캐스팅하지 않습니다. 이 인터페이스는 32 비트 포인터에서만 작동합니까? – ritter

+0

드라이버는 32 비트 또는 64 비트 시스템에 상관없이 32 비트 void 포인터 만 허용합니다. 믿어지지 않는 정도로 어리 석다. 따라서 64 비트 시스템에서 해결책은 ** void (매뉴얼에 표시된대로)를 사용하지 말고 * int입니다. 그들은 키디가되어야 해. – ritter

+0

물론 컴파일 로그를 얻기 위해 버퍼 포인터를 전달하는 데 사용할 수 없다는 것을 의미합니다. – ritter

관련 문제