【问题标题】:OpenCL inside Visual Studio - can we compile one exe that would use all possible CPUs OpenCL can get an all OpenCL supporting platforms?Visual Studio 中的 OpenCL - 我们可以编译一个使用所有可能的 CPU 的 exe OpenCL 可以获得所有 OpenCL 支持的平台吗?
【发布时间】:2011-01-29 03:38:25
【问题描述】:

所以我的意思是编译如下代码:

//******************************************************************* 
// Demo OpenCL application to compute a simple vector addition  
// computation between 2 arrays on the GPU 
// ****************************************************************** 
#include <stdio.h> 
#include <stdlib.h> 
#include <CL/cl.h> 

// OpenCL source code 
const char* OpenCLSource[] = {   
"__kernel void VectorAdd(__global int* c, __global int* a,__global int* b)", 
  "{", 
  "  // Index of the elements to add \n", 
  "  unsigned int n = get_global_id(0);", 
  "  // Sum the n’th element of vectors a and b and store in c \n", 
  "  c[n] = a[n] + b[n];", 
  "}" 
}; 

// Some interesting data for the vectors 
int InitialData1[20] = {37,50,54,50,56,0,43,43,74,71,32,36,16,43,56,100,50,25,15,17}; 
int InitialData2[20] = {35,51,54,58,55,32,36,69,27,39,35,40,16,44,55,14,58,75,18,15}; 

// Number of elements in the vectors to be added 
#define SIZE 2048   

// Main function  
// ********************************************************************* 
int main(int argc, char **argv) 
{ 
   // Two integer source vectors in Host memory 
    int HostVector1[SIZE], HostVector2[SIZE]; 

    // Initialize with some interesting repeating data 
    for(int c = 0; c < SIZE; c++)  
    {   
HostVector1[c] = InitialData1[c%20]; 
HostVector2[c] = InitialData2[c%20]; 
    } 

    // Create a context to run OpenCL on our CUDA-enabled NVIDIA GPU  
    cl_context GPUContext = clCreateContextFromType(0, CL_DEVICE_TYPE_GPU,  
                    NULL, NULL, NULL); 

    // Get the list of GPU devices associated with this context 
    size_t ParmDataBytes; 
    clGetContextInfo(GPUContext, CL_CONTEXT_DEVICES, 0, NULL, &ParmDataBytes); 
    cl_device_id* GPUDevices = (cl_device_id*)malloc(ParmDataBytes); 
    clGetContextInfo(GPUContext, CL_CONTEXT_DEVICES, ParmDataBytes, GPUDevices, NULL);
    // Create a command-queue on the first GPU device 
    cl_command_queue GPUCommandQueue = clCreateCommandQueue(GPUContext,  
                 GPUDevices[0], 0, NULL); 

    // Allocate GPU memory for source vectors AND initialize from CPU memory 
    cl_mem GPUVector1 = clCreateBuffer(GPUContext, CL_MEM_READ_ONLY | 
          CL_MEM_COPY_HOST_PTR, sizeof(int) * SIZE, HostVector1, NULL); 
    cl_mem GPUVector2 = clCreateBuffer(GPUContext, CL_MEM_READ_ONLY | 
               CL_MEM_COPY_HOST_PTR, sizeof(int) * SIZE, HostVector2, NULL); 

    // Allocate output memory on GPU 
    cl_mem GPUOutputVector = clCreateBuffer(GPUContext, CL_MEM_WRITE_ONLY, 
               sizeof(int) * SIZE, NULL, NULL); 

    // Create OpenCL program with source code 
    cl_program OpenCLProgram = clCreateProgramWithSource(GPUContext, 7, 
               OpenCLSource, NULL, NULL); 

    // Build the program (OpenCL JIT compilation) 
    clBuildProgram(OpenCLProgram, 0, NULL, NULL, NULL, NULL); 

    // Create a handle to the compiled OpenCL function (Kernel) 
    cl_kernel OpenCLVectorAdd = clCreateKernel(OpenCLProgram, "VectorAdd", NULL);

    // In the next step we associate the GPU memory with the Kernel arguments 
    clSetKernelArg(OpenCLVectorAdd, 0, sizeof(cl_mem),(void*)&GPUOutputVector); 
    clSetKernelArg(OpenCLVectorAdd, 1, sizeof(cl_mem), (void*)&GPUVector1); 
    clSetKernelArg(OpenCLVectorAdd, 2, sizeof(cl_mem), (void*)&GPUVector2); 

    // Launch the Kernel on the GPU 
    size_t WorkSize[1] = {SIZE};  // one dimensional Range 
    clEnqueueNDRangeKernel(GPUCommandQueue, OpenCLVectorAdd, 1, NULL, 
         WorkSize, NULL, 0, NULL, NULL); 

    // Copy the output in GPU memory back to CPU memory 
    int HostOutputVector[SIZE]; 
    clEnqueueReadBuffer(GPUCommandQueue, GPUOutputVector, CL_TRUE, 0, 
               SIZE * sizeof(int), HostOutputVector, 0, NULL, NULL); 

    // Cleanup  
    free(GPUDevices); 
    clReleaseKernel(OpenCLVectorAdd);   
    clReleaseProgram(OpenCLProgram); 
    clReleaseCommandQueue(GPUCommandQueue); 
    clReleaseContext(GPUContext); 
    clReleaseMemObject(GPUVector1); 
    clReleaseMemObject(GPUVector2); 
    clReleaseMemObject(GPUOutputVector); 

    // Print out the results 
    for (int Rows = 0; Rows < (SIZE/20); Rows++, printf("\n")){ 
        for(int c = 0; c <20; c++){ 
            printf("%c",(char)HostOutputVector[Rows * 20 + c]); 
    } 
    }  
    return 0; 
}

