Skip to content

Commit e090b2e

Browse files
committed
Add interfaces for tensors, tensors data and backend
1 parent 2dad6e5 commit e090b2e

11 files changed

Lines changed: 236 additions & 36 deletions

File tree

.github/worklfows/publish.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- '**'
7+
8+
jobs:
9+
publish:
10+
name: Release build and publish
11+
runs-on: macOS-latest
12+
steps:
13+
- name: Check out code
14+
uses: actions/checkout@v5
15+
- name: Set up JDK 21
16+
uses: actions/setup-java@v5
17+
with:
18+
distribution: 'zulu'
19+
java-version: 21
20+
- name: Publish to MavenCentral
21+
run: ./gradlew publish --no-configuration-cache --stacktrace
22+
env:
23+
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
24+
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
25+
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_PRIVATE_KEY }}
26+
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}

build.gradle.kts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,10 @@ plugins {
22
alias(libs.plugins.androidLibrary) apply false
33
alias(libs.plugins.kotlinMultiplatform) apply false
44
alias(libs.plugins.jetbrainsKotlinJvm) apply false
5-
alias(libs.plugins.binaryCompatibility) apply false
6-
alias(libs.plugins.modulegraph.souza) apply true
7-
8-
5+
alias(libs.plugins.vanniktech.mavenPublish) apply false
96
}
107

118
allprojects {
129
group = "sk.ai.net"
1310
version = "0.0.7"
14-
}
15-
16-
moduleGraphConfig {
17-
readmePath.set("./Modules.md")
18-
heading = "### Module Graph"
19-
}
11+
}

gradle.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
GROUP=sk.ainet.core
2+
VERSION_NAME=0.0.8
3+
4+
mavenCentralPublishing=true
5+
mavenCentralAutomaticPublishing=true
6+
17
#Gradle
28
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
39
org.gradle.caching=true

gradle/libs.versions.toml

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,16 @@
11
[versions]
2-
agp = "8.12.1"
3-
kotlin = "2.2.10"
2+
agp = "8.11.2"
3+
kotlin = "2.2.20"
44
kotlinx-coroutines = "1.10.2"
55
android-minSdk = "24"
6-
android-compileSdk = "35"
7-
kotlinxSerializationJson = "1.9.0"
8-
ktorClientCore = "3.2.3"
9-
ktorClientPlugins = "3.1.1"
10-
logbackClassic = "1.5.18"
11-
kotlinxIo = "0.8.0"
12-
kotlinxCli = "0.3.6"
13-
nexus-publish = "2.0.0"
14-
testng = "7.10.2"
15-
binaryCompatibility = "0.18.1"
16-
moduleGraphSouza = "0.12.1"
6+
android-compileSdk = "36"
177

188
[libraries]
199
kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
2010
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
21-
kotlinx-coroutines-core-jvm = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm", version.ref = "kotlinxSerializationJson" }
22-
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
23-
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktorClientCore" }
24-
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktorClientCore" }
25-
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktorClientCore" }
26-
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktorClientCore" }
27-
ktor-client-plugins = { module = "io.ktor:ktor-client-plugins", version.ref = "ktorClientPlugins" }
28-
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logbackClassic" }
29-
kotlinx-io-core = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version.ref = "kotlinxIo" }
30-
kotlinx-cli = { module = "org.jetbrains.kotlinx:kotlinx-cli", version.ref = "kotlinxCli" }
3111

3212
[plugins]
3313
androidLibrary = { id = "com.android.library", version.ref = "agp" }
3414
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
3515
jetbrainsKotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
36-
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
37-
binaryCompatibility = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binaryCompatibility" }
38-
modulegraph-souza = { id = "dev.iurysouza.modulegraph", version.ref = "moduleGraphSouza" }
3916
vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version = "0.34.0" }

settings.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ dependencyResolutionManagement {
1414
}
1515

