• 締切済み

CUDAプログラムが実行できません。

行列の加算プログラムを作成したいのですが、どうもGPUとのやり取りがうまくいってないみたいです。 コンパイルは通るのですが、ホスト側で0を渡して計算結果をデバイス側から返すはずなのですが、計算結果ではなく0が返ってきます。 なので、GPUとのやり取りの部分だけを抜粋したプログラムを載せるので、ご指摘よろしくお願いします。 環境はUbuntu12.04.、CUDA5.0、GPUはtesla k20です。 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <cublas.h> #define N 64 #define BLOCK 16 __global__ void matrixMul(int* inMatA); int main(int argc,char** argv){ //cudaError_t CuErr; int matrixSize=sizeof(unsigned int)*N*N; int* hMatA; hMatA=(int*)malloc(matrixSize); int x,y; for(x=0;x<N;x++){ for(y=0;y<N;y++){ hMatA[x*N+y]=1; } } printf("hMatA \n"); for(x=0;x<N;x++){ for(y=0;y<N;y++){ printf("%d ",hMatA[x*N+y]); } printf("\n"); } int* dMatA; cudaMalloc((void**)&dMatA, matrixSize); cudaMemcpy(dMatA, hMatA, matrixSize, cudaMemcpyHostToDevice); dim3 block(BLOCK,BLOCK); dim3 grid(N/BLOCK,N/BLOCK); matrixMul<<<grid,block>>>(dMatA); cudaThreadSynchronize(); cudaMemcpy(hMatA, dMatA, matrixSize, cudaMemcpyDeviceToHost); printf("hMatA \n"); for(x=0;x<N;x++){ for(y=0;y<N;y++){ printf("%d ",hMatA[x*N+y]); } printf("\n"); } free(hMatA); cudaFree(hMatA); cudaThreadExit(); } __global__ void matrixMul(int* inMatA){ int x,y; for(y=0;y<N;y++){ for(x=0;x<N;x++){ inMatA[x+y*N]=0; } } }

みんなの回答

  • ki073
  • ベストアンサー率77% (491/634)
回答No.3

No.1,2です。 >inMatA[x+y*N]=0; >はループを逆にするか、xyを入れ替える方が良いです 勘違いです。質問欄のプログラムが正解です。コンパイルするときに私自身が少し書き換えたのでその時に間違えたのが原因でした。 すみませんでした。

  • ki073
  • ベストアンサー率77% (491/634)
回答No.2

こちらはtesla k20ではなく普通のGPUですが、質問欄のプログラムをそのままnvccでコンパイルしましたが、正常に動きますよ。 最初は1だけの出力、その次に0だけの出力になります。 tesla k20でのバグの報告もあるようです。CUDA5.5が出ていますので、それにされてはいかがでしょうか? http://on-demand.gputechconf.com/gtc/2013/jp/sessions/4006.pdf 余談ですが、最後の inMatA[x+y*N]=0; はループを逆にするか、xyを入れ替える方が良いです。他はちゃんとなっていますので気がつかれているとは思いますが。

  • ki073
  • ベストアンサー率77% (491/634)
回答No.1

openACCしか使っていないので、完全に理解していませんが、 質問欄のプログラムは正しく動いているように見えます。 プログラム自体は1を配列に入れ、device側で0を埋めていますので、当然そうなります。

taiti_023
質問者

補足

補足です。 ホスト側で0をを渡して0が返ってくると書きましたが、 ホスト側で1を渡す→デバイス側で0に変更→ホスト側に0を返す→ホスト側を表示するが1のまま の間違いでしたすみません。

