アプリケーションのパフォーマンスを向上させるために、CUDAカーネルをnvrtc JITコンパイラでコンパイルする必要があります(命令フェッチの量が増えますが、複数の配列アクセスを保存しています)。cuModuleGetFunctionが返されない
このようにして(その重要ではありません)私のファンクション・ジェネレータによって生成されます。私は、以下の機能を備えた上記のコードをコンパイルしています
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);
の出力がこれですが:私のoptinionで
// 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
によって発見さsould。なぜ私に説明できますか?私は、PTXの出力だけであるstd::string savedString = std::string(programText);
をoutcomment
2番目の質問
:
// 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
は一切使用しておりませんので、これは奇妙です...
なぜあなたは '__device__'とマークされた問題の関数を持っていますか?これはCUDAカーネルではありません。ホストコードから呼び出すことはできません。とにかく、「なぜこれは機能しないのですか?」という質問に対してはあなたは[mcve]を提供するはずです –
私はそれについて私はちょうどカーネルをコンパイルしているとは考えていません..私は私もデバイスの機能をコンパイルできると思っています。あなたはちょうど私の問題を解決しました(多分あなたはポイントを得るために私の質問に答えたいです - それ以外の場合はありがとう)。次の質問では、私は最小で完全で検証可能な例を提供します。 – Jens