diff --git a/include/treelite/logging.h b/include/treelite/logging.h index 4589aae0..2a43f52e 100644 --- a/include/treelite/logging.h +++ b/include/treelite/logging.h @@ -62,25 +62,25 @@ DEFINE_CHECK_FUNC(_NE, !=) #pragma GCC diagnostic pop -#define CHECK_BINARY_OP(name, op, x, y) \ +#define TREELITE_CHECK_BINARY_OP(name, op, x, y) \ if (auto __treelite__log__err = ::treelite::LogCheck##name(x, y)) \ - ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ + ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ << "Check failed: " << #x " " #op " " #y << *__treelite__log__err << ": " -#define CHECK(x) \ +#define TREELITE_CHECK(x) \ if (!(x)) \ - ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ + ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ << "Check failed: " #x << ": " -#define CHECK_LT(x, y) CHECK_BINARY_OP(_LT, <, x, y) -#define CHECK_GT(x, y) CHECK_BINARY_OP(_GT, >, x, y) -#define CHECK_LE(x, y) CHECK_BINARY_OP(_LE, <=, x, y) -#define CHECK_GE(x, y) CHECK_BINARY_OP(_GE, >=, x, y) -#define CHECK_EQ(x, y) CHECK_BINARY_OP(_EQ, ==, x, y) -#define CHECK_NE(x, y) CHECK_BINARY_OP(_NE, !=, x, y) - -#define LOG_INFO ::treelite::LogMessage(__FILE__, __LINE__) -#define LOG_ERROR LOG_INFO -#define LOG_FATAL ::treelite::LogMessageFatal(__FILE__, __LINE__) -#define LOG(severity) LOG_##severity.stream() +#define TREELITE_CHECK_LT(x, y) TREELITE_CHECK_BINARY_OP(_LT, <, x, y) +#define TREELITE_CHECK_GT(x, y) TREELITE_CHECK_BINARY_OP(_GT, >, x, y) +#define TREELITE_CHECK_LE(x, y) TREELITE_CHECK_BINARY_OP(_LE, <=, x, y) +#define TREELITE_CHECK_GE(x, y) TREELITE_CHECK_BINARY_OP(_GE, >=, x, y) +#define TREELITE_CHECK_EQ(x, y) TREELITE_CHECK_BINARY_OP(_EQ, ==, x, y) +#define TREELITE_CHECK_NE(x, y) TREELITE_CHECK_BINARY_OP(_NE, !=, x, y) + +#define TREELITE_LOG_INFO ::treelite::LogMessage(__FILE__, __LINE__) +#define TREELITE_LOG_ERROR TREELITE_LOG_INFO +#define TREELITE_LOG_FATAL ::treelite::LogMessageFatal(__FILE__, __LINE__) +#define TREELITE_LOG(severity) TREELITE_LOG_##severity.stream() class DateLogger { public: diff --git a/include/treelite/predictor.h b/include/treelite/predictor.h index 38f9a552..4c4b8baa 100644 --- a/include/treelite/predictor.h +++ b/include/treelite/predictor.h @@ -152,7 +152,7 @@ class Predictor { * \return length of prediction array */ inline size_t QueryResultSize(const DMatrix* dmat) const { - CHECK(pred_func_) << "A shared library needs to be loaded first using Load()"; + TREELITE_CHECK(pred_func_) << "A shared library needs to be loaded first using Load()"; return dmat->GetNumRow() * num_class_; } /*! @@ -164,8 +164,8 @@ class Predictor { * \return length of prediction array */ inline size_t QueryResultSize(const DMatrix* dmat, size_t rbegin, size_t rend) const { - CHECK(pred_func_) << "A shared library needs to be loaded first using Load()"; - CHECK(rbegin < rend && rend <= dmat->GetNumRow()); + TREELITE_CHECK(pred_func_) << "A shared library needs to be loaded first using Load()"; + TREELITE_CHECK(rbegin < rend && rend <= dmat->GetNumRow()); return (rend - rbegin) * num_class_; } /*! diff --git a/runtime/java/treelite4j/src/native/treelite4j.cpp b/runtime/java/treelite4j/src/native/treelite4j.cpp index bc0d5c25..fd146cb9 100644 --- a/runtime/java/treelite4j/src/native/treelite4j.cpp +++ b/runtime/java/treelite4j/src/native/treelite4j.cpp @@ -251,7 +251,7 @@ Java_ml_dmlc_treelite4j_java_TreeliteJNI_TreelitePredictorPredictBatchWithUInt32 API_BEGIN(); PredictorHandle predictor = reinterpret_cast(jpredictor); DMatrixHandle dmat = reinterpret_cast(jbatch); - CHECK_EQ(sizeof(jint), sizeof(uint32_t)); + TREELITE_CHECK_EQ(sizeof(jint), sizeof(uint32_t)); jint* out_result = jenv->GetIntArrayElements(jout_result, nullptr); jlong* out_result_size = jenv->GetLongArrayElements(jout_result_size, nullptr); size_t out_result_size_tmp = 0; diff --git a/src/annotator.cc b/src/annotator.cc index 668f7a69..905f7a12 100644 --- a/src/annotator.cc +++ b/src/annotator.cc @@ -72,8 +72,8 @@ inline void ComputeBranchLoopImpl( const size_t* count_row_ptr, uint64_t* counts_tloc) { std::vector> inst(nthread * dmat->num_col, {-1}); const size_t ntree = model.trees.size(); - CHECK_LE(rbegin, rend); - CHECK_LT(static_cast(rend), std::numeric_limits::max()); + TREELITE_CHECK_LE(rbegin, rend); + TREELITE_CHECK_LT(static_cast(rend), std::numeric_limits::max()); const size_t num_col = dmat->num_col; const ElementType missing_value = dmat->missing_value; const bool nan_missing = treelite::math::CheckNAN(missing_value); @@ -87,7 +87,7 @@ inline void ComputeBranchLoopImpl( const size_t off2 = count_row_ptr[ntree] * tid; for (size_t j = 0; j < num_col; ++j) { if (treelite::math::CheckNAN(row[j])) { - CHECK(nan_missing) + TREELITE_CHECK(nan_missing) << "The missing_value argument must be set to NaN if there is any NaN in the matrix."; } else if (nan_missing || row[j] != missing_value) { inst[off + j].fvalue = row[j]; @@ -109,8 +109,8 @@ inline void ComputeBranchLoopImpl( const size_t* count_row_ptr, uint64_t* counts_tloc) { std::vector> inst(nthread * dmat->num_col, {-1}); const size_t ntree = model.trees.size(); - CHECK_LE(rbegin, rend); - CHECK_LT(static_cast(rend), std::numeric_limits::max()); + TREELITE_CHECK_LE(rbegin, rend); + TREELITE_CHECK_LT(static_cast(rend), std::numeric_limits::max()); const auto rbegin_i = static_cast(rbegin); const auto rend_i = static_cast(rend); #pragma omp parallel for schedule(static) num_threads(nthread) @@ -141,7 +141,7 @@ class ComputeBranchLoopDispatcherWithDenseDMatrix { const treelite::DMatrix* dmat, size_t rbegin, size_t rend, int nthread, const size_t* count_row_ptr, uint64_t* counts_tloc) { const auto* dmat_ = static_cast*>(dmat); - CHECK(dmat_) << "Dangling data matrix reference detected"; + TREELITE_CHECK(dmat_) << "Dangling data matrix reference detected"; ComputeBranchLoopImpl(model, dmat_, rbegin, rend, nthread, count_row_ptr, counts_tloc); } }; @@ -155,7 +155,7 @@ class ComputeBranchLoopDispatcherWithCSRDMatrix { const treelite::DMatrix* dmat, size_t rbegin, size_t rend, int nthread, const size_t* count_row_ptr, uint64_t* counts_tloc) { const auto* dmat_ = static_cast*>(dmat); - CHECK(dmat_) << "Dangling data matrix reference detected"; + TREELITE_CHECK(dmat_) << "Dangling data matrix reference detected"; ComputeBranchLoopImpl(model, dmat_, rbegin, rend, nthread, count_row_ptr, counts_tloc); } }; @@ -177,7 +177,7 @@ inline void ComputeBranchLoop(const treelite::ModelImpl(dmat->GetType()); break; } @@ -214,7 +214,7 @@ AnnotateImpl( const size_t rend = std::min(rbegin + pstep, num_row); ComputeBranchLoop(model, dmat, rbegin, rend, nthread, &count_row_ptr[0], &counts_tloc[0]); if (verbose > 0) { - LOG(INFO) << rend << " of " << num_row << " rows processed"; + TREELITE_LOG(INFO) << rend << " of " << num_row << " rows processed"; } } @@ -249,10 +249,10 @@ BranchAnnotator::Load(std::istream& fi) { doc.ParseStream(is); std::string err_msg = "JSON file must contain a list of lists of integers"; - CHECK(doc.IsArray()) << err_msg; + TREELITE_CHECK(doc.IsArray()) << err_msg; counts_.clear(); for (const auto& node_cnt : doc.GetArray()) { - CHECK(node_cnt.IsArray()) << err_msg; + TREELITE_CHECK(node_cnt.IsArray()) << err_msg; counts_.emplace_back(); for (const auto& e : node_cnt.GetArray()) { counts_.back().push_back(e.GetUint64()); diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc index 795f1107..07651543 100644 --- a/src/c_api/c_api.cc +++ b/src/c_api/c_api.cc @@ -30,7 +30,7 @@ int TreeliteAnnotateBranch( std::unique_ptr annotator{new BranchAnnotator()}; const Model* model_ = static_cast(model); const auto* dmat_ = static_cast(dmat); - CHECK(dmat_) << "Found a dangling reference to DMatrix"; + TREELITE_CHECK(dmat_) << "Found a dangling reference to DMatrix"; annotator->Annotate(*model_, dmat_, nthread, verbose); *out = static_cast(annotator.release()); API_END(); @@ -64,8 +64,8 @@ int TreeliteCompilerGenerateCodeV2(CompilerHandle compiler, API_BEGIN(); const Model* model_ = static_cast(model); Compiler* compiler_ = static_cast(compiler); - CHECK(model_); - CHECK(compiler_); + TREELITE_CHECK(model_); + TREELITE_CHECK(compiler_); compiler::CompilerParam param = compiler_->QueryParam(); // create directory named dirpath @@ -75,12 +75,12 @@ int TreeliteCompilerGenerateCodeV2(CompilerHandle compiler, /* compile model */ auto compiled_model = compiler_->Compile(*model_); if (param.verbose > 0) { - LOG(INFO) << "Code generation finished. Writing code to files..."; + TREELITE_LOG(INFO) << "Code generation finished. Writing code to files..."; } for (const auto& it : compiled_model.files) { if (param.verbose > 0) { - LOG(INFO) << "Writing file " << it.first << "..."; + TREELITE_LOG(INFO) << "Writing file " << it.first << "..."; } const std::string filename_full = dirpath_ + "/" + it.first; if (it.second.is_binary) { @@ -189,7 +189,7 @@ int TreeliteLoadSKLearnGradientBoostingClassifier( int TreeliteSerializeModel(const char* filename, ModelHandle handle) { API_BEGIN(); FILE* fp = std::fopen(filename, "wb"); - CHECK(fp) << "Failed to open file '" << filename << "'"; + TREELITE_CHECK(fp) << "Failed to open file '" << filename << "'"; auto* model_ = static_cast(handle); model_->SerializeToFile(fp); std::fclose(fp); @@ -199,7 +199,7 @@ int TreeliteSerializeModel(const char* filename, ModelHandle handle) { int TreeliteDeserializeModel(const char* filename, ModelHandle* out) { API_BEGIN(); FILE* fp = std::fopen(filename, "rb"); - CHECK(fp) << "Failed to open file '" << filename << "'"; + TREELITE_CHECK(fp) << "Failed to open file '" << filename << "'"; std::unique_ptr model = Model::DeserializeFromFile(fp); std::fclose(fp); *out = static_cast(model.release()); @@ -251,10 +251,10 @@ int TreeliteQueryNumClass(ModelHandle handle, size_t* out) { int TreeliteSetTreeLimit(ModelHandle handle, size_t limit) { API_BEGIN(); - CHECK_GT(limit, 0) << "limit should be greater than 0!"; + TREELITE_CHECK_GT(limit, 0) << "limit should be greater than 0!"; auto* model_ = static_cast(handle); const size_t num_tree = model_->GetNumTree(); - CHECK_GE(num_tree, limit) << "Model contains less trees(" << num_tree << ") than limit"; + TREELITE_CHECK_GE(num_tree, limit) << "Model contains fewer trees(" << num_tree << ") than limit"; model_->SetTreeLimit(limit); API_END(); } @@ -293,7 +293,7 @@ int TreeliteDeleteTreeBuilder(TreeBuilderHandle handle) { int TreeliteTreeBuilderCreateNode(TreeBuilderHandle handle, int node_key) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; builder->CreateNode(node_key); API_END(); } @@ -301,7 +301,7 @@ int TreeliteTreeBuilderCreateNode(TreeBuilderHandle handle, int node_key) { int TreeliteTreeBuilderDeleteNode(TreeBuilderHandle handle, int node_key) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; builder->DeleteNode(node_key); API_END(); } @@ -309,7 +309,7 @@ int TreeliteTreeBuilderDeleteNode(TreeBuilderHandle handle, int node_key) { int TreeliteTreeBuilderSetRootNode(TreeBuilderHandle handle, int node_key) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; builder->SetRootNode(node_key); API_END(); } @@ -319,7 +319,7 @@ int TreeliteTreeBuilderSetNumericalTestNode( ValueHandle threshold, int default_left, int left_child_key, int right_child_key) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; builder->SetNumericalTestNode(node_key, feature_id, opname, *static_cast(threshold), (default_left != 0), left_child_key, right_child_key); @@ -332,10 +332,10 @@ int TreeliteTreeBuilderSetCategoricalTestNode( int left_child_key, int right_child_key) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; std::vector vec(left_categories_len); for (size_t i = 0; i < left_categories_len; ++i) { - CHECK(left_categories[i] <= std::numeric_limits::max()); + TREELITE_CHECK(left_categories[i] <= std::numeric_limits::max()); vec[i] = static_cast(left_categories[i]); } builder->SetCategoricalTestNode(node_key, feature_id, vec, (default_left != 0), @@ -346,7 +346,7 @@ int TreeliteTreeBuilderSetCategoricalTestNode( int TreeliteTreeBuilderSetLeafNode(TreeBuilderHandle handle, int node_key, ValueHandle leaf_value) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; builder->SetLeafNode(node_key, *static_cast(leaf_value)); API_END(); } @@ -355,11 +355,11 @@ int TreeliteTreeBuilderSetLeafVectorNode(TreeBuilderHandle handle, int node_key, const ValueHandle* leaf_vector, size_t leaf_vector_len) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted TreeBuilder object"; std::vector vec(leaf_vector_len); - CHECK(leaf_vector) << "leaf_vector argument must not be null"; + TREELITE_CHECK(leaf_vector) << "leaf_vector argument must not be null"; for (size_t i = 0; i < leaf_vector_len; ++i) { - CHECK(leaf_vector[i]) << "leaf_vector[" << i << "] contains an empty Value handle"; + TREELITE_CHECK(leaf_vector[i]) << "leaf_vector[" << i << "] contains an empty Value handle"; vec[i] = *static_cast(leaf_vector[i]); } builder->SetLeafVectorNode(node_key, vec); @@ -381,7 +381,7 @@ int TreeliteModelBuilderSetModelParam(ModelBuilderHandle handle, const char* nam const char* value) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted ModelBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted ModelBuilder object"; builder->SetModelParam(name, value); API_END(); } @@ -396,9 +396,9 @@ int TreeliteModelBuilderInsertTree(ModelBuilderHandle handle, TreeBuilderHandle int index) { API_BEGIN(); auto* model_builder = static_cast(handle); - CHECK(model_builder) << "Detected dangling reference to deleted ModelBuilder object"; + TREELITE_CHECK(model_builder) << "Detected dangling reference to deleted ModelBuilder object"; auto* tree_builder = static_cast(tree_builder_handle); - CHECK(tree_builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(tree_builder) << "Detected dangling reference to deleted TreeBuilder object"; return model_builder->InsertTree(tree_builder, index); API_END(); } @@ -406,9 +406,9 @@ int TreeliteModelBuilderInsertTree(ModelBuilderHandle handle, TreeBuilderHandle int TreeliteModelBuilderGetTree(ModelBuilderHandle handle, int index, TreeBuilderHandle *out) { API_BEGIN(); auto* model_builder = static_cast(handle); - CHECK(model_builder) << "Detected dangling reference to deleted ModelBuilder object"; + TREELITE_CHECK(model_builder) << "Detected dangling reference to deleted ModelBuilder object"; auto* tree_builder = model_builder->GetTree(index); - CHECK(tree_builder) << "Detected dangling reference to deleted TreeBuilder object"; + TREELITE_CHECK(tree_builder) << "Detected dangling reference to deleted TreeBuilder object"; *out = static_cast(tree_builder); API_END(); } @@ -416,7 +416,7 @@ int TreeliteModelBuilderGetTree(ModelBuilderHandle handle, int index, TreeBuilde int TreeliteModelBuilderDeleteTree(ModelBuilderHandle handle, int index) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted ModelBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted ModelBuilder object"; builder->DeleteTree(index); API_END(); } @@ -424,7 +424,7 @@ int TreeliteModelBuilderDeleteTree(ModelBuilderHandle handle, int index) { int TreeliteModelBuilderCommitModel(ModelBuilderHandle handle, ModelHandle* out) { API_BEGIN(); auto* builder = static_cast(handle); - CHECK(builder) << "Detected dangling reference to deleted ModelBuilder object"; + TREELITE_CHECK(builder) << "Detected dangling reference to deleted ModelBuilder object"; std::unique_ptr model = builder->CommitModel(); *out = static_cast(model.release()); API_END(); diff --git a/src/c_api/c_api_runtime.cc b/src/c_api/c_api_runtime.cc index f2b48e6e..06fa1fa8 100644 --- a/src/c_api/c_api_runtime.cc +++ b/src/c_api/c_api_runtime.cc @@ -45,7 +45,7 @@ int TreelitePredictorPredictBatch( const std::string err_msg = std::string("Too many columns (features) in the given batch. " "Number of features must not exceed ") + std::to_string(num_feature); - CHECK_LE(dmat->GetNumCol(), num_feature) << err_msg; + TREELITE_CHECK_LE(dmat->GetNumCol(), num_feature) << err_msg; *out_result_size = predictor->PredictBatch(dmat, verbose, (pred_margin != 0), out_result); API_END(); } diff --git a/src/compiler/ast/dump.cc b/src/compiler/ast/dump.cc index c2f7c317..26b63e71 100644 --- a/src/compiler/ast/dump.cc +++ b/src/compiler/ast/dump.cc @@ -13,7 +13,7 @@ void get_dump_from_node(std::ostringstream* oss, int indent) { (*oss) << std::string(indent, ' ') << node->GetDump() << "\n"; for (const treelite::compiler::ASTNode* child : node->children) { - CHECK(child); + TREELITE_CHECK(child); get_dump_from_node(oss, child, indent + 2); } } diff --git a/src/compiler/ast/fold_code.cc b/src/compiler/ast/fold_code.cc index 71a89e9c..3b04b034 100644 --- a/src/compiler/ast/fold_code.cc +++ b/src/compiler/ast/fold_code.cc @@ -62,7 +62,7 @@ bool fold_code(ASTNode* node, CodeFoldingContext* context, break; } } - CHECK_NE(node_loc, -1); // parent should have a link to current node + TREELITE_CHECK_NE(node_loc, -1); // parent should have a link to current node parent_node->children[node_loc] = context->create_new_translation_unit ? tu_node : folder_node; folder_node->children.push_back(node); diff --git a/src/compiler/ast/quantize.cc b/src/compiler/ast/quantize.cc index f39a7d9c..99c62def 100644 --- a/src/compiler/ast/quantize.cc +++ b/src/compiler/ast/quantize.cc @@ -17,7 +17,7 @@ static void scan_thresholds(ASTNode* node, std::vector>* cut_pts) { NumericalConditionNode* num_cond; if ( (num_cond = dynamic_cast*>(node)) ) { - CHECK(!num_cond->quantized) << "should not be already quantized"; + TREELITE_CHECK(!num_cond->quantized) << "should not be already quantized"; const ThresholdType threshold = num_cond->threshold.float_val; if (std::isfinite(threshold)) { (*cut_pts)[num_cond->split_index].insert(threshold); @@ -33,13 +33,13 @@ static void rewrite_thresholds(ASTNode* node, const std::vector>& cut_pts) { NumericalConditionNode* num_cond; if ( (num_cond = dynamic_cast*>(node)) ) { - CHECK(!num_cond->quantized) << "should not be already quantized"; + TREELITE_CHECK(!num_cond->quantized) << "should not be already quantized"; const ThresholdType threshold = num_cond->threshold.float_val; if (std::isfinite(threshold)) { const auto& v = cut_pts[num_cond->split_index]; { auto loc = math::binary_search(v.begin(), v.end(), threshold); - CHECK(loc != v.end()); + TREELITE_CHECK(loc != v.end()); num_cond->threshold.int_val = static_cast(loc - v.begin()) * 2; } { @@ -75,9 +75,9 @@ ASTBuilder::QuantizeThresholds() { /* revise all numerical splits by quantizing thresholds */ rewrite_thresholds(this->main_node, cut_pts_vec); - CHECK_EQ(this->main_node->children.size(), 1); + TREELITE_CHECK_EQ(this->main_node->children.size(), 1); ASTNode* top_ac_node = this->main_node->children[0]; - CHECK(dynamic_cast(top_ac_node)); + TREELITE_CHECK(dynamic_cast(top_ac_node)); /* dynamic_cast<> is used here to check node types. This is to ensure that we don't accidentally call QuantizeThresholds() twice. */ diff --git a/src/compiler/ast/split.cc b/src/compiler/ast/split.cc index a7358417..cf0c6f39 100644 --- a/src/compiler/ast/split.cc +++ b/src/compiler/ast/split.cc @@ -21,22 +21,23 @@ template void ASTBuilder::Split(int parallel_comp) { if (parallel_comp <= 0) { - LOG(INFO) << "Parallel compilation disabled; all member trees will be " - << "dumped to a single source file. This may increase " - << "compilation time and memory usage."; + TREELITE_LOG(INFO) << "Parallel compilation disabled; all member trees will be " + << "dumped to a single source file. This may increase " + << "compilation time and memory usage."; return; } - LOG(INFO) << "Parallel compilation enabled; member trees will be " - << "divided into " << parallel_comp << " translation units."; - CHECK_EQ(this->main_node->children.size(), 1); + TREELITE_LOG(INFO) << "Parallel compilation enabled; member trees will be " + << "divided into " << parallel_comp << " translation units."; + TREELITE_CHECK_EQ(this->main_node->children.size(), 1); ASTNode* top_ac_node = this->main_node->children[0]; - CHECK(dynamic_cast(top_ac_node)); + TREELITE_CHECK(dynamic_cast(top_ac_node)); /* tree_head[i] stores reference to head of tree i */ std::vector tree_head; for (ASTNode* node : top_ac_node->children) { - CHECK(dynamic_cast(node) || dynamic_cast*>(node) - || dynamic_cast(node)); + TREELITE_CHECK(dynamic_cast(node) + || dynamic_cast*>(node) + || dynamic_cast(node)); tree_head.push_back(node); } /* dynamic_cast<> is used here to check node types. This is to ensure diff --git a/src/compiler/ast_native.cc b/src/compiler/ast_native.cc index a35d32e4..cee1a616 100644 --- a/src/compiler/ast_native.cc +++ b/src/compiler/ast_native.cc @@ -48,9 +48,9 @@ class ASTNativeCompilerImpl { CompiledModel cm; cm.backend = "native"; - CHECK(model.task_type != TaskType::kMultiClfCategLeaf) + TREELITE_CHECK(model.task_type != TaskType::kMultiClfCategLeaf) << "Model task type unsupported by ASTNativeCompiler"; - CHECK(model.task_param.output_type == TaskParam::OutputType::kFloat) + TREELITE_CHECK(model.task_param.output_type == TaskParam::OutputType::kFloat) << "ASTNativeCompiler only supports models with float output"; num_feature_ = model.num_feature; @@ -74,8 +74,8 @@ class ASTNativeCompilerImpl { annotator.Load(fi); const auto annotation = annotator.Get(); builder.LoadDataCounts(annotation); - LOG(INFO) << "Loading node frequencies from `" - << param_.annotate_in << "'"; + TREELITE_LOG(INFO) << "Loading node frequencies from `" + << param_.annotate_in << "'"; } builder.Split(param_.parallel_comp); if (param_.quantize > 0) { @@ -128,7 +128,7 @@ class ASTNativeCompilerImpl { } CompiledModel Compile(const Model& model) { - CHECK(model.GetLeafOutputType() != TypeInfo::kUInt32) + TREELITE_CHECK(model.GetLeafOutputType() != TypeInfo::kUInt32) << "Integer leaf outputs not yet supported"; this->pred_tranform_func_ = PredTransformFunction("native", model); return model.Dispatch([this](const auto& model_handle) { @@ -178,7 +178,7 @@ class ASTNativeCompilerImpl { } else if ( (t7 = dynamic_cast(node)) ) { HandleCodeFolderNode(t7, dest, indent); } else { - LOG(FATAL) << "Unrecognized AST node type"; + TREELITE_LOG(FATAL) << "Unrecognized AST node type"; } } @@ -247,24 +247,24 @@ class ASTNativeCompilerImpl { "threshold_type_Node"_a = (param_.quantize > 0 ? std::string("int") : threshold_type)), indent); - CHECK_EQ(node->children.size(), 1); + TREELITE_CHECK_EQ(node->children.size(), 1); WalkAST(node->children[0], dest, indent + 2); std::string optional_average_field; if (node->average_result) { if (task_type_ == TaskType::kMultiClfGrovePerClass) { - CHECK(task_param_.grove_per_class); - CHECK_EQ(task_param_.leaf_vector_size, 1); - CHECK_GT(task_param_.num_class, 1); - CHECK_EQ(node->num_tree % task_param_.num_class, 0) + TREELITE_CHECK(task_param_.grove_per_class); + TREELITE_CHECK_EQ(task_param_.leaf_vector_size, 1); + TREELITE_CHECK_GT(task_param_.num_class, 1); + TREELITE_CHECK_EQ(node->num_tree % task_param_.num_class, 0) << "Expected the number of trees to be divisible by the number of classes"; int num_boosting_round = node->num_tree / static_cast(task_param_.num_class); optional_average_field = fmt::format(" / {}", num_boosting_round); } else { - CHECK(task_type_ == TaskType::kBinaryClfRegr - || task_type_ == TaskType::kMultiClfProbDistLeaf); - CHECK_EQ(task_param_.num_class, task_param_.leaf_vector_size); - CHECK(!task_param_.grove_per_class); + TREELITE_CHECK(task_type_ == TaskType::kBinaryClfRegr + || task_type_ == TaskType::kMultiClfProbDistLeaf); + TREELITE_CHECK_EQ(task_param_.num_class, task_param_.leaf_vector_size); + TREELITE_CHECK(!task_param_.grove_per_class); optional_average_field = fmt::format(" / {}", node->num_tree); } } @@ -331,7 +331,7 @@ class ASTNativeCompilerImpl { "condition"_a = condition); } else { /* categorical split */ const CategoricalConditionNode* t2 = dynamic_cast(node); - CHECK(t2); + TREELITE_CHECK(t2); condition_with_na_check = ExtractCategoricalCondition(t2); } if (node->children[0]->data_count && node->children[1]->data_count) { @@ -344,7 +344,7 @@ class ASTNativeCompilerImpl { } AppendToBuffer(dest, fmt::format("if ({}) {{\n", condition_with_na_check), indent); - CHECK_EQ(node->children.size(), 2); + TREELITE_CHECK_EQ(node->children.size(), 2); WalkAST(node->children[0], dest, indent + 2); AppendToBuffer(dest, "} else {\n", indent); WalkAST(node->children[1], dest, indent + 2); @@ -356,7 +356,7 @@ class ASTNativeCompilerImpl { const std::string& dest, size_t indent) { AppendToBuffer(dest, RenderOutputStatement(node), indent); - CHECK_EQ(node->children.size(), 0); + TREELITE_CHECK_EQ(node->children.size(), 0); } template @@ -393,7 +393,7 @@ class ASTNativeCompilerImpl { AppendToBuffer(new_file, fmt::format("#include \"header.h\"\n" "{} {{\n", unit_function_signature), 0); - CHECK_EQ(node->children.size(), 1); + TREELITE_CHECK_EQ(node->children.size(), 1); WalkAST(node->children[0], new_file, 2); if (task_param_.num_class > 1) { AppendToBuffer(new_file, @@ -481,7 +481,7 @@ class ASTNativeCompilerImpl { "{array_th_len}\n" "}};\n", "array_th_len"_a = array_th_len), 0); } - CHECK_EQ(node->children.size(), 1); + TREELITE_CHECK_EQ(node->children.size(), 1); WalkAST(node->children[0], dest, indent); } @@ -489,7 +489,7 @@ class ASTNativeCompilerImpl { void HandleCodeFolderNode(const CodeFolderNode* node, const std::string& dest, size_t indent) { - CHECK_EQ(node->children.size(), 1); + TREELITE_CHECK_EQ(node->children.size(), 1); const int node_id = node->children[0]->node_id; const int tree_id = node->children[0]->tree_id; @@ -616,7 +616,7 @@ class ASTNativeCompilerImpl { std::string result; std::vector bitmap = common_util::GetCategoricalBitmap(node->matching_categories); - CHECK_GE(bitmap.size(), 1); + TREELITE_CHECK_GE(bitmap.size(), 1); bool all_zeros = true; for (uint64_t e : bitmap) { all_zeros &= (e == 0); @@ -670,7 +670,7 @@ class ASTNativeCompilerImpl { if (task_param_.num_class > 1) { if (node->is_vector) { // multi-class classification with random forest - CHECK_EQ(node->vector.size(), static_cast(task_param_.num_class)) + TREELITE_CHECK_EQ(node->vector.size(), static_cast(task_param_.num_class)) << "Ill-formed model: leaf vector must be of length [num_class]"; for (size_t group_id = 0; group_id < task_param_.num_class; ++group_id) { output_statement @@ -700,10 +700,10 @@ class ASTNativeCompilerImpl { ASTNativeCompiler::ASTNativeCompiler(const CompilerParam& param) : pimpl_(std::make_unique(param)) { if (param.verbose > 0) { - LOG(INFO) << "Using ASTNativeCompiler"; + TREELITE_LOG(INFO) << "Using ASTNativeCompiler"; } if (param.dump_array_as_elf > 0) { - LOG(INFO) << "Warning: 'dump_array_as_elf' parameter is not applicable " + TREELITE_LOG(INFO) << "Warning: 'dump_array_as_elf' parameter is not applicable " "for ASTNativeCompiler"; } } diff --git a/src/compiler/common/code_folding_util.h b/src/compiler/common/code_folding_util.h index af2de630..77891669 100644 --- a/src/compiler/common/code_folding_util.h +++ b/src/compiler/common/code_folding_util.h @@ -37,7 +37,7 @@ RenderCodeFolderArrays(const CodeFolderNode* node, std::string* array_cat_begin, std::string* output_switch_statements, Operator* common_comp_op) { - CHECK_EQ(node->children.size(), 1); + TREELITE_CHECK_EQ(node->children.size(), 1); const int tree_id = node->children[0]->tree_id; // list of descendants, with newly assigned ID's std::unordered_map descendants; @@ -58,12 +58,12 @@ RenderCodeFolderArrays(const CodeFolderNode* node, while (!Q.empty()) { ASTNode* e = Q.front(); Q.pop(); // sanity check: all descendants must have same tree_id - CHECK_EQ(e->tree_id, tree_id); + TREELITE_CHECK_EQ(e->tree_id, tree_id); // sanity check: all descendants must be ConditionNode or OutputNode ConditionNode* t1 = dynamic_cast(e); OutputNode* t2 = dynamic_cast*>(e); NumericalConditionNode* t3; - CHECK(t1 || t2); + TREELITE_CHECK(t1 || t2); if (t2) { // e is OutputNode descendants[e] = new_leaf_id--; } else { @@ -77,7 +77,7 @@ RenderCodeFolderArrays(const CodeFolderNode* node, } } // sanity check: all numerical splits must have identical comparison operators - CHECK_LE(ops.size(), 1); + TREELITE_CHECK_LE(ops.size(), 1); *common_comp_op = ops.empty() ? Operator::kLT : *ops.begin(); } @@ -102,7 +102,7 @@ RenderCodeFolderArrays(const CodeFolderNode* node, output_nodes.push_back(t1); // don't render OutputNode but save it for later } else { - CHECK_EQ(e->children.size(), 2U); + TREELITE_CHECK_EQ(e->children.size(), 2U); left_child_id = descendants[ e->children[0] ]; right_child_id = descendants[ e->children[1] ]; if ( (t2 = dynamic_cast*>(e)) ) { @@ -112,7 +112,7 @@ RenderCodeFolderArrays(const CodeFolderNode* node, = quantize ? std::to_string(t2->threshold.int_val) : ToStringHighPrecision(t2->threshold.float_val); } else { - CHECK((t3 = dynamic_cast(e))); + TREELITE_CHECK((t3 = dynamic_cast(e))); default_left = t3->default_left; split_index = t3->split_index; threshold = "-1"; // dummy value diff --git a/src/compiler/compiler.cc b/src/compiler/compiler.cc index 03d8abb6..de9e2c00 100644 --- a/src/compiler/compiler.cc +++ b/src/compiler/compiler.cc @@ -20,7 +20,7 @@ Compiler* Compiler::Create(const std::string& name, const char* param_json_str) } else if (name == "failsafe") { return new compiler::FailSafeCompiler(param); } else { - LOG(FATAL) << "Unrecognized compiler '" << name << "'"; + TREELITE_LOG(FATAL) << "Unrecognized compiler '" << name << "'"; return nullptr; } } @@ -41,36 +41,37 @@ CompilerParam::ParseFromJSON(const char* param_json_str) { rapidjson::Document doc; doc.Parse(param_json_str); - CHECK(doc.IsObject()) << "Got an invalid JSON string:\n" << param_json_str; + TREELITE_CHECK(doc.IsObject()) << "Got an invalid JSON string:\n" << param_json_str; for (const auto& e : doc.GetObject()) { const std::string key = e.name.GetString(); if (key == "annotate_in") { - CHECK(e.value.IsString()) << "Expected a string for 'annotate_in'"; + TREELITE_CHECK(e.value.IsString()) << "Expected a string for 'annotate_in'"; param.annotate_in = e.value.GetString(); } else if (key == "quantize") { - CHECK(e.value.IsInt()) << "Expected an integer for 'quantize'"; + TREELITE_CHECK(e.value.IsInt()) << "Expected an integer for 'quantize'"; param.quantize = e.value.GetInt(); - CHECK_GE(param.quantize, 0) << "'quantize' must be 0 or greater"; + TREELITE_CHECK_GE(param.quantize, 0) << "'quantize' must be 0 or greater"; } else if (key == "parallel_comp") { - CHECK(e.value.IsInt()) << "Expected an integer for 'parallel_comp'"; + TREELITE_CHECK(e.value.IsInt()) << "Expected an integer for 'parallel_comp'"; param.parallel_comp = e.value.GetInt(); - CHECK_GE(param.parallel_comp, 0) << "'parallel_comp' must be 0 or greater"; + TREELITE_CHECK_GE(param.parallel_comp, 0) << "'parallel_comp' must be 0 or greater"; } else if (key == "verbose") { - CHECK(e.value.IsInt()) << "Expected an integer for 'verbose'"; + TREELITE_CHECK(e.value.IsInt()) << "Expected an integer for 'verbose'"; param.verbose = e.value.GetInt(); } else if (key == "native_lib_name") { - CHECK(e.value.IsString()) << "Expected a string for 'native_lib_name'"; + TREELITE_CHECK(e.value.IsString()) << "Expected a string for 'native_lib_name'"; param.native_lib_name = e.value.GetString(); } else if (key == "code_folding_req") { - CHECK(e.value.IsDouble()) << "Expected a floating-point decimal for 'code_folding_req'"; + TREELITE_CHECK(e.value.IsDouble()) + << "Expected a floating-point decimal for 'code_folding_req'"; param.code_folding_req = e.value.GetDouble(); - CHECK_GE(param.code_folding_req, 0) << "'code_folding_req' must be 0 or greater"; + TREELITE_CHECK_GE(param.code_folding_req, 0) << "'code_folding_req' must be 0 or greater"; } else if (key == "dump_array_as_elf") { - CHECK(e.value.IsInt()) << "Expected an integer for 'dump_array_as_elf'"; + TREELITE_CHECK(e.value.IsInt()) << "Expected an integer for 'dump_array_as_elf'"; param.dump_array_as_elf = e.value.GetInt(); - CHECK_GE(param.dump_array_as_elf, 0) << "'dump_array_as_elf' must be 0 or greater"; + TREELITE_CHECK_GE(param.dump_array_as_elf, 0) << "'dump_array_as_elf' must be 0 or greater"; } else { - LOG(FATAL) << "Unrecognized key '" << key << "' in JSON"; + TREELITE_LOG(FATAL) << "Unrecognized key '" << key << "' in JSON"; } } diff --git a/src/compiler/elf/elf_formatter.cc b/src/compiler/elf/elf_formatter.cc index fe457c10..71c051d8 100644 --- a/src/compiler/elf/elf_formatter.cc +++ b/src/compiler/elf/elf_formatter.cc @@ -205,11 +205,11 @@ namespace treelite { namespace compiler { void AllocateELFHeader(std::vector* elf_buffer) { - LOG(FATAL) << "dump_array_as_elf is not supported in non-Linux OSes"; + TREELITE_LOG(FATAL) << "dump_array_as_elf is not supported in non-Linux OSes"; } void FormatArrayAsELF(std::vector* elf_buffer) { - LOG(FATAL) << "dump_array_as_elf is not supported in non-Linux OSes"; + TREELITE_LOG(FATAL) << "dump_array_as_elf is not supported in non-Linux OSes"; } } // namespace compiler diff --git a/src/compiler/failsafe.cc b/src/compiler/failsafe.cc index bccca74e..39d1d81b 100644 --- a/src/compiler/failsafe.cc +++ b/src/compiler/failsafe.cc @@ -144,7 +144,7 @@ inline std::pair FormatNodesArray( for (const auto& tree : model.trees) { for (int nid = 0; nid < tree.num_nodes; ++nid) { if (tree.IsLeaf(nid)) { - CHECK(!tree.HasLeafVector(nid)) + TREELITE_CHECK(!tree.HasLeafVector(nid)) << "multi-class random forest classifier is not supported in FailSafeCompiler"; nodes << fmt::format("{{ 0x{sindex:X}, {info}, {cleft}, {cright} }}", "sindex"_a = 0, @@ -152,8 +152,8 @@ inline std::pair FormatNodesArray( "cleft"_a = -1, "cright"_a = -1); } else { - CHECK(tree.SplitType(nid) == treelite::SplitFeatureType::kNumerical - && !tree.HasMatchingCategories(nid)) + TREELITE_CHECK(tree.SplitType(nid) == treelite::SplitFeatureType::kNumerical + && !tree.HasMatchingCategories(nid)) << "categorical splits are not supported in FailSafeCompiler"; nodes << fmt::format("{{ 0x{sindex:X}, {info}, {cleft}, {cright} }}", "sindex"_a @@ -184,12 +184,12 @@ inline std::pair, std::string> FormatNodesArrayELF( for (const auto& tree : model.trees) { for (int nid = 0; nid < tree.num_nodes; ++nid) { if (tree.IsLeaf(nid)) { - CHECK(!tree.HasLeafVector(nid)) + TREELITE_CHECK(!tree.HasLeafVector(nid)) << "multi-class random forest classifier is not supported in FailSafeCompiler"; val = {0, static_cast(tree.LeafValue(nid)), -1, -1}; } else { - CHECK(tree.SplitType(nid) == treelite::SplitFeatureType::kNumerical - && !tree.HasMatchingCategories(nid)) + TREELITE_CHECK(tree.SplitType(nid) == treelite::SplitFeatureType::kNumerical + && !tree.HasMatchingCategories(nid)) << "categorical splits are not supported in FailSafeCompiler"; val = {(tree.SplitIndex(nid) | (static_cast(tree.DefaultLeft(nid)) << 31)), static_cast(tree.Threshold(nid)), tree.LeftChild(nid), tree.RightChild(nid)}; @@ -219,7 +219,7 @@ inline std::string GetCommonOp(const treelite::ModelImpl& model) { } } // sanity check: all numerical splits must have identical comparison operators - CHECK_EQ(ops.size(), 1) + TREELITE_CHECK_EQ(ops.size(), 1) << "FailSafeCompiler only supports models where all splits use identical comparison operator."; return treelite::OpName(*ops.begin()); } @@ -241,8 +241,8 @@ class FailSafeCompilerImpl { explicit FailSafeCompilerImpl(const CompilerParam& param) : param_(param) {} CompiledModel Compile(const Model& model_ptr) { - CHECK(model_ptr.GetThresholdType() == TypeInfo::kFloat32 - && model_ptr.GetLeafOutputType() == TypeInfo::kFloat32) + TREELITE_CHECK(model_ptr.GetThresholdType() == TypeInfo::kFloat32 + && model_ptr.GetLeafOutputType() == TypeInfo::kFloat32) << "Failsafe compiler only supports models with float32 thresholds and float32 leaf outputs"; const auto& model = dynamic_cast&>(model_ptr); @@ -251,12 +251,12 @@ class FailSafeCompilerImpl { num_feature_ = model.num_feature; num_class_ = model.task_param.num_class; - CHECK(!model.average_tree_output) + TREELITE_CHECK(!model.average_tree_output) << "Averaging tree output is not supported in FailSafeCompiler"; - CHECK(model.task_type == TaskType::kBinaryClfRegr - || model.task_type == TaskType::kMultiClfGrovePerClass) + TREELITE_CHECK(model.task_type == TaskType::kBinaryClfRegr + || model.task_type == TaskType::kMultiClfGrovePerClass) << "Model task type unsupported by FailSafeCompiler"; - CHECK_EQ(model.task_param.leaf_vector_size, 1) + TREELITE_CHECK_EQ(model.task_param.leaf_vector_size, 1) << "Model with leaf vectors is not support by FailSafeCompiler"; pred_tranform_func_ = PredTransformFunction("native", model_ptr); files_.clear(); @@ -293,7 +293,7 @@ class FailSafeCompilerImpl { std::vector nodes_elf; if (param_.dump_array_as_elf > 0) { if (param_.verbose > 0) { - LOG(INFO) << "Dumping arrays as an ELF relocatable object..."; + TREELITE_LOG(INFO) << "Dumping arrays as an ELF relocatable object..."; } std::tie(nodes_elf, nodes_row_ptr) = FormatNodesArrayELF(model); } else { @@ -397,22 +397,22 @@ class FailSafeCompilerImpl { FailSafeCompiler::FailSafeCompiler(const CompilerParam& param) : pimpl_(std::make_unique(param)) { if (param.verbose > 0) { - LOG(INFO) << "Using FailSafeCompiler"; + TREELITE_LOG(INFO) << "Using FailSafeCompiler"; } if (param.annotate_in != "NULL") { - LOG(INFO) << "Warning: 'annotate_in' parameter is not applicable for " + TREELITE_LOG(INFO) << "Warning: 'annotate_in' parameter is not applicable for " "FailSafeCompiler"; } if (param.quantize > 0) { - LOG(INFO) << "Warning: 'quantize' parameter is not applicable for " + TREELITE_LOG(INFO) << "Warning: 'quantize' parameter is not applicable for " "FailSafeCompiler"; } if (param.parallel_comp > 0) { - LOG(INFO) << "Warning: 'parallel_comp' parameter is not applicable for " + TREELITE_LOG(INFO) << "Warning: 'parallel_comp' parameter is not applicable for " "FailSafeCompiler"; } if (std::isfinite(param.code_folding_req)) { - LOG(INFO) << "Warning: 'code_folding_req' parameter is not applicable " + TREELITE_LOG(INFO) << "Warning: 'code_folding_req' parameter is not applicable " "for FailSafeCompiler"; } } diff --git a/src/compiler/native/pred_transform.h b/src/compiler/native/pred_transform.h index 9b247946..c56b1f33 100644 --- a/src/compiler/native/pred_transform.h +++ b/src/compiler/native/pred_transform.h @@ -54,7 +54,7 @@ inline std::string hinge(const Model& model) { inline std::string sigmoid(const Model& model) { const float alpha = model.param.sigmoid_alpha; const TypeInfo threshold_type = model.GetThresholdType(); - CHECK_GT(alpha, 0.0f) << "sigmoid: alpha must be strictly positive"; + TREELITE_CHECK_GT(alpha, 0.0f) << "sigmoid: alpha must be strictly positive"; return fmt::format( R"TREELITETEMPLATE(static inline {threshold_type} pred_transform({threshold_type} margin) {{ const {threshold_type} alpha = ({threshold_type}){alpha}; @@ -87,7 +87,7 @@ R"TREELITETEMPLATE(static inline {threshold_type} pred_transform({threshold_type } inline std::string identity_multiclass(const Model& model) { - CHECK_GT(model.task_param.num_class, 1) + TREELITE_CHECK_GT(model.task_param.num_class, 1) << "identity_multiclass: model is not a proper multi-class classifier"; return fmt::format( R"TREELITETEMPLATE(static inline size_t pred_transform({threshold_type}* pred) {{ @@ -98,7 +98,7 @@ R"TREELITETEMPLATE(static inline size_t pred_transform({threshold_type}* pred) { } inline std::string max_index(const Model& model) { - CHECK_GT(model.task_param.num_class, 1) + TREELITE_CHECK_GT(model.task_param.num_class, 1) << "max_index: model is not a proper multi-class classifier"; const TypeInfo threshold_type = model.GetThresholdType(); return fmt::format( @@ -120,7 +120,7 @@ R"TREELITETEMPLATE(static inline size_t pred_transform({threshold_type}* pred) { } inline std::string softmax(const Model& model) { - CHECK_GT(model.task_param.num_class, 1) + TREELITE_CHECK_GT(model.task_param.num_class, 1) << "softmax: model is not a proper multi-class classifier"; const TypeInfo threshold_type = model.GetThresholdType(); return fmt::format( @@ -150,12 +150,12 @@ R"TREELITETEMPLATE(static inline size_t pred_transform({threshold_type}* pred) { } inline std::string multiclass_ova(const Model& model) { - CHECK(model.task_param.num_class > 1) + TREELITE_CHECK(model.task_param.num_class > 1) << "multiclass_ova: model is not a proper multi-class classifier"; const unsigned int num_class = model.task_param.num_class; const float alpha = model.param.sigmoid_alpha; const TypeInfo threshold_type = model.GetThresholdType(); - CHECK_GT(alpha, 0.0f) << "multiclass_ova: alpha must be strictly positive"; + TREELITE_CHECK_GT(alpha, 0.0f) << "multiclass_ova: alpha must be strictly positive"; return fmt::format( R"TREELITETEMPLATE(static inline size_t pred_transform({threshold_type}* pred) {{ const {threshold_type} alpha = ({threshold_type}){alpha}; diff --git a/src/compiler/pred_transform.cc b/src/compiler/pred_transform.cc index 10a5feef..fb77ee77 100644 --- a/src/compiler/pred_transform.cc +++ b/src/compiler/pred_transform.cc @@ -26,7 +26,7 @@ FUNC_NAME(const std::string& backend, const Model& model) { \ if (backend == "native") { \ return treelite::compiler::native::pred_transform::FUNC_NAME(model); \ } else { \ - LOG(FATAL) << "Unrecognized backend: " << backend; \ + TREELITE_LOG(FATAL) << "Unrecognized backend: " << backend; \ return std::string(); \ } \ } @@ -113,10 +113,10 @@ treelite::compiler::PredTransformFunction(const std::string& backend, for (const auto& e : pred_transform_multiclass_db) { oss << "'" << e.first << "', "; } - LOG(FATAL) << "Invalid argument given for `pred_transform` parameter. " - << "For multi-class classification, you should set " - << "`pred_transform` to one of the following: " - << "{ " << oss.str() << " }"; + TREELITE_LOG(FATAL) << "Invalid argument given for `pred_transform` parameter. " + << "For multi-class classification, you should set " + << "`pred_transform` to one of the following: " + << "{ " << oss.str() << " }"; } return (it->second)(backend, model); } else { @@ -126,10 +126,10 @@ treelite::compiler::PredTransformFunction(const std::string& backend, for (const auto& e : pred_transform_db) { oss << "'" << e.first << "', "; } - LOG(FATAL) << "Invalid argument given for `pred_transform` parameter. " - << "For any task that is NOT multi-class classification, you " - << "should set `pred_transform` to one of the following: " - << "{ " << oss.str() << " }"; + TREELITE_LOG(FATAL) << "Invalid argument given for `pred_transform` parameter. " + << "For any task that is NOT multi-class classification, you " + << "should set `pred_transform` to one of the following: " + << "{ " << oss.str() << " }"; } return (it->second)(backend, model); } diff --git a/src/data.cc b/src/data.cc index e2346fea..fccd50a5 100644 --- a/src/data.cc +++ b/src/data.cc @@ -35,7 +35,7 @@ DenseDMatrix::Create(const void* data, const void* missing_value, size_t num_row std::unique_ptr DenseDMatrix::Create( TypeInfo type, const void* data, const void* missing_value, size_t num_row, size_t num_col) { - CHECK(type != TypeInfo::kInvalid) << "ElementType cannot be invalid"; + TREELITE_CHECK(type != TypeInfo::kInvalid) << "ElementType cannot be invalid"; switch (type) { case TypeInfo::kFloat32: return Create(data, missing_value, num_row, num_col); @@ -44,7 +44,7 @@ DenseDMatrix::Create( case TypeInfo::kInvalid: case TypeInfo::kUInt32: default: - LOG(FATAL) << "Invalid type for DenseDMatrix: " << TypeInfoToString(type); + TREELITE_LOG(FATAL) << "Invalid type for DenseDMatrix: " << TypeInfoToString(type); } return std::unique_ptr(nullptr); } @@ -133,7 +133,7 @@ CSRDMatrix::Create(const void* data, const uint32_t* col_ind, std::unique_ptr CSRDMatrix::Create(TypeInfo type, const void* data, const uint32_t* col_ind, const size_t* row_ptr, size_t num_row, size_t num_col) { - CHECK(type != TypeInfo::kInvalid) << "ElementType cannot be invalid"; + TREELITE_CHECK(type != TypeInfo::kInvalid) << "ElementType cannot be invalid"; switch (type) { case TypeInfo::kFloat32: return Create(data, col_ind, row_ptr, num_row, num_col); @@ -142,7 +142,7 @@ CSRDMatrix::Create(TypeInfo type, const void* data, const uint32_t* col_ind, con case TypeInfo::kInvalid: case TypeInfo::kUInt32: default: - LOG(FATAL) << "Invalid type for CSRDMatrix: " << TypeInfoToString(type); + TREELITE_LOG(FATAL) << "Invalid type for CSRDMatrix: " << TypeInfoToString(type); } return std::unique_ptr(nullptr); } diff --git a/src/filesystem.cc b/src/filesystem.cc index 16fd8439..07582b00 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -43,7 +43,7 @@ inline void HandleSystemError(const std::string& msg) { #else const std::string msg_err(strerror(errno)); #endif - LOG(FATAL) << msg << "\nReason: " << msg_err; + TREELITE_LOG(FATAL) << msg << "\nReason: " << msg_err; } } // anonymous namespace @@ -63,8 +63,8 @@ void CreateDirectoryIfNotExist(const char* dirpath) { } } else { if (!(ftyp & FILE_ATTRIBUTE_DIRECTORY)) { - LOG(FATAL) << "CreateDirectoryIfNotExist: " - << dirpath << " is a file, not a directory"; + TREELITE_LOG(FATAL) << "CreateDirectoryIfNotExist: " + << dirpath << " is a file, not a directory"; } } #else @@ -78,8 +78,8 @@ void CreateDirectoryIfNotExist(const char* dirpath) { } } else { if (!S_ISDIR(sb.st_mode)) { - LOG(FATAL) << "CreateDirectoryIfNotExist: " - << dirpath << " is a file, not a directory"; + TREELITE_LOG(FATAL) << "CreateDirectoryIfNotExist: " + << dirpath << " is a file, not a directory"; } } #endif diff --git a/src/frontend/builder.cc b/src/frontend/builder.cc index f94095fc..07145b04 100644 --- a/src/frontend/builder.cc +++ b/src/frontend/builder.cc @@ -84,11 +84,11 @@ struct ModelBuilderImpl { : trees(), num_feature(num_feature), num_class(num_class), average_tree_output(average_tree_output), threshold_type(threshold_type), leaf_output_type(leaf_output_type), cfg() { - CHECK_GT(num_feature, 0) << "ModelBuilder: num_feature must be positive"; - CHECK_GT(num_class, 0) << "ModelBuilder: num_class must be positive"; - CHECK(threshold_type != TypeInfo::kInvalid) + TREELITE_CHECK_GT(num_feature, 0) << "ModelBuilder: num_feature must be positive"; + TREELITE_CHECK_GT(num_class, 0) << "ModelBuilder: num_class must be positive"; + TREELITE_CHECK(threshold_type != TypeInfo::kInvalid) << "ModelBuilder: threshold_type can't be invalid"; - CHECK(leaf_output_type != TypeInfo::kInvalid) + TREELITE_CHECK(leaf_output_type != TypeInfo::kInvalid) << "ModelBuilder: leaf_output_type can't be invalid"; } // Templatized implementation of CommitModel() @@ -104,7 +104,7 @@ void SetLeafVector(Tree* tree, int nid, std::vector out_leaf_vector; for (size_t i = 0; i < leaf_vector_size; ++i) { const Value& leaf_value = leaf_vector[i]; - CHECK(leaf_value.GetValueType() == expected_leaf_type) + TREELITE_CHECK(leaf_value.GetValueType() == expected_leaf_type) << "Leaf value at index " << i << " has incorrect type. Expected: " << TypeInfoToString(expected_leaf_type) << ", Given: " << TypeInfoToString(leaf_value.GetValueType()); @@ -130,7 +130,7 @@ class CreateHandle { public: inline static std::shared_ptr Dispatch(const void* init_value) { const auto* v_ptr = static_cast(init_value); - CHECK(v_ptr); + TREELITE_CHECK(v_ptr); ValueType v = *v_ptr; return std::make_shared(v); } @@ -139,7 +139,7 @@ class CreateHandle { Value Value::Create(const void* init_value, TypeInfo type) { Value value; - CHECK(type != TypeInfo::kInvalid) << "Type must be valid"; + TREELITE_CHECK(type != TypeInfo::kInvalid) << "Type must be valid"; value.type_ = type; value.handle_ = DispatchWithTypeInfo(type, init_value); return value; @@ -148,18 +148,18 @@ Value::Create(const void* init_value, TypeInfo type) { template T& Value::Get() { - CHECK(handle_); + TREELITE_CHECK(handle_); T* out = static_cast(handle_.get()); - CHECK(out); + TREELITE_CHECK(out); return *out; } template const T& Value::Get() const { - CHECK(handle_); + TREELITE_CHECK(handle_); const T* out = static_cast(handle_.get()); - CHECK(out); + TREELITE_CHECK(out); return *out; } @@ -175,7 +175,8 @@ TreeBuilder::~TreeBuilder() = default; void TreeBuilder::CreateNode(int node_key) { auto& nodes = pimpl_->tree.nodes; - CHECK_EQ(nodes.count(node_key), 0) << "CreateNode: nodes with duplicate keys are not allowed"; + TREELITE_CHECK_EQ(nodes.count(node_key), 0) + << "CreateNode: nodes with duplicate keys are not allowed"; nodes[node_key] = std::make_unique(); } @@ -183,7 +184,7 @@ void TreeBuilder::DeleteNode(int node_key) { auto& tree = pimpl_->tree; auto& nodes = tree.nodes; - CHECK_GT(nodes.count(node_key), 0) << "DeleteNode: no node found with node_key"; + TREELITE_CHECK_GT(nodes.count(node_key), 0) << "DeleteNode: no node found with node_key"; NodeDraft* node = nodes[node_key].get(); if (tree.root == node) { // deleting root tree.root = nullptr; @@ -206,9 +207,9 @@ void TreeBuilder::SetRootNode(int node_key) { auto& tree = pimpl_->tree; auto& nodes = tree.nodes; - CHECK_GT(nodes.count(node_key), 0) << "SetRootNode: no node found with node_key"; + TREELITE_CHECK_GT(nodes.count(node_key), 0) << "SetRootNode: no node found with node_key"; NodeDraft* node = nodes[node_key].get(); - CHECK(!node->parent) << "SetRootNode: a root node cannot have a parent"; + TREELITE_CHECK(!node->parent) << "SetRootNode: a root node cannot have a parent"; tree.root = node; } @@ -216,7 +217,7 @@ void TreeBuilder::SetNumericalTestNode(int node_key, unsigned feature_id, const char* opname, Value threshold, bool default_left, int left_child_key, int right_child_key) { - CHECK_GT(optable.count(opname), 0) << "No operator \"" << opname << "\" exists"; + TREELITE_CHECK_GT(optable.count(opname), 0) << "No operator \"" << opname << "\" exists"; Operator op = optable.at(opname); SetNumericalTestNode(node_key, feature_id, op, std::move(threshold), default_left, left_child_key, right_child_key); @@ -227,25 +228,26 @@ TreeBuilder::SetNumericalTestNode(int node_key, unsigned feature_id, Operator op bool default_left, int left_child_key, int right_child_key) { auto& tree = pimpl_->tree; auto& nodes = tree.nodes; - CHECK(tree.threshold_type == threshold.GetValueType()) + TREELITE_CHECK(tree.threshold_type == threshold.GetValueType()) << "SetNumericalTestNode: threshold has an incorrect type. " << "Expected: " << TypeInfoToString(tree.threshold_type) << ", Given: " << TypeInfoToString(threshold.GetValueType()); - CHECK_GT(nodes.count(node_key), 0) << "SetNumericalTestNode: no node found with node_key"; - CHECK_GT(nodes.count(left_child_key), 0) + TREELITE_CHECK_GT(nodes.count(node_key), 0) + << "SetNumericalTestNode: no node found with node_key"; + TREELITE_CHECK_GT(nodes.count(left_child_key), 0) << "SetNumericalTestNode: no node found with left_child_key"; - CHECK_GT(nodes.count(right_child_key), 0) + TREELITE_CHECK_GT(nodes.count(right_child_key), 0) << "SetNumericalTestNode: no node found with right_child_key"; NodeDraft* node = nodes[node_key].get(); NodeDraft* left_child = nodes[left_child_key].get(); NodeDraft* right_child = nodes[right_child_key].get(); - CHECK(node->status == NodeDraft::Status::kEmpty) + TREELITE_CHECK(node->status == NodeDraft::Status::kEmpty) << "SetNumericalTestNode: cannot modify a non-empty node"; - CHECK(!left_child->parent) + TREELITE_CHECK(!left_child->parent) << "SetNumericalTestNode: node designated as left child already has a parent"; - CHECK(!right_child->parent) + TREELITE_CHECK(!right_child->parent) << "SetNumericalTestNode: node designated as right child already has a parent"; - CHECK(left_child != tree.root && right_child != tree.root) + TREELITE_CHECK(left_child != tree.root && right_child != tree.root) << "SetNumericalTestNode: the root node cannot be a child"; node->status = NodeDraft::Status::kNumericalTest; node->left_child = nodes[left_child_key].get(); @@ -264,21 +266,22 @@ TreeBuilder::SetCategoricalTestNode(int node_key, unsigned feature_id, int left_child_key, int right_child_key) { auto &tree = pimpl_->tree; auto &nodes = tree.nodes; - CHECK_GT(nodes.count(node_key), 0) << "SetCategoricalTestNode: no node found with node_key"; - CHECK_GT(nodes.count(left_child_key), 0) + TREELITE_CHECK_GT(nodes.count(node_key), 0) + << "SetCategoricalTestNode: no node found with node_key"; + TREELITE_CHECK_GT(nodes.count(left_child_key), 0) << "SetCategoricalTestNode: no node found with left_child_key"; - CHECK_GT(nodes.count(right_child_key), 0) + TREELITE_CHECK_GT(nodes.count(right_child_key), 0) << "SetCategoricalTestNode: no node found with right_child_key"; NodeDraft* node = nodes[node_key].get(); NodeDraft* left_child = nodes[left_child_key].get(); NodeDraft* right_child = nodes[right_child_key].get(); - CHECK(node->status == NodeDraft::Status::kEmpty) + TREELITE_CHECK(node->status == NodeDraft::Status::kEmpty) << "SetCategoricalTestNode: cannot modify a non-empty node"; - CHECK(!left_child->parent) + TREELITE_CHECK(!left_child->parent) << "SetCategoricalTestNode: node designated as left child already has a parent"; - CHECK(!right_child->parent) + TREELITE_CHECK(!right_child->parent) << "SetCategoricalTestNode: node designated as right child already has a parent"; - CHECK(left_child != tree.root && right_child != tree.root) + TREELITE_CHECK(left_child != tree.root && right_child != tree.root) << "SetCategoricalTestNode: the root node cannot be a child"; node->status = NodeDraft::Status::kCategoricalTest; node->left_child = nodes[left_child_key].get(); @@ -294,13 +297,14 @@ void TreeBuilder::SetLeafNode(int node_key, Value leaf_value) { auto& tree = pimpl_->tree; auto& nodes = tree.nodes; - CHECK(tree.leaf_output_type == leaf_value.GetValueType()) + TREELITE_CHECK(tree.leaf_output_type == leaf_value.GetValueType()) << "SetLeafNode: leaf_value has an incorrect type. " << "Expected: " << TypeInfoToString(tree.leaf_output_type) << ", Given: " << TypeInfoToString(leaf_value.GetValueType()); - CHECK_GT(nodes.count(node_key), 0) << "SetLeafNode: no node found with node_key"; + TREELITE_CHECK_GT(nodes.count(node_key), 0) << "SetLeafNode: no node found with node_key"; NodeDraft* node = nodes[node_key].get(); - CHECK(node->status == NodeDraft::Status::kEmpty) << "SetLeafNode: cannot modify a non-empty node"; + TREELITE_CHECK(node->status == NodeDraft::Status::kEmpty) + << "SetLeafNode: cannot modify a non-empty node"; node->status = NodeDraft::Status::kLeaf; node->leaf_value = std::move(leaf_value); } @@ -312,14 +316,15 @@ TreeBuilder::SetLeafVectorNode(int node_key, const std::vector& leaf_vect const size_t leaf_vector_len = leaf_vector.size(); for (size_t i = 0; i < leaf_vector_len; ++i) { const Value& leaf_value = leaf_vector[i]; - CHECK(tree.leaf_output_type == leaf_value.GetValueType()) + TREELITE_CHECK(tree.leaf_output_type == leaf_value.GetValueType()) << "SetLeafVectorNode: the element " << i << " in leaf_vector has an incorrect type. " << "Expected: " << TypeInfoToString(tree.leaf_output_type) << ", Given: " << TypeInfoToString(leaf_value.GetValueType()); } - CHECK_GT(nodes.count(node_key), 0) << "SetLeafVectorNode: no node found with node_key"; + TREELITE_CHECK_GT(nodes.count(node_key), 0) + << "SetLeafVectorNode: no node found with node_key"; NodeDraft* node = nodes[node_key].get(); - CHECK(node->status == NodeDraft::Status::kEmpty) + TREELITE_CHECK(node->status == NodeDraft::Status::kEmpty) << "SetLeafVectorNode: cannot modify a non-empty node"; node->status = NodeDraft::Status::kLeaf; node->leaf_vector = leaf_vector; @@ -339,15 +344,15 @@ ModelBuilder::SetModelParam(const char* name, const char* value) { int ModelBuilder::InsertTree(TreeBuilder* tree_builder, int index) { if (tree_builder == nullptr) { - LOG(FATAL) << "InsertTree: not a valid tree builder"; + TREELITE_LOG(FATAL) << "InsertTree: not a valid tree builder"; return -1; } if (tree_builder->ensemble_id_ != nullptr) { - LOG(FATAL) << "InsertTree: tree is already part of another ensemble"; + TREELITE_LOG(FATAL) << "InsertTree: tree is already part of another ensemble"; return -1; } if (tree_builder->pimpl_->tree.threshold_type != this->pimpl_->threshold_type) { - LOG(FATAL) + TREELITE_LOG(FATAL) << "InsertTree: cannot insert the tree into the ensemble, because the ensemble requires all " << "member trees to use " << TypeInfoToString(this->pimpl_->threshold_type) << " type for split thresholds whereas the tree is using " @@ -355,7 +360,7 @@ ModelBuilder::InsertTree(TreeBuilder* tree_builder, int index) { return -1; } if (tree_builder->pimpl_->tree.leaf_output_type != this->pimpl_->leaf_output_type) { - LOG(FATAL) + TREELITE_LOG(FATAL) << "InsertTree: cannot insert the tree into the ensemble, because the ensemble requires all " << "member trees to use " << TypeInfoToString(this->pimpl_->leaf_output_type) << " type for leaf outputs whereas the tree is using " @@ -370,8 +375,9 @@ ModelBuilder::InsertTree(TreeBuilder* tree_builder, int index) { status == NodeDraft::Status::kCategoricalTest) { const int fid = static_cast(kv.second->feature_id); if (fid < 0 || fid >= this->pimpl_->num_feature) { - LOG(FATAL) << "InsertTree: tree has an invalid split at node " - << kv.first << ": feature id " << kv.second->feature_id << " is out of bound"; + TREELITE_LOG(FATAL) << "InsertTree: tree has an invalid split at node " + << kv.first << ": feature id " + << kv.second->feature_id << " is out of bound"; return -1; } } @@ -389,7 +395,7 @@ ModelBuilder::InsertTree(TreeBuilder* tree_builder, int index) { tree_builder->ensemble_id_ = this; return index; } else { - LOG(FATAL) << "InsertTree: index out of bound"; + TREELITE_LOG(FATAL) << "InsertTree: index out of bound"; return -1; } } @@ -408,7 +414,8 @@ ModelBuilder::GetTree(int index) const { void ModelBuilder::DeleteTree(int index) { auto& trees = pimpl_->trees; - CHECK_LT(static_cast(index), trees.size()) << "DeleteTree: index out of bound"; + TREELITE_CHECK_LT(static_cast(index), trees.size()) + << "DeleteTree: index out of bound"; trees.erase(trees.begin() + index); } @@ -441,8 +448,8 @@ ModelBuilderImpl::CommitModelImpl(ModelImpl* out_ for (const auto& tree_builder : this->trees) { const auto& _tree = tree_builder.pimpl_->tree; - CHECK(_tree.root) << "CommitModel: a tree has no root node"; - CHECK(_tree.root->status != NodeDraft::Status::kEmpty) + TREELITE_CHECK(_tree.root) << "CommitModel: a tree has no root node"; + TREELITE_CHECK(_tree.root->status != NodeDraft::Status::kEmpty) << "SetRootNode: cannot set an empty node as root"; model.trees.emplace_back(); Tree& tree = model.trees.back(); @@ -457,15 +464,17 @@ ModelBuilderImpl::CommitModelImpl(ModelImpl* out_ int nid; std::tie(node, nid) = Q.front(); Q.pop(); - CHECK(node->status != NodeDraft::Status::kEmpty) + TREELITE_CHECK(node->status != NodeDraft::Status::kEmpty) << "CommitModel: encountered an empty node in the middle of a tree"; if (node->status == NodeDraft::Status::kNumericalTest) { - CHECK(node->left_child) << "CommitModel: a test node lacks a left child"; - CHECK(node->right_child) << "CommitModel: a test node lacks a right child"; - CHECK(node->left_child->parent == node) << "CommitModel: left child has wrong parent"; - CHECK(node->right_child->parent == node) << "CommitModel: right child has wrong parent"; + TREELITE_CHECK(node->left_child) << "CommitModel: a test node lacks a left child"; + TREELITE_CHECK(node->right_child) << "CommitModel: a test node lacks a right child"; + TREELITE_CHECK(node->left_child->parent == node) + << "CommitModel: left child has wrong parent"; + TREELITE_CHECK(node->right_child->parent == node) + << "CommitModel: right child has wrong parent"; tree.AddChilds(nid); - CHECK(node->threshold.GetValueType() == TypeToInfo()) + TREELITE_CHECK(node->threshold.GetValueType() == TypeToInfo()) << "CommitModel: The specified threshold has incorrect type. Expected: " << TypeInfoToString(TypeToInfo()) << " Given: " << TypeInfoToString(node->threshold.GetValueType()); @@ -474,33 +483,35 @@ ModelBuilderImpl::CommitModelImpl(ModelImpl* out_ Q.push({node->left_child, tree.LeftChild(nid)}); Q.push({node->right_child, tree.RightChild(nid)}); } else if (node->status == NodeDraft::Status::kCategoricalTest) { - CHECK(node->left_child) << "CommitModel: a test node lacks a left child"; - CHECK(node->right_child) << "CommitModel: a test node lacks a right child"; - CHECK(node->left_child->parent == node) << "CommitModel: left child has wrong parent"; - CHECK(node->right_child->parent == node) << "CommitModel: right child has wrong parent"; + TREELITE_CHECK(node->left_child) << "CommitModel: a test node lacks a left child"; + TREELITE_CHECK(node->right_child) << "CommitModel: a test node lacks a right child"; + TREELITE_CHECK(node->left_child->parent == node) + << "CommitModel: left child has wrong parent"; + TREELITE_CHECK(node->right_child->parent == node) + << "CommitModel: right child has wrong parent"; tree.AddChilds(nid); tree.SetCategoricalSplit(nid, node->feature_id, node->default_left, node->left_categories, false); Q.push({node->left_child, tree.LeftChild(nid)}); Q.push({node->right_child, tree.RightChild(nid)}); } else { // leaf node - CHECK(node->left_child == nullptr && node->right_child == nullptr) + TREELITE_CHECK(node->left_child == nullptr && node->right_child == nullptr) << "CommitModel: a leaf node cannot have children"; if (!node->leaf_vector.empty()) { // leaf vector exists - CHECK_NE(flag_leaf_vector, 0) + TREELITE_CHECK_NE(flag_leaf_vector, 0) << "CommitModel: Inconsistent use of leaf vector: if one leaf node uses a leaf vector, " << "*every* leaf node must use a leaf vector"; flag_leaf_vector = 1; // now every leaf must use leaf vector - CHECK_EQ(node->leaf_vector.size(), model.task_param.num_class) + TREELITE_CHECK_EQ(node->leaf_vector.size(), model.task_param.num_class) << "CommitModel: The length of leaf vector must be identical to the number of output " << "groups"; SetLeafVector(&tree, nid, node->leaf_vector); } else { // ordinary leaf - CHECK_NE(flag_leaf_vector, 1) + TREELITE_CHECK_NE(flag_leaf_vector, 1) << "CommitModel: Inconsistent use of leaf vector: if one leaf node does not use a leaf " << "vector, *no other* leaf node can use a leaf vector"; flag_leaf_vector = 0; // now no leaf can use leaf vector - CHECK(node->leaf_value.GetValueType() == TypeToInfo()) + TREELITE_CHECK(node->leaf_value.GetValueType() == TypeToInfo()) << "CommitModel: The specified leaf value has incorrect type. Expected: " << TypeInfoToString(TypeToInfo()) << " Given: " << TypeInfoToString(node->leaf_value.GetValueType()); @@ -516,7 +527,7 @@ ModelBuilderImpl::CommitModelImpl(ModelImpl* out_ // multi-class classifier, XGBoost/LightGBM style model.task_type = TaskType::kMultiClfGrovePerClass; model.task_param.grove_per_class = true; - CHECK_EQ(this->trees.size() % model.task_param.num_class, 0) + TREELITE_CHECK_EQ(this->trees.size() % model.task_param.num_class, 0) << "For multi-class classifiers with gradient boosted trees, the number of trees must be " << "evenly divisible by the number of output groups"; } else { @@ -528,10 +539,11 @@ ModelBuilderImpl::CommitModelImpl(ModelImpl* out_ // multi-class classifier, sklearn RF style model.task_type = TaskType::kMultiClfProbDistLeaf; model.task_param.grove_per_class = false; - CHECK_GT(model.task_param.num_class, 1) << "Expected leaf vectors with length exceeding 1"; + TREELITE_CHECK_GT(model.task_param.num_class, 1) + << "Expected leaf vectors with length exceeding 1"; model.task_param.leaf_vector_size = model.task_param.num_class; } else { - LOG(FATAL) << "Impossible thing happened: model has no leaf node!"; + TREELITE_LOG(FATAL) << "Impossible thing happened: model has no leaf node!"; } } diff --git a/src/frontend/lightgbm.cc b/src/frontend/lightgbm.cc index 3af3a0e7..2d0218eb 100644 --- a/src/frontend/lightgbm.cc +++ b/src/frontend/lightgbm.cc @@ -53,11 +53,11 @@ inline float TextToNumber(const std::string& str) { char *endptr; float val = std::strtof(str.c_str(), &endptr); if (errno == ERANGE) { - LOG(FATAL) << "Range error while converting string to double"; + TREELITE_LOG(FATAL) << "Range error while converting string to double"; } else if (errno != 0) { - LOG(FATAL) << "Unknown error"; + TREELITE_LOG(FATAL) << "Unknown error"; } else if (*endptr != '\0') { - LOG(FATAL) << "String does not represent a valid floating-point number"; + TREELITE_LOG(FATAL) << "String does not represent a valid floating-point number"; } return val; } @@ -68,11 +68,11 @@ inline double TextToNumber(const std::string& str) { char *endptr; double val = std::strtod(str.c_str(), &endptr); if (errno == ERANGE) { - LOG(FATAL) << "Range error while converting string to double"; + TREELITE_LOG(FATAL) << "Range error while converting string to double"; } else if (errno != 0) { - LOG(FATAL) << "Unknown error"; + TREELITE_LOG(FATAL) << "Unknown error"; } else if (*endptr != '\0') { - LOG(FATAL) << "String does not represent a valid floating-point number"; + TREELITE_LOG(FATAL) << "String does not represent a valid floating-point number"; } return val; } @@ -84,11 +84,11 @@ inline int TextToNumber(const std::string& str) { auto val = std::strtol(str.c_str(), &endptr, 10); if (errno == ERANGE || val < std::numeric_limits::min() || val > std::numeric_limits::max()) { - LOG(FATAL) << "Range error while converting string to int"; + TREELITE_LOG(FATAL) << "Range error while converting string to int"; } else if (errno != 0) { - LOG(FATAL) << "Unknown error"; + TREELITE_LOG(FATAL) << "Unknown error"; } else if (*endptr != '\0') { - LOG(FATAL) << "String does not represent a valid integer"; + TREELITE_LOG(FATAL) << "String does not represent a valid integer"; } return static_cast(val); } @@ -100,11 +100,11 @@ inline int8_t TextToNumber(const std::string& str) { auto val = std::strtol(str.c_str(), &endptr, 10); if (errno == ERANGE || val < std::numeric_limits::min() || val > std::numeric_limits::max()) { - LOG(FATAL) << "Range error while converting string to int8_t"; + TREELITE_LOG(FATAL) << "Range error while converting string to int8_t"; } else if (errno != 0) { - LOG(FATAL) << "Unknown error"; + TREELITE_LOG(FATAL) << "Unknown error"; } else if (*endptr != '\0') { - LOG(FATAL) << "String does not represent a valid integer"; + TREELITE_LOG(FATAL) << "String does not represent a valid integer"; } return static_cast(val); } @@ -115,11 +115,11 @@ inline uint32_t TextToNumber(const std::string& str) { char *endptr; auto val = std::strtoul(str.c_str(), &endptr, 10); if (errno == ERANGE || val > std::numeric_limits::max()) { - LOG(FATAL) << "Range error while converting string to uint32_t"; + TREELITE_LOG(FATAL) << "Range error while converting string to uint32_t"; } else if (errno != 0) { - LOG(FATAL) << "Unknown error"; + TREELITE_LOG(FATAL) << "Unknown error"; } else if (*endptr != '\0') { - LOG(FATAL) << "String does not represent a valid integer"; + TREELITE_LOG(FATAL) << "String does not represent a valid integer"; } return static_cast(val); } @@ -130,11 +130,11 @@ inline uint64_t TextToNumber(const std::string& str) { char *endptr; auto val = std::strtoull(str.c_str(), &endptr, 10); if (errno == ERANGE || val > std::numeric_limits::max()) { - LOG(FATAL) << "Range error while converting string to uint64_t"; + TREELITE_LOG(FATAL) << "Range error while converting string to uint64_t"; } else if (errno != 0) { - LOG(FATAL) << "Unknown error"; + TREELITE_LOG(FATAL) << "Unknown error"; } else if (*endptr != '\0') { - LOG(FATAL) << "String does not represent a valid integer"; + TREELITE_LOG(FATAL) << "String does not represent a valid integer"; } return static_cast(val); } @@ -152,7 +152,7 @@ inline std::vector Split(const std::string& text, char delim) { template inline std::vector TextToArray(const std::string& text, int num_entry) { if (text.empty() && num_entry > 0) { - LOG(FATAL) << "Cannot convert empty text into array"; + TREELITE_LOG(FATAL) << "Cannot convert empty text into array"; } std::vector array; std::istringstream ss(text); @@ -243,7 +243,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { std::getline(ss, key, '='); std::getline(ss, value, '='); std::getline(ss, rest); - CHECK(rest.empty()) << "Ill-formed LightGBM model file"; + TREELITE_CHECK(rest.empty()) << "Ill-formed LightGBM model file"; if (key == "Tree") { in_tree = true; tree_dict.emplace_back(); @@ -267,11 +267,11 @@ inline std::unique_ptr ParseStream(std::istream& fi) { } it = global_dict.find("max_feature_idx"); - CHECK(it != global_dict.end()) + TREELITE_CHECK(it != global_dict.end()) << "Ill-formed LightGBM model file: need max_feature_idx"; max_feature_idx_ = TextToNumber(it->second); it = global_dict.find("num_class"); - CHECK(it != global_dict.end()) + TREELITE_CHECK(it != global_dict.end()) << "Ill-formed LightGBM model file: need num_class"; num_class_ = TextToNumber(it->second); @@ -284,16 +284,16 @@ inline std::unique_ptr ParseStream(std::istream& fi) { LGBTree& tree = lgb_trees_.back(); auto it = dict.find("num_leaves"); - CHECK(it != dict.end()) + TREELITE_CHECK(it != dict.end()) << "Ill-formed LightGBM model file: need num_leaves"; tree.num_leaves = TextToNumber(it->second); it = dict.find("num_cat"); - CHECK(it != dict.end()) << "Ill-formed LightGBM model file: need num_cat"; + TREELITE_CHECK(it != dict.end()) << "Ill-formed LightGBM model file: need num_cat"; tree.num_cat = TextToNumber(it->second); it = dict.find("leaf_value"); - CHECK(it != dict.end() && !it->second.empty()) + TREELITE_CHECK(it != dict.end() && !it->second.empty()) << "Ill-formed LightGBM model file: need leaf_value"; tree.leaf_value = TextToArray(it->second, tree.num_leaves); @@ -302,11 +302,11 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves <= 1) { tree.decision_type = std::vector(); } else { - CHECK_GT(tree.num_leaves, 1); + TREELITE_CHECK_GT(tree.num_leaves, 1); if (it == dict.end()) { tree.decision_type = std::vector(tree.num_leaves - 1, 0); } else { - CHECK(!it->second.empty()) + TREELITE_CHECK(!it->second.empty()) << "Ill-formed LightGBM model file: decision_type cannot be empty string"; tree.decision_type = TextToArray(it->second, tree.num_leaves - 1); } @@ -314,12 +314,12 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_cat > 0) { it = dict.find("cat_boundaries"); - CHECK(it != dict.end() && !it->second.empty()) + TREELITE_CHECK(it != dict.end() && !it->second.empty()) << "Ill-formed LightGBM model file: need cat_boundaries"; tree.cat_boundaries = TextToArray(it->second, tree.num_cat + 1); it = dict.find("cat_threshold"); - CHECK(it != dict.end() && !it->second.empty()) + TREELITE_CHECK(it != dict.end() && !it->second.empty()) << "Ill-formed LightGBM model file: need cat_threshold"; tree.cat_threshold = TextToArray(it->second, static_cast(tree.cat_boundaries.back())); @@ -329,8 +329,8 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves <= 1) { tree.split_feature = std::vector(); } else { - CHECK_GT(tree.num_leaves, 1); - CHECK(it != dict.end() && !it->second.empty()) + TREELITE_CHECK_GT(tree.num_leaves, 1); + TREELITE_CHECK(it != dict.end() && !it->second.empty()) << "Ill-formed LightGBM model file: need split_feature"; tree.split_feature = TextToArray(it->second, tree.num_leaves - 1); } @@ -339,8 +339,8 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves <= 1) { tree.threshold = std::vector(); } else { - CHECK_GT(tree.num_leaves, 1); - CHECK(it != dict.end() && !it->second.empty()) + TREELITE_CHECK_GT(tree.num_leaves, 1); + TREELITE_CHECK(it != dict.end() && !it->second.empty()) << "Ill-formed LightGBM model file: need threshold"; tree.threshold = TextToArray(it->second, tree.num_leaves - 1); } @@ -349,9 +349,9 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves <= 1) { tree.split_gain = std::vector(); } else { - CHECK_GT(tree.num_leaves, 1); + TREELITE_CHECK_GT(tree.num_leaves, 1); if (it != dict.end()) { - CHECK(!it->second.empty()) + TREELITE_CHECK(!it->second.empty()) << "Ill-formed LightGBM model file: split_gain cannot be empty string"; tree.split_gain = TextToArray(it->second, tree.num_leaves - 1); } else { @@ -363,9 +363,9 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves <= 1) { tree.internal_count = std::vector(); } else { - CHECK_GT(tree.num_leaves, 1); + TREELITE_CHECK_GT(tree.num_leaves, 1); if (it != dict.end()) { - CHECK(!it->second.empty()) + TREELITE_CHECK(!it->second.empty()) << "Ill-formed LightGBM model file: internal_count cannot be empty string"; tree.internal_count = TextToArray(it->second, tree.num_leaves - 1); } else { @@ -377,7 +377,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves == 0) { tree.leaf_count = std::vector(); } else { - CHECK_GT(tree.num_leaves, 0); + TREELITE_CHECK_GT(tree.num_leaves, 0); if (it != dict.end() && !it->second.empty()) { tree.leaf_count = TextToArray(it->second, tree.num_leaves); } else { @@ -389,8 +389,8 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves <= 1) { tree.left_child = std::vector(); } else { - CHECK_GT(tree.num_leaves, 1); - CHECK(it != dict.end() && !it->second.empty()) + TREELITE_CHECK_GT(tree.num_leaves, 1); + TREELITE_CHECK(it != dict.end() && !it->second.empty()) << "Ill-formed LightGBM model file: need left_child"; tree.left_child = TextToArray(it->second, tree.num_leaves - 1); } @@ -399,8 +399,8 @@ inline std::unique_ptr ParseStream(std::istream& fi) { if (tree.num_leaves <= 1) { tree.right_child = std::vector(); } else { - CHECK_GT(tree.num_leaves, 1); - CHECK(it != dict.end() && !it->second.empty()) + TREELITE_CHECK_GT(tree.num_leaves, 1); + TREELITE_CHECK(it != dict.end() && !it->second.empty()) << "Ill-formed LightGBM model file: need right_child"; tree.right_child = TextToArray(it->second, tree.num_leaves - 1); } @@ -437,7 +437,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { break; } } - CHECK(num_class >= 0 && static_cast(num_class) == model->task_param.num_class) + TREELITE_CHECK(num_class >= 0 && static_cast(num_class) == model->task_param.num_class) << "Ill-formed LightGBM model file: not a valid multiclass objective"; std::strncpy(model->param.pred_transform, "softmax", sizeof(model->param.pred_transform)); @@ -459,8 +459,8 @@ inline std::unique_ptr ParseStream(std::istream& fi) { } } } - CHECK(num_class >= 0 && static_cast(num_class) == model->task_param.num_class - && alpha > 0.0f) + TREELITE_CHECK(num_class >= 0 && static_cast(num_class) == model->task_param.num_class + && alpha > 0.0f) << "Ill-formed LightGBM model file: not a valid multiclassova objective"; std::strncpy(model->param.pred_transform, "multiclass_ova", @@ -478,7 +478,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { break; } } - CHECK_GT(alpha, 0.0f) + TREELITE_CHECK_GT(alpha, 0.0f) << "Ill-formed LightGBM model file: not a valid binary objective"; std::strncpy(model->param.pred_transform, "sigmoid", sizeof(model->param.pred_transform)); @@ -508,7 +508,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { std::strncpy(model->param.pred_transform, "identity", sizeof(model->param.pred_transform)); } else { - LOG(FATAL) << "Unrecognized objective: " << obj_name_; + TREELITE_LOG(FATAL) << "Unrecognized objective: " << obj_name_; } // traverse trees @@ -536,7 +536,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { tree.SetLeaf(new_id, static_cast(leaf_value)); if (!lgb_tree.leaf_count.empty()) { const int data_count = lgb_tree.leaf_count[~old_id]; - CHECK_GE(data_count, 0); + TREELITE_CHECK_GE(data_count, 0); tree.SetDataCount(new_id, static_cast(data_count)); } } else { // non-leaf @@ -578,7 +578,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { } if (!lgb_tree.internal_count.empty()) { const int data_count = lgb_tree.internal_count[old_id]; - CHECK_GE(data_count, 0); + TREELITE_CHECK_GE(data_count, 0); tree.SetDataCount(new_id, static_cast(data_count)); } if (!lgb_tree.split_gain.empty()) { diff --git a/src/frontend/sklearn.cc b/src/frontend/sklearn.cc index 34f8fe89..6de4fd88 100644 --- a/src/frontend/sklearn.cc +++ b/src/frontend/sklearn.cc @@ -22,8 +22,8 @@ std::unique_ptr LoadSKLearnModel( const int64_t** children_left, const int64_t** children_right, const int64_t** feature, const double** threshold, const double** value, const int64_t** n_node_samples, const double** impurity, MetaHandlerFunc meta_handler, LeafHandlerFunc leaf_handler) { - CHECK_GT(n_trees, 0); - CHECK_GT(n_features, 0); + TREELITE_CHECK_GT(n_trees, 0); + TREELITE_CHECK_GT(n_features, 0); std::unique_ptr model_ptr = treelite::Model::Create(); meta_handler(model_ptr.get(), n_features, n_classes); @@ -164,7 +164,7 @@ std::unique_ptr LoadSKLearnRandomForestClassifier( const int64_t** children_left, const int64_t** children_right, const int64_t** feature, const double** threshold, const double** value, const int64_t** n_node_samples, const double** impurity) { - CHECK_GE(n_classes, 2); + TREELITE_CHECK_GE(n_classes, 2); if (n_classes == 2) { return LoadSKLearnRandomForestClassifierBinary(n_estimators, n_features, n_classes, node_count, children_left, children_right, feature, threshold, value, n_node_samples, impurity); @@ -257,7 +257,7 @@ std::unique_ptr LoadSKLearnGradientBoostingClassifier( const int64_t** children_left, const int64_t** children_right, const int64_t** feature, const double** threshold, const double** value, const int64_t** n_node_samples, const double** impurity) { - CHECK_GE(n_classes, 2); + TREELITE_CHECK_GE(n_classes, 2); if (n_classes == 2) { return LoadSKLearnGradientBoostingClassifierBinary(n_estimators, n_features, n_classes, node_count, children_left, children_right, feature, threshold, value, n_node_samples, diff --git a/src/frontend/xgboost.cc b/src/frontend/xgboost.cc index 23f47d7d..fe14e6bf 100644 --- a/src/frontend/xgboost.cc +++ b/src/frontend/xgboost.cc @@ -83,7 +83,7 @@ class PeekableInputStream { } inline size_t PeekRead(void* ptr, size_t size) { - CHECK_LE(size, MAX_PEEK_WINDOW) + TREELITE_CHECK_LE(size, MAX_PEEK_WINDOW) << "PeekableInputStream allows peeking up to " << MAX_PEEK_WINDOW << " bytes"; char* cptr = static_cast(ptr); @@ -93,7 +93,7 @@ class PeekableInputStream { const size_t bytes_to_read = size - bytes_buffered; if (end_ptr_ + bytes_to_read < MAX_PEEK_WINDOW + 1) { istm_.read(&buf_[end_ptr_], bytes_to_read); - CHECK_EQ(istm_.gcount(), bytes_to_read) + TREELITE_CHECK_EQ(istm_.gcount(), bytes_to_read) << "Failed to peek " << size << " bytes"; end_ptr_ += bytes_to_read; } else { @@ -101,7 +101,7 @@ class PeekableInputStream { size_t first_read = istm_.gcount(); istm_.read(&buf_[0], bytes_to_read + end_ptr_ - MAX_PEEK_WINDOW - 1); size_t second_read = istm_.gcount(); - CHECK_EQ(first_read + second_read, bytes_to_read) + TREELITE_CHECK_EQ(first_read + second_read, bytes_to_read) << "Ill-formed XGBoost model: Failed to peek " << size << " bytes"; end_ptr_ = bytes_to_read + end_ptr_ - MAX_PEEK_WINDOW - 1; } @@ -135,7 +135,7 @@ template inline void CONSUME_BYTES(const T& fi, size_t size) { static std::vector dummy(500); if (size > dummy.size()) dummy.resize(size); - CHECK_EQ(fi->Read(&dummy[0], size), size) + TREELITE_CHECK_EQ(fi->Read(&dummy[0], size), size) << "Ill-formed XGBoost model format: cannot read " << size << " bytes from the file"; } @@ -259,7 +259,7 @@ class XGBTree { inline int AllocNode() { int nd = param.num_nodes++; - CHECK_LT(param.num_nodes, std::numeric_limits::max()) + TREELITE_CHECK_LT(param.num_nodes, std::numeric_limits::max()) << "number of nodes in the tree exceed 2^31"; nodes.resize(param.num_nodes); return nd; @@ -297,27 +297,27 @@ class XGBTree { nodes[nodes[nid].cright()].set_parent(nid, false); } inline void Load(PeekableInputStream* fi) { - CHECK_EQ(fi->Read(¶m, sizeof(TreeParam)), sizeof(TreeParam)) + TREELITE_CHECK_EQ(fi->Read(¶m, sizeof(TreeParam)), sizeof(TreeParam)) << "Ill-formed XGBoost model file: can't read TreeParam"; - CHECK_GT(param.num_nodes, 0) + TREELITE_CHECK_GT(param.num_nodes, 0) << "Ill-formed XGBoost model file: a tree can't be empty"; nodes.resize(param.num_nodes); stats.resize(param.num_nodes); - CHECK_EQ(fi->Read(nodes.data(), sizeof(Node) * nodes.size()), + TREELITE_CHECK_EQ(fi->Read(nodes.data(), sizeof(Node) * nodes.size()), sizeof(Node) * nodes.size()) << "Ill-formed XGBoost model file: cannot read specified number of nodes"; - CHECK_EQ(fi->Read(stats.data(), sizeof(NodeStat) * stats.size()), + TREELITE_CHECK_EQ(fi->Read(stats.data(), sizeof(NodeStat) * stats.size()), sizeof(NodeStat) * stats.size()) << "Ill-formed XGBoost model file: cannot read specified number of nodes"; if (param.size_leaf_vector != 0) { uint64_t len; - CHECK_EQ(fi->Read(&len, sizeof(len)), sizeof(len)) + TREELITE_CHECK_EQ(fi->Read(&len, sizeof(len)), sizeof(len)) << "Ill-formed XGBoost model file"; if (len > 0) { CONSUME_BYTES(fi, sizeof(bst_float) * len); } } - CHECK_EQ(param.num_roots, 1) + TREELITE_CHECK_EQ(param.num_roots, 1) << "Invalid XGBoost model file: treelite does not support trees " << "with multiple roots"; } @@ -336,56 +336,56 @@ inline std::unique_ptr ParseStream(std::istream& fi) { std::string header; header.resize(4); if (fp->PeekRead(&header[0], 4) == 4) { - CHECK_NE(header, "bs64") + TREELITE_CHECK_NE(header, "bs64") << "Ill-formed XGBoost model file: Base64 format no longer supported"; if (header == "binf") { CONSUME_BYTES(fp, 4); } } // read parameter - CHECK_EQ(fp->Read(&mparam_, sizeof(mparam_)), sizeof(mparam_)) + TREELITE_CHECK_EQ(fp->Read(&mparam_, sizeof(mparam_)), sizeof(mparam_)) << "Ill-formed XGBoost model file: corrupted header"; { uint64_t len; - CHECK_EQ(fp->Read(&len, sizeof(len)), sizeof(len)) + TREELITE_CHECK_EQ(fp->Read(&len, sizeof(len)), sizeof(len)) << "Ill-formed XGBoost model file: corrupted header"; if (len != 0) { name_obj_.resize(len); - CHECK_EQ(fp->Read(&name_obj_[0], len), len) + TREELITE_CHECK_EQ(fp->Read(&name_obj_[0], len), len) << "Ill-formed XGBoost model file: corrupted header"; } } { uint64_t len; - CHECK_EQ(fp->Read(&len, sizeof(len)), sizeof(len)) + TREELITE_CHECK_EQ(fp->Read(&len, sizeof(len)), sizeof(len)) << "Ill-formed XGBoost model file: corrupted header"; name_gbm_.resize(len); if (len > 0) { - CHECK_EQ(fp->Read(&name_gbm_[0], len), len) + TREELITE_CHECK_EQ(fp->Read(&name_gbm_[0], len), len) << "Ill-formed XGBoost model file: corrupted header"; } } /* loading GBTree */ - CHECK(name_gbm_ == "gbtree" || name_gbm_ == "dart") + TREELITE_CHECK(name_gbm_ == "gbtree" || name_gbm_ == "dart") << "Invalid XGBoost model file: " << "Gradient booster must be gbtree or dart type."; - CHECK_EQ(fp->Read(&gbm_param_, sizeof(gbm_param_)), sizeof(gbm_param_)) + TREELITE_CHECK_EQ(fp->Read(&gbm_param_, sizeof(gbm_param_)), sizeof(gbm_param_)) << "Invalid XGBoost model file: corrupted GBTree parameters"; - CHECK_GE(gbm_param_.num_trees, 0) + TREELITE_CHECK_GE(gbm_param_.num_trees, 0) << "Invalid XGBoost model file: num_trees must be 0 or greater"; for (int i = 0; i < gbm_param_.num_trees; ++i) { xgb_trees_.emplace_back(); xgb_trees_.back().Load(fp.get()); } - CHECK_EQ(gbm_param_.num_roots, 1) << "multi-root trees not supported"; + TREELITE_CHECK_EQ(gbm_param_.num_roots, 1) << "multi-root trees not supported"; // tree_info is currently unused. std::vector tree_info; tree_info.resize(gbm_param_.num_trees); if (gbm_param_.num_trees > 0) { - CHECK_EQ(fp->Read(tree_info.data(), sizeof(int32_t) * tree_info.size()), + TREELITE_CHECK_EQ(fp->Read(tree_info.data(), sizeof(int32_t) * tree_info.size()), sizeof(int32_t) * tree_info.size()); } // Load weight drop values (per tree) for dart models. @@ -394,7 +394,7 @@ inline std::unique_ptr ParseStream(std::istream& fi) { weight_drop.resize(gbm_param_.num_trees); uint64_t sz; fi.read(reinterpret_cast(&sz), sizeof(uint64_t)); - CHECK_EQ(sz, gbm_param_.num_trees); + TREELITE_CHECK_EQ(sz, gbm_param_.num_trees); if (gbm_param_.num_trees != 0) { for (uint64_t i = 0; i < sz; ++i) { fi.read(reinterpret_cast(&weight_drop[i]), sizeof(bst_float)); diff --git a/src/frontend/xgboost_json.cc b/src/frontend/xgboost_json.cc index cec943a0..ecf7b3a9 100644 --- a/src/frontend/xgboost_json.cc +++ b/src/frontend/xgboost_json.cc @@ -48,7 +48,7 @@ std::unique_ptr LoadXGBoostJSONModel(const char* filename) { FILE* fp = std::fopen(filename, "r"); #endif if (!fp) { - LOG(FATAL) << "Failed to open file '" << filename << "': " << std::strerror(errno); + TREELITE_LOG(FATAL) << "Failed to open file '" << filename << "': " << std::strerror(errno); } auto input_stream = std::make_unique( @@ -215,53 +215,53 @@ bool RegTreeHandler::EndObject(std::size_t) { split_type.resize(num_nodes, details::xgboost::FeatureType::kNumerical); } if (static_cast(num_nodes) != loss_changes.size()) { - LOG(ERROR) << "Field loss_changes has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << loss_changes.size(); + TREELITE_LOG(ERROR) << "Field loss_changes has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << loss_changes.size(); return false; } if (static_cast(num_nodes) != sum_hessian.size()) { - LOG(ERROR) << "Field sum_hessian has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << sum_hessian.size(); + TREELITE_LOG(ERROR) << "Field sum_hessian has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << sum_hessian.size(); return false; } if (static_cast(num_nodes) != base_weights.size()) { - LOG(ERROR) << "Field base_weights has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << base_weights.size(); + TREELITE_LOG(ERROR) << "Field base_weights has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << base_weights.size(); return false; } if (static_cast(num_nodes) != left_children.size()) { - LOG(ERROR) << "Field left_children has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << left_children.size(); + TREELITE_LOG(ERROR) << "Field left_children has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << left_children.size(); return false; } if (static_cast(num_nodes) != right_children.size()) { - LOG(ERROR) << "Field right_children has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << right_children.size(); + TREELITE_LOG(ERROR) << "Field right_children has an incorrect dimension. Expected: " + << num_nodes << ", Actual: " << right_children.size(); return false; } if (static_cast(num_nodes) != parents.size()) { - LOG(ERROR) << "Field parents has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << parents.size(); + TREELITE_LOG(ERROR) << "Field parents has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << parents.size(); return false; } if (static_cast(num_nodes) != split_indices.size()) { - LOG(ERROR) << "Field split_indices has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << split_indices.size(); + TREELITE_LOG(ERROR) << "Field split_indices has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << split_indices.size(); return false; } if (static_cast(num_nodes) != split_type.size()) { - LOG(ERROR) << "Field split_type has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << split_type.size(); + TREELITE_LOG(ERROR) << "Field split_type has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << split_type.size(); return false; } if (static_cast(num_nodes) != split_conditions.size()) { - LOG(ERROR) << "Field split_conditions has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << split_conditions.size(); + TREELITE_LOG(ERROR) << "Field split_conditions has an incorrect dimension. Expected: " + << num_nodes << ", Actual: " << split_conditions.size(); return false; } if (static_cast(num_nodes) != default_left.size()) { - LOG(ERROR) << "Field default_left has an incorrect dimension. Expected: " << num_nodes - << ", Actual: " << default_left.size(); + TREELITE_LOG(ERROR) << "Field default_left has an incorrect dimension. Expected: " << num_nodes + << ", Actual: " << default_left.size(); return false; } @@ -281,7 +281,7 @@ bool RegTreeHandler::EndObject(std::size_t) { if (split_type[old_id] == details::xgboost::FeatureType::kCategorical) { auto categorical_split_loc = math::binary_search(categories_nodes.begin(), categories_nodes.end(), old_id); - CHECK(categorical_split_loc != categories_nodes.end()) + TREELITE_CHECK(categorical_split_loc != categories_nodes.end()) << "Could not find record for the categorical split in node " << old_id; auto categorical_split_id = std::distance(categories_nodes.begin(), categorical_split_loc); int offset = categories_segments[categorical_split_id]; @@ -331,7 +331,7 @@ bool GradientBoosterHandler::String(const char *str, if (name == "gbtree" || name == "dart") { return true; } else { - LOG(ERROR) << "Only GBTree or DART boosters are currently supported."; + TREELITE_LOG(ERROR) << "Only GBTree or DART boosters are currently supported."; return false; } } else { @@ -346,8 +346,8 @@ bool GradientBoosterHandler::StartObject() { // "dart" booster contains a standard gbtree under ["gradient_booster"]["gbtree"]["model"]. return true; } else { - LOG(ERROR) << "Key \"" << get_cur_key() - << "\" not recognized. Is this a GBTree-type booster?"; + TREELITE_LOG(ERROR) << "Key \"" << get_cur_key() + << "\" not recognized. Is this a GBTree-type booster?"; return false; } } @@ -357,7 +357,7 @@ bool GradientBoosterHandler::StartArray() { bool GradientBoosterHandler::EndObject(std::size_t memberCount) { if (name == "dart" && !weight_drop.empty()) { // Fold weight drop into leaf value for dart models. - CHECK_EQ(output.trees.size(), weight_drop.size()); + TREELITE_CHECK_EQ(output.trees.size(), weight_drop.size()); for (size_t i = 0; i < output.trees.size(); ++i) { for (int nid = 0; nid < output.trees[i].num_nodes; ++nid) { if (output.trees[i].IsLeaf(nid)) { @@ -436,7 +436,7 @@ bool XGBoostModelHandler::StartObject() { bool XGBoostModelHandler::EndObject(std::size_t memberCount) { if (memberCount != 2) { - LOG(ERROR) << "Expected two members in XGBoostModel"; + TREELITE_LOG(ERROR) << "Expected two members in XGBoostModel"; return false; } output.model->average_tree_output = false; @@ -512,9 +512,9 @@ std::unique_ptr ParseStream(std::unique_ptr input_s const auto error_code = result.Code(); const size_t offset = result.Offset(); std::string diagnostic = error_handler(offset); - LOG(FATAL) << "Provided JSON could not be parsed as XGBoost model. Parsing error at offset " - << offset << ": " << rapidjson::GetParseError_En(error_code) << "\n" - << diagnostic; + TREELITE_LOG(FATAL) << "Provided JSON could not be parsed as XGBoost model. " + << "Parsing error at offset " << offset << ": " + << rapidjson::GetParseError_En(error_code) << "\n" << diagnostic; } return handler->get_result(); } diff --git a/src/frontend/xgboost_util.cc b/src/frontend/xgboost_util.cc index 3788d5f2..d7a97299 100644 --- a/src/frontend/xgboost_util.cc +++ b/src/frontend/xgboost_util.cc @@ -49,7 +49,7 @@ void SetPredTransform(const std::string& objective_name, ModelParam* param) { || objective_name == "rank:map") { SetPredTransformString("identity", param); } else { - LOG(FATAL) << "Unrecognized XGBoost objective: " << objective_name; + TREELITE_LOG(FATAL) << "Unrecognized XGBoost objective: " << objective_name; } } diff --git a/src/gtil/pred_transform.cc b/src/gtil/pred_transform.cc index 75972f5e..602c3e0b 100644 --- a/src/gtil/pred_transform.cc +++ b/src/gtil/pred_transform.cc @@ -35,7 +35,7 @@ std::size_t hinge(const treelite::Model&, const float* in, float* out) { std::size_t sigmoid(const treelite::Model& model, const float* in, float* out) { const float alpha = model.param.sigmoid_alpha; - CHECK(alpha > 0.0f) << "sigmoid: alpha must be strictly positive"; + TREELITE_CHECK(alpha > 0.0f) << "sigmoid: alpha must be strictly positive"; *out = 1.0f / (1.0f + std::exp(-alpha * *in)); return 1; } @@ -52,7 +52,7 @@ std::size_t logarithm_one_plus_exp(const treelite::Model&, const float* in, floa std::size_t identity_multiclass(const treelite::Model& model, const float* in, float* out) { auto num_class = static_cast(model.task_param.num_class); - CHECK(num_class > 1) << "model must be a multi-class classifier"; + TREELITE_CHECK(num_class > 1) << "model must be a multi-class classifier"; for (std::size_t i = 0; i < num_class; ++i) { out[i] = in[i]; } @@ -61,7 +61,7 @@ std::size_t identity_multiclass(const treelite::Model& model, const float* in, f std::size_t max_index(const treelite::Model& model, const float* in, float* out) { auto num_class = static_cast(model.task_param.num_class); - CHECK(num_class > 1) << "model must be a multi-class classifier"; + TREELITE_CHECK(num_class > 1) << "model must be a multi-class classifier"; std::size_t max_index = 0; float max_margin = in[0]; for (std::size_t i = 1; i < num_class; ++i) { @@ -76,7 +76,7 @@ std::size_t max_index(const treelite::Model& model, const float* in, float* out) std::size_t softmax(const treelite::Model& model, const float* in, float* out) { auto num_class = static_cast(model.task_param.num_class); - CHECK(num_class > 1) << "model must be a multi-class classifier"; + TREELITE_CHECK(num_class > 1) << "model must be a multi-class classifier"; float max_margin = in[0]; double norm_const = 0.0; float t; @@ -98,9 +98,9 @@ std::size_t softmax(const treelite::Model& model, const float* in, float* out) { std::size_t multiclass_ova(const treelite::Model& model, const float* in, float* out) { auto num_class = static_cast(model.task_param.num_class); - CHECK(num_class > 1) << "model must be a multi-class classifier"; + TREELITE_CHECK(num_class > 1) << "model must be a multi-class classifier"; const float alpha = model.param.sigmoid_alpha; - CHECK(alpha > 0.0f) << "multiclass_ova: alpha must be strictly positive"; + TREELITE_CHECK(alpha > 0.0f) << "multiclass_ova: alpha must be strictly positive"; for (std::size_t i = 0; i < num_class; ++i) { out[i] = 1.0f / (1.0f + std::exp(-alpha * in[i])); } diff --git a/src/gtil/predict.cc b/src/gtil/predict.cc index e2d54d81..aa7b0f51 100644 --- a/src/gtil/predict.cc +++ b/src/gtil/predict.cc @@ -38,7 +38,7 @@ inline int NextNode(float fvalue, T threshold, treelite::Operator op, case treelite::Operator::kGE: return (fvalue >= threshold) ? left_child : right_child; default: - CHECK(false) << "Unrecognized comparison operator " << static_cast(op); + TREELITE_CHECK(false) << "Unrecognized comparison operator " << static_cast(op); return -1; } } @@ -94,7 +94,7 @@ inline std::size_t PredictImplInner(const treelite::ModelImpl(split_type); + TREELITE_CHECK(false) << "Unrecognized split type: " << static_cast(split_type); } } output_func(tree, tree_id, node_id, sum.data()); @@ -102,18 +102,18 @@ inline std::size_t PredictImplInner(const treelite::ModelImpl(task_param.num_class); average_factor = static_cast(num_boosting_round); } else { - CHECK(model.task_type == treelite::TaskType::kBinaryClfRegr - || model.task_type == treelite::TaskType::kMultiClfProbDistLeaf); - CHECK(task_param.num_class == task_param.leaf_vector_size); - CHECK(!task_param.grove_per_class); + TREELITE_CHECK(model.task_type == treelite::TaskType::kBinaryClfRegr + || model.task_type == treelite::TaskType::kMultiClfProbDistLeaf); + TREELITE_CHECK(task_param.num_class == task_param.leaf_vector_size); + TREELITE_CHECK(!task_param.grove_per_class); average_factor = static_cast(num_tree); } for (unsigned int i = 0; i < task_param.num_class; ++i) { @@ -190,7 +190,7 @@ std::size_t Predict(const Model* model, const DMatrix* input, float* output, boo return PredictImpl(model, d2, output, pred_transform); }); } else { - LOG(FATAL) << "DMatrix with float64 data is not supported"; + TREELITE_LOG(FATAL) << "DMatrix with float64 data is not supported"; return 0; } } diff --git a/src/json_serializer.cc b/src/json_serializer.cc index f93739ba..92fcac21 100644 --- a/src/json_serializer.cc +++ b/src/json_serializer.cc @@ -132,11 +132,11 @@ void SerializeTreeToJSON(WriterType& writer, const Tree diff --git a/src/predictor/predictor.cc b/src/predictor/predictor.cc index 96c9d9c7..9b3d6582 100644 --- a/src/predictor/predictor.cc +++ b/src/predictor/predictor.cc @@ -50,10 +50,10 @@ using PredThreadPool template inline size_t PredLoop(const treelite::CSRDMatrixImpl* dmat, int num_feature, size_t rbegin, size_t rend, LeafOutputType* out_pred, PredFunc func) { - CHECK_LE(dmat->num_col, static_cast(num_feature)); + TREELITE_CHECK_LE(dmat->num_col, static_cast(num_feature)); std::vector> inst( std::max(dmat->num_col, static_cast(num_feature)), {-1}); - CHECK(rbegin < rend && rend <= dmat->num_row); + TREELITE_CHECK(rbegin < rend && rend <= dmat->num_row); const ElementType* data = dmat->data.data(); const uint32_t* col_ind = dmat->col_ind.data(); const size_t* row_ptr = dmat->row_ptr.data(); @@ -76,10 +76,10 @@ template * dmat, int num_feature, size_t rbegin, size_t rend, LeafOutputType* out_pred, PredFunc func) { const bool nan_missing = treelite::math::CheckNAN(dmat->missing_value); - CHECK_LE(dmat->num_col, static_cast(num_feature)); + TREELITE_CHECK_LE(dmat->num_col, static_cast(num_feature)); std::vector> inst( std::max(dmat->num_col, static_cast(num_feature)), {-1}); - CHECK(rbegin < rend && rend <= dmat->num_row); + TREELITE_CHECK(rbegin < rend && rend <= dmat->num_row); const size_t num_col = dmat->num_col; const ElementType missing_value = dmat->missing_value; const ElementType* data = dmat->data.data(); @@ -89,7 +89,7 @@ inline size_t PredLoop(const treelite::DenseDMatrixImpl* dmat, int row = &data[rid * num_col]; for (size_t j = 0; j < num_col; ++j) { if (treelite::math::CheckNAN(row[j])) { - CHECK(nan_missing) + TREELITE_CHECK(nan_missing) << "The missing_value argument must be set to NaN if there is any NaN in the matrix."; } else if (nan_missing || row[j] != missing_value) { inst[j].fvalue = static_cast(row[j]); @@ -143,7 +143,7 @@ inline size_t PredLoop(const treelite::DMatrix* dmat, ThresholdType test_val, in dmat->GetElementType(), dmat, test_val, num_feature, rbegin, rend, out_pred, func); } default: - LOG(FATAL) << "Unrecognized data matrix type: " << static_cast(dmat_type); + TREELITE_LOG(FATAL) << "Unrecognized data matrix type: " << static_cast(dmat_type); return 0; } } @@ -172,7 +172,7 @@ SharedLibrary::Load(const char* libpath) { #else void* handle = dlopen(libpath, RTLD_LAZY | RTLD_LOCAL); #endif - CHECK(handle) << "Failed to load dynamic shared library `" << libpath << "'"; + TREELITE_CHECK(handle) << "Failed to load dynamic shared library `" << libpath << "'"; handle_ = static_cast(handle); libpath_ = std::string(libpath); } @@ -184,7 +184,7 @@ SharedLibrary::LoadFunction(const char* name) const { #else void* func_handle = dlsym(static_cast(handle_), name); #endif - CHECK(func_handle) + TREELITE_CHECK(func_handle) << "Dynamic shared library `" << libpath_ << "' does not contain a function " << name << "()."; return static_cast(func_handle); } @@ -193,8 +193,9 @@ template HandleType SharedLibrary::LoadFunctionWithSignature(const char* name) const { auto func_handle = reinterpret_cast(LoadFunction(name)); - CHECK(func_handle) << "Dynamic shared library `" << libpath_ << "' does not contain a function " - << name << "() with the requested signature"; + TREELITE_CHECK(func_handle) << "Dynamic shared library `" << libpath_ + << "' does not contain a function " << name + << "() with the requested signature"; return func_handle; } @@ -219,7 +220,7 @@ PredFunction::Create( template PredFunctionImpl::PredFunctionImpl( const SharedLibrary& library, int num_feature, int num_class) { - CHECK_GT(num_class, 0) << "num_class cannot be zero"; + TREELITE_CHECK_GT(num_class, 0) << "num_class cannot be zero"; if (num_class > 1) { // multi-class classification handle_ = library.LoadFunction("predict_multiclass"); } else { // everything else @@ -253,11 +254,11 @@ PredFunctionImpl::PredictBatch( // can be either [num_data] or [num_class]*[num_data]. // Note that size of prediction may be smaller than out_pred (this occurs // when pred_function is set to "max_index"). - CHECK(rbegin < rend && rend <= dmat->GetNumRow()); + TREELITE_CHECK(rbegin < rend && rend <= dmat->GetNumRow()); if (num_class_ > 1) { // multi-class classification using PredFunc = size_t (*)(Entry*, int, LeafOutputType*); auto pred_func = reinterpret_cast(handle_); - CHECK(pred_func) << "The predict_multiclass() function has incorrect signature."; + TREELITE_CHECK(pred_func) << "The predict_multiclass() function has incorrect signature."; auto pred_func_wrapper = [pred_func, num_class = num_class_, pred_margin] (int64_t rid, Entry* inst, LeafOutputType* out_pred) -> size_t { @@ -269,7 +270,7 @@ PredFunctionImpl::PredictBatch( } else { // everything else using PredFunc = LeafOutputType (*)(Entry*, int); auto pred_func = reinterpret_cast(handle_); - CHECK(pred_func) << "The predict() function has incorrect signature."; + TREELITE_CHECK(pred_func) << "The predict() function has incorrect signature."; auto pred_func_wrapper = [pred_func, pred_margin] (int64_t rid, Entry* inst, LeafOutputType* out_pred) -> size_t { @@ -315,7 +316,7 @@ Predictor::Load(const char* libpath) { auto* num_feature_query_func = lib_.LoadFunctionWithSignature("get_num_feature"); num_feature_ = num_feature_query_func(); - CHECK_GT(num_feature_, 0) << "num_feature cannot be zero"; + TREELITE_CHECK_GT(num_feature_, 0) << "num_feature cannot be zero"; /* 3. query # of pred_transform name */ auto* pred_transform_query_func @@ -340,7 +341,7 @@ Predictor::Load(const char* libpath) { leaf_output_type_ = GetTypeInfoByName(leaf_output_type_query_func()); /* 7. load appropriate function for margin prediction */ - CHECK_GT(num_class_, 0) << "num_class cannot be zero"; + TREELITE_CHECK_GT(num_class_, 0) << "num_class cannot be zero"; pred_func_ = PredFunction::Create( threshold_type_, leaf_output_type_, lib_, static_cast(num_feature_), static_cast(num_class_)); @@ -375,7 +376,7 @@ Predictor::Free() { static inline std::vector SplitBatch(const DMatrix* dmat, size_t split_factor) { const size_t num_row = dmat->GetNumRow(); - CHECK_LE(split_factor, num_row); + TREELITE_CHECK_LE(split_factor, num_row); const size_t portion = num_row / split_factor; const size_t remainder = num_row % split_factor; std::vector workload(split_factor, portion); @@ -420,7 +421,7 @@ Predictor::PredictBatch( auto* pool = static_cast(thread_pool_handle_); InputToken request{dmat, pred_margin, pred_func_.get(), 0, num_row, out_result}; OutputToken response; - CHECK_GT(num_row, 0); + TREELITE_CHECK_GT(num_row, 0); const int nthread = std::min(num_worker_thread_, static_cast(num_row)); const std::vector row_ptr = SplitBatch(dmat, nthread); for (int tid = 0; tid < nthread - 1; ++tid) { @@ -444,17 +445,17 @@ Predictor::PredictBatch( } // re-shape output if total_size < dimension of out_result if (total_size < QueryResultSize(dmat, 0, num_row)) { - CHECK_GT(num_class_, 1); - CHECK_EQ(total_size % num_row, 0); + TREELITE_CHECK_GT(num_class_, 1); + TREELITE_CHECK_EQ(total_size % num_row, 0); const size_t query_size_per_instance = total_size / num_row; - CHECK_GT(query_size_per_instance, 0); - CHECK_LT(query_size_per_instance, num_class_); + TREELITE_CHECK_GT(query_size_per_instance, 0); + TREELITE_CHECK_LT(query_size_per_instance, num_class_); DispatchWithTypeInfo( leaf_output_type_, num_row, query_size_per_instance, num_class_, out_result); } const double tend = GetTime(); if (verbose > 0) { - LOG(INFO) << "Treelite: Finished prediction in " << tend - tstart << " sec"; + TREELITE_LOG(INFO) << "Treelite: Finished prediction in " << tend - tstart << " sec"; } return total_size; } diff --git a/src/predictor/thread_pool/spsc_queue.h b/src/predictor/thread_pool/spsc_queue.h index 23cb6bb2..0f120b0d 100644 --- a/src/predictor/thread_pool/spsc_queue.h +++ b/src/predictor/thread_pool/spsc_queue.h @@ -62,7 +62,7 @@ class SpscQueue { } const uint32_t head = head_.load(std::memory_order_relaxed); // sanity check if the queue is empty - CHECK(tail_.load(std::memory_order_acquire) != head); + TREELITE_CHECK(tail_.load(std::memory_order_acquire) != head); *output = buffer_[head]; head_.store((head + 1) % kRingSize, std::memory_order_release); return true; diff --git a/src/predictor/thread_pool/thread_pool.h b/src/predictor/thread_pool/thread_pool.h index f0d21b24..78f7aff9 100644 --- a/src/predictor/thread_pool/thread_pool.h +++ b/src/predictor/thread_pool/thread_pool.h @@ -35,8 +35,8 @@ class ThreadPool { ThreadPool(int num_worker, const TaskContext* context, TaskFunc task) : num_worker_(num_worker), context_(context), task_(task) { - CHECK(num_worker_ >= 0 - && static_cast(num_worker_) < std::thread::hardware_concurrency()) + TREELITE_CHECK(num_worker_ >= 0 + && static_cast(num_worker_) < std::thread::hardware_concurrency()) << "Number of worker threads must be between 0 and " << (std::thread::hardware_concurrency() - 1); for (int i = 0; i < num_worker_; ++i) {