スポンサーリンク

CUDAでグラデーション画像を作成

 

CUDAでグラデーション画像を作成する。

勉強中なので突っ込みどころは多そうだが、気をつけたところは、

・1ブロック内のスレッド数を512以下にする

・1ブロック内のスレッド数を32の倍数にする(ワープの単位)

 

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <cstring>
void pnmP3_Write(const char* const fname, const int vmax, const int width, const int height, const unsigned char* const p);

///////////////////////////////////////////////
// GPU側 ////////////////////////////////////// 
__global__ void gradation(unsigned char* c,const int N) {

  //アクセス法
  //このスレッドが担当する画素の位置を二次元座標で求める
  size_t xpos = blockIdx.x * blockDim.x + threadIdx.x;
  size_t ypos = blockIdx.y * blockDim.y + threadIdx.y;

  if (xpos < N && ypos < N) {
    size_t pos = N*ypos + xpos;//二次元座標を一次元座標に
    float R = ypos / (float)N;
    float G = (N - ypos) / (float)N;
    float B = xpos / (float)N;
    c[pos * 3 + 0] = R * 255;//0~255にして色書き込み
    c[pos * 3 + 1] = G * 255;
    c[pos * 3 + 2] = B * 255;
  }
}
//////////////////////////////////////////
//CPU側エントリーポイント///////////////////
int main(void) {

  //作成画像 N × N × 3
  const int N = 1000;

  //16×16の領域に分けて計算する
  dim3 block(16, 16);

  //グリッド数
  dim3 grid(N / 16+1, N / 16 + 1);

  unsigned char* p_gpu;//GPU側メモリ確保
  cudaMalloc((void**)&p_gpu, N * N * 3);
  gradation << <grid, block >> > (p_gpu,N);

  //CPU側メモリ確保
  unsigned char *p_cpu = new unsigned char[N * N * 3];
  //GPU→CPU側へメモリコピー
  cudaMemcpy(p_cpu, p_gpu, N*N*3, cudaMemcpyDeviceToHost);
  cudaFree(p_gpu);

  //ファイル出力
  pnmP3_Write("C:\\test\\hello.ppm", 255, N, N, p_cpu);

  delete[] p_cpu;

  getchar();
}
/////////////////////////////////////////////
//画像ファイル書き出し/////////////////////////
//! @brief PPM(RGB各1byte,カラー,テキスト)を書き込む
//! @param [in] fname ファイル名
//! @param [in] vmax 全てのRGBの中の最大値
//! @param [in] width 画像の幅
//! @param [in] height 画像の高さ
//! @param [in] p 画像のメモリへのアドレス
//! @details RGBRGBRGB....のメモリを渡すと、RGBテキストでファイル名fnameで書き込む
void pnmP3_Write(const char* const fname, const int vmax, const int width, const int height, const unsigned char* const p) { // PPM ASCII

  FILE* fp = fopen(fname, "wb");
  fprintf(fp, "P3\n%d %d\n%d\n", width, height, vmax);

  size_t k = 0;
  for (size_t i = 0; i < (size_t)height; i++) {
    for (size_t j = 0; j < (size_t)width; j++) {
      fprintf(fp, "%d %d %d ", p[k * 3 + 0], p[k * 3 + 1], p[k * 3 + 2]);
      k++;
    }
    fprintf(fp, "\n");
  }

  fclose(fp);
}

 

 

 

 

 

 

 

 

 

 

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: