| 65 | } |
| 66 | |
| 67 | std::string GBDT::ModelToIfElse(int num_iteration) const { |
| 68 | std::stringstream str_buf; |
| 69 | |
| 70 | str_buf << "#include \"gbdt.h\"" << '\n'; |
| 71 | str_buf << "#include <LightGBM/utils/common.h>" << '\n'; |
| 72 | str_buf << "#include <LightGBM/objective_function.h>" << '\n'; |
| 73 | str_buf << "#include <LightGBM/metric.h>" << '\n'; |
| 74 | str_buf << "#include <LightGBM/prediction_early_stop.h>" << '\n'; |
| 75 | str_buf << "#include <ctime>" << '\n'; |
| 76 | str_buf << "#include <sstream>" << '\n'; |
| 77 | str_buf << "#include <chrono>" << '\n'; |
| 78 | str_buf << "#include <string>" << '\n'; |
| 79 | str_buf << "#include <vector>" << '\n'; |
| 80 | str_buf << "#include <utility>" << '\n'; |
| 81 | str_buf << "namespace LightGBM {" << '\n'; |
| 82 | |
| 83 | int num_used_model = static_cast<int>(models_.size()); |
| 84 | if (num_iteration > 0) { |
| 85 | num_used_model = std::min(num_iteration * num_tree_per_iteration_, num_used_model); |
| 86 | } |
| 87 | |
| 88 | // PredictRaw |
| 89 | for (int i = 0; i < num_used_model; ++i) { |
| 90 | str_buf << models_[i]->ToIfElse(i, false) << '\n'; |
| 91 | } |
| 92 | |
| 93 | str_buf << "double (*PredictTreePtr[])(const double*) = { "; |
| 94 | for (int i = 0; i < num_used_model; ++i) { |
| 95 | if (i > 0) { |
| 96 | str_buf << " , "; |
| 97 | } |
| 98 | str_buf << "PredictTree" << i; |
| 99 | } |
| 100 | str_buf << " };" << '\n' << '\n'; |
| 101 | |
| 102 | std::stringstream pred_str_buf; |
| 103 | |
| 104 | pred_str_buf << "\t" << "int early_stop_round_counter = 0;" << '\n'; |
| 105 | pred_str_buf << "\t" << "std::memset(output, 0, sizeof(double) * num_tree_per_iteration_);" << '\n'; |
| 106 | pred_str_buf << "\t" << "for (int i = 0; i < num_iteration_for_pred_; ++i) {" << '\n'; |
| 107 | pred_str_buf << "\t\t" << "for (int k = 0; k < num_tree_per_iteration_; ++k) {" << '\n'; |
| 108 | pred_str_buf << "\t\t\t" << "output[k] += (*PredictTreePtr[i * num_tree_per_iteration_ + k])(features);" << '\n'; |
| 109 | pred_str_buf << "\t\t" << "}" << '\n'; |
| 110 | pred_str_buf << "\t\t" << "++early_stop_round_counter;" << '\n'; |
| 111 | pred_str_buf << "\t\t" << "if (early_stop->round_period == early_stop_round_counter) {" << '\n'; |
| 112 | pred_str_buf << "\t\t\t" << "if (early_stop->callback_function(output, num_tree_per_iteration_))" << '\n'; |
| 113 | pred_str_buf << "\t\t\t\t" << "return;" << '\n'; |
| 114 | pred_str_buf << "\t\t\t" << "early_stop_round_counter = 0;" << '\n'; |
| 115 | pred_str_buf << "\t\t" << "}" << '\n'; |
| 116 | pred_str_buf << "\t" << "}" << '\n'; |
| 117 | |
| 118 | str_buf << "void GBDT::PredictRaw(const double* features, double *output, const PredictionEarlyStopInstance* early_stop) const {" << '\n'; |
| 119 | str_buf << pred_str_buf.str(); |
| 120 | str_buf << "}" << '\n'; |
| 121 | str_buf << '\n'; |
| 122 | |
| 123 | // PredictRawByMap |
| 124 | str_buf << "double (*PredictTreeByMapPtr[])(const std::unordered_map<int, double>&) = { "; |