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.

reduce.cpp 9.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * \file dnn/test/fallback/reduce.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 "test/fallback/fixture.h"
  12. #include "megdnn/oprs.h"
  13. #include "test/common/checker.h"
  14. #include "test/common/task_record_check.h"
  15. #include "test/common/tensor.h"
  16. #include "test/common/workspace_wrapper.h"
  17. using namespace megdnn;
  18. using namespace test;
  19. TEST_F(FALLBACK, REDUCE) {
  20. using Param = Reduce::Param;
  21. using Mode = Param::Mode;
  22. using DataType = Param::DataType;
  23. Checker<Reduce> checker(handle());
  24. struct Config {
  25. Param param;
  26. DType dtype;
  27. TensorShape shape;
  28. Config(Param param, DType dtype, TensorShape shape)
  29. : param(param), dtype(dtype), shape(shape) {}
  30. };
  31. std::vector<Config> configs;
  32. // general
  33. for (auto mode :
  34. {Mode::SUM, Mode::MEAN, Mode::SUM_SQR, Mode::PRODUCT, Mode::MIN, Mode::MAX})
  35. for (auto dtype : std::vector<DType>{
  36. dtype::Float16(), dtype::Float32(), dtype::Int32(), dtype::Int16(),
  37. dtype::Int8(), dtype::Uint8()})
  38. for (int32_t axis : {0, 1, 2, 3}) {
  39. TensorShape shape{2, 3, 20, 5};
  40. Param param(mode, axis);
  41. Config config(param, dtype, shape);
  42. configs.push_back(config);
  43. if (dtype.category() == DTypeCategory::FLOAT) {
  44. Param param(mode, axis, DataType::FLOAT_O16xC32);
  45. Config config(param, dtype, shape);
  46. configs.push_back(config);
  47. param.data_type = DataType::FLOAT_O32xC32;
  48. config = Config(param, dtype, shape);
  49. configs.push_back(config);
  50. } else if (dtype == dtype::Int32()) {
  51. Param param(mode, axis, DataType::FLOAT_O32xC32);
  52. Config config(param, dtype, shape);
  53. configs.push_back(config);
  54. }
  55. }
  56. // large (ABC) -> (A1C) case
  57. for (auto mode : {Mode::SUM_SQR})
  58. for (auto dtype : std::vector<DType>{dtype::Int32()})
  59. for (int32_t axis : {0, 1, 2, 3}) {
  60. TensorShape shape{2, 3, 10000, 5};
  61. Param param(mode, axis);
  62. Config config(param, dtype, shape);
  63. configs.push_back(config);
  64. }
  65. // large (AB) -> (A1) case
  66. for (auto mode : {Mode::SUM_SQR})
  67. for (auto dtype : std::vector<DType>{dtype::Int32()})
  68. for (int32_t axis : {0, 1, 2, 3}) {
  69. TensorShape shape{2, 3, 5, 10000};
  70. Param param(mode, axis);
  71. Config config(param, dtype, shape);
  72. configs.push_back(config);
  73. }
  74. {
  75. // large reduce_mean for O16C32
  76. TensorShape shape{1, 65536, 5};
  77. Param param(Mode::MEAN, 1, DataType::FLOAT_O16xC32);
  78. Config config(param, dtype::Float16(), shape);
  79. configs.push_back(config);
  80. }
  81. for (auto&& config : configs) {
  82. auto&& dtype = config.dtype;
  83. auto&& param = config.param;
  84. auto&& mode = config.param.mode;
  85. auto&& shape = config.shape;
  86. auto&& data_type = config.param.data_type;
  87. // when input/output both float16, the internal compute is float16, mode
  88. // is SUM or SUM_SQR, need set epsilon to 1e-2 to pass test
  89. if (dtype == dtype::Float16() && data_type == DataType::DEFAULT &&
  90. (mode == Mode::SUM || mode == Mode::SUM_SQR)) {
  91. checker.set_epsilon(1e-2);
  92. }
  93. checker.set_dtype(0, dtype).set_param(param).execs({shape, {}});
  94. }
  95. {
  96. static size_t N = 1 << 26;
  97. {
  98. // cpu vs naive
  99. Checker<Reduce> checker(handle());
  100. Reduce::Param param;
  101. param.axis = 0;
  102. UniformFloatRNG rng(1, 1);
  103. checker.set_param(param);
  104. checker.set_rng(0, &rng);
  105. checker.execs({{N}, {}});
  106. }
  107. {
  108. // naive vs groundtruth
  109. TensorLayout layoutN(TensorShape{N}, dtype::Float32()),
  110. layout1(TensorShape{1}, dtype::Float32());
  111. auto handle = this->handle();
  112. Tensor<float> src(handle, layoutN), dst(handle, layout1);
  113. float* ptr = src.ptr();
  114. for (size_t i = 0; i < N; ++i)
  115. ptr[i] = 1;
  116. auto opr = handle->create_operator<Reduce>();
  117. opr->param().axis = 0;
  118. auto wsize = opr->get_workspace_in_bytes(layoutN, layout1);
  119. WorkspaceWrapper workspace(handle, wsize);
  120. opr->exec(src.tensornd(), dst.tensornd(), workspace.workspace());
  121. megdnn_sync(handle);
  122. ASSERT_EQ(N, dst.ptr()[0]);
  123. }
  124. }
  125. }
  126. TEST_F(FALLBACK, REDUCE_RECORD) {
  127. using Param = Reduce::Param;
  128. using Mode = Param::Mode;
  129. using DataType = Param::DataType;
  130. TaskRecordChecker<Reduce> checker(1);
  131. struct Config {
  132. Param param;
  133. DType dtype;
  134. TensorShape shape;
  135. Config(Param param, DType dtype, TensorShape shape)
  136. : param(param), dtype(dtype), shape(shape) {}
  137. };
  138. std::vector<Config> configs;
  139. // general
  140. for (auto mode :
  141. {Mode::SUM, Mode::MEAN, Mode::SUM_SQR, Mode::PRODUCT, Mode::MIN, Mode::MAX})
  142. for (auto dtype : std::vector<DType>{
  143. dtype::Float16(), dtype::Float32(), dtype::Int32(), dtype::Int16(),
  144. dtype::Int8(), dtype::Uint8()})
  145. for (int32_t axis : {0, 1, 2, 3}) {
  146. TensorShape shape{2, 3, 20, 5};
  147. Param param(mode, axis);
  148. Config config(param, dtype, shape);
  149. configs.push_back(config);
  150. if (dtype.category() == DTypeCategory::FLOAT) {
  151. Param param(mode, axis, DataType::FLOAT_O16xC32);
  152. Config config(param, dtype, shape);
  153. configs.push_back(config);
  154. param.data_type = DataType::FLOAT_O32xC32;
  155. config = Config(param, dtype, shape);
  156. configs.push_back(config);
  157. } else if (dtype == dtype::Int32()) {
  158. Param param(mode, axis, DataType::FLOAT_O32xC32);
  159. Config config(param, dtype, shape);
  160. configs.push_back(config);
  161. }
  162. }
  163. // large (ABC) -> (A1C) case
  164. for (auto mode : {Mode::SUM_SQR})
  165. for (auto dtype : std::vector<DType>{dtype::Int32()})
  166. for (int32_t axis : {0, 1, 2, 3}) {
  167. TensorShape shape{2, 3, 10000, 5};
  168. Param param(mode, axis);
  169. Config config(param, dtype, shape);
  170. configs.push_back(config);
  171. }
  172. // large (AB) -> (A1) case
  173. for (auto mode : {Mode::SUM_SQR})
  174. for (auto dtype : std::vector<DType>{dtype::Int32()})
  175. for (int32_t axis : {0, 1, 2, 3}) {
  176. TensorShape shape{2, 3, 5, 10000};
  177. Param param(mode, axis);
  178. Config config(param, dtype, shape);
  179. configs.push_back(config);
  180. }
  181. {
  182. // large reduce_mean for O16C32
  183. TensorShape shape{1, 65536, 5};
  184. Param param(Mode::MEAN, 1, DataType::FLOAT_O16xC32);
  185. Config config(param, dtype::Float16(), shape);
  186. configs.push_back(config);
  187. }
  188. for (auto&& config : configs) {
  189. auto&& dtype = config.dtype;
  190. auto&& param = config.param;
  191. auto&& mode = config.param.mode;
  192. auto&& shape = config.shape;
  193. auto&& data_type = config.param.data_type;
  194. // when input/output both float16, the internal compute is float16, mode
  195. // is SUM or SUM_SQR, need set epsilon to 1e-2 to pass test
  196. if (dtype == dtype::Float16() && data_type == DataType::DEFAULT &&
  197. (mode == Mode::SUM || mode == Mode::SUM_SQR)) {
  198. checker.set_epsilon(1e-2);
  199. }
  200. checker.set_dtype(0, dtype).set_param(param).execs({shape, {}});
  201. }
  202. {
  203. static size_t N = 1 << 26;
  204. {
  205. // cpu vs naive
  206. TaskRecordChecker<Reduce> checker(1);
  207. Reduce::Param param;
  208. param.axis = 0;
  209. UniformFloatRNG rng(1, 1);
  210. checker.set_param(param);
  211. checker.set_rng(0, &rng);
  212. checker.execs({{N}, {}});
  213. }
  214. {
  215. // naive vs groundtruth
  216. TensorLayout layoutN(TensorShape{N}, dtype::Float32()),
  217. layout1(TensorShape{1}, dtype::Float32());
  218. auto handle = this->handle();
  219. Tensor<float> src(handle, layoutN), dst(handle, layout1);
  220. float* ptr = src.ptr();
  221. for (size_t i = 0; i < N; ++i)
  222. ptr[i] = 1;
  223. auto opr = handle->create_operator<Reduce>();
  224. opr->param().axis = 0;
  225. auto wsize = opr->get_workspace_in_bytes(layoutN, layout1);
  226. WorkspaceWrapper workspace(handle, wsize);
  227. opr->exec(src.tensornd(), dst.tensornd(), workspace.workspace());
  228. megdnn_sync(handle);
  229. ASSERT_EQ(N, dst.ptr()[0]);
  230. }
  231. }
  232. }
  233. // vim: syntax=cpp.doxygen