Commit 1f64874f authored by Roland Levillain's avatar Roland Levillain
Browse files

apps/bench: More comparisons (2- and 1-pointer based non-gen impl.).

	* apps/bench/trait.hh: New.
	Use it...
	* apps/bench/dilation-lena.cc: ...here.
	(nongen_2ptr::dilation, nongen_1ptr::dilation): New functions.
	Exercise them...
	(run): ...here.
	(main): Store the number of iterations in a variable.
	* apps/bench/static_dpoints_pixter.hh
	(mln::static_dpoints_fwd_pixter<I, n>)
	(mln::static_dpoints_bkd_pixter<I, n>):
	Turn into...
	(mln::static_dpoints_fwd_pixter<I, W>)
	(mln::static_dpoints_bkd_pixter<I, W>):
	...these, so that these pixters are built from a (static) window
	instead of a length.
	(mln::static_dpoints_fwd_pixter<I, W>::n)
	(mln::static_dpoints_bkd_pixter<I, W>::n):
	New attributes.
	* apps/bench/static_window.hh
	(mln::static_window<D, n>::Size): Rename as...
	(mln::static_window<D, n>::length): ...this.
	* apps/bench/Makefile.am (noinst_HEADERS): Add trait.hh.
	(MOSTLYCLEANFILES): Update.
parent f588e466
2010-12-14 Roland Levillain <roland@lrde.epita.fr>
apps/bench: More comparisons (2- and 1-pointer based non-gen impl.).
* apps/bench/trait.hh: New.
Use it...
* apps/bench/dilation-lena.cc: ...here.
(nongen_2ptr::dilation, nongen_1ptr::dilation): New functions.
Exercise them...
(run): ...here.
(main): Store the number of iterations in a variable.
* apps/bench/static_dpoints_pixter.hh
(mln::static_dpoints_fwd_pixter<I, n>)
(mln::static_dpoints_bkd_pixter<I, n>):
Turn into...
(mln::static_dpoints_fwd_pixter<I, W>)
(mln::static_dpoints_bkd_pixter<I, W>):
...these, so that these pixters are built from a (static) window
instead of a length.
(mln::static_dpoints_fwd_pixter<I, W>::n)
(mln::static_dpoints_bkd_pixter<I, W>::n):
New attributes.
* apps/bench/static_window.hh
(mln::static_window<D, n>::Size): Rename as...
(mln::static_window<D, n>::length): ...this.
* apps/bench/Makefile.am (noinst_HEADERS): Add trait.hh.
(MOSTLYCLEANFILES): Update.
2010-12-14 Roland Levillain <roland@lrde.epita.fr>
 
apps/bench: Run more test cases, make comparisons more robust, factor.
# 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.
#
......@@ -28,10 +28,13 @@ noinst_HEADERS = \
minus.hh \
static_array.hh \
static_dpoints_pixter.hh \
static_window.hh
static_window.hh \
trait.hh
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 \
......@@ -41,6 +44,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 \
......@@ -50,6 +55,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 \
......
// 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);
}
// 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_offset(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_offset(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;
}
......
// 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;
......
// 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;