Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 83 additions & 52 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ on:
- r[0-9]+.*
types: [opened, reopened, synchronize, labeled, unlabeled]
env:
STAGING_PROFILE_ID: 46f80d0729c92d
DEPLOY_SNAPSHOT: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/staging') }}
DEPLOY_RELEASE: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/heads/r') }}
DEPLOY: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/r')) }}
jobs:
check-format:
if: github.event_name == 'pull_request'
Expand All @@ -36,37 +34,8 @@ jobs:
- name: Run format checks
run: |
mvn spotless:check -Pjdk17 -B -U -e
prepare:
runs-on: ubuntu-22.04
outputs:
repositoryUrl: ${{ steps.repository.outputs.repositoryUrl }}
steps:
- name: Create staging repository
if: env.DEPLOY_RELEASE == 'true'
id: staging
run: |
echo "Creating staging repository with profile $STAGING_PROFILE_ID"
echo "<promoteRequest><data><description>Releasing TF Java - created by CI build</description></data></promoteRequest>" > request.xml
curl -X POST -d @request.xml -s -o response.xml -u ${{ secrets.CI_DEPLOY_USERNAME }}:${{ secrets.CI_DEPLOY_PASSWORD }} -H "Content-Type:application/xml" \
https://ossrh-staging-api.central.sonatype.com/service/local/staging/profiles/$STAGING_PROFILE_ID/start
export STAGING_REPOSITORY_ID=`awk -F'[<>]' '/stagedRepositoryId/{print $3}' response.xml`
echo "Staging repository created: $STAGING_REPOSITORY_ID"
echo "::set-output name=stagingRepositoryId::$STAGING_REPOSITORY_ID"
- name: Checkout repository
uses: actions/checkout@v6
- name: Extract distribution repository URL
id: repository
run: |
if [[ "${{ env.DEPLOY_RELEASE }}" = "true" ]]; then
export REPOSITORY_URL=`mvn exec:exec -q -N -Dexec.executable='echo' -Dexec.args="\\${project.distributionManagement.repository.url}" -DstagingRepositoryId=${{ steps.staging.outputs.stagingRepositoryId }}`
else
export REPOSITORY_URL=`mvn exec:exec -q -N -Dexec.executable='echo' -Dexec.args="\\${project.distributionManagement.snapshotRepository.url}"`
fi
echo "Repository URL: $REPOSITORY_URL"
echo "::set-output name=repositoryUrl::$REPOSITORY_URL"
linux-arm64:
runs-on: ubuntu-2204-arm64-2c
needs: prepare
strategy:
matrix:
ext: [""]
Expand All @@ -87,14 +56,19 @@ jobs:
run: |
gcc --version
mvn -version
echo "<settings><servers><server><id>central</id><username>${{ secrets.CI_DEPLOY_USERNAME }}</username><password>${{ secrets.CI_DEPLOY_PASSWORD }}</password></server></servers></settings>" > $HOME/.m2/settings.xml
mvn clean install -pl '!tensorflow-framework' -B -U -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }}
- name: Deploy native artifact
if: env.DEPLOY_RELEASE == 'true' || env.DEPLOY_SNAPSHOT == 'true'
run: mvn -f tensorflow-core/tensorflow-core-native/pom.xml deploy:deploy-file@native-only -B -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }} -Durl=${{ needs.prepare.outputs.repositoryUrl }}
- name: Build native artifact
run: mvn -f tensorflow-core/tensorflow-core-native/pom.xml package -B -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }}
- name: Upload native artifact
if: env.DEPLOY == 'true'
uses: actions/upload-artifact@v7
with:
name: native-artifact-${{ github.job }}${{ matrix.ext }}
path: tensorflow-core/tensorflow-core-native/target/tensorflow-core-native-*-${{ github.job }}*.jar
if-no-files-found: error
retention-days: 1
linux-x86_64:
runs-on: ubuntu-22.04
needs: prepare
strategy:
matrix:
ext: ["", -gpu]
Expand All @@ -110,14 +84,19 @@ jobs:
run: |
gcc --version
mvn -version
echo "<settings><servers><server><id>central</id><username>${{ secrets.CI_DEPLOY_USERNAME }}</username><password>${{ secrets.CI_DEPLOY_PASSWORD }}</password></server></servers></settings>" > $HOME/.m2/settings.xml
mvn clean install -pl '!tensorflow-framework' -B -U -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }}
- name: Deploy native artifact
if: env.DEPLOY_RELEASE == 'true' || env.DEPLOY_SNAPSHOT == 'true'
run: mvn -f tensorflow-core/tensorflow-core-native/pom.xml deploy:deploy-file@native-only -B -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }} -Durl=${{ needs.prepare.outputs.repositoryUrl }}
- name: Build native artifact
run: mvn -f tensorflow-core/tensorflow-core-native/pom.xml package -B -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }}
- name: Upload native artifact
if: env.DEPLOY == 'true'
uses: actions/upload-artifact@v7
with:
name: native-artifact-${{ github.job }}${{ matrix.ext }}
path: tensorflow-core/tensorflow-core-native/target/tensorflow-core-native-*-${{ github.job }}*.jar
if-no-files-found: error
retention-days: 1
macosx-arm64:
runs-on: macos-14
needs: prepare
strategy:
matrix:
ext: [""]
Expand All @@ -134,13 +113,19 @@ jobs:
run: |
clang --version
mvn -version
echo "<settings><servers><server><id>central</id><username>${{ secrets.CI_DEPLOY_USERNAME }}</username><password>${{ secrets.CI_DEPLOY_PASSWORD }}</password></server></servers></settings>" > $HOME/.m2/settings.xml
mvn clean install -pl '!tensorflow-framework' -B -U -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }}
- name: Deploy native artifact
if: env.DEPLOY_RELEASE == 'true' || env.DEPLOY_SNAPSHOT == 'true'
run: mvn -f tensorflow-core/tensorflow-core-native/pom.xml deploy:deploy-file@native-only -B -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }} -Durl=${{ needs.prepare.outputs.repositoryUrl }}
- name: Build native artifact
run: mvn -f tensorflow-core/tensorflow-core-native/pom.xml package -B -e -Djavacpp.platform=${{ github.job }} -Djavacpp.platform.extension=${{ matrix.ext }}
- name: Upload native artifact
if: env.DEPLOY == 'true'
uses: actions/upload-artifact@v7
with:
name: native-artifact-${{ github.job }}${{ matrix.ext }}
path: tensorflow-core/tensorflow-core-native/target/tensorflow-core-native-*-${{ github.job }}*.jar
if-no-files-found: error
retention-days: 1
deploy:
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/staging') }} # DEPLOY_SNAPSHOT (releases should be signed and deployed manually from local machine)
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
needs: [linux-x86_64, macosx-arm64, linux-arm64]
runs-on: ubuntu-22.04
steps:
Expand All @@ -149,14 +134,60 @@ jobs:
with:
distribution: 'adopt'
java-version: '11'
server-id: central
server-username: MAVEN_USERNAME # env variable for username in deploy
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE # Handled as an env variable name reference
- name: Checkout repository
uses: actions/checkout@v6
- name: Build project
- name: Download native artifacts
uses: actions/download-artifact@v8
with:
pattern: native-artifact-*
path: tensorflow-core/tensorflow-core-native/target
merge-multiple: true
- name: Build and Deploy snapshot artifacts
env:
MAVEN_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
MAVEN_CENTRAL_TOKEN: ${{ secrets.CI_DEPLOY_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
MAVEN_GPG_KEY: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
run: |
java -version
mvn -version
mvn clean install -B -U -e -Pdeploying
- name: Deploy snapshot artifacts
mvn deploy -Pdeploying -B -e
release:
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/heads/r') }}
needs: [linux-x86_64, macosx-arm64, linux-arm64]
runs-on: ubuntu-22.04
steps:
- name: Configure Java
uses: actions/setup-java@v5
with:
distribution: 'adopt'
java-version: '11'
server-id: central
server-username: MAVEN_USERNAME # env variable for username in deploy
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE # Handled as an env variable name reference
- name: Checkout repository
uses: actions/checkout@v6
- name: Download native artifacts
uses: actions/download-artifact@v8
with:
pattern: native-artifact-*
path: tensorflow-core/tensorflow-core-native/target
merge-multiple: true
- name: Build and Deploy release artifacts
env:
MAVEN_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
MAVEN_CENTRAL_TOKEN: ${{ secrets.CI_DEPLOY_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
MAVEN_GPG_KEY: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
run: |
echo "<settings><servers><server><id>central</id><username>${{ secrets.CI_DEPLOY_USERNAME }}</username><password>${{ secrets.CI_DEPLOY_PASSWORD }}</password></server></servers></settings>" > $HOME/.m2/settings.xml
mvn deploy -Pdeploying -B -e -Dmaven.test.skip=true
java -version
mvn -version
mvn deploy -Pdeploying -Preleasing -B -e

7 changes: 4 additions & 3 deletions MIGRATING.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Migrating Between TensorFlow Java Releases

TensorFlow Java is still in an alpha stage, therefore is subject to contain breaking changes between the different releases. This guide explain in detail
how to migrate your code from a previous version to a new one that includes some changes that are not backward compatible.
This guide explains in detail how to migrate your code from a pre-1.0 release to a 1.0 or newer release. Post 1.0
releases have API stability as much as possible, though upstream TensorFlow does remove ops from time to time and
consequently those ops will be removed from TensorFlow-Java

## Migrating to 1.0.0
## Migrating to 1.0.0 or newer

TensorFlow-Java 1.0.0 requires Java 11 or later.

Expand Down
58 changes: 37 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ The following describes the layout of the repository and its different artifacts
* Intended audience: neural network developers
* For more information: [tensorflow-framework/README.md](tensorflow-framework/README.md)

*Note: The NdArray Library module has now its own [repository](https://github.com/tensorflow/java-ndarray) and has been moved out of TensorFlow Java.*
* `tensorflow-ndarray`
* API for creating and manipulating n-dimensional arrays, can be used independently from TensorFlow.

## Communication

Expand Down Expand Up @@ -60,29 +61,30 @@ only binaries for the following are being **supported and distributed** by this
- `linux-x86_64-gpu`: Linux platforms on Intel/AMD chips with Cuda GPU support
- `linux-arm64`: Linux platforms on Arm chips
- `macosx-arm64`: MacOS X platforms on Apple Silicon chips
- `windows-x86_64`: Windows platforms on Intel/AMD chips (v1.1.0 and earlier)

Binaries for `macosx-x86_64` are available for TF-Java 1.0 series releases and earlier, they were dropped from
TF-Java 1.1 and newer as they are no longer supported or released by Google.
TF-Java 1.1 and newer as they are no longer supported or released by Google. Binaries for `windows-x86_64` are available
for TF-Java 1.1 and earlier, they were dropped for the 1.2 release and newer as the native binaries are no longer supported or
released by Google.

For example, for building a JAR that uses TensorFlow and is targeted to be deployed only on Linux
systems with no GPU support, you should add the following dependencies:
```xml
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-api</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-native</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
<classifier>linux-x86_64</classifier>
</dependency>
```
Or Gradle:
```groovy
def tfVersion = '1.1.0'
def tfVersion = '1.2.0'
implementation "org.tensorflow:tensorflow-core-api:$tfVersion"
implementation "org.tensorflow:tensorflow-core-native:$tfVersion:linux-x86_64"
```
Expand All @@ -93,34 +95,33 @@ native dependencies as follows:
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-api</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-native</artifactId>
<version>1.1.0</version>
<classifier>linux-x86_64-gpu</classifier>
<version>1.2.0</version>
<classifier>linux-arm64</classifier>
</dependency>
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-native</artifactId>
<version>1.1.0</version>
<classifier>macosx-arm64</classifier>
<version>1.2.0</version>
<classifier>linux-x86_64-gpu</classifier>
</dependency>
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-native</artifactId>
<version>1.1.0</version>
<classifier>windows-x86_64</classifier>
<version>1.2.0</version>
<classifier>macosx-arm64</classifier>
</dependency>
```
Or Gradle:
```groovy
def tfVersion = '1.1.0'
def tfVersion = '1.2.0'
implementation "org.tensorflow:tensorflow-core-api:$tfVersion"
implementation "org.tensorflow:tensorflow-core-native:$tfVersion:linux-x86_64-gpu"
implementation "org.tensorflow:tensorflow-core-native:$tfVersion:macosx-arm64"
implementation "org.tensorflow:tensorflow-core-native:$tfVersion:windows-x86_64"
```

Only one dependency can be added per platform, meaning that you cannot add native dependencies to both `linux-x86_64` and
Expand All @@ -135,20 +136,20 @@ For Ubuntu 24.04, you can install them with the following command:
In some cases, it might be preferable to add a single dependency that includes transitively all the artifacts
required to run TensorFlow Java on any [supported platforms](README.md#individual-dependencies)

- `tensorflow-core-platform`: Includes `tensorflow-core-api`, plus native artifacts for `linux-x86_64`, `linux-x86_64-arm64`, `macosx-arm64` and `windows-x86_64`
- `tensorflow-core-platform`: Includes `tensorflow-core-api`, plus native artifacts for `linux-x86_64`, `linux-arm64`, and `macosx-arm64`

For example, to run TensorFlow Java on any CPU platform for which a binary is being distributed by this project, you can
simply add this dependency to your application:
```xml
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-platform</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>
```
Or Gradle:
```groovy
implementation "org.tensorflow:tensorflow-core-platform:1.1.0"
implementation "org.tensorflow:tensorflow-core-platform:1.2.0"
```

Be aware though that the builds of TensorFlow are quite voluminous and including too many native dependencies may
Expand Down Expand Up @@ -177,7 +178,7 @@ to add Sonatype OSS repository in your `pom.xml`, like the following
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-platform</artifactId>
<version>1.2.0-SNAPSHOT</version>
<version>1.3.0-SNAPSHOT</version>
</dependency>
</dependencies>
```
Expand All @@ -192,10 +193,24 @@ repositories {

dependencies {
// Example of dependency, see section above for more options
implementation "org.tensorflow:tensorflow-core-platform:1.2.0-SNAPSHOT"
implementation "org.tensorflow:tensorflow-core-platform:1.3.0-SNAPSHOT"
}
```

## TensorFlow native libraries

TensorFlow-Java is built on top of the native TensorFlow library, and uses [JavaCPP](https://github.com/bytedeco/javacpp)
to call that library which in turn uses the Java Native Interface (JNI). In [Java 24 and newer](https://openjdk.org/jeps/472)
uses of JNI trigger a warning of the form:
```
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::loadLibrary has been called by org.bytedeco.javacpp.Loader in an unnamed module (file:/.../.m2/repository/org/bytedeco/javacpp/1.5.12/javacpp-1.5.12.jar)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
```
This is expected, and adding the `--enable-native-access=ALL-UNNAMED` flag to enable JNI will suppress it. In a future
Java version this warning may be turned into an error and the flag will be required to use TensorFlow-Java.

## TensorFlow/Java Version Support

This table shows the mapping between TensorFlow, TensorFlow Java and minimum supported Java versions.
Expand All @@ -215,7 +230,8 @@ This table shows the mapping between TensorFlow, TensorFlow Java and minimum sup
| 1.0.0-rc.2 | 2.16.2 | 11 |
| 1.0.0 | 2.16.2 | 11 |
| 1.1.0 | 2.18.0 | 11 |
| 1.2.0-SNAPSHOT | 2.21.0 | 11 |
| 1.2.0 | 2.21.0 | 11 |
| 1.3.0-SNAPSHOT | 2.21.0 | 11 |

## How to Contribute?

Expand Down
2 changes: 1 addition & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Some things of note:
```
2. In your local copy, checkout the master branch and increase the next snapshot version.
```
mvn versions:set -DnewVersion=1.1.0-SNAPSHOT
mvn versions:set -DnewVersion=1.3.0-SNAPSHOT
```
3. Update the TensorFlow Java version to reflect the new snapshot at the following locations:
- https://github.com/tensorflow/java/blob/master/docs/install.md?plain=1#L104
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The following describes the layout of the repository and its different artifacts
* **Intended audience**: neural network developers.
* Primary API for building and training neural networks with TensorFlow.

### [ndarray](https://github.com/tensorflow/java-ndarray)
### [tensorflow-ndarray](https://github.com/tensorflow/java/tree/master/tensorflow-ndarray)
* **Intended audience**: any developer who needs a Java n-dimensional array implementation, whether or not they use it with TensorFlow.
* Generic utility library for n-dimensional data I/O operations.
* Used by TensorFlow but does not depend on TensorFlow.
Expand Down
Loading
Loading