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.

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to