FFI: returning three Int#'s on the stack - haskell

Is there any way to return three Int# on the stack from a foreign function call? Here is the C code (or C code that generates an object file equivalent to the one I'm actually interested in):
struct Tuple {
int bezout1, bezout2, gcd;
}
struct Tuple extendedGcd(int a, int b) {
/* elided */
}
This won't compile since (# Int#, Int#, Int# #) isn't supported by ccall:
foreign import ccall "extendedGcd"
extendedGcd :: Int# -> Int# -> (# Int#, Int#, Int# #)
All my uses of the following (which compiles, albeit with MagicHash, GHCForeignImportPrim, ForeignFunctionInterface, UnboxedTuples, and MagicHash) seg-fault:
foreign import prim "extendedGcd"
extendedGcd :: Int# -> Int# -> (# Int#, Int#, Int# #)
I can find some evidence that there was some effort to get around this sort of problem:
thread on the mailing list
a proposed (but abandoned) CStructures GHC extension (by the same person)
I imagine this is a common issue, yet I can't find any working examples. Is this at all possible? If it isn't does anyone care about this anymore (is there a Trac ticket somewhere?)

If you can implement your procedure in assembly directly, rather than C, it's pretty easy to do this. See: http://brandon.si/code/almost-inline-asm-in-haskell-with-foreign-import-prim/ . Maybe for a GCD algorithm this will be okay for you.
There is a complete cabal project I put together here.

Related

Copying GHC ByteArray# to Ptr

