| 37 | |
| 38 | template <typename ArrayLayoutT> |
| 39 | void CheckArrayLayout(const RegTree& tree, ArrayLayoutT buffer, int max_depth, int depth, |
| 40 | size_t nid, size_t nid_array) { |
| 41 | const auto& split_idx = buffer.SplitIndex(); |
| 42 | const auto& split_cond = buffer.SplitCond(); |
| 43 | const auto& default_left = buffer.DefaultLeft(); |
| 44 | const auto& nidx_in_tree = buffer.NidxInTree(); |
| 45 | const auto& nodes = tree.GetNodes(DeviceOrd::CPU()); |
| 46 | |
| 47 | if (depth == max_depth) { |
| 48 | ASSERT_EQ(nidx_in_tree[nid_array - (1u << max_depth) + 1], nid); |
| 49 | return; |
| 50 | } |
| 51 | |
| 52 | if (nodes[nid].IsLeaf()) { |
| 53 | ASSERT_EQ(default_left[nid_array], 0); |
| 54 | ASSERT_TRUE(std::isnan(split_cond[nid_array])); |
| 55 | |
| 56 | CheckArrayLayout(tree, buffer, max_depth, depth + 1, nid, 2 * nid_array + 2); |
| 57 | } else { |
| 58 | ASSERT_EQ(nodes[nid].SplitIndex(), split_idx[nid_array]); |
| 59 | ASSERT_EQ(nodes[nid].SplitCond(), split_cond[nid_array]); |
| 60 | ASSERT_EQ(nodes[nid].DefaultLeft(), default_left[nid_array]); |
| 61 | |
| 62 | if (nodes[nid].LeftChild() != RegTree::kInvalidNodeId) { |
| 63 | CheckArrayLayout(tree, buffer, max_depth, depth + 1, nodes[nid].LeftChild(), |
| 64 | 2 * nid_array + 1); |
| 65 | } |
| 66 | if (nodes[nid].RightChild() != RegTree::kInvalidNodeId) { |
| 67 | CheckArrayLayout(tree, buffer, max_depth, depth + 1, nodes[nid].RightChild(), |
| 68 | 2 * nid_array + 2); |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | namespace { |
| 74 | template <bst_node_t kDepth> |
no test coverage detected