
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.