如何在运行时生成、编译和运行CUDA内核

如何在运行时生成、编译和运行CUDA内核,cuda,compilation,gpgpu,ptx,Cuda,Compilation,Gpgpu,Ptx,嗯,我有一个相当微妙的问题:) 让我们从我拥有的开始: 数据,大量数据,复制到GPU 程序,由CPU(主机)生成,需要对该数组中的每个数据进行评估 程序经常更改,可以生成CUDA字符串、PTX字符串或其他(?),每次更改后需要重新评估 我想要的:基本上只是想让它尽可能有效(快速),例如,避免将CUDA编译成PTX。解决方案甚至可以是完全特定于设备的,这里不需要很大的兼容性:) 我知道的:我已经知道函数cuLoadModule,它可以从存储在文件中的PTX代码加载和创建内核。但我认为,必须有其他方

嗯,我有一个相当微妙的问题:)

让我们从我拥有的开始:

  • 数据,大量数据,复制到GPU
  • 程序,由CPU(主机)生成,需要对该数组中的每个数据进行评估
  • 程序经常更改,可以生成CUDA字符串、PTX字符串或其他(?),每次更改后需要重新评估
  • 我想要的:基本上只是想让它尽可能有效(快速),例如,避免将CUDA编译成PTX。解决方案甚至可以是完全特定于设备的,这里不需要很大的兼容性:)

    我知道的:我已经知道函数cuLoadModule,它可以从存储在文件中的PTX代码加载和创建内核。但我认为,必须有其他方法直接创建内核,而不必先将其保存到文件中。或者也许可以将其存储为字节码

    我的问题:你会怎么做?你能发布一个例子或链接到类似主题的网站吗?泰

    编辑:现在,PTX内核可以直接使用字符串(字符数组)。无论如何,我仍然想知道,有没有更好/更快的解决方案?仍然存在从字符串到某些PTX字节码的转换,这应该尽可能避免。我还怀疑,可能存在一些从PTX创建特定于设备的Cuda二进制文件的聪明方法,这将消除JIT编译器延迟(虽然很小,但如果要运行大量内核,它会累积起来):)


    罗杰·达尔在评论中链接了以下帖子

    其中介绍了两个函数的使用,即
    cuModuleLoad
    cuModuleLoadDataEx
    。前者用于从文件加载PTX代码并将其传递到
    nvcc
    编译器驱动程序。后者避免了I/O,并允许将PTX代码作为C字符串传递给驱动程序。在这两种情况下,您都需要已经拥有PTX代码,作为CUDA内核编译的结果(加载或复制并粘贴到C字符串中),或者作为手工编写的源代码

    但是,如果必须从CUDA内核开始动态创建PTX代码,会发生什么?按照中的方法,可以定义包含CUDA内核的字符串,如

    ss << "extern \"C\" __global__ void kernel( ";
    ss << def_line.str() << ", unsigned int vector_size, unsigned int number_of_used_threads ) { \n";
    ss << "\tint idx = blockDim.x * blockIdx.x + threadIdx.x; \n";
    ss << "\tfor(unsigned int i = 0; i < ";
    ss << "(vector_size + number_of_used_threads - 1) / number_of_used_threads; ++i) {\n";
    ss << "\t\tif(idx < vector_size) { \n";
    ss << "\t\t\t" << eval_line.str() << "\n";
    ss << "\t\t\tidx += number_of_used_threads;\n";
    ss << "\t\t}\n";
    ss << "\t}\n";
    ss << "}\n\n\n\n";
    

    当然,表达式模板与此问题无关,我只是引用了我在回答中报告的想法的来源。

    在中,作者使用表达式模板技术在运行时为每种表达式类型生成CUDA内核。看一看这张照片。你会对这样的东西感兴趣吗?+1因为指向有趣的相关文章,他们最终从文件中加载了PTX,但我喜欢他们从cuda中完全抽象出矢量操作的方式:)很高兴看到其他人是如何做的,谢谢你链接代码杰克!我认为上面的文章是将表达式模板与CUDA结合使用的第一个示例。我想到的批评是,可能在运行时动态生成CUDA代码以及编译和加载PTX代码的需要会阻碍使用表达式模板的优势。如果您对CUDA中的表达式模板感兴趣,那么,其他库已经开发出来了:使用推力、J.M. Cohen、“处理设备阵列与C++元编程”、GPU计算GEMS -玉石版等。我们开发了一个用于主机和设备的表达式模板库,旨在实现类似Matlab的语法。这是一个测试版。非常感谢你的推荐。这是一个很好的复制/粘贴示例,介绍了如何编译和执行Cuda内核。。并回答了一个事实上的问题:)使用PTX,您可以跳过编译当然有一种方法可以执行NVCC编译器而不在命令行上实际执行它?@Dmitinesteruk,请检查。@PatrickRoberts谢谢!看来这正是我需要的!
    int nvcc_exit_status = system(
             (std::string(NVCC) + " -ptx " + NVCC_FLAGS + " " + kernel_filename 
                  + " -o " + kernel_comp_filename).c_str()
        );
    
        if (nvcc_exit_status) {
                std::cerr << "ERROR: nvcc exits with status code: " << nvcc_exit_status << std::endl;
                exit(1);
        }
    
        result = cuModuleLoad(&cuModule, kernel_comp_filename.c_str());
        assert(result == CUDA_SUCCESS);
        result =  cuModuleGetFunction(&cuFunction, cuModule, "kernel");
        assert(result == CUDA_SUCCESS);