From 7d315e37d172d7726ec93e211ba323328cb6049e Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 27 Sep 2020 11:13:30 +0300 Subject: [PATCH] native memory --- .gitignore | 2 - CHANGELOG.md | 2 +- gradle.properties | 9 ++ kmath-core/build.gradle.kts | 1 + .../kscience/kmath/operations/Complex.kt | 6 +- .../kscience/kmath/structures/MemoryBuffer.kt | 2 +- kmath-memory/build.gradle.kts | 5 +- .../kmath}/memory/Memory.kt | 2 +- .../kmath}/memory/MemorySpec.kt | 2 +- .../kmath}/memory/DataViewMemory.kt | 2 +- .../kmath}/memory/ByteBufferMemory.kt | 2 +- .../kscience/kmath/memory/NativeMemory.kt | 93 +++++++++++++++++++ 12 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 gradle.properties rename kmath-memory/src/commonMain/kotlin/{scientifik => kscience/kmath}/memory/Memory.kt (99%) rename kmath-memory/src/commonMain/kotlin/{scientifik => kscience/kmath}/memory/MemorySpec.kt (98%) rename kmath-memory/src/jsMain/kotlin/{scientifik => kscience/kmath}/memory/DataViewMemory.kt (99%) rename kmath-memory/src/jvmMain/kotlin/{scientifik => kscience/kmath}/memory/ByteBufferMemory.kt (99%) create mode 100644 kmath-memory/src/nativeMain/kotlin/kscience/kmath/memory/NativeMemory.kt diff --git a/.gitignore b/.gitignore index a9294eff9..bade7f08c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,3 @@ out/ # Cache of project .gradletasknamecache - -gradle.properties \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e017fe565..09c6274df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - `fun` annotation for SAM interfaces in library - Explicit `public` visibility for all public APIs - Better trigonometric and hyperbolic functions for `AutoDiffField` (https://github.com/mipt-npm/kmath/pull/140). -- Automatic documentation generation for features (#139) +- Automatic README generation for features (#139) ### Changed - Package changed from `scientifik` to `kscience.kmath`. diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..930bba550 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,9 @@ +kotlin.code.style=official +kotlin.parallel.tasks.in.project=true +kotlin.mpp.enableGranularSourceSetsMetadata=true +kotlin.native.enableDependencyPropagation=false +kotlin.mpp.stability.nowarn=true + +org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m +org.gradle.parallel=true +systemProp.org.gradle.internal.publish.checksums.insecure=true \ No newline at end of file diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index d64a4d8a5..b56151abe 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } kotlin.sourceSets.commonMain { diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt index c0faf5dc5..24bfec054 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt @@ -1,11 +1,11 @@ package kscience.kmath.operations +import kscience.kmath.memory.MemoryReader +import kscience.kmath.memory.MemorySpec +import kscience.kmath.memory.MemoryWriter import kscience.kmath.structures.Buffer import kscience.kmath.structures.MemoryBuffer import kscience.kmath.structures.MutableBuffer -import kscience.memory.MemoryReader -import kscience.memory.MemorySpec -import kscience.memory.MemoryWriter import kotlin.math.* /** diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt index b7e6a8218..c171e7c1d 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt @@ -1,6 +1,6 @@ package kscience.kmath.structures -import kscience.memory.* +import kscience.kmath.memory.* /** * A non-boxing buffer over [Memory] object. diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts index 94527a6a3..9f92cca92 100644 --- a/kmath-memory/build.gradle.kts +++ b/kmath-memory/build.gradle.kts @@ -1 +1,4 @@ -plugins { id("ru.mipt.npm.mpp") } +plugins { + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") +} diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt b/kmath-memory/src/commonMain/kotlin/kscience/kmath/memory/Memory.kt similarity index 99% rename from kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt rename to kmath-memory/src/commonMain/kotlin/kscience/kmath/memory/Memory.kt index 8de9a7a0c..344a1f1d3 100644 --- a/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt +++ b/kmath-memory/src/commonMain/kotlin/kscience/kmath/memory/Memory.kt @@ -1,4 +1,4 @@ -package kscience.memory +package kscience.kmath.memory import kotlin.contracts.InvocationKind import kotlin.contracts.contract diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/kscience/kmath/memory/MemorySpec.kt similarity index 98% rename from kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt rename to kmath-memory/src/commonMain/kotlin/kscience/kmath/memory/MemorySpec.kt index d2cbb32fd..572dab0fa 100644 --- a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt +++ b/kmath-memory/src/commonMain/kotlin/kscience/kmath/memory/MemorySpec.kt @@ -1,4 +1,4 @@ -package kscience.memory +package kscience.kmath.memory /** * A specification to read or write custom objects with fixed size in bytes. diff --git a/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt b/kmath-memory/src/jsMain/kotlin/kscience/kmath/memory/DataViewMemory.kt similarity index 99% rename from kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt rename to kmath-memory/src/jsMain/kotlin/kscience/kmath/memory/DataViewMemory.kt index d6b8841e4..2146cd4e1 100644 --- a/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt +++ b/kmath-memory/src/jsMain/kotlin/kscience/kmath/memory/DataViewMemory.kt @@ -1,4 +1,4 @@ -package kscience.memory +package kscience.kmath.memory import org.khronos.webgl.ArrayBuffer import org.khronos.webgl.DataView diff --git a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt b/kmath-memory/src/jvmMain/kotlin/kscience/kmath/memory/ByteBufferMemory.kt similarity index 99% rename from kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt rename to kmath-memory/src/jvmMain/kotlin/kscience/kmath/memory/ByteBufferMemory.kt index c912b28ff..7a75b423e 100644 --- a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt +++ b/kmath-memory/src/jvmMain/kotlin/kscience/kmath/memory/ByteBufferMemory.kt @@ -1,4 +1,4 @@ -package kscience.memory +package kscience.kmath.memory import java.io.IOException import java.nio.ByteBuffer diff --git a/kmath-memory/src/nativeMain/kotlin/kscience/kmath/memory/NativeMemory.kt b/kmath-memory/src/nativeMain/kotlin/kscience/kmath/memory/NativeMemory.kt new file mode 100644 index 000000000..0e007a8ab --- /dev/null +++ b/kmath-memory/src/nativeMain/kotlin/kscience/kmath/memory/NativeMemory.kt @@ -0,0 +1,93 @@ +package kscience.kmath.memory + +@PublishedApi +internal class NativeMemory( + val array: ByteArray, + val startOffset: Int = 0, + override val size: Int = array.size +) : Memory { + @Suppress("NOTHING_TO_INLINE") + private inline fun position(o: Int): Int = startOffset + o + + override fun view(offset: Int, length: Int): Memory { + require(offset >= 0) { "offset shouldn't be negative: $offset" } + require(length >= 0) { "length shouldn't be negative: $length" } + require(offset + length <= size) { "Can't view memory outside the parent region." } + return NativeMemory(array, position(offset), length) + } + + override fun copy(): Memory { + val copy = array.copyOfRange(startOffset, startOffset + size) + return NativeMemory(copy) + } + + private val reader: MemoryReader = object : MemoryReader { + override val memory: Memory get() = this@NativeMemory + + override fun readDouble(offset: Int) = array.getDoubleAt(position(offset)) + + override fun readFloat(offset: Int) = array.getFloatAt(position(offset)) + + override fun readByte(offset: Int) = array[position(offset)] + + override fun readShort(offset: Int) = array.getShortAt(position(offset)) + + override fun readInt(offset: Int) = array.getIntAt(position(offset)) + + override fun readLong(offset: Int) = array.getLongAt(position(offset)) + + override fun release() { + // does nothing on JVM + } + } + + override fun reader(): MemoryReader = reader + + private val writer: MemoryWriter = object : MemoryWriter { + override val memory: Memory get() = this@NativeMemory + + override fun writeDouble(offset: Int, value: Double) { + array.setDoubleAt(position(offset), value) + } + + override fun writeFloat(offset: Int, value: Float) { + array.setFloatAt(position(offset), value) + } + + override fun writeByte(offset: Int, value: Byte) { + array.set(position(offset), value) + } + + override fun writeShort(offset: Int, value: Short) { + array.setShortAt(position(offset), value) + } + + override fun writeInt(offset: Int, value: Int) { + array.setIntAt(position(offset), value) + } + + override fun writeLong(offset: Int, value: Long) { + array.setLongAt(position(offset), value) + } + + override fun release() { + // does nothing on JVM + } + } + + override fun writer(): MemoryWriter = writer +} + +/** + * Wraps a [Memory] around existing [ByteArray]. This operation is unsafe since the array is not copied + * and could be mutated independently from the resulting [Memory]. + */ +public actual fun Memory.Companion.wrap(array: ByteArray): Memory = NativeMemory(array) + +/** + * Allocates the most effective platform-specific memory. + */ +public actual fun Memory.Companion.allocate(length: Int): Memory { + val array = ByteArray(length) + return NativeMemory(array) +} \ No newline at end of file