cond_take.cpp 3.3 KB
Newer Older
1
/**
M
Megvii Engine Team 已提交
2 3
 * \file imperative/src/impl/ops/cond_take.cpp
 * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
4
 *
5
 * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
6
 *
M
Megvii Engine Team 已提交
7 8 9
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 11
 */

12
#include "megbrain/imperative/ops/autogen.h"
13 14 15 16 17 18 19 20 21 22 23 24 25
#include "megbrain/opr/misc.h"
#include "../dnn_op_helper.h"
#include "../op_trait.h"

using namespace megdnn;

namespace mgb::imperative {

namespace {

cg::OperatorNodeBase* apply_on_var_node(
        const OpDef& def,
        const VarNodeArray& inputs) {
26
    auto&& op = def.cast_final_safe<CondTake>();
27 28 29 30
    auto&& graph = inputs[0]->owner_graph();

    opr::CondTake::Param param;
    param.val = 1;
31
    OperatorNodeConfig config{op.make_name()};
32 33 34 35 36 37 38 39 40
    cg::OperatorNodeBase* opr = graph->insert_opr(
            std::make_unique<opr::CondTake>(
                    inputs[0], inputs[1], param, config));
    return opr;
}

SmallVector<TensorPtr> apply_on_physical_tensor(
        const OpDef& def,
        const SmallVector<TensorPtr>& inputs) {
41
    auto&& opr = def.cast_final_safe<CondTake>();
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
    mgb_assert(opr.same_type<CondTake>());
    mgb_assert(inputs.size() == 2, "CondTake take 2 inputs, got %lu",
               inputs.size());

    auto&& inp = inputs[0];
    auto&& msk = inputs[1];
    mgb_assert(inp->layout().eq_shape(msk->layout()),
               "input shape does not match mask shape");
    mgb_assert(msk->get_value().dtype().enumv() == DTypeEnum::Bool,
               "mask dtype must be bool");
    DnnOprCaller<megdnn::CondTake> dnn_op(inp->comp_node());
    dnn_op.op->param().val = 1;

    TensorLayout m_layout({dnn_op.op->get_workspace_in_bytes(inp->layout())},
                           dtype::Byte());

    auto dnn_workspace = dnn_op.create_workspace(m_layout);
59
    MegDNNDynOutMallocImpl<2> policy{inp->comp_node()};
60 61 62 63 64 65 66 67 68 69 70 71

    dnn_op.op->exec(inp->dev_tensor().as_megdnn(),
                  msk->dev_tensor().as_megdnn(),
                  dnn_workspace,
                  &policy);

    SmallVector<TensorPtr> out;
    out.push_back(policy.at(0));
    out.push_back(policy.at(1));
    return out;
}

72
std::tuple<SmallVector<LogicalTensorDesc>, bool> infer_output_attrs_fallible(
73
    const OpDef& def,
74 75
    const SmallVector<LogicalTensorDesc>& inputs) {
    auto cn = inputs[0].comp_node;
76
    return {{
77 78
        {TensorLayout(inputs[0].layout.dtype), cn},
        {TensorLayout(dtype::Int32()), cn}
79
    }, false};
80 81
}

82 83 84 85 86 87 88 89 90 91 92 93
std::tuple<SmallVector<MemoryDesc>, SmallVector<MemoryDesc>> infer_output_mem_desc(
        const OpDef& def,
        const SmallVector<TensorPtr>& inputs,
        const SmallVector<MemoryDesc>& inputs_mems) {
    return {{}, {}};
}

void execute(const OpDef& def, const SmallVector<TensorPtr>& inputs,
          const SmallVector<TensorPtr>& outputs, const SmallVector<TensorPtr>& workspace) {
    mgb_assert(0);
}

94 95 96
OP_TRAIT_REG(CondTake, CondTake, opr::CondTake)
    .apply_on_var_node(apply_on_var_node)
    .apply_on_physical_tensor(apply_on_physical_tensor)
97
    .infer_output_attrs_fallible(infer_output_attrs_fallible)
98 99
    .infer_output_mem_desc(infer_output_mem_desc)
    .execute(execute)
100 101 102 103
    .fallback();

} // namespace

104
} // namespace mgb::imperative