の行列とサイズ1×Nの行列を乗算するカーネル関数を設計しなければならないのはどのように持っていますこの問題の解決策を今すぐ見つけました:
#include <stdio.h>
#include <iostream>
using namespace std;
__global__
void kernel(float *a, float *b, float *c, int N, int M) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
float sum = 0;
if (tid < M) {
for (int i = 0; i < N; i++)
sum += a[i] * b[(i * M) + tid];
c[tid] = sum;
}
}
int main(void) {
float *dev_a, *dev_b, *dev_c;
int N = 16;
int M = 12;
float a[N];
float b[N][M];
float c[M];
for (int i = 0; i < N; i++) {
a[i] = 1.0;
}
for (int i = 0; i < N; i++) {
for (int e = 0; e < M; e++) {
b[i][e] = 1.0;
}
}
cudaMalloc((void**) &dev_a, sizeof(float) * N);
cudaMalloc((void**) &dev_b, sizeof(float) * N * M);
cudaMalloc((void**) &dev_c, sizeof(float) * M);
cudaMemcpy(dev_a, a, sizeof(float) * N, cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, b, sizeof(float) * N * M, cudaMemcpyHostToDevice);
kernel<<<M/256 + 1, 256>>>(dev_a, dev_b, dev_c, N, M);
cudaMemcpy(c, dev_c, sizeof(float) * M, cudaMemcpyDeviceToHost);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
for (int i = 0; i < M; i++) {
cout << c[i] << endl;
}
return 0;
}
しかし、私はまだ1つの質問があります。パフォーマンス上の理由からカーネル内のforループ操作をいくつかのカーネルで分割するのは理にかなっていますか?
「サイズNのマトリックス」 - あなたはN×Nを意味しますか? – PRP
私はここでの質問を理解していません。関与する行列の他の次元に関係なく、行と列の内積であるコード(ループ内のストアはなぜですか?)は変わりません。 – talonmies
いいえ、1次元行列Nに2次元行列N x Mを掛けたいと思います。結果を格納する行列はMでなければなりません。 @talonmies、私は上記のコードを変更していない。 N x Nの2つの行列を掛けるのは問題ありませんが、非正方行列の場合は、 "a index"の高さパラメータを使用していますが、これは役に立ちません – avaj