I am trying to write the following function:
memcpyByteArrayToPtr ::
ByteArray# -- ^ source
-> Int -- ^ start
-> Int -- ^ length
-> Ptr a -- ^ destination
-> IO ()
The behavior should be to internally use memcpy to copy the contents of a ByteArray# to the Ptr. There are two techniques I have seen for doing something like this, but it's difficult for me to reason about their safety.
The first is found in the memory package. There is an auxiliary function withPtr defined as:
data Bytes = Bytes (MutableByteArray# RealWorld)
withPtr :: Bytes -> (Ptr p -> IO a) -> IO a
withPtr b#(Bytes mba) f = do
a <- f (Ptr (byteArrayContents# (unsafeCoerce# mba)))
touchBytes b
return a
But, I'm pretty sure that this is only safe because the only way to construct Bytes is by using a smart constructor that calls newAlignedPinnedByteArray#. An answer given to a similar question and the docs for byteArrayContents# indicate that it is only safe when dealing with pinned ByteArray#s. In my situation, I'm dealing with the ByteArray#s that the text library uses internally, and they are not pinned, so I believe this would be unsafe.
The second possibility I've stumbled across is in text itself. At the bottom of the Data.Text.Array source code, there is an ffi function memcpyI:
foreign import ccall unsafe "_hs_text_memcpy" memcpyI
:: MutableByteArray# s -> CSize -> ByteArray# -> CSize -> CSize -> IO ()
This is backed by the following c code:
void _hs_text_memcpy(void *dest, size_t doff, const void *src, size_t soff, size_t n)
{
memcpy(dest + (doff<<1), src + (soff<<1), n<<1);
}
Because its a part of text, I trust that this is safe. It looks like it's dangerous because is that it's getting a memory location from an unpinned ByteArray#, the very thing that the byteArrayContents# documentation warns against. I suspect that it's ok because the ffi call is marked as unsafe, which I think prevents the GC from moving the ByteArray# during the ffi call.
That's the research I've done far. So far, my best guess is that I can just copy what's been done in text. The big difference would be that, instead of passing in MutableByteArray# and ByteArray# as the two pointers, I would be passing in ByteArray# and Ptr a (or maybe Addr#, I'm not sure which of those you typically use with the ffi).
Is what I have suggested safe? Is there a better way that would allow me to avoid using the ffi? Is there something in base that does this? Feel free to correct any incorrect assumptions I've made, and thanks for any suggestions or guidance.
copyByteArrayToAddr# :: ByteArray# -> Int# -> Addr# -> Int# -> State# s -> State# s
looks like the right primop. You just need to be sure not to try to copy it into memory it occupies. So you should probably be safe with
copyByteArrayToPtr :: ByteArray# -> Int -> Ptr a -> Int -> ST s ()
copyByteArrayToPtr ba (I# x) (Ptr p) (I# y) = ST $ \ s ->
(# copyByteArrayToAddr# ba x p y s, () #)
Unfortunately, the documentation gives me no clue what each Int# is supposed to mean, but I imagine you can figure that out through trial and segfault.

What are hashes (#) used for in the library's source?

I was trying to figure out how mVars work, and I came across this bit of code:
-- |Create an 'MVar' which is initially empty.
newEmptyMVar :: IO (MVar a)
newEmptyMVar = IO $ \ s# ->
case newMVar# s# of
(# s2#, svar# #) -> (# s2#, MVar svar# #)
Besides being confusingly mutually recursive with newMVar, it's also littered with hashs (#).
Between the two, I can't figure out how it works. I know that this is basically just a pseudo-constructor for mVar, but the rest of the module (most of the library actually) contains them, and I can't find anything on them. Googling "Haskell hashs" didn't yield anything relevant.
They're (literally) magic hashes. They distinguish GHC's primitive's like addition, unboxed types, and unboxed tuples. You can enable writing them with
{-# LANGUAGE MagicHash #-}
Now you can import the stubs that let you use them with
import GHC.Exts
unboxed :: Int# -> Int# -> Int#
unboxed a# b# = a# +# b#
boxed :: Int -> Int -> Int
boxed (I# a#) (I# b#) = I# (unboxed a# b#)
This actually is kinda nifty when you think about it, by wrapping the magical and strict primitives like this, we can handle lazy Ints and Chars uniformly at the runtime system level.
Because primitives are not boxed, they're segregated at the kind level. This means that Int# doesn't have the kind * like normal types, which also means something like
kindClash :: Int# -> Int#
kindClash = id -- id expects boxed types
Won't compile.
To further elaborate on your code, newMVar includes a call to a compiler primitive in GHC to allocate a new mutable variable. It's not mutually recursive so much as a thin wrapper over a compiler call. There's also some darkness gathering at the corners of this function since we're treating IO as a perverse state monad, but let's not look to closely at that. I like my sanity too much.
I don't use primitives in everyday code, nor should you. They come up when implementing crazy optimized hotspots, or near primitive abstractions like what you're looking at.

Can Haskell inline functions passed as an argument?

Let's say I pass a small function f to map. Can Haskell inline f with map to produce a small imperative loop? If so, how does Haskell keep track of what function f really is? Can the same be done with Arrow combinators?
If f is passed in as an argument, then no, probably not. If f is the name of a top-level function or a local function, then probably yes.
foobar f = ... map f ...
-- Probably not inlined.
foobar = ... map (\ x -> ...) ...
-- Probably inlined.
That said, I gather that most of the performance difference between inline and out of line comes not from the actual inlining itself, but rather from any additional subsequent optimisations this might allow.
The only way to be "sure" about these things is to actually write the code, actually compile it, and have a look at the Core that gets generated. And the only way to know if it makes a difference (positive or negative) is to actually benchmark the thing.
The definition of the Haskell language does not mandate a Haskell implementation to inline code, or to perform any kind of optimization. Any implementation is free to apply any optimization it may deem appropriate.
That being said, Haskell is nowadays often run using GHC, which does optimize Haskell code. For inlining, GHC uses some heuristics to decide whether something should inlined or not. The general advice is to turn optimization on with -O2 and check the output of the compiler. You can see the produced Core with -ddump-simpl, or the assembly code with -ddump-asm. Some other flags can be useful as well.
If you then see that GHC is not inlining stuff you would like to, you can provide a hint to the compiler with {-# INLINE foo #-} and related pragmas.
Be wary of mindlessly applying optimizations, though. Often, programmers spend their time to optimize parts of the program which have a negligible impact to the overall performance. To avoid this, it is strongly recommended to profile your code first, so that you know where your program spends a lot of time.
Here is an example where GHC does inline a function passed as an argument :
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector as V
plus :: Int -> Int -> Int
plus = (+)
sumVect :: V.Vector Int -> Int
sumVect = V.foldl1 plus
plus is passed as the argument of foldl1, which results in summing a vector of integers. In the Core, plus is inlined and optimized to the unboxed GHC.Prim.+# :: Int# -> Int# -> Int# :
letrec {
$s$wfoldlM_loop_s759
:: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int#
$s$wfoldlM_loop_s759 =
\ (sc_s758 :: GHC.Prim.Int#) (sc1_s757 :: GHC.Prim.Int#) ->
case GHC.Prim.tagToEnum# # Bool (GHC.Prim.>=# sc_s758 ww1_s748)
of _ {
False ->
case GHC.Prim.indexArray#
# Int ww2_s749 (GHC.Prim.+# ww_s747 sc_s758)
of _ { (# ipv1_X72o #) ->
case ipv1_X72o of _ { GHC.Types.I# y_a5Kg ->
$s$wfoldlM_loop_s759
(GHC.Prim.+# sc_s758 1#) (GHC.Prim.+# sc1_s757 y_a5Kg)
}
};
True -> sc1_s757
}; }
That's the GHC.Prim.+# sc1_s757 y_a5Kg. You can add simple artihmetic inside function plus and see this Core expression expand.

Python-"is"-like equality operator for Haskell/GHC

Is there a GHC-specific "unsafe" extension to ask whether two Haskell references point to the same location?
I'm aware this can break referential transparency if not used properly. But there should be little harm (unless I'm missing something), if it is used very careful, as a means for optimizations by short-cutting recursive (or expensive) data traversal, e.g. for implementing an optimized Eq instance, e.g.:
instance Eq ComplexTree where
a == b = (a `unsafeSameRef` b) || (a `deepCompare` b)
providing deepCompare is guaranteed to be true if unsafeSameRef decides true (but not necessarily the other way around).
EDIT/PS: Thanks to the answer pointing to System.Mem.StableName, I was able to also find the paper Stretching the storage manager: weak pointers and stable names in Haskell which happens to have addressed this very problem already over 10 years ago...
GHC's System.Mem.StableName solves exactly this problem.
There's a pitfall to be aware of:
Pointer equality can change strictness. I.e., you might get pointer equality saying True when in fact the real equality test would have looped because of, e.g., a circular structure. So pointer equality ruins the semantics (but you knew that).
I think StablePointers might be of help here
http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Foreign-StablePtr.html
Perhaps this is the kind of solution you are looking for:
import Foreign.StablePtr (newStablePtr, freeStablePtr)
import System.IO.Unsafe (unsafePerformIO)
unsafeSameRef :: a -> a -> Bool
unsafeSameRef x y = unsafePerformIO $ do
a <- newStablePtr x
b <- newStablePtr y
let z = a == b
freeStablePtr a
freeStablePtr b
return z;
There's unpackClosure# in GHC.Prim, with the following type:
unpackClosure# :: a -> (# Addr#,Array# b,ByteArray# #)
Using that you could whip up something like:
{-# LANGUAGE MagicHash, UnboxedTuples #-}
import GHC.Prim
eq a b = case unpackClosure# a of
(# a1,a2,a3 #) -> case unpackClosure# b of
(# b1,b2,b3 #) -> eqAddr# a1 b1
And in the same package, there's the interestingly named reallyUnsafePtrEquality# of type
reallyUnsafePtrEquality# :: a -> a -> Int#
But I'm not sure what the return value of that one is - going by the name it will lead to much gnashing of teeth.

Is there any hope to cast ForeignPtr to ByteArray# (for a function :: ByteString -> Vector)

For performance reasons I would like a zero-copy cast of ByteString (strict, for now) to a Vector. Since Vector is just a ByteArray# under the hood, and ByteString is a ForeignPtr this might look something like:
caseBStoVector :: ByteString -> Vector a
caseBStoVector (BS fptr off len) =
withForeignPtr fptr $ \ptr -> do
let ptr' = plusPtr ptr off
p = alignPtr ptr' (alignment (undefined :: a))
barr = ptrToByteArray# p len -- I want this function, or something similar
barr' = ByteArray barr
alignI = minusPtr p ptr
size = (len-alignI) `div` sizeOf (undefined :: a)
return (Vector 0 size barr')
That certainly isn't right. Even with the missing function ptrToByteArray# this seems to need to escape the ptr outside of the withForeignPtr scope. So my quesetions are:
This post probably advertises my primitive understanding of ByteArray#, if anyone can talk a bit about ByteArray#, it's representation, how it is managed (GCed), etc I'd be grateful.
The fact that ByteArray# lives on the GCed heap and ForeignPtr is external seems to be a fundamental issue - all the access operations are different. Perhaps I should look at redefining Vector from = ByteArray !Int !Int to something with another indirection? Someing like = Location !Int !Int where data Location = LocBA ByteArray | LocFPtr ForeignPtr and provide wrapping operations for both those types? This indirection might hurt performance too much though.
Failing to marry these two together, maybe I can just access arbitrary element types in a ForeignPtr in a more efficient manner. Does anyone know of a library that treats ForeignPtr (or ByteString) as an array of arbitrary Storable or Primitive types? This would still lose me the stream fusion and tuning from the Vector package.
Disclaimer: everything here is an implementation detail and specific to GHC and the internal representations of the libraries in question at the time of posting.
This response is a couple years after the fact, but it is indeed possible to get a pointer to bytearray contents. It's problematic as the GC likes to move data in the heap around, and things outside of the GC heap can leak, which isn't necessarily ideal. GHC solves this with:
newPinnedByteArray# :: Int# -> State# s -> (#State# s, MutableByteArray# s#)
Primitive bytearrays (internally typedef'd C char arrays) can be statically pinned to an address. The GC guarantees not to move them. You can convert a bytearray reference to a pointer with this function:
byteArrayContents# :: ByteArray# -> Addr#
The address type forms the basis of Ptr and ForeignPtr types. Ptrs are addresses marked with a phantom type and ForeignPtrs are that plus optional references to GHC memory and IORef finalizers.
Disclaimer: This will only work if your ByteString was built Haskell. Otherwise, you can't get a reference to the bytearray. You cannot dereference an arbitrary addr. Don't try to cast or coerce your way to a bytearray; that way lies segfaults. Example:
{-# LANGUAGE MagicHash, UnboxedTuples #-}
import GHC.IO
import GHC.Prim
import GHC.Types
main :: IO()
main = test
test :: IO () -- Create the test array.
test = IO $ \s0 -> case newPinnedByteArray# 8# s0 of {(# s1, mbarr# #) ->
-- Write something and read it back as baseline.
case writeInt64Array# mbarr# 0# 1# s1 of {s2 ->
case readInt64Array# mbarr# 0# s2 of {(# s3, x# #) ->
-- Print it. Should match what was written.
case unIO (print (I# x#)) s3 of {(# s4, _ #) ->
-- Convert bytearray to pointer.
case byteArrayContents# (unsafeCoerce# mbarr#) of {addr# ->
-- Dereference the pointer.
case readInt64OffAddr# addr# 0# s4 of {(# s5, x'# #) ->
-- Print what's read. Should match the above.
case unIO (print (I# x'#)) s5 of {(# s6, _ #) ->
-- Coerce the pointer into an array and try to read.
case readInt64Array# (unsafeCoerce# addr#) 0# s6 of {(# s7, y# #) ->
-- Haskell is not C. Arrays are not pointers.
-- This won't match. It might segfault. At best, it's garbage.
case unIO (print (I# y#)) s7 of (# s8, _ #) -> (# s8, () #)}}}}}}}}
Output:
1
1
(some garbage value)
To get the bytearray from a ByteString, you need to import the constructor from Data.ByteString.Internal and pattern match.
data ByteString = PS !(ForeignPtr Word8) !Int !Int
(\(PS foreignPointer offset length) -> foreignPointer)
Now we need to rip the goods out of the ForeignPtr. This part is entirely implementation-specific. For GHC, import from GHC.ForeignPtr.
data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
(\(ForeignPtr addr# foreignPointerContents) -> foreignPointerContents)
data ForeignPtrContents = PlainForeignPtr !(IORef (Finalizers, [IO ()]))
| MallocPtr (MutableByteArray# RealWorld) !(IORef (Finalizers, [IO ()]))
| PlainPtr (MutableByteArray# RealWorld)
In GHC, ByteString is built with PlainPtrs which are wrapped around pinned byte arrays. They carry no finalizers. They are GC'd like regular Haskell data when they fall out of scope. Addrs don't count, though. GHC assumes they point to things outside of the GC heap. If the bytearray itself falls out of the scope, you're left with a dangling pointer.
data PlainPtr = (MutableByteArray# RealWorld)
(\(PlainPtr mutableByteArray#) -> mutableByteArray#)
MutableByteArrays are identical to ByteArrays. If you want true zero-copy construction, make sure you either unsafeCoerce# or unsafeFreeze# to a bytearray. Otherwise, GHC creates a duplicate.
mbarrTobarr :: MutableByteArray# s -> ByteArray#
mbarrTobarr = unsafeCoerce#
And now you have the raw contents of the ByteString ready to be turned into a vector.
Best Wishes,
You might be able to hack together something :: ForeignPtr -> Maybe ByteArray#, but there is nothing you can do in general.
You should look at the Data.Vector.Storable module. It includes a function unsafeFromForeignPtr :: ForeignPtr a -> Int -> Int -> Vector a. It sounds like what you want.
There is also a Data.Vector.Storable.Mutable variant.

Resources