我正在使用 Haskell 的加速库做一个有趣的项目。我有一个需要编写的函数,在纯 Haskell 中看起来像这样:
oddfac :: Int -> Int
oddfac n = product [1,3...n]
即类似于阶乘函数,但只乘以奇数。我想在加速后端执行这个功能,所以如果我理解正确,它需要变成 type Exp Int -> Exp Int
。Exp
但是,出于性能原因,该库不允许在 中评估任意表达式。幸运的是,我只需要为小值评估这个函数,例如 n<=7。我的想法是定义一个预先计算的返回值的列表(或数组),以便简单地对其进行索引将返回适当的值,并且每次评估都将花费相同的时间,而天真的版本则不是这种情况。但是,我还没有找到一种方法来做到这一点。我现在有两个问题:
1) 有没有办法做到这一点,即定义一个硬编码数组,然后对其进行索引以检索类型函数中的适当值Exp a -> Exp b
?
2) 我是否以有效的方式处理事情?我对这个问题的看法有什么明显的缺陷吗?
更新
以下作品基于@ErikR 的回答和随后的评论:
module Test where
import Data.Array.Accelerate as A
import Prelude as P
oddfac :: Exp Int -> Exp Int
oddfac n = (use $ A.fromList (Z :. 6) [1, 1, 3, 3, 15, 15]) A.! (index1 n)
alloddfac :: Acc (Vector Int)
alloddfac = A.map oddfac $ use $ A.fromList (Z :. 3) [1, 3, 5]