明らかな何かを見落としているだけかどうかはわかりませんが、周りをグーグルで調べているにもかかわらず、BLAS操作を使用してベクトル(または行列)にスカラーを単純に追加する方法がわかりません。私はcuBLAS/CUDAでこれを実行しようとしているので、そのフレームワーク内でこれを達成するためのあらゆる方法を取ります。BLASに<t>scal
はスカラー乗法(cublas<t>scal
)がありますが、加算のアナログはどこにありますか?!つまり、GSLに類似したものですgsl_vector_add_constant
。私は何が欠けていますか?
2 に答える
おそらく、あなたが求めていることを行う唯一の方法はaxpy
、追加したい定数でスケーリングされた同じサイズの単位ベクトルを適用することです。
したがって、操作はになります。これは、の各エントリにX <- X + alpha * I
追加するのと同じです。alpha
X
編集:
コメントから、SAXPY呼び出しの単位ベクトルを作成するのは難しいと予想されているようです。これを行う1つの方法は、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;
}
ここで、CUBLASヘルパー関数(とにかくランタイムAPI呼び出しの非常に薄いラッパーのみ)を使用するのではなく、CUDAランタイムAPIを直接使用してCUBLASベクトルにメモリを割り当ててコピーしたことに注意してください。「トリッキー」な部分は、ビットパターンを作成し、ドライバー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;
}
}
[免責事項:このカーネルはブラウザで記述されており、テストされていません。自己責任として使用]
最良から最悪の順にランク付けされた 4 つのオプション:
- 別のライブラリで必要な関数を見つける
- 必要な機能を自分で実装する
- 定数ベクトルを割り当てて初期化し、それを で使用し
*axpy
ます。 - 0 のストライドは正式には BLAS でサポートされていませんが、一部の実装では、必要な意味でストライド 0 のベクトルを「スカラー」として扱います。多分cuBLASはそうします。ただし、これに依存することは本当に悪い考えです(非常に悪いので、言及しないことを強く検討しました)。この動作は BLAS ではサポートされていません。nvidia が BLAS よりも強力な API 保証を行わない限り、コードは移植性がなく、将来のバージョンのライブラリによって壊れる可能性さえあります。