0

次のコードをインターネットからコピーし、Tesla C2075 がインストールされているサーバーでコンパイルしようとしましたが、倍精度をサポートする必要があります。また、フラグ sm_20 を使用してコードをコンパイルします。

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cuda_runtime.h>
#include <cuComplex.h>
#include <cublas_v2.h>

using namespace std;

typedef double2 Complex;

#define m 1024
#define n 300
#define k 1024

int main(int argc, char *argv[])
{
  Complex _A[m*k], _B[k*n];
  Complex *A, *B;

  cudaMalloc((void**)&A, m*k*sizeof(Complex));
  cudaMalloc((void**)&B, k*n*sizeof(Complex));

  for (int i=0; i<m*k; i++) _A[i] = make_cuDoubleComplex(rand()/(double)RAND_MAX, rand()/(double)RAND_MAX);;
  for (int i=0; i<k*n; i++) _B[i] = make_cuDoubleComplex(rand()/(double)RAND_MAX, rand()/(double)RAND_MAX);

  cudaMemcpy( A, _A, (m*k)*sizeof(Complex), cudaMemcpyHostToDevice );
  cudaMemcpy( B, _B, (k*n)*sizeof(Complex), cudaMemcpyHostToDevice );

  return 0;
}

コンパイルはしますが、実行時には常に「セグメンテーション エラー (コア ダンプ)」が返されます。コードに何か問題がありますか?ありがとう。

4

1 に答える 1

3

配列が大きすぎてスタックに収まらない可能性があります_A_B簡単な修正方法は、配列をグローバル スコープに移動することです。より良い修正は、次のように new と delete を使用してそれらを動的に割り当てることです。

Complex *_A = new Complex[m*k];
Complex *_B = new Complex[k*n];
...
delete [] _A;
delete [] _B;

C++ を使用しているため、さらに良いオプションは std::vector を使用することです。

std::vector < Complex > _A(m*k);
std::vector < Complex > _B(k*n);

// But now to get the pointer you need this:
cudaMemcpy( A, &_A[0], (m*k)*sizeof(Complex), cudaMemcpyHostToDevice );
// etc.

その&_A[0]構文は、配列全体へのポインターと同じである、ベクトルの最初の要素のアドレスを取得することを意味します。メモリを手動で割り当てるよりもベクトルを優先する理由は、変数がスコープ外になると破棄/割り当て解除が自動的に行われるためです。これは、例外セーフ コードを記述するために不可欠です。

また、必要になります#include <vector>

于 2013-09-10T14:22:05.397 に答える