@@ -63,7 +63,7 @@ class Csr : public ::testing::Test {
6363 using ComplexVec = gko::matrix::Dense<std::complex <double >>;
6464 using ComplexMtx = gko::matrix::Csr<std::complex <double >>;
6565
66- Csr () : rand_engine(42 ) {}
66+ Csr () : mtx_size( 532 , 231 ), rand_engine(42 ) {}
6767
6868 void SetUp ()
6969 {
@@ -93,11 +93,11 @@ class Csr : public ::testing::Test {
9393 int num_vectors = 1 )
9494 {
9595 mtx = Mtx::create (ref, strategy);
96- mtx->copy_from (gen_mtx<Vec>(532 , 231 , 1 ));
96+ mtx->copy_from (gen_mtx<Vec>(mtx_size[ 0 ], mtx_size[ 1 ] , 1 ));
9797 square_mtx = Mtx::create (ref, strategy);
98- square_mtx->copy_from (gen_mtx<Vec>(532 , 532 , 1 ));
99- expected = gen_mtx<Vec>(532 , num_vectors, 1 );
100- y = gen_mtx<Vec>(231 , num_vectors, 1 );
98+ square_mtx->copy_from (gen_mtx<Vec>(mtx_size[ 0 ], mtx_size[ 0 ] , 1 ));
99+ expected = gen_mtx<Vec>(mtx_size[ 0 ] , num_vectors, 1 );
100+ y = gen_mtx<Vec>(mtx_size[ 1 ] , num_vectors, 1 );
101101 alpha = gko::initialize<Vec>({2.0 }, ref);
102102 beta = gko::initialize<Vec>({-1.0 }, ref);
103103 dmtx = Mtx::create (cuda, strategy);
@@ -118,14 +118,48 @@ class Csr : public ::testing::Test {
118118 std::shared_ptr<ComplexMtx::strategy_type> strategy)
119119 {
120120 complex_mtx = ComplexMtx::create (ref, strategy);
121- complex_mtx->copy_from (gen_mtx<ComplexVec>(532 , 231 , 1 ));
121+ complex_mtx->copy_from (
122+ gen_mtx<ComplexVec>(mtx_size[0 ], mtx_size[1 ], 1 ));
122123 complex_dmtx = ComplexMtx::create (cuda, strategy);
123124 complex_dmtx->copy_from (complex_mtx.get ());
124125 }
125126
127+ struct matrix_pair {
128+ std::unique_ptr<Mtx> ref;
129+ std::unique_ptr<Mtx> cuda;
130+ };
131+
132+ matrix_pair gen_unsorted_mtx ()
133+ {
134+ constexpr int min_nnz_per_row = 2 ; // Must be larger/equal than 2
135+ auto local_mtx_ref =
136+ gen_mtx<Mtx>(mtx_size[0 ], mtx_size[1 ], min_nnz_per_row);
137+ for (size_t row = 0 ; row < mtx_size[0 ]; ++row) {
138+ const auto row_ptrs = local_mtx_ref->get_const_row_ptrs ();
139+ const auto start_row = row_ptrs[row];
140+ auto col_idx = local_mtx_ref->get_col_idxs () + start_row;
141+ auto vals = local_mtx_ref->get_values () + start_row;
142+ const auto nnz_in_this_row = row_ptrs[row + 1 ] - row_ptrs[row];
143+ auto swap_idx_dist =
144+ std::uniform_int_distribution<>(0 , nnz_in_this_row - 1 );
145+ // shuffle `nnz_in_this_row / 2` times
146+ for (size_t perm = 0 ; perm < nnz_in_this_row; perm += 2 ) {
147+ const auto idx1 = swap_idx_dist (rand_engine);
148+ const auto idx2 = swap_idx_dist (rand_engine);
149+ std::swap (col_idx[idx1], col_idx[idx2]);
150+ std::swap (vals[idx1], vals[idx2]);
151+ }
152+ }
153+ auto local_mtx_cuda = Mtx::create (cuda);
154+ local_mtx_cuda->copy_from (local_mtx_ref.get ());
155+
156+ return {std::move (local_mtx_ref), std::move (local_mtx_cuda)};
157+ }
158+
126159 std::shared_ptr<gko::ReferenceExecutor> ref;
127160 std::shared_ptr<const gko::CudaExecutor> cuda;
128161
162+ const gko::dim<2 > mtx_size;
129163 std::ranlux48 rand_engine;
130164
131165 std::unique_ptr<Mtx> mtx;
@@ -576,4 +610,28 @@ TEST_F(Csr, MoveToHybridIsEquivalentToRef)
576610}
577611
578612
613+ TEST_F (Csr, SortSortedMatrixIsEquivalentToRef)
614+ {
615+ set_up_apply_data (std::make_shared<Mtx::automatical>());
616+
617+ mtx->sort_by_column_index ();
618+ dmtx->sort_by_column_index ();
619+
620+ // Values must be unchanged, therefore, tolerance is `0`
621+ GKO_ASSERT_MTX_NEAR (mtx, dmtx, 0 );
622+ }
623+
624+
625+ TEST_F (Csr, SortUnsortedMatrixIsEquivalentToRef)
626+ {
627+ auto uns_mtx = gen_unsorted_mtx ();
628+
629+ uns_mtx.ref ->sort_by_column_index ();
630+ uns_mtx.cuda ->sort_by_column_index ();
631+
632+ // Values must be unchanged, therefore, tolerance is `0`
633+ GKO_ASSERT_MTX_NEAR (uns_mtx.ref , uns_mtx.cuda , 0 );
634+ }
635+
636+
579637} // namespace
0 commit comments