onnxruntime/java/build.gradle
Adam Pocock 262b6bd3b7
[java][DML EP] Modifying dml_provider_factory.h so it can compile as a C header file (#20157)
### Description
The dml_provider_factory header file can't be used in C programs as it
defines C++ inline operators. This PR rearranges that header file so
that it looks like valid C when used from C, and also makes a couple of
small modifications to the Java code so it correctly binds to the DML EP
at build time.

I'm having some difficulty testing it as I think it's pulling in the old
version of DirectML on my computer and I can't figure out what the
library loading path is in Java to make it look at the recent version I
downloaded. So the test I added fails with:

```
InferenceTest > testDirectML() FAILED
    ai.onnxruntime.OrtException: Error code - ORT_RUNTIME_EXCEPTION - message: Exception during initialization: <path-to-ort>\onnxruntime\core\providers\dml\DmlExecutionProvider\src\AbiCustomRegistry.cpp(518)\onnxruntime.dll!00007FFF74819333: (caller: 00007FFF74793509) Exception(3) tid(4f58) 80070057 The parameter is incorrect.
        at app//ai.onnxruntime.OrtSession.createSession(Native Method)
        at app//ai.onnxruntime.OrtSession.<init>(OrtSession.java:74)
        at app//ai.onnxruntime.OrtEnvironment.createSession(OrtEnvironment.java:236)
        at app//ai.onnxruntime.OrtEnvironment.createSession(OrtEnvironment.java:221)
        at app//ai.onnxruntime.InferenceTest.openSessionSqueezeNet(InferenceTest.java:1961)
        at app//ai.onnxruntime.InferenceTest.runProvider(InferenceTest.java:665)
        at app//ai.onnxruntime.InferenceTest.testDirectML(InferenceTest.java:657)
```

But it does correctly compile, and this error seems very similar to
other issues with the DML provider when it doesn't like a model due to
the loaded library being old. The test is using the squeezenet file
that's been in the repo since 2019. If someone can help me figure out
how to get the right version of DML in the library path I can test it
more on my end. I tried adding the folder with the new version into the
system path, but I'm not very familiar with Windows' library loading
behaviour.

### Motivation and Context
Fixes #19656 to allow use of the DirectML EP from ORT Java.

cc @martinb35
2024-04-01 21:58:50 -07:00

262 lines
7.2 KiB
Groovy

plugins {
id 'java-library'
id 'maven-publish'
id 'signing'
id 'jacoco'
id "com.diffplug.spotless" version "6.25.0"
}
allprojects {
repositories {
mavenCentral()
}
}
project.group = "com.microsoft.onnxruntime"
version = rootProject.file('../VERSION_NUMBER').text.trim()
// cmake runs will inform us of the build directory of the current run
def cmakeBuildDir = System.properties['cmakeBuildDir']
def useCUDA = System.properties['USE_CUDA']
def useROCM = System.properties['USE_ROCM']
boolean enableTrainingApis = (System.properties['ENABLE_TRAINING_APIS'] ?: "0") == "1"
def cmakeJavaDir = "${cmakeBuildDir}/java"
def cmakeNativeLibDir = "${cmakeJavaDir}/native-lib"
def cmakeNativeJniDir = "${cmakeJavaDir}/native-jni"
def cmakeNativeTestDir = "${cmakeJavaDir}/native-test"
def cmakeBuildOutputDir = "${cmakeJavaDir}/build"
def mavenUser = System.properties['mavenUser']
def mavenPwd = System.properties['mavenPwd']
def tmpArtifactId = enableTrainingApis ? project.name + "-training" : project.name
def mavenArtifactId = (useCUDA == null && useROCM == null) ? tmpArtifactId : tmpArtifactId + "_gpu"
def defaultDescription = 'ONNX Runtime is a performance-focused inference engine for ONNX (Open Neural Network Exchange) models.'
def trainingDescription = 'ONNX Runtime Training is a training and inference package for ONNX ' +
'(Open Neural Network Exchange) models. This package is targeted for Learning on The Edge aka On-Device Training ' +
'See https://github.com/microsoft/onnxruntime-training-examples/tree/master/on_device_training for more details.'
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
// This jar tasks serves as a CMAKE signalling
// mechanism. The jar will be overwritten by allJar task
jar {
}
// Add explicit sources jar with pom file.
task sourcesJar(type: Jar, dependsOn: classes) {
archiveClassifier = "sources"
from sourceSets.main.allSource
into("META-INF/maven/$project.group/$mavenArtifactId") {
from { generatePomFileForMavenPublication }
rename ".*", "pom.xml"
}
}
// Add explicit javadoc jar with pom file
task javadocJar(type: Jar, dependsOn: javadoc) {
archiveClassifier = "javadoc"
from javadoc.destinationDir
into("META-INF/maven/$project.group/$mavenArtifactId") {
from { generatePomFileForMavenPublication }
rename ".*", "pom.xml"
}
}
spotless {
java {
removeUnusedImports()
googleJavaFormat()
targetExclude "src/test/java/ai/onnxruntime/OnnxMl.java"
}
format 'gradle', {
target '**/*.gradle'
trimTrailingWhitespace()
indentWithTabs()
}
}
compileJava {
dependsOn spotlessJava
options.compilerArgs += ["-h", "${project.buildDir}/headers/"]
if (!JavaVersion.current().isJava8()) {
// Ensures only methods present in Java 8 are used
options.compilerArgs.addAll(['--release', '8'])
// Gradle versions before 6.6 require that these flags are unset when using "-release"
java.sourceCompatibility = null
java.targetCompatibility = null
}
}
compileTestJava {
if (!JavaVersion.current().isJava8()) {
// Ensures only methods present in Java 8 are used
options.compilerArgs.addAll(['--release', '8'])
// Gradle versions before 6.6 require that these flags are unset when using "-release"
java.sourceCompatibility = null
java.targetCompatibility = null
}
}
sourceSets.main.java {
srcDirs = ['src/main/java', 'src/main/jvm']
}
sourceSets.test {
// add test resource files
resources.srcDirs += [
"${rootProject.projectDir}/../csharp/testdata",
"${rootProject.projectDir}/../onnxruntime/test/testdata",
"${rootProject.projectDir}/../onnxruntime/test/testdata/training_api",
"${rootProject.projectDir}/../java/testdata"
]
if (cmakeBuildDir != null) {
// add compiled native libs
resources.srcDirs += [
cmakeNativeLibDir,
cmakeNativeJniDir,
cmakeNativeTestDir
]
}
}
if (cmakeBuildDir != null) {
// generate tasks to be called from cmake
// Overwrite jar location
task allJar(type: Jar) {
manifest {
attributes('Automatic-Module-Name': project.group,
'Implementation-Title': 'onnxruntime',
'Implementation-Version': project.version)
}
into("META-INF/maven/$project.group/$mavenArtifactId") {
from { generatePomFileForMavenPublication }
rename ".*", "pom.xml"
}
from sourceSets.main.output
from cmakeNativeJniDir
from cmakeNativeLibDir
}
task cmakeBuild(type: Copy) {
from project.buildDir
include 'libs/**'
include 'docs/**'
into cmakeBuildOutputDir
}
cmakeBuild.dependsOn allJar
cmakeBuild.dependsOn sourcesJar
cmakeBuild.dependsOn javadocJar
cmakeBuild.dependsOn javadoc
task cmakeCheck(type: Copy) {
from project.buildDir
include 'reports/**'
into cmakeBuildOutputDir
}
cmakeCheck.dependsOn check
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
testImplementation 'com.google.protobuf:protobuf-java:3.21.7'
}
processTestResources {
duplicatesStrategy(DuplicatesStrategy.INCLUDE) // allows duplicates in the test resources
}
test {
java {
dependsOn spotlessJava
}
if (System.getProperty("JAVA_FULL_TEST") != null) {
// Forces each test class to be run in a separate JVM,
// which is necessary for testing the environment thread pool which is ignored if full test is not set.
forkEvery 1
}
useJUnitPlatform()
if (cmakeBuildDir != null) {
workingDir cmakeBuildDir
}
systemProperties System.getProperties().subMap(['USE_CUDA', 'USE_ROCM', 'USE_TENSORRT', 'USE_DNNL', 'USE_OPENVINO', 'USE_COREML', 'USE_DML', 'JAVA_FULL_TEST', 'ENABLE_TRAINING_APIS'])
testLogging {
events "passed", "skipped", "failed"
showStandardStreams = true
showStackTraces = true
exceptionFormat = "full"
}
}
jacocoTestReport {
reports {
xml.required = true
csv.required = true
html.destination file("${buildDir}/jacocoHtml")
}
}
publishing {
publications {
maven(MavenPublication) {
groupId = project.group
artifactId = mavenArtifactId
from components.java
pom {
name = enableTrainingApis ? 'onnxruntime-training' : 'onnx-runtime'
description = enableTrainingApis ? trainingDescription : defaultDescription
url = 'https://microsoft.github.io/onnxruntime/'
licenses {
license {
name = 'MIT License'
url = 'https://opensource.org/licenses/MIT'
}
}
organization {
name = 'Microsoft'
url = 'https://www.microsoft.com'
}
scm {
connection = 'scm:git:git://github.com:microsoft/onnxruntime.git'
developerConnection = 'scm:git:ssh://github.com/microsoft/onnxruntime.git'
url = 'https://github.com/microsoft/onnxruntime'
}
developers {
developer {
id = 'onnxruntime'
name = 'ONNX Runtime'
email = 'onnxruntime@microsoft.com'
}
}
}
}
}
repositories {
maven {
url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
credentials {
username mavenUser
password mavenPwd
}
}
}
}
// Generates a task signMavenPublication that will
// build all artifacts.
signing {
// Queries env vars:
// ORG_GRADLE_PROJECT_signingKey
// ORG_GRADLE_PROJECT_signingPassword but can be changed to properties
def signingKey = findProperty("signingKey")
def signingPassword = findProperty("signingPassword")
useInMemoryPgpKeys(signingKey, signingPassword)
sign publishing.publications.maven
}