Situation
目前,我正在从事一个处理边缘检测的项目。因此,我想使用加速数组来计算算法,以获得更好的性能。不幸的是,我对函数式编程和并行编程非常陌生,我不知道该怎么做。
问题
为了将给定的图像转换为灰度,甚至执行边缘检测,我需要访问数组的每个像素/值。
使用非加速数组( Data.Array包),我可以使用(!)-operator来获得所需的值。
使用加速数组( Data.Array.Accelerate包)有类似的函数,如。
(!) :: (Shape ix, Elt e) => Acc (Array ix e) -> Exp ix -> Exp e描述:从数组中提取标量的表达式表单。(!!) :: (Shape ix, Elt e) => Acc (Array ix e) -> Exp Int -> Exp e描述:从线性索引的数组中提取标量的表达式表单。
。。但它们总是以返回加速表达式值(Exp e)而结束,这就引出了我的问题。
问题
是否有可能从Exp数据类型中“解压”值,或者您还建议我做什么?
示例
从图像到加速数组的转换工作。
toArr :: Image PixelRGB8 -> Acc (Array DIM2 (Pixel8, Pixel8, Pixel8))
toArr img = use $ fromFunction (Z :. width :. height) (\(Z :. x :. y) -> let (PixelRGB8 r g b) = pixelAt img x y in (r, g, b))
where width = imageWidth img
height = imageHeight img。。但我不知道反之亦然,因为我需要访问表达式值才能从宽度/高度/像素生成图像。
toJuicy :: Acc (Array DIM2 (Pixel8, Pixel8, Pixel8)) -> Image PixelRGB8
toJuicy arr = undefined任何帮助都将不胜感激。
发布于 2017-10-09 20:23:05
必须强调的是,Accelerate不仅仅是“正常的并行化”--特别是SIMD并行化,它在GPU上工作得最好。但是你不能仅仅从GPU内存中读出任意的值,至少不能不损失所有的性能优势,因为这个内存完全不是为随机访问而优化的,而是只有在“批处理模式”下才能正常工作。因此,执行实际工作的库函数总是返回一个Acc / Exp值,因此中间结果实际上可以保留在GPU (或其他并行处理器)上。
现在,在CPU上执行加速代码也是可能的,在这种情况下,这个问题不会真正出现。但是,即使在这里,接口也是一致的;您应该始终执行昂贵的计算,并且只在最后将结果检索回“normal Haskell值”。
为了完成这个检索,每个特定于设备的后端都提供了一个run函数,例如Data.Array.Accelerate.LLVM.Native.run。
https://stackoverflow.com/questions/46648982
复制相似问题