From 665c87317e452f08fcb4923e1274abeaf978d220 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Thu, 12 Sep 2024 21:59:11 +0200 Subject: [PATCH 01/14] autoload bridge shared library for the cpp backend --- conifer/model.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/conifer/model.py b/conifer/model.py index 2812fe60..73239271 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -532,7 +532,7 @@ def make_model(ensembleDict, config=None): backend = get_backend(backend) return backend.make_model(ensembleDict, config) -def load_model(filename, new_config=None): +def load_model(filename, shared_library=None, new_config=None): ''' Load a Model from JSON file @@ -561,4 +561,17 @@ def load_model(filename, new_config=None): model = make_model(js, config) model._metadata = metadata + model._metadata + + try: + if config["backend"] == "cpp": + import importlib + last_timestamp=int(model._metadata[-2]._to_dict()["time"]) + #look for the shared library in the same directory as the model json if not specified + shared_library_path=os.path.join(os.path.dirname(filename), f'conifer_bridge_{last_timestamp}.so') if shared_library is None else shared_library + spec = importlib.util.spec_from_file_location(f'conifer_bridge_{last_timestamp}', shared_library_path) + model.bridge = importlib.util.module_from_spec(spec).BDT(filename) + spec.loader.exec_module(model.bridge) + except Exception as e: + logger.warn("Was not able to load the shared library. Run model.compile(): ", e) + return model From fe5f9b358ba278f24ce1b947e16c9f912ebcfec4 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Thu, 12 Sep 2024 22:05:29 +0200 Subject: [PATCH 02/14] Added same behavior for xilinxhls --- conifer/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conifer/model.py b/conifer/model.py index 73239271..83f2e61a 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -563,7 +563,7 @@ def load_model(filename, shared_library=None, new_config=None): model._metadata = metadata + model._metadata try: - if config["backend"] == "cpp": + if config["backend"] in ["cpp","xilinxhls"]: import importlib last_timestamp=int(model._metadata[-2]._to_dict()["time"]) #look for the shared library in the same directory as the model json if not specified From 022be2b0e80b13d236b71580159a1c28c7345933 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 16:56:50 +0200 Subject: [PATCH 03/14] swapped arguments --- conifer/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conifer/model.py b/conifer/model.py index 83f2e61a..d0796242 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -532,7 +532,7 @@ def make_model(ensembleDict, config=None): backend = get_backend(backend) return backend.make_model(ensembleDict, config) -def load_model(filename, shared_library=None, new_config=None): +def load_model(filename, new_config=None, shared_library=None): ''' Load a Model from JSON file From d1e8490102e50f8596a0d1952364acb707d0b833 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 16:57:37 +0200 Subject: [PATCH 04/14] added shared_l;ibrary docstring --- conifer/model.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conifer/model.py b/conifer/model.py index d0796242..1bbc7e67 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -542,6 +542,8 @@ def load_model(filename, new_config=None, shared_library=None): filename to load from new_config: dictionary (optional) if provided, override the configuration specified in the JSON file + shared_library: string (optional) + path to the shared library to load for the model. If not provided, the shared library will be looked for in the same directory as the JSON file, using the timestamp of the last metadata entry available ''' with open(filename, 'r') as json_file: js = json.load(json_file) From 9298f9289b3002305012ab8e764a1f6d4707356f Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 16:58:36 +0200 Subject: [PATCH 05/14] try .so loading just in a new config is not provided --- conifer/model.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/conifer/model.py b/conifer/model.py index 1bbc7e67..6210e222 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -564,16 +564,17 @@ def load_model(filename, new_config=None, shared_library=None): model = make_model(js, config) model._metadata = metadata + model._metadata - try: - if config["backend"] in ["cpp","xilinxhls"]: - import importlib - last_timestamp=int(model._metadata[-2]._to_dict()["time"]) - #look for the shared library in the same directory as the model json if not specified - shared_library_path=os.path.join(os.path.dirname(filename), f'conifer_bridge_{last_timestamp}.so') if shared_library is None else shared_library - spec = importlib.util.spec_from_file_location(f'conifer_bridge_{last_timestamp}', shared_library_path) - model.bridge = importlib.util.module_from_spec(spec).BDT(filename) - spec.loader.exec_module(model.bridge) - except Exception as e: - logger.warn("Was not able to load the shared library. Run model.compile(): ", e) + if new_config is None: + try: + if config["backend"] in ["cpp","xilinxhls"]: + import importlib + last_timestamp=int(model._metadata[-2]._to_dict()["time"]) + #look for the shared library in the same directory as the model json if not specified + shared_library_path=os.path.join(os.path.dirname(filename), f'conifer_bridge_{last_timestamp}.so') if shared_library is None else shared_library + spec = importlib.util.spec_from_file_location(f'conifer_bridge_{last_timestamp}', shared_library_path) + model.bridge = importlib.util.module_from_spec(spec).BDT(filename) + spec.loader.exec_module(model.bridge) + except Exception as e: + print("An existing shared library was either not found or could not be loaded. Run model.compile(): ", e) return model From 1bf4bff17507f7f07251bfbde7bf97015901356b Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 17:13:34 +0200 Subject: [PATCH 06/14] moved .so loading to the backends --- conifer/backends/cpp/writer.py | 11 +++++++---- conifer/backends/xilinxhls/writer.py | 11 +++++++---- conifer/model.py | 15 +++++++-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/conifer/backends/cpp/writer.py b/conifer/backends/cpp/writer.py index df6cdc5d..3f7e1b32 100644 --- a/conifer/backends/cpp/writer.py +++ b/conifer/backends/cpp/writer.py @@ -24,6 +24,12 @@ class CPPModel(ModelBase): def __init__(self, ensembleDict, config, metadata=None): super(CPPModel, self).__init__(ensembleDict, config, metadata) self.config = CPPConfig(config) + + def load_shared_library(self, model_json, shared_library): + import importlib + spec = importlib.util.spec_from_file_location(os.path.basename(shared_library).split(".so")[0], shared_library) + self.bridge = importlib.util.module_from_spec(spec).BDT(model_json) + spec.loader.exec_module(self.bridge) @copydocstring(ModelBase.write) def write(self): @@ -99,10 +105,7 @@ def compile(self): try: logger.debug(f'Importing conifer_bridge_{self._stamp} from conifer_bridge_{self._stamp}.so') - import importlib.util - spec = importlib.util.spec_from_file_location(f'conifer_bridge_{self._stamp}', f'./conifer_bridge_{self._stamp}.so') - self.bridge = importlib.util.module_from_spec(spec).BDT(f"{cfg.project_name}.json") - spec.loader.exec_module(self.bridge) + self.load_shared_library(f"{cfg.project_name}.json", f"./conifer_bridge_{self._stamp}.so") except ImportError: os.chdir(curr_dir) raise Exception("Can't import pybind11 bridge, is it compiled?") diff --git a/conifer/backends/xilinxhls/writer.py b/conifer/backends/xilinxhls/writer.py index e9b28f4c..290bbdcd 100644 --- a/conifer/backends/xilinxhls/writer.py +++ b/conifer/backends/xilinxhls/writer.py @@ -512,6 +512,12 @@ def decision_function(self, X, trees=False): y = y.reshape(y.shape[0]) return y + def load_shared_library(self, model_json, shared_library): + import importlib + spec = importlib.util.spec_from_file_location(os.path.basename(shared_library).split(".so")[0], shared_library) + self.bridge = importlib.util.module_from_spec(spec).BDT(model_json) + spec.loader.exec_module(self.bridge) + @copydocstring(ModelBase.compile) def compile(self): self.write() @@ -534,10 +540,7 @@ def compile(self): try: logger.debug(f'Importing conifer_bridge_{self._stamp} from conifer_bridge_{self._stamp}.so') - import importlib.util - spec = importlib.util.spec_from_file_location(f'conifer_bridge_{self._stamp}', f'./conifer_bridge_{self._stamp}.so') - self.bridge = importlib.util.module_from_spec(spec) - spec.loader.exec_module(self.bridge) + self.load_shared_library(f"{cfg.project_name}.json", f"./conifer_bridge_{self._stamp}.so") except ImportError: os.chdir(curr_dir) raise Exception("Can't import pybind11 bridge, is it compiled?") diff --git a/conifer/model.py b/conifer/model.py index 6210e222..93e06f2a 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -532,6 +532,9 @@ def make_model(ensembleDict, config=None): backend = get_backend(backend) return backend.make_model(ensembleDict, config) +def load_shared_library(self, model_json, shared_library): + pass + def load_model(filename, new_config=None, shared_library=None): ''' Load a Model from JSON file @@ -566,14 +569,10 @@ def load_model(filename, new_config=None, shared_library=None): if new_config is None: try: - if config["backend"] in ["cpp","xilinxhls"]: - import importlib - last_timestamp=int(model._metadata[-2]._to_dict()["time"]) - #look for the shared library in the same directory as the model json if not specified - shared_library_path=os.path.join(os.path.dirname(filename), f'conifer_bridge_{last_timestamp}.so') if shared_library is None else shared_library - spec = importlib.util.spec_from_file_location(f'conifer_bridge_{last_timestamp}', shared_library_path) - model.bridge = importlib.util.module_from_spec(spec).BDT(filename) - spec.loader.exec_module(model.bridge) + last_timestamp=int(model._metadata[-2]._to_dict()["time"]) + #look for the shared library in the same directory as the model json if not specified + shared_library_path=os.path.join(os.path.dirname(filename), f'conifer_bridge_{last_timestamp}.so') if shared_library is None else shared_library + model.load_shared_library(filename, shared_library_path) except Exception as e: print("An existing shared library was either not found or could not be loaded. Run model.compile(): ", e) From 9e843af391f87b0c32bc80453d91d48b7efd8c90 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 17:44:41 +0200 Subject: [PATCH 07/14] fix: moved load_shared_library to the right class --- conifer/model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conifer/model.py b/conifer/model.py index 93e06f2a..61dd92e1 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -495,6 +495,9 @@ def _profile(self, what : Literal["scores", "thresholds"], ax=None): return ax + def load_shared_library(self, model_json, shared_library): + pass + class ModelMetaData: def __init__(self): self.version = version @@ -532,9 +535,6 @@ def make_model(ensembleDict, config=None): backend = get_backend(backend) return backend.make_model(ensembleDict, config) -def load_shared_library(self, model_json, shared_library): - pass - def load_model(filename, new_config=None, shared_library=None): ''' Load a Model from JSON file From 0bf9206270ef3070ea482a40872baa561e3b72b0 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 17:45:17 +0200 Subject: [PATCH 08/14] look for all the timestamps from the last to the first --- conifer/model.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/conifer/model.py b/conifer/model.py index 61dd92e1..3118fd0b 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -546,7 +546,8 @@ def load_model(filename, new_config=None, shared_library=None): new_config: dictionary (optional) if provided, override the configuration specified in the JSON file shared_library: string (optional) - path to the shared library to load for the model. If not provided, the shared library will be looked for in the same directory as the JSON file, using the timestamp of the last metadata entry available + path to the shared library (or to the directory where to look for the .so file) to load for the model. + If not provided, the shared library will be looked for in the same directory as the JSON file, using the timestamp of the last metadata entry available ''' with open(filename, 'r') as json_file: js = json.load(json_file) @@ -568,12 +569,23 @@ def load_model(filename, new_config=None, shared_library=None): model._metadata = metadata + model._metadata if new_config is None: + shared_library_path=None + if shared_library is None or not shared_library.endswith(".so"): + from glob import glob + shared_library_dirpath=os.path.abspath(os.path.dirname(filename)) if shared_library is None else shared_library + timestamps=[int(md._to_dict()["time"]) for md in model._metadata[-2::-1]] + so_files=glob(os.path.join(shared_library_dirpath, 'conifer_bridge_*.so')) + so_files=[os.path.basename(so_file) for so_file in so_files] + for timestamp in timestamps: + if f"conifer_bridge_{timestamp}.so" in so_files: + shared_library_path=os.path.join(shared_library_dirpath, f'conifer_bridge_{timestamp}.so') + break + elif shared_library.endswith(".so"): + shared_library_path=shared_library + try: - last_timestamp=int(model._metadata[-2]._to_dict()["time"]) - #look for the shared library in the same directory as the model json if not specified - shared_library_path=os.path.join(os.path.dirname(filename), f'conifer_bridge_{last_timestamp}.so') if shared_library is None else shared_library model.load_shared_library(filename, shared_library_path) - except Exception as e: - print("An existing shared library was either not found or could not be loaded. Run model.compile(): ", e) + except Exception: + print("An existing shared library was either not found or could not be loaded. Run model.compile()") return model From 8c961dd084896374cd011022dd845f9943a03bfc Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 18:47:20 +0200 Subject: [PATCH 09/14] fixed xilinxhls backend --- conifer/backends/xilinxhls/writer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conifer/backends/xilinxhls/writer.py b/conifer/backends/xilinxhls/writer.py index 290bbdcd..9b188978 100644 --- a/conifer/backends/xilinxhls/writer.py +++ b/conifer/backends/xilinxhls/writer.py @@ -515,7 +515,7 @@ def decision_function(self, X, trees=False): def load_shared_library(self, model_json, shared_library): import importlib spec = importlib.util.spec_from_file_location(os.path.basename(shared_library).split(".so")[0], shared_library) - self.bridge = importlib.util.module_from_spec(spec).BDT(model_json) + self.bridge = importlib.util.module_from_spec(spec) spec.loader.exec_module(self.bridge) @copydocstring(ModelBase.compile) From 9aaf2991748e96a17c79d535d20829d1e7689f03 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 18:55:20 +0200 Subject: [PATCH 10/14] Added test --- tests/test_save_load.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_save_load.py b/tests/test_save_load.py index c617ec8a..e6c1ac49 100644 --- a/tests/test_save_load.py +++ b/tests/test_save_load.py @@ -15,6 +15,10 @@ def test_hls_save_load(hls_convert, train_skl): load_model.compile() y_hls_0, y_hls_1 = util.predict_skl(orig_model, X, y, load_model) np.testing.assert_array_equal(y_hls_0, y_hls_1) + # Re-load without recompiling to check if the shared library is loaded correctly + load_model2 = conifer.model.load_model(f'{orig_model.config.output_dir}/{orig_model.config.project_name}.json') + _, y_hls_2 = util.predict_skl(orig_model, X, y, load_model2) + np.testing.assert_array_equal(y_hls_0, y_hls_2) def test_hdl_save_load(vhdl_convert, train_skl): orig_model = vhdl_convert From 7118a0ab1ad81cfdfef5367e82f2e71d58ab9524 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 23:15:32 +0200 Subject: [PATCH 11/14] shared_library bool or str --- conifer/model.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/conifer/model.py b/conifer/model.py index 3118fd0b..dae2ff9c 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -535,7 +535,7 @@ def make_model(ensembleDict, config=None): backend = get_backend(backend) return backend.make_model(ensembleDict, config) -def load_model(filename, new_config=None, shared_library=None): +def load_model(filename, new_config=None, shared_library=True): ''' Load a Model from JSON file @@ -545,9 +545,14 @@ def load_model(filename, new_config=None, shared_library=None): filename to load from new_config: dictionary (optional) if provided, override the configuration specified in the JSON file - shared_library: string (optional) - path to the shared library (or to the directory where to look for the .so file) to load for the model. - If not provided, the shared library will be looked for in the same directory as the JSON file, using the timestamp of the last metadata entry available + shared_library: string|bool (optional) + If True, the shared library will be looked for in the same directory as the JSON file, using the timestamp of the last metadata entry available + If False, the shared library will not be loaded + If a string, it could be: + - path to the shared library to load for the model + - path to the directory where to look for the .so file, using the timestamp of the last metadata entry available + + No shared library will be loaded if a new configuration is provided ''' with open(filename, 'r') as json_file: js = json.load(json_file) @@ -568,9 +573,11 @@ def load_model(filename, new_config=None, shared_library=None): model = make_model(js, config) model._metadata = metadata + model._metadata - if new_config is None: + if new_config is None and shared_library is not False: shared_library_path=None - if shared_library is None or not shared_library.endswith(".so"): + if shared_library.endswith(".so"): + shared_library_path=shared_library + else: from glob import glob shared_library_dirpath=os.path.abspath(os.path.dirname(filename)) if shared_library is None else shared_library timestamps=[int(md._to_dict()["time"]) for md in model._metadata[-2::-1]] @@ -580,8 +587,6 @@ def load_model(filename, new_config=None, shared_library=None): if f"conifer_bridge_{timestamp}.so" in so_files: shared_library_path=os.path.join(shared_library_dirpath, f'conifer_bridge_{timestamp}.so') break - elif shared_library.endswith(".so"): - shared_library_path=shared_library try: model.load_shared_library(filename, shared_library_path) From c00753db1ba598e120d3cd65478a2ed4e3e7091d Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Fri, 13 Sep 2024 23:22:03 +0200 Subject: [PATCH 12/14] fix: type check + None -> True --- conifer/model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conifer/model.py b/conifer/model.py index dae2ff9c..4b16c0aa 100644 --- a/conifer/model.py +++ b/conifer/model.py @@ -549,7 +549,7 @@ def load_model(filename, new_config=None, shared_library=True): If True, the shared library will be looked for in the same directory as the JSON file, using the timestamp of the last metadata entry available If False, the shared library will not be loaded If a string, it could be: - - path to the shared library to load for the model + - path to the shared library to load - path to the directory where to look for the .so file, using the timestamp of the last metadata entry available No shared library will be loaded if a new configuration is provided @@ -575,11 +575,11 @@ def load_model(filename, new_config=None, shared_library=True): if new_config is None and shared_library is not False: shared_library_path=None - if shared_library.endswith(".so"): + if isinstance(shared_library, str) and shared_library.endswith(".so"): shared_library_path=shared_library else: from glob import glob - shared_library_dirpath=os.path.abspath(os.path.dirname(filename)) if shared_library is None else shared_library + shared_library_dirpath=os.path.abspath(os.path.dirname(filename)) if shared_library is True else os.path.abspath(shared_library) timestamps=[int(md._to_dict()["time"]) for md in model._metadata[-2::-1]] so_files=glob(os.path.join(shared_library_dirpath, 'conifer_bridge_*.so')) so_files=[os.path.basename(so_file) for so_file in so_files] From 0f8a122ef49b76dffc90977ab89c547c796d1000 Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Tue, 11 Feb 2025 20:19:12 +0100 Subject: [PATCH 13/14] added separate tests for the .so autoloading feature --- tests/test_save_load.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/tests/test_save_load.py b/tests/test_save_load.py index e6c1ac49..2d989f8b 100644 --- a/tests/test_save_load.py +++ b/tests/test_save_load.py @@ -2,6 +2,7 @@ import numpy as np import conifer import json +import os ''' Test conifer's model saving and loading functionality by loading some models and checking the predictions @@ -15,10 +16,29 @@ def test_hls_save_load(hls_convert, train_skl): load_model.compile() y_hls_0, y_hls_1 = util.predict_skl(orig_model, X, y, load_model) np.testing.assert_array_equal(y_hls_0, y_hls_1) + +def test_hls_reload_last_shared_library(hls_convert, train_skl): + clf, X, y = train_skl + initial_model = conifer.model.load_model(f'{hls_convert.config.output_dir}/{hls_convert.config.project_name}.json', shared_library = False) + initial_model.config.output_dir += '_loaded' + initial_model.compile() + # Re-load without recompiling to check if the shared library is loaded correctly + reload_model = conifer.model.load_model(f'{hls_convert.config.output_dir}_loaded/{hls_convert.config.project_name}.json', shared_library=True) + y_hls, y_hls_reload = util.predict_skl(initial_model, X, y, reload_model) + np.testing.assert_array_equal(y_hls, y_hls_reload) + assert os.path.abspath(initial_model.bridge.__file__) == os.path.abspath(reload_model.bridge.__file__), "Loaded two different shared libraries" + +def test_hls_reload_manual_shared_library(hls_convert, train_skl): + clf, X, y = train_skl + initial_model = conifer.model.load_model(f'{hls_convert.config.output_dir}/{hls_convert.config.project_name}.json', shared_library = False) + initial_model.config.output_dir += '_loaded' + initial_model.compile() + so_path = os.path.abspath(initial_model.bridge.__file__) # manually get the shared library path # Re-load without recompiling to check if the shared library is loaded correctly - load_model2 = conifer.model.load_model(f'{orig_model.config.output_dir}/{orig_model.config.project_name}.json') - _, y_hls_2 = util.predict_skl(orig_model, X, y, load_model2) - np.testing.assert_array_equal(y_hls_0, y_hls_2) + reload_model = conifer.model.load_model(f'{hls_convert.config.output_dir}_loaded/{hls_convert.config.project_name}.json', shared_library=so_path) # pass the shared library path manually + y_hls, y_hls_reload = util.predict_skl(initial_model, X, y, reload_model) + np.testing.assert_array_equal(y_hls, y_hls_reload) + assert os.path.abspath(initial_model.bridge.__file__) == os.path.abspath(reload_model.bridge.__file__), "Loaded two different shared libraries" def test_hdl_save_load(vhdl_convert, train_skl): orig_model = vhdl_convert From 165fce9565744e5e9151b34343a669cd8b4f98fb Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Mon, 10 Mar 2025 13:39:11 +0100 Subject: [PATCH 14/14] replaced abspath with basename --- tests/test_save_load.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_save_load.py b/tests/test_save_load.py index 2d989f8b..734a9ee5 100644 --- a/tests/test_save_load.py +++ b/tests/test_save_load.py @@ -26,19 +26,19 @@ def test_hls_reload_last_shared_library(hls_convert, train_skl): reload_model = conifer.model.load_model(f'{hls_convert.config.output_dir}_loaded/{hls_convert.config.project_name}.json', shared_library=True) y_hls, y_hls_reload = util.predict_skl(initial_model, X, y, reload_model) np.testing.assert_array_equal(y_hls, y_hls_reload) - assert os.path.abspath(initial_model.bridge.__file__) == os.path.abspath(reload_model.bridge.__file__), "Loaded two different shared libraries" + assert os.path.basename(initial_model.bridge.__file__) == os.path.basename(reload_model.bridge.__file__), "Loaded two different shared libraries" def test_hls_reload_manual_shared_library(hls_convert, train_skl): clf, X, y = train_skl initial_model = conifer.model.load_model(f'{hls_convert.config.output_dir}/{hls_convert.config.project_name}.json', shared_library = False) initial_model.config.output_dir += '_loaded' initial_model.compile() - so_path = os.path.abspath(initial_model.bridge.__file__) # manually get the shared library path + so_path = os.path.basename(initial_model.bridge.__file__) # manually get the shared library path # Re-load without recompiling to check if the shared library is loaded correctly reload_model = conifer.model.load_model(f'{hls_convert.config.output_dir}_loaded/{hls_convert.config.project_name}.json', shared_library=so_path) # pass the shared library path manually y_hls, y_hls_reload = util.predict_skl(initial_model, X, y, reload_model) np.testing.assert_array_equal(y_hls, y_hls_reload) - assert os.path.abspath(initial_model.bridge.__file__) == os.path.abspath(reload_model.bridge.__file__), "Loaded two different shared libraries" + assert os.path.basename(initial_model.bridge.__file__) == os.path.basename(reload_model.bridge.__file__), "Loaded two different shared libraries" def test_hdl_save_load(vhdl_convert, train_skl): orig_model = vhdl_convert