@ -18,43 +18,12 @@ limitations under the License. */
# include <vector>
# include <vector>
# include "paddle/fluid/framework/op_registry.h"
# include "paddle/fluid/framework/op_registry.h"
# include "paddle/fluid/operators/math/math_function.h"
# include "paddle/fluid/operators/math/math_function.h"
# include "paddle/fluid/operators/utils.h"
namespace paddle {
namespace paddle {
namespace operators {
namespace operators {
using Tensor = framework : : Tensor ;
using Tensor = framework : : Tensor ;
inline std : : vector < int > get_new_data_from_tensorlist (
const std : : vector < const Tensor * > & list_new_data_tensor ) {
// get tensor from
std : : vector < int > vec_new_data ;
for ( size_t i = 0 ; i < list_new_data_tensor . size ( ) ; + + i ) {
auto tensor = list_new_data_tensor [ i ] ;
PADDLE_ENFORCE_EQ ( tensor - > dims ( ) , framework : : make_ddim ( { 1 } ) ,
" shape of dim tensor should be [1] " ) ;
if ( platform : : is_gpu_place ( tensor - > place ( ) ) ) {
framework : : Tensor temp ;
TensorCopySync ( * tensor , platform : : CPUPlace ( ) , & temp ) ;
vec_new_data . push_back ( static_cast < int32_t > ( * temp . data < int32_t > ( ) ) ) ;
} else {
vec_new_data . push_back ( static_cast < int32_t > ( * tensor - > data < int32_t > ( ) ) ) ;
}
}
return vec_new_data ;
}
inline std : : vector < int > get_new_data_from_tensor (
const Tensor * new_data_tensor ) {
std : : vector < int > vec_new_data ;
auto * new_data = new_data_tensor - > data < int > ( ) ;
framework : : Tensor cpu_starts_tensor ;
if ( platform : : is_gpu_place ( new_data_tensor - > place ( ) ) ) {
TensorCopySync ( * new_data_tensor , platform : : CPUPlace ( ) , & cpu_starts_tensor ) ;
new_data = cpu_starts_tensor . data < int > ( ) ;
}
vec_new_data =
std : : vector < int > ( new_data , new_data + new_data_tensor - > numel ( ) ) ;
return vec_new_data ;
}
template < typename DeviceContext , typename T >
template < typename DeviceContext , typename T >
class SliceKernel : public framework : : OpKernel < T > {
class SliceKernel : public framework : : OpKernel < T > {
public :
public :
@ -98,9 +67,11 @@ class SliceKernel : public framework::OpKernel<T> {
bool out_is_tensor_array = out_var - > IsType < framework : : LoDTensorArray > ( ) ;
bool out_is_tensor_array = out_var - > IsType < framework : : LoDTensorArray > ( ) ;
auto axes = context . Attr < std : : vector < int > > ( " axes " ) ;
auto axes = context . Attr < std : : vector < int > > ( " axes " ) ;
auto starts = context . Attr < std : : vector < int > > ( " starts " ) ;
auto ends = context . Attr < std : : vector < int > > ( " ends " ) ;
auto starts_int = context . Attr < std : : vector < int > > ( " starts " ) ;
std : : vector < int64_t > starts ( starts_int . begin ( ) , starts_int . end ( ) ) ;
auto ends_int = context . Attr < std : : vector < int > > ( " ends " ) ;
std : : vector < int64_t > ends ( ends_int . begin ( ) , ends_int . end ( ) ) ;
auto decrease_axis = context . Attr < std : : vector < int > > ( " decrease_axis " ) ;
auto decrease_axis = context . Attr < std : : vector < int > > ( " decrease_axis " ) ;
auto infer_flags = context . Attr < std : : vector < int > > ( " infer_flags " ) ;
auto infer_flags = context . Attr < std : : vector < int > > ( " infer_flags " ) ;
auto list_new_ends_tensor =
auto list_new_ends_tensor =
@ -118,15 +89,15 @@ class SliceKernel : public framework::OpKernel<T> {
if ( need_infer ) {
if ( need_infer ) {
if ( context . HasInput ( " StartsTensor " ) ) {
if ( context . HasInput ( " StartsTensor " ) ) {
auto * starts_tensor = context . Input < framework : : Tensor > ( " StartsTensor " ) ;
auto * starts_tensor = context . Input < framework : : Tensor > ( " StartsTensor " ) ;
starts = get_new_data_from_tensor ( starts_tensor ) ;
starts = GetDataFromTensor < int64_t > ( starts_tensor ) ;
} else if ( list_new_starts_tensor . size ( ) > 0 ) {
} else if ( list_new_starts_tensor . size ( ) > 0 ) {
starts = get_new_data_from_tensorlist ( list_new_starts_tensor ) ;
starts = GetDataFromTensorList < int64_t > ( list_new_starts_tensor ) ;
}
}
if ( context . HasInput ( " EndsTensor " ) ) {
if ( context . HasInput ( " EndsTensor " ) ) {
auto * ends_tensor = context . Input < framework : : Tensor > ( " EndsTensor " ) ;
auto * ends_tensor = context . Input < framework : : Tensor > ( " EndsTensor " ) ;
ends = get_new_data_from_tensor ( ends_tensor ) ;
ends = GetDataFromTensor < int64_t > ( ends_tensor ) ;
} else if ( list_new_ends_tensor . size ( ) > 0 ) {
} else if ( list_new_ends_tensor . size ( ) > 0 ) {
ends = get_new_data_from_tensorlist ( list_new_ends_tensor ) ;
ends = GetDataFromTensorList < int64_t > ( list_new_ends_tensor ) ;
}
}
}
}
PADDLE_ENFORCE_EQ (
PADDLE_ENFORCE_EQ (
@ -140,11 +111,12 @@ class SliceKernel : public framework::OpKernel<T> {
if ( input_is_tensor_array ) {
if ( input_is_tensor_array ) {
auto in_array = context . Input < framework : : LoDTensorArray > ( " Input " ) ;
auto in_array = context . Input < framework : : LoDTensorArray > ( " Input " ) ;
// If the input is LoDTensorArray, the rank of input is 1.
// If the input is LoDTensorArray, the rank of input is 1.
int in_size = in_array - > size ( ) ;
int64_t in_size = in_array - > size ( ) ;
int start = starts [ 0 ] < 0 ? ( starts [ 0 ] + in_size ) : starts [ 0 ] ;
int64_t start = starts [ 0 ] < 0 ? ( starts [ 0 ] + in_size ) : starts [ 0 ] ;
int end = ends [ 0 ] < 0 ? ( ends [ 0 ] + in_size ) : ends [ 0 ] ;
int64_t end = ends [ 0 ] < 0 ? ( ends [ 0 ] + in_size ) : ends [ 0 ] ;
start = std : : max ( start , 0 ) ;
end = std : : max ( end , 0 ) ;
start = std : : max ( start , static_cast < int64_t > ( 0 ) ) ;
end = std : : max ( end , static_cast < int64_t > ( 0 ) ) ;
end = std : : min ( end , in_size ) ;
end = std : : min ( end , in_size ) ;
PADDLE_ENFORCE_GT ( end , start ,
PADDLE_ENFORCE_GT ( end , start ,
@ -152,7 +124,7 @@ class SliceKernel : public framework::OpKernel<T> {
" Attr(ends) should be greater than attr(starts) in "
" Attr(ends) should be greater than attr(starts) in "
" slice op. But received ends = %d, starts = %d. " ,
" slice op. But received ends = %d, starts = %d. " ,
end , start ) ) ;
end , start ) ) ;
int out_size = end - start ;
int 64_t out_size = end - start ;
if ( out_is_tensor_array ) {
if ( out_is_tensor_array ) {
auto out_array = context . Output < framework : : LoDTensorArray > ( " Out " ) ;
auto out_array = context . Output < framework : : LoDTensorArray > ( " Out " ) ;
@ -187,7 +159,7 @@ class SliceKernel : public framework::OpKernel<T> {
auto in_dims = in - > dims ( ) ;
auto in_dims = in - > dims ( ) ;
if ( need_infer ) {
if ( need_infer ) {
out_dims = in_dims ;
out_dims = in_dims ;
int dim_value , start , end ;
int 64_t dim_value , start , end ;
for ( size_t i = 0 ; i < axes . size ( ) ; + + i ) {
for ( size_t i = 0 ; i < axes . size ( ) ; + + i ) {
dim_value = out_dims [ axes [ i ] ] ;
dim_value = out_dims [ axes [ i ] ] ;
if ( dim_value > 0 ) {
if ( dim_value > 0 ) {
@ -202,17 +174,22 @@ class SliceKernel : public framework::OpKernel<T> {
start = starts [ i ] < 0 ? ( starts [ i ] + dim_value ) : starts [ i ] ;
start = starts [ i ] < 0 ? ( starts [ i ] + dim_value ) : starts [ i ] ;
end = ends [ i ] < 0 ? ( ends [ i ] + dim_value ) : ends [ i ] ;
end = ends [ i ] < 0 ? ( ends [ i ] + dim_value ) : ends [ i ] ;
start = std : : max ( start , 0 ) ;
start = std : : max ( start , static_cast < int64_t > ( 0 ) ) ;
end = std : : max ( end , 0 ) ;
end = std : : max ( end , static_cast < int64_t > ( 0 ) ) ;
end = std : : min ( end , dim_value ) ;
end = std : : min ( end , dim_value ) ;
PADDLE_ENFORCE_GT ( end , start , " end should greater than start " ) ;
PADDLE_ENFORCE_GT (
end , start ,
platform : : errors : : InvalidArgument (
" Attr(ends) should be greater than attr(starts) in "
" slice op. But received ends = %d, starts = %d. " ,
end , start ) ) ;
out_dims [ axes [ i ] ] = end - start ;
out_dims [ axes [ i ] ] = end - start ;
}
}
}
}
out - > Resize ( out_dims ) ;
out - > Resize ( out_dims ) ;
// generate new shape
// generate new shape
if ( decrease_axis . size ( ) > 0 ) {
if ( decrease_axis . size ( ) > 0 ) {
std : : vector < int > new_out_shape ;
std : : vector < int 64_t > new_out_shape ;
for ( size_t i = 0 ; i < decrease_axis . size ( ) ; + + i ) {
for ( size_t i = 0 ; i < decrease_axis . size ( ) ; + + i ) {
PADDLE_ENFORCE_EQ ( out_dims [ decrease_axis [ i ] ] , 1 ,
PADDLE_ENFORCE_EQ ( out_dims [ decrease_axis [ i ] ] , 1 ,
" decrease dim should be 1 " ) ;
" decrease dim should be 1 " ) ;
@ -260,19 +237,19 @@ class SliceKernel : public framework::OpKernel<T> {
out - > mutable_data < T > ( context . GetPlace ( ) ) ;
out - > mutable_data < T > ( context . GetPlace ( ) ) ;
auto new_out_dims = out - > dims ( ) ;
auto new_out_dims = out - > dims ( ) ;
auto offsets = Eigen : : array < int , D > ( ) ;
auto offsets = Eigen : : array < int 64_t , D > ( ) ;
auto extents = Eigen : : array < int , D > ( ) ;
auto extents = Eigen : : array < int 64_t , D > ( ) ;
for ( size_t i = 0 ; i < D ; + + i ) {
for ( size_t i = 0 ; i < D ; + + i ) {
offsets [ i ] = 0 ;
offsets [ i ] = 0 ;
extents [ i ] = new_out_dims [ i ] ;
extents [ i ] = new_out_dims [ i ] ;
}
}
int start ;
int 64_t start ;
for ( size_t i = 0 ; i < axes . size ( ) ; + + i ) {
for ( size_t i = 0 ; i < axes . size ( ) ; + + i ) {
start = starts [ i ] ;
start = starts [ i ] ;
if ( start < 0 ) {
if ( start < 0 ) {
start = ( start + in_dims [ axes [ i ] ] ) ;
start = ( start + in_dims [ axes [ i ] ] ) ;
}
}
start = std : : max ( start , 0 ) ;
start = std : : max ( start , static_cast < int64_t > ( 0 ) ) ;
offsets [ axes [ i ] ] = start ;
offsets [ axes [ i ] ] = start ;
}
}
auto in_t =
auto in_t =
@ -325,25 +302,30 @@ class SliceGradKernel : public framework::OpKernel<T> {
auto & place =
auto & place =
* context . template device_context < DeviceContext > ( ) . eigen_device ( ) ;
* context . template device_context < DeviceContext > ( ) . eigen_device ( ) ;
auto axes = context . Attr < std : : vector < int > > ( " axes " ) ;
auto axes = context . Attr < std : : vector < int > > ( " axes " ) ;
auto starts = context . Attr < std : : vector < int > > ( " starts " ) ;
auto ends = context . Attr < std : : vector < int > > ( " ends " ) ;
auto starts_int = context . Attr < std : : vector < int > > ( " starts " ) ;
std : : vector < int64_t > starts ( starts_int . begin ( ) , starts_int . end ( ) ) ;
auto ends_int = context . Attr < std : : vector < int > > ( " ends " ) ;
std : : vector < int64_t > ends ( ends_int . begin ( ) , ends_int . end ( ) ) ;
auto list_new_ends_tensor =
auto list_new_ends_tensor =
context . MultiInput < framework : : Tensor > ( " EndsTensorList " ) ;
context . MultiInput < framework : : Tensor > ( " EndsTensorList " ) ;
auto list_new_starts_tensor =
auto list_new_starts_tensor =
context . MultiInput < framework : : Tensor > ( " StartsTensorList " ) ;
context . MultiInput < framework : : Tensor > ( " StartsTensorList " ) ;
if ( list_new_starts_tensor . size ( ) > 0 ) {
if ( list_new_starts_tensor . size ( ) > 0 ) {
starts = get_new_data_from_tensorlist ( list_new_starts_tensor ) ;
starts = GetDataFromTensorList < int64_t > ( list_new_starts_tensor ) ;
} else if ( context . HasInput ( " StartsTensor " ) ) {
} else if ( context . HasInput ( " StartsTensor " ) ) {
auto * starts_tensor = context . Input < framework : : Tensor > ( " StartsTensor " ) ;
auto * starts_tensor = context . Input < framework : : Tensor > ( " StartsTensor " ) ;
starts = get_new_data_from_tensor ( starts_tensor ) ;
starts = GetDataFromTensor < int64_t > ( starts_tensor ) ;
}
}
if ( list_new_ends_tensor . size ( ) > 0 ) {
if ( list_new_ends_tensor . size ( ) > 0 ) {
ends = get_new_data_from_tensorlist ( list_new_ends_tensor ) ;
ends = GetDataFromTensorList < int64_t > ( list_new_ends_tensor ) ;
} else if ( context . HasInput ( " EndsTensor " ) ) {
} else if ( context . HasInput ( " EndsTensor " ) ) {
auto * ends_tensor = context . Input < framework : : Tensor > ( " EndsTensor " ) ;
auto * ends_tensor = context . Input < framework : : Tensor > ( " EndsTensor " ) ;
ends = get_new_data_from_tensor ( ends_tensor ) ;
ends = GetDataFromTensor < int64_t > ( ends_tensor ) ;
}
}
framework : : Variable * d_input_var =
framework : : Variable * d_input_var =
context . OutputVar ( framework : : GradVarName ( " Input " ) ) ;
context . OutputVar ( framework : : GradVarName ( " Input " ) ) ;
@ -358,12 +340,12 @@ class SliceGradKernel : public framework::OpKernel<T> {
auto * d_input_array = context . Output < framework : : LoDTensorArray > (
auto * d_input_array = context . Output < framework : : LoDTensorArray > (
framework : : GradVarName ( " Input " ) ) ;
framework : : GradVarName ( " Input " ) ) ;
int d_in_size = input_array - > size ( ) ;
int 64_t d_in_size = input_array - > size ( ) ;
d_input_array - > resize ( d_in_size ) ;
d_input_array - > resize ( d_in_size ) ;
// If the input is LoDTensorArray, the rank of input is 1.
// If the input is LoDTensorArray, the rank of input is 1.
// So only use the 0th element of starts.
// So only use the 0th element of starts.
int start = starts [ 0 ] < 0 ? ( starts [ 0 ] + d_in_size ) : starts [ 0 ] ;
int 64_t start = starts [ 0 ] < 0 ? ( starts [ 0 ] + d_in_size ) : starts [ 0 ] ;
start = std : : max ( start , 0 ) ;
start = std : : max ( start , static_cast < int64_t > ( 0 ) ) ;
// set zero
// set zero
platform : : DeviceContextPool & pool =
platform : : DeviceContextPool & pool =
platform : : DeviceContextPool : : Instance ( ) ;
platform : : DeviceContextPool : : Instance ( ) ;
@ -432,22 +414,22 @@ class SliceGradKernel : public framework::OpKernel<T> {
}
}
}
}
auto offsets = Eigen : : array < int , D > ( ) ;
auto offsets = Eigen : : array < int 64_t , D > ( ) ;
auto extents = Eigen : : array < int , D > ( ) ;
auto extents = Eigen : : array < int 64_t , D > ( ) ;
for ( size_t i = 0 ; i < D ; + + i ) {
for ( size_t i = 0 ; i < D ; + + i ) {
offsets [ i ] = 0 ;
offsets [ i ] = 0 ;
extents [ i ] = out_dims [ i ] ;
extents [ i ] = out_dims [ i ] ;
}
}
int start ;
int 64_t start ;
for ( size_t i = 0 ; i < axes . size ( ) ; + + i ) {
for ( size_t i = 0 ; i < axes . size ( ) ; + + i ) {
start = starts [ i ] ;
start = starts [ i ] ;
if ( start < 0 ) {
if ( start < 0 ) {
start = ( start + in_dims [ axes [ i ] ] ) ;
start = ( start + in_dims [ axes [ i ] ] ) ;
}
}
start = std : : max ( start , 0 ) ;
start = std : : max ( start , static_cast < int64_t > ( 0 ) ) ;
offsets [ axes [ i ] ] = start ;
offsets [ axes [ i ] ] = start ;
}
}
Eigen : : array < std : : pair < int , in t> , D > paddings ;
Eigen : : array < std : : pair < int 64_t , in t64_ t> , D > paddings ;
for ( size_t i = 0 ; i < paddings . size ( ) ; + + i ) {
for ( size_t i = 0 ; i < paddings . size ( ) ; + + i ) {
paddings [ i ] . first = offsets [ i ] ;
paddings [ i ] . first = offsets [ i ] ;
paddings [ i ] . second = ( in_dims [ i ] - out_dims [ i ] ) - offsets [ i ] ;
paddings [ i ] . second = ( in_dims [ i ] - out_dims [ i ] ) - offsets [ i ] ;