1

この質問はcuModuleLoadDataEx オプションに似ていますが、トピックを再度取り上げ、さらに情報を提供したいと思います。

cuModuleLoadDataEx を介して NV ドライバーで 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";
}

ビルド (CUDA が /usr/local/cuda にインストールされていると仮定して、CUDA 5.0 を使用します):

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

誰かがコンパイルプロセスから賢明な情報を抽出できれば、それは素晴らしいことです! cuModuleLoadDataEx が説明されている CUDA ドライバー API のドキュメント (およびそれが受け入れるはずのオプション) 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コンパイル時間を取得することができました。ただし、ドライバーは OptVals として 32 ビット値の配列を想定しているようです。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 コンパイル時間を更新しません。この値が変更されたかどうかを調べていたので、呼び出しがオプションをすべて無視すると仮定しました。そうではありません。それは正常に動作します。

4

1 に答える 1