🎼

Haskell-Accelerate関数の図示

2024/11/30に公開

概要

HaskellのGPU含む並列実行ライブラリであるAccelerateの関数仕様の一部を図示したものです。後々追加します。元のライブラリ仕様はこちら

scatter

defaultに対し、sourceの要素をdestinationに示されたインデックスにコピーするものです。以下では、sourceの先頭の1,9,6のみに対してresultにコピーされる様子を示しています。

サンプル
{-# LANGUAGE CPP, BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}

import Data.Array.Accelerate as A
import Data.Array.Accelerate.LLVM.PTX

main :: IO ()
main = do
  let to    = fromList (Z :. 6) [1,3,7,2,5,8] :: Vector Int
  let input = fromList (Z :. 7) [1,9,6,4,4,2,5] :: Vector Int
  let result = run $ scatter (use to) (fill (constant (Z:.10)) 0) (use input)
  print result

-- compile: ghc -O2 scatter.hs -threaded
-- execute: ./scatter
-- result: Vector (Z :. 10) [0,1,4,9,0,4,0,6,2,0]

permute

scatterの処理を一般化したもので、sourceをperm-funcによりdefaultの要素を指すように写像し、defaultの各要素でcombi-funcで総計します。以下はhistgramを出すために0~9までのxs上での発生回数を算出しています。xsはpermuteの直接の引数ではなく、perm-funcの例を構成するためのものです。0,3のみ例として示しています。

サンプル
{-# LANGUAGE CPP, BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}

import Data.Array.Accelerate as A
import Data.Array.Accelerate.LLVM.PTX

histogram :: Acc (Vector Int) -> Acc (Vector Int)
histogram xs =
  let zeros = fill (constant (Z:.10)) 0
      ones  = fill (shape xs)         1
  in
    permute (+) zeros (\ix -> Just_ (I1 (xs!ix))) ones

main :: IO ()
main = do
  let xs = fromList (Z :. 20)
            [0,0,1,2,1,1,2,4,8,3,4,9,8,3,2,5,5,3,1,2] :: Vector Int
  let result = run $ histogram (use xs)
  print result
-- compile: ghc -O2 permute.hs -threaded
-- execute: ./permute
-- result: Vector (Z :. 10) [2,4,4,3,2,2,0,0,2,1]

gather

sourceの中からindexで選択した要素を取り出します。indexの0,2要素目がsourceの9,1を指しているため、結果の0,2要素目が9,1となります。

サンプル
{-# LANGUAGE CPP, BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}

import Data.Array.Accelerate as A
import Data.Array.Accelerate.LLVM.PTX

main :: IO ()
main = do 
  let input = fromList (Z:.9) [1,9,6,4,4,2,0,1,2] :: Vector Int
  let from  = fromList (Z:.6) [1,3,7,2,5,3] :: Vector Int
  let result = run $ gather (use from) (use input)
  print result
-- compile: ghc -O2 gather.hs -threaded
-- execute: ./gather
-- result: Vector (Z :. 6) [9,4,1,6,2,4]

backpermute

gatherを一般化したものです。以下は上記gatherを再現しています。

サンプル
{-# LANGUAGE CPP, BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}

import Data.Array.Accelerate as A
import Data.Array.Accelerate.LLVM.PTX

gather' :: (Elt e, Shape sh) =>
  Acc (Array sh Int) -> Acc (Vector e) -> Acc (Array sh e)
gather' xs source =
  let
    permFunc ix = I1 $ xs ! ix
  in
    backpermute (shape xs) permFunc source
    
main :: IO ()
main = do
  let input = fromList (Z:.9) [1,9,6,4,4,2,0,1,2] :: Vector Int
  let from  = fromList (Z:.6) [1,3,7,2,5,3] :: Vector Int
  let result = run $ gather' (use from) (use input)
  print result 
-- compile: ghc -O2 backpermute.hs -threaded 
-- execute: ./backpermute
-- result: Vector (Z :. 6) [9,4,1,6,2,4]

Discussion