@ -6,6 +6,9 @@
# include "layers_common.hpp"
# include "cpu_kernels/fast_norm.hpp"
// CANN backend
# include "../op_cann.hpp"
namespace cv { namespace dnn {
class LayerNormLayerImpl CV_FINAL : public LayerNormLayer
@ -22,7 +25,8 @@ public:
virtual bool supportBackend ( int backendId ) CV_OVERRIDE
{
return backendId = = DNN_BACKEND_OPENCV ;
return backendId = = DNN_BACKEND_OPENCV | |
( backendId = = DNN_BACKEND_CANN & & axis ! = - 1 ) ; // axis=-1 not supported due to 1d mat shape problem
}
virtual bool getMemoryShapes ( const std : : vector < MatShape > & inputs ,
@ -90,6 +94,59 @@ public:
fastNorm ( input , scale , output , epsilon , static_cast < size_t > ( axis ) ) ;
}
}
# ifdef HAVE_CANN
virtual Ptr < BackendNode > initCann ( const std : : vector < Ptr < BackendWrapper > > & inputs ,
const std : : vector < Ptr < BackendWrapper > > & outputs ,
const std : : vector < Ptr < BackendNode > > & nodes ) CV_OVERRIDE {
CV_CheckEQ ( inputs . size ( ) , static_cast < size_t > ( 3 ) , " LayerNorm/CANN: requires three input wrappers " ) ;
CV_CheckEQ ( nodes . size ( ) , static_cast < size_t > ( 3 ) , " LayerNorm/CANN: requires three input nodes " ) ;
auto input_tensor_wrapper = inputs [ 0 ] . dynamicCast < CannBackendWrapper > ( ) ;
auto input_tensor_desc = input_tensor_wrapper - > getTensorDesc ( ) ;
CV_CheckNE ( axis , static_cast < int > ( input_tensor_desc - > GetShape ( ) . GetDimNum ( ) - 1 ) , " LayerNorm: CANN does not support axis set as last axis due to 1D mat compatibility issue " ) ;
auto scale_tensor_wrapper = inputs [ 1 ] . dynamicCast < CannBackendWrapper > ( ) ;
auto scale_tensor_desc = scale_tensor_wrapper - > getTensorDesc ( ) ;
auto bias_tensor_wrapper = inputs [ 2 ] . dynamicCast < CannBackendWrapper > ( ) ;
auto bias_tensor_desc = bias_tensor_wrapper - > getTensorDesc ( ) ;
auto last_node = nodes [ 0 ] . dynamicCast < CannBackendNode > ( ) - > getOp ( ) ;
auto scale_node = nodes [ 1 ] . dynamicCast < CannBackendNode > ( ) - > getOp ( ) ;
auto bias_node = nodes [ 2 ] . dynamicCast < CannBackendNode > ( ) - > getOp ( ) ;
auto op = std : : make_shared < ge : : op : : LayerNorm > ( name ) ;
// set attrs
op - > set_attr_begin_norm_axis ( axis ) ;
op - > set_attr_begin_params_axis ( axis ) ;
op - > set_attr_epsilon ( epsilon ) ;
// set inputs
// set inputs : x
op - > set_input_x_by_name ( * last_node , input_tensor_wrapper - > name . c_str ( ) ) ;
op - > update_input_desc_x ( * input_tensor_desc ) ;
// set inputs : gamma
op - > set_input_gamma_by_name ( * scale_node , scale_tensor_wrapper - > name . c_str ( ) ) ;
op - > update_input_desc_gamma ( * scale_tensor_desc ) ;
// set inputs : beta
op - > set_input_beta_by_name ( * bias_node , bias_tensor_wrapper - > name . c_str ( ) ) ;
op - > update_input_desc_beta ( * bias_tensor_desc ) ;
// set outputs
auto output_desc_y = std : : make_shared < ge : : TensorDesc > ( ge : : Shape ( ) , ge : : FORMAT_NCHW , ge : : DT_FLOAT ) ;
op - > update_output_desc_y ( * output_desc_y ) ;
auto output_desc_mean = std : : make_shared < ge : : TensorDesc > ( ge : : Shape ( ) , ge : : FORMAT_NCHW , ge : : DT_FLOAT ) ;
op - > update_output_desc_mean ( * output_desc_mean ) ;
auto output_desc_var = std : : make_shared < ge : : TensorDesc > ( ge : : Shape ( ) , ge : : FORMAT_NCHW , ge : : DT_FLOAT ) ;
op - > update_output_desc_variance ( * output_desc_var ) ;
return Ptr < BackendNode > ( new CannBackendNode ( op ) ) ;
}
# endif // HAVE_CANN
} ;
Ptr < LayerNormLayer > LayerNormLayer : : create ( const LayerParams & params )