From f364060acfa20539b5c4ff7b89a89c3b2236efce Mon Sep 17 00:00:00 2001 From: Commander Tvis Date: Thu, 11 Jun 2020 12:16:22 +0700 Subject: [PATCH 1/4] Add project stub --- kmath-nd4j/build.gradle.kts | 3 +++ settings.gradle.kts | 1 + 2 files changed, 4 insertions(+) create mode 100644 kmath-nd4j/build.gradle.kts diff --git a/kmath-nd4j/build.gradle.kts b/kmath-nd4j/build.gradle.kts new file mode 100644 index 000000000..5da7d66b7 --- /dev/null +++ b/kmath-nd4j/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("scientifik.jvm") +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 57173250b..afb5598b4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -39,6 +39,7 @@ include( ":kmath-commons", ":kmath-viktor", ":kmath-koma", + ":kmath-nd4j", ":kmath-prob", ":kmath-io", ":kmath-dimensions", -- 2.34.1 From 3df9892de53c0aa719091ad3d0c4aa0405081655 Mon Sep 17 00:00:00 2001 From: Commander Tvis Date: Thu, 11 Jun 2020 14:10:39 +0700 Subject: [PATCH 2/4] Implement the ND4J module for scalars --- build.gradle.kts | 1 + kmath-nd4j/build.gradle.kts | 10 ++++++++-- .../INDArrayScalarsIterator.kt | 19 +++++++++++++++++++ .../scientifik.kmath.nd4j/ND4JStructure.kt | 14 ++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt create mode 100644 kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt diff --git a/build.gradle.kts b/build.gradle.kts index 6d102a77a..10e030520 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,6 +11,7 @@ allprojects { repositories { jcenter() maven("https://dl.bintray.com/kotlin/kotlinx") + mavenCentral() } group = "scientifik" diff --git a/kmath-nd4j/build.gradle.kts b/kmath-nd4j/build.gradle.kts index 5da7d66b7..59354a8f9 100644 --- a/kmath-nd4j/build.gradle.kts +++ b/kmath-nd4j/build.gradle.kts @@ -1,3 +1,9 @@ -plugins { - id("scientifik.jvm") +plugins { id("scientifik.jvm") } + +dependencies { + api(project(":kmath-core")) + api("org.nd4j:nd4j-api:1.0.0-beta7") + testImplementation("org.deeplearning4j:deeplearning4j-core:1.0.0-beta7") + testImplementation("org.nd4j:nd4j-native-platform:1.0.0-beta7") + testImplementation("org.slf4j:slf4j-simple:1.7.30") } diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt new file mode 100644 index 000000000..2c2dc970f --- /dev/null +++ b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt @@ -0,0 +1,19 @@ +package scientifik.kmath.nd4j + +import org.nd4j.linalg.api.ndarray.INDArray +import org.nd4j.linalg.api.shape.Shape + +internal class INDArrayScalarsIterator(private val iterateOver: INDArray) : Iterator> { + private var i: Int = 0 + + override fun hasNext(): Boolean = i < iterateOver.length() + + override fun next(): Pair { + val idx = if (iterateOver.ordering() == 'c') + Shape.ind2subC(iterateOver, i++.toLong())!! + else + Shape.ind2sub(iterateOver, i++.toLong())!! + + return narrowToIntArray(idx) to iterateOver.getScalar(*idx) + } +} diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt new file mode 100644 index 000000000..eb9f9b80c --- /dev/null +++ b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt @@ -0,0 +1,14 @@ +package scientifik.kmath.nd4j + +import org.nd4j.linalg.api.ndarray.INDArray +import scientifik.kmath.structures.NDStructure + +internal fun narrowToIntArray(la: LongArray): IntArray = IntArray(la.size) { la[it].toInt() } + +data class ND4JStructure(val ndArray: INDArray) : NDStructure { + override val shape: IntArray + get() = narrowToIntArray(ndArray.shape()) + + override fun get(index: IntArray): INDArray = ndArray.getScalar(*index) + override fun elements(): Sequence> = Sequence { INDArrayScalarsIterator(ndArray) } +} -- 2.34.1 From 9a4dd315072e6cb27c430c799074b1dd36a06f94 Mon Sep 17 00:00:00 2001 From: Commander Tvis Date: Thu, 11 Jun 2020 14:17:46 +0700 Subject: [PATCH 3/4] Move narrowToIntArray to new file --- kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt | 3 +++ .../src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt new file mode 100644 index 000000000..5d341dd68 --- /dev/null +++ b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt @@ -0,0 +1,3 @@ +package scientifik.kmath.nd4j + +internal fun narrowToIntArray(la: LongArray): IntArray = IntArray(la.size) { la[it].toInt() } \ No newline at end of file diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt index eb9f9b80c..1d0301ff9 100644 --- a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt +++ b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt @@ -3,8 +3,6 @@ package scientifik.kmath.nd4j import org.nd4j.linalg.api.ndarray.INDArray import scientifik.kmath.structures.NDStructure -internal fun narrowToIntArray(la: LongArray): IntArray = IntArray(la.size) { la[it].toInt() } - data class ND4JStructure(val ndArray: INDArray) : NDStructure { override val shape: IntArray get() = narrowToIntArray(ndArray.shape()) -- 2.34.1 From d0cc75098bdc523c1c5f945c5a83a460efa00af8 Mon Sep 17 00:00:00 2001 From: Commander Tvis Date: Thu, 11 Jun 2020 14:36:19 +0700 Subject: [PATCH 4/4] Rework with specialized NDStructure implementations --- .../kotlin/scientifik.kmath.nd4j/Arrays.kt | 3 +- .../INDArrayScalarsIterator.kt | 19 ---------- .../scientifik.kmath.nd4j/ND4JStructure.kt | 12 ------ .../scientifik.kmath.nd4j/NDArrayIterators.kt | 37 +++++++++++++++++++ .../ScalarsND4JStructure.kt | 34 +++++++++++++++++ 5 files changed, 73 insertions(+), 32 deletions(-) delete mode 100644 kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt delete mode 100644 kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt create mode 100644 kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/NDArrayIterators.kt create mode 100644 kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ScalarsND4JStructure.kt diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt index 5d341dd68..3d5062a4f 100644 --- a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt +++ b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/Arrays.kt @@ -1,3 +1,4 @@ package scientifik.kmath.nd4j -internal fun narrowToIntArray(la: LongArray): IntArray = IntArray(la.size) { la[it].toInt() } \ No newline at end of file +internal fun widenToLongArray(ia: IntArray): LongArray = LongArray(ia.size) { ia[it].toLong() } +internal fun narrowToIntArray(la: LongArray): IntArray = IntArray(la.size) { la[it].toInt() } diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt deleted file mode 100644 index 2c2dc970f..000000000 --- a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/INDArrayScalarsIterator.kt +++ /dev/null @@ -1,19 +0,0 @@ -package scientifik.kmath.nd4j - -import org.nd4j.linalg.api.ndarray.INDArray -import org.nd4j.linalg.api.shape.Shape - -internal class INDArrayScalarsIterator(private val iterateOver: INDArray) : Iterator> { - private var i: Int = 0 - - override fun hasNext(): Boolean = i < iterateOver.length() - - override fun next(): Pair { - val idx = if (iterateOver.ordering() == 'c') - Shape.ind2subC(iterateOver, i++.toLong())!! - else - Shape.ind2sub(iterateOver, i++.toLong())!! - - return narrowToIntArray(idx) to iterateOver.getScalar(*idx) - } -} diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt deleted file mode 100644 index 1d0301ff9..000000000 --- a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ND4JStructure.kt +++ /dev/null @@ -1,12 +0,0 @@ -package scientifik.kmath.nd4j - -import org.nd4j.linalg.api.ndarray.INDArray -import scientifik.kmath.structures.NDStructure - -data class ND4JStructure(val ndArray: INDArray) : NDStructure { - override val shape: IntArray - get() = narrowToIntArray(ndArray.shape()) - - override fun get(index: IntArray): INDArray = ndArray.getScalar(*index) - override fun elements(): Sequence> = Sequence { INDArrayScalarsIterator(ndArray) } -} diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/NDArrayIterators.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/NDArrayIterators.kt new file mode 100644 index 000000000..426b1ec2d --- /dev/null +++ b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/NDArrayIterators.kt @@ -0,0 +1,37 @@ +package scientifik.kmath.nd4j + +import org.nd4j.linalg.api.ndarray.INDArray +import org.nd4j.linalg.api.shape.Shape + +internal sealed class INDArrayIteratorBase(protected val iterateOver: INDArray) : Iterator> { + private var i: Int = 0 + + override fun hasNext(): Boolean = i < iterateOver.length() + + abstract fun getSingle(indices: LongArray): T + + final override fun next(): Pair { + val la = if (iterateOver.ordering() == 'c') + Shape.ind2subC(iterateOver, i++.toLong())!! + else + Shape.ind2sub(iterateOver, i++.toLong())!! + + return narrowToIntArray(la) to getSingle(la) + } +} + +internal class INDArrayDoubleIterator(iterateOver: INDArray) : INDArrayIteratorBase(iterateOver) { + override fun getSingle(indices: LongArray): Double = iterateOver.getDouble(*indices) +} + +internal class INDArrayLongIterator(iterateOver: INDArray) : INDArrayIteratorBase(iterateOver) { + override fun getSingle(indices: LongArray) = iterateOver.getLong(*indices) +} + +internal class INDArrayIntIterator(iterateOver: INDArray) : INDArrayIteratorBase(iterateOver) { + override fun getSingle(indices: LongArray) = iterateOver.getInt(*narrowToIntArray(indices)) +} + +internal class INDArrayFloatIterator(iterateOver: INDArray) : INDArrayIteratorBase(iterateOver) { + override fun getSingle(indices: LongArray) = iterateOver.getFloat(*indices) +} diff --git a/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ScalarsND4JStructure.kt b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ScalarsND4JStructure.kt new file mode 100644 index 000000000..ef8c3ec2e --- /dev/null +++ b/kmath-nd4j/src/main/kotlin/scientifik.kmath.nd4j/ScalarsND4JStructure.kt @@ -0,0 +1,34 @@ +package scientifik.kmath.nd4j + +import org.nd4j.linalg.api.ndarray.INDArray +import scientifik.kmath.structures.NDStructure + +interface INDArrayStructureBase : NDStructure { + val ndArray: INDArray + + override val shape: IntArray + get() = narrowToIntArray(ndArray.shape()) + + fun elementsIterator(): Iterator> + override fun elements(): Sequence> = Sequence { elementsIterator() } +} + +data class INDArrayIntStructure(override val ndArray: INDArray) : INDArrayStructureBase { + override fun elementsIterator(): Iterator> = INDArrayIntIterator(ndArray) + override fun get(index: IntArray): Int = ndArray.getInt(*index) +} + +data class INDArrayLongStructure(override val ndArray: INDArray) : INDArrayStructureBase { + override fun elementsIterator(): Iterator> = INDArrayLongIterator(ndArray) + override fun get(index: IntArray): Long = ndArray.getLong(*widenToLongArray(index)) +} + +data class INDArrayDoubleStructure(override val ndArray: INDArray) : INDArrayStructureBase { + override fun elementsIterator(): Iterator> = INDArrayDoubleIterator(ndArray) + override fun get(index: IntArray): Double = ndArray.getDouble(*index) +} + +data class INDArrayFloatStructure(override val ndArray: INDArray) : INDArrayStructureBase { + override fun elementsIterator(): Iterator> = INDArrayFloatIterator(ndArray) + override fun get(index: IntArray): Float = ndArray.getFloat(*index) +} -- 2.34.1