使用 VS 进入 exe(在我的例子中是 08)我们可以确定我们运行它的任何地方都会使用最大的 PC 计算能力吗?如果没有怎么办? (顺便说一句,如何让它与 AMD 卡和其他非 CUDA gpus 一起工作?(意味着所有 PC 的一个程序))

【问题讨论】:

    标签: c++ c visual-studio-2008 opencl gpu


    【解决方案1】:

    此代码应在任何具有支持 OpenCL 的 GPU 驱动程序的 Windows PC 上运行。

    但是,为了提高可移植性和可能的​​性能,您应该更加小心一些事情。

    • 您需要一个有效的 OpenCL 实现。如果没有可用的 OpenCL 实现,这将根本不起作用 - 在这种情况下缺少 DLL。
    • 您需要 OpenCL 的 GPU 实现。最好查询所有 OpenCL 平台和设备并首选 GPU 设备
    • 您只需使用第一个可用的设备,这可能并不理想。通过启发式方法确定最强大的设备或让用户选择是一个更好的主意。

    此外,您没有正确使用 clCreateContextFromType。您需要在启用 ICD 的 OpenCL 实现上明确指定平台 ID(您可以使用 clGetPlatformIDs 查询 ID)。今天所有的 OpenCL 实现都使用 ICD 包装器。 (嗯,苹果除外)

    【讨论】:

      【解决方案2】:

      通过为 OpenCL 编写程序,它可以在任何支持您的可执行格式并具有 OpenCL 驱动程序的计算机上运行。可能是 GPU 加速的,也可能不是,并且不会像特定于硬件的机器代码那样快,但应该是相当可移植的。如果通过便携式,您的意思是 x86 CPU 架构和 Windows 操作系统,只有显卡发生变化。为了实现真正的可移植性,您需要分发 JIT 编译的源代码或字节码,而不是 C 或 C++ 二进制文件。

      【讨论】:

        【解决方案3】:

        原则上,OpenCL 代码应该在任何地方运行。但是它的实现有多个版本,1.1 和 1.2(还没有在 Nvidia 上)以及 2.0 规范发布并在某个时候发布。 OpenCL 版本之间存在 API 不兼容问题。 AMD 为其 OpenCL 1.2 实现提供了一种使用 1.1 API 调用的方法。

        上面有其他作者指出的重要警告,OpenCL ICD http://www.khronos.org/registry/cl/extensions/khr/cl_khr_icd.txt 支持运行 在不同的供应商平台上,但由于编译的内核代码没有二进制可移植性,您需要提供内核源代码。

        在一般情况下,检查 OpenCL 平台版本和配置文件。请记住,一个系统上很容易有多个平台和设备。然后确定可以运行的最低平台版本和配置文件。如果您的代码依赖于特定的设备扩展,例如双精度浮点,那么您需要检查它们是否存在于设备上。

        使用

        clGetPlatformInfo( ...  )
        

        获取平台配置文件和版本。

        使用

         clGetDeviceInfo( ... )
        

        获取设备特定的扩展

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-15
          • 1970-01-01
          • 1970-01-01
          • 2012-05-19
          相关资源
          最近更新 更多