import org.gradle.api.internal.java.DefaultJavaPlatformExtension import org.gradle.api.plugins.internal.DefaultJavaPluginExtension import org.gradle.api.publish.maven.internal.publisher.MavenRemotePublisher import org.gradle.language.nativeplatform.internal.Dimensions buildscript { /**************************************************************************** * Establish Visual Studio configuration environment for Windows native builds * NOTE: vsconfig.gradle path is relative to each GPL project module ****************************************************************************/ apply from: "../../vsconfig.gradle" apply from: "../../chooseBackend.gradle" ext { host_cores = Runtime.getRuntime().availableProcessors() buildHelper = "-mingw" javacppPlatform = osdetector.classifier println "Building on ${host_cores} CPU cores." println "JavaCPP target plattform is ${javacppPlatform}" if (project.hasProperty("CAVIS_AVX_EXTENSION")) { avxExtension = project.getProperty("CAVIS_AVX_EXTENSION").toLowerCase() println "Bulding with ${avxExtension}" } else { avxExtension = "avx2" logger.quiet("No AVX CPU extension selected (avx2|avx512). Building with default 'avx2'") } javacppPlatformExtension = "-${avxExtension}".toString() getBuildPlatform = { String chip, Task tsk -> def pf ="" if(chip.equals("cuda")) { pf = osdetector.classifier } else { if(osdetector.os.equals("windows")) { pf = "${osdetector.classifier}-mingw" } else { pf = "${osdetector.classifier}" } } logger.info("Setting properties for task '{}' to '{}'", tsk.getName(), pf) return pf } } // End of ext block dependencies { classpath platform(project(":cavis-common-platform")) classpath group: "org.bytedeco", name: "openblas" classpath group: "org.bytedeco", name: "openblas", classifier: "${javacppPlatform}" classpath group: "org.bytedeco", name:"mkl" classpath group: "org.bytedeco", name:"mkl", classifier: "${javacppPlatform}" classpath group: "org.bytedeco", name: "javacpp" classpath group: "org.bytedeco", name: "javacpp", classifier: "${javacppPlatform}" } } plugins { id 'java-library' id 'org.bytedeco.gradle-javacpp-build' version "1.5.9" //version "1.5.10-SNAPSHOT" id 'maven-publish' id 'signing' } chipList.each {String thisChip -> /*sourceSets.register(thisChip) { java { srcDirs = ["${projectDir}/src/main/java/"] include "org/nd4j/nativeblas/${thisChip}/Nd4j${thisChip.capitalize()}Helper.java" include "org/nd4j/nativeblas/${thisChip}/Nd4j${thisChip.capitalize()}Presets.java" } }*/ sourceSets.register("${thisChip}").configure { java { srcDirs = ["${buildDir}/generated/sources/javacpp/${thisChip}/${javacppPlatform}${javacppPlatformExtension}/"] include "org/nd4j/nativeblas/Nd4j${thisChip.capitalize()}.java" } compiledBy "javacpp${thisChip.capitalize()}SupportBuildCompiler" } } /* sourceSets { main { java { srcDirs = new HashSet<>(); include 'org/nd4j/nativeblas/Dummy.java' } } } */ // This block registers the cpu and cuda features and creates // i. e. the {chip}Implementation java { chipList.each {thisChip -> registerFeature("${thisChip}Support") { usingSourceSet(sourceSets.findByName("${thisChip}")) capability(project.group, "cavis-native-lib-${thisChip}-support", project.version) //withJavadocJar() //withSourcesJar() }}} dependencies { if(withCuda()) { cudaImplementation platform(project(':cavis-common-platform')) //cudaImplementation project(":cavis-dnn:cavis-dnn-api") //cudaImplementation project(":cavis-dnn:cavis-dnn-common") cudaImplementation project(":cavis-native:cavis-native-blas") //cudaImplementation project(":cavis-native:cavis-native-common") //cudaImplementation "commons-io:commons-io" //cudaImplementation "org.bytedeco:openblas" //cudaImplementation "org.bytedeco:openblas::${javacppPlatform}" //cudaImplementation "org.bytedeco:cuda" //cudaImplementation "org.bytedeco:cuda::${javacppPlatform}" //cudaImplementation "org.apache.logging.log4j:log4j-core:2.17.0" //cudaImplementation "com.google.guava:guava:14.0.1" //cudaImplementation "org.apache.commons:commons-lang3" //cudaImplementation "org.apache.commons:commons-math3" //cudaImplementation "com.google.flatbuffers:flatbuffers-java" //cudaImplementation 'javax.mail:javax.mail-api:1.6.2' cudaImplementation "org.bytedeco:javacpp" cudaImplementation "org.bytedeco:javacpp::${javacppPlatform}" cudaImplementation project(":cavis-native:cavis-native-cuda-presets") //cudaGeneratedImplementation platform(project(':cavis-common-platform')) //cudaGeneratedImplementation project(":cavis-native:cavis-native-blas") //cudaGeneratedImplementation "org.bytedeco:javacpp" //cudaGeneratedImplementation "org.bytedeco:javacpp::${javacppPlatform}" //cudaGeneratedImplementation project(":cavis-native:cavis-native-cuda-presets") } if(withCpu()) { cpuImplementation platform(project(':cavis-common-platform')) //cpuImplementation project(":cavis-dnn:cavis-dnn-api") //cpuImplementation project(":cavis-dnn:cavis-dnn-common") cpuImplementation project(":cavis-native:cavis-native-blas") //cpuImplementation project(":cavis-native:cavis-native-common") //cpuImplementation "commons-io:commons-io" //cpuImplementation "org.bytedeco:opencv" //cpuImplementation "org.bytedeco:opencv::${javacppPlatform}" //cpuImplementation "org.apache.logging.log4j:log4j-core:2.17.0" //cpuImplementation "com.google.guava:guava:14.0.1" //cpuImplementation "org.apache.commons:commons-lang3" //cpuImplementation "org.apache.commons:commons-math3" //cpuImplementation "com.google.flatbuffers:flatbuffers-java" //cpuImplementation 'javax.mail:javax.mail-api:1.6.2' cpuImplementation "org.bytedeco:javacpp" cpuImplementation "org.bytedeco:javacpp::${javacppPlatform}" // https://mvnrepository.com/artifact/org.bytedeco/openblas cpuImplementation 'org.bytedeco:openblas:0.3.23-1.5.9' cpuImplementation project(":cavis-native:cavis-native-cpu-presets") } } clean { doFirst { delete "${projectDir}/build" delete "${projectDir}/src/main/include/config.h" chipList.each { delete "${projectDir}/blasbuild/${it}" } } } task deepClean(type: Delete) { dependsOn clean doFirst { delete "$projectDir}/blasbuild" } } tasks.withType(org.bytedeco.gradle.javacpp.BuildTask).configureEach { org.bytedeco.gradle.javacpp.BuildTask it -> it.buildResource = ["/org/bytedeco/openblas/${javacppPlatform}/", "/org/bytedeco/mkldnn/${javacppPlatform}/"] it.includeResource = ["/org/bytedeco/openblas/${javacppPlatform}/include/"] it.linkResource = ["/org/bytedeco/openblas/${javacppPlatform}/", "/org/bytedeco/openblas/${javacppPlatform}/lib/"] } // Disable the standard javacpp generated tasks and use own // versions below. This allows to build for each variant [javacppBuildParser, javacppBuildCommand, javacppCompileJava, javacppBuildCompiler].each { it.enabled false } chipList.each { String thisChip -> // 1) //Run the C++ compile first tasks.register("javacpp${thisChip.capitalize()}SupportBuildCommand", org.bytedeco.gradle.javacpp.BuildTask) {org.bytedeco.gradle.javacpp.BuildTask it -> properties = getBuildPlatform( thisChip, it ) includePath = ["${projectDir}/src/main/cpp/blas/", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/src/main/include/", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/flatbuffers-src/include", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/cpu_features-src/include", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/mkldnn-src/include"] linkPath = ["${projectDir}/blasbuild/${thisChip}/${avxExtension}/output"] //No idea why this is here, but it looks like even for the javacppBuildCommand task, //there is a javacpp Loader actively determining platform etc. classOrPackageNames = ["org.nd4j.nativeblas.${thisChip}.Nd4j${thisChip.capitalize()}Presets"] //workingDirectory = projectDir //if the classpath is not set here, the javacpp classloader starts to look around //everywhere and causes java.io.IOExceptions: because files is being used by another process //logger.quiet("Using compile classpath from configuration named '{}'", sourceSets.named(thisChip).get().getCompileClasspathConfigurationName()) classPath = sourceSets.named(thisChip).get().compileClasspath.collect() /* Get VCVARS in case we want to build CUDA * MinGW64 g++ on MSYS is used otherwise */ if (thisChip.equals('cuda') && osdetector.os.startsWith("win") && !VISUAL_STUDIO_INSTALL_DIR.isEmpty()) { def proc = ["cmd.exe", "/c", "${VISUAL_STUDIO_VCVARS_CMD} > nul && set"].execute() it.environmentVariables = it.environmentVariables ?: [:] def lines = proc.text.split("\\r?\\n") for (def line in lines) { if (line.contains("=")) { def parts = line.split("=") it.environmentVariables.put(parts[0], parts[1]) logger.debug("Added variable to environment: {} = {}", parts[0], parts[1]) } } } workingDirectory projectDir if (thisChip.equals('cuda') && osdetector.os.startsWith("windows")) { //cuDNN requires CUDA it.buildCommand = ['sh', 'buildnativeoperations.sh', '-V', '--build-type', 'release', '--chip', thisChip, '--plattform', 'x86_64', '--chip-extension', avxExtension, '-j', "${host_cores}", // '--helper', 'mkldnn', '--helper', 'cudnn'] } else if (thisChip.equals('cuda') && osdetector.os.startsWith("linux")) { //cuDNN requires CUDA it.buildCommand = ['bash', 'buildnativeoperations.sh', '-V', '--build-type', 'release', '--chip', thisChip, '--plattform', 'x86_64', '--chip-extension', avxExtension, '-j', "${host_cores}", // '--helper', 'mkldnn', '--helper', 'cudnn'] } else { it.buildCommand = ['bash', 'buildnativeoperations.sh', '-V', '--build-type', 'release', '--chip', thisChip, '--plattform', 'x86_64', '--chip-extension', avxExtension, '-j', "${host_cores}", '--helper', 'mkldnn'] } } //Run the parser on the InfoMap in Nd4j$ChipPresets and listed header files in @Platform //Generates Nd4jCpu.java and/ or Nd4jCuda.java Java JNI code tasks.register("javacpp${thisChip.capitalize()}SupportBuildParser", org.bytedeco.gradle.javacpp.BuildTask) { includePath = ["${projectDir}/src/main/cpp/blas/", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/src/main/include/", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/flatbuffers-src/include", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/cpu_features-src/include", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/mkldnn-src/include"] classOrPackageNames = ["org.nd4j.nativeblas.${thisChip}.Nd4j${thisChip.capitalize()}Presets"] classPath = sourceSets.named(thisChip).get().compileClasspath.collect() outputDirectory file("${buildDir}/generated/sources/javacpp/${thisChip}/${javacppPlatform}${javacppPlatformExtension}/") } // Generates jnijavacpp.cpp and jniNativeLibrary.cpp, compiles and links it tasks.register("javacpp${thisChip.capitalize()}SupportBuildCompiler", org.bytedeco.gradle.javacpp.BuildTask) {org.bytedeco.gradle.javacpp.BuildTask it -> linkPath = ["${projectDir}/blasbuild/${thisChip}/${avxExtension}/output"] includePath = ["${projectDir}/src/main/cpp/blas/", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/src/main/include/", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/flatbuffers-src/include", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/cpu_features-src/include", "${projectDir}/blasbuild/${thisChip}/${avxExtension}/mkldnn-src/include"] properties = getBuildPlatform( thisChip, it ) if(thisChip.equals('cuda') && osdetector.os.startsWith("win") && !VISUAL_STUDIO_INSTALL_DIR.isEmpty()) { def proc = ["cmd.exe", "/c", "${VISUAL_STUDIO_VCVARS_CMD} > nul && where.exe cl.exe"].execute() def outp = proc.text def cl = "\"" + outp.replace("\\", "\\\\").trim() + "\"" def currentCompiler = "" doFirst{ currentCompiler = System.getProperty("org.bytedeco.javacpp.platform.compiler") System.setProperty("org.bytedeco.javacpp.platform.compiler", cl) System.setProperty("platform.compiler.cpp11", cl) logger.quiet("Task ${name} overrides compiler '${currentCompiler}' with '${cl}'.") } doLast { //restore compiler System.setProperty("org.bytedeco.javacpp.platform.compiler", currentCompiler ?: "") }//System.setProperty("org.bytedeco.javacpp.platform.compiler", cl) //System.setProperty("org.bytedeco.javacpp.platform.compiler.cpp11", cl) proc = ["cmd.exe", "/c", "${VISUAL_STUDIO_VCVARS_CMD} > nul && set"].execute() environmentVariables = environmentVariables ?: [:] def lines = proc.text.split("\\r?\\n") for (def line in lines) { if (line.contains("=")) { def parts = line.split("=") environmentVariables.put(parts[0], parts[1]) } } } else { //System.setProperty("org.bytedeco.javacpp.platform.compiler", "g++") } buildPath = ["${buildDir}/generated/sources/javacpp/${thisChip}/${javacppPlatform}${javacppPlatformExtension}/"] copyLibs = true deleteJniFiles(false) //outputName = "jnind4j${thisChip}" outputDirectory = file("${buildDir}/generated/sources/javacpp/${thisChip}/${javacppPlatform}${javacppPlatformExtension}/") classOrPackageNames= ["org.nd4j.nativeblas.Nd4j${thisChip.capitalize()}"] configDirectory = file("${buildDir}/classes/java/${thisChip}Support/META-INF/native-image/${javacppPlatform}") classPath = sourceSets.named("${thisChip}").get().compileClasspath.collect() classPath += "${buildDir}/classes/java/${thisChip}/" } // Create Jar with classifier tasks.named("${thisChip}Jar").configure { Jar thisTask -> dependsOn "javacpp${thisChip.capitalize()}SupportBuildCompiler" dependsOn "javacpp${thisChip.capitalize()}SupportBuildCommand" def spec = copySpec { from(tasks.named("javacpp${thisChip.capitalize()}SupportBuildCompiler").get()) { exclude { f -> def exclude = f.file.isDirectory() if(exclude) { logger.info("${thisTask.name}: excluding '${f}'") } else { logger.info("${thisTask.name}: including '${f}'") } return exclude } into "${javacppPlatform}/" //path within jar, we need it in a platform, that javacpp Loader understands } from(sourceSets.named(thisChip).get().getOutput()) { into "${javacppPlatform}/" //path within jar, we need it in a platform, that javacpp Loader understands } duplicatesStrategy DuplicatesStrategy.EXCLUDE } thisTask.with spec thisTask.archiveClassifier = "${javacppPlatform}${javacppPlatformExtension}-${thisChip}" } } //Before we can compile the whole java part, we //need to generate the Nd4jXXX.java files first tasks.named("compileJava").configure {enabled false} chipList.each { String thisChip -> //ensure full build process is running on "build" tasks.named("build").configure { dependsOn "javacpp${thisChip.capitalize()}SupportBuildCompiler" } //Compiles and links the generated jni code with the underlying native library tasks.named("javacpp${thisChip.capitalize()}SupportBuildCompiler").configure { dependsOn "javacpp${thisChip.capitalize()}SupportBuildParser" } //Generates the jni interface sources tasks.named("javacpp${thisChip.capitalize()}SupportBuildParser").configure { dependsOn "javacpp${thisChip.capitalize()}SupportBuildCommand" } //Compiles the c++ and cuda sources tasks.named("javacpp${thisChip.capitalize()}SupportBuildCommand").configure { } //Compile the generates jni interface (java portion) tasks.named("compile${thisChip.capitalize()}Java").configure { dependsOn "javacpp${thisChip.capitalize()}SupportBuildParser" } tasks.named("${thisChip}Jar").configure { dependsOn "javacpp${thisChip.capitalize()}SupportBuildCompiler" } } tasks.withType(JavaCompile).configureEach { // options.setCompilerArgs(Arrays.asList("-Xlint:unchecked")) } tasks.withType(Javadoc).configureEach { options.addStringOption('Xdoclint:none', '-quiet') } javadoc { dependsOn "javacppPomProperties" failOnError = false //options.links = ['http://bytedeco.org/javacpp/apidocs'] options.addStringOption('Xdoclint:none', '-quiet') //options.JFlags = ["-Xdoclint:none"] } tasks.getByName("generatePomFileForMavenJavaPublication") { enabled = true } tasks.getByName("publishMavenJavaPublicationToLocalRemoteRepository") { enabled = true } artifacts { //implementation(jar) chipList.each { String thisChip -> implementation tasks.getByName("${thisChip}Jar") } } /* if( osdetector.os.startsWith("windows")) { FileCollection collection = layout.files { file("build/libs/").listFiles() } //collection.collect { relativePath(it) }.sort().each { println it } publishing { publications { mavenJava(MavenPublication) { artifact jar collection.collect {File fi -> if( fi.name.contains('linux-x86_64-avx2-cpu')) { logger.quiet("Adding artifact ${fi.name} to publication.") artifact source: fi, classifier: 'linux-x86_64-avx2-cpu', extension: 'jar' } } } } } } */ signing { useGpgCmd() if (!version.endsWith('SNAPSHOT')) { sign publishing.publications.mavenJava //sign publishing.publications.mavenJavacppPlatform } }