How to store Haskell data type in unboxed vector in continuous memory

I want to store a nonparametric, decompressed data type

data Point3D = Point3D {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int

In unbound vectors Data. Vector. Unboxed said:

Why? I want my point3d to be laid out one by one in memory to get fast cache local access when iterating them sequentially – equivalent to mystruct [1000] in C

Use vector Un@R_197_2419 @Ed or other ways, how can I achieve it?

By the way: the same is true with vector th unbox, because you only need to convert the data type to( Un@R_197_2419 @ a, Un@R_197_2419 @ b)=> Un@R_197_2419 @(a,b)instance.

Solution

I don't know why pairs of vectors are stored as vector pairs, but you can easily write instances for your data types to store elements in order

{-# LANGUAGE TypeFamilies,MultiParamTypeClasses #-}

import qualified Data.Vector.Generic as G 
import qualified Data.Vector.Generic.Mutable as M 
import Control.Monad (liftM,zipWithM_)
import Data.Vector.Un@R_197_2419@ed.Base

data Point3D = Point3D {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int

newtype instance MVector s Point3D = MV_Point3D (MVector s Int)
newtype instance Vector    Point3D = V_Point3D  (Vector    Int)
instance Un@R_197_2419@ Point3D

At this point, the last line causes an error because point3d has no instance of vector type They can be written as follows:

instance M.MVector MVector Point3D where 
  basicLength (MV_Point3D v) = M.basicLength v `div` 3 
  basicUnsafeSlice a b (MV_Point3D v) = MV_Point3D $M.basicUnsafeSlice (a*3) (b*3) v 
  basicOverlaps (MV_Point3D v0) (MV_Point3D v1) = M.basicOverlaps v0 v1 
  basicUnsafeNew n = liftM MV_Point3D (M.basicUnsafeNew (3*n))
  basicUnsafeRead (MV_Point3D v) n = do 
    [a,b,c] <- mapM (M.basicUnsafeRead v) [3*n,3*n+1,3*n+2]
    return $Point3D a b c 
  basicUnsafeWrite (MV_Point3D v) n (Point3D a b c) = zipWithM_ (M.basicUnsafeWrite v) [3*n,3*n+2] [a,c]

instance G.Vector Vector Point3D where 
  basicUnsafeFreeze (MV_Point3D v) = liftM V_Point3D (G.basicUnsafeFreeze v)
  basicUnsafeThaw (V_Point3D v) = liftM MV_Point3D (G.basicUnsafeThaw v)
  basicLength (V_Point3D v) = G.basicLength v `div` 3
  basicUnsafeSlice a b (V_Point3D v) = V_Point3D $G.basicUnsafeSlice (a*3) (b*3) v 
  basicUnsafeIndexM (V_Point3D v) n = do 
    [a,c] <- mapM (G.basicUnsafeIndexM v) [3*n,3*n+2]
    return $Point3D a b c

I think most function definitions are self explanatory The point vector is stored as the vector of ints, and the nth point is 3N, 3N 1,3n 2 ints

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>