雑記帳

ちょっとした文章とかメモ書きとか。

HaskellでOpenCLを使ってみる

HaskellでOpenCLを使ってみると言う記事。

HackageにControl.Parallel.OpenCLと言うライブラリがあったのでこれを使ってきます。

Control.Parallel.OpenCLの導入

cabalで導入すれば終わりなのですが少し依存関係があるので注意。
このパッケージはc2hsをcabal install時に要求する為、それをまずインストールします。

% cabal install c2hs

これでc2hsを入れた後、c2hsは
Linux:
$HOME/.cabal/bin
OSX:
$HOME/Library/Haskell/bin
へインストールされます。これを$PATHへ追加します。

例えば以下のようなコマンドで一時的に追加します。
bash/zsh:
export PATH=$HOME/.cabal/bin:$PATH
csh/tcsh:
set path=($HOME/.cabal/bin $path)
bashrcやzshrcに書いておいてもいいかも知れません。

これで

% cabal install opencl

として Control.Parallel.OpenCLが入ります。

使ってみる

早速使ってみます。
–testCL.hs–

import Control.Parallel.OpenCL

-- clDeviceCheck
clDeviceCheck :: IO ()
clDeviceCheck = do
  (platform:_) <- clGetPlatformIDs
  (dev:_<- clGetDeviceIDs platform CL_DEVICE_TYPE_ALL
  cl_e <- clGetDeviceExtensions dev
  cl_t <- clGetDeviceType dev
  cl_ven <- clGetDeviceVendor dev
  cl_venid <- clGetDeviceVendorID dev
  cl_driver <- clGetDeviceDriverVersion dev
  cl_name <- clGetDeviceName dev
  cl_v <- clGetDeviceVersion platform
  cl_p <- clGetDeviceProfile platform
  cl_maxunit <- clGetDeviceMaxComputeUnits dev
  cl_freq <- clGetDeviceMaxClockFrequency dev
  cl_gmem_t <- clGetDeviceGlobalMemCacheType dev
  cl_gmem_s <- clGetDeviceGlobalMemSize dev
  cl_mem_cache <- clGetDeviceGlobalMemCachelineSize dev
  cl_dim <- clGetDeviceMaxWorkItemDimensions dev
  cl_work <- clGetDeviceMaxWorkGroupSize dev
  cl_item <- clGetDeviceMaxWorkItemSizes dev
  cl_res <- clGetDeviceProfilingTimerResolution dev
  cl_maxmem <- clGetDeviceMaxMemAllocSize dev
  cl_const_buffer <- clGetDeviceMaxConstantBufferSize dev
  cl_img <- clGetDeviceImageSupport dev
  cl_double <- clGetDeviceDoubleFPConfig dev
  cl_single <- clGetDeviceSingleFPConfig dev
  cl_capable <- clGetDeviceExecutionCapabilities dev

  putStrLn $ unlines $
              [ "Device Id: " ++ show dev
               , "Device Info: " ++ cl_e
               , "Device Type: "  ++ show cl_t
               , "Device Vendor: "  ++ cl_ven
               , "Vendor ID: "  ++ show cl_venid
               , "Device Driver Version: "  ++ cl_driver
               , "Device Name: "  ++ cl_name
               , "Device Version: "  ++ cl_v
               , "Device Profile: "  ++ cl_p
               , "Max unit: "  ++ show cl_maxunit
               , "Max clock frequency: "  ++ show cl_freq
               , "Global Memory Cache Type : "  ++ show cl_gmem_t
               , "Global Memory Size: "  ++ show cl_gmem_s
               , "Global Memory Cacheline Size: "  ++ show cl_mem_cache
               , "Max dimension: "  ++ show cl_dim
               , "Max work group size: "  ++ show cl_work
               , "Max Work Item: "  ++ show cl_item
               , "CL timer resolution: "  ++ show cl_res
               , "Max alloc Memory size: "  ++ show cl_maxmem
               , "Max constant buffer size: "  ++ show cl_const_buffer
               , "Device image Support: "  ++ show cl_img
               , "Double precision floating point: "  ++ show cl_double
               , "Single precision floating point: " ++ show cl_single
               , "Device capability: " ++ show cl_capable]

main :: IO ()
main = clDeviceCheck

となりました。これではまだ一つのデバイスしか対応できてないです。

複数デバイスに対応したものはshelarcyさんが書いてくださいました。
複数デバイス対応版はこちら→http://ideone.com/2vQjl

これをghcでコンパイルするには
Linux:

% ghc --make testCL.hs

OSX:

% ghc -framework OpenCL -o testCL testCL.hs

とします。

動かしてみる

  • Ubuntu64bit
  • GTX550Ti NVIDIA
  • Driver304.37

の時の結果は以下のようになりました。

% ./testCL
Device Id: 0x0000000001e39c50
Device Info: cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll  cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_fp64
Device Type: [CL_DEVICE_TYPE_GPU]
Device Vendor: NVIDIA Corporation
Vendor ID: 4318
Device Driver Version: 304.37
Device Name: GeForce GTX 550 Ti
Device Version: OpenCL 1.1 CUDA
Device Profile: FULL_PROFILE
Max unit: 4
Max clock frequency: 1800
Global Memory Cache Type : CL_READ_WRITE_CACHE
Global Memory Size: 1073610752
Global Memory Cacheline Size: 128
Max dimension: 3
Max work group size: 1024
Max Work Item: [1024,1024,64]
CL timer resolution: 1000
Max alloc Memory size: 268402688
Max constant buffer size: 65536
Device image Support: True
Double precision floating point: [CL_FP_DENORM,CL_FP_INF_NAN,CL_FP_ROUND_TO_NEAREST,CL_FP_ROUND_TO_ZERO,CL_FP_ROUND_TO_INF,CL_FP_FMA]
Single precision floating point: [CL_FP_DENORM,CL_FP_INF_NAN,CL_FP_ROUND_TO_NEAREST,CL_FP_ROUND_TO_ZERO,CL_FP_ROUND_TO_INF,CL_FP_FMA]
Device capability: [CL_EXEC_KERNEL]

OpenCL 1.1のFull Profileに対応しているようです。
GTX550TiのカードはOpenCLでも倍精度浮動小数点型が使えるみたいですね。

Ubuntu12.04でcabalがLexical Error ‘#’になる場合

Ubuntu12.04のcabalはLexical Error ‘#’でエラーになります。
これはコンフィグのミスに依るもので、LANG=C環境なら正常に動きます。

この場合は

% cabal install ...

では無く

% LANG=C cabal install ...

としてみてください。

参考:https://github.com/aleator/CV/wiki/BuildProblems のLexical Error ‘#’項

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。