[Haskell-cafe] Linking to third party libraries in windows

Matthew Bromberg mattcbro at earthlink.net
Fri May 26 00:49:02 EDT 2006


OK I'm punting on the AMD libraries for now and will just use the Atlas 
libraries until I can get
to the bottom of this. 

However, for me, it seems the rabbit hole goes a little deeper on the 
issue of array copies.  Consider this
code snippet

import Matrix


main = do
    print "Matrices"
    let r2 = listtoRmatrix 3 2 [1, 1, 1, 1, 1, 1]
    rout <- mac r2 (-0.5) rmat
    putStrLn "\nrout"
    mprint rout
    putStrLn "\nrmat2"
    mprint r2
    putStrLn "\nrmat"
    mprint rmat

An  Rmatrix has type (Int, Int, IO (StorableArray Int CDouble)) and mac 
(multiply and accumulate) should
provide the side effecting operation A <- A+ alpha * B  for mac A alpha 
B .  It returns IO(Rmatrix) for clarity here.
listtoRmatrix just returns a regular Rmatrix.  Now mac is implemented 
via daxpy and it should modify the mutable array in r2. 

rout is printed prior to r2,  which (surprisingly?)  remains unchanged. 
Here are the outputs
rout
      0.5000000      -1.0000000
      0.0000000      -1.5000000
     -0.5000000      -2.0000000

rmat2
      1.0000000       1.0000000
      1.0000000       1.0000000
      1.0000000       1.0000000

rmat
      1.0000000       4.0000000
      2.0000000       5.0000000
      3.0000000       6.0000000



 Thus Haskell does not allow the side effect to affect the let binding.  
How does it achieve this without copying r2?  If I bound r2 to this 
matrix using <- and a monad wrapper the result is the same. Does it 
recreate r2 just prior to the call to mprint r2?

If Haskell has a magic way of doing this, without actually making a copy 
of the mutable array in r2, that would be pretty nifty actually.

Brian Hulley wrote:
>
> I'd thought the stub was just to give the compiler something to 
> compile against, and that __stdcall was only used by Windows API 
> rather than all DLLs, but no doubt you're right. Ive just been looking 
> at the "Exporting from a DLL" help page from Visual Studio and it says 
> "When exporting functions with either method, make sure to use 
> __stdcall", so perhaps the functions I've exported using 
> __declspec(dllexport) are using __stdcall after all.
>
>>
>> Now for my 'surprising' result.  The matrix library is working against
>> double arrays stored in a StorableArray.  Presumably these storable
>> arrays are mutable, but in fact the compiler makes sure that the
>> array's are copied, when I enter a do clause. So for example
>> arrx = newListArray (1 , 3) [3,2,1]:: IO (StorableArray Int CDouble)
>> arry = newListArray (1 , 3) [1,1,1]:: IO (StorableArray Int CDouble)
>>
>> allocates two Storable arrays.
>
> No - this doesn't do any allocation. It just sets up two equations so 
> that anywhere you write arrx is equivalent to writing newListArray (1 
> , 3) [3,2,1]:: IO (StorableArray Int CDouble)
>
>
> It's not copied. A new array is created. Your do loop is the same as:
>
> -- the outer do
> do
>    -- presumably you wrote arr <- arrx somewhere here
>    arr <- newListArray (1 , 3) [3,2,1]:: IO (StorableArray Int CDouble)
>
>    -- the do loop quoted above
>     do
>           arr <- newListArray (1 , 3) [3,2,1]:: IO (StorableArray Int 
> CDouble)
>           withStorableArray arr sumarr >>= print
>
> -- view the contents of the first "arr"
> putStrLn "Element 1: " >> (readArray arr 1 >>= print)
>
> Regards, Brian.
>


More information about the Haskell-Cafe mailing list