関連するQ&A

  • Cの九九を表示するプログラムについて

    九九の表示を変えたいんですけど #include <stdio.h> int main(void) { int x,y; for (x = 1;x <= 9;x++) { for (y = 1;y <= 9;y++) { printf(" %2d ", x * y); } printf("\n"); } return 0; } これを実行すると 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 . . 9 . . . . . . . 81 となるのですが、これを 1 * 1 1 * 2 1 * 3 . . . 1 * 9 1 * 2 . . 1 * 9 . . . . . 9 * 9 と表示させたいのですがどなたか知恵を貸していただきませんでしょうか?

  • RPGゲームの簡単なプログラムを打ってみたんですがうまく表示されません

    RPGゲームの簡単な初歩的なサンプルプログラムを自分で打ってみたんですが、思った通りに表示されません。 以下のソースのどこかおかしいとこありますでしょうか。 #include<stdio.h> #include<windows.h> #define MAP_SIZE_Y 10 #define MAP_SIZE_X 10 int x = 4,y = 5; int j,i; int map[100][100] = { {1,1,1,1,1,1,1}, {1,0,0,3,0,0,1}, {1,0,0,0,0,0,1}, {1,0,2,0,2,0,1}, {1,0,0,0,0,0,1}, {1,1,1,1,1,1,1}, }; void DrawMap(){ for(j = 0; i < MAP_SIZE_Y; j++){ for(i = 0; i < MAP_SIZE_X; i++){ if(j == y && i == x){ printf("勇"); }else{ switch ( map[j][i]){ case 1: printf("■"); break; case 2: printf("兵"); break; case 3: printf("王"); break; default:printf(" "); break; } } } printf("\n"); } } void main(){ while(1) { system("cls"); DrawMap(); } }

  • プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結

    プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結果にならないので教えていただけませんか? 下記に記したプログラムを実行すると x=9 y=-9 [ 9]*[-9]=[ -81],[ 9]*[-8]=[ -72],[ 9]*[-7]=[ -63],・・・・ ・・・・ [10]*[-9]=[ -90],[10]*[-8]=[-80],・・・・ ・・・・ のようになるのですが、 x=9 y=-9 [ 9]*[-9]=[ -81],[10]*[-9]=[-90],・・・ [ 9]*[-8]=[ -72],[10]*[-8]=[-80],・・・ [ 9]*[-7]=[ -63],・・・ ・・・・ のようにするためにはどうすればいいですか? #include <stdio.h> int main(void) { int x,y,m,n; printf("x="); scanf("%d",&x); printf("y="); scanf("%d",&y); for(m=x;m<=x+3;m++) { printf("\n"); for(n=y;n<=y+14;n++) { printf("[%2d]*[%2d]=[%4d],",m,n,m*n); } printf("\n"); } return(0); }

  • for文を使ったプログラムで困っています

    for文を使って、10000からある数xを何回引けるか?またその残りを求めるプログラム(例:10000から3000は3回引くことができ、残りは1000である。)を作りたいのですが、引く回数が1多くなってしまいます。どこがいけないかわからないので困っています。よろしくおねがいします。 #include<stdio.h> void main() { int x; int Sa = 10000; int y; printf("10000以下の数を入力してください:"); scanf("%d",&x); for(y = 1; y*x <= 10000 ; y++) { Sa = Sa - x; } printf("10000から%d回引くことができます。\n",y); printf("残りは%dです。",Sa); }

  • プログラムの改良。

    うまく改良できなくて困っています。 このプログラムを #include <stdio.h> #include <stdlib.h> /* データ用変数 */ struct xy {  int x;  int y; } *hil; int idx; /* ヒルベルトスキャン */ void hilbert(int n, int p, int x, int y) {  if (n>1) {   hilbert(n/2, (p+4)%8, x+(p&1)*(n/2), y+((p>>1)&1)*(n/2));   hilbert(n/2, p, x+((((p>>1)^(p>>2)))&1)*(n/2), y+(~(p^(p>>2))&1)*(n/2));   hilbert(n/2, p, x+(~p&1)*(n/2), y+(~(p>>1)&1)*(n/2));   hilbert(n/2, 7-p, x+(~((p>>1)^(p>>2))&1)*(n/2), y+((p^(p>>2))&1)*(n/2));  } else {   hil[idx].x=x; hil[idx].y=y; idx++;  } } int main(void) {  int i,n;  /* nの入力と領域確保 */  printf("n? "); scanf("%d",&n);  if((hil=(struct xy*)malloc(sizeof(struct xy)*(1<<n)*(1<<n)))==NULL) {   printf("malloc error\n"); return -1;  }  /* ヒルベルトスキャン */  idx=0; hilbert((1<<n),4,0,0);  /* データ表示 */  for (i=0; i<idx; i++) {   printf("%d ([d %d]\n",i,hil[i].x,hil[i].y);  }  /* 領域開放 */  free(hil);  return 0; } 実行結果はn?8 0 [0 0] 1 [0 1] ・ ・ 65534 [0 254] 65535 [0 255] と表示されます。これを buf[0]=img[hil[0].x][hil[0].y][0] buf[1]=img[hil[0].x][hil[1].y][0] ・ ・ buf[65534]=img[hil[0].x][hil[254].y][0] buf[65535]=img[hil[0].x][hil[255].y][0] と表示させたいのですがうまくできません。どこを改良すればいいでしょうか?お願い致します。 buf[]の中身は0から256*256-1を表しています。

  • N王妃システムの解のタイム計算

    先輩方にご協力をお願いしたく書き込みさせていただきます。 #include <stdio.h> #define FREE 0 #define BUSY 1 #define N 8 int q_pos[N+1]; int colum[N+1]; int r_up[2*N]; int r_dw[2*N]; void disp(void) { int y,x; static count = 0; printf("\n解 %d\n", ++count); for(y=1;y<=N; y++){ for(x=1;x<=N; x++){ if (q_pos[y] == x)printf("○"); else printf("×"); } printf("\n"); } } void eight_queens(int y) { int x; for (x=1; x<=N; x++){ if(colum[x]==FREE && r_up[y+x-1]==FREE && r_dw[y-x+N]==FREE){ q_pos[y]=x; if (y>=N) disp(); else{ colum[x]=BUSY; r_up[y+x-1]= r_dw[y-x+N]=BUSY; eight_queens(y+1); colum[x]=FREE; r_up[y+x-1]= r_dw[y-x+N]=FREE; } } } } int main(void) { int i; for(i=1;i<=N; i++) colum[i]=FREE; for(i=1;i<2*N;i++) r_up[i]= r_dw[i]=FREE; eight_queens(1); return 0; } こちらのプログラムに #include<stdio.h> #include<stdlib.h> #include<time.h> void sleep(clock_t wait); void main(void) { int i,j,n; time_t start,finish; double duration,v; printf("繰り返し回数は>"); scanf("%d",&n); time(&start); v=1.01; for(i=0; i<n; i++) { if(((i+1)% 10)==0) { fprintf(stdout,"."); fflush(stdout); } for(j=0; j<n; j++) { v *=1.0001; } } printf("\n"); time(&finish); duration=difftime(finish,start); printf("計算にかかった時間は約%6.2f 秒です \n", duration); } のプログラムを合体させ、1つのプログラムを完成させたいのですが、どのような配列にしたらいいのか教えて欲しいです>< アルゴリズムとしては、チェスのN王妃のプログラムから解を導きだすと同時に、そのプログラムを起動してから終わりまでのタイムを計算するプログラムを挿入すると言う内容です。 長くてすいません;;

  • 組織的ディザ法のプログラムがうまくいきません

    下記のプログラムはPGM画像に組織的ディザ法を行い、2値化を行うプログラムなのですがうまく作動しません。 どこがダメなのかわかる方回答お願いします。 また、PGMのフォーマットをP5しか読み込むことしか出来ないのですが、これを P2のアスキーで読み込めるように変更できないでしょうか? /* 組織的ディザ法のプログラム dither.c */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include"mypgm.h" #define BLOCK_SIZE 4 /* ブロックの横(=縦)画素数 */ #define NEW_LEVEL 16 /* 擬似階調数(= BLOCK_SIZE の2乗) */ #define MAXWIDTH 1000 #define MAXHEIGHT 1000 /* 原画像 image1[y][x] のディザ画像を作り image2[y][x] に代入 */ void make_dither_image( ) { double width; /* 16段階画像の階調値の単位幅 */ int x,y,i,j,m,n; int x_block = x_size1 / BLOCK_SIZE; /* 横のブロック数 */ int y_block = y_size1 / BLOCK_SIZE; /* 縦のブロック数 */ int gray_16 = (int)( image1[y][x] / width ); /* 新しい階調(16階調での値) */ /* Bayer 型ディザ行列 */ int dither_matrix [4][4] = { { 0, 8, 2, 10}, {12, 4, 14, 6}, { 3, 11, 1, 9}, {15, 7, 13, 5} }; /* 横,縦の画素数がBLOCK_SIZEの倍数であるかのチェック */ if ( x_size1 % BLOCK_SIZE != 0 || y_size1 % BLOCK_SIZE != 0 ){ printf("原画像の横・縦の画素数が不適切です.\n"); exit(1); } /* 16階調の画像を作る */ //一度、画像を16階調に変換して(正確にはディザブロック分の1)さらに2階調(白黒)に変換する。 width = MAX_BRIGHTNESS / (double)NEW_LEVEL; x_size2 = x_size1; y_size2 = y_size1; for (y = 0; y < y_size1; y ++ ){ for (x = 0; x < x_size1; x ++ ){ if ( gray_16 > NEW_LEVEL - 1 ) gray_16 = NEW_LEVEL - 1; image2[y][x] = (unsigned char)gray_16; } } /* ディザ画像を作る */ printf("ディザ画像を作ります.\n"); for (i = 0; i < y_block; i ++ ){ for (j = 0; j < x_block; j ++ ){ int x = BLOCK_SIZE * j; int y = BLOCK_SIZE * i; for (m = 0; m < BLOCK_SIZE; m ++ ){ for (n = 0; n < BLOCK_SIZE; n ++ ){ if ( image2[y + m][x + n] <= dither_matrix[m][n] ) image2[y + m][x + n] = 0; else image2[y + m][x + n] = MAX_BRIGHTNESS; } } } } } 【mypgm.h】 http://cis.k.hosei.ac.jp/~wakahara/mypgm.h

  • プログラムの最適化について質問です。

    プログラムの最適化について質問です。 /* 課題7 */ #include<stdio.h> #define A n /* n=10^0~9 */ void main() { int a,x; for(a=0;a<A;a++){ x=x+1; } } /* 課題8 */ #include<stdio.h> #define A n /* n=10^0~9 */ void main() { int a,x; for(a=0;a<A;a++){ x++; } } 課題7に比べて課題8の記述のメリットとして、単にソースコードを短くできる以外に、何が考えられるか。 という質問に対しての答えが分かりません。解説お願いします。

  • C言語を実行すると-infが出てきて困っています。

    C言語を実行すると-infが出てきて困っています。 コンパイラはgccを使っています。 よろしくお願いします。 #include <stdio.h> #include <math.h> #include <stdlib.h> #define data 100//計算回数 double seiki(void)//正規乱数 { double n; double i; double y; double x1,x2; double sigma; double mean; double Pi = 2*asin(1); sigma = 1; mean = 0; { x1 = (double)rand()/(RAND_MAX); x2 = (double)rand()/(RAND_MAX); y = sigma*sqrt(-2*log(x1))*sin(2*Pi*x2) + mean; //printf("%f\n",y); } return (y); } int main(void) { double* price; int i, j, k; double a, b, c; //メモリ確保 price=(double*)malloc(sizeof(double)*data+10); for(i = 0;i<data;i++) { price[i+1] = price[i]+seiki(); printf("%lf\n",price[i+1]); } return 0; }

  • 3目並べのプログラムについての質問です

    以下のようにプログラムをつくりました #include <stdio.h> #include <stdlib.h> #include <time.h> void cleanSquare(void); void hand(char); void hand_CPU(char); void printSquare(void); void judge(void); void three(char, char, char); char square[3][3]; int nokori = 9; int main( void ) { cleanSquare(); printSquare(); while(1) { printf("Your turn.\n"); printf("Input (x,y) :"); hand('o'); printf("CPU chose (x,y):"); hand_CPU('x'); } } void cleanSquare(void) { int x, y; for(x = 0; x < 3; x++) { for(y = 0; y < 3; y++ ) { square[x][y] = ' '; } } } void hand(char mark) { int h, v; scanf("%1d%1d", &h, &v); while(square[h][v] != ' ' ) { printf("%1d-%1dは埋まっています。再入力(横縦):", h, v); scanf("%1d%1d", &h, &v); } square[h][v] = mark; nokori--; printSquare(); judge(); if(!nokori) { printf("引き分け\n"); exit(1); } } void hand_CPU(char mark) { int h, v; srand(time(NULL)); //scanf("%1d%1d", &h, &v); h = rand() % 3; v = rand() % 3; printf("(%d,%d)\n", h, v); while(square[h][v] != ' ' ) { printf("%1d-%1dは埋まっています。再入力(横縦):", h, v); scanf("%1d%1d", &h, &v); } square[h][v] = mark; nokori--; printSquare(); judge(); if(!nokori) { printf("Tie \n"); exit(1); } } void printSquare(void) { int cnt; printf("\n 0 1 2\n"); printf(" -------------\n"); for(cnt = 0; cnt < 3; cnt++) { printf("%1d| %c | %c | %c |\n", cnt, square[0][cnt], square[1][cnt], square[2][cnt]); printf(" -------------\n"); } } void judge(void) { int x, y; for(y = 0; y < 3; y++) { three(square[0][y], square[1][y], square[2][y]); for(x = 0; x < 3; x++) { three(square[x][0], square[x][1], square[x][2]); three(square[0][0], square[1][1], square[2][2]); three(square[2][0], square[1][1], square[0][2]); } } } void three(char a, char b, char c) { if(a == ' ') { return; } if(a == b && b == c) { if(a == 'o') { printf("Win! \n"); } else { printf("Lose. \n"); } exit(1); } return; } 以前、学校の課題としてでたものを復習していたのですが、わからない部分がでてきました。 このプログラムを次のように改造したいのですが、どのように改造すればいいのかわかりません 1.ゲーム全体を関数化する main関数でこの関数を呼び出すと何回もゲームができるようにする int game(int n)と宣言しようと考えています 2.マス目の大きさを関数game()が引数として受け取ったnを、n×nのマス目でゲームができるようにする nは、ゲームごとにmain関数で入力 10×10までの大きさ 3.自分の番の時に、座標を入力する時に負の値が入力されたら、ゲームを終了させる 4.勝敗の記録と表示 例えば、引き分けを0、勝ちを1、負けを2、途中終了を-1 を戻り値として返すようにして、途中終了以外の場合はゲームの成績を 勝ち:3、負け:2、引き分け:0のように表示する 5.ゲーム終了後に続けるか、やめるかの選択 文字を一文字入力して、'y'なら1を返し、'n'なら0を返す それ以外の文字だったら、再入力させるという処理を関数化する int newgame(void)として宣言しようと考えています また、この関数の戻り値が0の場合プログラムの終了、1なら新しいゲームの開始 です。長くて申し訳ないですm(_ _)m よろしくお願いしますm(_ _)m

専門家に質問してみよう