我不知道我是否只是忽略了一些明显的东西,但是尽管在谷歌上搜索了一下,但我看不到使用 BLAS 操作简单地将标量添加到向量(或矩阵)的方法。我正在尝试在 cuBLAS/CUDA 中执行此操作,因此我将采取任何方式在该框架内完成此操作。BLAS 具有<t>scal
标量乘法 ( cublas<t>scal
) 但加法的模拟量在哪里?!即类似于 GSL的东西gsl_vector_add_constant
。我错过了什么?
问问题
5559 次
2 回答
4
可能完成您所要求的唯一方法是应用axpy
相同大小的单位向量,该向量由您要添加的常数缩放。
所以操作就变成了X <- X + alpha * I
,相当于把里面alpha
的每一项都加进去了X
。
编辑:
从评论中,您似乎预见到为 SAXPY 调用创建单位向量时会遇到一些困难。一种方法是使用 memset 调用在设备上设置单位向量的值,如下所示:
#include "cuda.h"
#include "cuda_runtime_api.h"
#include "cublas_v2.h"
#include <iostream>
int main(void)
{
const int N = 10;
const size_t sz = sizeof(float) * size_t(N);
float *A, *I;
float Ah[N] = { 0., 1., 2., 3., 4., 5., 6., 7., 8., 9. };
cudaMalloc((void **)&A, sz);
cudaMemcpy(A, &Ah[0], sz, cudaMemcpyHostToDevice);
// this creates a bit pattern for a single precision unity value
// and uses 32-bit memset from the driver API to set the values in the
// vector.
const float one = 1.0f;
const int* one_bits = reinterpret_cast<const int*>(&one);
cudaMalloc((void **)&I, sz);
cuMemsetD32(CUdeviceptr(I), *one_bits, N);
cublasHandle_t h;
cublasCreate(&h);
const float alpha = 5.0f;
cublasSaxpy(h, N, &alpha, I, 1, A, 1);
cudaMemcpy(&Ah[0], A, sz, cudaMemcpyDeviceToHost);
for(int i=0; i<N; i++) {
std::cout << i << " " << Ah[i] << std::endl;
}
cublasDestroy(h);
cudaDeviceReset();
return 0;
}
请注意,我直接使用 CUDA 运行时 API 为 CUBLAS 向量分配和复制了内存,而不是使用 CUBLAS 辅助函数(无论如何,它们只是运行时 API 调用的非常薄的包装器)。“棘手”部分是制作位模式并使用驱动程序 API memset 函数来设置数组的每个 32 位字。
您同样可以使用来自推力库的几行模板代码来完成整个事情,或者只是编写自己的内核,这可能就像
template<typename T>
__global__
void vector_add_constant( T * vector, const T scalar, int N)
{
int tidx = threadIdx.x + blockIdx.x*blockDim.x;
int stride = blockDim.x * gridDim.x;
for(; tidx < N; tidx += stride) {
vector[tidx] += scalar;
}
}
[免责声明:此内核是在浏览器中编写的,未经测试。使用风险自负]
于 2012-12-27T07:56:17.237 回答
4
四个选项,从最好到最差排列:
- 在不同的库中找到您需要的功能
- 自己实现需要的功能
- 分配并初始化一个常量向量,将其与
*axpy
. - 尽管 BLAS 正式不支持步幅为零,但某些实现将步幅为 0 的向量视为您想要的“标量”。也许 cuBLAS 可以。然而,依赖这个是一个非常糟糕的主意(糟糕到我强烈考虑不提它),因为这种行为不受 BLAS 的支持;您的代码将不可移植,甚至可能会被库的未来版本破坏,除非 nvidia 提供比 BLAS 更强大的 API 保证。
于 2012-12-27T16:33:54.507 回答