Skylark (Sketching Library)
0.1
|
00001 00013 #include <vector> 00014 00015 #include <boost/mpi.hpp> 00016 #include <boost/test/minimal.hpp> 00017 00018 //FIXME: ugly 00019 #define SKYLARK_SKETCH_HPP 1 00020 00021 #include "../../base/context.hpp" 00022 #include "../../utility/distributions.hpp" 00023 #include "../../sketch/hash_transform.hpp" 00024 00025 #include "../../base/sparse_matrix.hpp" 00026 00027 typedef FullyDistVec<size_t, double> mpi_vector_t; 00028 typedef SpDCCols<size_t, double> col_t; 00029 typedef SpParMat<size_t, double, col_t> DistMatrixType; 00030 typedef PlusTimesSRing<double, double> PTDD; 00031 typedef skylark::base::sparse_matrix_t<double> LocalMatrixType; 00032 00033 00034 template < typename InputMatrixType, 00035 typename OutputMatrixType = InputMatrixType > 00036 struct Dummy_t : public skylark::sketch::hash_transform_t< 00037 InputMatrixType, OutputMatrixType, 00038 boost::random::uniform_int_distribution, 00039 skylark::utility::rademacher_distribution_t > { 00040 00041 typedef skylark::sketch::hash_transform_t< 00042 InputMatrixType, OutputMatrixType, 00043 boost::random::uniform_int_distribution, 00044 skylark::utility::rademacher_distribution_t > 00045 hash_t; 00046 00047 Dummy_t(int N, int S, skylark::base::context_t& context) 00048 : skylark::sketch::hash_transform_t<InputMatrixType, OutputMatrixType, 00049 boost::random::uniform_int_distribution, 00050 skylark::utility::rademacher_distribution_t>(N, S, context) 00051 {} 00052 00053 std::vector<size_t> getRowIdx() { return hash_t::row_idx; } 00054 std::vector<double> getRowValues() { return hash_t::row_value; } 00055 }; 00056 00057 00058 template<typename sketch_t> 00059 void compute_sketch_matrix(sketch_t sketch, const DistMatrixType &A, 00060 DistMatrixType &result) { 00061 00062 std::vector<size_t> row_idx = sketch.getRowIdx(); 00063 std::vector<double> row_val = sketch.getRowValues(); 00064 00065 // PI generated by random number gen 00066 size_t sketch_size = row_val.size(); 00067 mpi_vector_t cols(sketch_size); 00068 mpi_vector_t rows(sketch_size); 00069 mpi_vector_t vals(sketch_size); 00070 00071 for(size_t i = 0; i < sketch_size; ++i) { 00072 cols.SetElement(i, i); 00073 rows.SetElement(i, row_idx[i]); 00074 vals.SetElement(i, row_val[i]); 00075 } 00076 00077 result = DistMatrixType(result.getnrow(), result.getncol(), 00078 rows, cols, vals); 00079 } 00080 00081 00082 int test_main(int argc, char *argv[]) { 00083 00085 //[> Parameters <] 00086 00087 //FIXME: use random sizes? 00088 const size_t n = 200; 00089 const size_t m = 100; 00090 const size_t n_s = 120; 00091 const size_t m_s = 60; 00092 00094 //[> Setup test <] 00095 namespace mpi = boost::mpi; 00096 mpi::environment env(argc, argv); 00097 mpi::communicator world; 00098 const size_t rank = world.rank(); 00099 00100 skylark::base::context_t context (0); 00101 00102 double count = 1.0; 00103 00104 const size_t matrix_full = n * m; 00105 mpi_vector_t colsf(matrix_full); 00106 mpi_vector_t rowsf(matrix_full); 00107 mpi_vector_t valsf(matrix_full); 00108 00109 for(size_t i = 0; i < matrix_full; ++i) { 00110 colsf.SetElement(i, i % m); 00111 rowsf.SetElement(i, i / m); 00112 valsf.SetElement(i, count); 00113 count++; 00114 } 00115 00116 DistMatrixType A(n, m, rowsf, colsf, valsf); 00117 00118 00120 //[> Column wise application DistSparseMatrix -> DistSparseMatrix <] 00121 00122 //[> 1. Create the sketching matrix <] 00123 Dummy_t<DistMatrixType, DistMatrixType> Sparse(n, n_s, context); 00124 00125 //[> 2. Create space for the sketched matrix <] 00126 mpi_vector_t zero; 00127 DistMatrixType sketch_A(n_s, m, zero, zero, zero); 00128 00129 //[> 3. Apply the transform <] 00130 Sparse.apply(A, sketch_A, skylark::sketch::columnwise_tag()); 00131 00132 //[> 4. Build structure to compare <] 00133 DistMatrixType pi_sketch(n_s, n, zero, zero, zero); 00134 compute_sketch_matrix(Sparse, A, pi_sketch); 00135 DistMatrixType expected_A = Mult_AnXBn_Synch<PTDD, double, col_t>(pi_sketch, A, false, false); 00136 if (!static_cast<bool>(expected_A == sketch_A)) 00137 BOOST_FAIL("Result of colwise (dist -> dist) application not as expected"); 00138 00140 //[> Column wise application DistSparseMatrix -> LocalSparseMatrix <] 00141 00142 Dummy_t<DistMatrixType, LocalMatrixType> LocalSparse(n, n_s, context); 00143 LocalMatrixType local_sketch_A; 00144 LocalSparse.apply(A, local_sketch_A, skylark::sketch::columnwise_tag()); 00145 00146 if(rank == 0) { 00147 std::vector<size_t> row_idx = LocalSparse.getRowIdx(); 00148 std::vector<double> row_val = LocalSparse.getRowValues(); 00149 00150 // PI generated by random number gen 00151 int sketch_size = row_val.size(); 00152 typename LocalMatrixType::coords_t coords; 00153 for(int i = 0; i < sketch_size; ++i) { 00154 typename LocalMatrixType::coord_tuple_t new_entry(row_idx[i], i, row_val[i]); 00155 coords.push_back(new_entry); 00156 } 00157 00158 LocalMatrixType pi_sketch_l; 00159 pi_sketch_l.set(coords); 00160 00161 typename LocalMatrixType::coords_t coords_new; 00162 const int* indptr = pi_sketch_l.indptr(); 00163 const int* indices = pi_sketch_l.indices(); 00164 const double* values = pi_sketch_l.locked_values(); 00165 00166 // multiply with vector where an entry has the value: 00167 // col_idx + row_idx * m + 1. 00168 // See creation of A. 00169 for(int col = 0; col < pi_sketch_l.width(); col++) { 00170 for(int idx = indptr[col]; idx < indptr[col + 1]; idx++) { 00171 for(int ccol = 0; ccol < m; ++ccol) { 00172 typename LocalMatrixType::coord_tuple_t new_entry(indices[idx], 00173 ccol, values[idx] * (ccol + col * m + 1)); 00174 coords_new.push_back(new_entry); 00175 } 00176 } 00177 } 00178 00179 LocalMatrixType expected_A_l; 00180 expected_A_l.set(coords_new, n_s, m); 00181 00182 if (!static_cast<bool>(expected_A_l == local_sketch_A)) 00183 BOOST_FAIL("Result of local colwise application not as expected"); 00184 } 00185 00186 00188 //[> Row wise application DistSparseMatrix -> DistSparseMatrix <] 00189 00190 //[> 1. Create the sketching matrix <] 00191 Dummy_t<DistMatrixType, DistMatrixType> Sparse_r(m, m_s, context); 00192 00193 //[> 2. Create space for the sketched matrix <] 00194 DistMatrixType sketch_A_r(n, m_s, zero, zero, zero); 00195 00196 //[> 3. Apply the transform <] 00197 Sparse_r.apply(A, sketch_A_r, skylark::sketch::rowwise_tag()); 00198 00199 //[> 4. Build structure to compare <] 00200 DistMatrixType pi_sketch_r(m_s, m, zero, zero, zero); 00201 compute_sketch_matrix(Sparse_r, A, pi_sketch_r); 00202 pi_sketch_r.Transpose(); 00203 DistMatrixType expected_AR = PSpGEMM<PTDD>(A, pi_sketch_r); 00204 00205 if (!static_cast<bool>(expected_AR == sketch_A_r)) 00206 BOOST_FAIL("Result of rowwise (dist -> dist) application not as expected"); 00207 00208 return 0; 00209 }