Difference between revisions of "Tensorflow JNI development"
(→Java maven project in Eclipse) |
(→A few words on TF in Maven Central repository) |
||
(29 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | ==About== | + | ==<font color='blue'>About</font>== |
− | |||
− | + | Based on [https://medium.com/@maxime.durand.54/build-tennsorflow-2-0-for-java-on-windows-2ab51b9cac45 Build TensorFlow 2.0 for Java on Windows] article. | |
+ | Also this one - [https://github.com/tensorflow/tensorflow/blob/master/tensorflow/java/README.md tensorflow/java/README.md]. | ||
− | + | These instructions are for '''Linux''' and old '''TensorFlow 1.15.0'''. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | How to: | |
− | * | + | * '''Build TF JNI''' - libtensorflow.jar, libtensorflow_jni.so and pom.xml |
− | * | + | * '''Add TF JAR to local Maven''' which will override the [https://mvnrepository.com/artifact/org.tensorflow/tensorflow Central Maven Repository] |
− | * | + | * '''Modify TF JNI functions''' |
+ | * '''Create Elipse project''' | ||
− | + | There's [https://github.com/bytedeco/javacpp-presets JavaCPP Presets] project. Seems useless. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ==<font color='blue'>Install</font>== | |
− | + | In Kubuntu: | |
− | + | * Get [https://github.com/tensorflow/tensorflow/archive/v1.15.0.tar.gz TensorFlow-1.15.0] | |
− | + | * Install [https://github.com/bazelbuild/bazel/releases/download/0.25.2/bazel_0.25.2-linux-x86_64.deb bazel 0.25.2] | |
− | * '''xml''' and '''jar''' | + | Based on [[Feeding_Tensorflow_from_GPU|Feeding Tensorflow from GPU]]. |
+ | |||
+ | ==<font color='blue'>Build</font>== | ||
+ | <font size=2>cd ~/git/tensorflow-1.15.0 | ||
+ | ./configure # do not forget CUDA | ||
+ | bazel build -c opt //tensorflow/java:tensorflow //tensorflow/java:libtensorflow_jni //tensorflow/java:pom</font> | ||
+ | |||
+ | With TF, bazel tends to rebuild everything from scratch - takes a ton of time. | ||
+ | Is it because it gets restarted after idle timeout or something else? A somewhat solution might be | ||
+ | <font size=2>At launch bazel starts its server which, to prevent it, add to ~/.bazelrc: | ||
+ | startup --max_idle_secs=0</font> | ||
+ | |||
+ | Artifacts of interest are in '''bazel-bin/tensorflow/java/''': | ||
+ | <font size=2>'''libtensorflow_jni.so''' | ||
+ | '''libtensorflow.jar''' | ||
+ | '''pom.xml'''</font> | ||
+ | |||
+ | * '''xml''' and '''jar''' will be taken care of by '''mvn''' command. | ||
* '''so''' will have to be in the library path - set LD_LIBRARY_PATH or PATH or go "java -Djava.library.path" | * '''so''' will have to be in the library path - set LD_LIBRARY_PATH or PATH or go "java -Djava.library.path" | ||
− | ==Modify TF JNI== | + | ==<font color='blue'>Install JAR to local Maven Repository</font>== |
+ | <font size=2>~/GIT/tensorflow-1.15.0$ <b>mvn install:install-file -Dfile=bazel-bin/tensorflow/java/libtensorflow.jar -DpomFile=bazel-bin/tensorflow/java/pom.xml</b></font> | ||
+ | |||
+ | How to uninstall maven local repo - and switch back to official versions from Maven Central - [https://stackoverflow.com/questions/15358851/how-to-remove-jar-file-from-local-maven-repository-which-was-added-with-install this link]. Or remove unneeded stuff from '''~/.m2/repository/org/tensorflow''' | ||
+ | |||
+ | ==<font color='blue'>Modify TF JNI functions</font>== | ||
For example, one wants to create a new function in org.tensorflow.TensorFlow package. | For example, one wants to create a new function in org.tensorflow.TensorFlow package. | ||
− | Then | + | Then see inside: |
− | '''tensorflow/java/src/main/java/org/tensorflow/''' | + | <font size=2>'''tensorflow/java/src/main/java/org/tensorflow/''' |
− | '''tensorflow/java/src/main/native/''' | + | '''tensorflow/java/src/main/native/'''</font> |
− | + | Three places: | |
* add native method to tensorflow/java/src/main/java/org/tensorflow/TensorFlow.java | * add native method to tensorflow/java/src/main/java/org/tensorflow/TensorFlow.java | ||
* add to header file tensorflow/java/src/main/native/tensorflow_jni.h | * add to header file tensorflow/java/src/main/native/tensorflow_jni.h | ||
* add to c file tensorflow/java/src/main/native/tensorflow_jni.cc | * add to c file tensorflow/java/src/main/native/tensorflow_jni.cc | ||
− | + | Rebuild and Reinstall. | |
+ | |||
+ | The native header files seem to be regenerated but I haven't tested if they are actually used (need to test). | ||
+ | In function naming - avoid underscores, e.g.: | ||
+ | <font size=2>Java_org_tensorflow_TensorFlow_<Name></font> | ||
− | ==Java | + | ==<font color='blue'>Java Maven project in Eclipse</font>== |
+ | Nothing special. | ||
* Create a new maven project | * Create a new maven project | ||
* Edit pom.xml: | * Edit pom.xml: | ||
− | <project> | + | <font size=2><project> |
... | ... | ||
<dependencies> | <dependencies> | ||
... | ... | ||
− | <dependency> | + | <b><dependency> |
− | <groupId> | + | <groupId>org.tensorflow</groupId> |
− | <artifactId> | + | <artifactId>libtensorflow</artifactId> |
− | <version> | + | <version>1.15.0</version> |
− | </dependency> | + | </dependency></b> |
... | ... | ||
</dependencies> | </dependencies> | ||
... | ... | ||
− | </project> | + | </project></font> |
+ | |||
+ | ===Basic example code=== | ||
+ | tfhello.java: | ||
+ | <font size=2>import org.tensorflow.TensorFlow; | ||
+ | |||
+ | public class tfhello{ | ||
+ | public static void main(String[] args){ | ||
+ | System.out.println(TensorFlow.version()); | ||
+ | } | ||
+ | }</font> | ||
+ | |||
+ | ==<font color='blue'>A few words on TF in Maven Central repository</font>== | ||
+ | |||
+ | ===libtensorflow=== | ||
+ | Record in pom.xml: | ||
+ | <dependency> | ||
+ | <groupId>org.tensorflow</groupId> | ||
+ | <artifactId>libtensorflow</artifactId> | ||
+ | <version>1.15.0</version> | ||
+ | </dependency> | ||
+ | |||
+ | Archive contains Java classes. | ||
+ | |||
+ | ===libtensorflow_jni_gpu=== | ||
+ | Record in pom.xml: | ||
+ | <dependency> | ||
+ | <groupId>org.tensorflow</groupId> | ||
+ | <artifactId>libtensorflow_jni_gpu</artifactId> | ||
+ | <version>1.14.0</version> | ||
+ | </dependency> | ||
+ | |||
+ | Archive contains native library: | ||
+ | <font size=2>├── META-INF | ||
+ | │ ├── MANIFEST.MF | ||
+ | │ └── maven | ||
+ | │ └── org.tensorflow | ||
+ | │ └── libtensorflow_jni_gpu | ||
+ | │ ├── pom.properties | ||
+ | │ └── pom.xml | ||
+ | └── org | ||
+ | └── tensorflow | ||
+ | └── native | ||
+ | ├── linux-x86_64 | ||
+ | │ ├── '''libtensorflow_framework.so.1''' | ||
+ | │ ├── '''libtensorflow_jni.so''' | ||
+ | │ ├── LICENSE | ||
+ | │ └── THIRD_PARTY_TF_JNI_LICENSES | ||
+ | └── windows-x86_64 | ||
+ | ├── LICENSE | ||
+ | └── tensorflow_jni.dll</font> |
Revision as of 09:02, 5 March 2020
Contents
About
Based on Build TensorFlow 2.0 for Java on Windows article. Also this one - tensorflow/java/README.md.
These instructions are for Linux and old TensorFlow 1.15.0.
How to:
- Build TF JNI - libtensorflow.jar, libtensorflow_jni.so and pom.xml
- Add TF JAR to local Maven which will override the Central Maven Repository
- Modify TF JNI functions
- Create Elipse project
There's JavaCPP Presets project. Seems useless.
Install
In Kubuntu:
- Get TensorFlow-1.15.0
- Install bazel 0.25.2
Based on Feeding Tensorflow from GPU.
Build
cd ~/git/tensorflow-1.15.0 ./configure # do not forget CUDA bazel build -c opt //tensorflow/java:tensorflow //tensorflow/java:libtensorflow_jni //tensorflow/java:pom
With TF, bazel tends to rebuild everything from scratch - takes a ton of time. Is it because it gets restarted after idle timeout or something else? A somewhat solution might be
At launch bazel starts its server which, to prevent it, add to ~/.bazelrc: startup --max_idle_secs=0
Artifacts of interest are in bazel-bin/tensorflow/java/:
libtensorflow_jni.so libtensorflow.jar pom.xml
- xml and jar will be taken care of by mvn command.
- so will have to be in the library path - set LD_LIBRARY_PATH or PATH or go "java -Djava.library.path"
Install JAR to local Maven Repository
~/GIT/tensorflow-1.15.0$ mvn install:install-file -Dfile=bazel-bin/tensorflow/java/libtensorflow.jar -DpomFile=bazel-bin/tensorflow/java/pom.xml
How to uninstall maven local repo - and switch back to official versions from Maven Central - this link. Or remove unneeded stuff from ~/.m2/repository/org/tensorflow
Modify TF JNI functions
For example, one wants to create a new function in org.tensorflow.TensorFlow package. Then see inside:
tensorflow/java/src/main/java/org/tensorflow/ tensorflow/java/src/main/native/
Three places:
- add native method to tensorflow/java/src/main/java/org/tensorflow/TensorFlow.java
- add to header file tensorflow/java/src/main/native/tensorflow_jni.h
- add to c file tensorflow/java/src/main/native/tensorflow_jni.cc
Rebuild and Reinstall.
The native header files seem to be regenerated but I haven't tested if they are actually used (need to test). In function naming - avoid underscores, e.g.:
Java_org_tensorflow_TensorFlow_<Name>
Java Maven project in Eclipse
Nothing special.
- Create a new maven project
- Edit pom.xml:
<project> ... <dependencies> ... <dependency> <groupId>org.tensorflow</groupId> <artifactId>libtensorflow</artifactId> <version>1.15.0</version> </dependency> ... </dependencies> ... </project>
Basic example code
tfhello.java:
import org.tensorflow.TensorFlow; public class tfhello{ public static void main(String[] args){ System.out.println(TensorFlow.version()); } }
A few words on TF in Maven Central repository
libtensorflow
Record in pom.xml:
<dependency> <groupId>org.tensorflow</groupId> <artifactId>libtensorflow</artifactId> <version>1.15.0</version> </dependency>
Archive contains Java classes.
libtensorflow_jni_gpu
Record in pom.xml:
<dependency> <groupId>org.tensorflow</groupId> <artifactId>libtensorflow_jni_gpu</artifactId> <version>1.14.0</version> </dependency>
Archive contains native library:
├── META-INF │ ├── MANIFEST.MF │ └── maven │ └── org.tensorflow │ └── libtensorflow_jni_gpu │ ├── pom.properties │ └── pom.xml └── org └── tensorflow └── native ├── linux-x86_64 │ ├── libtensorflow_framework.so.1 │ ├── libtensorflow_jni.so │ ├── LICENSE │ └── THIRD_PARTY_TF_JNI_LICENSES └── windows-x86_64 ├── LICENSE └── tensorflow_jni.dll