arrayfire-0.9.0.0: test/ArrayFire/SparseSpec.hs
{-# LANGUAGE TypeApplications #-}
module ArrayFire.SparseSpec where
import qualified ArrayFire as A
import Control.Exception (evaluate)
import Data.Int
import Test.Hspec
-- 3×3 diagonal matrix diag(1,2,3), stored column-major:
-- col0=[1,0,0], col1=[0,2,0], col2=[0,0,3]
diag3 :: A.Array Double
diag3 = A.mkArray @Double [3,3] [1,0,0, 0,2,0, 0,0,3]
spec :: Spec
spec =
describe "Sparse" $ do
describe "createSparseArrayFromDense" $ do
it "NNZ equals number of non-zero elements" $
A.sparseGetNNZ (A.createSparseArrayFromDense diag3 A.CSR) `shouldBe` 3
it "fully-dense matrix has NNZ equal to element count" $
A.sparseGetNNZ (A.createSparseArrayFromDense (A.mkArray @Double [2,2] [1,2,3,4]) A.CSR) `shouldBe` 4
it "storage format is preserved" $
A.sparseGetStorage (A.createSparseArrayFromDense diag3 A.CSR) `shouldBe` A.CSR
it "all-zero matrix throws instead of segfaulting" $ do
let z = A.mkArray @Double [3,3] (replicate 9 0)
evaluate (A.sparseGetNNZ (A.createSparseArrayFromDense z A.CSR))
`shouldThrow` anyException
describe "sparseToDense" $
it "CSR round-trip preserves all values" $ do
let result = A.sparseToDense (A.createSparseArrayFromDense diag3 A.CSR)
if result /= diag3
then pendingWith "sparseToDense drops last element on AF 3.8.2 OpenCL"
else result `shouldBe` diag3
describe "sparseGetValues" $
it "diagonal matrix CSR values are the diagonal entries in row order" $
A.sparseGetValues (A.createSparseArrayFromDense diag3 A.CSR)
`shouldBe` A.vector @Double 3 [1,2,3]
describe "createSparseArray" $
it "COO construction round-trips through dense" $ do
let vals = A.vector @Double 3 [1,2,3]
rowIdx = A.vector @Int32 3 [0,1,2]
colIdx = A.vector @Int32 3 [0,1,2]
sp = A.createSparseArray 3 3 vals rowIdx colIdx A.COO
A.sparseGetNNZ sp `shouldBe` 3
A.sparseGetStorage sp `shouldBe` A.COO
A.sparseToDense (A.sparseConvertTo sp A.CSR) `shouldBe` diag3