strategy_normal.cpp 5.4 KB
Newer Older
1
#include "strategy_normal.h"
2 3 4 5 6 7 8 9 10 11
#include <iostream>
#include <thread>
#include "megbrain/common.h"
#include "megbrain/utils/timer.h"
#include "megbrain/version.h"
#include "megdnn/version.h"

using namespace lar;

NormalStrategy::NormalStrategy(std::string model_path) {
12
    m_options = std::make_shared<OptionMap>();
13 14 15 16 17 18 19
    m_model_path = model_path;
    auto option_creator_map = OptionFactory::get_Instance().get_option_creator_map();
    mgb_log_debug("option map size: %lu", option_creator_map->size());
    auto construct_option = [&](std::string name) -> void {
        auto& creator = (*option_creator_map)[name];
        auto option = creator();
        if (option) {
20
            m_options->insert({name, option});
21 22 23 24 25
        }
    };

    for (auto& creator : *option_creator_map) {
        auto name = creator.first;
26
        if (m_options->count(name) == 0) {
27 28 29 30 31 32 33 34 35 36
            construct_option(name);
        }
    }
}

void NormalStrategy::run_subline() {
    auto model = ModelBase::create_model(m_model_path);
    mgb_assert(model != nullptr, "create model failed!!");

    auto stage_config_model = [&]() {
37
        for (auto& option : *m_options) {
38 39 40 41 42 43 44
            option.second->config_model(m_runtime_param, model);
        }
    };
    //! execute before load config
    m_runtime_param.stage = RunStage::BEFORE_MODEL_LOAD;
    stage_config_model();

45 46 47 48
    m_runtime_param.stage = RunStage::AFTER_NETWORK_CREATED;
    model->create_network();
    stage_config_model();

49 50
    mgb::RealTimer timer;
    model->load_model();
51
    mgb_log("load model: %.3fms\n", timer.get_msecs_reset());
52 53

    //! after load configure
54 55
    auto config_after_load = [&]() {
        for (auto stage :
56 57 58
             {RunStage::AFTER_MODEL_LOAD, RunStage::UPDATE_IO,
              RunStage::GLOBAL_OPTIMIZATION, RunStage::BEFORE_OUTSPEC_SET,
              RunStage::AFTER_OUTSPEC_SET}) {
59 60 61 62
            m_runtime_param.stage = stage;
            stage_config_model();
        }
    };
63 64 65 66

    auto warm_up = [&]() {
        auto warmup_num = m_runtime_param.warmup_iter;
        for (size_t i = 0; i < warmup_num; i++) {
67
            mgb_log("=== prepare: %.3fms; going to warmup", timer.get_msecs_reset());
68 69
            model->run_model();
            model->wait();
70
            mgb_log("warm up %lu  %.3fms", i, timer.get_msecs_reset());
71 72 73 74 75 76 77 78 79 80 81 82 83 84
            m_runtime_param.stage = RunStage::AFTER_RUNNING_WAIT;
            stage_config_model();
        }
    };

    auto run_iter = [&](int idx) {
        double time_sqrsum = 0, time_sum = 0,
               min_time = std::numeric_limits<double>::max(), max_time = 0;
        auto run_num = m_runtime_param.run_iter;
        for (size_t i = 0; i < run_num; i++) {
            timer.reset();
            model->run_model();
            auto exec_time = timer.get_msecs();
            model->wait();
85
            auto cur = timer.get_msecs();
86 87
            m_runtime_param.stage = RunStage::AFTER_RUNNING_WAIT;
            stage_config_model();
88 89
            mgb_log("iter %lu/%lu: e2e=%.3f ms (host=%.3f ms)", i, run_num, cur,
                    exec_time);
90 91 92 93 94 95
            time_sum += cur;
            time_sqrsum += cur * cur;
            fflush(stdout);
            min_time = std::min(min_time, cur);
            max_time = std::max(max_time, cur);
        }
M
Megvii Engine Team 已提交
96 97 98 99 100 101 102 103 104
        if (run_num > 0) {
            mgb_log("=== finished test #%u: time=%.3f ms avg_time=%.3f ms "
                    "standard_deviation=%.3f ms min=%.3f ms max=%.3f ms",
                    idx, time_sum, time_sum / run_num,
                    std::sqrt(
                            (time_sqrsum * run_num - time_sum * time_sum) /
                            (run_num * (run_num - 1))),
                    min_time, max_time);
        }
105 106 107 108 109 110 111 112
        return time_sum;
    };

    //! model with testcase
    size_t iter_num = m_runtime_param.testcase_num;

    double tot_time = 0;
    for (size_t idx = 0; idx < iter_num; idx++) {
113 114
        //! config model
        config_after_load();
115
        //! config when running model
116
        mgb_log("run testcase: %zu ", idx);
117 118 119
        m_runtime_param.stage = RunStage::MODEL_RUNNING;
        stage_config_model();

120
        if (idx == 0) {
121 122 123 124 125 126 127 128
            warm_up();
        }
        tot_time += run_iter(idx);

        m_runtime_param.stage = RunStage::AFTER_RUNNING_ITER;
        stage_config_model();
    }

129
    mgb_log("=== total time: %.3fms\n", tot_time);
130 131 132 133 134 135 136 137
    //! execute after run
    m_runtime_param.stage = RunStage::AFTER_MODEL_RUNNING;
    stage_config_model();
};

void NormalStrategy::run() {
    auto v0 = mgb::get_version();
    auto v1 = megdnn::get_version();
138 139 140
    mgb_log("megbrain/lite/load_and_run:\nusing MegBrain "
            "%d.%d.%d(%d) and MegDNN %d.%d.%d\n",
            v0.major, v0.minor, v0.patch, v0.is_dev, v1.major, v1.minor, v1.patch);
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

    size_t thread_num = m_runtime_param.threads;
    auto run_sub = [&]() { run_subline(); };
    if (thread_num == 1) {
        run_sub();
    } else if (thread_num > 1) {
#if MGB_HAVE_THREAD
        std::vector<std::thread> threads;

        for (size_t i = 0; i < thread_num; ++i) {
            threads.emplace_back(run_sub);
        }
        for (auto&& i : threads) {
            i.join();
        }
#else
        mgb_log_error(
                "%d threads requested, but load_and_run was compiled "
                "without <thread> support.",
                thread_num);
#endif
    } else {
        mgb_assert(false, "--thread must input a positive number!!");
    }
    //! execute before run
166
}