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.

dispatch.cpp 2.6 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /**
  2. * \file imperative/src/impl/dispatch.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/dispatch.h"
  12. #include "megbrain/imperative/utils/debug.h"
  13. #include "megbrain/imperative/utils/helper.h"
  14. #include "megbrain/imperative/utils/map.h"
  15. #include "megbrain/imperative/utils/stats.h"
  16. namespace mgb {
  17. namespace imperative {
  18. ValueRefList apply(const Operator& op, Span<ValueRef> inputs) {
  19. auto& context = Transformation::get_context();
  20. size_t& depth = context.next_transformation;
  21. // TODO: add fallback transformation
  22. bool fallback = depth >= context.transformations.size();
  23. if (mgb_unlikely(fallback)) {
  24. return op.fallback(inputs);
  25. } else {
  26. auto& transformation = *context.transformations[depth++];
  27. CleanupGuard _{[&] { --depth; }};
  28. return transformation.apply_transformation(op, inputs);
  29. }
  30. }
  31. ValueRefList apply(const OpDef& def, Span<ValueRef> inputs) {
  32. return imperative::apply(ApplyOp{def}, inputs);
  33. }
  34. ValueRefList apply(const Subgraph& graph, Span<ValueRef> inputs) {
  35. auto apply_functor = [](std::shared_ptr<OpDef> op, Span<ValueRef> inputs, size_t) {
  36. auto outputs = imperative::apply(*op, inputs);
  37. return SmallVector<ValueRef>(outputs.begin(), outputs.end());
  38. };
  39. auto make_const = [](TensorPtr constant) -> ValueRef {
  40. auto host_value = constant->get_value();
  41. auto device_value = constant->dev_tensor();
  42. mgb_assert(
  43. host_value.layout().is_contiguous() &&
  44. device_value.layout().is_contiguous());
  45. ValueShape shape;
  46. // FIXME: assume Tensor with shape {1} is scalar
  47. if (!constant->shape().is_scalar()) {
  48. shape = ValueShape::from(constant->shape());
  49. }
  50. return imperative::apply(
  51. CreateTensor(
  52. CreateTensor::Const, constant->comp_node(), constant->dtype(),
  53. shape),
  54. HostStorage::make(host_value.storage()),
  55. DeviceStorage::make(device_value.storage()))[0];
  56. };
  57. auto outputs = graph.apply(inputs, apply_functor, make_const);
  58. return ValueRefList{outputs.begin(), outputs.end()};
  59. }
  60. } // namespace imperative
  61. } // namespace mgb