dmlc / tl2cgen

TL2cgen (TreeLite 2 C GENerator) is a model compiler for decision tree models
https://tl2cgen.readthedocs.io/en/latest/
Apache License 2.0
17 stars 6 forks source link

treelite4j: Predictor constructor using`dlopen` not working as expected when model library path does not include a `/` #3

Open thvasilo opened 1 year ago

thvasilo commented 1 year ago

I'm trying to run a basic example with treelite4j, and I couldn't get the model to load as expected. I was trying to use:

Predictor treelitePredictor = new Predictor("myModel.so", treeliteThreads, true);

but was getting the error:

Exception in thread "main" ml.dmlc.treelite4j.java.TreeliteError: [00:08:33] /local/home/thvasilo/repos/treelite/src/predictor/predictor.cc:175: Check failed: handle: Failed to load dynamic shared library `test00.so'
        at ml.dmlc.treelite4j.java.TreeliteJNI.checkCall(TreeliteJNI.java:28)
        at ml.dmlc.treelite4j.java.Predictor.initNativeLibrary(Predictor.java:94)
        at ml.dmlc.treelite4j.java.Predictor.<init>(Predictor.java:57)
        at com.amazon.treelitetest.SimpleTreelitePrediction.main(SimpleTreelitePrediction.java:22)

Turns out that dlopen does not consider the input argument const char* file a path unless it contains a /, or not exactly at least: From https://pubs.opengroup.org/onlinepubs/7908799/xsh/dlopen.html

void dlopen(const char file, int mode); file is used to construct a pathname to the object file. If file contains a slash character, the file argument is used as the pathname for the file. Otherwise, file is used in an implementation-dependent manner to yield a pathname.

After I changed the call to:

Predictor treelitePredictor = new Predictor("/path/to/myModel.so", treeliteThreads, true); the model loaded fine.

So this is a bit of a sneaky bug that's possibly implementation/platform dependent. My env was Amazon Linux 2 on JDK 1.8.

hcho3 commented 1 year ago

Indeed, this is why the Python package uses the absolute path for the lib: https://github.com/dmlc/treelite/blob/99e7f7389e1385ae6d8ab76466e63eb57aa7f12c/runtime/python/treelite_runtime/predictor.py#L106