0

我有以下代码行,gamma是一个 CPU 变量,之后我需要复制到 GPU。gamma_x并且delta也存储在CPU上。有什么方法可以执行以下行并将其结果直接存储在 GPU 上?所以基本上,在 GPU 上 host gammagamma_xdelta在 GPU 上获得以下行的输出。之后的行会大大加快我的代码速度。我试过了,magma_dcopy但到目前为止我找不到让它工作的方法,因为它的输出magma_ddot是 CPU 的两倍。

gamma = -(gamma_x[i+1] + magma_ddot(i,&d_gamma_x[1],1,&(d_l2)[1],1, queue))/delta;
4

1 回答 1

1

非常简短的回答是否定的,你不能这样做,或者至少如果你使用magma_ddot.

但是,magma_ddot它本身只是一个非常薄的包装器cublasDdot,并且 cublas 函数完全支持将操作结果存储在 GPU 内存中而不是返回给主机。

理论上你可以这样做:

// before the apparent loop you have not shown us:
double* dotresult;
cudaMalloc(&dotresult, sizeof(double));

for (int i=....) { 
    // ...

    // magma_ddot(i,&d_gamma_x[1],1,&(d_l2)[1],1, queue);
    cublasSetPointerMode( queue->cublas_handle(), CUBLAS_POINTER_MODE_DEVICE);
    cublasDdot(queue->cublas_handle(), i, &d_gamma_x[1], 1, &(d_l2)[1], 1, &dotresult);
    cudaDeviceSynchronize();
    cublasSetPointerMode( queue->cublas_handle(), CUBLAS_POINTER_MODE_HOST);

    // Now dotresult holds the magma_ddot result in device memory

    // ...

}

请注意,这可能会使 Magma 爆炸,具体取决于您使用它的方式,因为 Magma 在内部使用 CUBLAS 并且在 Magma 内部如何处理 CUBLAS 状态和异步操作是完全没有记录的。话虽如此,如果你小心,应该没问题。

然后执行你的计算,要么编写一个非常简单的内核并用一个线程启动它,要么使用一个简单的带有 lambda 表达式的推力调用,这取决于你的偏好。我把它作为练习留给读者。

于 2019-05-10T08:54:02.633 回答