@ -47,76 +47,79 @@ public:
inputs_arr . getMatVector ( inputs ) ;
outputs_arr . getMatVector ( outputs ) ;
// Get x tensor.
const auto & src_mat = inputs [ 0 ] ;
const auto * src_ptr = src_mat . ptr < float > ( ) ;
// Get input tensor.
const auto & src_mat = inputs [ 0 ] ;
const auto * src_ptr = src_mat . ptr < float > ( ) ;
// Get axis.
const int axis = normalize_axis ( axis_raw , src_mat . dims ) ;
// Get target axis.
int axis = inputs . size ( ) > 1 ? parseAxis ( inputs [ 1 ] ) : axis_raw ;
axis = normalize_axis ( axis , src_mat . dims ) ;
// Get y tensor.
auto & dst_mat = outputs [ 0 ] ;
src_mat . copyTo ( dst_mat ) ;
auto * dst_ptr = dst_mat . ptr < float > ( ) ;
// Get output tensor.
auto & dst_mat = outputs [ 0 ] ;
auto * dst_ptr = dst_mat . ptr < float > ( ) ;
// Get flags.
const auto exclusive = exclusive_raw = = 1 ;
const auto reverse = reverse_raw = = 1 ;
// Get parameters to iterate outer dimension.
// Data with [dim_1, .. , dim_k-1, target_dim, dim_k+1, .. , dim_n]
// dimensions is represented here as [outer_dim, target_dim, inner_dim]
const size_t outer_size = src_mat . total ( 0 , axis ) ;
const size_t outer_step_length = src_mat . total ( axis ) ;
// Get parameters to iterate inner dimension.
const size_t inner_size = src_mat . size [ axis ] ;
if ( ! inner_size )
return ;
const size_t target_size = src_mat . size [ axis ] ;
const size_t inner_size = src_mat . total ( axis + 1 ) ;
const size_t outer_step_length = target_size * inner_size ;
const size_t inner_step_length = src_mat . total ( axis + 1 ) ;
const int inner_step = ( reverse ? - 1 : 1 ) * inner_step_length ;
const int inner_s tart = reverse ? inner_size - 1 : 0 ;
const int inner_stop = reverse ? - 1 : inner_size ;
const int inner_delta = reverse ? - 1 : 1 ;
// Calculating steps in target dimensions
const int target_start = reverse ? target_size - 1 : 0 ;
const int target_stop = reverse ? - 1 : target_size ;
const int target_delta = reverse ? - 1 : 1 ;
const int target_step = target_delta * inner_size ;
// Get parameters to populate channels.
const size_t num_channels = src_mat . total ( axis + 1 ) ;
// If exclusive, the j-th output element would be the sum of the first (j-1) elements.
// Otherwise, it would be the sum of the first j elements.
const int exclusive_delta = exclusive ? target_step : 0 ;
for ( size_t outer_dim = 0 ; outer_dim < outer_size ; outer_dim + + )
for ( size_t outer_idx = 0 ; outer_idx < outer_size ; outer_idx + + )
{
const size_t outer_offset = outer_dim * outer_step_length ;
size_t src_offset = outer_offset + inner_start * inner_step_length ;
// Populate first element of inner dimension.
for ( size_t channel = 0 ; channel < num_channels ; channel + + )
{
if ( exclusive )
{
dst_ptr [ src_offset + channel ] = 0.0f ;
}
else
{
dst_ptr [ src_offset + channel ] = src_ptr [ src_offset + channel ] ;
src_offset + = inner_step ;
}
}
// Populate remaining elements of inner dimension.
for ( int inner_dim = inner_start + inner_delta ; inner_dim ! = inner_stop ; inner_dim + = inner_delta )
const size_t target_offset = outer_idx * outer_step_length ;
// Handle first element of target dimension.
size_t first_inner_offset = target_offset + target_start * inner_size ;
if ( exclusive )
for ( size_t inner_idx = 0 ; inner_idx < inner_size ; inner_idx + + )
dst_ptr [ first_inner_offset + inner_idx ] = 0.0f ;
else
for ( size_t inner_idx = 0 ; inner_idx < inner_size ; inner_idx + + )
dst_ptr [ first_inner_offset + inner_idx ] = src_ptr [ first_inner_offset + inner_idx ] ;
// Handle remaining elements of target dimension.
for ( int target_idx = target_start + target_delta ; target_idx ! = target_stop ; target_idx + = target_delta )
{
const size_t dst_offset = outer_offset + inner_dim * inner_step_length ;
const size_t inner_offset = target_offset + target_idx * inner_size ;
for ( size_t channel = 0 ; channel < num_channels ; channel + + )
for ( size_t inner_idx = 0 ; inner_idx < inner_size ; inner_idx + + )
{
const size_t previous_dst_offset = dst_offset - inner_step ;
dst_ptr [ dst_offset + channel ] = dst_ptr [ previous_dst_offset + channel ] +
src_ptr [ src_offset + channel ] ;
src_offset + = inner_step ;
dst_ptr [ inner_offset + inner_idx ] = dst_ptr [ inner_offset - target_step + inner_idx ] +
src_ptr [ inner_offset - exclusive_delta + inner_idx ] ;
}
}
}
}
int parseAxis ( const Mat & axis_mat ) {
CV_CheckEQ ( axis_mat . total ( ) , 1u , " Axis tensor should contain single value " ) ;
if ( axis_mat . type ( ) = = CV_32SC1 )
return axis_mat . at < int32_t > ( 0 ) ;
else
{
Mat axis_mat_int ;
axis_mat . convertTo ( axis_mat_int , CV_32SC1 ) ;
return axis_mat_int . at < int32_t > ( 0 ) ;
}
}
int axis_raw ;
int exclusive_raw ;
int reverse_raw ;