Files
2026-07-13 12:47:05 +08:00

4711 lines
113 KiB
Plaintext

025-05-05T03:09:52.4345489Z [INFO]
2025-05-05T03:09:52.4345948Z [INFO] --- javacpp:1.5.11:build (javacpp-compiler) @ nd4j-cuda-12.3 ---
2025-05-05T03:09:52.4372452Z [INFO] Detected platform "linux-x86_64"
2025-05-05T03:09:52.4373298Z [INFO] Building platform "linux-x86_64"
2025-05-05T03:09:52.4383310Z Functrace on: false
2025-05-05T03:09:52.4385260Z Functrace on: false
2025-05-05T03:09:52.4387262Z Functrace on: false
2025-05-05T03:09:52.4388167Z Functrace on: false
2025-05-05T03:09:52.4390245Z Functrace on: false
2025-05-05T03:09:52.4391088Z Functrace on: false
2025-05-05T03:09:52.4391695Z Functrace on: false
2025-05-05T03:09:52.4393410Z [INFO] Generating /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/org/nd4j/linalg/jcublas/bindings/linux-x86_64/jnijavacpp.cpp
2025-05-05T03:09:52.4514086Z [INFO] Generating /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/META-INF/native-image/linux-x86_64/jnijavacpp/jni-config.json
2025-05-05T03:09:52.4519270Z [INFO] Generating /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/META-INF/native-image/linux-x86_64/jnijavacpp/reflect-config.json
2025-05-05T03:09:52.4608494Z [INFO] Generating /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/org/nd4j/linalg/jcublas/bindings/linux-x86_64/jnind4jcuda.cpp
2025-05-05T03:09:52.4610954Z Functrace on: false
2025-05-05T03:09:52.4612065Z Functrace on: false
2025-05-05T03:09:52.4612717Z Functrace on: false
2025-05-05T03:09:52.7444052Z [INFO] Generating /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/META-INF/native-image/linux-x86_64/jnind4jcuda/jni-config.json
2025-05-05T03:09:52.7447513Z [INFO] Generating /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/META-INF/native-image/linux-x86_64/jnind4jcuda/reflect-config.json
2025-05-05T03:09:52.7451240Z Functrace on: false
2025-05-05T03:09:52.7451872Z Functrace on: false
2025-05-05T03:09:52.7452475Z Functrace on: false
2025-05-05T03:09:53.0276155Z [INFO] Compiling /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/org/nd4j/linalg/jcublas/bindings/linux-x86_64/libjnind4jcuda.so
2025-05-05T03:09:53.0411438Z [INFO] g++ -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/blasbuild/cuda/include -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/blasbuild/cuda/flatbuffers-src/include -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/helpers -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/array -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/cnpy -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/execution -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/exceptions -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/graph -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/indexing -I/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/memory -I/usr/lib/jvm/temurin-11-jdk-amd64/include/linux -I/usr/lib/jvm/temurin-11-jdk-amd64/include /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/org/nd4j/linalg/jcublas/bindings/linux-x86_64/jnind4jcuda.cpp /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/org/nd4j/linalg/jcublas/bindings/linux-x86_64/jnijavacpp.cpp -march=x86-64 -m64 -O3 -s -std=c++11 -w -std=c++17 -Wl,--no-undefined -L/home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/../../../../libnd4j//blasbuild/cuda/blas -Wl,-rpath,$ORIGIN/ -Wl,-z,noexecstack -Wl,-Bsymbolic -Wall -fPIC -pthread -shared -o libjnind4jcuda.so -L/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/blasbuild/cuda -Wl,-rpath,/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/blasbuild/cuda -lnd4jcuda
2025-05-05T03:10:17.9724419Z [INFO] Deleting /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/org/nd4j/linalg/jcublas/bindings/linux-x86_64/jnind4jcuda.cpp
2025-05-05T03:10:17.9729818Z [INFO] Deleting /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/org/nd4j/linalg/jcublas/bindings/linux-x86_64/jnijavacpp.cpp
2025-05-05T03:10:17.9733270Z Functrace on: false
2025-05-05T03:10:17.9733954Z Functrace on: false
2025-05-05T03:10:17.9734594Z Functrace on: false
2025-05-05T03:10:17.9735237Z Functrace on: false
2025-05-05T03:10:17.9735864Z Functrace on: false
2025-05-05T03:10:17.9736456Z Functrace on: false
2025-05-05T03:10:17.9738730Z [WARNING] Could not find library gomp@.1
2025-05-05T03:10:17.9740249Z [INFO] Copying /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/../../../../libnd4j/blasbuild/cuda/libnd4jcuda.so
2025-05-05T03:10:18.5352603Z [INFO] Generating /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/classes/META-INF/native-image/linux-x86_64/jnind4jcuda/resource-config.json
2025-05-05T03:10:18.5354365Z [INFO]
2025-05-05T03:10:18.5355627Z [INFO] --- resources:3.3.1:testResources (default-testResources) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:18.5368816Z [INFO] skip non existing resourceDirectory /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/src/test/resources
2025-05-05T03:10:18.5369744Z [INFO]
2025-05-05T03:10:18.5370635Z [INFO] --- kotlin:1.9.24:test-compile (test-compile) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:18.5388379Z [INFO] No sources to compile
2025-05-05T03:10:18.5389340Z [INFO]
2025-05-05T03:10:18.5390143Z [INFO] --- compiler:3.13.0:testCompile (java-testCompile) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:18.5403382Z [INFO] No sources to compile
2025-05-05T03:10:18.5404057Z [INFO]
2025-05-05T03:10:18.5404793Z [INFO] --- surefire:3.3.0:test (default-test) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:18.5431942Z [INFO] Tests are skipped.
2025-05-05T03:10:18.5432811Z [INFO]
2025-05-05T03:10:18.5433516Z [INFO] --- jar:3.0.2:jar (default-jar) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:18.5724945Z [INFO] Building jar: /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/nd4j-cuda-12.3-1.0.0-SNAPSHOT.jar
2025-05-05T03:10:18.6341942Z [INFO]
2025-05-05T03:10:18.6342448Z [INFO] --- jar:3.0.2:jar (linux-x86_64) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:18.6423151Z [INFO] Building jar: /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/nd4j-cuda-12.3-1.0.0-SNAPSHOT-linux-x86_64.jar
2025-05-05T03:10:46.2853343Z [WARNING] artifact org.nd4j:nd4j-cuda-12.3:jar:linux-x86_64:1.0.0-SNAPSHOT already attached, replace previous instance
2025-05-05T03:10:46.2856994Z [INFO]
2025-05-05T03:10:46.2858005Z [INFO] --- install:2.5.2:install (default-install) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:46.2865789Z [INFO] Installing /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/nd4j-cuda-12.3-1.0.0-SNAPSHOT.jar to /home/runner/.m2/repository/org/nd4j/nd4j-cuda-12.3/1.0.0-SNAPSHOT/nd4j-cuda-12.3-1.0.0-SNAPSHOT.jar
2025-05-05T03:10:46.2883071Z [INFO] Installing /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/pom.xml to /home/runner/.m2/repository/org/nd4j/nd4j-cuda-12.3/1.0.0-SNAPSHOT/nd4j-cuda-12.3-1.0.0-SNAPSHOT.pom
2025-05-05T03:10:46.2918686Z [INFO] Installing /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/nd4j-cuda-12.3-1.0.0-SNAPSHOT-linux-x86_64.jar to /home/runner/.m2/repository/org/nd4j/nd4j-cuda-12.3/1.0.0-SNAPSHOT/nd4j-cuda-12.3-1.0.0-SNAPSHOT-linux-x86_64.jar
2025-05-05T03:10:47.7434450Z [INFO]
2025-05-05T03:10:47.7435473Z [INFO] --- central-publishing:0.7.0:publish (injected-central-publishing) @ nd4j-cuda-12.3 ---
2025-05-05T03:10:47.7451743Z [INFO] Installing /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/nd4j-cuda-12.3-1.0.0-SNAPSHOT.jar to /home/runner/work/deeplearning4j/deeplearning4j/target/central-deferred/org/nd4j/nd4j-cuda-12.3/1.0.0-SNAPSHOT/nd4j-cuda-12.3-1.0.0-SNAPSHOT.jar
2025-05-05T03:10:47.7462077Z [INFO] Installing /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/pom.xml to /home/runner/work/deeplearning4j/deeplearning4j/target/central-deferred/org/nd4j/nd4j-cuda-12.3/1.0.0-SNAPSHOT/nd4j-cuda-12.3-1.0.0-SNAPSHOT.pom
2025-05-05T03:10:47.7473209Z [INFO] Installing /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cuda/target/nd4j-cuda-12.3-1.0.0-SNAPSHOT-linux-x86_64.jar to /home/runner/work/deeplearning4j/deeplearning4j/target/central-deferred/org/nd4j/nd4j-cuda-12.3/1.0.0-SNAPSHOT/nd4j-cuda-12.3-1.0.0-SNAPSHOT-linux-x86_64.jar
05T03:03:45.9719537Z [100%] Linking CXX shared library libnd4jcuda.so
2025-05-05T03:03:45.9723929Z /usr/local/bin/cmake -E cmake_link_script CMakeFiles/nd4jcuda.dir/link.txt --verbose=1
2025-05-05T03:03:48.2413685Z /usr/bin/g++-11 -fPIC -O3 -fPIC -D_RELEASE=true -shared -Wl,-soname,libnd4jcuda.so -o libnd4jcuda.so @CMakeFiles/nd4jcuda.dir/objects1.rsp -L/usr/local/lib -L/usr/local/cuda-12.3/targets/x86_64-linux/lib/stubs -L/usr/local/cuda-12.3/targets/x86_64-linux/lib -Wl,-rpath,/usr/local/lib:/usr/local/cuda-12.3/lib64: /usr/local/cuda-12.3/lib64/libcudart_static.a -ldl /usr/lib/x86_64-linux-gnu/librt.a /usr/local/cuda-12.3/lib64/libcublas.so /usr/local/cuda-12.3/lib64/libcusolver.so flatbuffers-build/libflatbuffers.a -lcudadevrt -lcudart_static -lrt -lpthread -ldl
2025-05-05T03:03:48.2417371Z make[2]: Leaving directory '/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/blasbuild/cuda'
2025-05-05T03:03:48.2442663Z [100%] Built target nd4jcuda
2025-05-05T03:03:48.2447536Z make[1]: Leaving directory '/home/runner/work/deeplearning4j/deeplearning4j/libnd4j/blasbuild/cuda'
2025-05-05T03:03:48.2450298Z /usr/local/bin/cmake -E cmake_progress_start /home/runner/work/deeplearning4j/deeplearning4j/libnd4j/blasbuild/cuda/CMakeFiles 0
2025-05-05T03:03:48.2522772Z Copying flatc generated for java
2025-05-05T03:03:48.2595664Z + echo 'Script directory: /home/runner/work/deeplearning4j/deeplearning4j/libnd4j'
2025-05-05T03:03:48.2596785Z Script directory: /home/runner/work/deeplearning4j/deeplearning4j/libnd4j
2025-05-05T03:03:48.2597545Z + echo 'LibND4J directory: /home/runner/work/deeplearning4j/deeplearning4j/libnd4j'
2025-05-05T03:03:48.2598267Z + echo 'Project root: /home/runner/work/deeplearning4j/deeplearning4j'
2025-05-05T03:03:48.2599123Z + echo 'Source directory: /home/runner/work/deeplearning4j/deeplearning4j/libnd4j/include/graph/generated/org/nd4j/graph'
2025-05-05T03:03:48.2600763Z + echo 'Target directory: /home/runner/work/deeplearning4j/deeplearning4j/nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ /* ******************************************************************************
~ *
~ *
~ * This program and the accompanying materials are made available under the
~ * terms of the Apache License, Version 2.0 which is available at
~ * https://www.apache.org/licenses/LICENSE-2.0.
~ *
~ * See the NOTICE file distributed with this work for additional
~ * information regarding copyright ownership.
~ * Unless required by applicable law or agreed to in writing, software
~ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
~ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
~ * License for the specific language governing permissions and limitations
~ * under the License.
~ *
~ * SPDX-License-Identifier: Apache-2.0
~ ******************************************************************************/
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.deeplearning4j</groupId>
<artifactId>deeplearning4j</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.deeplearning4j</groupId>
<artifactId>libnd4j</artifactId>
<packaging>pom</packaging>
<name>libnd4j</name>
<description>The C++ engine that powers the scientific computing library ND4J - n-dimensional
arrays for Java
</description>
<properties>
<libnd4j.generate.flatc>false</libnd4j.generate.flatc>
<libnd4j.outputPath>${project.basedir}/blasbuild/${libnd4j.chip}</libnd4j.outputPath>
<cuda.version>12.3</cuda.version>
<cudnn.version>8.9</cudnn.version>
<libnd4j.build>release</libnd4j.build>
<libnd4j.chip>cpu</libnd4j.chip>
<libnd4j.platform>${javacpp.platform}</libnd4j.platform>
<libnd4j.extension></libnd4j.extension>
<libnd4j.cuda></libnd4j.cuda>
<libnd4j.compute></libnd4j.compute>
<libnd4j.classifier>${libnd4j.platform}</libnd4j.classifier>
<libnd4j.buildthreads></libnd4j.buildthreads>
<libnd4j.helper></libnd4j.helper>
<libnd4j.buildprogram>bash</libnd4j.buildprogram>
<libnd4j.operations></libnd4j.operations>
<libnd4j.datatypes></libnd4j.datatypes>
<libnd4j.sanitize>OFF</libnd4j.sanitize>
<libnd4j.ptxas>OFF</libnd4j.ptxas>
<libnd4j.sanitizers>address,</libnd4j.sanitizers>
<libnd4j.arch></libnd4j.arch>
<openblas.artifactId></openblas.artifactId>
<openblas.classifier></openblas.classifier>
<libnd4j.calltrace>OFF</libnd4j.calltrace>
<libnd4j.lto>OFF</libnd4j.lto>
<libnd4j.vectorization>OFF</libnd4j.vectorization>
<libnd4j.cpu.compile.skip>false</libnd4j.cpu.compile.skip>
<libnd4j.cuda.compile.skip>false</libnd4j.cuda.compile.skip>
<libnd4j.test.filter>none</libnd4j.test.filter>
<libnd4j.log>none</libnd4j.log>
<libnd4j.test.runner></libnd4j.test.runner>
<libnd4j.keepnvcc>OFF</libnd4j.keepnvcc>
<libnd4j.optimization>3</libnd4j.optimization>
<libnd4j.printindices>OFF</libnd4j.printindices>
<libnd4j.printmath>OFF</libnd4j.printmath>
<junit.version>5.9.2</junit.version>
<cpu.core.count></cpu.core.count>
<libnd4j.preprocess>OFF</libnd4j.preprocess>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>org.kuali.maven.wagons</groupId>
<artifactId>maven-s3-wagon</artifactId>
<version>1.2.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire.version}</version>
<configuration>
<reportsDirectory>tests_cpu/surefire-reports/</reportsDirectory>
<systemPropertyVariables>
<libnd4j.build.dir>${project.basedir}</libnd4j.build.dir>
<libnd4j.chip>${libnd4j.chip}</libnd4j.chip>
<libnd4j.test.filter>${libnd4j.test.filter}</libnd4j.test.filter>
<libnd4j.test.runner>${libnd4j.test.runner}</libnd4j.test.runner>
</systemPropertyVariables>
<forkedProcessExitTimeoutInSeconds>0</forkedProcessExitTimeoutInSeconds>
<forkedProcessTimeoutInSeconds>0</forkedProcessTimeoutInSeconds>
</configuration>
<executions>
<execution>
<id>test-results</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<reportsDirectory>tests_cpu/surefire-reports/</reportsDirectory>
<systemPropertyVariables>
<libnd4j.build.dir>${project.build.directory}</libnd4j.build.dir>
<libnd4j.chip>${libnd4j.chip}</libnd4j.chip>
<libnd4j.test.filter>${libnd4j.test.filter}</libnd4j.test.filter>
<libnd4j.test.runner>${libnd4j.test.runner}</libnd4j.test.runner>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${maven-build-helper-plugin.version}</version>
<executions>
<execution>
<id>get-cpu-count</id>
<goals>
<goal>cpu-count</goal>
</goals>
<configuration>
<cpuCount>cpu.core.count</cpuCount>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>javacpp-cppbuild-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<filesets>
<fileset>
<directory>blasbuild</directory>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>compat-profile</id>
<activation>
<property>
<name>javacpp.platform.extension</name>
<value>/.+/</value>
</property>
</activation>
<properties>
<openblas.artifactId>openblas</openblas.artifactId>
<openblas.classifier>${javacpp.platform}</openblas.classifier>
</properties>
</profile>
<profile>
<id>default-javacpp</id>
<activation>
<property>
<name>!javacpp.platform.extension</name>
</property>
</activation>
<properties>
<openblas.artifactId>openblas-platform</openblas.artifactId>
</properties>
</profile>
<profile>
<id>build-windows</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
<properties>
<libnd4j.buildprogram>sh</libnd4j.buildprogram>
</properties>
</profile>
<profile>
<id>build-unix</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<libnd4j.buildprogram>bash</libnd4j.buildprogram>
</properties>
</profile>
<profile>
<id>libnd4j-single-thread</id>
<activation>
<property>
<name>libnd4j.singlethread</name>
</property>
</activation>
<properties>
<libnd4j.buildthreads>1</libnd4j.buildthreads>
</properties>
</profile>
<profile>
<id>libnd4-multi-thread</id>
<activation>
<property>
<name>!libnd4j.singlethread</name>
</property>
</activation>
<properties>
<libnd4j.buildthreads>${cpu.core.count}</libnd4j.buildthreads>
</properties>
</profile>
<profile>
<id>chip</id>
<activation>
<property>
<name>libnd4j.chip</name>
</property>
</activation>
<properties>
<libnd4j.classifier>${libnd4j.platform}-${libnd4j.chip}-${cuda.version}
</libnd4j.classifier>
</properties>
</profile>
<profile>
<id>extension</id>
<activation>
<property>
<name>libnd4j.extension</name>
</property>
</activation>
<properties>
<libnd4j.classifier>${libnd4j.platform}-${libnd4j.extension}</libnd4j.classifier>
</properties>
</profile>
<profile>
<id>cuda</id>
<activation>
<property>
<name>libnd4j.cuda</name>
</property>
</activation>
<properties>
<libnd4j.cpu.compile.skip>true</libnd4j.cpu.compile.skip>
<libnd4j.cuda.compile.skip>false</libnd4j.cuda.compile.skip>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>${javacpp.version}</version>
<configuration>
<properties>${libnd4j.platform}</properties>
</configuration>
<executions>
<execution>
<id>javacpp-cppbuild-compile-cuda</id>
<phase>compile</phase>
<goals>
<goal>build</goal>
</goals>
<configuration>
<skip>${libnd4j.cuda.compile.skip}</skip>
<buildCommand>
<program>${libnd4j.buildprogram}</program>
<argument>buildnativeoperations.sh</argument>
<argument>--output-path</argument>
<argument>${libnd4j.outputPath}</argument>
<argument>--build-type</argument>
<argument>${libnd4j.build}</argument>
<argument>--chip</argument>
<argument>cuda</argument>
<argument>--platform</argument>
<argument>${libnd4j.platform}</argument>
<argument>--chip-extension</argument>
<argument>${libnd4j.extension}</argument>
<argument>--chip-version</argument>
<argument>${cuda.version}</argument>
<argument>--compute</argument>
<argument>${libnd4j.compute}</argument>
<argument>${libnd4j.tests}</argument>
<argument>-j</argument>
<argument>${libnd4j.buildthreads}</argument>
<argument>-h</argument>
<argument>${libnd4j.helper}</argument>
<argument>--operations</argument>
<argument>${libnd4j.operations}</argument>
<argument>--datatypes</argument>
<argument>${libnd4j.datatypes}</argument>
<argument>--sanitize</argument>
<argument>${libnd4j.sanitize}</argument>
<argument>--sanitizers</argument>
<argument>${libnd4j.sanitizers}</argument>
<argument>--use_lto</argument>
<argument>${libnd4j.lto}</argument>
<argument>--functrace</argument>
<argument>${libnd4j.calltrace}</argument>
<argument>--log-output</argument>
<argument>${libnd4j.log}</argument>
<argument>--optimization-level</argument>
<argument>${libnd4j.optimization}</argument>
<argument>--print-indices</argument>
<argument>${libnd4j.printindices}</argument>
<argument>--print-math</argument>
<argument>${libnd4j.printmath}</argument>
<argument>--preprocess</argument>
<argument>${libnd4j.preprocess}</argument>
<argument>--generate-flatc</argument>
<argument>${libnd4j.generate.flatc}</argument>
</buildCommand>
<workingDirectory>${project.basedir}</workingDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>libnd4j-package-cuda</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-cuda.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>build-cpu</id>
<activation>
<property>
<name>!libnd4j.cuda</name>
</property>
</activation>
<properties>
<libnd4j.cuda.compile.skip>true</libnd4j.cuda.compile.skip>
<libnd4j.cpu.compile.skip>false</libnd4j.cpu.compile.skip>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>${javacpp.version}</version>
<dependencies>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>${openblas.artifactId}</artifactId>
<version>${openblas.version}-${javacpp-presets.version}</version>
<classifier>${openblas.classifier}</classifier>
</dependency>
</dependencies>
<configuration>
<properties>${libnd4j.platform}</properties>
<buildResources>
<buildResource>/${javacpp.platform.library.path}/</buildResource>
<buildResource>/org/bytedeco/openblas/${libnd4j.platform}/</buildResource>
</buildResources>
<includeResources>
<includeResource>/${javacpp.platform.library.path}/include/
</includeResource>
<includeResource>/org/bytedeco/openblas/${libnd4j.platform}/include/
</includeResource>
</includeResources>
<linkResources>
<linkResource>/${javacpp.platform.library.path}/</linkResource>
<linkResource>/${javacpp.platform.library.path}/lib/</linkResource>
<linkResource>/org/bytedeco/openblas/${libnd4j.platform}/</linkResource>
<linkResource>/org/bytedeco/openblas/${libnd4j.platform}/lib/</linkResource>
</linkResources>
</configuration>
<executions>
<execution>
<id>javacpp-cppbuild-validate</id>
<phase>validate</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
<execution>
<id>javacpp-cppbuild-compile</id>
<phase>compile</phase>
<goals>
<goal>build</goal>
</goals>
<configuration>
<skip>${libnd4j.cpu.compile.skip}</skip>
<buildCommand>
<program>${libnd4j.buildprogram}</program>
<argument>buildnativeoperations.sh</argument>
<argument>--output-path</argument>
<argument>${libnd4j.outputPath}</argument>
<argument>--build-type</argument>
<argument>${libnd4j.build}</argument>
<argument>--chip</argument>
<argument>${libnd4j.chip}</argument>
<argument>--platform</argument>
<argument>${libnd4j.platform}</argument>
<argument>--check-vectorization</argument>
<argument>${libnd4j.vectorization}</argument>
<argument>--chip-extension</argument>
<argument>${libnd4j.extension}</argument>
<argument>--chip-version</argument>
<argument>${cuda.version}</argument>
<argument>--compute</argument>
<argument>${libnd4j.compute}</argument>
<argument>${libnd4j.tests}</argument>
<argument>-j</argument>
<argument>${libnd4j.buildthreads}</argument>
<argument>-h</argument>
<argument>${libnd4j.helper}</argument>
<argument>--operations</argument>
<argument>${libnd4j.operations}</argument>
<argument>--datatypes</argument>
<argument>${libnd4j.datatypes}</argument>
<argument>--sanitize</argument>
<argument>${libnd4j.sanitize}</argument>
<argument>--sanitizers</argument>
<argument>${libnd4j.sanitizers}</argument>
<argument>--arch</argument>
<argument>${libnd4j.arch}</argument>
<argument>--use_lto</argument>
<argument>${libnd4j.lto}</argument>
<argument>--functrace</argument>
<argument>${libnd4j.calltrace}</argument>
<argument>--log-output</argument>
<argument>${libnd4j.log}</argument>
<argument>--keep-nvcc-output</argument>
<argument>${libnd4j.keepnvcc}</argument>
<argument>--optimization-level</argument>
<argument>${libnd4j.optimization}</argument>
<argument>--print-indices</argument>
<argument>${libnd4j.printindices}</argument>
<argument>--print-math</argument>
<argument>${libnd4j.printmath}</argument>
<argument>--preprocess</argument>
<argument>${libnd4j.preprocess}</argument>
<argument>--generate-flatc</argument>
<argument>${libnd4j.generate.flatc}</argument>
</buildCommand>
<workingDirectory>${project.basedir}</workingDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>clean-tests</id>
<activation>
<file>
<exists>${basedir}/tests_cpu/Makefile</exists>
</file>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>libnd4j-test-clean</id>
<phase>clean</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>make</executable>
<workingDirectory>${basedir}/tests_cpu</workingDirectory>
<arguments>
<argument>clean</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
################################################################################
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
cmake_minimum_required(VERSION 3.15)
project(libnd4j)
# Basic CMake Configuration
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
message("CMAKE MODULE PATH ${CMAKE_MODULE_PATH}")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF)
set(CMAKE_VERBOSE_MAKEFILE OFF)
set(CMAKE_FIND_DEBUG_MODE 1)
# Standard Settings
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
include(CheckCXXCompilerFlag)
# Set Windows specific flags
if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_WINDOWS_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_WINDOWS_BUILD=true")
endif()
# Options
option(SD_NATIVE "Optimize for build machine (might not work on others)" OFF)
option(SD_CHECK_VECTORIZATION "checks for vectorization" OFF)
option(SD_BUILD_TESTS "Build tests" OFF)
# Force shared library build - these options are kept for potential compatibility but ignored by the simplified logic below
option(SD_STATIC_LIB "Build static library (ignored, only shared lib is built)" OFF)
option(SD_SHARED_LIB "Build shared library (ignored, this is the default)" ON)
option(SD_SANITIZE "Enable Address Sanitizer" OFF)
option(SD_USE_LTO "Use link time optimization" OFF)
option(PRINT_INDICES "Print indices" OFF)
option(PRINT_MATH "Print math operations" OFF)
option(SD_PREPROCESSOR "Use preprocessor" OFF)
option(SD_GCC_FUNCTRACE "Use call traces" OFF)
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler" OFF)
option(SD_PTXAS "Enable ptxas verbose output" OFF)
option(SD_KEEP_NVCC_OUTPUT "Keep NVCC output files" OFF)
option(SD_PREPROCESS "Enable preprocessing" OFF)
# Handle PRINT_INDICES option
message("PRINT_INDICES: ${PRINT_INDICES}")
if(PRINT_INDICES)
message("Added print indices compile definition")
add_compile_definitions(PRINT_INDICES)
endif()
# Handle PRINT_MATH option
message("PRINT_MATH: ${PRINT_MATH}")
if(PRINT_MATH)
message("Added print indices compile definition")
add_compile_definitions(SD_PRINT_MATH)
endif()
# Set optimization level based on GCC_FUNCTRACE
if(SD_GCC_FUNCTRACE)
message("Set optimization for functrace ${SD_GCC_FUNCTRACE}")
set(SD_OPTIMIZATION_LEVEL "0")
else()
message("Set optimization level for no functrace ${SD_GCC_FUNCTRACE}")
set(SD_OPTIMIZATION_LEVEL "3")
endif()
message("Set default optimization level ${SD_OPTIMIZATION_LEVEL}")
set(FLATBUFFERS_BUILD_FLATC "OFF" CACHE STRING "Hack to disable flatc build" FORCE)
# Print build type and all variables
message("BUILD TYPE: ${CMAKE_BUILD_TYPE}")
macro(print_all_variables)
message(STATUS "print_all_variables------------------------------------------{")
get_cmake_property(_variableNames VARIABLES)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
message(STATUS "print_all_variables------------------------------------------}")
endmacro()
# Add this near the top with other option definitions
option(SD_PREPROCESSOR "Use preprocessor" OFF)
# Add this section before the flatbuffers download section
# Compile Definitions for Operations
set(DEFINITIONS_CONTENT "")
if(SD_ALL_OPS OR "${SD_OPS_LIST}" STREQUAL "")
message("Adding all ops due to empty op list or SD_ALL_OPS definition: SD_ALL_OPS=${SD_ALL_OPS} SD_OPS_LIST=${SD_OPS_LIST}")
add_compile_definitions(SD_ALL_OPS=1)
string(APPEND DEFINITIONS_CONTENT "#define SD_ALL_OPS 1\n")
else()
message("_OPS: ${SD_OPS_LIST}")
foreach(OP ${SD_OPS_LIST})
add_compile_definitions(OP_${OP}=1)
message(STATUS "OP: ${OP}")
string(APPEND DEFINITIONS_CONTENT "#define OP_${OP} 1\n")
endforeach()
endif()
# Compile Definitions for Types
list(LENGTH SD_TYPES_LIST SD_TYPES_LIST_COUNT)
if(SD_TYPES_LIST_COUNT GREATER 0)
add_compile_definitions(SD_SELECTIVE_TYPES)
string(APPEND DEFINITIONS_CONTENT "#define SD_SELECTIVE_TYPES\n")
foreach(SD_TYPE ${SD_TYPES_LIST})
string(TOUPPER ${SD_TYPE} SD_TYPE_UPPERCASE)
add_compile_definitions(HAS_${SD_TYPE_UPPERCASE})
message(STATUS "TYPE: ${SD_TYPE_UPPERCASE}")
string(APPEND DEFINITIONS_CONTENT "#define HAS_${SD_TYPE_UPPERCASE}\n")
endforeach()
endif()
# Create the directory for generated files if it doesn't exist
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/generated")
# Write Definitions to include_ops.h file
set(INCLUDE_OPS_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/generated/include_ops.h")
message("Generating include_ops.h at: ${INCLUDE_OPS_FILE}")
file(WRITE "${INCLUDE_OPS_FILE}" "#ifndef SD_DEFINITIONS_GEN_H_\n#define SD_DEFINITIONS_GEN_H_\n${DEFINITIONS_CONTENT}\n#endif\n")
# Add the generated directory to include paths
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/generated")
print_all_variables()
# Define ARM Compute Library URLs based on architecture
set(ARM_COMPUTE_URL_ARMV7 "https://github.com/ARM-software/ComputeLibrary/releases/download/v25.04/arm_compute-v25.04-linux-armv7a-cpu-bin.tar.gz")
set(ARM_COMPUTE_URL_AARCH64 "https://github.com/ARM-software/ComputeLibrary/releases/download/v25.04/arm_compute-v25.04-linux-aarch64-cpu-bin.tar.gz")
set(ARM_COMPUTE_URL_ANDROID_AARCH64 "https://github.com/ARM-software/ComputeLibrary/releases/download/v25.04/arm_compute-v25.04-android-aarch64-cpu-bin.tar.gz")
# Set the appropriate URL based on architecture
if(${SD_ARCH} MATCHES "armv7")
set(ARM_COMPUTE_URL ${ARM_COMPUTE_URL_ARMV7})
message("Using ARM Compute Library for ARMv7 32-bit")
elseif(${SD_ARCH} MATCHES "armv8-a")
if(SD_ANDROID_BUILD)
set(ARM_COMPUTE_URL ${ARM_COMPUTE_URL_ANDROID_AARCH64})
message("Using ARM Compute Library for Android ARM64 (matched armv8-a)")
else()
set(ARM_COMPUTE_URL ${ARM_COMPUTE_URL_AARCH64})
message("Using ARM Compute Library for ARM64 (matched armv8-a)")
endif()
elseif(${SD_ARCH} MATCHES "arm64")
if(SD_ANDROID_BUILD)
set(ARM_COMPUTE_URL ${ARM_COMPUTE_URL_ANDROID_AARCH64})
message("Using ARM Compute Library for Android ARM64 (matched arm64)")
else()
set(ARM_COMPUTE_URL ${ARM_COMPUTE_URL_AARCH64})
message("Using ARM Compute Library for ARM64 (matched arm64)")
endif()
endif()
# Include Directories Based on OS
if(UNIX)
link_directories(/usr/local/lib /usr/lib /lib)
endif()
if(APPLE)
message("Using Apple")
link_directories(/usr/local/lib /usr/lib /lib)
endif()
# Define Compiler Flags for Specific Builds
if(SD_APPLE_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_APPLE_BUILD=true -mmacosx-version-min=10.10")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_APPLE_BUILD=true -mmacosx-version-min=10.10")
endif()
if(SD_ARM_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_ARM_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_ARM_BUILD=true")
endif()
if(SD_ANDROID_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_ANDROID_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_ANDROID_BUILD=true")
endif()
if(SD_IOS_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_IOS_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_IOS_BUILD=true")
endif()
# Windows Specific Configurations
if(WIN32 AND NOT ANDROID)
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
endif()
message(STATUS "Include Directories:")
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
# Workaround for Long Command Lines
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS ON)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS ON)
set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@")
set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@")
set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON CACHE INTERNAL "")
endif()
# Link Time Optimization
if(SD_USE_LTO)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
message(STATUS "Using Link Time Optimization")
add_compile_options(-flto)
add_link_options(-flto)
endif()
endif()
# Compile Definitions for Operations (Appears duplicated, but harmless)
# set(DEFINITIONS_CONTENT "")
# if(SD_ALL_OPS OR "${SD_OPS_LIST}" STREQUAL "")
# message("Adding all ops due to empty op list or SD_ALL_OPS definition: SD_ALL_OPS=${SD_ALL_OPS} SD_OPS_LIST=${SD_OPS_LIST}")
# add_compile_definitions(SD_ALL_OPS=1)
# string(APPEND DEFINITIONS_CONTENT "#define SD_ALL_OPS 1\n")
# else()
# message("_OPS: ${SD_OPS_LIST}")
# foreach(OP ${SD_OPS_LIST})
# add_compile_definitions(OP_${OP}=1)
# message(STATUS "OP: ${OP}")
# string(APPEND DEFINITIONS_CONTENT "#define OP_${OP} 1\n")
# endforeach()
# endif()
# Compile Definitions for Types (Appears duplicated, but harmless)
# list(LENGTH SD_TYPES_LIST SD_TYPES_LIST_COUNT)
# if(SD_TYPES_LIST_COUNT GREATER 0)
# add_compile_definitions(SD_SELECTIVE_TYPES)
# string(APPEND DEFINITIONS_CONTENT "#define SD_SELECTIVE_TYPES\n")
# foreach(SD_TYPE ${SD_TYPES_LIST})
# string(TOUPPER ${SD_TYPE} SD_TYPE_UPPERCASE)
# add_compile_definitions(HAS_${SD_TYPE_UPPERCASE})
# message(STATUS "TYPE: ${SD_TYPE_UPPERCASE}")
# string(APPEND DEFINITIONS_CONTENT "#define HAS_${SD_TYPE_UPPERCASE}\n")
# endforeach()
# endif()
# Write Definitions to Header File (Appears duplicated, but harmless)
# if(OP_OUTPUT_FILE MATCHES ".h$")
# message("Definitions will be written to \"${OP_OUTPUT_FILE}\"")
# file(WRITE "${OP_OUTPUT_FILE}" "#ifndef SD_DEFINITIONS_GEN_H_\n#define SD_DEFINITIONS_GEN_H_\n${DEFINITIONS_CONTENT}\n#endif\n")
# endif()
# Architecture Tuning
if(SD_ARCH MATCHES "armv8")
set(ARCH_TUNE "-march=${SD_ARCH}")
elseif(SD_ARCH MATCHES "armv7")
set(ARCH_TUNE "-march=${SD_ARCH} -mfpu=neon")
elseif(CMAKE_SYSTEM_NAME MATCHES "Aurora")
set_source_files_properties(./include/graph/impl/GraphHolder.cpp PROPERTIES COMPILE_FLAGS -g0)
elseif(SD_ARCH MATCHES "power*")
set(ARCH_TUNE "-mcpu=${SD_ARCH} -mtune=${SD_ARCH} -D__POWER")
elseif(SD_EXTENSION MATCHES "avx2")
message("Building AVX2 binary...")
set(ARCH_TUNE "-mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mprefetchwt1 -DSD_F16C=true -DF_AVX2=true")
check_cxx_compiler_flag("-mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store" NO_AVX256_SPLIT)
if(NO_AVX256_SPLIT)
set(ARCH_TUNE "${ARCH_TUNE} -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store")
endif()
else()
if("${SD_ARCH}" STREQUAL "x86-64")
message("Building x86_64 binary...")
set(ARCH_TYPE "generic")
add_compile_definitions(F_X64=true)
else()
set(ARCH_TYPE "${SD_ARCH}")
endif()
if(SD_EXTENSION MATCHES "avx512")
message("Building AVX512 binary...")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mavx512f -mavx512vl -mavx512bw -mavx512dq -mavx512cd -mbmi -mbmi2 -mprefetchwt1 -mclflushopt -mxsavec -mxsaves -DSD_F16C=true -DF_AVX512=true")
endif()
if(NOT WIN32 AND NOT SD_CUDA)
set(ARCH_TUNE "-march=${SD_ARCH} -mtune=${ARCH_TYPE}")
endif()
endif()
# Compiler-Specific Flags
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND SD_X86_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE}")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE}")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE} -O${SD_OPTIMIZATION_LEVEL} -fp-model fast")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE}")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_SYSTEM_NAME MATCHES "Aurora" AND NOT SD_CUDA)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE} ${INFORMATIVE_FLAGS} -std=c++11")
if(UNIX)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,$ORIGIN/,-z,--no-undefined,--verbose")
else()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,$ORIGIN/,--no-undefined,--verbose")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE AND NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic -Wl,-export-dynamic,--verbose")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -export-dynamic,--verbose")
endif()
if("${SD_GCC_FUNCTRACE}" STREQUAL "ON")
# See: https://github.com/bombela/backward-cpp
# Check if compiler is nvcc or nvcc_wrapper
set(COMPILER_IS_NVCC false)
get_filename_component(COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME)
if(COMPILER_NAME MATCHES "^nvcc")
set(COMPILER_IS_NVCC TRUE)
endif()
if(DEFINED ENV{OMPI_CXX} OR DEFINED ENV{MPICH_CXX})
if("$ENV{OMPI_CXX}" MATCHES "nvcc" OR "$ENV{MPICH_CXX}" MATCHES "nvcc")
set(COMPILER_IS_NVCC TRUE)
endif()
endif()
# Set C++ standard
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
if(COMPILER_IS_NVCC)
# GNU C++ extensions are not supported by nvcc
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
# Set C++ compiler and flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector -fstack-protector-all -Wall -Wextra -Werror -Wno-return-type -Wno-error=int-in-bool-context -Wno-unused-variable -Wno-error=implicit-fallthrough -Wno-return-type -Wno-unused-parameter -Wno-error=unknown-pragmas -ggdb3 -lpthread -pthread -MT -Bsymbolic -lbfd -rdynamic -lunwind -ldw -ldl -fno-omit-frame-pointer -fno-optimize-sibling-calls -rdynamic -finstrument-functions -O0 -fPIC")
add_compile_definitions(SD_GCC_FUNCTRACE)
endif()
endif()
# Ensure SD_CPU is TRUE if neither SD_CUDA nor SD_CPU is set
if(NOT SD_CUDA)
if(NOT SD_CPU)
set(SD_CUDA FALSE)
set(SD_CPU TRUE)
endif()
endif()
# Set SD_LIBRARY_NAME Based on Build Type
if(NOT DEFINED SD_LIBRARY_NAME)
if(SD_CUDA)
set(SD_LIBRARY_NAME nd4jcuda)
else()
set(SD_LIBRARY_NAME nd4jcpu)
endif()
endif()
# Set default engine
if(SD_CUDA)
set(DEFAULT_ENGINE "samediff::ENGINE_CUDA")
else()
set(DEFAULT_ENGINE "samediff::ENGINE_CPU")
endif()
# MSVC runtime lib can be either "MultiThreaded" or "MultiThreadedDLL", /MT and /MD respectively
set(MSVC_RT_LIB "MultiThreadedDLL")
# Determine platform type more accurately
set(SD_X86_BUILD false)
set(SD_ARM_BUILD false)
if(SD_ANDROID_BUILD)
# For Android, trust ANDROID_ABI
if(ANDROID_ABI MATCHES "x86_64")
set(SD_X86_BUILD true)
set(SD_ARCH "x86-64")
elseif(ANDROID_ABI MATCHES "x86")
set(SD_X86_BUILD true)
set(SD_ARCH "x86")
elseif(ANDROID_ABI MATCHES "arm64-v8a")
set(SD_ARM_BUILD true)
set(SD_ARCH "arm64-v8a")
elseif(ANDROID_ABI MATCHES "armeabi-v7a")
set(SD_ARM_BUILD true)
set(SD_ARCH "armv7-a")
endif()
elseif(NOT SD_IOS_BUILD)
# Non-Android, Non-iOS logic
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64")
set(SD_X86_BUILD true)
if(NOT DEFINED SD_ARCH)
set(SD_ARCH "x86-64")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm*|aarch64")
set(SD_ARM_BUILD true)
endif()
endif()
message(STATUS "Build flags determined: SD_ANDROID_BUILD=${SD_ANDROID_BUILD}, SD_X86_BUILD=${SD_X86_BUILD}, SD_ARM_BUILD=${SD_ARM_BUILD}, SD_ARCH=${SD_ARCH}")
# Platform specific compiler flags
if(SD_ANDROID_BUILD)
set_property(GLOBAL PROPERTY JOB_POOLS one_job=1 two_jobs=2)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O${SD_OPTIMIZATION_LEVEL} -fPIC -Wno-return-type -Wno-unknown-pragmas -Wno-braced-scalar-init -Wno-delete-non-virtual-dtor -Wno-unused-command-line-argument -Wno-dangling-else -D_RELEASE=true")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O${SD_OPTIMIZATION_LEVEL} -g -fPIC -Wno-return-type -Wno-unknown-pragmas -Wno-braced-scalar-init -Wno-delete-non-virtual-dtor -Wno-unused-command-line-argument -Wno-dangling-else")
elseif(APPLE)
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64*" OR "${SD_ARCH}" MATCHES "armv8-a")
set(SD_ARCH armv8-a)
set(SD_X86_BUILD false)
set(CMAKE_OSX_ARCHITECTURES "arm64")
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-O${SD_OPTIMIZATION_LEVEL} -fPIC -Wno-return-type -Wno-braced-scalar-init -Wno-unknown-pragmas -Wno-delete-non-virtual-dtor -Wno-unused-command-line-argument -Wno-dangling-else -D__APPLE_OS__=true -D_RELEASE=true")
set(CMAKE_CXX_FLAGS_DEBUG " -O${SD_OPTIMIZATION_LEVEL} -g -fPIC -Wno-return-type -Wno-braced-scalar-init -Wno-unknown-pragmas -Wno-delete-non-virtual-dtor -Wno-unused-command-line-argument -Wno-dangling-else -D__APPLE_OS__=true")
elseif(WIN32)
set(SD_X86_BUILD true)
if(SD_CUDA)
set(CMAKE_CXX_FLAGS_RELEASE "-D_RELEASE=true")
set(CMAKE_CXX_FLAGS_DEBUG " /FS /EHsc")
else()
set(CMAKE_CXX_FLAGS_RELEASE "-O${SD_OPTIMIZATION_LEVEL} -fPIC -D_RELEASE=true")
set(CMAKE_CXX_FLAGS_DEBUG " -g -O${SD_OPTIMIZATION_LEVEL} -fPIC")
endif()
else()
if("${SD_GCC_FUNCTRACE}" STREQUAL "ON")
set(CMAKE_CXX_FLAGS_RELEASE "-O${SD_OPTIMIZATION_LEVEL} -fPIC -g")
else()
set(CMAKE_CXX_FLAGS_RELEASE "-O${SD_OPTIMIZATION_LEVEL} -fPIC -D_RELEASE=true")
endif()
set(CMAKE_CXX_FLAGS_DEBUG " -g -O${SD_OPTIMIZATION_LEVEL} -fPIC")
if(SD_SANITIZE)
set(SANITIZE_FLAGS " -Wall -Wextra -fPIE -lpthread -ftls-model=local-dynamic -static-libasan -fsanitize=${SD_SANITIZERS} -fno-sanitize-recover=all")
message("Using sanitizers: ${SD_SANITIZERS} - note you can not use both thread and address sanitizer at the same time. Be careful what sanitizers you specify.
Note that address and undefined can not be used at the same time or an address overlap error will occur. See: https://github.com/google/sanitizers/issues/856
FOR THREADS USE: thread,undefined,float-divide-by-zero,float-cast-overflow
FOR ADDRESS USE: address,undefined,float-divide-by-zero,float-cast-overflow")
if(SD_CPU)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
endif()
if(SD_CUDA)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS} -lpthread -ftls-model=local-dynamic --relocatable-device-code=true")
endif()
endif()
endif()
if(SD_NATIVE)
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64*" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64*")
set(SD_X86_BUILD false)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
endif()
# External Include Directories
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
list(APPEND EXTERNAL_INCLUDE_DIRS "/usr/include" "/usr/local/include")
endif()
# Initialize job pools for parallel builds
set_property(GLOBAL PROPERTY JOB_POOLS one_jobs=1 two_jobs=2)
# Common functions for both CPU and CUDA builds
# removeFileIfExcluded: removes the file from the given glob list
function(removeFileIfExcluded)
cmake_parse_arguments(
PARSED_ARGS
""
"FILE_ITEM"
"LIST_ITEM"
${ARGN}
)
file(READ ${PARSED_ARGS_FILE_ITEM} FILE_CONTENTS)
string(FIND "${FILE_CONTENTS}" "NOT_EXCLUDED" NOT_EXCLUDED_IDX)
if(${NOT_EXCLUDED_IDX} GREATER_EQUAL 0)
set(local_list ${${PARSED_ARGS_LIST_ITEM}})
set(file_removed FALSE)
foreach(OP ${SD_OPS_LIST})
string(FIND "${FILE_CONTENTS}" "NOT_EXCLUDED(OP_${OP})" NOT_EXCLUDED_OP_IDX)
if(${NOT_EXCLUDED_OP_IDX} LESS 0)
list(REMOVE_ITEM local_list "${PARSED_ARGS_FILE_ITEM}")
set(file_removed TRUE)
break()
endif()
endforeach()
if(file_removed)
set(${PARSED_ARGS_LIST_ITEM} ${local_list} PARENT_SCOPE)
endif()
endif()
endfunction()
function(genCompilation FL_ITEM)
get_filename_component(FILE_ITEM_WE ${FL_ITEM} NAME_WE)
set(EXTENSION "cpp")
if(FL_ITEM MATCHES "cu.in$")
set(EXTENSION "cu")
endif()
file(READ ${FL_ITEM} CONTENT_FL)
# Set all flags to false initially
set(SD_FLOAT_TYPES_GEN 0)
set(SD_INTEGER_TYPES_GEN 0)
set(SD_COMMON_TYPES_GEN 0)
set(SD_PAIRWISE_TYPES_GEN 0)
set(RANGE_STOP -1)
string(REGEX MATCHALL "#cmakedefine[ \t]+SD_(INTEGER|COMMON|FLOAT|PAIRWISE)_TYPES_GEN" TYPE_MATCHES ${CONTENT_FL})
# Define range limits
set(SD_INTEGER_TYPES_END 7)
set(SD_COMMON_TYPES_END 12)
set(SD_FLOAT_TYPES_END 3)
set(SD_PAIRWISE_TYPES_END 12)
# Process matches and set flags
foreach(TYPEX ${TYPE_MATCHES})
set(STOP -1)
if(TYPEX MATCHES "SD_INTEGER_TYPES_GEN$")
set(SD_INTEGER_TYPES_GEN 1)
set(STOP ${SD_INTEGER_TYPES_END})
endif()
if(TYPEX MATCHES "SD_COMMON_TYPES_GEN$")
set(SD_COMMON_TYPES_GEN 1)
set(STOP ${SD_COMMON_TYPES_END})
endif()
if(TYPEX MATCHES "SD_FLOAT_TYPES_GEN$")
set(SD_FLOAT_TYPES_GEN 1)
set(STOP ${SD_FLOAT_TYPES_END})
endif()
if(TYPEX MATCHES "SD_PAIRWISE_TYPES_GEN$")
set(SD_PAIRWISE_TYPES_GEN 1)
set(STOP ${SD_PAIRWISE_TYPES_END})
endif()
if(STOP GREATER RANGE_STOP)
set(RANGE_STOP ${STOP})
endif()
endforeach()
# Create output directory
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/compilation_units")
# Generate files in a single pass - just like the original
if(RANGE_STOP GREATER -1)
foreach(FL_TYPE_INDEX RANGE 0 ${RANGE_STOP})
# Reset flags if index exceeds limits - directly modify the variables
if(FL_TYPE_INDEX GREATER ${SD_FLOAT_TYPES_END})
set(SD_FLOAT_TYPES_GEN 0)
endif()
if(FL_TYPE_INDEX GREATER ${SD_INTEGER_TYPES_END})
set(SD_INTEGER_TYPES_GEN 0)
endif()
if(FL_TYPE_INDEX GREATER ${SD_COMMON_TYPES_END})
set(SD_COMMON_TYPES_GEN 0)
endif()
# Generate the file unconditionally
set(GENERATED_SOURCE "${CMAKE_BINARY_DIR}/compilation_units/${FILE_ITEM_WE}_${FL_TYPE_INDEX}.${EXTENSION}")
configure_file("${FL_ITEM}" "${GENERATED_SOURCE}" @ONLY)
list(APPEND CUSTOMOPS_GENERIC_SOURCES ${GENERATED_SOURCE})
endforeach()
endif()
# Pass the updated list to parent scope
set(CUSTOMOPS_GENERIC_SOURCES ${CUSTOMOPS_GENERIC_SOURCES} PARENT_SCOPE)
endfunction()
# genPartitionCombination: Generates combination files for CPU
function(genPartitionCombination TEMPLATE_FILE COMBINATION_TYPE COMBINATION OUTPUT_DIR)
# Split combination string into a list
string(REPLACE "," ";" COMB_LIST "${COMBINATION}")
# Determine number of elements
list(LENGTH COMB_LIST COMB_COUNT)
# Validate combination
if(NOT (COMBINATION_TYPE EQUAL 3 OR COMBINATION_TYPE EQUAL 2))
message(FATAL_ERROR "Unsupported COMBINATION_TYPE: ${COMBINATION_TYPE}. Use 3 or 2.")
endif()
if(NOT ((COMBINATION_TYPE EQUAL 3 AND COMB_COUNT EQUAL 3) OR
(COMBINATION_TYPE EQUAL 2 AND COMB_COUNT EQUAL 2)))
message(FATAL_ERROR "Combination length (${COMB_COUNT}) does not match COMBINATION_TYPE (${COMBINATION_TYPE}).")
endif()
# Define placeholders based on combination type
if(COMBINATION_TYPE EQUAL 3)
list(GET COMB_LIST 0 COMB1)
list(GET COMB_LIST 1 COMB2)
list(GET COMB_LIST 2 COMB3)
set(PLACEHOLDER1 "@COMB1@")
set(PLACEHOLDER2 "@COMB2@")
set(PLACEHOLDER3 "@COMB3@")
elseif(COMBINATION_TYPE EQUAL 2)
list(GET COMB_LIST 0 COMB1)
list(GET COMB_LIST 1 COMB2)
set(PLACEHOLDER1 "@COMB1@")
set(PLACEHOLDER2 "@COMB2@")
endif()
# Read the template content
file(READ "${TEMPLATE_FILE}" TEMPLATE_CONTENT)
# Perform placeholder replacements
if(COMBINATION_TYPE EQUAL 3)
string(REPLACE "${PLACEHOLDER1}" "${COMB1}" TEMP_CONTENT "${TEMPLATE_CONTENT}")
string(REPLACE "${PLACEHOLDER2}" "${COMB2}" TEMP_CONTENT "${TEMP_CONTENT}")
string(REPLACE "${PLACEHOLDER3}" "${COMB3}" FINAL_CONTENT "${TEMP_CONTENT}")
elseif(COMBINATION_TYPE EQUAL 2)
string(REPLACE "${PLACEHOLDER1}" "${COMB1}" FINAL_CONTENT "${TEMPLATE_CONTENT}")
string(REPLACE "${PLACEHOLDER2}" "${COMB2}" FINAL_CONTENT "${FINAL_CONTENT}")
endif()
# Define the output file name based on combination
get_filename_component(TEMPLATE_BASE "${TEMPLATE_FILE}" NAME_WE) # Get base name like "pairwise_instantiation_template_2"
string(REPLACE "_template_" "_" OUTPUT_BASE_NAME "${TEMPLATE_BASE}") # Make it shorter like "pairwise_instantiation_2"
if(COMBINATION_TYPE EQUAL 3)
set(OUTPUT_FILE "${OUTPUT_BASE_NAME}_${COMB1}_${COMB2}_${COMB3}.cpp")
elseif(COMBINATION_TYPE EQUAL 2)
set(OUTPUT_FILE "${OUTPUT_BASE_NAME}_${COMB1}_${COMB2}.cpp")
endif()
# Define the full path for the generated file
set(GENERATED_FILE "${OUTPUT_DIR}/${OUTPUT_FILE}")
# Write the processed content to the output file
file(WRITE "${GENERATED_FILE}" "${FINAL_CONTENT}")
# Optionally, collect generated sources for further processing
list(APPEND CUSTOMOPS_GENERIC_SOURCES "${GENERATED_FILE}")
set(CUSTOMOPS_GENERIC_SOURCES ${CUSTOMOPS_GENERIC_SOURCES} PARENT_SCOPE) # Pass back up
# Output a message for verification
message(STATUS "Generated Instantiation File: ${GENERATED_FILE}")
endfunction()
# genSingleFunctionCuda: Generate individual CUDA files for each type combination
function(genSingleFunctionCuda TEMPLATE_FILE COMBINATION OUTPUT_DIR)
# Split the COMBINATION string into a list
string(REPLACE "," ";" COMB_LIST "${COMBINATION}")
# Extract combination values
list(GET COMB_LIST 0 COMB1)
list(GET COMB_LIST 1 COMB2)
list(GET COMB_LIST 2 COMB3)
# Get the base name from the template file
get_filename_component(TEMPLATE_BASE "${TEMPLATE_FILE}" NAME_WE)
# Read the template content
file(READ "${TEMPLATE_FILE}" TEMPLATE_CONTENT)
# Extract class and method names using regex
string(REGEX MATCH "([a-zA-Z0-9_:]+),[ \n\t]*::([a-zA-Z0-9_]+)" FUNCTION_MATCH "${TEMPLATE_CONTENT}")
set(CLASS_NAME ${CMAKE_MATCH_1})
set(METHOD_NAME ${CMAKE_MATCH_2})
# Clean class name for file naming
string(REGEX REPLACE "::" "_" CLASS_NAME_CLEAN "${CLASS_NAME}")
# Extract function signature to create a hash
string(REGEX MATCH "::${METHOD_NAME}\\(([^;]+)\\);" FUNC_ARGS_MATCH "${TEMPLATE_CONTENT}")
set(FUNCTION_ARGS "${CMAKE_MATCH_1}")
# Create a signature identifier based on parameter count and types
set(PARAM_COUNT 0)
set(SIGNATURE_ID "")
# Split the function arguments and count them
string(REPLACE "," ";" ARGS_LIST "${FUNCTION_ARGS}")
list(LENGTH ARGS_LIST PARAM_COUNT)
# Create a hash of the signature
foreach(ARG ${ARGS_LIST})
# Extract just the type name from the parameter
string(REGEX MATCH "^[^*& \t]+" TYPE_NAME "${ARG}")
if(TYPE_NAME)
# Append to the signature ID
string(APPEND SIGNATURE_ID "_${TYPE_NAME}")
endif()
endforeach()
# Create a shorter hash if the signature is too long
if(SIGNATURE_ID MATCHES ".{30,}")
string(MD5 SIGNATURE_HASH "${SIGNATURE_ID}")
string(SUBSTRING "${SIGNATURE_HASH}" 0 8 SIGNATURE_ID)
set(SIGNATURE_ID "_h${SIGNATURE_ID}")
endif()
# Output filename with signature identifier
set(OUTPUT_FILE "${CLASS_NAME_CLEAN}_${METHOD_NAME}${SIGNATURE_ID}_${COMB1}_${COMB2}_${COMB3}.cu")
set(GENERATED_FILE "${OUTPUT_DIR}/${OUTPUT_FILE}")
# Check if this file already exists - if so, no need to regenerate
if(EXISTS "${GENERATED_FILE}")
# Add to CUDA_GENERATED_SOURCES without regenerating
list(APPEND CUDA_GENERATED_SOURCES "${GENERATED_FILE}")
set(CUDA_GENERATED_SOURCES ${CUDA_GENERATED_SOURCES} PARENT_SCOPE)
return()
endif()
# Extract just the necessary header information
set(START_MARKER "ITERATE_COMBINATIONS_3")
string(FIND "${TEMPLATE_CONTENT}" "${START_MARKER}" START_POS)
if(START_POS EQUAL -1)
message(FATAL_ERROR "Could not find ITERATE_COMBINATIONS_3 in template file ${TEMPLATE_FILE}")
endif()
string(SUBSTRING "${TEMPLATE_CONTENT}" 0 ${START_POS} HEADER_CONTENT)
# Create streamlined content with just the single instantiation needed
set(NEW_CONTENT "${HEADER_CONTENT}\n\n// Single function instantiation for ${CLASS_NAME}::${METHOD_NAME}\n")
string(APPEND NEW_CONTENT "template void ${CLASS_NAME}::${METHOD_NAME}<SD_SINGLE_TYPE_${COMB1}, SD_SINGLE_TYPE_${COMB2}, SD_SINGLE_TYPE_${COMB3}>(${FUNCTION_ARGS});\n")
# Create directory if needed
file(MAKE_DIRECTORY "${OUTPUT_DIR}")
# Write the processed content to the output file
file(WRITE "${GENERATED_FILE}" "${NEW_CONTENT}")
# Set properties and add to sources
set_source_files_properties("${GENERATED_FILE}" PROPERTIES LANGUAGE CUDA)
list(APPEND CUDA_GENERATED_SOURCES "${GENERATED_FILE}")
set(CUDA_GENERATED_SOURCES ${CUDA_GENERATED_SOURCES} PARENT_SCOPE)
message(STATUS "Generated: ${GENERATED_FILE}")
endfunction()
# Configure BLAS for CPU builds
if(NOT SD_CUDA)
# We need this definition to avoid global memory use within onednn
add_definitions(-DDNNL_ENABLE_CONCURRENT_EXEC=true)
if("${OPENBLAS_PATH}" STREQUAL "")
# We don't want OpenBLAS on Apple
if(NOT APPLE)
# Note: this is not a typo
set(BLA_VENDOR "OpenBLAS")
endif()
# Look around for system blas
find_package(BLAS REQUIRED)
if(BLAS_FOUND)
message("Found external BLAS implementation: ${BLAS_LIBRARIES} ")
add_definitions(-D__EXTERNAL_BLAS__=true)
endif()
else()
# Use externally provided OPENBLAS_PATH
set(HAVE_OPENBLAS 1)
message("Setting openblas")
include_directories(${OPENBLAS_PATH}/include/)
link_directories(${OPENBLAS_PATH} ${OPENBLAS_PATH}/lib/)
set(OPENBLAS_LIBRARIES openblas)
endif()
endif()
# ARM Compute configuration
# Initialize variables to indicate ARM Compute is not yet configured
set(ARMCOMPUTE_LIBRARIES "")
set(HAVE_ARMCOMPUTE 0)
# Only attempt ARM Compute configuration if the helper flag is set
if(${HELPERS_armcompute})
# ===================================================================
# Manage ARM Compute Dependency using ExternalProject_Add
# ===================================================================
option(LIBND4J_BUILD_WITH_ARMCOMPUTE "Build with ARM Compute Library support" ON) # Make it optional if needed
if(LIBND4J_BUILD_WITH_ARMCOMPUTE AND (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm64|ARM64"))
message(STATUS "Configuring ARM Compute Library download using ExternalProject_Add")
include(ExternalProject)
# --- Configuration (Adjust these as needed) ---
set(ARMCOMPUTE_VERSION "v25.04") # Version from your logs
set(ARMCOMPUTE_ARCH "aarch64") # Arch from your logs
set(ARMCOMPUTE_PLATFORM "linux") # Platform from your logs
set(ARMCOMPUTE_FLAVOR "cpu") # Flavor from your logs
# Directory where headers/libs will be "installed" within the build tree
set(ARMCOMPUTE_INSTALL_DIR "${CMAKE_BINARY_DIR}/armcompute_install")
# Directory where ExternalProject will download/extract source archive
set(ARMCOMPUTE_SOURCE_DIR "${CMAKE_BINARY_DIR}/armcompute_external/src")
# Construct package name and URL (VERIFY THIS URL IS CORRECT!)
set(ARMCOMPUTE_PKG_NAME "arm_compute-${ARMCOMPUTE_VERSION}-${ARMCOMPUTE_PLATFORM}-${ARMCOMPUTE_ARCH}-${ARMCOMPUTE_FLAVOR}-bin")
set(ARMCOMPUTE_URL "https://github.com/ARM-software/ComputeLibrary/releases/download/${ARMCOMPUTE_VERSION}/${ARMCOMPUTE_PKG_NAME}.tar.gz")
# Subdirectory within the extracted archive containing the libs (based on your previous log)
# VERIFY this matches the actual archive structure.
set(ARMCOMPUTE_LIB_SUBDIR "lib/armv8a-neon")
ExternalProject_Add(armcompute_external # Define the external project target
PREFIX "${CMAKE_BINARY_DIR}/armcompute_external" # Base directory for EP build/tmp files
URL "${ARMCOMPUTE_URL}"
DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/downloads" # Cache downloads here
SOURCE_DIR "${ARMCOMPUTE_SOURCE_DIR}" # Where archive contents are extracted
# Since it's pre-built, no configure or build steps needed
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
# Define the "install" step: Copy needed files from extracted archive to our install dir
INSTALL_COMMAND ${CMAKE_COMMAND} -E remove_directory "${ARMCOMPUTE_INSTALL_DIR}" && # Clean first
# Copy headers
${CMAKE_COMMAND} -E copy_directory "${ARMCOMPUTE_SOURCE_DIR}/${ARMCOMPUTE_PKG_NAME}/include" "${ARMCOMPUTE_INSTALL_DIR}/include" &&
# Copy the specific library directory
${CMAKE_COMMAND} -E copy_directory "${ARMCOMPUTE_SOURCE_DIR}/${ARMCOMPUTE_PKG_NAME}/${ARMCOMPUTE_LIB_SUBDIR}" "${ARMCOMPUTE_INSTALL_DIR}/lib"
# Specify key output files to ensure the install step completes before dependents build
# Use library names/paths known to exist in the package. Adjust if needed.
BUILD_BYPRODUCTS "${ARMCOMPUTE_INSTALL_DIR}/include/arm_compute/core/CL/CLKernelLibrary.h"
"${ARMCOMPUTE_INSTALL_DIR}/lib/libarm_compute.so"
"${ARMCOMPUTE_INSTALL_DIR}/lib/libarm_compute_graph.so"
BUILD_IN_SOURCE 1 # Often needed if there's no real build step
)
# --- Define an INTERFACE Library ---
# This represents the ARM Compute dependency for other targets to link against.
add_library(armcompute_interface INTERFACE)
# Tell targets linking this where to find headers
target_include_directories(armcompute_interface INTERFACE "${ARMCOMPUTE_INSTALL_DIR}/include")
# Tell targets linking this where to find libraries (-L flag)
target_link_directories(armcompute_interface INTERFACE "${ARMCOMPUTE_INSTALL_DIR}/lib")
# Specify libraries to link (-l flag names derived from lib*.so)
target_link_libraries(armcompute_interface INTERFACE arm_compute arm_compute_graph)
# Crucial: Make the interface target depend on the external project completing its install step.
add_dependencies(armcompute_interface armcompute_external)
# Set a variable to indicate ARM Compute is available via this method
set(ARMCOMPUTE_FOUND TRUE)
set(ARMCOMPUTE_INCLUDE_DIRS "${ARMCOMPUTE_INSTALL_DIR}/include") # For potential backward compatibility checks, not strictly needed
set(ARMCOMPUTE_LIBRARIES armcompute_interface) # The target name representing the libraries
else()
message(STATUS "Skipping ARM Compute setup via ExternalProject_Add (disabled or not AArch64)")
set(ARMCOMPUTE_FOUND FALSE)
endif()
# ===================================================================
endif()
if(NOT DEFINED ONEDNN_PROCESSING_DONE)
set(ONEDNN_PROCESSING_DONE FALSE CACHE INTERNAL "Flag to indicate OneDNN processing status")
endif()
if(${HELPERS_onednn})
include(ExternalProject)
message(STATUS "Configuring OneDNN dependency using ExternalProject_Add")
set(HAVE_ONEDNN TRUE) # Assume success initially, ExternalProject handles failure
# Define directories for OneDNN within the build tree
set(ONEDNN_INSTALL_DIR "${CMAKE_BINARY_DIR}/onednn_install") # Where headers/libs will be installed
set(ONEDNN_SOURCE_DIR "${CMAKE_BINARY_DIR}/onednn_external/src") # Where source code will be cloned
set(ONEDNN_BUILD_DIR "${CMAKE_BINARY_DIR}/onednn_external/build") # Where OneDNN will be built
# --- Add OneDNN using ExternalProject_Add ---
ExternalProject_Add(onednn_external # Define the external project target
PREFIX "${CMAKE_BINARY_DIR}/onednn_external" # Base directory for EP build/tmp files
GIT_REPOSITORY "https://github.com/KonduitAI/oneDNN.git" # Use the correct repo
GIT_TAG "master" # Or a specific commit/tag for stability
SOURCE_DIR "${ONEDNN_SOURCE_DIR}"
BINARY_DIR "${ONEDNN_BUILD_DIR}" # Explicitly set build directory
# --- CMake Configuration Step ---
# Pass necessary options to OneDNN's CMake configuration
# Ensure CMAKE_INSTALL_PREFIX directs install artifacts correctly
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${ONEDNN_INSTALL_DIR}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DDNNL_LIBRARY_TYPE=STATIC # Build static library
-DDNNL_BUILD_TESTS=OFF # Disable tests
-DDNNL_BUILD_EXAMPLES=OFF # Disable examples
-DDNNL_VERBOSE=OFF # Disable verbose build unless debugging
# Add other necessary flags like compiler paths or toolchains if needed for cross-compilation
# Example for cross-compiling: -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
# --- Build Step ---
# Use CMake's build command
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config ${CMAKE_BUILD_TYPE}
# --- Install Step ---
# Use CMake's install command targeting the prefix defined in CMAKE_ARGS
INSTALL_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target install --config ${CMAKE_BUILD_TYPE}
# --- Specify key output files ---
# These ensure the install step completes before dependents build.
# Adjust paths/names if OneDNN's install structure changes.
BUILD_BYPRODUCTS "${ONEDNN_INSTALL_DIR}/include/dnnl.h"
"${ONEDNN_INSTALL_DIR}/lib/libdnnl.a" # Assuming static lib name
# --- Logging ---
LOG_DOWNLOAD ON
LOG_CONFIGURE ON
LOG_BUILD ON
LOG_INSTALL ON
)
# --- Define an INTERFACE Library for OneDNN ---
# This represents the OneDNN dependency for other targets (like libnd4j) to link against.
add_library(onednn_interface INTERFACE)
# Tell targets linking this where to find OneDNN headers
target_include_directories(onednn_interface INTERFACE
"${ONEDNN_INSTALL_DIR}/include"
)
# Tell targets linking this the full path to the static library to link
# For static libraries, linking the full path is often necessary.
# Adjust the library name/extension (.a/.lib) based on the platform if needed.
target_link_libraries(onednn_interface INTERFACE
"${ONEDNN_INSTALL_DIR}/lib/libdnnl.a"
)
# Crucial: Make the interface target depend on the external project completing its install step.
add_dependencies(onednn_interface onednn_external)
# Set the variable used later in target_link_libraries for libnd4j
set(ONEDNN onednn_interface) # Use the interface library target name
message(STATUS "OneDNN configured via ExternalProject_Add. Build artifacts will be in ${ONEDNN_INSTALL_DIR}")
else()
message(STATUS "Skipping OneDNN setup via ExternalProject_Add (HELPERS_onednn is OFF)")
set(HAVE_ONEDNN FALSE)
set(ONEDNN "") # Ensure variable is empty if not used
endif()
# cuDNN configuration
if(${HELPERS_cudnn})
if(NOT SD_CUDA)
message(FATAL_ERROR "Can't build cuDNN on non-CUDA platform")
endif()
SET(CUDNN_LIBNAME "cudnn")
if(DEFINED ENV{CUDNN_ROOT_DIR})
message("Using cudnn root directory from environment")
set(CUDNN_ROOT_DIR $ENV{CUDNN_ROOT_DIR})
endif()
if(DEFINED ENV{CUDA_TOOLKIT_ROOT_DIR})
message("Using cuda root directory from environment")
set(CUDA_TOOLKIT_ROOT_DIR $ENV{CUDA_TOOLKIT_ROOT_DIR})
endif()
message("Cudnn root dir ${CUDNN_ROOT_DIR} CUDA TOOLKIT ROOT DIR ${CUDA_TOOLKIT_ROOT_DIR}")
# Look for cuDNN in multiple potential locations
find_path(CUDNN_INCLUDE_DIR cudnn.h
HINTS
${CUDNN_ROOT_DIR}
${CUDA_TOOLKIT_ROOT_DIR}
/usr/local/cuda
ENV CUDNN_ROOT_DIR
ENV CUDA_TOOLKIT_ROOT_DIR
PATH_SUFFIXES
cuda/include
include
include/cuda)
find_library(CUDNN_LIBRARY ${CUDNN_LIBNAME}
HINTS
${CUDNN_ROOT_DIR}
${CUDA_TOOLKIT_ROOT_DIR}
/usr/local/cuda
ENV CUDNN_ROOT_DIR
ENV CUDA_TOOLKIT_ROOT_DIR
PATH_SUFFIXES
lib
lib64
cuda/lib
cuda/lib64
cuda/lib/x64
lib/x64)
# Debug output to help diagnose the issue
message("CUDNN_INCLUDE_DIR search result: ${CUDNN_INCLUDE_DIR}")
message("CUDNN_LIBRARY search result: ${CUDNN_LIBRARY}")
if(CUDNN_LIBRARY AND CUDNN_INCLUDE_DIR)
message("Found cuDNN: include at ${CUDNN_INCLUDE_DIR}, library at ${CUDNN_LIBRARY}")
include_directories(${CUDNN_INCLUDE_DIR})
set(HAVE_CUDNN true)
set(CUDNN ${CUDNN_LIBRARY})
else()
# More detailed error message but continue with build
message(WARNING "cuDNN not found. Continuing without cuDNN support.")
message("Searched for include in: ${CUDNN_ROOT_DIR}, ${CUDA_TOOLKIT_ROOT_DIR}, and system paths")
message("Searched for library '${CUDNN_LIBNAME}' in: ${CUDNN_ROOT_DIR}, ${CUDA_TOOLKIT_ROOT_DIR}, and system paths")
set(HAVE_CUDNN false)
endif()
endif()
# Flatbuffers configuration
if(DEFINED ENV{GENERATE_FLATC} OR DEFINED GENERATE_FLATC)
set(FLATBUFFERS_BUILD_FLATC "ON" CACHE STRING "Enable flatc build" FORCE)
else()
set(FLATBUFFERS_BUILD_FLATC "OFF" CACHE STRING "Disable flatc build" FORCE)
endif()
# Flatbuffers download
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-download-complete.marker")
configure_file(CMakeLists.txt.in flatbuffers-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-download)
if(result)
message(FATAL_ERROR "CMake step for flatbuffers failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-download)
if(result)
message(FATAL_ERROR "Build step for flatbuffers failed: ${result}")
endif()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-download-complete.marker" "Download complete")
else()
message(STATUS "Flatbuffers already downloaded, skipping download step")
endif()
# Add flatbuffers directly to build
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src
${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build
EXCLUDE_FROM_ALL)
# Flatbuffers generation
if(DEFINED ENV{GENERATE_FLATC} OR DEFINED GENERATE_FLATC)
# First, ensure flatc is built
execute_process(
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build --target flatc
RESULT_VARIABLE FLATC_BUILD_RESULT
)
if(FLATC_BUILD_RESULT)
message(FATAL_ERROR "Failed to build flatc: ${FLATC_BUILD_RESULT}")
endif()
set(FLATC_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build/flatc")
message("Using flatc from: ${FLATC_EXECUTABLE}")
# Create required directories
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
${CMAKE_CURRENT_SOURCE_DIR}/include/graph/generated
${CMAKE_CURRENT_SOURCE_DIR}/include/graph/generated/sd
)
# Run flatc generation
execute_process(
COMMAND ${CMAKE_COMMAND} -E env "FLATC_PATH=${FLATC_EXECUTABLE}"
bash ${CMAKE_CURRENT_SOURCE_DIR}/flatc-generate.sh
RESULT_VARIABLE FLATC_RESULT
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if(FLATC_RESULT)
message(FATAL_ERROR "Flatbuffer generation failed: ${FLATC_RESULT}")
endif()
# Copy Java files
execute_process(
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/copy-flatc-java.sh
RESULT_VARIABLE COPY_RESULT
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if(COPY_RESULT)
message(FATAL_ERROR "Java file copying failed: ${COPY_RESULT}")
endif()
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src/include)
# Configuration file
configure_file(include/config.h.in include/config.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# Set type combinations for CUDA generation
# Set type combinations for CUDA generation
set(COMBINATIONS_3
"0,0,0"
"0,0,1"
"0,0,2"
"0,1,0"
"0,1,1"
"0,1,2"
"0,2,0"
"0,2,1"
"0,2,2"
"1,0,0"
"1,0,1"
"1,0,2"
"1,1,0"
"1,1,1"
"1,1,2"
"1,2,0"
"1,2,1"
"1,2,2"
"2,0,0"
"2,0,1"
"2,0,2"
"2,1,0"
"2,1,1"
"2,1,2"
"2,2,0"
"2,2,1"
"2,2,2"
)
set(COMBINATIONS_2
"0,0"
"0,1"
"1,0"
"1,1"
"0,2"
"2,0"
"1,2"
"2,1"
"2,2"
)
# Define template locations
set(INSTANTIATION_TEMPLATES_3
"${CMAKE_CURRENT_SOURCE_DIR}/include/loops/cpu/comb_compilation_units/pairwise_instantiation_template_3.cpp.in"
)
set(INSTANTIATION_TEMPLATES_2
"${CMAKE_CURRENT_SOURCE_DIR}/include/loops/cpu/comb_compilation_units/pairwise_instantiation_template_2.cpp.in"
"${CMAKE_CURRENT_SOURCE_DIR}/include/ops/impl/compilation_units/specials_double.cpp.in"
"${CMAKE_CURRENT_SOURCE_DIR}/include/ops/impl/compilation_units/specials_single.cpp.in"
)
# CUDA Configuration
if(SD_CUDA)
message("Building with CUDA support")
# Platform-specific settings
if(WIN32)
message("Setting up Windows-specific CUDA unsupported compiler flags")
else()
message("Setting up Linux-specific CUDA unsupported compiler flags")
endif()
# Enable CUDA language
enable_language(CUDA)
add_definitions(-D__CUDABLAS__=true)
find_package(CUDA REQUIRED)
if(CUDA_FOUND)
message("CUDA include directory: ${CUDA_INCLUDE_DIRS} with CXX compiler ${CMAKE_CXX_COMPILER_ID} SD_GCC_FUNCTRACE=${SD_GCC_FUNCTRACE}")
include_directories(${CUDA_INCLUDE_DIRS})
message("CUDA found!")
set(CMAKE_CUDA_FLAGS_DEBUG " -g")
message("CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
# Add --allow-unsupported-compiler to CUDA flags
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --allow-unsupported-compiler")
if("${SD_PTXAS}" STREQUAL "ON")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --ptxas-options=-v")
endif()
if(SD_KEEP_NVCC_OUTPUT)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --keep")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(SD_GCC_FUNCTRACE STREQUAL "ON")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wno-return-type -Wno-unknown-pragmas -Wno-unused-variable -Wno-unused-parameter -Wreturn-type -W -ggdb3 -fPIC -DSD_GCC_FUNCTRACE=1 -Bsymbolic -lbfd -rdynamic -lunwind -ldw -ldl -fno-omit-frame-pointer -fno-optimize-sibling-calls -finstrument-functions -O0")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=-fPIC --device-debug -lineinfo -G")
add_compile_definitions(SD_GCC_FUNCTRACE)
else()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=-fPIC")
endif()
endif()
if(WIN32)
message("Configuring CUDA libraries for Windows")
if(NOT DEFINED CUDA_cublas_LIBRARY)
set(CUDA_cublas_LIBRARY "${CUDA_HOME}/lib/x64/cublas.lib")
endif()
if(NOT DEFINED CUDA_cusolver_LIBRARY)
set(CUDA_cusolver_LIBRARY "${CUDA_HOME}/lib/x64/cusolver.lib")
endif()
endif()
if("${SD_ARCH}" MATCHES "armv8-a" AND UNIX)
message("Adding Jetson Nano specific settings")
if(NOT DEFINED CUDA_cublas_LIBRARY OR "${CUDA_cublas_LIBRARY}" MATCHES ".*NOTFOUND.*" )
message("Setting cublas library manually")
set(CUDA_cublas_LIBRARY "$ENV{loc_DIR}/cuda/targets/aarch64-linux/lib/stubs/libcublas.so" CACHE STRING "CUDA CUBLAS LIB" FORCE)
unset(CUDA_cublas-NOTFOUND CACHE)
unset(CUDA_cublas_LIBRARY-NOTFOUND CACHE)
unset(CUDA_cublas_LIBRARY-NOTFOUND PARENT_SCOPE)
endif()
if(NOT DEFINED CUDA_cusolver_LIBRARY OR CUDA_cusolver_LIBRARY MATCHES ".*NOTFOUND.*")
message("Setting cusolver library manually for Jetson Nano")
set(CUDA_cusolver_LIBRARY "$ENV{loc_DIR}/cuda/targets/aarch64-linux/lib/stubs/libcusolver.so" CACHE STRING "CUDA CUSOLVER LIB" FORCE)
unset(CUDA_cusolver-NOTFOUND CACHE)
unset(CUDA_cusolver_LIBRARY-NOTFOUND CACHE)
unset(CUDA_cusolver_LIBRARY-NOTFOUND PARENT_SCOPE)
endif()
message("Jetson Nano cublas library: ${CUDA_cublas_LIBRARY}, cusolver library: ${CUDA_cusolver_LIBRARY}")
endif()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -maxrregcount=128")
string(TOLOWER "${COMPUTE}" COMPUTE_CMP)
if(COMPUTE_CMP STREQUAL "all")
# Updated architecture flags for CUDA 12.3
set(CUDA_ARCH_FLAGS "-gencode arch=compute_86,code=sm_86 -gencode arch=compute_89,code=sm_89 -gencode arch=compute_90,code=sm_90")
elseif(COMPUTE_CMP STREQUAL "auto")
CUDA_SELECT_NVCC_ARCH_FLAGS(CUDA_ARCH_FLAGS "Auto")
else()
CUDA_SELECT_NVCC_ARCH_FLAGS(CUDA_ARCH_FLAGS "${COMPUTE}")
string(REPLACE ";" " " CUDA_ARCH_FLAGS "${TMP_CUDA_ARCH_FLAGS}") # Force replace ; with space
endif()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -lcuda -lcudart -DCUDA_VERSION_MAJOR=${CUDA_VERSION_MAJOR} -w --cudart=shared --expt-extended-lambda -Xfatbin -compress-all ${CUDA_ARCH_FLAGS}") # Added CUDA_ARCH_FLAGS
message("Final CUDA flags: ${CMAKE_CUDA_FLAGS}")
if(WIN32)
message("Setting up Windows-specific CUDA unsupported compiler flags")
else()
message("Setting up Linux-specific CUDA unsupported compiler flags")
endif()
add_compile_definitions(SD_CUDA=true)
set(DEFAULT_ENGINE "samediff::ENGINE_CUDA")
# Gather CUDA source files
file(GLOB_RECURSE PERF_SOURCES ./include/performance/*.cpp ./include/performance/*.h)
file(GLOB_RECURSE EXCEPTIONS_SOURCES ./include/exceptions/*.cpp ./include/exceptions/*.h)
file(GLOB_RECURSE EXEC_SOURCES ./include/execution/impl/*.cpp ./include/execution/cuda/*.cu ./include/execution/cuda/*.h ./include/execution/*.cu ./include/execution/*.h)
file(GLOB_RECURSE TYPES_SOURCES ./include/types/*.cpp ./include/types/*.h)
file(GLOB_RECURSE ARRAY_SOURCES ./include/array/cuda/*.cu ./include/array/cuda/*.chpp ./include/array/impl/*.cpp ./include/array/cuda/*.cu ./include/array/*.h)
file(GLOB_RECURSE MEMORY_SOURCES ./include/memory/impl/*.cpp ./include/memory/cuda/*.cu ./include/memory/*.h)
file(GLOB_RECURSE GRAPH_SOURCES ./include/graph/*.cpp ./include/graph/*.cu ./include/graph/*.h)
file(GLOB_RECURSE CUSTOMOPS_SOURCES ./include/ops/declarable/generic/*.cpp)
file(GLOB_RECURSE CUSTOMOPS_HELPERS_SOURCES ./include/ops/declarable/helpers/cuda/*.cu ./include/ops/declarable/helpers/impl/*.cpp)
file(GLOB_RECURSE OPS_SOURCES ./include/ops/impl/*.cpp ./include/ops/declarable/impl/*.cpp ./include/ops/*.h)
file(GLOB_RECURSE HELPERS_SOURCES
./include/build_info.cpp
./include/ConstMessages.cpp
./include/helpers/*.cpp
./include/helpers/cuda/*.cu
./include/helpers/*.h)
file(GLOB CPU_HELPERS_TO_EXCLUDE
./include/helpers/cpu/*.cpp)
list(REMOVE_ITEM HELPERS_SOURCES ${CPU_HELPERS_TO_EXCLUDE})
file(GLOB_RECURSE INDEXING_SOURCES ./include/indexing/*.cpp ./include/indexing/*.h)
file(GLOB_RECURSE LOOPS_SOURCES ./include/loops/impl/*.cpp ./include/loops/*.h)
file(GLOB_RECURSE LEGACY_SOURCES ./include/legacy/impl/*.cpp ./include/legacy/*.cu ./include/legacy/*.h)
file(GLOB_RECURSE LOOPS_SOURCES_CUDA ./include/loops/*.cu ./include/loops/cuda/**/*.cu)
file(GLOB_RECURSE COMPILATION_UNITS ./include/loops/cuda/compilation_units/*.cu.in)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
foreach(FL_ITEM ${COMPILATION_UNITS})
genCompilation(${FL_ITEM}) # Appends to CUSTOMOPS_GENERIC_SOURCES
endforeach()
set(ALL_SOURCES
${PERF_SOURCES}
${EXCEPTIONS_SOURCES}
${EXEC_SOURCES}
${TYPES_SOURCES}
${ARRAY_SOURCES}
${MEMORY_SOURCES}
${GRAPH_SOURCES}
${CUSTOMOPS_SOURCES}
${CUSTOMOPS_HELPERS_SOURCES}
${OPS_SOURCES}
${HELPERS_SOURCES}
${INDEXING_SOURCES}
${LOOPS_SOURCES}
${LEGACY_SOURCES}
${LOOPS_SOURCES_CUDA}
${CUSTOMOPS_GENERIC_SOURCES} # Generated by genCompilation
)
if(HAVE_CUDNN)
message("cuDNN included")
file(GLOB_RECURSE CUSTOMOPS_CUDNN_SOURCES ./include/ops/declarable/platform/cudnn/*.cu)
list(APPEND ALL_SOURCES ${CUSTOMOPS_CUDNN_SOURCES})
endif()
# Create an OBJECT library first (compiles sources without linking)
# This internal target name doesn't conflict with the final library name
set(OBJECT_LIB_NAME "${SD_LIBRARY_NAME}_object")
add_library(${OBJECT_LIB_NAME} OBJECT
${ALL_SOURCES}
)
target_include_directories(${OBJECT_LIB_NAME} PUBLIC ${EXTERNAL_INCLUDE_DIRS})
set_property(TARGET ${OBJECT_LIB_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "${MSVC_RT_LIB}$<$<CONFIG:Debug>:Debug>")
# Add platform-specific flags to the object library
if(WIN32)
message("Enabling /EHsc for CUDA on Windows")
target_compile_options(${OBJECT_LIB_NAME} INTERFACE "/EHsc" "/bigobj") # Apply to interface if needed by consumers
target_compile_options(${OBJECT_LIB_NAME} PRIVATE "/EHsc" "/bigobj") # Apply to internal build
endif()
# Create the final SHARED library using the object library
add_library(${SD_LIBRARY_NAME} SHARED $<TARGET_OBJECTS:${OBJECT_LIB_NAME}>)
set_target_properties(${SD_LIBRARY_NAME} PROPERTIES OUTPUT_NAME ${SD_LIBRARY_NAME}) # Ensure output file is nd4jcuda.dll/so
set_property(TARGET ${SD_LIBRARY_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "${MSVC_RT_LIB}$<$<CONFIG:Debug>:Debug>")
# Link dependencies to the final shared library
target_link_libraries(${SD_LIBRARY_NAME} PUBLIC
${CUDA_LIBRARIES}
${CUDA_DRIVER_LIBRARY}
${CUDA_CUBLAS_LIBRARIES}
${CUDA_cusolver_LIBRARY}
${CUDNN}
# Add flatbuffers if needed for CUDA build? Assuming yes for now.
flatbuffers
)
install(TARGETS ${SD_LIBRARY_NAME} DESTINATION .) # Install the final shared library
endif()
else() # Start of CPU Build Section
set(DEFAULT_ENGINE "samediff::ENGINE_CPU")
# Configure BLAS for CPU builds
message("CPU BLAS")
add_definitions(-D__CPUBLAS__=true)
# Set Library Output Directories
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") # This affects where the final library goes, might want top-level
set(CUSTOMOPS_GENERIC_SOURCES "") # Initialize list for generated sources
# Gather templates processed by genCompilation (old style)
# Updated: Removed ops/impl/compilation_units/*.cpp.in if specials_* moved
file(GLOB_RECURSE COMPILATION_UNITS
./include/ops/declarable/helpers/cpu/compilation_units/*.cpp.in
./include/loops/cpu/compilation_units/*.cpp.in
./include/helpers/cpu/loops/*.cpp.in)
# Generate Compilation Units (Old Style)
foreach(FL_ITEM ${COMPILATION_UNITS})
genCompilation(${FL_ITEM}) # Appends to CUSTOMOPS_GENERIC_SOURCES
endforeach()
# Gather CPU Source Files
file(GLOB_RECURSE PERF_SOURCES ./include/performance/*.cpp ./include/performance/*.h)
file(GLOB_RECURSE EXCEPTIONS_SOURCES ./include/exceptions/*.cpp ./include/exceptions/*.h)
file(GLOB_RECURSE EXEC_SOURCES ./include/execution/*.cpp ./include/execution/*.h)
file(GLOB_RECURSE TYPES_SOURCES ./include/types/*.cpp ./include/types/*.h)
file(GLOB_RECURSE ARRAY_SOURCES ./include/array/*.cpp ./include/array/*.h)
file(GLOB_RECURSE MEMORY_SOURCES ./include/memory/*.cpp ./include/memory/*.h)
file(GLOB_RECURSE GRAPH_SOURCES ./include/graph/*.cpp ./include/graph/*.h)
file(GLOB_RECURSE CUSTOMOPS_SOURCES ./include/ops/declarable/generic/*.cpp)
# Updated: CUSTOMOPS_GENERIC_SOURCES now refers ONLY to genCompilation outputs. Partitioned sources are added later.
file(GLOB_RECURSE CUSTOMOPS_HELPERS_IMPL_SOURCES ./include/ops/declarable/helpers/impl/*.cpp)
file(GLOB_RECURSE CUSTOMOPS_HELPERS_CPU_SOURCES ./include/ops/declarable/helpers/cpu/*.cpp) # Regular CPU helpers
file(GLOB_RECURSE OPS_SOURCES ./include/ops/impl/*.cpp ./include/ops/declarable/impl/*.cpp ./include/ops/*.h)
file(GLOB_RECURSE INDEXING_SOURCES ./include/indexing/*.cpp ./include/indexing/*.h)
file(GLOB_RECURSE HELPERS_SOURCES ./include/build_info.cpp ./include/ConstMessages.cpp ./include/helpers/*.cpp ./include/helpers/cpu/*.cpp ./include/helpers/*.h)
file(GLOB_RECURSE LEGACY_SOURCES ./include/legacy/impl/*.cpp ./include/legacy/cpu/*.cpp ./include/legacy/*.h)
file(GLOB_RECURSE LOOPS_SOURCES ./include/loops/*.cpp ./include/loops/*.h)
# Initialize ALL_SOURCES list here before conditional appends
set(ALL_SOURCES "")
# Include ONEDNN and ARM Compute Sources Conditionally
set(CUSTOMOPS_ONEDNN_SOURCES "") # Initialize
if(HAVE_ONEDNN)
file(GLOB_RECURSE CUSTOMOPS_ONEDNN_SOURCES_TMP
./include/ops/declarable/platform/mkldnn/*.cpp
./include/ops/declarable/platform/mkldnn/mkldnnUtils.h
)
set(CUSTOMOPS_ONEDNN_SOURCES ${CUSTOMOPS_ONEDNN_SOURCES_TMP})
list(APPEND ALL_SOURCES ${CUSTOMOPS_ONEDNN_SOURCES})
endif()
set(CUSTOMOPS_ARMCOMPUTE_SOURCES "") # Initialize
if(HAVE_ARMCOMPUTE)
file(GLOB_RECURSE CUSTOMOPS_ARMCOMPUTE_SOURCES_TMP
./include/ops/declarable/platform/armcompute/*.cpp
./include/ops/declarable/platform/armcompute/*.h
)
set(CUSTOMOPS_ARMCOMPUTE_SOURCES ${CUSTOMOPS_ARMCOMPUTE_SOURCES_TMP})
list(APPEND ALL_SOURCES ${CUSTOMOPS_ARMCOMPUTE_SOURCES})
endif()
if (SD_X86_BUILD)
# Disable platform optimizations for certain files on Linux/macOS
# Note: Path cpu/NativeOps.cpp seems incorrect based on glob patterns, assuming it's within include structure
# set_source_files_properties(./include/??/cpu/NativeOps.cpp PROPERTIES COMPILE_FLAGS "-march=x86-64 -mtune=generic")
set_source_files_properties(./include/helpers/impl/OpTracker.cpp PROPERTIES COMPILE_FLAGS "-march=x86-64 -mtune=generic")
endif()
# Filter Sources Based on SD_ALL_OPS
# Combine static source lists for checking
set(STATIC_SOURCES_TO_CHECK
${PERF_SOURCES} ${EXCEPTIONS_SOURCES} ${EXEC_SOURCES} ${TYPES_SOURCES} ${ARRAY_SOURCES}
${MEMORY_SOURCES} ${GRAPH_SOURCES} ${CUSTOMOPS_SOURCES} ${CUSTOMOPS_HELPERS_IMPL_SOURCES}
${CUSTOMOPS_HELPERS_CPU_SOURCES} ${OPS_SOURCES} ${INDEXING_SOURCES} ${HELPERS_SOURCES}
${LEGACY_SOURCES} ${LOOPS_SOURCES} ${CUSTOMOPS_ONEDNN_SOURCES} ${CUSTOMOPS_ARMCOMPUTE_SOURCES}
)
if(NOT SD_ALL_OPS)
message("Not all SD OPS INCLUDED - Filtering sources")
set(FILTERED_STATIC_SOURCES "")
foreach(SRC_FILE ${STATIC_SOURCES_TO_CHECK})
# Check if the file should be kept (removeFileIfExcluded modifies the list passed by name)
set(temp_list "${SRC_FILE}") # Create a temporary list with one item
removeFileIfExcluded(FILE_ITEM "${SRC_FILE}" LIST_ITEM "temp_list")
if(temp_list) # If the list is not empty after checking, keep the file
list(APPEND FILTERED_STATIC_SOURCES "${SRC_FILE}")
else()
message("Excluding file due to op restrictions: ${SRC_FILE}")
endif()
endforeach()
# Append filtered static sources to ALL_SOURCES (which might already contain platform sources if they weren't filtered above)
# To avoid duplicates if platform sources were already added, filter the main list
list(REMOVE_ITEM ALL_SOURCES ${STATIC_SOURCES_TO_CHECK}) # Remove all potential static sources first
list(APPEND ALL_SOURCES ${FILTERED_STATIC_SOURCES}) # Add back only the filtered ones
else()
# If SD_ALL_OPS is true, include all static sources directly (ensure no duplicates with platform sources)
list(APPEND ALL_SOURCES
${PERF_SOURCES} ${EXCEPTIONS_SOURCES} ${EXEC_SOURCES} ${TYPES_SOURCES} ${ARRAY_SOURCES}
${MEMORY_SOURCES} ${GRAPH_SOURCES} ${CUSTOMOPS_SOURCES} ${CUSTOMOPS_HELPERS_IMPL_SOURCES}
${CUSTOMOPS_HELPERS_CPU_SOURCES} ${OPS_SOURCES} ${INDEXING_SOURCES} ${HELPERS_SOURCES}
${LEGACY_SOURCES} ${LOOPS_SOURCES} # Platform sources already added
)
list(REMOVE_DUPLICATES ALL_SOURCES) # Clean up potential duplicates
endif()
# Add sources generated by genCompilation (already filtered if necessary by its internal logic)
list(APPEND ALL_SOURCES ${CUSTOMOPS_GENERIC_SOURCES})
# Process type combinations using genPartitionCombination (New Style)
set(PARTITION_SOURCES "") # Initialize list for these generated sources
set(CPU_INST_DIR "${CMAKE_BINARY_DIR}/cpu_instantiations")
file(MAKE_DIRECTORY "${CPU_INST_DIR}")
# Temporarily store generated partition sources to avoid scope issues with PARENT_SCOPE
set(GENERATED_PARTITION_SOURCES_TEMP "")
foreach(TEMPLATE_FILE ${INSTANTIATION_TEMPLATES_3})
foreach(COMBINATION ${COMBINATIONS_3})
# Call genPartitionCombination, it appends to CUSTOMOPS_GENERIC_SOURCES in its scope
set(CUSTOMOPS_GENERIC_SOURCES "") # Clear before call
genPartitionCombination(${TEMPLATE_FILE} 3 ${COMBINATION} "${CPU_INST_DIR}")
# Append the returned list to PARTITION_SOURCES
list(APPEND GENERATED_PARTITION_SOURCES_TEMP ${CUSTOMOPS_GENERIC_SOURCES})
endforeach()
endforeach()
foreach(TEMPLATE_FILE ${INSTANTIATION_TEMPLATES_2})
foreach(COMBINATION ${COMBINATIONS_2})
# Call genPartitionCombination, it appends to CUSTOMOPS_GENERIC_SOURCES in its scope
set(CUSTOMOPS_GENERIC_SOURCES "") # Clear before call
genPartitionCombination(${TEMPLATE_FILE} 2 ${COMBINATION} "${CPU_INST_DIR}")
# Append the returned list to PARTITION_SOURCES
list(APPEND GENERATED_PARTITION_SOURCES_TEMP ${CUSTOMOPS_GENERIC_SOURCES})
endforeach()
endforeach()
set(PARTITION_SOURCES ${GENERATED_PARTITION_SOURCES_TEMP}) # Assign accumulated list
# Add sources generated by genPartitionCombination to the main list
list(APPEND ALL_SOURCES ${PARTITION_SOURCES})
list(REMOVE_DUPLICATES ALL_SOURCES) # Final cleanup
# Create Object Library
# Use a distinct internal name for the object library
set(OBJECT_LIB_NAME "${SD_LIBRARY_NAME}_object")
add_library(${OBJECT_LIB_NAME} OBJECT
${ALL_SOURCES}
)
target_include_directories(${OBJECT_LIB_NAME} PUBLIC ${EXTERNAL_INCLUDE_DIRS})
set_property(TARGET ${OBJECT_LIB_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "${MSVC_RT_LIB}$<$<CONFIG:Debug>:Debug>")
# Create the final shared library using the object library
add_library(${SD_LIBRARY_NAME} SHARED $<TARGET_OBJECTS:${OBJECT_LIB_NAME}>)
set_target_properties(${SD_LIBRARY_NAME} PROPERTIES OUTPUT_NAME ${SD_LIBRARY_NAME}) # Ensure output file is nd4jcpu.dll/so
set_property(TARGET ${SD_LIBRARY_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "${MSVC_RT_LIB}$<$<CONFIG:Debug>:Debug>")
# Apply Android specific properties if needed
if(ANDROID)
# Limit the number of compile jobs on systems with few cores
cmake_host_system_information(RESULT _logical_cores QUERY NUMBER_OF_LOGICAL_CORES)
if(_logical_cores LESS 4)
set_target_properties(${SD_LIBRARY_NAME} PROPERTIES JOB_POOL_COMPILE one_jobs)
endif()
endif()
# Link required libraries to the shared library
target_link_libraries(${SD_LIBRARY_NAME} PUBLIC
${ONEDNN} # Interface target 'onednn_interface' or empty
${ARMCOMPUTE_LIBRARIES} # Interface target 'armcompute_interface' or empty
${OPENBLAS_LIBRARIES}
${BLAS_LIBRARIES}
flatbuffers # Link flatbuffers
)
install(TARGETS ${SD_LIBRARY_NAME} DESTINATION .) # Install the final shared library
# Compiler Checks
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
message(FATAL_ERROR "You need at least GCC 4.9")
endif()
# OpenMP for GCC
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
find_package(OpenMP)
if(OPENMP_FOUND)
# Apply flags to the object library target
target_compile_options(${OBJECT_LIB_NAME} INTERFACE ${OpenMP_C_FLAGS} ${OpenMP_CXX_FLAGS})
target_compile_options(${OBJECT_LIB_NAME} PRIVATE ${OpenMP_C_FLAGS} ${OpenMP_CXX_FLAGS})
# Link OpenMP to the final shared library
target_link_libraries(${SD_LIBRARY_NAME} PUBLIC OpenMP::OpenMP_CXX)
endif()
endif()
endif() # End of CPU Build Section
# Add tests if enabled
if(SD_BUILD_TESTS)
include(CTest)
# tests are always compiled with all ops included
set(SD_ALL_OPS true)
enable_testing()
add_subdirectory(tests_cpu)
endif()
# Preprocessing Configuration
if(SD_PREPROCESS STREQUAL "ON")
message("Preprocessing enabled: ${CMAKE_BINARY_DIR}")
include_directories(${CMAKE_BINARY_DIR}/.././include)
# Get ALL_SOURCES from the final object library target
get_target_property(FINAL_ALL_SOURCES ${OBJECT_LIB_NAME} SOURCES)
list(REMOVE_DUPLICATES FINAL_ALL_SOURCES)
# Define Output Directory
set(PREPROCESSED_DIR "${CMAKE_SOURCE_DIR}/preprocessed")
file(MAKE_DIRECTORY ${PREPROCESSED_DIR})
# Initialize Lists
set(PREPROCESSED_FILES)
set(PROCESSED_SOURCES "")
# Create Custom Commands for Each Source File
foreach(src IN LISTS FINAL_ALL_SOURCES)
# Skip generated files that don't exist on disk yet or are not regular source files
if(NOT EXISTS ${src} OR NOT src MATCHES "\\.(c|cpp|cxx|cc|cu)$")
continue()
endif()
if(NOT src IN_LIST PROCESSED_SOURCES)
get_filename_component(src_name ${src} NAME_WE)
get_filename_component(src_path ${src} PATH) # Get full path
# Create a unique name based on relative path if possible
file(RELATIVE_PATH rel_path ${CMAKE_SOURCE_DIR} ${src_path})
string(REPLACE "/" "_" src_dir_ "${rel_path}") # Use relative path for uniqueness
# Handle absolute paths outside source dir (e.g., generated files in build dir)
if(IS_ABSOLUTE ${src} AND NOT src MATCHES "^${CMAKE_SOURCE_DIR}")
file(RELATIVE_PATH rel_path_build ${CMAKE_BINARY_DIR} ${src_path})
string(REPLACE "/" "_" src_dir_build_ "${rel_path_build}")
set(src_dir_ "build_${src_dir_build_}")
endif()
set(preprocessed_file "${PREPROCESSED_DIR}/${src_dir_}_${src_name}.i")
message(STATUS "Processing ${src} to ${preprocessed_file}")
if(NOT EXISTS "${preprocessed_file}")
set(compiler "")
set(lang_flags "")
set(includes_list "")
get_target_property(includes_list ${OBJECT_LIB_NAME} INCLUDE_DIRECTORIES)
get_target_property(compile_defs ${OBJECT_LIB_NAME} COMPILE_DEFINITIONS)
get_target_property(compile_opts ${OBJECT_LIB_NAME} COMPILE_OPTIONS)
set(include_flags "")
foreach(dir IN LISTS includes_list)
string(APPEND include_flags " -I\"${dir}\"")
endforeach()
set(defs_flags "")
foreach(def IN LISTS compile_defs)
string(APPEND defs_flags " -D${def}")
endforeach()
set(opts_flags "")
# Be careful with compile options, some might not be valid for -E
# list(APPEND opts_flags ${compile_opts})
# string(REPLACE ";" " " opts_flags_str "${opts_flags}")
if(src MATCHES "\\.cu$")
set(language "CUDA")
set(compiler "${CMAKE_CUDA_COMPILER}")
# Add CUDA specific flags if necessary, excluding those incompatible with -E
# set(lang_flags "${CMAKE_CUDA_FLAGS}") - This contains incompatible flags like -Xcompiler
elseif(src MATCHES "\\.c$")
set(language "C")
set(compiler "${CMAKE_C_COMPILER}")
set(lang_flags "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}")
elseif(src MATCHES "\\.cpp$|\\.cxx$|\\.cc$")
set(language "CXX")
set(compiler "${CMAKE_CXX_COMPILER}")
set(lang_flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
else()
message(WARNING "Skipping preprocessing for unknown file type: ${src}")
continue()
endif()
# Filter flags incompatible with -E (like linker flags, optimization flags potentially)
# This is a basic attempt; might need refinement
string(REGEX REPLACE "-O[0-9]" "" lang_flags "${lang_flags}")
string(REGEX REPLACE "-g" "" lang_flags "${lang_flags}")
string(REGEX REPLACE "-flto" "" lang_flags "${lang_flags}")
string(REGEX REPLACE "-fPIC" "" lang_flags "${lang_flags}") # -fPIC usually OK, but remove for safety
# Add more filters as needed
message("COMMAND ${compiler} -E ${lang_flags} ${defs_flags} ${include_flags} ${src} -o ${preprocessed_file}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E time "${compiler}" -E ${lang_flags} ${defs_flags} ${include_flags} "${src}" -o "${preprocessed_file}"
# WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/../" # Better to use absolute paths for sources
RESULT_VARIABLE result
OUTPUT_VARIABLE stdout_output
ERROR_VARIABLE stderr_output
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
set(output_log_file "${preprocessed_file}.log")
file(WRITE ${output_log_file} "Command:\n${compiler} -E ${lang_flags} ${defs_flags} ${include_flags} ${src} -o ${preprocessed_file}\n\n")
file(APPEND ${output_log_file} "Result: ${result}\n\n")
file(APPEND ${output_log_file} "Standard Output:\n${stdout_output}\n\n")
file(APPEND ${output_log_file} "Standard Error:\n${stderr_output}\n")
if(result)
message(WARNING "Preprocessing failed for ${src}. See log: ${output_log_file}")
else()
list(APPEND PREPROCESSED_FILES ${preprocessed_file})
endif()
else()
message(STATUS "Preprocessed file already exists, skipping: ${preprocessed_file}")
list(APPEND PREPROCESSED_FILES ${preprocessed_file})
endif()
list(APPEND PROCESSED_SOURCES ${src})
else()
# message(STATUS "Skipping already processed file: ${src}")
endif()
endforeach()
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM 1)
# Create a Custom Target for All Preprocessed Files
if(PREPROCESSED_FILES)
add_custom_target(preprocess_sources ALL DEPENDS ${PREPROCESSED_FILES})
else()
add_custom_target(preprocess_sources ALL) # Define target even if no files processed
endif()
endif()
Why is the path still not matching for the linker path? Right now I gave you the pom and the cmake file for the libnd4j module. Let me know if you want the nd4j-cuda module too.