last-svn-commit-548-g4762c47 WIP: More comparisons (2- and 1-pointer based non-gen impl.)

--- milena/apps/bench/Makefile.am | 15 +++- milena/apps/bench/dilation-lena.cc | 119 +++++++++++++++++++++++++-- milena/apps/bench/static_dpoints_pixter.hh | 102 ++++++++++++----------- milena/apps/bench/static_window.hh | 4 +- milena/apps/bench/trait.hh | 99 +++++++++++++++++++++++ 5 files changed, 277 insertions(+), 62 deletions(-) create mode 100644 milena/apps/bench/trait.hh diff --git a/milena/apps/bench/Makefile.am b/milena/apps/bench/Makefile.am index adc0cdf..266b71b 100644 --- a/milena/apps/bench/Makefile.am +++ b/milena/apps/bench/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE). +# Copyright (C) 2010, 2011 EPITA Research and Development Laboratory (LRDE). # # This file is part of Olena. # @@ -29,7 +29,12 @@ noinst_PROGRAMS = \ EXTRA_DIST += \ and_not.hh \ - minus.hh + minus.hh \ + \ + static_array.hh \ + static_dpoints_pixter.hh \ + static_window.hh \ + trait.hh dilation_lena_SOURCES = dilation-lena.cc gradient_lena_SOURCES = gradient-lena.cc @@ -37,6 +42,8 @@ gradient_spe_lena_SOURCES = gradient-spe-lena.cc MOSTLYCLEANFILES = \ dilation-lena-out-512-nongen.pgm \ + dilation-lena-out-512-nongen_2ptr.pgm \ + dilation-lena-out-512-nongen_1ptr.pgm \ dilation-lena-out-512-gen.pgm \ dilation-lena-out-512-fast.pgm \ dilation-lena-out-512-fast_noaccu.pgm \ @@ -46,6 +53,8 @@ MOSTLYCLEANFILES = \ dilation-lena-out-512-faster_static.pgm \ \ dilation-lena-out-1024-nongen.pgm \ + dilation-lena-out-1024-nongen_2ptr.pgm \ + dilation-lena-out-1024-nongen_1ptr.pgm \ dilation-lena-out-1024-gen.pgm \ dilation-lena-out-1024-fast.pgm \ dilation-lena-out-1024-fast_noaccu.pgm \ @@ -55,6 +64,8 @@ MOSTLYCLEANFILES = \ dilation-lena-out-1024-faster_static.pgm \ \ dilation-lena-out-2048-nongen.pgm \ + dilation-lena-out-2048-nongen_2ptr.pgm \ + dilation-lena-out-2048-nongen_1ptr.pgm \ dilation-lena-out-2048-gen.pgm \ dilation-lena-out-2048-fast.pgm \ dilation-lena-out-2048-fast_noaccu.pgm \ diff --git a/milena/apps/bench/dilation-lena.cc b/milena/apps/bench/dilation-lena.cc index 69c82a7..e4996fb 100644 --- a/milena/apps/bench/dilation-lena.cc +++ b/milena/apps/bench/dilation-lena.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory (LRDE) // // This file is part of Olena. // @@ -23,6 +23,8 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. +#include <cstddef> + #include <iostream> #include <mln/core/image/image2d.hh> @@ -39,9 +41,12 @@ #include "apps/bench/static_window.hh" #include "apps/bench/static_dpoints_pixter.hh" +#include "apps/bench/trait.hh" + #include "apps/data.hh" + namespace nongen { typedef mln::image2d<mln::value::int_u8> image; @@ -63,6 +68,99 @@ namespace nongen } } +namespace nongen_2ptr +{ + typedef mln::image2d<mln::value::int_u8> image; + + image dilation(const image& input) + { + typedef mln::value::int_u8 val_t; + // Offsets corresponding to a 4-c window on INPUT. + ptrdiff_t win_offset[4] = { &input.at_(-1, 0) - &input.at_(0, 0), + &input.at_(+1, 0) - &input.at_(0, 0), + &input.at_( 0, -1) - &input.at_(0, 0), + &input.at_( 0, +1) - &input.at_(0, 0) }; + + image output (input.nrows(), input.ncols()); // Initialize an output image. + for (unsigned int r = 0; r < input.nrows(); ++r) // Iterate on rows. + { + const val_t* pi = &input.at_(r, 0); + val_t* po = &output.at_(r, 0); + for (; pi < &input.at_(r, 0) + input.ncols(); ++pi, ++po) + { + unsigned char sup = *pi; + // (-1, 0) neighbor. + if (r != 0 + && *(pi + win_offset[0]) > sup) + sup = *(pi + win_offset[0]); + // (+1, 0) neighbor. + if (r != input.nrows() - 1 + && *(pi + win_offset[1]) > sup) + sup = *(pi + win_offset[1]); + // (0, -1) neighbor. + if (pi != &input.at_(r, 0) + && *(pi + win_offset[2]) > sup) + sup = *(pi + win_offset[2]); + // (0, +1) neighbor. + if (pi != &input.at_(r, 0) + input.ncols() - 1 + && *(pi + win_offset[3]) > sup) + sup = *(pi + win_offset[3]); + *po = sup; + } + } + return output; + } +} + +namespace nongen_1ptr +{ + typedef mln::image2d<mln::value::int_u8> image; + + image dilation(const image& input) + { + typedef mln::value::int_u8 val_t; + // Offsets corresponding to a 4-c window on INPUT. + ptrdiff_t win_offset[4] = { &input.at_(-1, 0) - &input.at_(0, 0), + &input.at_(+1, 0) - &input.at_(0, 0), + &input.at_( 0, -1) - &input.at_(0, 0), + &input.at_( 0, +1) - &input.at_(0, 0) }; + + image output; + initialize(output, input); + // Offset between a the pixel located at the same position in + // INPUT and OUTPUT. + ptrdiff_t output_offset = &output.at_(0, 0) - &input.at_(0, 0); + + for (unsigned int r = 0; r < input.nrows(); ++r) // Iterate on rows. + { + for (const val_t* pi = &input.at_(r, 0); + pi < &input.at_(r, 0) + input.ncols(); + ++pi) + { + unsigned char sup = *pi; + // (-1, 0) neighbor. + if (r != 0 + && *(pi + win_offset[0]) > sup) + sup = *(pi + win_offset[0]); + // (+1, 0) neighbor. + if (r != input.nrows() - 1 + && *(pi + win_offset[1]) > sup) + sup = *(pi + win_offset[1]); + // (0, -1) neighbor. + if (pi != &input.at_(r, 0) + && *(pi + win_offset[2]) > sup) + sup = *(pi + win_offset[2]); + // (0, +1) neighbor. + if (pi != &input.at_(r, 0) + input.ncols() - 1 + && *(pi + win_offset[3]) > sup) + sup = *(pi + win_offset[3]); + const_cast<val_t&>(*(pi + output_offset)) = sup; + } + } + return output; + } +} + namespace gen { using namespace mln; @@ -201,9 +299,8 @@ namespace fast_static mln_pixter(const I) pi(input); // Iterator on the pixels of `input'. mln_pixter(O) po(output); // Iterator on the pixels of `output'. + mln_static_qixter(const I, W) q(pi, win); // Iterator on the neighbors of `p' w.r.t. `win'. - typedef mln::static_dpoints_fwd_pixter<const I, W::Size> mln_static_qixter; - mln_static_qixter q(pi, win); for_all_2(pi, po) { // FIXME: Cheat: replace the accu::supremum by a maximum. @@ -227,9 +324,8 @@ namespace faster_static O output; initialize(output, input); // Initialize output. mln_pixter(const I) p(input); // Iterator on the pixels of `input'. + mln_static_qixter(const I, W) q(p, win); // Iterator on the neighbors of `p' w.r.t. `win'. - typedef mln::static_dpoints_fwd_pixter<const I, W::Size> mln_static_qixter; - mln_static_qixter q(p, win); for_all(p) { // FIXME: Cheat: replace the accu::supremum by a maximum. @@ -288,9 +384,13 @@ run(const std::string& filename, const std::string& length, unsigned niters) std::string prefix = "dilation-lena-out"; std::cout << "== " << filename << std::endl; - DILATION_WITH_BUILTIN_WINDOW(nongen, "nongen", "nongen\t\t"); + DILATION_WITH_BUILTIN_WINDOW(nongen, "nongen", "nongen\t\t"); + DILATION_WITH_BUILTIN_WINDOW(nongen_2ptr, "nongen_2ptr", "nongen_2ptr\t"); + DILATION_WITH_BUILTIN_WINDOW(nongen_1ptr, "nongen_1ptr", "nongen_1ptr\t"); DILATION(gen, win_c4p(), "gen", "gen\t\t"); + // FIXME: Introduce a new test case, gen_static, using a static window + // and static_qiters. DILATION(fast, win_c4p(), "fast", "fast\t\t"); DILATION(fast_noaccu, win_c4p(), "fast_noaccu", "fast_noaccu\t"); DILATION(faster, win_c4p(), "faster", "faster\t\t"); @@ -315,7 +415,8 @@ run(const std::string& filename, const std::string& length, unsigned niters) int main () { - run(MLN_IMG_DIR "/lena.pgm", "512", 10); - run(MLN_APPS_DIR "/bench/lena1024.pgm", "1024", 10); - run(MLN_APPS_DIR "/bench/lena2048.pgm", "2048", 10); + unsigned niters = 10; + run(MLN_IMG_DIR "/lena.pgm", "512", niters); + run(MLN_APPS_DIR "/bench/lena1024.pgm", "1024", niters); + run(MLN_APPS_DIR "/bench/lena2048.pgm", "2048", niters); } diff --git a/milena/apps/bench/static_dpoints_pixter.hh b/milena/apps/bench/static_dpoints_pixter.hh index d7823ac..ffa4a81 100644 --- a/milena/apps/bench/static_dpoints_pixter.hh +++ b/milena/apps/bench/static_dpoints_pixter.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development +// Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and Development // Laboratory (LRDE) // // This file is part of Olena. @@ -50,19 +50,19 @@ namespace mln { /*----------------------------------. - | static_dpoints_fwd_pixter<I, n>. | + | static_dpoints_fwd_pixter<I, W>. | `----------------------------------*/ /// \brief A generic forward iterator on the pixels of a /// dpoint-based window or neighborhood. /// /// Parameter \c I is the image type. - template <typename I, unsigned n> + template <typename I, typename W> class static_dpoints_fwd_pixter - : public Pixel_Iterator< static_dpoints_fwd_pixter<I, n> >, - public internal::pixel_impl_< I, static_dpoints_fwd_pixter<I, n> > + : public Pixel_Iterator< static_dpoints_fwd_pixter<I, W> >, + public internal::pixel_impl_< I, static_dpoints_fwd_pixter<I, W> > { - typedef typename internal::pixel_impl_< I, static_dpoints_fwd_pixter<I, n> > super_; + typedef typename internal::pixel_impl_< I, static_dpoints_fwd_pixter<I, W> > super_; public: /// \brief Constructor (using an image). @@ -111,6 +111,8 @@ namespace mln void init_(const Dps& dps); private: + enum { n = W::length }; + /// \brief Offset of each delta-point. /// /// offset_[0] is absolute, while other offsets are relative @@ -133,19 +135,19 @@ namespace mln /*----------------------------------. - | static_dpoints_bkd_pixter<I, n>. | + | static_dpoints_bkd_pixter<I, W>. | `----------------------------------*/ /// \brief A generic backward iterator on the pixels of a /// dpoint-based window or neighborhood. /// /// Parameter \c I is the image type. - template <typename I, unsigned n> + template <typename I, typename W> class static_dpoints_bkd_pixter - : public Pixel_Iterator< static_dpoints_bkd_pixter<I, n> >, - public internal::pixel_impl_< I, static_dpoints_bkd_pixter<I, n> > + : public Pixel_Iterator< static_dpoints_bkd_pixter<I, W> >, + public internal::pixel_impl_< I, static_dpoints_bkd_pixter<I, W> > { - typedef typename internal::pixel_impl_< I, static_dpoints_bkd_pixter<I, n> > super_; + typedef typename internal::pixel_impl_< I, static_dpoints_bkd_pixter<I, W> > super_; public: /// \brief Constructor (using an image). @@ -194,6 +196,8 @@ namespace mln void init_(const Dps& dps); private: + enum { n = W::length }; + /// \brief Offset of each delta-point. /// /// offset_[dps.size() - 1] is absolute, while other offsets @@ -219,13 +223,13 @@ namespace mln #ifndef MLN_INCLUDE_ONLY /*----------------------------------. - | static_dpoints_fwd_pixter<I, n>. | + | static_dpoints_fwd_pixter<I, W>. | `----------------------------------*/ - template <typename I, unsigned n> + template <typename I, typename W> template <typename Dps, typename Pref> inline - static_dpoints_fwd_pixter<I, n>::static_dpoints_fwd_pixter(I& image, + static_dpoints_fwd_pixter<I, W>::static_dpoints_fwd_pixter(I& image, const Dps& dps, const Pref& p_ref) : super_(image) @@ -239,10 +243,10 @@ namespace mln init_(dps); } - template <typename I, unsigned n> + template <typename I, typename W> template <typename Dps, typename Pref> inline - static_dpoints_fwd_pixter<I, n>::static_dpoints_fwd_pixter(const Generalized_Pixel<Pref>& pxl_ref_, + static_dpoints_fwd_pixter<I, W>::static_dpoints_fwd_pixter(const Generalized_Pixel<Pref>& pxl_ref_, const Dps& dps) : super_(internal::force_exact<Pref>(pxl_ref_).ima()) { @@ -254,10 +258,10 @@ namespace mln init_(dps); } - template <typename I, unsigned n> + template <typename I, typename W> inline const mln_value(I)& - static_dpoints_fwd_pixter<I, n>::center_val() const + static_dpoints_fwd_pixter<I, W>::center_val() const { mln_invariant(value_ref_ != 0 || p_ref_ != 0); if (p_ref_) @@ -266,11 +270,11 @@ namespace mln return **value_ref_; } - template <typename I, unsigned n> + template <typename I, typename W> template <typename Dps> inline void - static_dpoints_fwd_pixter<I, n>::init_(const Dps& dps) + static_dpoints_fwd_pixter<I, W>::init_(const Dps& dps) { for (unsigned i = 0; i < dps.size(); ++i) offset_[i] = this->image_.delta_index(dps.dp(i)); @@ -282,10 +286,10 @@ namespace mln invalidate(); } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_fwd_pixter<I, n>::update() + static_dpoints_fwd_pixter<I, W>::update() { if (is_valid()) { @@ -296,50 +300,50 @@ namespace mln } } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_fwd_pixter<I, n>::start() + static_dpoints_fwd_pixter<I, W>::start() { i_ = 0; update(); } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_fwd_pixter<I, n>::next_() + static_dpoints_fwd_pixter<I, W>::next_() { ++i_; if (is_valid()) this->value_ptr_ += offset_[i_]; } - template <typename I, unsigned n> + template <typename I, typename W> inline bool - static_dpoints_fwd_pixter<I, n>::is_valid() const + static_dpoints_fwd_pixter<I, W>::is_valid() const { return i_ < n; } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_fwd_pixter<I, n>::invalidate() + static_dpoints_fwd_pixter<I, W>::invalidate() { i_ = n; } /*----------------------------------. - | static_dpoints_bkd_pixter<I, n>. | + | static_dpoints_bkd_pixter<I, W>. | `----------------------------------*/ - template <typename I, unsigned n> + template <typename I, typename W> template <typename Dps, typename Pref> inline - static_dpoints_bkd_pixter<I, n>::static_dpoints_bkd_pixter(I& image, + static_dpoints_bkd_pixter<I, W>::static_dpoints_bkd_pixter(I& image, const Dps& dps, const Pref& p_ref) : super_(image) @@ -350,10 +354,10 @@ namespace mln init_(dps); } - template <typename I, unsigned n> + template <typename I, typename W> template <typename Dps, typename Pref> inline - static_dpoints_bkd_pixter<I, n>::static_dpoints_bkd_pixter(const Generalized_Pixel<Pref>& pxl_ref_, + static_dpoints_bkd_pixter<I, W>::static_dpoints_bkd_pixter(const Generalized_Pixel<Pref>& pxl_ref_, const Dps& dps) : super_(internal::force_exact<Pref>(pxl_ref_).ima()) { @@ -365,10 +369,10 @@ namespace mln init_(dps); } - template <typename I, unsigned n> + template <typename I, typename W> inline const mln_value(I)& - static_dpoints_bkd_pixter<I, n>::center_val() const + static_dpoints_bkd_pixter<I, W>::center_val() const { mln_invariant(value_ref_ != 0 || p_ref_ != 0); if (p_ref_) @@ -377,11 +381,11 @@ namespace mln return **value_ref_; } - template <typename I, unsigned n> + template <typename I, typename W> template <typename Dps> inline void - static_dpoints_bkd_pixter<I, n>::init_(const Dps& dps) + static_dpoints_bkd_pixter<I, W>::init_(const Dps& dps) { for (unsigned i = 0; i < dps.size(); ++i) offset_[i] = this->image_.delta_index(dps.dp(i)); @@ -393,10 +397,10 @@ namespace mln invalidate(); } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_bkd_pixter<I, n>::update() + static_dpoints_bkd_pixter<I, W>::update() { if (is_valid()) { @@ -407,37 +411,37 @@ namespace mln } } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_bkd_pixter<I, n>::start() + static_dpoints_bkd_pixter<I, W>::start() { i_ = 0; update(); } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_bkd_pixter<I, n>::next_() + static_dpoints_bkd_pixter<I, W>::next_() { ++i_; if (is_valid()) this->value_ptr_ += offset_[n - 1 - i_]; } - template <typename I, unsigned n> + template <typename I, typename W> inline bool - static_dpoints_bkd_pixter<I, n>::is_valid() const + static_dpoints_bkd_pixter<I, W>::is_valid() const { return i_ < n; } - template <typename I, unsigned n> + template <typename I, typename W> inline void - static_dpoints_bkd_pixter<I, n>::invalidate() + static_dpoints_bkd_pixter<I, W>::invalidate() { i_ = n; } diff --git a/milena/apps/bench/static_window.hh b/milena/apps/bench/static_window.hh index fe8f791..5a8ce21 100644 --- a/milena/apps/bench/static_window.hh +++ b/milena/apps/bench/static_window.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development +// Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and Development // Laboratory (LRDE) // // This file is part of Olena. @@ -90,7 +90,7 @@ namespace mln { public: - enum { Size = n }; + enum { length = n }; /// Regular window associated type. typedef static_window<D, n> regular; diff --git a/milena/apps/bench/trait.hh b/milena/apps/bench/trait.hh new file mode 100644 index 0000000..e3e5004 --- /dev/null +++ b/milena/apps/bench/trait.hh @@ -0,0 +1,99 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef APPS_BENCH_TRAITS_HH +# define APPS_BENCH_TRAITS_HH + +# include <mln/core/image/image2d.hh> +# include <mln/metal/none.hh> + +# include "apps/bench/static_dpoints_pixter.hh" + + +// FIXME: Move this into mln/core/macro.hh. +# define mln_static_fwd_qixter(I, W) typename mln::trait::static_fwd_qixter< I, W >::ret +# define mln_static_fwd_qixter_(I, W) mln::trait::static_fwd_qixter< I, W >::ret + +# define mln_static_bkd_qixter(I, W) typename mln::trait::static_bkd_qixter< I, W >::ret +# define mln_static_bkd_qixter_(I, W) mln::trait::static_bkd_qixter< I, W >::ret + +# define mln_static_qixter(I, W) mln_static_fwd_qixter(I, W) +# define mln_static_qixter_(I, W) mln_static_fwd_qixter_(I, W) + + +// FIXME: Move this into mln/trait/ (and mln/core/image/?) +namespace mln +{ + + namespace trait + { + + // qixter + + template <typename I, typename W> + struct static_fwd_qixter + { + typedef metal::none ret; + }; + + template <typename I, typename W> + struct static_bkd_qixter + { + typedef metal::none ret; + }; + + + template <typename T, typename W> + struct static_fwd_qixter< image2d<T>, W > + { + typedef static_dpoints_fwd_pixter< image2d<T>, W > ret; + }; + + template <typename T, typename W> + struct static_fwd_qixter< const image2d<T>, W > + { + typedef static_dpoints_fwd_pixter< const image2d<T>, W > ret; + }; + + template <typename T, typename W> + struct static_bkd_qixter< image2d<T>, W > + { + typedef static_dpoints_bkd_pixter< image2d<T>, W > ret; + }; + + template <typename T, typename W> + struct static_bkd_qixter< const image2d<T>, W > + { + typedef static_dpoints_bkd_pixter< const image2d<T>, W > ret; + }; + + // FIXME: Also handle mln::image1d<T> and mln::image3d<T>. + + + } // end of namespace mln::trait + +} // end of namespace mln + +#endif // ! APPS_BENCH_TRAITS_HH -- 1.7.2.5
participants (1)
-
Roland Levillain