test_mul_op.cpp 6.9 KB
Newer Older
E
eclipsess 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

/* Copyright (c) 2016 Baidu, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==============================================================================*/
#pragma once
#include "../test_include.h"
E
eclipsess 已提交
21
#include "operators/mul_op.h"
E
eclipsess 已提交
22 23

namespace paddle_mobile {
E
eclipsess 已提交
24
namespace framework {
E
eclipsess 已提交
25

E
eclipsess 已提交
26 27
template <typename Dtype> class TestMulOp {
  public:
E
eclipsess 已提交
28
    explicit TestMulOp(const Program<Dtype> p) : program_(p) {
E
eclipsess 已提交
29 30 31 32 33
        if (use_optimize_) {
            to_predict_program_ = program_.optimizeProgram;
        } else {
            to_predict_program_ = program_.originProgram;
        }
E
eclipsess 已提交
34

E
eclipsess 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
        const std::vector<std::shared_ptr<BlockDesc>> blocks =
            to_predict_program_->Blocks();
        //  DLOG << " **block size " << blocks.size();
        for (int i = 0; i < blocks.size(); ++i) {
            std::shared_ptr<BlockDesc> block_desc = blocks[i];
            std::vector<std::shared_ptr<OpDesc>> ops = block_desc->Ops();
            //    DLOG << " ops " << ops.size();
            for (int j = 0; j < ops.size(); ++j) {
                std::shared_ptr<OpDesc> op = ops[j];
                if (op->Type() == "mul" &&
                    op->Input("X")[0] == "pool2d_0.tmp_0") {
                    DLOG << " mul attr size: " << op->GetAttrMap().size();
                    DLOG << " inputs size: " << op->GetInputs().size();
                    DLOG << " outputs size: " << op->GetOutputs().size();
                    DLOG << " Input X is : " << op->Input("X")[0];
                    DLOG << " Input Y is : " << op->Input("Y")[0];
                    DLOG << " Output Out is : " << op->Output("Out")[0];
                    DLOG << "x_num_col_dims : "
                         << op->GetAttrMap().at("x_num_col_dims").Get<int>();
                    DLOG << "y_num_col_dims : "
                         << op->GetAttrMap().at("y_num_col_dims").Get<int>();
E
eclipsess 已提交
56

E
eclipsess 已提交
57
                    std::shared_ptr<operators::MulOp<Dtype, float>> mul =
E
eclipsess 已提交
58 59 60
                        std::make_shared<operators::MulOp<Dtype, float>>(
                            op->Type(), op->GetInputs(), op->GetOutputs(),
                            op->GetAttrMap(), program_.scope);
E
eclipsess 已提交
61
                    ops_of_block_[*block_desc.get()].push_back(mul);
E
eclipsess 已提交
62 63
                }
            }
E
eclipsess 已提交
64 65
        }
    }
E
eclipsess 已提交
66

E
eclipsess 已提交
67
    std::shared_ptr<Tensor> predict_mul(Tensor &t1, Tensor &t2) {
E
eclipsess 已提交
68 69 70 71 72
        // feed
        auto scope = program_.scope;
        Variable *x_feed_value = scope->Var("pool2d_0.tmp_0");
        auto tensor_x = x_feed_value->GetMutable<Tensor>();
        tensor_x->ShareDataWith(t1);
E
eclipsess 已提交
73

E
eclipsess 已提交
74 75 76
        Variable *y_feed_value = scope->Var("fc_0.w_0");
        auto tensor_y = y_feed_value->GetMutable<Tensor>();
        tensor_y->ShareDataWith(t2);
E
eclipsess 已提交
77

E
eclipsess 已提交
78
        Variable *con_output = scope->Var("fc_0.tmp_0");
E
eclipsess 已提交
79
        auto *output_tensor = con_output->GetMutable<Tensor>();
E
eclipsess 已提交
80 81 82
        output_tensor->mutable_data<float>({3, 3});
        //  DLOG << typeid(output_tensor).name();
        //  DLOG << "output_tensor dims: " << output_tensor->dims();
E
eclipsess 已提交
83

E
eclipsess 已提交
84 85
        std::shared_ptr<Tensor> out_tensor = std::make_shared<LoDTensor>();
        out_tensor.reset(output_tensor);
E
eclipsess 已提交
86

E
eclipsess 已提交
87
        predict_mul(t1, t2, 0);
E
eclipsess 已提交
88 89
        return out_tensor;
    }
E
eclipsess 已提交
90

E
eclipsess 已提交
91 92 93 94 95 96 97
  private:
    const framework::Program<Dtype> program_;
    std::shared_ptr<ProgramDesc> to_predict_program_;
    std::map<framework::BlockDesc,
             std::vector<std::shared_ptr<OperatorBase<Dtype>>>>
        ops_of_block_;
    bool use_optimize_ = false;
E
eclipsess 已提交
98

E
eclipsess 已提交
99
    void predict_mul(const Tensor &t1, const Tensor &t2, int block_id) {
E
eclipsess 已提交
100 101 102 103 104 105 106 107 108 109
        std::shared_ptr<BlockDesc> to_predict_block =
            to_predict_program_->Block(block_id);
        for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size();
             ++j) {
            auto op = ops_of_block_[*to_predict_block.get()][j];
            DLOG << "op -> run()";
            op->Run();
        }
    }
};
E
eclipsess 已提交
110

E
eclipsess 已提交
111 112 113
template class TestMulOp<CPU>;
} // namespace framework
} // namespace paddle_mobile
E
eclipsess 已提交
114

