将CSV文件读入Accelerate(或Repa)阵列的最有效方法是什么?

时间:2014-02-10 02:40:41

标签: arrays haskell csv accelerate-haskell

我有兴趣使用Accelerate库,我想对存储在CSV文件中的数据执行一些操作。我已经阅读了this excellent introduction to Accelerate,但我不确定如何有效地将CSV读入加速。我已经考虑过了,我唯一能想到的就是将整个CSV文件解析成一个长列表,然后将整个列表提供给Accelerate。

我的数据集非常大,将1 gb +文件读入内存只是为了复制到其他地方似乎并不高效。我注意到Hackage上有一个CSV Enumerator包,但我不确定如何将它与Accelerate的generate函数一起使用。另一个限制是,在使用Accelerate生成数组之前,似乎必须知道Array的维度或至少数量的元素。

之前有没有人处理过这类问题?

谢谢!

2 个答案:

答案 0 :(得分:1)

我不确定这是否100%适用于acceleraterepa,但这是我过去为Vector处理此问题的一种方法:

-- | A hopefully-efficient sink that incrementally grows a vector from the input stream
sinkVector :: (PrimMonad m, GV.Vector v a) => Int -> ConduitM a o m (Int, v a)
sinkVector by = do
    v <- lift $ GMV.new by
    go 0 v
  where
    -- i is the index of the next element to be written by go
    -- also exactly the number of elements in v so far
    go i v = do
        res <- await
        case res of
          Nothing -> do
            v' <- lift $ GV.freeze $ GMV.slice 0 i v
            return $! (i, v')
          Just x -> do
            v' <- case GMV.length v == i of
                    True -> lift $ GMV.grow v by
                    False -> return v
            lift $ GMV.write v' i x
            go (i+1) v'

它基本上分配by个空槽并继续填充它们。一旦它到达天花板,它再次增长底层矢量。我没有基准测试任何东西,但它似乎在实践中表现良好。我很想知道这里是否会有更有效的答案。

希望这在某种程度上有所帮助。我确实在fromVector中看到了一个repa函数,也许这就是你与这种方法相结合的金票。

答案 1 :(得分:1)

我还没有尝试将CS​​V文件读入修复,但我建议使用木薯(http://hackage.haskell.org/package/cassava)。 Iirc我有一个1.5G文件,我用它来创建我的统计数据。使用木薯,我的程序运行的内存非常少。这是一个扩展的使用示例:

http://idontgetoutmuch.wordpress.com/2013/10/23/parking-in-westminster-an-analysis-in-haskell/

在修复的情况下,如果你逐行地向行添加行(听起来你想做),那么人们希望空间使用也会逐渐增长。这当然值得一个实验。也可能还联系了修理人员。请报告您的结果: - )