Skip to content

[R] Research existing Kotlin libraries with tensors #98

Description

@michalharakal

Collect and analyze existing libraries for tensors calculations written in Kotlin. Evaluate support for:

  • Kotlin multiplatform
  • support for custom data types
  • memory layout
  • supported operations

Activity

  1. michalharakal commented on Sep 14, 2025

    @michalharakal
    ContributorAuthor

    Tensor Kotlin

    https://github.com/qoncept/tensor-kotlin

    Overview

    TensorKotlin is a lightweight tensor calculation library with TensorFlow-like APIs designed for JVM environments. This analysis evaluates the library's support for Kotlin multiplatform, custom data types, memory layout, and available operations.

    1. Kotlin Multiplatform Support

    Current Status: ❌ Not Supported

    Findings:

    • Project uses IntelliJ IDEA module configuration (.iml file) as JAVA_MODULE type
    • No multiplatform build configuration (no build.gradle.kts with multiplatform plugin)
    • Heavy reliance on Java-specific APIs:
      • java.util.Arrays for string representation
      • Math class for mathematical operations (sin, cos, exp, etc.)
      • TestNG framework for testing (Java-specific)
      • Java reflection in assertion checking (Tensor::class.java.desiredAssertionStatus())

    Platform Dependencies:

    • All mathematical operations use java.lang.Math
    • Array operations rely on Java's built-in utilities
    • Testing framework is Java-specific (TestNG)

    Recommendation:
    To support multiplatform, the library would need:

    • Migration to Gradle with Kotlin Multiplatform plugin
    • Replace java.lang.Math with kotlin.math functions
    • Use Kotlin's native array operations instead of Java utilities
    • Migrate tests to kotlin.test framework
    • Abstract platform-specific functionality

    2. Custom Data Types Support

    Current Status: ❌ Limited (Float Only)

    Findings:

    • Tensor class hardcoded to use FloatArray for data storage
    • No generic type parameters in class definition: class Tensor(val shape: Shape, val elements: FloatArray)
    • All operations assume Float data type
    • No abstraction for different numeric types

    Limitations:

    • Cannot create tensors with Double, Int, Long, or custom numeric types
    • No type-safe operations for different data types
    • Mathematical operations fixed to Float precision

    Current Constructor Signatures:

    class Tensor(val shape: Shape, val elements: FloatArray)
    constructor(shape: Shape, element: Float = 0.0f)

    Recommendation:
    To support custom data types:

    • Make Tensor generic: class Tensor<T : Number>(val shape: Shape, val elements: Array<T>)
    • Create type-specific implementations or use sealed classes
    • Add type conversion utilities
    • Implement type-safe mathematical operations

    3. Memory Layout

    Current Implementation: Row-Major Layout

    Storage Model:

    • Uses standard Kotlin/Java FloatArray for linear storage
    • Row-major memory layout (C-style)
    • Contiguous memory allocation
    • Index calculation: shape.dimensions.zip(indices).fold(0) { a, x -> a * x.first + x.second }

    Memory Management:

    • Relies on JVM garbage collection
    • No manual memory management
    • Each tensor operation creates new FloatArray instances
    • No in-place operations to minimize memory allocation

    Indexing Performance:

    • O(n) index calculation where n is number of dimensions
    • No stride pre-computation for faster access
    • Index bounds checking on every access (when assertions enabled)

    Broadcasting Support:

    • Efficient broadcasting implementation for operations between tensors of different shapes
    • Uses modulo arithmetic for element repetition: infiniteB[i % infiniteB.size]

    Memory Efficiency Concerns:

    • No memory pooling or reuse mechanisms
    • Frequent array allocations during operations
    • No lazy evaluation or computation graphs

    4. Supported Operations

    Arithmetic Operations ✅

    • Element-wise: +, -, *, /
    • Scalar operations: * scalar, / scalar
    • Broadcasting: Supports tensor operations with different but compatible shapes

    Mathematical Functions ✅ (via TensorMath.kt)

    • Trigonometric: sin, cos, tan, asin, acos, atan
    • Hyperbolic: sinh, cosh, tanh
    • Exponential/Logarithmic: exp, log, sqrt, cbrt
    • Power: pow (tensor^tensor, tensor^scalar)
    • Activation: sigmoid

    Matrix Operations ✅

    • Matrix Multiplication: matmul() for 2D matrices only
    • Limitations: No support for batch matrix multiplication or higher-order tensor contractions

    Neural Network Operations ✅ (via TensorNN.kt)

    • Activation Functions: relu, softmax
    • Convolution: 2D convolution (conv2d) with 4D filter support
    • Pooling: Max pooling (maxPool) for 3D tensors
    • Advanced: Supports strides, padding (implicit), multi-channel processing

    Tensor Manipulation ✅

    • Indexing: Single element access tensor[i, j, k]
    • Slicing: Range-based slicing tensor[1..3, 2..4]
    • Shape: Multi-dimensional shape management

    Missing Operations ❌

    • Reduction Operations: No sum, mean, max, min along axes
    • Linear Algebra: No transpose, determinant, eigenvalues, SVD
    • Tensor Contractions: No einsum or generalized tensor contractions
    • Batch Operations: No batch matrix multiplication
    • Reshaping: No reshape, flatten, squeeze operations
    • Concatenation: No concat, stack, split operations
    • Statistical: No variance, standard deviation, percentiles

    5. Code Quality and Architecture

    Strengths ✅

    • Clean, readable Kotlin code
    • Comprehensive test coverage for existing operations
    • Efficient broadcasting implementation
    • Good separation of concerns (Math, NN, Utils in separate files)
    • Proper error handling with assertions

    Areas for Improvement ❌

    • No documentation or KDoc comments
    • Hardcoded to single data type
    • Platform-specific dependencies
    • No extensibility mechanisms
    • Limited operation set compared to modern tensor libraries

    6. Performance Characteristics

    Computational Efficiency

    • Good: Direct array operations without unnecessary abstractions
    • Good: Efficient broadcasting with modulo arithmetic
    • Moderate: Matrix multiplication implementation (basic triple loop)
    • Poor: No BLAS integration or native acceleration

    Memory Efficiency

    • Poor: No memory reuse or pooling
    • Poor: Frequent allocations during operations
    • Moderate: Contiguous memory layout for cache efficiency

    7. Recommendations for Enhancement

    Immediate Priorities

    1. Add Generic Type Support: Enable Double, Int, and custom numeric types
    2. Implement Missing Operations: Add reduction, linear algebra, and reshaping operations
    3. Optimize Memory Usage: Implement in-place operations and memory pooling
    4. Add Documentation: Comprehensive KDoc and usage examples

    Medium-term Goals

    1. Multiplatform Migration: Support Native, JS, and other Kotlin targets
    2. Performance Optimization: BLAS integration, SIMD operations
    3. Extended Neural Network Operations: Batch normalization, dropout, advanced pooling

    Long-term Vision

    1. GPU Acceleration: CUDA/OpenCL support for compute-intensive operations
    2. Automatic Differentiation: Gradient computation for machine learning
    3. Computation Graphs: Lazy evaluation and optimization

    Conclusion

    TensorKotlin is a solid foundation for tensor operations on JVM with clean implementation and good test coverage. However, it currently lacks multiplatform support, is limited to Float data types, and has a restricted operation set compared to modern tensor libraries. The memory layout is efficient but could benefit from optimization for performance-critical applications.

    The library is suitable for educational purposes and simple tensor operations but would require significant enhancements for production machine learning workloads or multiplatform deployment.

  2. michalharakal commented on Sep 14, 2025

    @michalharakal
    ContributorAuthor

    Numeriko

    see discussion on slack

    https://github.com/TomasVolker/numeriko.git

    NumeriKo Tensor Implementation Analysis Report

    Date: September 14, 2025
    Analysis Focus: Kotlin Multiplatform Support, Custom Data Types, Mathematical Operations, and Code Quality

    Executive Summary

    NumeriKo is a sophisticated NDArray library for Kotlin that implements tensor operations through a well-designed interface-based architecture. The project demonstrates strong foundations in API design and mathematical operations but has limitations in multiplatform support and custom data type extensibility.

    1. Kotlin Multiplatform Support

    Current Status: Limited

    Findings:

    • JVM-Only Implementation: The project currently uses kotlin("jvm") plugin exclusively
    • No Multiplatform Configuration: No kotlin("multiplatform") plugin or platform-specific source sets
    • JVM-Specific Dependencies: Uses JUnit 5 and other JVM-specific testing frameworks
    • Build System: Gradle-based with version 8.11+ and Kotlin 2.2.20

    Architecture Compatibility:

    • Interface-based design is inherently multiplatform-friendly
    • No platform-specific code detected in core interfaces
    • Mathematical operations rely on Kotlin stdlib, which is multiplatform compatible

    Recommendations:

    • Migrate to kotlin("multiplatform") plugin
    • Create platform-specific source sets (commonMain, jvmMain, jsMain, nativeMain)
    • Replace JVM-specific test dependencies with kotlin-test multiplatform
    • Consider performance implications for JavaScript and Native targets

    2. Custom Data Types Support

    Current Status: Moderately Extensible

    Type Hierarchy:

    ArrayND<T> (Generic)
        ↓
    NumericArrayND<N: Number> (Numeric constraint)
        ↓
    DoubleArrayND, IntArrayND (Concrete implementations)
    

    Extensibility Analysis:

    ✅ Strengths:

    • Generic Foundation: Base ArrayND<T> interface supports any type
    • Numeric Abstraction: NumericArrayND<N: Number> provides numeric operations framework
    • Type Safety: Strong typing with covariant generics
    • Dimension Flexibility: Supports 0D through ND arrays

    ❌ Limitations for Custom Types (int4, ternary):

    • Number Constraint: Custom types must extend Number class (problematic for int4, ternary)
    • Arithmetic Operations: No abstraction for custom arithmetic beyond standard Number methods
    • Memory Layout: No custom memory layout support for packed types like int4
    • Value Constraints: No built-in support for constrained domains (e.g., ternary: {-1, 0, 1})

    Example Custom Type Requirements:

    // For int4 support, would need:
    interface PackedNumericArray<T: PackedNumber> : ArrayND<T>
    
    // For ternary support, would need:
    interface ConstrainedArray<T: ConstrainedValue> : ArrayND<T>

    Current Custom Type Support:

    • ✅ Any reference type implementing required interfaces
    • ✅ Custom Number subclasses (with limitations)
    • ❌ Efficient packed types (int4, int2, etc.)
    • ❌ Non-numeric constrained types (ternary values)
    • ❌ Custom arithmetic operations beyond Number interface

    3. Supported Mathematical Operations

    Current Status: Comprehensive for Standard Types

    Core Operations:

    ✅ Element Access & Manipulation:

    • Multi-dimensional indexing with getValue(vararg indices: Int)
    • Advanced indexing with First, Last, All, Size abstractions
    • View-based slicing and sub-array access
    • Range operations: array[2..4], array[First until Last]

    ✅ Array Transformations:

    • Shape manipulation: reshape, transpose, lowerRank, higherRank
    • Dimension operations: arrayAlongAxis, view-based operations
    • Stacking operations for combining arrays

    ✅ Mathematical Functions (DoubleArray types):

    // Trigonometric
    cos, sin, tan, cosh, sinh, tanh
    
    // Exponential/Logarithmic  
    exp, ln, log10, log2
    
    // Applied element-wise to Array1D and Array2D

    ✅ Reduction Operations:

    // Comprehensive reduction framework
    reduce(initial, combine) // Custom reductions
    // Axis-specific reductions for 2D and ND arrays

    ✅ Element-wise Operations:

    • Function application via elementWise { transform }
    • Custom function composition with RealFunction1 type alias
    • Operator overloading through extension functions

    ❌ Missing Standard Operations:

    • Linear algebra: matrix multiplication, eigenvalues, SVD
    • Statistical functions: mean, variance, standard deviation
    • Comparison operations: argmax, argmin, sorting
    • Broadcasting for different array shapes
    • Convolution and signal processing operations

    DSL Support:

    // Elegant construction syntax
    val vector = D[1, 2, 3, 4, 5]
    val matrix = D[D[1, 2], D[3, 4]]
    val intArray = I[1, 2, 3]

    4. Ease of Use and Code Quality

    Current Status: High Quality with Some Issues

    ✅ Strengths:

    API Design:

    • Intuitive DSL: Clean construction syntax with D[...] and I[...]
    • Type Safety: Strong typing prevents common errors
    • Consistent Naming: Clear patterns like DoubleArray1D, MutableDoubleArray1D
    • Interface Segregation: Separate interfaces for different capabilities

    Code Organization:

    • Logical Package Structure: Clear separation by dimension and type
    • Interface-First Design: Promotes testability and extensibility
    • View-Based Operations: Efficient memory usage through views vs copies
    • Comprehensive Index System: Sophisticated relative indexing

    Developer Experience:

    // Natural syntax for common operations
    val matrix = D[D[1, 2, 3], D[4, 5, 6]]
    val element = matrix[First, Last]  // matrix[0, 2] = 3
    val slice = matrix[All, 1..2]      // column slice

    ❌ Current Issues:

    Compilation Problems:

    • Return Type Conflicts: Mutable interface inheritance issues
    • Deprecated API Usage: toShort() calls need toInt().toShort()
    • Uninitialized Variables: Some view classes have uninitialized shape properties

    Documentation:

    • Limited Examples: Few usage examples in codebase
    • Missing Documentation: Complex index system needs more explanation
    • No Performance Guides: No guidance on view vs copy operations

    Testing:

    • Compilation Blocks Testing: Current issues prevent test execution
    • Comprehensive Test Structure: Well-organized when working

    Disabled Modules:

    • numeriko-complex: Complex number support disabled
    • kyplot: Plotting capabilities disabled
    • sandbox: Examples and playground disabled

    5. Recommendations

    Immediate (High Priority)

    1. Fix Compilation Issues

      • Resolve mutable interface return type conflicts
      • Update deprecated API usage for Kotlin 2.2.20
      • Initialize uninitialized variables in view classes
    2. Re-enable Disabled Modules

      • Enable numeriko-complex for complex number support
      • Enable sandbox for examples and documentation

    Short Term (Medium Priority)

    1. Expand Mathematical Operations

      • Add linear algebra operations (matrix multiplication, decompositions)
      • Implement statistical functions (mean, variance, etc.)
      • Add comparison and sorting operations
    2. Improve Documentation

      • Add comprehensive API documentation
      • Create usage examples and tutorials
      • Document performance characteristics

    Long Term (Lower Priority)

    1. Multiplatform Migration

      • Migrate to Kotlin Multiplatform
      • Create platform-specific optimizations
      • Ensure consistent behavior across platforms
    2. Custom Data Type Framework

      • Design abstraction for packed numeric types
      • Create framework for constrained value types
      • Implement efficient memory layouts

    Conclusion

    NumeriKo demonstrates excellent architectural foundations with a sophisticated interface hierarchy and elegant DSL. The project excels in type safety, API design, and extensibility patterns. However, it currently faces limitations in multiplatform support and custom data type extensibility for specialized types like int4 and ternary values.

    The immediate focus should be on resolving compilation issues and expanding the mathematical operations library. The long-term vision of supporting custom data types and multiplatform deployment is achievable but requires significant architectural enhancements.

    Overall Assessment:

    • Architecture: ⭐⭐⭐⭐⭐ Excellent
    • Multiplatform Support: ⭐⭐ Limited (JVM only)
    • Custom Data Types: ⭐⭐⭐ Good (with noted limitations)
    • Mathematical Operations: ⭐⭐⭐⭐ Very Good
    • Code Quality: ⭐⭐⭐⭐ Very Good (pending compilation fixes)
    • Ease of Use: ⭐⭐⭐⭐ Very Good
  3. michalharakal commented on Jun 10, 2026

    @michalharakal
    ContributorAuthor

    Closing — research concluded. The tensor-library investigation resulted in SKaiNET's own tensor stack (tensor/Tensor.kt + backend ops). No further research action pending.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions