Skylark (Sketching Library)
0.1
|
00001 #ifndef SKYLARK_DENSE_TRANSFORM_DATA_HPP 00002 #define SKYLARK_DENSE_TRANSFORM_DATA_HPP 00003 00004 #ifndef SKYLARK_SKETCH_HPP 00005 #error "Include top-level sketch.hpp instead of including individuals headers" 00006 #endif 00007 00008 #include <vector> 00009 00010 #include "../utility/randgen.hpp" 00011 #include "boost/smart_ptr.hpp" 00012 00013 namespace skylark { namespace sketch { 00014 00015 //FIXME: WHY DO WE NEED TO ALLOW COPY CONSTRUCTOR HERE (or more precisely in 00016 // dense_transform_Elemental)? 00022 template <template <typename> class ValueDistribution> 00023 struct dense_transform_data_t : public sketch_transform_data_t { 00024 typedef sketch_transform_data_t base_t; 00025 00026 // Note: we always generate doubles for array values, 00027 // but when applying to floats the size can be reduced. 00028 typedef ValueDistribution<double> value_distribution_type; 00029 00030 typedef double value_type; 00031 00035 dense_transform_data_t (int N, int S, double scale, 00036 base::context_t& context) 00037 : base_t(N, S, context, "DenseTransform"), 00038 scale(scale), distribution() { 00039 00040 // No scaling in "raw" form 00041 context = build(); 00042 } 00043 00044 virtual 00045 boost::property_tree::ptree to_ptree() const { 00046 SKYLARK_THROW_EXCEPTION ( 00047 base::sketch_exception() 00048 << base::error_msg( 00049 "Do not yet support serialization of generic dense transform")); 00050 00051 return boost::property_tree::ptree(); 00052 } 00053 00054 dense_transform_data_t(const dense_transform_data_t& other) 00055 : base_t(other), scale(other.scale), distribution(other.distribution), 00056 random_samples(other.random_samples) { 00057 00058 } 00059 00060 00061 void realize_matrix_view(elem::Matrix<value_type>& A) const { 00062 realize_matrix_view(A, 0, 0, _S, _N); 00063 } 00064 00065 00066 void realize_matrix_view(elem::Matrix<value_type>& A, 00067 int i, int j, int height, int width) const { 00068 realize_matrix_view(A, i, j, height, width, 1, 1); 00069 } 00070 00071 00072 void realize_matrix_view(elem::Matrix<value_type>& A, 00073 int i, int j, int height, int width, 00074 int col_stride, int row_stride) const { 00075 00076 A.Resize(height, width); 00077 value_type *data = A.Buffer(); 00078 00079 #ifdef SKYLARK_HAVE_OPENMP 00080 #pragma omp parallel for 00081 #endif 00082 for(int j_loc = 0; j_loc < width; j_loc++) { 00083 int j_glob = j + j_loc * row_stride; 00084 for (int i_loc = 0; i_loc < height; i_loc++) { 00085 int i_glob = i + i_loc * col_stride; 00086 value_type sample = 00087 random_samples[j_glob * _S + i_glob]; 00088 data[j_loc * height + i_loc] = scale * sample; 00089 } 00090 } 00091 } 00092 00093 00094 template<elem::Distribution ColDist, 00095 elem::Distribution RowDist> 00096 void realize_matrix_view(elem::DistMatrix<value_type, 00097 ColDist, 00098 RowDist>& A) const { 00099 realize_matrix_view<ColDist, RowDist>(A, 0, 0, _S, _N); 00100 } 00101 00102 00103 template<elem::Distribution ColDist, 00104 elem::Distribution RowDist> 00105 void realize_matrix_view(elem::DistMatrix<value_type, ColDist, RowDist>& A, 00106 int i, int j, int height, int width) const { 00107 00108 elem::DistMatrix<value_type, ColDist, RowDist> parent; 00109 const elem::Grid& grid = parent.Grid(); 00110 00111 // for view (A) and parent matrices: stride, rank are the same 00112 const int col_stride = parent.ColStride(); 00113 const int row_stride = parent.RowStride(); 00114 const int col_rank = parent.ColRank(); 00115 const int row_rank = parent.RowRank(); 00116 00117 // for view (A) and parent matrices: alignment (and shift) are different 00118 const int parent_col_alignment = parent.ColAlign(); 00119 const int parent_row_alignment = parent.RowAlign(); 00120 00121 const int col_alignment = (parent_col_alignment + i) % col_stride; 00122 const int row_alignment = (parent_row_alignment + j) % row_stride; 00123 const int col_shift = 00124 elem::Shift(col_rank, col_alignment, col_stride); 00125 const int row_shift = 00126 elem::Shift(row_rank, row_alignment, row_stride); 00127 const int local_height = 00128 elem::Length(height, col_shift, col_stride); 00129 const int local_width = 00130 elem::Length(width, row_shift, row_stride); 00131 00132 A.Empty(); 00133 00134 A = elem::DistMatrix<value_type, ColDist, RowDist>(height, width, 00135 col_alignment, row_alignment, grid); 00136 00137 elem::Matrix<value_type>& local_matrix = A.Matrix(); 00138 realize_matrix_view(local_matrix, 00139 i + col_shift, j + row_shift, 00140 local_height, local_width, 00141 col_stride, row_stride); 00142 } 00143 00144 00145 protected: 00146 00147 dense_transform_data_t (int N, int S, double scale, 00148 const base::context_t& context, std::string type) 00149 : base_t(N, S, context, type), 00150 scale(scale), 00151 distribution() { 00152 00153 } 00154 00155 base::context_t build() { 00156 base::context_t ctx = base_t::build(); 00157 random_samples = ctx.allocate_random_samples_array(_N * _S, distribution); 00158 return ctx; 00159 } 00160 00161 double scale; 00162 value_distribution_type distribution; 00163 skylark::utility::random_samples_array_t <value_distribution_type> 00164 random_samples; 00168 }; 00169 00170 } } 00172 #endif