Skylark (Sketching Library)
0.1
|
00001 00013 #include <vector> 00014 00015 #include <boost/mpi.hpp> 00016 #include <boost/test/minimal.hpp> 00017 00018 #include "../../utility/distributions.hpp" 00019 #include "../../base/sparse_matrix.hpp" 00020 #include "../../sketch/sketch.hpp" 00021 00022 00023 template < typename InputMatrixType, 00024 typename OutputMatrixType = InputMatrixType > 00025 struct Dummy_t : public skylark::sketch::hash_transform_t< 00026 InputMatrixType, OutputMatrixType, 00027 boost::random::uniform_int_distribution, 00028 skylark::utility::rademacher_distribution_t > { 00029 00030 typedef skylark::sketch::hash_transform_t< 00031 InputMatrixType, OutputMatrixType, 00032 boost::random::uniform_int_distribution, 00033 skylark::utility::rademacher_distribution_t > 00034 hash_t; 00035 00036 Dummy_t(int N, int S, skylark::base::context_t& context) 00037 : skylark::sketch::hash_transform_t<InputMatrixType, OutputMatrixType, 00038 boost::random::uniform_int_distribution, 00039 skylark::utility::rademacher_distribution_t>(N, S, context) 00040 {} 00041 00042 std::vector<size_t> getRowIdx() { return hash_t::row_idx; } 00043 std::vector<double> getRowValues() { return hash_t::row_value; } 00044 }; 00045 00046 int test_main(int argc, char *argv[]) { 00047 00049 //[> Parameters <] 00050 00051 //FIXME: use random sizes? 00052 const size_t n = 10; 00053 const size_t m = 5; 00054 const size_t n_s = 6; 00055 const size_t m_s = 3; 00056 00057 typedef skylark::base::sparse_matrix_t<double> Matrix_t; 00058 00060 //[> Setup test <] 00061 00062 namespace mpi = boost::mpi; 00063 mpi::environment env(argc, argv); 00064 mpi::communicator world; 00065 const size_t rank = world.rank(); 00066 00067 skylark::base::context_t context (0); 00068 00069 double count = 1.0; 00070 00071 const int matrix_full = n * m; 00072 std::vector<int> colsf(m + 1); 00073 std::vector<int> rowsf(matrix_full); 00074 std::vector<double> valsf(matrix_full); 00075 00076 for(size_t i = 0; i < m + 1; ++i) 00077 colsf[i] = i * n; 00078 00079 for(size_t i = 0; i < matrix_full; ++i) { 00080 rowsf[i] = i % n; 00081 valsf[i] = count; 00082 count++; 00083 } 00084 00085 Matrix_t A; 00086 A.attach(&colsf[0], &rowsf[0], &valsf[0], matrix_full, n, m, false); 00087 00088 count = 1; 00089 const int* indptr = A.indptr(); 00090 const int* indices = A.indices(); 00091 const double* values = A.locked_values(); 00092 00093 for(int col = 0; col < A.width(); col++) { 00094 for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { 00095 BOOST_REQUIRE( values[idx] == count ); 00096 count++; 00097 } 00098 } 00099 00101 //[> Test COO to CSC <] 00102 typename Matrix_t::coords_t coords_mat; 00103 count = 1; 00104 for(int col = 0; col < A.width(); col++) { 00105 for(int row = 0; row < A.height(); row++) { 00106 typename Matrix_t::coord_tuple_t new_entry(row, col, count); 00107 coords_mat.push_back(new_entry); 00108 count++; 00109 } 00110 } 00111 00112 Matrix_t A_coord; 00113 A_coord.set(coords_mat); 00114 00115 count = 1; 00116 indptr = A_coord.indptr(); 00117 indices = A_coord.indices(); 00118 values = A_coord.locked_values(); 00119 00120 for(int col = 0; col < A_coord.width(); col++) { 00121 for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { 00122 BOOST_REQUIRE( values[idx] == count ); 00123 count++; 00124 } 00125 } 00126 00128 //[> Column wise application <] 00129 00130 //[> 1. Create the sketching matrix <] 00131 Dummy_t<Matrix_t, Matrix_t> Sparse(n, n_s, context); 00132 std::vector<size_t> row_idx = Sparse.getRowIdx(); 00133 std::vector<double> row_val = Sparse.getRowValues(); 00134 00135 // PI generated by random number gen 00136 int sketch_size = row_val.size(); 00137 typename Matrix_t::coords_t coords; 00138 for(int i = 0; i < sketch_size; ++i) { 00139 typename Matrix_t::coord_tuple_t new_entry(row_idx[i], i, row_val[i]); 00140 coords.push_back(new_entry); 00141 } 00142 00143 Matrix_t pi_sketch; 00144 pi_sketch.set(coords); 00145 00146 //[> 2. Create sketched matrix <] 00147 Matrix_t sketch_A; 00148 00149 //[> 3. Apply the transform <] 00150 Sparse.apply(A, sketch_A, skylark::sketch::columnwise_tag()); 00151 00152 BOOST_CHECK(sketch_A.height() == n_s); 00153 BOOST_CHECK(sketch_A.width() == m); 00154 00155 //[> 4. Build structure to compare: PI * A ?= sketch_A <] 00156 typename Matrix_t::coords_t coords_new; 00157 indptr = pi_sketch.indptr(); 00158 indices = pi_sketch.indices(); 00159 values = pi_sketch.locked_values(); 00160 00161 // multiply with vector where an entry has the value: 00162 // col_idx * n + row_idx + 1. 00163 // See creation of A. 00164 for(int col = 0; col < pi_sketch.width(); col++) { 00165 for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { 00166 for(int ccol = 0; ccol < m; ++ccol) { 00167 typename Matrix_t::coord_tuple_t new_entry(indices[idx], ccol, 00168 values[idx] * (ccol * n + col + 1)); 00169 coords_new.push_back(new_entry); 00170 } 00171 } 00172 } 00173 00174 Matrix_t expected_A; 00175 expected_A.set(coords_new, n_s, m); 00176 00177 if (!static_cast<bool>(expected_A == sketch_A)) 00178 BOOST_FAIL("Result of colwise application not as expected"); 00179 00180 00182 //[> Row wise application <] 00183 00184 //[> 1. Create the sketching matrix <] 00185 Dummy_t<Matrix_t, Matrix_t> Sparse_row(m, m_s, context); 00186 row_idx = Sparse_row.getRowIdx(); 00187 row_val = Sparse_row.getRowValues(); 00188 00189 // PI generated by random number gen 00190 sketch_size = row_val.size(); 00191 coords.clear(); 00192 for(int i = 0; i < sketch_size; ++i) { 00193 typename Matrix_t::coord_tuple_t new_entry(i, row_idx[i], row_val[i]); 00194 coords.push_back(new_entry); 00195 } 00196 00197 Matrix_t pi_sketch_row; 00198 pi_sketch_row.set(coords); 00199 00200 //[> 2. Create sketched matrix <] 00201 Matrix_t sketch_A_row; 00202 00203 //[> 3. Apply the transform <] 00204 Sparse_row.apply(A, sketch_A_row, skylark::sketch::rowwise_tag()); 00205 00206 BOOST_CHECK(sketch_A_row.height() == n); 00207 BOOST_CHECK(sketch_A_row.width() == m_s); 00208 00209 //[> 4. Build structure to compare: A * PI ?= sketch_A <] 00210 coords_new.clear(); 00211 indptr = pi_sketch_row.indptr(); 00212 indices = pi_sketch_row.indices(); 00213 values = pi_sketch_row.locked_values(); 00214 00215 // multiply with vector where an entry has the value: 00216 // col_idx * n + row_idx + 1. 00217 // See creation of A. 00218 for(int col = 0; col < pi_sketch_row.width(); col++) { 00219 for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { 00220 for(int row = 0; row < n; ++row) { 00221 typename Matrix_t::coord_tuple_t new_entry(row, col, 00222 values[idx] * (indices[idx] * n + row + 1)); 00223 coords_new.push_back(new_entry); 00224 } 00225 } 00226 } 00227 00228 Matrix_t expected_A_row; 00229 expected_A_row.set(coords_new, n, m_s); 00230 00231 if (!static_cast<bool>(expected_A_row == sketch_A_row)) 00232 BOOST_FAIL("Result of rowwise application not as expected"); 00233 00234 return 0; 00235 }