问题标签 [repa]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
python - 使用 REPA 优化 haskell 中的平均图像颜色程序
问题
我编写了一个 Haskell 程序,它遍历文件夹并找到文件夹中每个图像的平均颜色。它使用来自 hackage 的 repa-devil 包将图像加载到 repa 数组中。我通过将所有红色、蓝色和绿色值相加然后除以像素数来找到平均值:
我还使用 Python Image Library 用 Python 编写了这个程序。它以相同的方式找到图像的平均值:
当这两个都在一个包含 301 个图像的文件夹上运行时,Haskell 版本的性能优于 0.2 秒(0.87 对 0.64)。这看起来很奇怪,因为 Haskell 是一种编译语言(通常比解释语言快),而且我听说 repa 数组具有良好的性能(尽管这可能只是与其他 Haskell 数据类型相比,如列表)。
我试过的
我做的第一件事是注意到我正在使用显式递归,因此我决定使用折叠替换它,这也意味着我不再需要检查我是否超出了数组的范围:
这使其运行速度变慢(1.2 秒),所以我决定分析代码并查看大部分时间都花在了哪里(以防我造成了明显的瓶颈或 repa-devil 包很慢)。配置文件告诉我,约 58% 的时间花在 f 函数上,约 35% 的时间花在 addCol 上。
不幸的是,我想不出任何办法让这个运行得更快。该函数只是一个数组索引和一个加法 - 与 python 代码相同。有没有办法提高这段代码的性能,或者 Python 图像库只是提供更好的性能?
arrays - 使用 Haskell 的 Repa 实现 2D 圆环阵列
我刚开始研究 Repa,想知道如何最好地实现一个由模板操作读取/写入的环绕式、圆环式 2D 数组。我在使用 ST monad 和可变向量之前实现了这一点,但似乎 Repa 不支持这一点。一些方法似乎是可能的:
我可以“遍历”数组并在每个元素处进行索引包装。对于简单的模板,在任何地方都应用包装逻辑的成本非常高,所以我需要避免这个
Data.Array.Repa.Stencil 不支持我需要的边界条件,但看起来像 Data.Array.Repa.Algorithms.Convolve 一样。但是,文档表明会造成严重的性能损失
据我了解,我可以使用切片遍历数组的一个子集。所以,我可以定义一个内部 (1, 1) - (w-2, h-2),两个水平和两个垂直的平板代表边界,然后使用两个不同的函数/模板遍历它们,得到一个结果数组? 关于此的任何示例代码或进一步的文档?
Repa 似乎也有“分区”的概念,可以用来实现边界条件吗?
哪一个可能最快?我缺少任何选项吗?
谢谢!
arrays - 行星模拟的“Repa”性能
我已经使用欧拉辛方法编写了太阳系外行星的模拟,并实现了这个 a) usingrepa
和 b) using yarr
。
鉴于此,我什至没有尝试使用并行性。我的repa
代码中是否存在明显的性能问题?存储库位于github。如果这有帮助,我可以制作一个仅缩减repa
版的版本,但是您将无法获得与yarr
.
或者,我如何调试性能问题repa
?
arrays - 简单数值方法的 Repa 性能
我已经使用 repa 实现了欧拉辛方法。这是一个非常简单的方法。可悲的是,我得到的表现并没有我希望的那么好。repa 的人非常乐于助人(尤其是 Ben Lippmeier),我遵循了他关于内联和添加严格性注释的建议。不幸的是,这些似乎没有帮助。我正在生产核心
可悲的是,这似乎很大,我目前不确定如何进行。我认为更广泛的 Haskell 社区可能对如何调试或指出我哪里出错有一些想法。
代码在这里:https ://gist.github.com/idontgetoutmuch/6209752
如果有帮助,我也可以将核心发布在要点中。
arrays - 在 Haskell 中存储和排序矩形数据的最佳方法是什么?
我有一些 ASCII 文件,总共包含大约 1700 万行,每行/大多数行中有一个固定的 36 字节标识符。所以我的数据是矩形的:我有很多固定宽度的行。使用 Haskell,我想读取所有行,使用正则表达式提取标识符(我很好),然后对它们进行排序并计算唯一标识符的数量(非常接近grep | sort | uniq
)。(我已经通过并行读取每个文件来进行并行化。)听起来像一个简单的问题,但是......
我发现即使在排序阶段之前,也很难从这个问题中获得体面的表现。这是我所知道的。 String
对于 36 字节的 ASCII 来说太过分了,所以我想使用ByteString
. 但是大小为 1700 万的(链接)列表似乎是个坏主意,所以我尝试了IOVector ByteString
. 但这似乎很慢。我相信垃圾收集正在遭受痛苦,因为我在向量中保留了数百万个小字节字符串:GC 花费的时间至少是代码的 3 倍(根据+RTS -s
),我认为随着程序继续运行它只会变得更糟。
我在想我应该使用 Repa 或某种单一的巨型ByteString
// IOVector Char8
whatever(因为我知道每行的确切宽度是 36)为每个线程将数据存储在一个巨大的矩形数组中,这应该可以缓解 GC 问题. 但是,之后我仍然需要对行进行排序,并且 Repa 似乎不支持排序,我不想自己编写排序算法。所以我不知道如何拥有一个巨大的矩形阵列,但仍然对其进行排序。
对要使用的库、要设置的 GC 标志或其他什么的建议?这台机器有 24 个内核和 24GB 的 RAM,所以我不受硬件限制。我想留在 Haskell 中,因为我有很多相关的代码(也用于解析相同的文件并生成摘要统计信息)工作正常,而且我不想重写它。
algorithm - 使用 Haskell Repa 数组实现相位展开算法
我正在尝试使用 Repa 阵列在 Haskell 中实现用于三相结构光扫描的相位展开算法。我想实现从点(宽度/ 2,高度/ 2)向外递归的基于洪水填充的展开算法。不幸的是,使用这种递归方法,我遇到了内存不足的异常。我是 Haskell 和 Repa 库的新手,所以我想知道我是否在做任何明显错误的事情。对此的任何帮助将不胜感激!
更新(@leventov):
我现在正在考虑使用 Yarr 中的可变数组实现以下路径跟踪算法。(出版物:K. Chen、J. Xi、Y. Yu 和 JF Chicharo,“用于三维条纹图案轮廓测量的快速质量引导洪水填充相位展开算法”,工业应用光学计量和检测,2010 年,第 1 页-9。)
performance - Haskell Repa 模板技巧
问题
我试图了解Repa 的工作原理,并且我正在使用Repa 示例包中的“模糊”示例代码。代码使用stencil2 Quasi Quote
:
这只是TemplateHaskell
一个片段,它生成一个函数:
可以使用 TH,但我希望将 coefs 保留在 Repa 数组中,因此我将代码更改为使用 Repa Array,但与原始代码相比,我的代码运行速度慢了 2 倍。
一些花哨的笔记
我注意到,Repa 作者使用硬编码的 7 x 7 值矩阵来获取系数: http ://hackage.haskell.org/package/repa-3.2.3.3/docs/src/Data-Array-Repa-Stencil- Dim2.html#forStencil2 (参见:template7x7)
问题
- 我想问你为什么它没有像原来的那样优化,我们该如何解决?我想编写一个“卷积”函数,它允许我在图像上运行模板(Repa 数组)的卷积。
- 我们真的必须使用这样的硬编码矩阵来让 GHC 优化代码吗?如果不使用这样的“黑客”,真的没有办法创建快速的 Haskell 代码吗?
编码
原始模糊功能:
我的模糊功能:
其余代码:
编译:ghc -O2 -threaded -fllvm -fforce-recomp Main.hs -ddump-splices
haskell - 带有 Haskell repa 数组库的彩色图像文件 IO
我正在通过尝试大量编程示例来探索 Haskell repa 库。我的目标是使用 repa 实现常见的图像处理算法。
重复示例
repa 存储库中有一些有用的代码示例。它们都对类型为Array U DIM2 a
or的图像进行Array DIM2 Float
操作Array U DIM2 Double
。
图片文件IO
图像文件 IO 有两种选择:
- 支持 PNG、BMP、JPG、TIF的 repa-devil软件包。不幸的是,它们被解析为不符合上述 repa 示例的数组类型,正如 repa-devil 维护者在此处确认的那样。
- repa-io包更接近于repa-examples中图像的数组类型参数,但仅支持 BMP 文件。
repa-devil(与 repa-examples 不兼容)
repa-examples 包中的图像类型为Array F DIM3 Word8
,或者Array F DIM2 Word8
如果它是灰度图像。这意味着 repa-devil 不能用于读取要与 repa-examples 中的示例一起处理的图像,因为 repa-examples 中的图像是二维数组,而 repa-devil 中的图像是三维数组。
repa-io(与 repa-examples 有一些兼容性)
repa-examples 和 repa-io 之间有更密切的对应关系。
这一次,一个 BMP 图像文件被解析成一个二维数组,其元素类型为(Word8,Word8,Word8)
,大概代表 R、G 和 B 值。即便如此,repa-examples 包中唯一兼容的函数toGreyScale
来自上面。所有其他函数都对Array U DIM2 Float
or Array DIM2 Float
or类型的值进行操作Array U DIM2 Double
。
问题
- 除了
toGreyScale
,repa-examples 中的所有示例都只适用于灰度图像吗?虽然从类型上看这是有道理的,但令人惊讶的是,没有彩色图像的 repa 示例。例如,为什么类型为blur
not 而不是:blur :: Monad m => Int -> Array U DIM2 (Word8, Word8, Word8) -> m (Array U DIM2 (Word8, Word8, Word8))
- 浮动捕获的值是
Array U DIM2 Float
多少?它是 0 到 255 之间的灰度值吗? - 在 repa-io 包中添加 JPG/PNG/TIF IO 支持是否有任何工作?
arrays - 编写一次并行数组 Haskell 表达式,在 CPU 和 GPU 上运行 repa 并加速
修复和加速 API 相似性
Haskell repa 库用于在 CPU 上自动进行并行数组计算。加速库是 GPU 上的自动数据并行性。API 非常相似,具有相同的 N 维数组表示。fromRepa
甚至可以使用和toRepa
in在加速和 repa 数组之间切换Data.Array.Accelerate.IO
:
有多个用于加速的后端,包括 LLVM、CUDA 和 FPGA(参见http://www.cse.unsw.edu.au/~keller/Papers/acc-cuda.pdf的图 2 )。我发现了一个用于加速的repa 后端,尽管该库似乎没有得到维护。鉴于repa 和Accelerator 编程模型相似,我希望有一种优雅的方式在它们之间切换,即编写一次的函数可以使用repa 的R.computeP 或Accel 的后端之一执行,例如使用CUDA运行函数。
两个非常相似的功能:南瓜上的 Repa 和 Accelerate
取一个简单的图像处理阈值函数。如果灰度像素值小于 50,则将其设置为 0,否则保留其值。这是它对南瓜的作用:


以下代码介绍了 repa 和加速实现:
问题:我可以只写一次吗?
thresholdAccelerate
和的实现thresholdRepa
非常相似。是否有一种优雅的方法可以编写一次数组处理函数,然后以编程方式在交换机中选择多核 CPU(repa)或 GPU(加速)?我可以考虑根据我想要 CPU 还是 GPU 来选择我的导入,即导入或者Data.Array.Accelerate.CUDA
执行Data.Array.Repa
以下类型的操作Acc a
:
或者,使用类型类,例如大致如下:
或者是这样的情况,对于我希望为 CPU 和 GPU 表达的每个并行数组函数,我必须实现它两次——一次使用 repa 库,另一次使用加速库?
haskell - 在具有边界情况的 repa 数组上映射窗口函数
问题
我正在寻找可能已经存在的 repa 库中的函数。我想要一个功能:
- 采用二维数组
- 指定窗口大小的两个整数
- 在二维数组上给定大小的每个窗口中,计算一个新值,例如该特定窗口中的小值。
例子
min
使用 3x3 窗口映射函数:
将返回:
请注意,我正在使用类似于BoundClamp 构造函数的方案Data.Array.Repa.Stencil
。这不是模板卷积,即它没有将模板应用于 2D 数组的每个元素。相反,它在数组的每个窗口上执行一个函数,边缘的超出范围的元素被分配到二维数组边缘的最接近的值。
可能解决方案的类型
该函数可能类似于:
这是已经存在的东西,还是编码起来很简单?