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.

tensor_sanity_check.cpp 4.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /**
  2. * \file src/core/impl/imperative/tensor_sanity_check.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 "megbrain/imperative/tensor_sanity_check.h"
  12. #include "./op_trait.h"
  13. namespace mgb {
  14. namespace imperative {
  15. TensorChecksumCalc::ChecksumResult TensorChecksumCalc::calc(TensorPtr ptr) {
  16. auto&& dt = ptr->dev_tensor();
  17. if (!dt.layout().total_nr_elems()) {
  18. static ChecksumResult empty_checksum;
  19. return empty_checksum;
  20. }
  21. auto span = dt.layout().span();
  22. megdnn::TensorND tensor;
  23. tensor.raw_ptr = dt.raw_ptr() + span.low_byte;
  24. tensor.layout.init_contiguous_stride({span.dist_byte()});
  25. tensor.layout.dtype = dtype::Byte();
  26. DeviceTensorStorage* workspace;
  27. {
  28. MGB_LOCK_GUARD(m_workspace_mtx);
  29. workspace = &m_workspace[std::this_thread::get_id()]
  30. .storage[ptr->comp_node()];
  31. }
  32. auto comp_node = ptr->comp_node();
  33. comp_node.activate();
  34. auto opr = opr::intl::get_megdnn_global_opr<megdnn::Checksum>(comp_node);
  35. auto workspace_reqsize = opr->get_workspace_in_bytes(tensor.layout);
  36. workspace->comp_node(ptr->comp_node()).ensure_size(workspace_reqsize);
  37. megdnn::Workspace mwk;
  38. if (workspace_reqsize)
  39. mwk = {workspace->ptr(), workspace_reqsize};
  40. return opr->exec(tensor, mwk);
  41. }
  42. class TensorSanityCheckImpl {
  43. public:
  44. std::vector<std::tuple<OpTrait*, std::unique_ptr<ApplyOnPhysicalTensor>>>
  45. hook_list;
  46. std::unordered_map<TensorPtr, TensorChecksumCalc::ChecksumResult>
  47. tensor2chksum; // TODO: may increase device memory overhead
  48. TensorSanityCheckImpl() {
  49. m_calc = std::make_unique<TensorChecksumCalc>();
  50. }
  51. bool check(TensorPtr p);
  52. private:
  53. std::unique_ptr<TensorChecksumCalc> m_calc;
  54. };
  55. bool TensorSanityCheckImpl::check(TensorPtr p) {
  56. auto&& it = tensor2chksum.find(p);
  57. auto&& chksum = m_calc->calc(p);
  58. if (it == tensor2chksum.end()) {
  59. tensor2chksum[p] = chksum;
  60. return true;
  61. }
  62. return it->second == chksum;
  63. }
  64. void TensorSanityCheck::enable() {
  65. CompNode::sync_all();
  66. OpTrait::for_each_trait([this](OpTrait& trait) {
  67. auto backup = std::make_unique<ApplyOnPhysicalTensor>(
  68. std::move(trait.apply_on_physical_tensor));
  69. trait.apply_on_physical_tensor = [this, backup = backup.get()] (
  70. const OpDef& def, const SmallVector<TensorPtr>& inputs) {
  71. for (auto&& i: inputs) {
  72. if (!m_checker->check(i)) {
  73. mgb_throw(TensorChecksumCalc::Error,
  74. "tensor modified before exec %s", print_op(def).c_str());
  75. }
  76. }
  77. auto output = (*backup)(def, inputs);
  78. for (auto&& i: output) {
  79. mgb_assert(m_checker->check(i));
  80. }
  81. for (auto&& i: inputs) {
  82. if (!m_checker->check(i)) {
  83. mgb_throw(TensorChecksumCalc::Error,
  84. "tensor modified after exec %s", print_op(def).c_str());
  85. }
  86. }
  87. return output;
  88. };
  89. m_checker->hook_list.push_back({&trait, std::move(backup)});
  90. });
  91. }
  92. void TensorSanityCheck::disable() {
  93. for (auto&& hook : m_checker->hook_list) {
  94. std::get<0>(hook)->apply_on_physical_tensor =
  95. std::move(*std::get<1>(hook));
  96. }
  97. m_checker->tensor2chksum.clear();
  98. m_checker->hook_list.clear();
  99. }
  100. TensorSanityCheck::TensorSanityCheck() {
  101. m_checker = std::make_unique<TensorSanityCheckImpl>();
  102. }
  103. TensorSanityCheck::~TensorSanityCheck () {
  104. }
  105. std::string TensorSanityCheck::print_op(const OpDef& def){
  106. auto* opr_attr = def.try_cast_final<const OprAttr>();
  107. if(opr_attr){
  108. return std::string("OprAttr:") + opr_attr->type;
  109. }
  110. return def.dyn_typeinfo()->name;
  111. }
  112. } // namespace imperative
  113. } // namespace mgb

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