| 25 | namespace singa { |
| 26 | |
| 27 | BatchNormHandle::BatchNormHandle(const float momentum, const Tensor& input) { |
| 28 | factor = momentum; |
| 29 | batchsize = input.shape(0); |
| 30 | channels = input.shape(1); |
| 31 | if (input.nDim() == 4u) { |
| 32 | height = input.shape().at(2); |
| 33 | width = input.shape().at(3); |
| 34 | is_2d = false; |
| 35 | } else if (input.nDim() == 2u) { |
| 36 | height = 1; |
| 37 | width = 1; |
| 38 | is_2d = true; |
| 39 | } else { |
| 40 | LOG(FATAL) << "The dimension of input should either be 4D or 2D."; |
| 41 | } |
| 42 | |
| 43 | #ifdef USE_DNNL |
| 44 | if (input.device()->lang() == kCpp) { |
| 45 | use_dnnl = true; |
| 46 | epsilon = 1e-5f; |
| 47 | x_dims = dnnl::memory::dims(input.shape().begin(), input.shape().end()); |
| 48 | |
| 49 | // support f32 only |
| 50 | auto dtype_ = memory::data_type::f32; |
| 51 | memory::format_tag format_tag_ = get_dnnl_format_tag(input); |
| 52 | x_md = dnnl::memory::desc({x_dims}, dtype_, format_tag_); |
| 53 | |
| 54 | // add to |
| 55 | bn_fwd_training_d = new dnnl::batch_normalization_forward::desc( |
| 56 | dnnl::prop_kind::forward_training, x_md, epsilon, |
| 57 | dnnl::normalization_flags::use_scale_shift); |
| 58 | |
| 59 | auto eng = input.device()->context(0)->dnnl_engine; |
| 60 | bn_fwd_training_pd = new dnnl::batch_normalization_forward::primitive_desc( |
| 61 | *bn_fwd_training_d, eng); |
| 62 | } |
| 63 | #endif // USE_DNNL |
| 64 | }; |
| 65 | |
| 66 | BatchNormHandle::~BatchNormHandle() { |
| 67 | #ifdef USE_DNNL |