使用CUBLAS例程在GPGPU上保留点积

use*_*690 3 cuda gpgpu dot-product cublas

我正在编写一个代码,使用点积的CUBLAS例程计算两个向量的点积,但它返回主机内存中的值.我想使用点积来进一步计算GPGPU.如何使值仅驻留在GPGPU上并将其用于进一步计算而无需从CPU到GPGPU的显式复制?

tal*_*ies 12

只要使用"V2"API,就可以在CUBLAS中执行此操作.较新的API包含一个函数cublasSetPointerMode,您可以使用该函数将API设置为假定所有返回标量值的例程将传递给设备指针而不是主机指针.这在最新的CUBLAS文档的第2.4节中讨论.例如:

#include <cuda_runtime.h>
#include <cublas_v2.h>
#include <stdio.h>

int main(void)
{
    const int nvals = 10;
    const size_t sz = sizeof(double) * (size_t)nvals;
    double x[nvals], y[nvals];
    double *x_, *y_, *result_;
    double result=0., resulth=0.;

    for(int i=0; i<nvals; i++) {
        x[i] = y[i] = (double)(i)/(double)(nvals);
        resulth += x[i] * y[i];
    }

    cublasHandle_t h;
    cublasCreate(&h);
    cublasSetPointerMode(h, CUBLAS_POINTER_MODE_DEVICE);

    cudaMalloc( (void **)(&x_), sz);
    cudaMalloc( (void **)(&y_), sz);
    cudaMalloc( (void **)(&result_), sizeof(double) );

    cudaMemcpy(x_, x, sz, cudaMemcpyHostToDevice);
    cudaMemcpy(y_, y, sz, cudaMemcpyHostToDevice);

    cublasDdot(h, nvals, x_, 1, y_, 1, result_);

    cudaMemcpy(&result, result_, sizeof(double), cudaMemcpyDeviceToHost);

    printf("%f %f\n", resulth, result);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用CUBLAS_POINTER_MODE_DEVICEmake cublasDdot假设它result_是设备指针,并且没有尝试将结果复制回主机.请注意,这会使例程dot异步,因此您可能需要密切关注设备和主机之间的同步.


har*_*ism 5

确切地说,您不能使用 CUBLAS。根据 talonmies 的回答,从 CUBLAS V2 api (CUDA 4.0) 开始,返回值可以是设备指针。参考他的回答。但是如果你使用的是 V1 API,它是一个单一的值,所以将它作为参数传递给使用它的内核是非常简单的——你不需要显式cudaMemcpy(但是为了返回一个主机值,有一个隐含的) )。

从 Tesla K20 GPU 和 CUDA 5 开始,您将能够使用 CUDA 动态并行性从设备内核调用 CUBLAS 例程。这意味着您可以cublasSdot__global__内核函数内部调用(例如),因此您的结果将在 GPU 上返回。

  • 马克,这不是真的。从 CUBLAS 4.0 开始(或每当 V2 API 发布时),结果参数可以是主机或设备指针,并且调用将很乐意将结果保存在设备内存中。 (2认同)