Skylark (Sketching Library)
0.1
|
00001 #ifndef SKYLARK_RFUT_ELEMENTAL_HPP 00002 #define SKYLARK_RFUT_ELEMENTAL_HPP 00003 00004 #include <boost/mpi.hpp> 00005 #include "../utility/randgen.hpp" 00006 00007 namespace skylark { namespace sketch { 00008 00012 template < typename ValueType, 00013 typename FUT, 00014 elem::Distribution RowDist, 00015 typename ValueDistributionType> 00016 struct RFUT_t< 00017 elem::DistMatrix<ValueType, elem::STAR, RowDist>, 00018 FUT, 00019 ValueDistributionType> : 00020 public RFUT_data_t<ValueDistributionType> { 00021 // Typedef value, matrix, distribution and transform data types 00022 // so that we can use them regularly and consistently. 00023 typedef ValueType value_type; 00024 typedef elem::Matrix<ValueType> local_type; 00025 typedef elem::DistMatrix<ValueType, elem::STAR, RowDist> matrix_type; 00026 typedef elem::DistMatrix<ValueType, 00027 elem::STAR, RowDist> output_matrix_type; 00028 typedef ValueDistributionType value_distribution_type; 00029 typedef RFUT_data_t<ValueDistributionType> data_type; 00030 00034 RFUT_t(int N, base::context_t& context) 00035 : data_type (N, context) { 00036 00037 } 00038 00042 RFUT_t (RFUT_t<matrix_type, 00043 FUT, 00044 value_distribution_type>& other) : 00045 data_type(other) {} 00046 00050 RFUT_t(const data_type& other_data) : 00051 data_type(other_data) {} 00052 00057 template <typename Dimension> 00058 void apply (const matrix_type& A, 00059 output_matrix_type& mixed_A, 00060 Dimension dimension) const { 00061 switch (RowDist) { 00062 case elem::VC: 00063 case elem::VR: 00064 try { 00065 apply_impl_vdist(A, mixed_A, dimension); 00066 } catch (std::logic_error e) { 00067 SKYLARK_THROW_EXCEPTION ( 00068 base::elemental_exception() 00069 << base::error_msg(e.what()) ); 00070 } catch(boost::mpi::exception e) { 00071 SKYLARK_THROW_EXCEPTION ( 00072 base::mpi_exception() 00073 << base::error_msg(e.what()) ); 00074 } 00075 break; 00076 00077 default: 00078 SKYLARK_THROW_EXCEPTION ( 00079 base::unsupported_matrix_distribution() ); 00080 } 00081 } 00082 00083 private: 00088 void apply_impl_vdist (const matrix_type& A, 00089 output_matrix_type& mixed_A, 00090 skylark::sketch::columnwise_tag) const { 00091 // TODO verify that A has the correct size 00092 00093 // TODO no need to create FUT everytime... 00094 FUT T(data_type::_N); 00095 00096 // Scale 00097 const local_type& local_A = A.LockedMatrix(); 00098 local_type& local_TA = mixed_A.Matrix(); 00099 value_type scale = T.scale(); 00100 for (int j = 0; j < local_A.Width(); j++) 00101 for (int i = 0; i < data_type::_N; i++) 00102 local_TA.Set(i, j, 00103 scale * data_type::D[i] * local_A.Get(i, j)); 00104 00105 // Apply underlying transform 00106 T.apply(local_TA, skylark::sketch::columnwise_tag()); 00107 } 00108 00109 00110 }; 00111 00115 template < typename ValueType, 00116 typename FUT, 00117 elem::Distribution RowDist, 00118 typename ValueDistributionType> 00119 struct RFUT_t< 00120 elem::DistMatrix<ValueType, RowDist, elem::STAR>, 00121 FUT, 00122 ValueDistributionType> : 00123 public RFUT_data_t<ValueDistributionType> { 00124 // Typedef value, matrix, distribution and transform data types 00125 // so that we can use them regularly and consistently. 00126 typedef ValueType value_type; 00127 typedef elem::Matrix<ValueType> local_type; 00128 typedef elem::DistMatrix<ValueType, RowDist, elem::STAR> matrix_type; 00129 typedef elem::DistMatrix<ValueType, RowDist, elem::STAR> output_matrix_type; 00130 typedef elem::DistMatrix<ValueType, elem::STAR, RowDist> intermediate_type; 00132 typedef ValueDistributionType value_distribution_type; 00133 typedef RFUT_data_t<ValueDistributionType> data_type; 00134 00138 RFUT_t(int N, base::context_t& context) 00139 : data_type (N, context) { 00140 00141 } 00142 00146 RFUT_t (RFUT_t<matrix_type, 00147 FUT, 00148 value_distribution_type>& other) : 00149 data_type(other) {} 00150 00154 RFUT_t(const data_type& other_data) : 00155 data_type(other_data) {} 00156 00160 template <typename Dimension> 00161 void apply(const matrix_type& A, 00162 output_matrix_type& mixed_A, 00163 Dimension dimension) const { 00164 00165 switch (RowDist) { 00166 case elem::VC: 00167 case elem::VR: 00168 try { 00169 apply_impl_vdist(A, mixed_A, dimension); 00170 } catch (std::logic_error e) { 00171 SKYLARK_THROW_EXCEPTION ( 00172 base::elemental_exception() 00173 << base::error_msg(e.what()) ); 00174 } catch(boost::mpi::exception e) { 00175 SKYLARK_THROW_EXCEPTION ( 00176 base::mpi_exception() 00177 << base::error_msg(e.what()) ); 00178 } 00179 00180 break; 00181 00182 default: 00183 SKYLARK_THROW_EXCEPTION ( 00184 base::unsupported_matrix_distribution() ); 00185 00186 } 00187 } 00188 00189 template <typename Dimension> 00190 void apply_inverse(const matrix_type& A, 00191 output_matrix_type& mixed_A, 00192 Dimension dimension) const { 00193 00194 switch (RowDist) { 00195 case elem::VC: 00196 case elem::VR: 00197 try { 00198 apply_inverse_impl_vdist(A, mixed_A, dimension); 00199 } catch (std::logic_error e) { 00200 SKYLARK_THROW_EXCEPTION ( 00201 base::elemental_exception() 00202 << base::error_msg(e.what()) ); 00203 } catch(boost::mpi::exception e) { 00204 SKYLARK_THROW_EXCEPTION ( 00205 base::mpi_exception() 00206 << base::error_msg(e.what()) ); 00207 } 00208 00209 break; 00210 00211 default: 00212 SKYLARK_THROW_EXCEPTION ( 00213 base::unsupported_matrix_distribution() ); 00214 00215 } 00216 } 00217 00218 00219 private: 00224 void apply_impl_vdist (const matrix_type& A, 00225 output_matrix_type& mixed_A, 00226 skylark::sketch::rowwise_tag) const { 00227 // TODO verify that A has the correct size 00228 00229 FUT T(data_type::_N); 00230 00231 // Scale 00232 const local_type& local_A = A.LockedMatrix(); 00233 local_type& local_TA = mixed_A.Matrix(); 00234 value_type scale = T.scale(local_A); 00235 for (int j = 0; j < data_type::_N; j++) 00236 for (int i = 0; i < local_A.Height(); i++) 00237 local_TA.Set(i, j, 00238 scale * data_type::D[j] * local_A.Get(i, j)); 00239 00240 // Apply underlying transform 00241 T.apply(local_TA, skylark::sketch::rowwise_tag()); 00242 } 00243 00248 void apply_impl_vdist (const matrix_type& A, 00249 output_matrix_type& mixed_A, 00250 skylark::sketch::columnwise_tag) const { 00251 // TODO verify that A has the correct size 00252 // TODO A and mixed_A have to match 00253 00254 FUT T(data_type::_N); 00255 00256 // Rearrange matrix 00257 intermediate_type inter_A(A.Grid()); 00258 inter_A = A; 00259 00260 // Scale 00261 local_type& local_A = inter_A.Matrix(); 00262 value_type scale = T.scale(local_A); 00263 for (int j = 0; j < local_A.Width(); j++) 00264 for (int i = 0; i < data_type::_N; i++) 00265 local_A.Set(i, j, 00266 scale * data_type::D[i] * local_A.Get(i, j)); 00267 00268 // Apply underlying transform 00269 T.apply(local_A, skylark::sketch::columnwise_tag()); 00270 00271 // Rearrange back 00272 mixed_A = inter_A; 00273 } 00274 00279 void apply_inverse_impl_vdist (const matrix_type& A, 00280 output_matrix_type& mixed_A, 00281 skylark::sketch::columnwise_tag) const { 00282 00283 FUT T(data_type::_N); 00284 00285 // TODO verify that A has the correct size 00286 // TODO A and mixed_A have to match 00287 00288 // Rearrange matrix 00289 intermediate_type inter_A(A.Grid()); 00290 inter_A = A; 00291 00292 // Apply underlying transform 00293 local_type& local_A = inter_A.Matrix(); 00294 T.apply_inverse(local_A, skylark::sketch::columnwise_tag()); 00295 00296 // Scale 00297 value_type scale = T.scale(local_A); 00298 for (int j = 0; j < local_A.Width(); j++) 00299 for (int i = 0; i < data_type::_N; i++) 00300 local_A.Set(i, j, 00301 scale * data_type::D[i] * local_A.Get(i, j)); 00302 00303 // Rearrange back 00304 mixed_A = inter_A; 00305 } 00306 00307 }; 00308 00309 } } 00311 #endif // SKYLARK_RFUT_HPP