Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GROUP=sk.ainet.core
VERSION_NAME=0.0.1.1
VERSION_NAME=0.0.1.2

POM_DESCRIPTION=SKaiNET

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public data class Shape(val dimensions: IntArray) {
}

val volume: Int
get() = dimensions.fold(1) { a, x -> a * x }
get() = dimensions.fold(if (dimensions.isNotEmpty()) 1 else 0) { a, x -> a * x }

val rank: Int
get() = dimensions.size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,82 +7,82 @@ import sk.ainet.lang.types.DType
/**
* The core tensor abstraction in the SKaiNET framework, representing a fundamental
* architectural decision to compose tensors from data and operations.
*
*
* ## Fundamental Architectural Decision: Tensor Composition
*
*
* This interface embodies a key architectural principle in the SKaiNET framework:
* **tensors are composed of two distinct, complementary components:**
*
*
* 1. **Data Component (`TensorData`)** - Responsible for:
* - Multi-dimensional data storage and indexing
* - Memory layout and access patterns
* - Shape and dimensional metadata
* - Type-safe element access
*
*
* 2. **Operations Component (`TensorOps`)** - Responsible for:
* - Mathematical operations and transformations
* - Computational algorithms
* - Operation chaining and composition
* - Performance-optimized implementations
*
*
* ## Benefits of This Compositional Architecture
*
*
* **Separation of Concerns**: Data management is cleanly separated from computational
* logic, making the codebase more maintainable and easier to understand.
*
*
* **Flexibility**: Different data storage strategies (dense, sparse, distributed) can
* be combined with different operation implementations (CPU, GPU, specialized hardware)
* without tight coupling.
*
*
* **Performance Optimization**: Data layout can be optimized independently from
* computational algorithms, enabling targeted performance improvements.
*
*
* **Extensibility**: New data formats or operation types can be added without
* modifying existing code, following the open-closed principle.
*
*
* **Testability**: Data and operations can be tested independently, improving
* test coverage and reducing complexity.
*
*
* ## Usage Pattern
*
*
* The tensor acts as a unified interface that delegates data access to the `data`
* component and computational operations to the `ops` component, providing a
* seamless experience while maintaining the benefits of compositional design.
*
*
* @param T the data type constraint extending DType, defining the numerical precision
* @param V the actual value type that will be stored and accessed
*/
public interface Tensor<T : DType, V> {
/**
* The data component responsible for storage, indexing, and memory management.
*
*
* This component handles all aspects related to data storage and access,
* including multi-dimensional indexing, shape management, and memory layout
* including multidimensional indexing, shape management, and memory layout
* optimization. It provides the foundation for the tensor's data model.
*/
public val data: TensorData<T, V>

/**
* The operations component responsible for computational algorithms and transformations.
*
*
* This component provides all mathematical operations that can be performed
* on the tensor, from basic arithmetic to complex neural network operations.
* It leverages the data component for element access while encapsulating
* all computational logic.
*/
public val ops: TensorOps<T, V>
public val ops: TensorOps<V>

/**
* The data type descriptor defining the numerical precision and value representation.
*
*
* This property provides metadata about the tensor's data type, enabling
* type-safe operations and appropriate memory allocation strategies.
*/
public val dtype: T

/**
* The shape descriptor inherited from the data component.
*
*
* This property delegates to the data component's shape, maintaining consistency
* between the tensor interface and its underlying data representation.
*/
Expand All @@ -91,7 +91,7 @@ public interface Tensor<T : DType, V> {

/**
* The total number of elements in the tensor.
*
*
* This computed property provides quick access to the tensor's total size,
* calculated from the shape's volume. Useful for memory allocation and
* iteration operations.
Expand All @@ -101,7 +101,7 @@ public interface Tensor<T : DType, V> {

/**
* The number of dimensions in the tensor.
*
*
* This computed property provides quick access to the tensor's dimensionality,
* derived from the shape's rank. Essential for dimension-aware operations
* and broadcasting compatibility checks.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import sk.ainet.lang.types.DType
* A fundamental data structure interface that provides indexed access to elements.
*
* This interface serves as the base for all data structures that need to provide
* element access through multi-dimensional indexing. It is designed to support
* element access through multidimensional indexing. It is designed to support
* efficient access patterns commonly used in neural network computations.
*
* @param T the type of elements that can be accessed
*/
public interface ItemsAccessor<T> {
/**
* Retrieves an element at the specified multi-dimensional indices.
* Retrieves an element at the specified multidimensional indices.
*
* This operator function allows accessing elements using bracket notation
* with variable number of indices, supporting tensors of any dimensionality.
Expand All @@ -24,6 +24,12 @@ public interface ItemsAccessor<T> {
* @throws IndexOutOfBoundsException if any index is out of bounds
*/
public operator fun get(vararg indices: Int): T


/**
* Setter
*/
public operator fun set(vararg indices: Int, value: T)
}

/**
Expand Down Expand Up @@ -61,4 +67,6 @@ public interface TensorData<T : DType, V> : ItemsAccessor<V> {
* @return the Shape object describing this tensor's dimensional structure
*/
public val shape: Shape

public companion object
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package sk.ainet.lang.tensor.data

import sk.ainet.lang.types.DType


public fun <T: DType,V> TensorData<T,V>.pprint(): String {
return when (this.shape.rank) {
0 -> {
// Scalar - single value
this.toString()
}
1 -> {
// Vector - horizontal representation with parentheses
val sb = StringBuilder()
sb.append("[ ")
for (i in 0 until this.shape[0]) {
if (i > 0) sb.append(", ")
sb.append(this[i].toString())
}
sb.append(" ]")
sb.toString()
}
2 -> {
// Matrix - vertical representation with Unicode brackets
val sb = StringBuilder()
val rows = this.shape[0]
val cols = this.shape[1]

for (i in 0 until rows) {
// Left bracket
val leftBracket = when {
rows == 1 -> "( "
i == 0 -> "⎛ "
i == rows - 1 -> "⎝ "
else -> "⎜ "
}
sb.append(leftBracket)

// Matrix elements
for (j in 0 until cols) {
if (j > 0) sb.append(", ")
sb.append(this[i, j].toString())
}

// Right bracket
val rightBracket = when {
rows == 1 -> " )"
i == 0 -> " ⎞"
i == rows - 1 -> " ⎠"
else -> " ⎟"
}
sb.append(rightBracket)

if (i < rows - 1) sb.append("\n")
}
sb.toString()
}
else -> {
// Higher rank tensors - use toString
this.toString()
}
}
}
Loading
Loading