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