Alea GPU を使って GrasshopperでGPU並列プログラミング
30 April, 2020 - 1 min read - Tags: Grasshopper,CSharp,構造とデジタル
GPU プログラミングが面白そうだったので、Grasshopper で実装して動作の感じを確認してみました。実装した方法について説明していきます。
使用するライブラリはAleaGPU です。
公式のドキュメントによると、AleaGPU は、早く使いやすく高い生産性となっており、コンパイルされたコードは CUDA C、C++と同程度の速さで実行されるとのことです。上記で書きましたが、CUDA を使用しているため、NVIDIA の GTX1050 以上 GPU を積んでいないと動作しないため注意してください。
基本的な内容はこちらの Qiita の記事がわかりやすかったので紹介します。Alea GPU で簡単 C# GPU プログラミング
まず VisualStudio で Alea ライブラリを使えるようするため、NuGet を使ってインストールしてください。合わせて FSharp.Core も必要になるので、インストールしてください。ここら辺のやり方はこちらの記事がわかりやすかったので合わせて紹介します。Alea GPU ライブラリを使って C#で簡単 GPU 並列プログラミング
Alea が使えるようになったら、Grasshopper での実装します。上で紹介したサイトでは例えば
Gpu.Default.for(0, 100, i => hogehoge)
のようにやる並列計算の例が書かれていますが、簡単に試すために Alea のあるメソッドを使って今回はやりました。使用したのは平均を求めるGpuExtension.Average メソッド と合計を求めるGpuExtension.Sum メソッド です。
入力を計算したい値のリストとして、SolveInstance を以下のようにしました。GH の入力はリストですが、並列計算は配列でないとできないため、20 行目で入力されたリストを配列に変換しています。その後 GpuExtension.Average メソッドを使用して GPU で計算して値を返しています。12 行目で GpuManaged のアトリビュートをつけていますが、これは Alea 側で GPU のメモリの管理を自動で行ってくれる設定で、これをつけると速度が上がります。
using System;
using System.Collections.Generic;
using Grasshopper.Kernel;
using Rhino.Geometry;
using Alea;
using Alea.Parallel;
・・・省略・・・
[GpuManaged]
protected override void SolveInstance(IGH_DataAccess DA)
{
var gpu = Gpu.Default;
double average;
var inputList = new List<double>();
if (!DA.GetDataList(0, inputList)) { return; }
var inputArray = inputList.ToArray();
average = GpuExtension.Average(gpu, inputArray);
DA.SetData(0, average);
}
合計もほぼ同じ書き方で書くことができます。詳細は、最後につけた私の GitHub のリポにソースを上げているので見てください。これでコードは終わりです。
これをビルドしただけでは動かないので、Rhino に必要なライブラリを入れます。上で作ったコードをビルドをすると以下のように bin フォルダの中に Alea 関連のファイルがいくつか作成されます。
この中で Alea.CUDA.CT.LibDevice から FSharp.Core.xml までを C:\Program Files\Rhino 6\System 内に入れます。
これで動くようになったので、Grasshopper を起動して作成したコンポーネントを使用して比較してみると以下のようになりました。比較としては、合計は、GH の MassAddition コンポーネントとの比較、平均は GH の Average コンポーネントと Impala の QuickAvr コンポーネントとの比較を行っています。
結果としては合計は GPU の方が早く、平均は Impala が早い結果になりました。計算するデータ数を増やすために Entwine を使って枝分かれさせて入力してみた結果が以下です。
並列化処理とか、GPU とのデータのやり取りに時間がかかるので、やっぱり必ずしも早くなるわけではないですね。実装は簡単だけどどんな時それが適切なのかよくわからないので、ここら辺は真面目にコンピューターサイエンスとか勉強してみたい範囲です。
実際に自分でビルドして使ってみたいからは GitHub のリポを参照してください。https://github.com/hrntsm/GHGpuComputingTest