非常简短的回答是否定的,你不能这样做,或者至少如果你使用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 表达式的推力调用,这取决于你的偏好。我把它作为练习留给读者。