diff --git a/settings.gradle.kts b/settings.gradle.kts index ec6ef6d7..909a2ea6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,6 +37,7 @@ include("skainet-compile:skainet-compile-hlo") include("skainet-compile:skainet-compile-c") // ====== BACKENDS +include("skainet-backends:skainet-backend-api") include("skainet-backends:skainet-backend-cpu") // ====== BENCHMARKS diff --git a/skainet-backends/skainet-backend-api/build.gradle.kts b/skainet-backends/skainet-backend-api/build.gradle.kts new file mode 100644 index 00000000..a573fcca --- /dev/null +++ b/skainet-backends/skainet-backend-api/build.gradle.kts @@ -0,0 +1,99 @@ +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.androidMultiplatformLibrary) + id("sk.ainet.dokka") +} + +kotlin { + explicitApi() + android { + namespace = "sk.ainet.backend.api" + compileSdk = libs.versions.android.compileSdk.get().toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + } + } + + iosArm64() + iosSimulatorArm64() + macosArm64() + linuxX64() + linuxArm64() + + jvm() + + js { + browser() + } + + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + browser() + } + + @OptIn(ExperimentalWasmDsl::class) + wasmWasi { + nodejs() + } + + sourceSets { + commonMain.dependencies { + // Neutral backend API is an `api` re-export of the tensor op and + // storage interfaces already defined in skainet-lang-core. Any + // concrete backend (CPU, IREE, Metal, NPU, ...) should depend on + // this module instead of pulling in skainet-backend-cpu just to + // reach TensorOps / TensorDataFactory / TensorData. + api(project(":skainet-lang:skainet-lang-core")) + } + + val jvmMain by getting + val androidMain by getting + val wasmJsMain by getting + + val commonMain by getting + + val nativeMain by creating { + dependsOn(commonMain) + } + + val appleMain by creating { + dependsOn(nativeMain) + } + + val linuxMain by creating { + dependsOn(nativeMain) + } + + val iosMain by creating { + dependsOn(appleMain) + } + + val macosMain by creating { + dependsOn(appleMain) + } + + val iosArm64Main by getting { + dependsOn(iosMain) + } + + val iosSimulatorArm64Main by getting { + dependsOn(iosMain) + } + + val macosArm64Main by getting { + dependsOn(macosMain) + } + + val linuxX64Main by getting { + dependsOn(linuxMain) + } + + val linuxArm64Main by getting { + dependsOn(linuxMain) + } + } +} diff --git a/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/BackendApi.kt b/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/BackendApi.kt new file mode 100644 index 00000000..eabd55df --- /dev/null +++ b/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/BackendApi.kt @@ -0,0 +1,17 @@ +package sk.ainet.backend.api + +/** + * Marker for the backend-neutral API surface of SKaiNET. + * + * This module owns no implementation of its own. It `api`-re-exports the + * tensor op and storage interfaces that already live in `skainet-lang-core` + * (notably `TensorOps`, `TensorDataFactory`, `TensorData` and friends), so + * that concrete backends — `skainet-backend-cpu` today, and future IREE / + * Metal / NPU backends — can depend on a single neutral module instead of + * pulling in the CPU backend just to reach the interfaces they implement. + * + * Consumer migration from `skainet-backend-cpu` to this module is handled + * in follow-up PRs in the P0-2 track and is intentionally out of scope for + * the first change that introduces the module. + */ +public object BackendApi diff --git a/skainet-backends/skainet-backend-cpu/build.gradle.kts b/skainet-backends/skainet-backend-cpu/build.gradle.kts index 3864033b..63e19acd 100644 --- a/skainet-backends/skainet-backend-cpu/build.gradle.kts +++ b/skainet-backends/skainet-backend-cpu/build.gradle.kts @@ -44,6 +44,9 @@ kotlin { sourceSets { commonMain.dependencies { + // Every concrete backend should go through the neutral api + // module; it transitively brings in skainet-lang-core. + implementation(project(":skainet-backends:skainet-backend-api")) implementation(project(":skainet-lang:skainet-lang-core")) implementation(project(":skainet-compile:skainet-compile-core")) implementation(project(":skainet-lang:skainet-lang-ksp-annotations"))