int test_main(int argc, char *argv[]) { ////////////////////////////////////////////////////////////////////////// //[> Parameters <] //FIXME: use random sizes? const size_t n = 10; const size_t m = 5; const size_t n_s = 6; const size_t m_s = 3; typedef skylark::base::sparse_matrix_t<double> Matrix_t; ////////////////////////////////////////////////////////////////////////// //[> Setup test <] namespace mpi = boost::mpi; mpi::environment env(argc, argv); mpi::communicator world; const size_t rank = world.rank(); skylark::base::context_t context (0); double count = 1.0; const int matrix_full = n * m; std::vector<int> colsf(m + 1); std::vector<int> rowsf(matrix_full); std::vector<double> valsf(matrix_full); for(size_t i = 0; i < m + 1; ++i) colsf[i] = i * n; for(size_t i = 0; i < matrix_full; ++i) { rowsf[i] = i % n; valsf[i] = count; count++; } Matrix_t A; A.attach(&colsf[0], &rowsf[0], &valsf[0], matrix_full, n, m, false); count = 1; const int* indptr = A.indptr(); const int* indices = A.indices(); const double* values = A.locked_values(); for(int col = 0; col < A.width(); col++) { for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { BOOST_REQUIRE( values[idx] == count ); count++; } } ////////////////////////////////////////////////////////////////////////// //[> Test COO to CSC <] typename Matrix_t::coords_t coords_mat; count = 1; for(int col = 0; col < A.width(); col++) { for(int row = 0; row < A.height(); row++) { typename Matrix_t::coord_tuple_t new_entry(row, col, count); coords_mat.push_back(new_entry); count++; } } Matrix_t A_coord; A_coord.set(coords_mat); count = 1; indptr = A_coord.indptr(); indices = A_coord.indices(); values = A_coord.locked_values(); for(int col = 0; col < A_coord.width(); col++) { for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { BOOST_REQUIRE( values[idx] == count ); count++; } } ////////////////////////////////////////////////////////////////////////// //[> Column wise application <] //[> 1. Create the sketching matrix <] Dummy_t<Matrix_t, Matrix_t> Sparse(n, n_s, context); std::vector<size_t> row_idx = Sparse.getRowIdx(); std::vector<double> row_val = Sparse.getRowValues(); // PI generated by random number gen int sketch_size = row_val.size(); typename Matrix_t::coords_t coords; for(int i = 0; i < sketch_size; ++i) { typename Matrix_t::coord_tuple_t new_entry(row_idx[i], i, row_val[i]); coords.push_back(new_entry); } Matrix_t pi_sketch; pi_sketch.set(coords); //[> 2. Create sketched matrix <] Matrix_t sketch_A; //[> 3. Apply the transform <] Sparse.apply(A, sketch_A, skylark::sketch::columnwise_tag()); BOOST_CHECK(sketch_A.height() == n_s); BOOST_CHECK(sketch_A.width() == m); //[> 4. Build structure to compare: PI * A ?= sketch_A <] typename Matrix_t::coords_t coords_new; indptr = pi_sketch.indptr(); indices = pi_sketch.indices(); values = pi_sketch.locked_values(); // multiply with vector where an entry has the value: // col_idx * n + row_idx + 1. // See creation of A. for(int col = 0; col < pi_sketch.width(); col++) { for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { for(int ccol = 0; ccol < m; ++ccol) { typename Matrix_t::coord_tuple_t new_entry(indices[idx], ccol, values[idx] * (ccol * n + col + 1)); coords_new.push_back(new_entry); } } } Matrix_t expected_A; expected_A.set(coords_new, n_s, m); if (!static_cast<bool>(expected_A == sketch_A)) BOOST_FAIL("Result of colwise application not as expected"); ////////////////////////////////////////////////////////////////////////// //[> Row wise application <] //[> 1. Create the sketching matrix <] Dummy_t<Matrix_t, Matrix_t> Sparse_row(m, m_s, context); row_idx = Sparse_row.getRowIdx(); row_val = Sparse_row.getRowValues(); // PI generated by random number gen sketch_size = row_val.size(); coords.clear(); for(int i = 0; i < sketch_size; ++i) { typename Matrix_t::coord_tuple_t new_entry(i, row_idx[i], row_val[i]); coords.push_back(new_entry); } Matrix_t pi_sketch_row; pi_sketch_row.set(coords); //[> 2. Create sketched matrix <] Matrix_t sketch_A_row; //[> 3. Apply the transform <] Sparse_row.apply(A, sketch_A_row, skylark::sketch::rowwise_tag()); BOOST_CHECK(sketch_A_row.height() == n); BOOST_CHECK(sketch_A_row.width() == m_s); //[> 4. Build structure to compare: A * PI ?= sketch_A <] coords_new.clear(); indptr = pi_sketch_row.indptr(); indices = pi_sketch_row.indices(); values = pi_sketch_row.locked_values(); // multiply with vector where an entry has the value: // col_idx * n + row_idx + 1. // See creation of A. for(int col = 0; col < pi_sketch_row.width(); col++) { for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { for(int row = 0; row < n; ++row) { typename Matrix_t::coord_tuple_t new_entry(row, col, values[idx] * (indices[idx] * n + row + 1)); coords_new.push_back(new_entry); } } } Matrix_t expected_A_row; expected_A_row.set(coords_new, n, m_s); if (!static_cast<bool>(expected_A_row == sketch_A_row)) BOOST_FAIL("Result of rowwise application not as expected"); return 0; }
int test_main(int argc, char *argv[]) { ////////////////////////////////////////////////////////////////////////// //[> Parameters <] //FIXME: use random sizes? const size_t n = 100; const size_t m = 50; const size_t n_s = 60; const size_t m_s = 30; ////////////////////////////////////////////////////////////////////////// //[> Setup test <] namespace mpi = boost::mpi; El::Initialize(argc, argv); mpi::environment env(argc, argv); mpi::communicator world; MPI_Comm mpi_world(world); El::Grid grid(mpi_world); const size_t rank = world.rank(); skylark::base::context_t context (0); double count = 1.0; const size_t matrix_full = n * m; mpi_vector_t colsf(matrix_full); mpi_vector_t rowsf(matrix_full); mpi_vector_t valsf(matrix_full); for(size_t i = 0; i < matrix_full; ++i) { colsf.SetElement(i, i % m); rowsf.SetElement(i, i / m); valsf.SetElement(i, count); count++; } DistMatrixType A(n, m, rowsf, colsf, valsf); mpi_vector_t zero; count = 1.0; El::Matrix<double> local_A(n, m); for( size_t j = 0; j < local_A.Height(); j++ ) for( size_t i = 0; i < local_A.Width(); i++ ) local_A.Set(j, i, count++); El::DistMatrix<double, El::STAR, El::STAR> result(grid); // columnwise application DistMatrixType expected_A; DistMatrixType pi_sketch(n_s, n, zero, zero, zero); // rowwise application DistMatrixType expected_AR; DistMatrixType pi_sketch_r(m_s, m, zero, zero, zero); ////////////////////////////////////////////////////////////////////////// //[> Column wise application DistSparseMatrix -> DistMatrix[MC/MR] <] typedef El::DistMatrix<double> mcmr_target_t; //[> 1. Create the sketching matrix <] Dummy_t<DistMatrixType, mcmr_target_t> Sparse(n, n_s, context); //[> 2. Create space for the sketched matrix <] mcmr_target_t sketch_A(n_s, m, grid); El::Zero(sketch_A); //[> 3. Apply the transform <] Sparse.apply(A, sketch_A, skylark::sketch::columnwise_tag()); //[> 4. Build structure to compare <] // easier to check if all processors own result result = sketch_A; compute_sketch_matrix(Sparse, A, pi_sketch); expected_A = Mult_AnXBn_Synch<PTDD, double, col_t>( pi_sketch, A, false, false); compare_result(rank, expected_A, result); ////////////////////////////////////////////////////////////////////////// //[> Column wise application DistSparseMatrix -> DistMatrix[VC/*] <] typedef El::DistMatrix<double, El::VC, El::STAR> vcs_target_t; //[> 1. Create the sketching matrix <] Dummy_t<DistMatrixType, vcs_target_t> SparseVC(n, n_s, context); //[> 2. Create space for the sketched matrix <] vcs_target_t sketch_A_vcs(n_s, m, grid); El::Zero(sketch_A_vcs); //[> 3. Apply the transform <] SparseVC.apply(A, sketch_A_vcs, skylark::sketch::columnwise_tag()); //[> 4. Build structure to compare <] // easier to check if all processors own result result = sketch_A_vcs; compute_sketch_matrix(SparseVC, A, pi_sketch); expected_A = Mult_AnXBn_Synch<PTDD, double, col_t>( pi_sketch, A, false, false); compare_result(rank, expected_A, result); ////////////////////////////////////////////////////////////////////////// //[> Column wise application DistSparseMatrix -> DistMatrix[*/VR] <] typedef El::DistMatrix<double, El::STAR, El::VR> svr_target_t; //[> 1. Create the sketching matrix <] Dummy_t<DistMatrixType, svr_target_t> SparseVR(n, n_s, context); //[> 2. Create space for the sketched matrix <] svr_target_t sketch_A_svr(n_s, m, grid); El::Zero(sketch_A_svr); //[> 3. Apply the transform <] SparseVR.apply(A, sketch_A_svr, skylark::sketch::columnwise_tag()); //[> 4. Build structure to compare <] // easier to check if all processors own result result = sketch_A_svr; compute_sketch_matrix(SparseVR, A, pi_sketch); expected_A = Mult_AnXBn_Synch<PTDD, double, col_t>( pi_sketch, A, false, false); compare_result(rank, expected_A, result); ////////////////////////////////////////////////////////////////////////// //[> Column wise application DistSparseMatrix -> DistMatrix[*/*] <] typedef El::DistMatrix<double, El::STAR, El::STAR> st_target_t; //[> 1. Create the sketching matrix <] Dummy_t<DistMatrixType, st_target_t> SparseST(n, n_s, context); //[> 2. Create space for the sketched matrix <] st_target_t sketch_A_st(n_s, m, grid); El::Zero(sketch_A_st); //[> 3. Apply the transform <] SparseST.apply(A, sketch_A_st, skylark::sketch::columnwise_tag()); //[> 4. Compare <] compute_sketch_matrix(SparseST, A, pi_sketch); expected_A = Mult_AnXBn_Synch<PTDD, double, col_t>( pi_sketch, A, false, false); compare_result(rank, expected_A, sketch_A_st); ////////////////////////////////////////////////////////////////////////// //[> Column wise application DistSparseMatrix -> LocalDenseMatrix <] Dummy_t<DistMatrixType, El::Matrix<double>> LocalSparse(n, n_s, context); El::Matrix<double> local_sketch_A(n_s, m); El::Zero(local_sketch_A); LocalSparse.apply(A, local_sketch_A, skylark::sketch::columnwise_tag()); El::Matrix<double> pi_sketch_l(n_s, n); El::Zero(pi_sketch_l); El::Matrix<double> expected_A_l(n_s, m); El::Zero(expected_A_l); if(rank == 0) { // PI generated by random number gen std::vector<size_t> row_idx = LocalSparse.getRowIdx(); std::vector<double> row_val = LocalSparse.getRowValues(); int sketch_size = row_val.size(); typename LocalMatrixType::coords_t coords; for(int i = 0; i < sketch_size; ++i) pi_sketch_l.Set(row_idx[i], i, row_val[i]); El::Gemm(El::NORMAL, El::NORMAL, 1.0, pi_sketch_l, local_A, 0.0, expected_A_l); for(int col = 0; col < expected_A_l.Width(); col++) { for(int row = 0; row < expected_A_l.Height(); row++) { if(local_sketch_A.Get(row, col) != expected_A_l.Get(row, col)) BOOST_FAIL("Result of local colwise application not as expected"); } } } ////////////////////////////////////////////////////////////////////////// //[> Row wise application DistSparseMatrix -> DistMatrix[MC/MR] <] //[> 1. Create the sketching matrix <] Dummy_t<DistMatrixType, mcmr_target_t> Sparse_r(m, m_s, context); //[> 2. Create space for the sketched matrix <] mcmr_target_t sketch_A_r(n, m_s, grid); El::Zero(sketch_A_r); //[> 3. Apply the transform <] Sparse_r.apply(A, sketch_A_r, skylark::sketch::rowwise_tag()); //[> 4. Build structure to compare <] // easier to check if all processors own result result = sketch_A_r; compute_sketch_matrix(Sparse_r, A, pi_sketch_r); pi_sketch_r.Transpose(); expected_AR = Mult_AnXBn_Synch<PTDD, double, col_t>( A, pi_sketch_r, false, false); compare_result(rank, expected_AR, result); ////////////////////////////////////////////////////////////////////////// //[> Row wise application DistSparseMatrix -> DistMatrix[VC/*] <] //[> 1. Create the sketching matrix <] Dummy_t<DistMatrixType, vcs_target_t> Sparse_r_vcs(m, m_s, context); //[> 2. Create space for the sketched matrix <] vcs_target_t sketch_A_r_vcs(n, m_s, grid); El::Zero(sketch_A_r_vcs); //[> 3. Apply the transform <] Sparse_r_vcs.apply(A, sketch_A_r_vcs, skylark::sketch::rowwise_tag()); //[> 4. Build structure to compare <] // easier to check if all processors own result result = sketch_A_r_vcs; pi_sketch_r.Transpose(); compute_sketch_matrix(Sparse_r_vcs, A, pi_sketch_r); pi_sketch_r.Transpose(); expected_AR = Mult_AnXBn_Synch<PTDD, double, col_t>( A, pi_sketch_r, false, false); compare_result(rank, expected_AR, result); ////////////////////////////////////////////////////////////////////////// //[> Row wise application DistSparseMatrix -> LocalDenseMatrix <] Dummy_t<DistMatrixType, El::Matrix<double>> LocalSparse_r(m, m_s, context); El::Matrix<double> local_sketch_A_r(n, m_s); El::Zero(local_sketch_A_r); LocalSparse_r.apply(A, local_sketch_A_r, skylark::sketch::rowwise_tag()); El::Matrix<double> local_pi_sketch_r(m_s, m); El::Zero(local_pi_sketch_r); El::Matrix<double> expected_A_r(n, m_s); El::Zero(expected_A_r); if(rank == 0) { // PI generated by random number gen std::vector<size_t> row_idx = LocalSparse_r.getRowIdx(); std::vector<double> row_val = LocalSparse_r.getRowValues(); int sketch_size = row_val.size(); typename LocalMatrixType::coords_t coords; for(int i = 0; i < sketch_size; ++i) local_pi_sketch_r.Set(row_idx[i], i, row_val[i]); El::Gemm(El::NORMAL, El::TRANSPOSE, 1.0, local_A, local_pi_sketch_r, 0.0, expected_A_r); for(int col = 0; col < expected_A_r.Width(); col++) { for(int row = 0; row < expected_A_r.Height(); row++) { if(local_sketch_A_r.Get(row, col) != expected_A_r.Get(row, col)) BOOST_FAIL("Result of local rowwise application not as expected"); } } } return 0; }
int test_main(int argc, char *argv[]) { ////////////////////////////////////////////////////////////////////////// //[> Parameters <] const size_t n = 10; const size_t m = 5; const size_t n_s = 6; const size_t m_s = 3; const int seed = static_cast<int>(rand() * 100); typedef FullyDistVec<size_t, double> mpi_vector_t; typedef SpDCCols<size_t, double> col_t; typedef SpParMat<size_t, double, col_t> DistMatrixType; namespace mpi = boost::mpi; mpi::environment env(argc, argv); mpi::communicator world; const size_t rank = world.rank(); skylark::base::context_t context (seed); double count = 1.0; const size_t matrix_full = n * m; mpi_vector_t colsf(matrix_full); mpi_vector_t rowsf(matrix_full); mpi_vector_t valsf(matrix_full); for(size_t i = 0; i < matrix_full; ++i) { colsf.SetElement(i, i % m); rowsf.SetElement(i, i / m); valsf.SetElement(i, count); count++; } DistMatrixType A(n, m, rowsf, colsf, valsf); ////////////////////////////////////////////////////////////////////////// //[> Setup test <] //[> 1. Create the sketching matrix and dump JSON <] skylark::sketch::CWT_t<DistMatrixType, DistMatrixType> Sparse(n, n_s, context); // dump to property tree boost::property_tree::ptree pt = Sparse.get_data()->to_ptree(); //[> 2. Dump the JSON string to file <] std::ofstream out("sketch.json"); write_json(out, pt); out.close(); //[> 3. Create a sketch from the JSON file. <] std::ifstream file; std::stringstream json; file.open("sketch.json", std::ios::in); boost::property_tree::ptree json_tree; boost::property_tree::read_json(file, json_tree); skylark::sketch::CWT_t<DistMatrixType, DistMatrixType> tmp(json_tree); //[> 4. Both sketches should compute the same result. <] mpi_vector_t zero; DistMatrixType sketch_A(n_s, m, zero, zero, zero); DistMatrixType sketch_Atmp(n_s, m, zero, zero, zero); Sparse.apply(A, sketch_A, skylark::sketch::columnwise_tag()); tmp.apply(A, sketch_Atmp, skylark::sketch::columnwise_tag()); if (!static_cast<bool>(sketch_A == sketch_Atmp)) BOOST_FAIL("Applied sketch did not result in same result"); return 0; }