SlideShare a Scribd company logo
.NET から CUDA を使うひとつの方法
C++/CLI による WRAPPER のつくりかた
episthmh epi@c.zaq.jp
Microsoft MVP for Visual C++ Jan.2004~
NVIDIA CUDA Ambassador for Apr.2015~
2015-1075
Hall-B1 16:20~
WINDOWS APPLICATION
CUI
Console (stdin/stdout)
GUI
Win API
MFC
Windows Forms
WPF
native : C/C++
managed : .NET (C#,VB etc.)
legacy…
MANAGED は直接 CUDA を呼べない…
host
memory
device
memory
PCI-bus
CLR
managed app.
MANAGED と NATIVE の仲介役
host
memory
device
memory
PCI-bus
CLR
managed app.
native assembly
call
C++/CLI で作る「仲介役」
見た目(インタフェース)はmanaged
ナカミ(実装)はnative
native assembly
PCI-bus
サンプル : SAXPY
Y[i] = alpha * X[i] + Y[i] (i = 0..N-1)
C# / Windows Forms app.
絵ヅラはC#, 計算はCUDA
C++/CLIが両者を仲介
WRAPPERのつくりかた 1: CLR クラスライブラリ
WRAPPERのつくりかた 2: ビルド カスタマイズ
※ C++/CLI プロジェクト内で デバイス・コード(~.cu) をコンパイルできます
WRAPPERのつくりかた 3: CUDA RUNTIME
WRAPPERのつくりかた 4: 64BIT PLATFORM
※ CUDA 7.0 以降、多くのCUDAライブラリは 64bit-only です
SAXPY DEVICE/HOST CODE
__global__ void kernel_saxpy(float alpha, const float* x, float* y,
unsigned int size) {
unsigned int i = blockDim.x * blockIdx.x + threadIdx.x;
if ( i < size ) { y[i] = alpha * x[i] + y[i]; } // Saxpy!
}
__host__ void device_saxpy(float alpha, const float* x, float* y,
unsigned int size) {
unsigned int block = 256U; unsigned int grid = (size + block -1U)/block;
kernel_saxpy<<<grid,block>>>(alpha, x, y, size);
}
※ device-code および それを呼び出すhost-codeは ~.cu に記述します
REF CLASS SAXPY : ~.h public部
namespace CUDA {
public ref class Saxpy {
private:
…
public:
Saxpy(); // コンストラクタ
~Saxpy(); // デストラクタ
!Saxpy(); // ファイナライザ
void calculate(float alpha, cli::array<float>^ x, cli::array<float>^ y);
};
} ※ C++/CLI: cli::array<float>^ は C#: float[] に相当します
REF CLASS SAXPY : ~.h private部
namespace CUDA {
public ref class Saxpy {
private:
float* dx_; // device-memory X[]
float* dy_; // device-memory Y[]
size_t bsize_; // dx_/dy_の大きさ(bytes)
void allocate(size_t new_bsize); // dx_/dy_を確保する
void deallocate() { // dx_/dy_を解放する
cudaFree(dx_); dx_ = nullptr;
cudaFree(dy_); dy_ = nullptr;
}
…
}
※利用者(C#,VB)に成り代わって device-memory を確保/解放します
namespace CUDA {
Saxpy::Saxpy() : dx_(nullptr), dy_(nullptr), bsize_(0U) {}
Saxpy::~Saxpy() { this->!Saxpy(); } // 明示的にファイナライザを呼ぶ
Saxpy::!Saxpy() { deallocate(); } // device-mem. を解放する
…
}
※ ファイナライザ : !クラス名() をお忘れなく
REF CLASS SAXPY : ~.cpp
namespace CUDA {
void Saxpy::allocate(size_t new_bsize) {
// 足りないときは一旦解放し、再確保
if ( bsize_ < new_bsize ) {
deallocate();
bsize_ = new_bsize;
float* ptr;
cudaMalloc(&ptr, bsize_); dx_ = ptr;
cudaMalloc(&ptr, bsize_); dy_ = ptr;
}
}
}
※ cudaMalloc(&dx_, bsize_) とは書けません
namespace CUDA {
void Saxpy::calculate(float alpha, array<float>^ x, array<float>^ y) {
unsigned int size = x->Length; if ( size != y->Length ) return;
allocate((size_t)(size*sizeof(float)));
// host → device
pin_ptr<float> hx = &x[0];
cudaMemcpy(dx_, hx, size*sizeof(float), cudaMemcpyHostToDevice);
pin_ptr<float> hy = &y[0];
cudaMemcpy(dy_, hy, size*sizeof(float), cudaMemcpyHostToDevice);
// kernel-call
device_saxpy(alpha, dx_, dy_, size);
// device → host
cudaMemcpy(hy, dy_, size*sizeof(float), cudaMemcpyDeviceToHost);
}
}
※ pin_ptr<float> でピン留めします
HOW TO USE IN .NET
※ 参照設定をお忘れなく
HOW TO USE IN C# : ~.cs
public partial class Form1 : Form {
private CUDA.Saxpy saxpy = new CUDA.Saxpy(); // 作って
private void btnCalc_Click(object sender, EventArgs e) {
if ( lstX.Items.Count != lstY.Items.Count ) return;
float[] x = …;
float[] y = …;
float alpha = …;
saxpy.calculate(alpha, x, y); // 呼ぶ!
…
}
※ インスタンスを生成(new)し、メソッドを呼び出すだけ
BITMAPを扱うには?
CUDAで画像処理
構造はSaxpyとおなじ。
配列じゃなく、
Bitmapの先頭アドレスを
CUDAに渡します。
namespace CUDA {
public ref class SepiaConverter {
public:
SepiaConverter();
~SepiaConverter();
!SepiaConverter();
// image(元画像)をcolor_にコピーし、モノクロ化
void LoadImage(System::IntPtr image, int width, int height, int stride);
// モノクロ画像を色調変換し、imageにコピー
void ConvertSepia(System::IntPtr image, float u, float v);
…
};
}
※ System::IntPtr が void* に相当します
namespace CUDA {
void SepiaConverter::ConvertSepia(System::IntPtr image, float u, float v) {
// 色調変換し、結果を color_ に
…
// 結果をコピー
size_t bsize = height_ * stride_;
void* ptr = static_cast<void*>(image);
cudaMemcpy(ptr, color_, bsize, cudaMemcpyDeviceToHost);
}
}
※ System::IntPtr は void* にキャストできます
// セピア変換
private CUDA.SepiaConverter converter_; // C++/CLIで作ったwrapper
private void convert_sepia(float u, float v) {
// Bitmapを生成し、 LockBitsで固定
var bmp = new Bitmap(幅, 高さ);
var data = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb);
// 色調変換
converter_.ConvertSepia(data.Scan0, u, v);
bmp.UnlockBits(data);
picOutput.Image = bmp;
picOutput.Invalidate();
}
※ IntPtr BitmapData.Scan0 が画像の先頭アドレスです
HAVE FUN!
BLOG http://blog.zaq.ne.jp/fareastprogramming
https://www.facebook.com/cppepisteme
@epitwit
http://codezine.jp/author/352CodeZine

More Related Content

What's hot (20)

PDF
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
Fixstars Corporation
 
PDF
Chainer でのプロファイリングをちょっと楽にする話
NVIDIA Japan
 
PPTX
画像処理ライブラリ OpenCV で 出来ること・出来ないこと
Norishige Fukushima
 
PPTX
RustによるGPUプログラミング環境
KiyotomoHiroyasu
 
PDF
CUDAプログラミング入門
NVIDIA Japan
 
PDF
1072: アプリケーション開発を加速するCUDAライブラリ
NVIDIA Japan
 
PDF
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
智啓 出川
 
PDF
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Preferred Networks
 
PDF
プログラムを高速化する話Ⅱ 〜GPGPU編〜
京大 マイコンクラブ
 
PPTX
【DL輪読会】EPro-PnP: Generalized End-to-End Probabilistic Perspective-n-Pointsfor...
Deep Learning JP
 
PDF
[DL輪読会]Auto-DeepLab: Hierarchical Neural Architecture Search for Semantic Ima...
Deep Learning JP
 
PDF
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
Takateru Yamagishi
 
PDF
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
智啓 出川
 
PPTX
AVX-512(フォーマット)詳解
MITSUNARI Shigeo
 
PDF
initramfsについて
Kazuhiro Nishiyama
 
PPTX
画像処理の高性能計算
Norishige Fukushima
 
PDF
プログラムを高速化する話
京大 マイコンクラブ
 
PDF
1076: CUDAデバッグ・プロファイリング入門
NVIDIA Japan
 
PPTX
backbone としての timm 入門
Takuji Tahara
 
PDF
SSII2022 [SS1] ニューラル3D表現の最新動向〜 ニューラルネットでなんでも表せる?? 〜​
SSII
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
Fixstars Corporation
 
Chainer でのプロファイリングをちょっと楽にする話
NVIDIA Japan
 
画像処理ライブラリ OpenCV で 出来ること・出来ないこと
Norishige Fukushima
 
RustによるGPUプログラミング環境
KiyotomoHiroyasu
 
CUDAプログラミング入門
NVIDIA Japan
 
1072: アプリケーション開発を加速するCUDAライブラリ
NVIDIA Japan
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
智啓 出川
 
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Preferred Networks
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
京大 マイコンクラブ
 
【DL輪読会】EPro-PnP: Generalized End-to-End Probabilistic Perspective-n-Pointsfor...
Deep Learning JP
 
[DL輪読会]Auto-DeepLab: Hierarchical Neural Architecture Search for Semantic Ima...
Deep Learning JP
 
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
Takateru Yamagishi
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
智啓 出川
 
AVX-512(フォーマット)詳解
MITSUNARI Shigeo
 
initramfsについて
Kazuhiro Nishiyama
 
画像処理の高性能計算
Norishige Fukushima
 
プログラムを高速化する話
京大 マイコンクラブ
 
1076: CUDAデバッグ・プロファイリング入門
NVIDIA Japan
 
backbone としての timm 入門
Takuji Tahara
 
SSII2022 [SS1] ニューラル3D表現の最新動向〜 ニューラルネットでなんでも表せる?? 〜​
SSII
 

Similar to 1075: .NETからCUDAを使うひとつの方法 (20)

KEY
NVIDIA Japan Seminar 2012
Takuro Iizuka
 
PDF
Maxwell と Java CUDAプログラミング
NVIDIA Japan
 
PDF
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティング
Computational Materials Science Initiative
 
KEY
CUDAを利用したPIV解析の高速化
翔新 史
 
PDF
200625material naruse
RCCSRENKEI
 
KEY
関東GPGPU勉強会 LLVM meets GPU
Takuro Iizuka
 
PDF
C base design methodology with s dx and xilinx ml
ssuser3a4b8c
 
DOC
GPGPUによるパーソナルスーパーコンピュータの可能性
Yusaku Watanabe
 
PDF
第12回 配信講義 計算科学技術特論B(2022)
RCCSRENKEI
 
PPTX
C++ AMPを使ってみよう
Osamu Masutani
 
PDF
Altera SDK for OpenCL解体新書 : ホストとデバイスの関係
Mr. Vengineer
 
PDF
20130126 sc12-reading
Toshiya Komoda
 
PDF
20190625 OpenACC 講習会 第2部
NVIDIA Japan
 
PDF
Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93
hiyohiyo
 
PDF
怪しいWindowsプログラミング
nagoya313
 
PDF
[Basic 7] OS の基本 / 割り込み / システム コール / メモリ管理
Yuto Takei
 
PDF
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算
智啓 出川
 
KEY
PyOpenCLによるGPGPU入門
Yosuke Onoue
 
PDF
Python physicalcomputing
Noboru Irieda
 
NVIDIA Japan Seminar 2012
Takuro Iizuka
 
Maxwell と Java CUDAプログラミング
NVIDIA Japan
 
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティング
Computational Materials Science Initiative
 
CUDAを利用したPIV解析の高速化
翔新 史
 
200625material naruse
RCCSRENKEI
 
関東GPGPU勉強会 LLVM meets GPU
Takuro Iizuka
 
C base design methodology with s dx and xilinx ml
ssuser3a4b8c
 
GPGPUによるパーソナルスーパーコンピュータの可能性
Yusaku Watanabe
 
第12回 配信講義 計算科学技術特論B(2022)
RCCSRENKEI
 
C++ AMPを使ってみよう
Osamu Masutani
 
Altera SDK for OpenCL解体新書 : ホストとデバイスの関係
Mr. Vengineer
 
20130126 sc12-reading
Toshiya Komoda
 
20190625 OpenACC 講習会 第2部
NVIDIA Japan
 
Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93
hiyohiyo
 
怪しいWindowsプログラミング
nagoya313
 
[Basic 7] OS の基本 / 割り込み / システム コール / メモリ管理
Yuto Takei
 
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算
智啓 出川
 
PyOpenCLによるGPGPU入門
Yosuke Onoue
 
Python physicalcomputing
Noboru Irieda
 
Ad

More from NVIDIA Japan (20)

PDF
HPC 的に H100 は魅力的な GPU なのか?
NVIDIA Japan
 
PDF
NVIDIA cuQuantum SDK による量子回路シミュレーターの高速化
NVIDIA Japan
 
PDF
Physics-ML のためのフレームワーク NVIDIA Modulus 最新事情
NVIDIA Japan
 
PDF
20221021_JP5.0.2-Webinar-JP_Final.pdf
NVIDIA Japan
 
PDF
開発者が語る NVIDIA cuQuantum SDK
NVIDIA Japan
 
PDF
NVIDIA Modulus: Physics ML 開発のためのフレームワーク
NVIDIA Japan
 
PDF
NVIDIA HPC ソフトウエア斜め読み
NVIDIA Japan
 
PDF
HPC+AI ってよく聞くけど結局なんなの
NVIDIA Japan
 
PDF
Magnum IO GPUDirect Storage 最新情報
NVIDIA Japan
 
PDF
データ爆発時代のネットワークインフラ
NVIDIA Japan
 
PDF
Hopper アーキテクチャで、変わること、変わらないこと
NVIDIA Japan
 
PDF
GPU と PYTHON と、それから最近の NVIDIA
NVIDIA Japan
 
PDF
GTC November 2021 – テレコム関連アップデート サマリー
NVIDIA Japan
 
PDF
テレコムのビッグデータ解析 & AI サイバーセキュリティ
NVIDIA Japan
 
PDF
必見!絶対におすすめの通信業界セッション 5 つ ~秋の GTC 2020~
NVIDIA Japan
 
PDF
2020年10月29日 プロフェッショナルAI×Roboticsエンジニアへのロードマップ
NVIDIA Japan
 
PDF
2020年10月29日 Jetson活用によるAI教育
NVIDIA Japan
 
PDF
2020年10月29日 Jetson Nano 2GBで始めるAI x Robotics教育
NVIDIA Japan
 
PDF
COVID-19 研究・対策に活用可能な NVIDIA ソフトウェアと関連情報
NVIDIA Japan
 
PDF
Jetson Xavier NX クラウドネイティブをエッジに
NVIDIA Japan
 
HPC 的に H100 は魅力的な GPU なのか?
NVIDIA Japan
 
NVIDIA cuQuantum SDK による量子回路シミュレーターの高速化
NVIDIA Japan
 
Physics-ML のためのフレームワーク NVIDIA Modulus 最新事情
NVIDIA Japan
 
20221021_JP5.0.2-Webinar-JP_Final.pdf
NVIDIA Japan
 
開発者が語る NVIDIA cuQuantum SDK
NVIDIA Japan
 
NVIDIA Modulus: Physics ML 開発のためのフレームワーク
NVIDIA Japan
 
NVIDIA HPC ソフトウエア斜め読み
NVIDIA Japan
 
HPC+AI ってよく聞くけど結局なんなの
NVIDIA Japan
 
Magnum IO GPUDirect Storage 最新情報
NVIDIA Japan
 
データ爆発時代のネットワークインフラ
NVIDIA Japan
 
Hopper アーキテクチャで、変わること、変わらないこと
NVIDIA Japan
 
GPU と PYTHON と、それから最近の NVIDIA
NVIDIA Japan
 
GTC November 2021 – テレコム関連アップデート サマリー
NVIDIA Japan
 
テレコムのビッグデータ解析 & AI サイバーセキュリティ
NVIDIA Japan
 
必見!絶対におすすめの通信業界セッション 5 つ ~秋の GTC 2020~
NVIDIA Japan
 
2020年10月29日 プロフェッショナルAI×Roboticsエンジニアへのロードマップ
NVIDIA Japan
 
2020年10月29日 Jetson活用によるAI教育
NVIDIA Japan
 
2020年10月29日 Jetson Nano 2GBで始めるAI x Robotics教育
NVIDIA Japan
 
COVID-19 研究・対策に活用可能な NVIDIA ソフトウェアと関連情報
NVIDIA Japan
 
Jetson Xavier NX クラウドネイティブをエッジに
NVIDIA Japan
 
Ad

Recently uploaded (7)

PDF
第三世代 ウェザーステーションキット v3 ー WSC3-L 日本語カタログ
CRI Japan, Inc.
 
PDF
Google Driveハブ型Obsidian同期環境:PC編集とモバイル閲覧を安全・効率的に実現するクロスデバイス構築ガイド
honeshabri
 
PDF
VMUG Japan book vsan 20250515 CPU/Memory vSAN
Kazuhiro Sota
 
PDF
【AI論文解説】 RLHF不要なLLMの強化学習手法: Direct Preference Optimization(+α)
Sony - Neural Network Libraries
 
PDF
20250711JIMUC総会_先進IT運用管理分科会Connpass公開資料.pdf
ChikakoInami1
 
PDF
LoRaWAN ウェザーステーションキット v3 -WSC3-L 日本語ユーザーマニュアル
CRI Japan, Inc.
 
PPTX
Devcontainerのススメ(1)-Devcontainerとはどういう技術?-
iPride Co., Ltd.
 
第三世代 ウェザーステーションキット v3 ー WSC3-L 日本語カタログ
CRI Japan, Inc.
 
Google Driveハブ型Obsidian同期環境:PC編集とモバイル閲覧を安全・効率的に実現するクロスデバイス構築ガイド
honeshabri
 
VMUG Japan book vsan 20250515 CPU/Memory vSAN
Kazuhiro Sota
 
【AI論文解説】 RLHF不要なLLMの強化学習手法: Direct Preference Optimization(+α)
Sony - Neural Network Libraries
 
20250711JIMUC総会_先進IT運用管理分科会Connpass公開資料.pdf
ChikakoInami1
 
LoRaWAN ウェザーステーションキット v3 -WSC3-L 日本語ユーザーマニュアル
CRI Japan, Inc.
 
Devcontainerのススメ(1)-Devcontainerとはどういう技術?-
iPride Co., Ltd.
 

1075: .NETからCUDAを使うひとつの方法

  • 1. .NET から CUDA を使うひとつの方法 C++/CLI による WRAPPER のつくりかた episthmh [email protected] Microsoft MVP for Visual C++ Jan.2004~ NVIDIA CUDA Ambassador for Apr.2015~ 2015-1075 Hall-B1 16:20~
  • 2. WINDOWS APPLICATION CUI Console (stdin/stdout) GUI Win API MFC Windows Forms WPF native : C/C++ managed : .NET (C#,VB etc.) legacy…
  • 3. MANAGED は直接 CUDA を呼べない… host memory device memory PCI-bus CLR managed app.
  • 4. MANAGED と NATIVE の仲介役 host memory device memory PCI-bus CLR managed app. native assembly call
  • 6. サンプル : SAXPY Y[i] = alpha * X[i] + Y[i] (i = 0..N-1) C# / Windows Forms app. 絵ヅラはC#, 計算はCUDA C++/CLIが両者を仲介
  • 7. WRAPPERのつくりかた 1: CLR クラスライブラリ
  • 8. WRAPPERのつくりかた 2: ビルド カスタマイズ ※ C++/CLI プロジェクト内で デバイス・コード(~.cu) をコンパイルできます
  • 10. WRAPPERのつくりかた 4: 64BIT PLATFORM ※ CUDA 7.0 以降、多くのCUDAライブラリは 64bit-only です
  • 11. SAXPY DEVICE/HOST CODE __global__ void kernel_saxpy(float alpha, const float* x, float* y, unsigned int size) { unsigned int i = blockDim.x * blockIdx.x + threadIdx.x; if ( i < size ) { y[i] = alpha * x[i] + y[i]; } // Saxpy! } __host__ void device_saxpy(float alpha, const float* x, float* y, unsigned int size) { unsigned int block = 256U; unsigned int grid = (size + block -1U)/block; kernel_saxpy<<<grid,block>>>(alpha, x, y, size); } ※ device-code および それを呼び出すhost-codeは ~.cu に記述します
  • 12. REF CLASS SAXPY : ~.h public部 namespace CUDA { public ref class Saxpy { private: … public: Saxpy(); // コンストラクタ ~Saxpy(); // デストラクタ !Saxpy(); // ファイナライザ void calculate(float alpha, cli::array<float>^ x, cli::array<float>^ y); }; } ※ C++/CLI: cli::array<float>^ は C#: float[] に相当します
  • 13. REF CLASS SAXPY : ~.h private部 namespace CUDA { public ref class Saxpy { private: float* dx_; // device-memory X[] float* dy_; // device-memory Y[] size_t bsize_; // dx_/dy_の大きさ(bytes) void allocate(size_t new_bsize); // dx_/dy_を確保する void deallocate() { // dx_/dy_を解放する cudaFree(dx_); dx_ = nullptr; cudaFree(dy_); dy_ = nullptr; } … } ※利用者(C#,VB)に成り代わって device-memory を確保/解放します
  • 14. namespace CUDA { Saxpy::Saxpy() : dx_(nullptr), dy_(nullptr), bsize_(0U) {} Saxpy::~Saxpy() { this->!Saxpy(); } // 明示的にファイナライザを呼ぶ Saxpy::!Saxpy() { deallocate(); } // device-mem. を解放する … } ※ ファイナライザ : !クラス名() をお忘れなく REF CLASS SAXPY : ~.cpp
  • 15. namespace CUDA { void Saxpy::allocate(size_t new_bsize) { // 足りないときは一旦解放し、再確保 if ( bsize_ < new_bsize ) { deallocate(); bsize_ = new_bsize; float* ptr; cudaMalloc(&ptr, bsize_); dx_ = ptr; cudaMalloc(&ptr, bsize_); dy_ = ptr; } } } ※ cudaMalloc(&dx_, bsize_) とは書けません
  • 16. namespace CUDA { void Saxpy::calculate(float alpha, array<float>^ x, array<float>^ y) { unsigned int size = x->Length; if ( size != y->Length ) return; allocate((size_t)(size*sizeof(float))); // host → device pin_ptr<float> hx = &x[0]; cudaMemcpy(dx_, hx, size*sizeof(float), cudaMemcpyHostToDevice); pin_ptr<float> hy = &y[0]; cudaMemcpy(dy_, hy, size*sizeof(float), cudaMemcpyHostToDevice); // kernel-call device_saxpy(alpha, dx_, dy_, size); // device → host cudaMemcpy(hy, dy_, size*sizeof(float), cudaMemcpyDeviceToHost); } } ※ pin_ptr<float> でピン留めします
  • 17. HOW TO USE IN .NET ※ 参照設定をお忘れなく
  • 18. HOW TO USE IN C# : ~.cs public partial class Form1 : Form { private CUDA.Saxpy saxpy = new CUDA.Saxpy(); // 作って private void btnCalc_Click(object sender, EventArgs e) { if ( lstX.Items.Count != lstY.Items.Count ) return; float[] x = …; float[] y = …; float alpha = …; saxpy.calculate(alpha, x, y); // 呼ぶ! … } ※ インスタンスを生成(new)し、メソッドを呼び出すだけ
  • 20. namespace CUDA { public ref class SepiaConverter { public: SepiaConverter(); ~SepiaConverter(); !SepiaConverter(); // image(元画像)をcolor_にコピーし、モノクロ化 void LoadImage(System::IntPtr image, int width, int height, int stride); // モノクロ画像を色調変換し、imageにコピー void ConvertSepia(System::IntPtr image, float u, float v); … }; } ※ System::IntPtr が void* に相当します
  • 21. namespace CUDA { void SepiaConverter::ConvertSepia(System::IntPtr image, float u, float v) { // 色調変換し、結果を color_ に … // 結果をコピー size_t bsize = height_ * stride_; void* ptr = static_cast<void*>(image); cudaMemcpy(ptr, color_, bsize, cudaMemcpyDeviceToHost); } } ※ System::IntPtr は void* にキャストできます
  • 22. // セピア変換 private CUDA.SepiaConverter converter_; // C++/CLIで作ったwrapper private void convert_sepia(float u, float v) { // Bitmapを生成し、 LockBitsで固定 var bmp = new Bitmap(幅, 高さ); var data = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb); // 色調変換 converter_.ConvertSepia(data.Scan0, u, v); bmp.UnlockBits(data); picOutput.Image = bmp; picOutput.Invalidate(); } ※ IntPtr BitmapData.Scan0 が画像の先頭アドレスです