Skip to content

Commit

Permalink
Input checking in af::sparse (Fixes arrayfire#2134) (arrayfire#2137)
Browse files Browse the repository at this point in the history
* Add test cases for input checking in af_create_sparse_array

These three tests create a sparse array from array data. In each test
the array data is valid for one storage type. The test checks that the
correct storage type succeeds while the other storage types fail.

* Add checks for length of rowIdx and colIdx
* Update length of rowIdx array to size nRow +1
  • Loading branch information
rstub authored and syurkevi committed Jul 25, 2018
1 parent 8b6e227 commit 95e3e39
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/api/c/sparse.cpp
Expand Up @@ -87,6 +87,18 @@ af_err af_create_sparse_array(
ARG_ASSERT(5, cInfo.getType() == s32);
DIM_ASSERT(5, cInfo.isLinear());

const size_t nNZ = vInfo.elements();
if(stype == AF_STORAGE_COO) {
DIM_ASSERT(4, rInfo.elements() == nNZ);
DIM_ASSERT(5, cInfo.elements() == nNZ);
} else if(stype == AF_STORAGE_CSR) {
DIM_ASSERT(4, rInfo.elements() == nRows + 1);
DIM_ASSERT(5, cInfo.elements() == nNZ);
} else if(stype == AF_STORAGE_CSC) {
DIM_ASSERT(4, rInfo.elements() == nNZ);
DIM_ASSERT(5, cInfo.elements() == nCols + 1);
}

af_array output = 0;

af::dim4 dims(nRows, nCols);
Expand Down
59 changes: 58 additions & 1 deletion test/sparse.cpp
Expand Up @@ -119,6 +119,63 @@ TEST(Sparse, ISSUE_1745)
ASSERT_EQ(AF_ERR_ARG, af_create_sparse_array(&A_sparse, A.dims(0), A.dims(1), data.get(), row_idx.get(), col_idx.get(), AF_STORAGE_CSR));
}

TEST(Sparse, ISSUE_2134_COO)
{
int rows[] = {0,0,0,1,1,2,2};
int cols[] = {0,1,2,0,1,0,2};
float values[] = {3,3,4,3,10,4,3};
af::array row(7, rows);
af::array col(7, cols);
af::array value(7, values);
af_array A = 0;
EXPECT_EQ(AF_ERR_SIZE, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_CSR));
if(A != 0) af_release_array(A);
A = 0;
EXPECT_EQ(AF_ERR_SIZE, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_CSC));
if(A != 0) af_release_array(A);
A = 0;
EXPECT_EQ(AF_SUCCESS, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_COO));
if(A != 0) af_release_array(A);
}

TEST(Sparse, ISSUE_2134_CSR)
{
int rows[] = {0,3,5,7};
int cols[] = {0,1,2,0,1,0,2};
float values[] = {3,3,4,3,10,4,3};
af::array row(4, rows);
af::array col(7, cols);
af::array value(7, values);
af_array A = 0;
EXPECT_EQ(AF_SUCCESS, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_CSR));
if(A != 0) af_release_array(A);
A = 0;
EXPECT_EQ(AF_ERR_SIZE, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_CSC));
if(A != 0) af_release_array(A);
A = 0;
EXPECT_EQ(AF_ERR_SIZE, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_COO));
if(A != 0) af_release_array(A);
}

TEST(Sparse, ISSUE_2134_CSC)
{
int rows[] = {0,0,0,1,1,2,2};
int cols[] = {0,3,5,7};
float values[] = {3,3,4,3,10,4,3};
af::array row(7, rows);
af::array col(4, cols);
af::array value(7, values);
af_array A = 0;
EXPECT_EQ(AF_ERR_SIZE, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_CSR));
if(A != 0) af_release_array(A);
A = 0;
EXPECT_EQ(AF_SUCCESS, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_CSC));
if(A != 0) af_release_array(A);
A = 0;
EXPECT_EQ(AF_ERR_SIZE, af_create_sparse_array(&A, 3, 3, value.get(), row.get(), col.get(), AF_STORAGE_COO));
if(A != 0) af_release_array(A);
}

template<typename T>
class Sparse : public ::testing::Test {};

Expand Down Expand Up @@ -194,7 +251,7 @@ TYPED_TEST(Sparse, EmptyDeepCopy) {
using namespace af;
array a = sparse(0, 0,
array(0, (af_dtype)af::dtype_traits<TypeParam>::af_type),
array(0, s32), array(0, s32));
array(1, s32), array(0, s32));
EXPECT_TRUE(a.issparse());
EXPECT_EQ(0, sparseGetNNZ(a));

Expand Down

0 comments on commit 95e3e39

Please sign in to comment.