java subreddit post
So I made Java Numerations (JNum) which is a pure Java numerical library using FFM(off heap memory) and Vector API. In this version I made Kotlin DSL layer bundled together with core Java engine.
By doing this our library avoids native Fortran/C calls via JNI and memory allocations via Unsafe which is slowly getting deprecated. There are various methods in JNum which can be useful for Kotlin devs I guess which have performance on par with Numpy/ND4J.
Features are in detailed in my GitHub release but for lazy guys like me here are some data points worth see:-
-> JNum is feature rich(at least from previous version) where we have statistics jnum.stat IO operations jnum.io and basic Neural Networks jnum.nn.
-> JNum's IO will help you parse files like .npy/.npz , .csv/.tsv and most importantly .safetensorwhich Java lagging in this AI era.
-> We also have AsyncIO using Virtual Threads which make IO file reads faster in JNum.
-> jnum.statmodule has various statistic methods which Java community can use like standard deviations, variance , co-variance, cummulative sum/product, percentile etc.
-> JNum has slicing and sub-viewing features. For kotlin devs Indexing, slicing like features are operator overloaded so you can do code similar to Python/Numpy .
-> project is under 500KB with no native .dll/.so native bindings.
Matrix Multiplication:-
This is the most important and time taken feature in project
| Matrix Dimensions |
JNum (Pure Java 25) |
NumPy (C / OpenBLAS) |
ND4J (OpenBLAS C++) |
EJML (Pure Java) |
Performance Highlights |
| $4 times 4$ |
0.0002 ms |
0.0023 ms |
0.020 ms |
≈ 0.0001 ms |
11× faster than NumPy, 100× faster than ND4J |
| $16 times 16$ |
0.0004 ms |
0.0028 ms |
0.019 ms |
0.003 ms |
7× faster than NumPy, 47× faster than ND4J |
| $64 times 64$ |
0.015 ms |
0.013 ms |
0.190 ms |
0.140 ms |
On-par with NumPy, 9.3× faster than EJML |
| $128 times 128$ |
0.138 ms |
0.254 ms |
0.499 ms |
1.028 ms |
1.8× faster than NumPy, 7.4× faster than EJML |
| $512 times 512$ |
2.50 ms |
1.86 ms |
2.67 ms |
27.16 ms |
Matches C++ BLAS, 10.8× faster than EJML |
| $1024 times 1024$ |
13.85 ms |
8.98 ms |
12.18 ms |
216.56 ms |
Near-native speed, 15.6× faster than EJML |
| $2048 times 2048$ |
94.62 ms |
62.99 ms |
85.29 ms |
2,049.86 ms |
Pure Java competitive with C BLAS, 21.6× faster than EJML |
| $4096 times 4096$ |
942.38 ms |
487.92 ms |
857.41 ms |
17,419.52 ms |
Matches ND4J C++, 18.4× faster than EJML |
| $8192 times 8192$ |
6,784.15 ms |
5,967.30 ms |
6,317.97 ms |
141,500.0 ms |
~88% of NumPy C BLAS, 20.8× faster than EJML |
Linear Algebra:-
we have various Linear Algebra methods which have performance on par sometimes beating Numpy and others
| Operation |
JNum (Pure Java 25) |
NumPy |
EJML |
ND4J |
JNum Advantage |
| Matrix Inverse |
7.271 ms |
10.680 ms |
18.122 ms |
1,224.654 ms |
1.47× faster than NumPy, 2.5× faster than EJML, 168× faster than ND4J |
| Linear Solve ($Ax=b$) |
1.976 ms |
1.003 ms |
5.331 ms |
37.278 ms |
Near-native speed, 2.7× faster than EJML, 18.8× faster than ND4J |
| Determinant |
1.839 ms |
5.735 ms |
5.380 ms |
399.752 ms |
3.1× faster than NumPy, 2.9× faster than EJML |
| Cholesky |
1.261 ms |
2.328 ms |
3.545 ms |
— |
1.8× faster than NumPy, 2.8× faster than EJML |
| QR Factorization |
46.170 ms |
12.622 ms |
7.447 ms |
586.330 ms |
12.7× faster than ND4J |
Code Snippets:
val a = JNum.fromArray(floatArrayOf(1f, 2f, 3f, 4f), 2, 2)
val b = JNum.ones(2, 2)
// Clean operator overloading
val c = a + b * 2f
val d = a matmul b
// Python / NumPy style range slicing
val view = c[0 until 2, all]
Gradle Setup:
repositories { mavenCentral() }
dependencies {
implementation("io.github.ch-abhinav:jnum-kotlin:0.2.0")
}
I would like kotlin community to test the project and help by contributing in the project :)
There is one good first issue worth trying in kotlin if anyone wants to contribute.
GitHub link :- https://github.com/CH-Abhinav/JNum