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.

imperative.cpp 6.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * \file imperative/src/test/imperative.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 "./helper.h"
  12. #include "megbrain/opr/basic_arith.h"
  13. #include "megbrain/opr/basic_arith_wrapper.h"
  14. #include "megbrain/opr/dnn/convolution.h"
  15. #include "megbrain/opr/tensor_manip.h"
  16. #include "megbrain/opr/dnn/batch_norm.h"
  17. #include "megbrain/opr/utility.h"
  18. #include "megbrain/imperative/blob_manager.h"
  19. #include "megbrain/imperative/ops/opr_attr.h"
  20. #include "megbrain/comp_node_env.h"
  21. using namespace mgb;
  22. using namespace cg;
  23. using namespace imperative;
  24. TEST(TestImperative, APlusB) {
  25. auto op = OprAttr::make("Elemwise");
  26. auto&& attr = op->cast_final_safe<OprAttr>();
  27. using Param = opr::Elemwise::Param;
  28. Param param{Param::Mode::ADD};
  29. attr.param.write_pod(param);
  30. OprChecker(op).run({TensorShape{42}, TensorShape{42}});
  31. }
  32. TEST(TestImperative, Convolution) {
  33. auto op = OprAttr::make("ConvolutionV2");
  34. auto&& attr = op->cast_final_safe<OprAttr>();
  35. using Param = opr::Convolution::Param;
  36. using Policy = opr::Convolution::ExecutionPolicy;
  37. Param param{Param::Mode::CONVOLUTION};
  38. Policy policy{Policy::Strategy::HEURISTIC};
  39. attr.param.write_pod(param);
  40. attr.param.write_pod(policy);
  41. size_t N = 4, IC = 3, OC = 8, FH = 3, FW = 3, IH = 16, IW = 16;
  42. OprChecker(op).run({TensorShape{N, IC, IH, IW}, TensorShape{OC, IC, FH, FW}});
  43. }
  44. TEST(TestImperative, Reduce) {
  45. auto op = OprAttr::make("ReduceV2");
  46. auto&& attr = op->cast_final_safe<OprAttr>();
  47. using Param = opr::Reduce::Param;
  48. Param param{Param::Mode::SUM_SQR};
  49. attr.param.write_pod(param);
  50. HostTensorND one{CompNode::load("xpu0"), {{1}, dtype::Int32()}};
  51. one.ptr<int>()[0] = 1;
  52. OprChecker(op).run({TensorShape{2, 3, 4}, one});
  53. }
  54. TEST(TestImperative, BatchNorm) {
  55. auto op = OprAttr::make("BatchNorm");
  56. auto&& attr = op->cast_final_safe<OprAttr>();
  57. using Param = opr::BatchNorm::Param;
  58. Param param;
  59. param.param_dim = Param::ParamDim::DIM_1C11;
  60. param.avg_factor = 0.999;
  61. attr.param.write_pod(param);
  62. size_t N=2, C=3, H=5, W=5;
  63. OprChecker(op).run({
  64. TensorShape{N, C, H, W},
  65. TensorShape{1, C, 1, 1},
  66. TensorShape{1, C, 1, 1},
  67. TensorShape{1, C, 1, 1},
  68. TensorShape{1, C, 1, 1}
  69. });
  70. }
  71. TEST(TestImperative, Concat) {
  72. REQUIRE_XPU(2);
  73. OprAttr::Param param;
  74. param.write_pod(megdnn::param::Axis(0));
  75. OperatorNodeConfig config{CompNode::load("xpu1")};
  76. OprChecker(OprAttr::make("Concat", param, config))
  77. .run({TensorShape{200, 300}, TensorShape{300, 300}});
  78. }
  79. TEST(TestImperative, Split) {
  80. OprAttr::Param param;
  81. param.write_pod(megdnn::param::Axis(0));
  82. auto op = OprAttr::make("Split", param, OperatorNodeConfig{});
  83. auto cn = CompNode::load("xpu0");
  84. HostTensorND s1{cn, {{1}, dtype::Int32()}};
  85. s1.ptr<int>()[0] = 20;
  86. HostTensorND s2{cn, {{1}, dtype::Int32()}};
  87. s2.ptr<int>()[0] = 80;
  88. OprChecker(op).run({TensorShape{100}, s1, s2});
  89. }
  90. #if MGB_CUDA && MGB_ENABLE_EXCEPTION
  91. void run_graph(size_t mem_reserved, bool enable_defrag) {
  92. CompNode::try_coalesce_all_free_memory();
  93. CompNode::finalize();
  94. auto cn = CompNode::load("gpux");
  95. cn.sync(); // wait for async init to finish
  96. BlobManager::inst() -> set_enable(enable_defrag);
  97. HostTensorGenerator<> gen;
  98. using TensorPtr = std::shared_ptr<Tensor>;
  99. TensorPtr ptr_a[100];
  100. size_t unit_size = mem_reserved / (100.5 * 4);
  101. auto host_a = gen({unit_size});
  102. for(int i = 0; i < 100; ++i) {
  103. ptr_a[i] = Tensor::make(*host_a);
  104. }
  105. // free half
  106. for(int i = 0; i < 100; i += 2) {
  107. ptr_a[i].reset();
  108. }
  109. auto op = OprAttr::make("Elemwise");
  110. auto&& attr = op->cast_final_safe<OprAttr>();
  111. using Param = opr::Elemwise::Param;
  112. Param param{Param::Mode::MUL};
  113. attr.param.write_pod(param);
  114. auto out = OpDef::apply_on_physical_tensor(*op, {ptr_a[1], ptr_a[99]}).at(0);
  115. // value before defrag
  116. HostTensorND host_out_before;
  117. host_out_before.copy_from(out->dev_tensor()).sync();
  118. // make defrag work
  119. auto e = Tensor::make(*gen({unit_size * 10}));
  120. // value after defrag
  121. HostTensorND host_out_after;
  122. host_out_after.copy_from(out->dev_tensor()).sync();
  123. // make sure defragment do not change the value
  124. for (size_t i = 0; i < unit_size; ++ i) {
  125. ASSERT_EQ(host_out_before.ptr<float>()[i], host_out_after.ptr<float>()[i]);
  126. }
  127. }
  128. TEST(TestImperative, Defragment) {
  129. #if WIN32
  130. //! FIXME, finalize on CUDA windows will be strip as windows CUDA101 DLL
  131. //! issue
  132. return;
  133. #endif
  134. REQUIRE_GPU(1);
  135. CompNode::load("gpux").activate();
  136. size_t reserve;
  137. {
  138. size_t free, tot;
  139. MGB_CUDA_CHECK(cudaMemGetInfo(&free, &tot));
  140. reserve = free * 0.92;
  141. }
  142. auto reserve_setting = ssprintf("b:%zu", reserve);
  143. auto do_run = [reserve]() {
  144. ASSERT_THROW(run_graph(reserve, false), MemAllocError);
  145. run_graph(reserve, true);
  146. };
  147. // reserve memory explicitly to avoid uncontrollable factors
  148. constexpr const char* KEY = "MGB_CUDA_RESERVE_MEMORY";
  149. auto old_value = getenv(KEY);
  150. setenv(KEY, reserve_setting.c_str(), 1);
  151. MGB_TRY { do_run(); }
  152. MGB_FINALLY(
  153. if (old_value) { setenv(KEY, old_value, 1); } else {
  154. unsetenv(KEY);
  155. } CompNode::try_coalesce_all_free_memory();
  156. CompNode::finalize(););
  157. }
  158. #endif // MGB_CUDA && MGB_ENABLE_EXCEPTION
  159. // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}

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