
In Haskell, what's the canonical way of declaring a top-level array (Data.Vector of a huge list of doubles, in my case)? Performance is key in my case. The straightforward way would just be something like: globalArray :: V.Vector Double globalArray = V.fromList [ huge list of doubles ] {-# NOINLINE globalArray #-} However, I don't want to have to run the fromList at runtime. Not only would this mean a bigger executable (having to store a linked list, instead of an array), it would be quite inefficient since we don't even use the source list! Therefore, I was thinking of storing the array in a C file: static const double globalArray[] = { huge list of doubles }; double* getGlobalArray() { return globalArray; } int getGlobalArraySize() { return sizeof(globalArray)/sizeof(globalArray[0]); } And importing it in haskell witht he FFI, followed with an unsafeCast: foreign import ccall unsafe "getGlobalArray" c_globalArray :: Ptr CDouble foreign import ccall unsafe "getGlobalArraySize" c_globalArraySize :: CInt globalArray :: V.Vector Double globalArray = V.unsafeCast $ unsafeFromForeignPtr0 (unsafePerformIO $ newForeignPtr_ c_globalArray) (fromIntegral c_globalArraySize) {-# NOINLINE globalArray #-} But this version (clearly) is full of "unsafe"ty. Is there a better way that I haven't thought of? Regards, - clark