1616
rootProject.name = "skainet"
17+
18+
include("skainet-core:skainet-tensors-api")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
POM_ARTIFACT_ID=core-api
2+
POM_NAME=skainet core API
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package sk.ai.net.core.tensor
2+
3+
// Base marker interface for all dtypes
4+
public sealed interface DType {
5+
public val sizeInBits: Int
6+
public val name: String
7+
}
8+
9+
public object Ternary : DType {
10+
override val sizeInBits: Int = 2
11+
override val name: String = "Ternary"
12+
}
13+
14+
15+
public object Int4 : DType {
16+
override val sizeInBits: Int = 4 // technically 4 bits, but minimum is 1 byte
17+
override val name: String = "Int4"
18+
}
19+
20+
public object Int8 : DType {
21+
override val sizeInBits: Int = 8 // technically 4 bits, but minimum is 1 byte
22+
override val name: String = "Int8"
23+
}
24+
25+
public object FP16 : DType {
26+
override val sizeInBits: Int = 16
27+
override val name: String = "Float16"
28+
}
29+
30+
public object FP32 : DType{
31+
override val sizeInBits: Int = 32
32+
override val name: String = "Float32"
33+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package sk.ai.net.core.tensor
2+
3+
/**
4+
* Data class representing the shape of a multi-dimensional array (tensor).
5+
*
6+
* @property dimensions An array of integers representing the size of each dimension.
7+
*/
8+
9+
public data class Shape(val dimensions: IntArray) {
10+
public companion object {
11+
public operator fun invoke(vararg dimensions: Int): Shape {
12+
return Shape(dimensions.copyOf())
13+
}
14+
}
15+
16+
val volume: Int
17+
get() = dimensions.fold(1) { a, x -> a * x }
18+
19+
val rank: Int
20+
get() = dimensions.size
21+
22+
internal fun index(indices: IntArray): Int {
23+
assert(
24+
{ indices.size == dimensions.size },
25+
{ "`indices.size` must be ${dimensions.size}: ${indices.size}" })
26+
return dimensions.zip(indices).fold(0) { a, x ->
27+
assert(
28+
{ 0 <= x.second && x.second < x.first },
29+
{ "Illegal index: indices = ${indices}, shape = $dimensions" })
30+
a * x.first + x.second
31+
}
32+
}
33+
34+
public operator fun get(index: Int): Int {
35+
return dimensions[index]
36+
}
37+
38+
override fun equals(other: Any?): Boolean {
39+
if (this === other) return true
40+
if (other !is Shape) return false
41+
42+
return dimensions.contentEquals(other.dimensions)
43+
}
44+
45+
override fun hashCode(): Int {
46+
return dimensions.contentHashCode()
47+
}
48+
49+
override fun toString(): String {
50+
// Create a string representation of the dimensions array
51+
val dimensionsString = dimensions.joinToString(separator = " x ", prefix = "[", postfix = "]")
52+
// Return the formatted string including dimensions and volume
53+
return "Shape: Dimensions = $dimensionsString, Size (Volume) = $volume"
54+
}
55+
}
56+
57+
internal inline fun assert(value: () -> Boolean, lazyMessage: () -> Any) {
58+
if (!value()) {
59+
val message = lazyMessage()
60+
throw AssertionError(message)
61+
}
62+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package sk.ai.net.core.tensor
2+
3+
/**
4+
* Interface representing a multi-dimensional array of numeric values.
5+
*
6+
* A Tensor is a generalization of vectors and matrices to potentially higher dimensions.
7+
* The [shape] property defines the dimensions of the tensor, and the [get] operator
8+
* allows accessing individual elements by their indices.
9+
*/
10+
public interface Tensor<T : DType, V> : TensorData<T, V>, TensorOps<Tensor<T, V>>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package sk.ai.net.core.tensor
2+
3+
public interface TensorData<T:DType, V> {
4+
/**
5+
* The shape of the tensor, represented as a Shape data class containing dimensions.
6+
*
7+
* For example, a scalar has an empty shape, a vector has a shape with one dimension,
8+
* a matrix has a shape with two dimensions, and so on.
9+
*/
10+
public val shape: Shape
11+
12+
/**
13+
* Retrieves the value at the specified indices.
14+
*
15+
* @param indices The indices of the element to retrieve.
16+
* @return The value at the specified indices.
17+
*/
18+
public operator fun get(vararg indices: Int): V
19+
}

0 commit comments

Comments
 (0)