From 83dc91a60406dc99abff5b95b2b290d57d154024 Mon Sep 17 00:00:00 2001 From: fuyw Date: Thu, 23 Jun 2022 09:20:40 -0400 Subject: [PATCH 1/4] add function_name to compiler --- lleaves/compiler/codegen/codegen.py | 4 ++-- lleaves/compiler/tree_compiler.py | 4 ++-- lleaves/lleaves.py | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lleaves/compiler/codegen/codegen.py b/lleaves/compiler/codegen/codegen.py index 2c55970..d277a3a 100644 --- a/lleaves/compiler/codegen/codegen.py +++ b/lleaves/compiler/codegen/codegen.py @@ -39,7 +39,7 @@ class LTree: class_id: int -def gen_forest(forest, module, fblocksize): +def gen_forest(forest, module, fblocksize, function_name="forest_root"): """ Populate the passed IR module with code for the forest. @@ -81,7 +81,7 @@ def gen_forest(forest, module, fblocksize): root_func = ir.Function( module, ir.FunctionType(ir.VoidType(), (DOUBLE_PTR, DOUBLE_PTR, INT, INT)), - name="forest_root", + name=function_name, ) def make_tree(tree): diff --git a/lleaves/compiler/tree_compiler.py b/lleaves/compiler/tree_compiler.py index 1ad65d5..de5a992 100644 --- a/lleaves/compiler/tree_compiler.py +++ b/lleaves/compiler/tree_compiler.py @@ -7,12 +7,12 @@ from lleaves.compiler.codegen import gen_forest -def compile_to_module(file_path, fblocksize=34, finline=True, raw_score=False): +def compile_to_module(file_path, fblocksize=34, finline=True, raw_score=False, function_name="forest_root"): forest = parse_to_ast(file_path) forest.raw_score = raw_score ir = llvmlite.ir.Module(name="forest") - gen_forest(forest, ir, fblocksize) + gen_forest(forest, ir, fblocksize, function_name) ir.triple = llvm.get_process_triple() module = llvm.parse_assembly(str(ir)) diff --git a/lleaves/lleaves.py b/lleaves/lleaves.py index 5a2956c..7dc9ecc 100644 --- a/lleaves/lleaves.py +++ b/lleaves/lleaves.py @@ -85,6 +85,7 @@ def compile( fblocksize=34, fcodemodel="large", finline=True, + function_name="forest_root", ): """ Generate the LLVM IR for this model and compile it to ASM. @@ -107,6 +108,7 @@ def compile( very large forests. :param finline: Whether or not to inline function. Setting this to False will speed-up compilation time significantly but will slow down prediction. + :function_name: Name of the prediction function, default to be `forest_root`. """ assert 0 < fblocksize assert fcodemodel in ("small", "large") @@ -117,6 +119,7 @@ def compile( raw_score=raw_score, fblocksize=fblocksize, finline=finline, + function_name=function_name, ) else: # when loading binary from cache we use a dummy empty module From c7db90dded32d47c4f3c7a1369289683905e80f7 Mon Sep 17 00:00:00 2001 From: fuyw Date: Thu, 23 Jun 2022 10:08:47 -0400 Subject: [PATCH 2/4] fix typo --- lleaves/lleaves.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lleaves/lleaves.py b/lleaves/lleaves.py index 7dc9ecc..2e8887e 100644 --- a/lleaves/lleaves.py +++ b/lleaves/lleaves.py @@ -108,7 +108,7 @@ def compile( very large forests. :param finline: Whether or not to inline function. Setting this to False will speed-up compilation time significantly but will slow down prediction. - :function_name: Name of the prediction function, default to be `forest_root`. + :param function_name: Name of the prediction function, default to be `forest_root`. """ assert 0 < fblocksize assert fcodemodel in ("small", "large") From e7132522e39771eded0ce1f4890de4f2b2c7c554 Mon Sep 17 00:00:00 2001 From: Simon Boehm Date: Sun, 10 Jul 2022 17:07:21 +0200 Subject: [PATCH 3/4] Fix wrong func name in default case, add test --- lleaves/lleaves.py | 2 +- tests/test_compile_flags.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lleaves/lleaves.py b/lleaves/lleaves.py index bbed4e2..60e9349 100644 --- a/lleaves/lleaves.py +++ b/lleaves/lleaves.py @@ -131,7 +131,7 @@ def compile( ) # Drops GIL during call, re-acquires it after - addr = self._execution_engine.get_function_address("forest_root") + addr = self._execution_engine.get_function_address(function_name) self._c_entry_func = ENTRY_FUNC_TYPE(addr) self.is_compiled = True diff --git a/tests/test_compile_flags.py b/tests/test_compile_flags.py index b63fd1b..19f2d84 100644 --- a/tests/test_compile_flags.py +++ b/tests/test_compile_flags.py @@ -74,3 +74,19 @@ def test_no_inline(NYC_data): llvm_model.predict(NYC_data[:1000], n_jobs=2), lgbm_model.predict(NYC_data[:1000], n_jobs=2), ) + + +def test_function_name(): + llvm_model = Model(model_file="tests/models/tiniest_single_tree/model.txt") + lgbm_model = Booster(model_file="tests/models/tiniest_single_tree/model.txt") + llvm_model.compile(function_name="tiniest_single_tree_123132_XXX-") + + data = [ + [1.0] * 3, + [0.0] * 3, + [-1.0] * 3, + ] + np.testing.assert_almost_equal( + llvm_model.predict(data, n_jobs=2), + lgbm_model.predict(data, n_jobs=2), + ) From 1bd2d5008cc955cf67ed10079f175a82cbe0c0ba Mon Sep 17 00:00:00 2001 From: Simon Boehm Date: Sun, 10 Jul 2022 17:15:42 +0200 Subject: [PATCH 4/4] Rename function_name parameter for consistency --- lleaves/compiler/codegen/codegen.py | 4 ++-- lleaves/compiler/tree_compiler.py | 10 ++++++++-- lleaves/lleaves.py | 9 +++++---- tests/test_compile_flags.py | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lleaves/compiler/codegen/codegen.py b/lleaves/compiler/codegen/codegen.py index d277a3a..d6c42d3 100644 --- a/lleaves/compiler/codegen/codegen.py +++ b/lleaves/compiler/codegen/codegen.py @@ -39,7 +39,7 @@ class LTree: class_id: int -def gen_forest(forest, module, fblocksize, function_name="forest_root"): +def gen_forest(forest, module, fblocksize, froot_func_name): """ Populate the passed IR module with code for the forest. @@ -81,7 +81,7 @@ def gen_forest(forest, module, fblocksize, function_name="forest_root"): root_func = ir.Function( module, ir.FunctionType(ir.VoidType(), (DOUBLE_PTR, DOUBLE_PTR, INT, INT)), - name=function_name, + name=froot_func_name, ) def make_tree(tree): diff --git a/lleaves/compiler/tree_compiler.py b/lleaves/compiler/tree_compiler.py index de5a992..aaeac49 100644 --- a/lleaves/compiler/tree_compiler.py +++ b/lleaves/compiler/tree_compiler.py @@ -7,12 +7,18 @@ from lleaves.compiler.codegen import gen_forest -def compile_to_module(file_path, fblocksize=34, finline=True, raw_score=False, function_name="forest_root"): +def compile_to_module( + file_path, + fblocksize=34, + finline=True, + raw_score=False, + froot_func_name="forest_root", +): forest = parse_to_ast(file_path) forest.raw_score = raw_score ir = llvmlite.ir.Module(name="forest") - gen_forest(forest, ir, fblocksize, function_name) + gen_forest(forest, ir, fblocksize, froot_func_name) ir.triple = llvm.get_process_triple() module = llvm.parse_assembly(str(ir)) diff --git a/lleaves/lleaves.py b/lleaves/lleaves.py index 60e9349..45e1625 100644 --- a/lleaves/lleaves.py +++ b/lleaves/lleaves.py @@ -85,7 +85,7 @@ def compile( fblocksize=34, fcodemodel="large", finline=True, - function_name="forest_root", + froot_func_name="forest_root", ): """ Generate the LLVM IR for this model and compile it to ASM. @@ -108,7 +108,8 @@ def compile( very large forests. :param finline: Whether or not to inline function. Setting this to False will speed-up compilation time significantly but will slow down prediction. - :param function_name: Name of the prediction function, default to be `forest_root`. + :param froot_func_name: Name of entry point function in the compiled binary. This is the function to link when + writing a C function wrapper. Defaults to "forest_root". """ assert 0 < fblocksize assert fcodemodel in ("small", "large") @@ -119,7 +120,7 @@ def compile( raw_score=raw_score, fblocksize=fblocksize, finline=finline, - function_name=function_name, + froot_func_name=froot_func_name, ) else: # when loading binary from cache we use a dummy empty module @@ -131,7 +132,7 @@ def compile( ) # Drops GIL during call, re-acquires it after - addr = self._execution_engine.get_function_address(function_name) + addr = self._execution_engine.get_function_address(froot_func_name) self._c_entry_func = ENTRY_FUNC_TYPE(addr) self.is_compiled = True diff --git a/tests/test_compile_flags.py b/tests/test_compile_flags.py index 19f2d84..5909388 100644 --- a/tests/test_compile_flags.py +++ b/tests/test_compile_flags.py @@ -79,7 +79,7 @@ def test_no_inline(NYC_data): def test_function_name(): llvm_model = Model(model_file="tests/models/tiniest_single_tree/model.txt") lgbm_model = Booster(model_file="tests/models/tiniest_single_tree/model.txt") - llvm_model.compile(function_name="tiniest_single_tree_123132_XXX-") + llvm_model.compile(froot_func_name="tiniest_single_tree_123132_XXX-") data = [ [1.0] * 3,