3

Repa を見始めたばかりで、ステンシル操作によって読み取り/書き込みされるラップアラウンド、トーラス スタイルの 2D 配列を最適に実装する方法を知りたいと考えています。ST モナドとミュータブル ベクトルを使用する前にこれを実装しましたが、これは Repa ではサポートされていないようです。いくつかのアプローチが可能と思われます:

  • 配列を「トラバース」して、各要素で自分自身をラップするインデックスを実行できます。単純なステンシルの場合、どこにでもラッピング ロジックを適用するコストは非常に厳しいため、これは避ける必要があります。

  • Data.Array.Repa.Stencil は必要な境界条件をサポートしていませんが、Data.Array.Repa.Algorithms.Convolve のように見えます。ドキュメンテーションは、パフォーマンスが大幅に低下することを示唆していますが、

  • 私が理解していることから、スライスを使用して配列のサブセットをトラバースできます。したがって、内部 (1, 1) - (w-2, h-2)、境界を表す 2 つの水平スラブと 2 つの垂直スラブを定義し、2 つの異なる関数/ステンシルを使用してそれらをトラバースし、結果として 1 つの配列を得ることができます。 ? これに関するサンプルコードまたはその他のドキュメントはありますか?

  • Repaにも「パーティション」という概念があるようですが、境界条件の実装に使用できますか?

どれが最速である可能性が高いですか? 不足しているオプションはありますか?

ありがとう!

4

1 に答える 1

3

最も効率的な方法は、配列表現 (4 番目のオプション) を使用することですが、手動で5 つの領域Partitionedを操作する必要があるため、不便です。

Yarrでは、ユーティリティを書くことができます

dim2WrapAround :: USource r l Dim2 a => UArray r l Dim2 a -> Dim2 -> Dim2 -> IO a
{-# INLINE dim2WrapAround #-}
dim2WrapAround arr (sizeX, sizeY) (posX, posY) =
    index arr (wrap sizeX posX, wrap sizeY posY)
  where wrap size pos = (pos + size) `mod` size

-- I'm afraid to write the signature...
{-# INLINE convolveOnThorus #-}
convolveOnThorus = convolveLinearDim2WithStaticStencil dim2WrapAround

使用法:

myConvolution :: UArray F L Dim2 Float -> UArray CV CVL Dim2 Float
myConvolution = convolveOnThorus [dim2St| some
                                           coeffs
                                               here |]
于 2013-07-28T23:07:04.353 に答える