FreeBSD でも GPU に計算させて遊ぶ(FFTライブラリ篇)

CUDA ではありません

FreeBSD でも Linux エミュレーションで頑張ったら CUDA を使えるよという話は FreeBSD forum になんか記事があったのでそっちを見てください。

FreeBSD でも GPU で計算

世の中、GPU(というよりは CUDA)で計算をいろいろやらせてとかうるせえなあ、しょせん私が使っているのは FreeBSD でと言いたいところだけど、 FreeBSD でも GPU が使える以上は GPU に計算してもらうことだってできるはず。

というわけで、AMD GPU なら FreeBSD でも cloverOpenCL 遊びができますよという話。 NVidiaGPU については知らないけど、そっちをサポートしている OpenCL の実装がなかったっけ?

いきなり OpenCL をがりがりと書くのもなんなので、まずは既存のライブラリを使って FFT 計算をやってもらおう。 Ports/packages には clFFT が入っているからそれを使えばいいよね。 比較のために、CPU で計算する FFTW も使ってみよう。

ソースコード

というわけで、サンプルコードをここ https://github.com/oikumene/fft_example においた。 bench-* というプログラムに指定した画像ファイルをグレースケールに変換して FFT をかけるだけ。 一般的には GPU での計算は float でやるみたいだけど、なんかの科学技術計算ができたらいいなと思っているので double でやってみた。 FFTW 版は、1スレッドと6スレッドの2回計算している。 preparation がそれぞれのライブラリ用のデータ構造に画像のデータをコピーする処理にかかっている時間で、 execution が FFT の実行時間。clFFT 版はGPUからデータを取ってくるところも execution に入れている。 FFT の結果としてどういう情報を保存すればよいのか分からないので実部だけを保存するようにしてみたが、なんかおかしい。 逆フーリエ変換はうまくいくので、画像を保存する時のデータの取り出し方がたぶんなんかまずいんだけど。

実行結果

FFTW版。Motorola g13 のカメラで撮影した画像を処理したもの。 6スレッドあると計算時間が 1/3 くらいになるみたい。

% ./bin/bench-fftw img/IMG_20250227_200104.jpg 
FFTW(double) image (nthread = 1): img/IMG_20250227_200104.jpg
preparation: 0.00387s; execution: 0.19646s; total: 0.20033s
FFTW(double) image (nthread = 6): img/IMG_20250227_200104.jpg
preparation: 0.01027s; execution: 0.06586s; total: 0.07613s

なんだけど、clFFT 版はエラーになる。どうやら画像が大きすぎるよう。

% ./bin/bench-clfft img/IMG_20250227_200104.jpg
clFFT image: img/IMG_20250227_200104.jpg
Platform: Clover
Device: AMD Radeon RX 580 Series (radeonsi, polaris10, LLVM 19.1.7, DRM 3.49, 14.3-STABLE)
preparation: 0.19309s; execution: 0.00000s; total: 0.19309s
Executing clFFT on img/IMG_20250227_200104.jpg failed.

もう少し小さい画像ということで、WX321J のカメラで撮った画像を処理してみた。 まず FFTW 版。 準備にかかる時間があまり変わらなくて、計算時間が縮まったので6スレッドでもトータルの時間はあまり変わらない。

% ./bin/bench-fftw img/J0010126.jpg 
FFTW(double) image (nthread = 1): img/J0010126.jpg
preparation: 0.00359s; execution: 0.00525s; total: 0.00885s
FFTW(double) image (nthread = 6): img/J0010126.jpg
preparation: 0.00505s; execution: 0.00175s; total: 0.00680s

clFFT 版。今度は計算できた。float にすれば必要なメモリ量が半分になるのでもう少し大きな画像でもいけるはず。 だが、Radeon RX580 くらいだと、CPU (Xeon のなんか) の一スレッドと同じくらいの計算時間で (データ転送の時間があるので、計算時間そのものは短いとは思うが)、 準備の時間がだいぶかかってしまって、あまり GPU で計算するメリットがないかもしれない。

% ./bin/bench-clfft img/J0010126.jpg          
clFFT image: img/J0010126.jpg
Platform: Clover
Device: AMD Radeon RX 580 Series (radeonsi, polaris10, LLVM 19.1.7, DRM 3.49, 14.3-STABLE)
preparation: 4.24376s; execution: 0.00579s; total: 4.24955s