Javacpp-presets: [MKL-DNN] How to tell javacpp to compile and use mkl-dnn with system-provided MKL?

Created on 20 Oct 2018  路  15Comments  路  Source: bytedeco/javacpp-presets

Hi,

Javacpp's mkl-dnn works well for me, but I have the following problem:

In my project, I have a code that loads and calls system-wide MKL (via mkl_rt), which in turn loads libiomp.so. Javacpp's mkl-dnn builds mkldnn to use a custom mklml build that it packs itself. That's all right. However, the problem arises when both MKL distributions try to load libiomp.so - MKL itself check whether that happens and kills the process with the message that it doesn't allow two instances of libiomp to be loaded at the same time (there is a workaround to tell it to ignore this, but it is out of the question because it slows MKL many times).

I'm trying to build a custom build of javacpp/mkldnn that will configure mkldnn to use MKL provided by the system. I've successfully built mkldnn to do that, but the thinkering that I've tried in javacpp lead me to no success - later I figured out that I can't even build javacpp/mkldnn without changes (#628).

Anyway, how should I approach this?

enhancement question

All 15 comments

That's an issue with MKL-DNN, it wants to use it's own version of MKL. If you've got everything installed on your system like you need it though, do like it's being done for MKL due to its licensing, that is,

  1. Provide a dummy cppbuild.sh:
    https://github.com/bytedeco/javacpp-presets/blob/master/mkl/cppbuild.sh
  2. Give the includepath and linkpath in presets/mklml.java:
    https://github.com/bytedeco/javacpp-presets/blob/master/mkl/src/main/java/org/bytedeco/javacpp/presets/mkl_rt.java#L42
  3. Set copyLibs to false in the pom.xml file:
    https://github.com/bytedeco/javacpp-presets/blob/master/mkl/pom.xml#L59

Then it's going to load MKL-DNN and MKL from your system files like any other native application!

Supercool! I'll try that as soon as #628 is resolved.

Though, since it looks like you'll need to remove presets/mklml.java, add the includepath and linkpath values to presets/mkldnn.java instead in that case.

@saudet Thanks! After a lot of thinkering, I made it work as I expected. I'm fine with maintaining my own fork, but it would be, of course, better if we can make somehing like this available in javacpp-presets.
Are you interested in that, and what would be the best approach? I suppose it would have to be its own subproject, something like mkl-dnn-system or you have a better idea?

For reference, here's what I did:

  1. Added a property to pom.xml to shut down cppbuild.sh (<javacpp.cppbuild.skip>true</javacpp.cppbuild.skip>) I guess providing a dummy cppbuild.sh is another, better, option, since it checks whether the global installation exists.
  2. As you suggested, completely deleted presets/mklml.java and all references to it.
  3. manually created ./cppbuild/lib and ./cppbuild/include and copied appropriate headers and binary from my custom mkl-dnn build folder. (no need to copy mkl headers)
  4. Run mvn install --projects .,mkl-dnn

It should be possible to modify everything so that we can have it build
using files from the system using an option. The mklml presets can also be
redirected to the files of the full MKL installation for simplicity.

I think the way to go about this would be with an extension, like we have -gpu extensions for OpenCV, Caffe, MXNet, and TensorFlow. In this case, it would be a -system extension that we could build with, for example, mvn -Djavacpp.platform=linux-x86_64 -Djavacpp.platform.extension=-system ..., which would end up in an artifact with a linux-x86_64-system classifier.

Actually, this is more about MKL on the system than about MKL-DNN, so I think it would make more sense to have an -mkl extension that still builds MKL-DNN and everything like it's doing right now, but that requires MKL to be installed on the system, just like the presets for MKL.

That describes my use case exactly!

Actually, we can do even better, we can link with MKL at runtime, just like the wrappers for OpenBLAS are already doing. I've implemented this in the last commit, so try to run your application after setting the system properties as per the added documentation here: https://github.com/bytedeco/javacpp-presets/tree/master/mkl-dnn#documentation

Thank you so much! Can I expect this to show in the SNAPSHOT build soon, or I'll have to build from source if I wanted to test this in the next few days?

Yes, it will be in the snapshots sometime tomorrow.

Another clarification: since the problem was not mklml itself, but it trying to load the second instance of iomp5, with this setup, that should or should not be an issue? If mkl_rt and iomp5 have already been loaded by another java code external to javacpp, javacpp will recognize that they are present and not try to load them redundantly?

As long as they are loading the same files from the system, there shouldn't be any problems, yes.

Fantastic! Thank you.

BTW, the new license actually permits redistributing the full version of MKL itself, see commit https://github.com/bytedeco/javacpp-presets/commit/03c5fdffc018cfac1f0a1ae6a8fbf6fa008ea514, so it is now being bundled! Enjoy

Was this page helpful?
0 / 5 - 0 ratings