E
eclipsess 已提交
115
int main() {
E
eclipsess 已提交
116 117 118 119
    DLOG << "----------**********----------";
    DLOG << "begin to run MulOp Test";
    paddle_mobile::Loader<paddle_mobile::CPU> loader;
    auto program =
E
eclipsess 已提交
120
        loader.Load(std::string("../../test/models/"
E
eclipsess 已提交
121 122 123 124 125 126
                                "image_classification_resnet.inference.model"));

    /// input x (3,2,1,1)
    paddle_mobile::framework::Tensor inputx;
    SetupTensor<float>(&inputx, {3, 2, 1, 1}, static_cast<float>(0),
                       static_cast<float>(1));
E
eclipsess 已提交
127
    auto *inputx_ptr = inputx.data<float>();
E
eclipsess 已提交
128 129 130 131 132

    /// input y (2,3)
    paddle_mobile::framework::Tensor inputy;
    SetupTensor<float>(&inputy, {2, 3}, static_cast<float>(0),
                       static_cast<float>(1));
E
eclipsess 已提交
133
    auto *inputy_ptr = inputy.data<float>();
E
eclipsess 已提交
134 135 136

    paddle_mobile::framework::TestMulOp<paddle_mobile::CPU> testMulOp(program);

E
eclipsess 已提交
137 138
    auto output_mul = testMulOp.predict_mul(inputx, inputy);
    auto *output_mul_ptr = output_mul->data<float>();
E
eclipsess 已提交
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174

    auto dimx_1 = inputx.numel() / inputx.dims()[0];
    DLOG << " inputx : ";
    for (int i = 0; i < inputx.dims()[0]; ++i) {
        for (int j = 0; j < dimx_1; ++j) {
            DLOGF("%f ", inputx_ptr[i * dimx_1 + j]);
        }
        DLOGF("\n");
    }

    auto dimy_1 = inputy.numel() / inputy.dims()[0];
    DLOG << " inputy : ";
    for (int i = 0; i < inputy.dims()[0]; ++i) {
        for (int j = 0; j < dimy_1; ++j) {
            DLOGF("%f ", inputy_ptr[i * dimx_1 + j]);
        }
        DLOGF("\n");
    }

    auto dim_output_1 = output_mul->numel() / output_mul->dims()[0];
    DLOG << " output : ";
    for (int i = 0; i < output_mul->dims()[0]; ++i) {
        for (int j = 0; j < dim_output_1; ++j) {
            DLOGF("%f ", output_mul_ptr[i * dimy_1 + j]);
        }
        DLOGF("\n");
    }

    /// output (3,3)
    DLOG << "output memory size : " << output_mul->memory_size();
    DLOG << "output numel : " << output_mul->numel();

    DLOG << inputx_ptr[0] << " x " << inputy_ptr[0] << " + " << inputx_ptr[1]
         << " x " << inputy_ptr[0 + 3] << " = " << output_mul_ptr[0];
    return 0;
}