Could template-Haskell be used somehow?
- Lyndon Maydwell
On Mar 10, 2012 4:50 AM, "Clark Gaebel"
In Haskell, what's the canonical way of declaring a top-level array (Data.Vector of a huge list of doubles, in my case)? Performance is key in my case.
The straightforward way would just be something like:
globalArray :: V.Vector Double globalArray = V.fromList [ huge list of doubles ] {-# NOINLINE globalArray #-}
However, I don't want to have to run the fromList at runtime. Not only would this mean a bigger executable (having to store a linked list, instead of an array), it would be quite inefficient since we don't even use the source list!
Therefore, I was thinking of storing the array in a C file:
static const double globalArray[] = { huge list of doubles }; double* getGlobalArray() { return globalArray; } int getGlobalArraySize() { return sizeof(globalArray)/sizeof(globalArray[0]); }
And importing it in haskell witht he FFI, followed with an unsafeCast:
foreign import ccall unsafe "getGlobalArray" c_globalArray :: Ptr CDouble foreign import ccall unsafe "getGlobalArraySize" c_globalArraySize :: CInt
globalArray :: V.Vector Double globalArray = V.unsafeCast $ unsafeFromForeignPtr0 (unsafePerformIO $ newForeignPtr_ c_globalArray) (fromIntegral c_globalArraySize) {-# NOINLINE globalArray #-}
But this version (clearly) is full of "unsafe"ty. Is there a better way that I haven't thought of?
Regards, - clark
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Fri, Mar 9, 2012 at 12:48 PM, Clark Gaebel
static const double globalArray[] = { huge list of doubles }; double* getGlobalArray() { return globalArray; } int getGlobalArraySize() { return sizeof(globalArray)/sizeof(globalArray[0]); }
And importing it in haskell witht he FFI, followed with an unsafeCast:
foreign import ccall unsafe "getGlobalArray" c_globalArray :: Ptr CDouble foreign import ccall unsafe "getGlobalArraySize" c_globalArraySize :: CInt
You can use Data.Array.Storable to do this. http://hackage.haskell.org/packages/archive/array/0.3.0.3/doc/html/Data-Arra... Also, there is no need to create stub C functions, you can foreign import the array directly And if you don't want to cast between CDouble and Double you can declare your array to be of HsDouble and #include "HsFFI.h" const HsDouble globalArray[] = { huge list of doubles }; foreign import ccall unsafe "&globalArray" :: Ptr Double John

What's the advantage of using D.A.Storable over D.Vector? And yes,
good call with creating an array of HSDouble directly. I didn't think
of that!
On Fri, Mar 9, 2012 at 8:25 PM, John Meacham
On Fri, Mar 9, 2012 at 12:48 PM, Clark Gaebel
wrote: static const double globalArray[] = { huge list of doubles }; double* getGlobalArray() { return globalArray; } int getGlobalArraySize() { return sizeof(globalArray)/sizeof(globalArray[0]); }
And importing it in haskell witht he FFI, followed with an unsafeCast:
foreign import ccall unsafe "getGlobalArray" c_globalArray :: Ptr CDouble foreign import ccall unsafe "getGlobalArraySize" c_globalArraySize :: CInt
You can use Data.Array.Storable to do this. http://hackage.haskell.org/packages/archive/array/0.3.0.3/doc/html/Data-Arra...
Also, there is no need to create stub C functions, you can foreign import the array directly And if you don't want to cast between CDouble and Double you can declare your array to be of HsDouble and #include "HsFFI.h"
const HsDouble globalArray[] = { huge list of doubles }; foreign import ccall unsafe "&globalArray" :: Ptr Double
John

On Fri, Mar 9, 2012 at 5:49 PM, Clark Gaebel
What's the advantage of using D.A.Storable over D.Vector? And yes, good call with creating an array of HSDouble directly. I didn't think of that!
Oh, looks like D.Vector has an unsafeFromForeignPtr too, I didn't see that. so D.Vector should work just fine. :) John

what's the canonical way of declaring a top-level array Did you try State/StateT monads?
10 марта 2012 г. 5:05 пользователь John Meacham
On Fri, Mar 9, 2012 at 5:49 PM, Clark Gaebel
wrote: What's the advantage of using D.A.Storable over D.Vector? And yes, good call with creating an array of HSDouble directly. I didn't think of that!
Oh, looks like D.Vector has an unsafeFromForeignPtr too, I didn't see that. so D.Vector should work just fine. :)
John
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- С уважением, Александр Личный блог: http://eax.me/ Мой форум: http://it-talk.org/ Мой Twitter: http://twitter.com/afiskon

Wouldn't that still have to loop through the array (or in this case,
evaluate the monad) in order to use it the first time?
On Sat, Mar 10, 2012 at 2:22 AM, Alexandr Alexeev
what's the canonical way of declaring a top-level array Did you try State/StateT monads?
10 марта 2012 г. 5:05 пользователь John Meacham
написал: On Fri, Mar 9, 2012 at 5:49 PM, Clark Gaebel
wrote: What's the advantage of using D.A.Storable over D.Vector? And yes, good call with creating an array of HSDouble directly. I didn't think of that!
Oh, looks like D.Vector has an unsafeFromForeignPtr too, I didn't see that. so D.Vector should work just fine. :)
John
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- С уважением, Александр Личный блог: http://eax.me/ Мой форум: http://it-talk.org/ Мой Twitter: http://twitter.com/afiskon

Clark Gaebel
In Haskell, what's the canonical way of declaring a top-level array (Data.Vector of a huge list of doubles, in my case)? Performance is key in my case.
The straightforward way would just be something like:
globalArray :: V.Vector Double globalArray = V.fromList [ huge list of doubles ] {-# NOINLINE globalArray #-}
However, I don't want to have to run the fromList at runtime.
I think GHC will convert it to an array (and in general evaluate constants) at compile time (probably requires -O). -k

Is there any proof of this? I'm not familiar enough with core to check.
On Mon, Mar 12, 2012 at 3:48 AM, Ketil Malde
Clark Gaebel
writes: In Haskell, what's the canonical way of declaring a top-level array (Data.Vector of a huge list of doubles, in my case)? Performance is key in my case.
The straightforward way would just be something like:
globalArray :: V.Vector Double globalArray = V.fromList [ huge list of doubles ] {-# NOINLINE globalArray #-}
However, I don't want to have to run the fromList at runtime.
I think GHC will convert it to an array (and in general evaluate constants) at compile time (probably requires -O).
-k
participants (5)
-
Alexandr Alexeev
-
Clark Gaebel
-
John Meacham
-
Ketil Malde
-
Lyndon Maydwell