将加速的 A 数组表示转换为 repa 的 U 数组表示

Posted

技术标签:

【中文标题】将加速的 A 数组表示转换为 repa 的 U 数组表示【英文标题】:Converting accelerate's A array representation to repa's U array representation 【发布时间】:2015-11-05 15:01:04 【问题描述】:

我想将加速数组转换为 repa 数组,然后使用 repa-io 中的writeImageToBMP 将数组写入 BMP 文件。忽略加速 io 中存在这样一个功能的事实,我只是将其用作问题的示例。采取:

-# LANGUAGE ScopedTypeVariables #-
import qualified Data.Array.Accelerate.Interpreter as A (run)
import Data.Array.Accelerate
import qualified Data.Array.Accelerate as A
import qualified Data.Array.Accelerate.IO as A
import qualified Data.Array.Repa as Repa
import qualified Data.Array.Repa.IO.BMP as Repa
import GHC.Word

main :: IO ()
main = do
  let accelArr = A.fromList
                 (Z :. (2::Int) :. (1::Int))
                 ([(1,2,3),(4,5,6)] :: [(Word8,Word8,Word8)])
      computation :: A.Acc (A.Array A.DIM2 (Word8,Word8,Word8))
      computation = A.map
       (\triple ->
           let (r',g',b') = unlift triple :: (Exp Word8,Exp Word8,Exp Word8)
           in lift (constant 0,g',b')) (use accelArr)
      repaArr :: Repa.Array A.A Repa.DIM2 (Word8,Word8,Word8)
      repaArr = A.toRepa (A.run computation)
  Repa.writeImageToBMP "out_repa.bmp" repaArr

需要包加速、加速-io、repa和repa-io来编译这段代码。

这不会编译,因为 repa-io 中 writeImageToBmp 的类型是:

writeImageToBMP
  :: FilePath
  -> Repa.Array Repa.U Repa.DIM2 (Word8, Word8, Word8)
  -> IO ()

其中U 表示repa 中的清单数组。 GHC 错误是:

Couldn't match type ‘A.A’ with ‘Repa.U’
Expected type: Repa.Array Repa.U Repa.DIM2 (Word8, Word8, Word8)
  Actual type: Repa.Array A.A Repa.DIM2 (Word8, Word8, Word8)
In the second argument of ‘Repa.writeImageToBMP’, namely ‘repaArr’
In a stmt of a 'do' block:
  Repa.writeImageToBMP "out_repa.bmp" repaArr

repaArr的类型是:

Repa.Array A.A Repa.DIM2 (Word8,Word8,Word8)

这就是为什么 GHC 抱怨它是 writeImageToBMP 的论据。

问题:如何将加速数组表示A转换为repa manifest数组表示U,以便我可以调用writeImageToBMP

【问题讨论】:

将任何 Repa 数组转换为未装箱的 Repa 数组的方法相同:computeUnboxedS/P. @user2407038 - 我能够让copyPcopyS 工作,但由于缺少Load 约束而无法使用任何计算方法。 【参考方案1】:

注意Data.Array.Repa中的computeScomputePcopyScopyP函数都有这种签名:

...constraints... => Array r1 sh e -> m (Array r2 sh e)

因此它们是允许您在不同的 Repa 表示之间进行转换的函数(即转换 r1 -> r2)。

考虑到这一点,我得到了这个代码来进行类型检查:

main :: IO ()
main = do
  let accelArr = A.fromList
                 (Z :. (2::Int) :. (1::Int))
                 ([(1,2,3),(4,5,6)] :: [(Word8,Word8,Word8)])
      computation :: A.Acc (A.Array A.DIM2 (Word8,Word8,Word8))
      computation = A.map
       (\triple ->
           let (r',g',b') = unlift triple :: (Exp Word8,Exp Word8,Exp Word8)
           in lift (constant 0,g',b')) (use accelArr)
      repaArr :: Repa.Array A.A Repa.DIM2 (Word8,Word8,Word8)
      repaArr = A.toRepa (A.run computation)
  zzz <- Repa.copyP repaArr
  Repa.writeImageToBMP "out_repa.bmp" zzz

您也可以在这里使用Repa.copyS

【讨论】:

以上是关于将加速的 A 数组表示转换为 repa 的 U 数组表示的主要内容,如果未能解决你的问题,请参考以下文章

将数字数组转换为二进制数

c语言 数组可以转换成字符串吗

将十进制数转换为二进制数----不用数组,也不用函数,只用循环

求c语言将十进制数转换为16进制的函数

keil c中如何把字符串转化为整型 具体一点

将数据帧转换为具有 3d 形状 (x,y,z) 的数组