You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

conv_pooling.cpp 5.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**
  2. * \file dnn/src/naive/convpooling/conv_pooling.cpp
  3. * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  4. *
  5. * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
  6. *
  7. * Unless required by applicable law or agreed to in writing,
  8. * software distributed under the License is distributed on an
  9. * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. */
  11. #include "src/naive/convpooling/opr_impl.h"
  12. #include "src/naive/handle.h"
  13. #include "src/common/utils.h"
  14. #include "megdnn/dtype.h"
  15. #include <cstring>
  16. namespace megdnn {
  17. namespace naive {
  18. ConvPoolingForwardImpl::ConvPoolingForwardImpl(Handle *handle):
  19. ConvPoolingForward(handle) {
  20. convFwd = new ConvolutionForwardImpl(this->handle());
  21. poolFwd = new PoolingForwardImpl(this->handle());
  22. return;
  23. }
  24. void ConvPoolingForwardImpl::setParamOfSublayers() {
  25. Convolution::Param &cparam = convFwd->param();
  26. cparam.pad_h = this->param().conv_pad_h;
  27. cparam.pad_w = this->param().conv_pad_w;
  28. cparam.stride_h = this->param().conv_stride_h;
  29. cparam.stride_w = this->param().conv_stride_w;
  30. // Alternative: Convolution::Mode::CONVOLUTION
  31. if(this->param().convMode == ConvPoolingBase::Param::ConvMode::CONVOLUTION) {
  32. cparam.mode = Convolution::Param::Mode::CONVOLUTION;
  33. } else {
  34. cparam.mode = Convolution::Param::Mode::CROSS_CORRELATION;
  35. }
  36. Pooling::Param &pparam = poolFwd->param();
  37. pparam.window_h = this->param().pool_shape_h;
  38. pparam.window_w = this->param().pool_shape_w;
  39. pparam.stride_h = this->param().pool_stride_h;
  40. pparam.stride_w = this->param().pool_stride_w;
  41. pparam.pad_h = this->param().pool_pad_h;
  42. pparam.pad_w = this->param().pool_pad_w;
  43. if(this->param().poolMode == ConvPoolingBase::Param::PoolMode::AVERAGE) {
  44. pparam.mode = PoolingBase::Param::Mode::AVERAGE;
  45. } else {
  46. pparam.mode = PoolingBase::Param::Mode::MAX;
  47. }
  48. }
  49. void ConvPoolingForwardImpl::check_layout(const TensorLayout & src,
  50. const TensorLayout & filter,
  51. const TensorLayout & bias,
  52. TensorLayout & dst,
  53. size_t /*workspace_limit_in_bytes*/) {
  54. TensorLayout dst_expected;
  55. this->deduce_layout(src, filter, bias, dst_expected);
  56. megdnn_assert_eq_layout(dst_expected, dst);
  57. megdnn_assert(bias.shape[1] == dst.shape[1]);
  58. megdnn_assert(dst.shape[1] == filter.shape[0]);
  59. //megdnn_assert_eq_layout(workspace_expected, workspace);
  60. return;
  61. }
  62. void ConvPoolingForwardImpl::deduce_layout(
  63. const TensorLayout &srcl,
  64. const TensorLayout &filterl,
  65. const TensorLayout & /*biasl*/,
  66. TensorLayout &dstl) {
  67. setParamOfSublayers();
  68. convFwd->deduce_layout(srcl, filterl, conv_dst_layout);
  69. poolFwd->deduce_layout(conv_dst_layout, dstl);
  70. }
  71. size_t ConvPoolingForwardImpl::get_workspace_in_bytes(const TensorLayout & src,
  72. const TensorLayout & filter,
  73. const TensorLayout & bias,
  74. const TensorLayout & /*dst*/) {
  75. // Worksapce contains the output of convolution layer in the workspace.
  76. TensorLayout tmp_layout;
  77. this->deduce_layout(src, filter, bias, tmp_layout);
  78. return conv_dst_layout.total_nr_elems() * sizeof(float);
  79. }
  80. void ConvPoolingForwardImpl::exec(const _megdnn_in TensorND src,
  81. const _megdnn_in TensorND filter,
  82. const _megdnn_in TensorND bias,
  83. _megdnn_out TensorND dst,
  84. _megdnn_out Workspace workspace) {
  85. Workspace empty_wsp;
  86. TensorND conv_dst((float*)(workspace.raw_ptr), conv_dst_layout);
  87. //convFwd->check_layout(src.layout, filter.layout, workspace.layout, empty_wsp.layout);
  88. check_layout(src.layout, filter.layout, bias.layout, dst.layout, workspace.size);
  89. convFwd->exec(src, filter, conv_dst, nullptr, empty_wsp);
  90. // calculate bias
  91. int conv_dst_batch = conv_dst.layout.shape[0];
  92. int conv_dst_channel = conv_dst.layout.shape[1];
  93. int chann_stride = conv_dst.layout.shape[2] * conv_dst.layout.shape[3];
  94. float *conv_dst_ptr = conv_dst.ptr<float>();
  95. for(int batch = 0; batch < conv_dst_batch; ++batch) {
  96. for(int chan = 0; chan < conv_dst_channel; ++chan) {
  97. float bias_val = bias.ptr<float>()[chan];
  98. for(int i = 0; i < chann_stride; ++i, ++conv_dst_ptr) {
  99. conv_dst_ptr[0] += bias_val;
  100. }
  101. }
  102. }
  103. // calculate nonline
  104. nonlineFwd = new ElemwiseForwardImpl(this->handle());
  105. switch(this->param().nonlineMode) {
  106. case Param::NonlineMode::RELU:
  107. nonlineFwd->param().mode = Elemwise::Param::Mode::RELU;
  108. nonlineFwd->exec({conv_dst}, conv_dst);
  109. break;
  110. case Param::NonlineMode::SIGMOID:
  111. nonlineFwd->param().mode = Elemwise::Param::Mode::SIGMOID;
  112. nonlineFwd->exec({conv_dst}, conv_dst);
  113. break;
  114. case Param::NonlineMode::IDENTITY:
  115. break;
  116. default:
  117. break;
  118. }
  119. poolFwd->exec(conv_dst, dst, empty_wsp);
  120. }
  121. } // namespace naive
  122. } // namespace megdnn
  123. // vim: syntax=cpp.doxygen

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台