Skylark (Sketching Library)  0.1
/var/lib/jenkins/jobs/Skylark/workspace/sketch/dense_transform_data.hpp
Go to the documentation of this file.
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