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); }