in src/compiler/ast_native.cc [52:119]
CompiledModel Compile(const Model& model) override {
CompiledModel cm;
cm.backend = "native";
num_feature_ = model.num_feature;
num_output_group_ = model.num_output_group;
pred_tranform_func_ = PredTransformFunction("native", model);
files_.clear();
ASTBuilder builder;
builder.BuildAST(model);
if (builder.FoldCode(param.code_folding_req)
|| param.quantize > 0) {
// is_categorical[i] : is i-th feature categorical?
array_is_categorical_
= RenderIsCategoricalArray(builder.GenerateIsCategoricalArray());
}
if (param.annotate_in != "NULL") {
BranchAnnotator annotator;
std::unique_ptr<dmlc::Stream> fi(
dmlc::Stream::Create(param.annotate_in.c_str(), "r"));
annotator.Load(fi.get());
const auto annotation = annotator.Get();
builder.LoadDataCounts(annotation);
LOG(INFO) << "Loading node frequencies from `"
<< param.annotate_in << "'";
}
builder.Split(param.parallel_comp);
if (param.quantize > 0) {
builder.QuantizeThresholds();
}
{
const char* destfile = getenv("TREELITE_DUMP_AST");
if (destfile) {
std::ofstream os(destfile);
os << builder.GetDump() << std::endl;
}
}
WalkAST(builder.GetRootNode(), "main.c", 0);
if (files_.count("arrays.c") > 0) {
PrependToBuffer("arrays.c", "#include \"header.h\"\n", 0);
}
{
/* write recipe.json */
std::vector<std::unordered_map<std::string, std::string>> source_list;
for (const auto& kv : files_) {
if (kv.first.compare(kv.first.length() - 2, 2, ".c") == 0) {
const size_t line_count
= std::count(kv.second.content.begin(), kv.second.content.end(), '\n');
source_list.push_back({ {"name",
kv.first.substr(0, kv.first.length() - 2)},
{"length", std::to_string(line_count)} });
}
}
std::ostringstream oss;
auto writer = common::make_unique<dmlc::JSONWriter>(&oss);
writer->BeginObject();
writer->WriteObjectKeyValue("target", param.native_lib_name);
writer->WriteObjectKeyValue("sources", source_list);
writer->EndObject();
files_["recipe.json"] = CompiledModel::FileEntry(oss.str());
}
cm.files = std::move(files_);
return cm;
}