[vspline] 54/72: changed template argument signature of grid_eval
Kay F. Jahnke
kfj-guest at moszumanska.debian.org
Sun Jul 2 09:02:42 UTC 2017
This is an automated email from the git hooks/post-receive script.
kfj-guest pushed a commit to branch master
in repository vspline.
commit 3e38f24c533e99071e03a96ab8db0d30b413b17f
Author: Kay F. Jahnke <kfjahnke at gmail.com>
Date: Wed May 3 18:32:06 2017 +0200
changed template argument signature of grid_eval
---
remap.h | 136 +++++++++++++++++++++++++++++-----------------------------------
1 file changed, 62 insertions(+), 74 deletions(-)
diff --git a/remap.h b/remap.h
index 20f96b4..81640e2 100644
--- a/remap.h
+++ b/remap.h
@@ -57,6 +57,13 @@
///
/// t[j] = i(a,c[j]) for all j
///
+/// Now we widen the concept of remapping to something which is more like a 'transform'
+/// function. Instead of limiting the process to the use of an 'interpolator', we use
+/// an arbitrary unary functor to transform incoming values to outgoing values, where
+/// the type of the incoming and outgoing values is determined by the functor. If the
+/// functor actually is an interpolator, we have a 'true' remap transforming coordinates
+/// into values, but this is merely a special case.
+///
/// st_remap is the single_threaded implementation; remap itself partitions it's work
/// and feeds several threads, each running one instance of st_remap.
///
@@ -69,12 +76,6 @@
/// for example, remap from a volume to a 2D image, using a 2D warp array containing
/// 3D coordinates.
///
-/// In these routines, we can switch the use of vectorization on or off. When using
-/// vectorization, this is done in a straightforward fashion by aggregating the input.
-/// If the source/target array lends itself to it, we can pass it's memory directly
-/// to the vectorized eval code.
-/// If the memory is not suited, I 'manually' aggregate to a simdized type.
-///
/// There is also a second set of remap functions in this file, which don't take a
/// 'warp' array. Instead, for every target location, the location's discrete coordinates
/// are passed to the unary_functor_type object. This way, transformation-based remaps
@@ -88,8 +89,8 @@
///
/// - unary_functor_type: functor object yielding values for coordinates
///
-/// This file also has code to evaluate a b-spline at positions in a mesh grid, which can be used
-/// for scaling, and for separable geometric transformations.
+/// This file also has code to evaluate a b-spline at positions in a mesh grid, which can
+/// be used for scaling, and for separable geometric transformations.
///
/// The current implementation of the remap functionality uses a straightforward mode of
/// operation, which factors out the various needed tasks into separate bits of code. The
@@ -167,7 +168,7 @@ using bcv_type = vigra::TinyVector < bc_code , dimension > ;
/// or gather/scatter operations, even when the arrays involved are strided.
/// Taking the hierarchical descent down to level 0 is encoded in fill() and it's
/// workhorse code, the generator objects implemented here depend on the descent
-/// going all thw way down.
+/// going all the way down to 1D.
///
/// _fill is used by st_fill. It's an object implementing an hierarchical fill
/// of the target array. This is done recursively. while the generator's and the
@@ -298,7 +299,7 @@ void st_fill ( shape_range_type < dim_out > range ,
/// turn uses st_fill, the single-threaded fill routine.
template < typename generator_type , // functor object yielding values
- int dim_target > // number of dimensions of output array
+ int dim_target > // number of dimensions of output array
void fill ( generator_type & gen ,
MultiArrayView < dim_target , typename generator_type::value_type >
& output )
@@ -562,7 +563,7 @@ void apply ( const unary_functor_type & ev ,
template < typename coordinate_type , // type of coordinates in the warp array
typename value_type , // type of values to produce
- int dim_out > // number of dimensions of output array
+ int dim_out > // number of dimensions of warp and output array
int remap ( const MultiArrayView
< vigra::ExpandElementResult < coordinate_type > :: size ,
value_type > & input ,
@@ -817,18 +818,18 @@ namespace detail // workhorse code for grid_eval
// offsets for all dimensions yields the offset into the coefficient array
// to the window of coefficients where the weights are to be applied.
-template < typename unary_functor_type , // type offering eval()
- typename target_type , // iterates over target array
- typename weight_type , // singular weight data type
- int level > // current axis
+template < typename evaluator_type , int level >
struct _grid_eval
{
+ typedef typename evaluator_type::ele_type weight_type ;
+ typedef MultiArrayView < level + 1 , typename evaluator_type::value_type > target_type ;
+
void operator() ( int initial_ofs ,
MultiArrayView < 2 , weight_type > & weight ,
weight_type** const & grid_weight ,
const int & ORDER ,
int ** const & grid_ofs ,
- const unary_functor_type & itp ,
+ const evaluator_type & itp ,
target_type & result )
{
for ( int ofs = 0 ; ofs < result.shape ( level ) ; ofs++ )
@@ -837,26 +838,24 @@ struct _grid_eval
weight [ vigra::Shape2 ( e , level ) ] = grid_weight [ level ] [ ORDER * ofs + e ] ;
int cum_ofs = initial_ofs + grid_ofs [ level ] [ ofs ] ;
auto region = result.bindAt ( level , ofs ) ;
- _grid_eval < unary_functor_type , decltype ( region ) , weight_type , level-1 >()
+ _grid_eval < evaluator_type , level-1 >()
( cum_ofs , weight , grid_weight , ORDER , grid_ofs , itp , region ) ;
}
}
} ;
-template < typename unary_functor_type ,
- typename target_type ,
- typename weight_type >
-struct _grid_eval < unary_functor_type ,
- target_type ,
- weight_type ,
- 0 >
+template < typename evaluator_type >
+struct _grid_eval < evaluator_type , 0 >
{
+ typedef typename evaluator_type::ele_type weight_type ;
+ typedef MultiArrayView < 1 , typename evaluator_type::value_type > target_type ;
+
void operator() ( int initial_ofs ,
MultiArrayView < 2 , weight_type > & weight ,
weight_type** const & grid_weight ,
const int & ORDER ,
int ** const & grid_ofs ,
- const unary_functor_type & itp ,
+ const evaluator_type & itp ,
target_type & region )
{
auto iter = region.begin() ;
@@ -868,13 +867,13 @@ struct _grid_eval < unary_functor_type ,
// than the unvectorized code. With g++, the vectorized code is faster
// than either clang version, but the unvectorized code is much slower.
- const int vsize = unary_functor_type::vsize ;
- const int channels = unary_functor_type::channels ;
- typedef typename unary_functor_type::value_type value_type ;
- typedef typename unary_functor_type::ele_type ele_type ;
- typedef typename unary_functor_type::ic_v ic_v ;
- typedef typename unary_functor_type::ele_v ele_v ;
- typedef typename unary_functor_type::mc_ele_v mc_ele_v ;
+ const int vsize = evaluator_type::vsize ;
+ const int channels = evaluator_type::channels ;
+ typedef typename evaluator_type::value_type value_type ;
+ typedef typename evaluator_type::ele_type ele_type ;
+ typedef typename evaluator_type::ic_v ic_v ;
+ typedef typename evaluator_type::ele_v ele_v ;
+ typedef typename evaluator_type::mc_ele_v mc_ele_v ;
// number of vectorized results
int aggregates = region.size() / vsize ;
@@ -954,37 +953,39 @@ struct _grid_eval < unary_functor_type ,
// via 'multithread()' which sets up the partitioning and distribution
// to threads from a thread pool.
-template < typename evaluator_type , // type offering eval()
- typename target_type , // type of target MultiArrayView
- typename weight_type , // singular weight data type
- typename rc_type > // singular real coordinate
-void st_grid_eval ( shape_range_type < target_type::actual_dimension > range ,
- rc_type ** const _grid_coordinate ,
+template < typename evaluator_type , // b-spline evaluator type
+ int dim_out > // dimension of target
+void st_grid_eval ( shape_range_type < dim_out > range ,
+ typename evaluator_type::rc_type ** const _grid_coordinate ,
const evaluator_type * itp ,
- target_type * p_result )
+ MultiArrayView < dim_out , typename evaluator_type::value_type >
+ * p_result )
{
+ typedef typename evaluator_type::ele_type weight_type ;
+ typedef typename evaluator_type::rc_type rc_type ;
+ typedef MultiArrayView < dim_out , typename evaluator_type::value_type > target_type ;
+
const int ORDER = itp->get_order() ;
- const int dim_target = target_type::actual_dimension ;
// pick the subarray of the 'whole' target array pertaining to this thread's range
auto result = p_result->subarray ( range[0] , range[1] ) ;
// pick the subset of coordinates pertaining to this thread's range
- const rc_type * grid_coordinate [ dim_target ] ;
- for ( int d = 0 ; d < dim_target ; d++ )
+ const rc_type * grid_coordinate [ dim_out ] ;
+ for ( int d = 0 ; d < dim_out ; d++ )
grid_coordinate[d] = _grid_coordinate[d] + range[0][d] ;
// set up storage for precalculated weights and offsets
- weight_type * grid_weight [ dim_target ] ;
- int * grid_ofs [ dim_target ] ;
+ weight_type * grid_weight [ dim_out ] ;
+ int * grid_ofs [ dim_out ] ;
// get some metrics
- TinyVector < int , dim_target > shape ( result.shape() ) ;
- TinyVector < int , dim_target > stride ( itp->get_stride() ) ;
+ TinyVector < int , dim_out > shape ( result.shape() ) ;
+ TinyVector < int , dim_out > stride ( itp->get_stride() ) ;
// allocate space for the per-axis weights and offsets
- for ( int d = 0 ; d < dim_target ; d++ )
+ for ( int d = 0 ; d < dim_out ; d++ )
{
grid_weight[d] = new weight_type [ ORDER * shape [ d ] ] ;
grid_ofs[d] = new int [ shape [ d ] ] ;
@@ -1000,7 +1001,7 @@ void st_grid_eval ( shape_range_type < target_type::actual_dimension > range ,
// the coordinates received in grid_coordinate, the interpolator's obtain_weights
// method to produce the weight components, and the strides of the coefficient array
// to convert the integral parts of the coordinates into offsets.
- for ( int d = 0 ; d < dim_target ; d++ )
+ for ( int d = 0 ; d < dim_out ; d++ )
{
for ( int c = 0 ; c < shape [ d ] ; c++ )
{
@@ -1011,23 +1012,14 @@ void st_grid_eval ( shape_range_type < target_type::actual_dimension > range ,
}
// allocate storage for a set of singular weights
- MultiArray < 2 , weight_type > weight ( vigra::Shape2 ( ORDER , dim_target ) ) ;
+ MultiArray < 2 , weight_type > weight ( vigra::Shape2 ( ORDER , dim_out ) ) ;
// now call the recursive workhorse routine
- detail::_grid_eval < evaluator_type ,
- target_type ,
- weight_type ,
- dim_target - 1 >()
- ( 0 ,
- weight ,
- grid_weight ,
- ORDER ,
- grid_ofs ,
- *itp ,
- result ) ;
+ detail::_grid_eval < evaluator_type , dim_out - 1 >()
+ ( 0 , weight , grid_weight , ORDER , grid_ofs , *itp , result ) ;
// clean up
- for ( int d = 0 ; d < dim_target ; d++ )
+ for ( int d = 0 ; d < dim_out ; d++ )
{
delete[] grid_weight[d] ;
delete[] grid_ofs[d] ;
@@ -1069,19 +1061,15 @@ void st_grid_eval ( shape_range_type < target_type::actual_dimension > range ,
/// to the prefiltering routine. Of course any other way of smoothing can
/// be used just the same, like a Burt filter or Gaussian smoothing.
-// TODO template args are too many and too unspecific, especially weight_type
-
-template < typename evaluator_type , // type offering eval()
- typename target_type ,
- typename weight_type , // singular weight data type
- typename rc_type > // singular real coordinate
-void grid_eval ( rc_type ** const grid_coordinate ,
+template < typename evaluator_type , // b-spline evaluator
+ int dim_out > // dimension of target
+void grid_eval ( typename evaluator_type::rc_type ** const grid_coordinate ,
const evaluator_type & itp ,
- target_type & result )
+ MultiArrayView < dim_out , typename evaluator_type::value_type >
+ & result )
{
- const int dim_target = target_type::actual_dimension ;
- shape_range_type < dim_target > range ( shape_type < dim_target > () , result.shape() ) ;
- multithread ( st_grid_eval < evaluator_type , target_type , weight_type , rc_type > ,
+ shape_range_type < dim_out > range ( shape_type < dim_out > () , result.shape() ) ;
+ multithread ( st_grid_eval < evaluator_type , dim_out > ,
ncores * 8 , range , grid_coordinate , &itp , &result ) ;
}
@@ -1122,14 +1110,14 @@ void restore ( const vspline::bspline < value_type , dimension > & bspl ,
{
typedef vspline::evaluator < coordinate_type , value_type , -1 , 0 > ev_type ;
ev_type ev ( bspl ) ;
- vspline::grid_eval < ev_type , target_type , weight_type , rc_type >
+ vspline::grid_eval < ev_type , dimension > // target_type , weight_type , rc_type >
( p_ruler , ev , target ) ;
}
else
{
typedef vspline::evaluator < coordinate_type , value_type , -1 , 1 > ev_type ;
ev_type ev ( bspl ) ;
- vspline::grid_eval < ev_type , target_type , weight_type , rc_type >
+ vspline::grid_eval < ev_type , dimension > // , target_type , weight_type , rc_type >
( p_ruler , ev , target ) ;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/vspline.git
More information about the debian-science-commits
mailing list