misc.cpp 3.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/**
 * \file imperative/src/impl/ops/tensor_manip.cpp
 * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
 *
 * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
 *
 * 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.
 */
11
#include "../dnn_op_helper.h"
12 13 14 15 16 17 18 19
#include "../op_trait.h"

#include "megbrain/imperative/ops/autogen.h"
#include "megbrain/opr/misc.h"

namespace mgb {
namespace imperative {

20
namespace check_non_finite {
21
SymbolVarArray apply_on_var_node(const OpDef& def, const VarNodeArray& inputs) {
22
    auto&& op = def.cast_final_safe<CheckNonFinite>();
23
    OperatorNodeConfig config{op.make_name()};
24
    return opr::CheckNonFinite::make(inputs, op.param(), config);
25 26 27
}

SmallVector<TensorPtr> apply_on_physical_tensor(
28 29
        const OpDef& def, const SmallVector<TensorPtr>& inputs,
        SmallVector<LogicalTensorDesc>& output_descs, const bool& validated) {
30
    size_t size = inputs.size();
31 32 33
    auto&& op = def.cast_final_safe<CheckNonFinite>();
    SmallVector<TensorPtr> outputs(size + 1);
    outputs[size] = Tensor::make(
34
            TensorLayout(TensorShape({1}), dtype::Int32()), inputs[0]->comp_node());
35 36

    auto dest = outputs[size];
37
    auto cn = dest->comp_node();
38
    DnnOprCaller<megdnn::CheckNonFinite> dnn_opr(cn);
39
    SmallVector<megdnn::TensorND> srcs(size);
40
    // copy an outputs to the dnn for inplace
41
    for (size_t i = 0; i < size; ++i) {
42 43 44
        outputs[i] = Tensor::make(inputs[i]->layout(), inputs[0]->comp_node());
        outputs[i]->dev_tensor().copy_from_fixlayout(inputs[i]->dev_tensor());
        srcs[i] = outputs[i]->dev_tensor().as_megdnn();
45
    }
46
    megdnn::CheckNonFinite::Param param({op.scale});
47 48 49 50 51
    dnn_opr.op->param() = param;
    size_t sz = dnn_opr.op->get_workspace_in_bytes(srcs, dest->layout());
    TensorLayout w_layout({sz}, dtype::Byte());
    auto dnn_wk = dnn_opr.create_workspace(w_layout);
    dnn_opr.op->exec(srcs, dest->dev_tensor().as_megdnn(), dnn_wk);
52
    return outputs;
53 54 55 56
}

std::tuple<SmallVector<LogicalTensorDesc>, bool> infer_output_attrs_fallible(
        const OpDef& def, const SmallVector<LogicalTensorDesc>& inputs) {
57 58 59 60 61 62 63 64
    size_t size = inputs.size();
    SmallVector<LogicalTensorDesc> dests(size + 1);
    for (size_t i = 0; i < size; ++i) {
        dests[i].comp_node = inputs[i].comp_node;
        dests[i].layout = inputs[i].layout;
    }
    dests[size].comp_node = inputs[0].comp_node;
    dests[size].layout = TensorLayout(TensorShape({1}), dtype::Int32());
65 66
    return {dests, true};
}
67

68
OP_TRAIT_REG(CheckNonFinite, CheckNonFinite)
69
        .apply_on_var_node(apply_on_var_node)
70 71
        .apply_on_physical_tensor(apply_on_physical_tensor)
        .infer_output_attrs_fallible(infer_output_attrs_fallible)
72
        .fallback();
73
}  // namespace check_non_finite
74 75 76 77 78

}  // namespace imperative
}  // namespace mgb

// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}