in src/compiler/ast_native.cc [414:506]
void HandleCodeFolderNode(const CodeFolderNode* node,
const std::string& dest,
size_t indent) {
CHECK_EQ(node->children.size(), 1);
const int node_id = node->children[0]->node_id;
const int tree_id = node->children[0]->tree_id;
/* render arrays needed for folding subtrees */
std::string array_nodes, array_cat_bitmap, array_cat_begin;
// node_treeXX_nodeXX[] : information of nodes for a particular subtree
const std::string node_array_name
= fmt::format("node_tree{}_node{}", tree_id, node_id);
// cat_bitmap_treeXX_nodeXX[] : list of all 64-bit integer bitmaps, used to
// make all categorical splits in a particular
// subtree
const std::string cat_bitmap_name
= fmt::format("cat_bitmap_tree{}_node{}", tree_id, node_id);
// cat_begin_treeXX_nodeXX[] : shows which bitmaps belong to each split.
// cat_bitmap[ cat_begin[i]:cat_begin[i+1] ]
// belongs to the i-th (categorical) split
const std::string cat_begin_name
= fmt::format("cat_begin_tree{}_node{}", tree_id, node_id);
std::string output_switch_statement;
Operator common_comp_op;
common_util::RenderCodeFolderArrays(node, param.quantize, false,
"{{ {default_left}, {split_index}, {threshold}, {left_child}, {right_child} }}",
[this](const OutputNode* node) { return RenderOutputStatement(node); },
&array_nodes, &array_cat_bitmap, &array_cat_begin,
&output_switch_statement, &common_comp_op);
if (!array_nodes.empty()) {
AppendToBuffer("header.h",
fmt::format("extern const struct Node {node_array_name}[];\n",
"node_array_name"_a = node_array_name), 0);
AppendToBuffer("arrays.c",
fmt::format("const struct Node {node_array_name}[] = {{\n"
"{array_nodes}\n"
"}};\n",
"node_array_name"_a = node_array_name,
"array_nodes"_a = array_nodes), 0);
}
if (!array_cat_bitmap.empty()) {
AppendToBuffer("header.h",
fmt::format("extern const uint64_t {cat_bitmap_name}[];\n",
"cat_bitmap_name"_a = cat_bitmap_name), 0);
AppendToBuffer("arrays.c",
fmt::format("const uint64_t {cat_bitmap_name}[] = {{\n"
"{array_cat_bitmap}\n"
"}};\n",
"cat_bitmap_name"_a = cat_bitmap_name,
"array_cat_bitmap"_a = array_cat_bitmap), 0);
}
if (!array_cat_begin.empty()) {
AppendToBuffer("header.h",
fmt::format("extern const size_t {cat_begin_name}[];\n",
"cat_begin_name"_a = cat_begin_name), 0);
AppendToBuffer("arrays.c",
fmt::format("const size_t {cat_begin_name}[] = {{\n"
"{array_cat_begin}\n"
"}};\n",
"cat_begin_name"_a = cat_begin_name,
"array_cat_begin"_a = array_cat_begin), 0);
}
if (array_nodes.empty()) {
/* folded code consists of a single leaf node */
AppendToBuffer(dest,
fmt::format("nid = -1;\n"
"{output_switch_statement}\n",
"output_switch_statement"_a
= output_switch_statement), indent);
} else if (!array_cat_bitmap.empty() && !array_cat_begin.empty()) {
AppendToBuffer(dest,
fmt::format(native::eval_loop_template,
"node_array_name"_a = node_array_name,
"cat_bitmap_name"_a = cat_bitmap_name,
"cat_begin_name"_a = cat_begin_name,
"data_field"_a = (param.quantize > 0 ? "qvalue" : "fvalue"),
"comp_op"_a = OpName(common_comp_op),
"output_switch_statement"_a
= output_switch_statement), indent);
} else {
AppendToBuffer(dest,
fmt::format(native::eval_loop_template_without_categorical_feature,
"node_array_name"_a = node_array_name,
"data_field"_a = (param.quantize > 0 ? "qvalue" : "fvalue"),
"comp_op"_a = OpName(common_comp_op),
"output_switch_statement"_a
= output_switch_statement), indent);
}
}