From 3ae2be06e2dd894d947c86be5d15be3b45d455e7 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 11 Oct 2020 21:24:10 +0700 Subject: [PATCH] Remove kotlinx-io dependency, use DeferScope to dispose native memory --- build.gradle.kts | 1 - .../kmath/gsl/codegen/matricesCodegen.kt | 9 +-- .../kmath/gsl/codegen/vectorsCodegen.kt | 5 +- kmath-gsl/build.gradle.kts | 9 ++- .../kotlin/kscience/kmath/gsl/GslComplex.kt | 19 ++--- .../kotlin/kscience/kmath/gsl/GslMatrix.kt | 4 +- .../kscience/kmath/gsl/GslMatrixContexts.kt | 42 ++++++----- .../kscience/kmath/gsl/GslMemoryHolder.kt | 10 ++- .../kotlin/kscience/kmath/gsl/GslVector.kt | 4 +- .../kotlin/kscience/kmath/gsl/_Matrices.kt | 72 ++++++++++--------- .../kotlin/kscience/kmath/gsl/_Vectors.kt | 40 ++++++----- kmath-gsl/src/nativeTest/kotlin/RealTest.kt | 52 +++++++------- 12 files changed, 155 insertions(+), 112 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 22ba35d18..56c9986c9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,6 @@ allprojects { maven("https://dl.bintray.com/kotlin/kotlin-eap") maven("https://dl.bintray.com/kotlin/kotlinx") maven("https://dl.bintray.com/hotkeytlt/maven") - maven("https://dl.bintray.com/commandertvis/kotlinx-io/") } group = "kscience.kmath" diff --git a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt index 92125f835..81324141c 100644 --- a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt +++ b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt @@ -19,8 +19,9 @@ private fun KtPsiFactory.createMatrixClass( @Language("kotlin") val text = """internal class $className( override val nativeHandle: CPointer<$structName>, - features: Set = emptySet() -) : GslMatrix<$kotlinTypeName, $structName>() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix<$kotlinTypeName, $structName>(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -30,7 +31,7 @@ private fun KtPsiFactory.createMatrixClass( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): $className = - ${className}(nativeHandle, this.features + features) + ${className}(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): $kotlinTypeName = ${ fn("gsl_matrixRget", cTypeName) @@ -42,7 +43,7 @@ private fun KtPsiFactory.createMatrixClass( override fun copy(): $className { val new = requireNotNull(${fn("gsl_matrixRalloc", cTypeName)}(rowNum.toULong(), colNum.toULong())) ${fn("gsl_matrixRmemcpy", cTypeName)}(new, nativeHandle) - return $className(new, features) + return $className(new, features, scope) } override fun close(): Unit = ${fn("gsl_matrixRfree", cTypeName)}(nativeHandle) diff --git a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt index 830e858c4..018d84773 100644 --- a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt +++ b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt @@ -18,7 +18,8 @@ private fun KtPsiFactory.createVectorClass( val structName = sn("gsl_vectorR", cTypeName) @Language("kotlin") val text = - """internal class $className(override val nativeHandle: CPointer<$structName>) : GslVector<$kotlinTypeName, $structName>() { + """internal class $className(override val nativeHandle: CPointer<$structName>, scope: DeferScope) + : GslVector<$kotlinTypeName, $structName>(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -30,7 +31,7 @@ private fun KtPsiFactory.createVectorClass( override fun copy(): $className { val new = requireNotNull(${fn("gsl_vectorRalloc", cTypeName)}(size.toULong())) ${fn("gsl_vectorRmemcpy", cTypeName)}(new, nativeHandle) - return ${className}(new) + return ${className}(new, scope) } override fun equals(other: Any?): Boolean { diff --git a/kmath-gsl/build.gradle.kts b/kmath-gsl/build.gradle.kts index dc8869ad1..e0bf1227d 100644 --- a/kmath-gsl/build.gradle.kts +++ b/kmath-gsl/build.gradle.kts @@ -8,6 +8,8 @@ plugins { } kotlin { + explicitApiWarning() + val nativeTarget = when (System.getProperty("os.name")) { "Mac OS X" -> macosX64("native") "Linux" -> linuxX64("native") @@ -20,7 +22,11 @@ kotlin { val main by nativeTarget.compilations.getting { cinterops { - val libgsl by creating { includeDirs { headerFilterOnly("/usr/include/", "/usr/local/") } } + val libgsl by creating { + includeDirs { + headerFilterOnly("/usr/include/", "/usr/local/") + } + } } } @@ -35,7 +41,6 @@ kotlin { dependencies { api(project(":kmath-core")) - api("org.jetbrains.kotlinx:kotlinx-io:0.2.0-tvis-3") } } } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt index 38d091414..582b1da57 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt @@ -14,8 +14,9 @@ internal fun Complex.toGsl(): CValue = cValue { internal class GslComplexMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -25,7 +26,7 @@ internal class GslComplexMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslComplexMatrix = - GslComplexMatrix(nativeHandle, this.features + features) + GslComplexMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): Complex = gsl_matrix_complex_get(nativeHandle, i.toULong(), j.toULong()).toKMath() @@ -36,7 +37,7 @@ internal class GslComplexMatrix( override fun copy(): GslComplexMatrix { val new = requireNotNull(gsl_matrix_complex_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_complex_memcpy(new, nativeHandle) - return GslComplexMatrix(new, features) + return GslComplexMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_complex_free(nativeHandle) @@ -47,18 +48,20 @@ internal class GslComplexMatrix( } } -internal class GslComplexVector(override val nativeHandle: CPointer) : - GslVector() { +internal class GslComplexVector(override val nativeHandle: CPointer, scope: DeferScope) : + GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() override fun get(index: Int): Complex = gsl_vector_complex_get(nativeHandle, index.toULong()).toKMath() - override fun set(index: Int, value: Complex): Unit = gsl_vector_complex_set(nativeHandle, index.toULong(), value.toGsl()) + + override fun set(index: Int, value: Complex): Unit = + gsl_vector_complex_set(nativeHandle, index.toULong(), value.toGsl()) override fun copy(): GslComplexVector { val new = requireNotNull(gsl_vector_complex_alloc(size.toULong())) gsl_vector_complex_memcpy(new, nativeHandle) - return GslComplexVector(new) + return GslComplexVector(new, scope) } override fun equals(other: Any?): Boolean { diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt index c7323437d..619372eef 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt @@ -1,10 +1,12 @@ package kscience.kmath.gsl import kotlinx.cinterop.CStructVar +import kotlinx.cinterop.DeferScope import kscience.kmath.linear.FeaturedMatrix import kscience.kmath.structures.NDStructure -public abstract class GslMatrix internal constructor(): GslMemoryHolder(), +public abstract class GslMatrix internal constructor(scope: DeferScope) : + GslMemoryHolder(scope), FeaturedMatrix { internal abstract operator fun set(i: Int, j: Int, value: T) internal abstract fun copy(): GslMatrix diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContexts.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContexts.kt index 4428b0185..3ac6582eb 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContexts.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContexts.kt @@ -1,6 +1,7 @@ package kscience.kmath.gsl import kotlinx.cinterop.CStructVar +import kotlinx.cinterop.DeferScope import kotlinx.cinterop.pointed import kscience.kmath.linear.MatrixContext import kscience.kmath.linear.Point @@ -18,8 +19,9 @@ internal inline fun GslMatrix.fill(initializer: internal inline fun GslVector.fill(initializer: (Int) -> T): GslVector = apply { (0 until size).forEach { index -> this[index] = initializer(index) } } -public abstract class GslMatrixContext internal constructor() : - MatrixContext { +public abstract class GslMatrixContext internal constructor( + internal val scope: DeferScope +) : MatrixContext { @Suppress("UNCHECKED_CAST") public fun Matrix.toGsl(): GslMatrix = (if (this is GslMatrix<*, *>) this as GslMatrix @@ -37,19 +39,19 @@ public abstract class GslMatrixContext() { +public class GslRealMatrixContext(scope: DeferScope) : GslMatrixContext(scope) { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = - GslRealMatrix(requireNotNull(gsl_matrix_alloc(rows.toULong(), columns.toULong()))) + GslRealMatrix(nativeHandle = requireNotNull(gsl_matrix_alloc(rows.toULong(), columns.toULong())), scope = scope) override fun produceDirtyVector(size: Int): GslVector = - GslRealVector(requireNotNull(gsl_vector_alloc(size.toULong()))) + GslRealVector(nativeHandle = requireNotNull(gsl_vector_alloc(size.toULong())), scope = scope) public override fun Matrix.dot(other: Matrix): GslMatrix { val x = toGsl().nativeHandle val a = other.toGsl().nativeHandle val result = requireNotNull(gsl_matrix_calloc(a.pointed.size1, a.pointed.size2)) gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, x, a, 1.0, result) - return GslRealMatrix(result) + return GslRealMatrix(result, scope = scope) } public override fun Matrix.dot(vector: Point): GslVector { @@ -57,7 +59,7 @@ public object GslRealMatrixContext : GslMatrixContext.times(value: Double): GslMatrix { @@ -79,19 +81,20 @@ public object GslRealMatrixContext : GslMatrixContext() { +public class GslFloatMatrixContext(scope: DeferScope) : + GslMatrixContext(scope) { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = - GslFloatMatrix(requireNotNull(gsl_matrix_float_alloc(rows.toULong(), columns.toULong()))) + GslFloatMatrix(requireNotNull(gsl_matrix_float_alloc(rows.toULong(), columns.toULong())), scope = scope) override fun produceDirtyVector(size: Int): GslVector = - GslFloatVector(requireNotNull(gsl_vector_float_alloc(size.toULong()))) + GslFloatVector(requireNotNull(gsl_vector_float_alloc(size.toULong())), scope) public override fun Matrix.dot(other: Matrix): GslMatrix { val x = toGsl().nativeHandle val a = other.toGsl().nativeHandle val result = requireNotNull(gsl_matrix_float_calloc(a.pointed.size1, a.pointed.size2)) gsl_blas_sgemm(CblasNoTrans, CblasNoTrans, 1f, x, a, 1f, result) - return GslFloatMatrix(result) + return GslFloatMatrix(nativeHandle = result, scope = scope) } public override fun Matrix.dot(vector: Point): GslVector { @@ -99,7 +102,7 @@ public object GslFloatMatrixContext : GslMatrixContext.times(value: Float): GslMatrix { @@ -121,19 +124,22 @@ public object GslFloatMatrixContext : GslMatrixContext() { - override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = - GslComplexMatrix(requireNotNull(gsl_matrix_complex_alloc(rows.toULong(), columns.toULong()))) +public class GslComplexMatrixContext(scope: DeferScope) : + GslMatrixContext(scope) { + override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = GslComplexMatrix( + nativeHandle = requireNotNull(gsl_matrix_complex_alloc(rows.toULong(), columns.toULong())), + scope = scope + ) override fun produceDirtyVector(size: Int): GslVector = - GslComplexVector(requireNotNull(gsl_vector_complex_alloc(size.toULong()))) + GslComplexVector(requireNotNull(gsl_vector_complex_alloc(size.toULong())), scope) public override fun Matrix.dot(other: Matrix): GslMatrix { val x = toGsl().nativeHandle val a = other.toGsl().nativeHandle val result = requireNotNull(gsl_matrix_complex_calloc(a.pointed.size1, a.pointed.size2)) gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, ComplexField.one.toGsl(), x, a, ComplexField.one.toGsl(), result) - return GslComplexMatrix(result) + return GslComplexMatrix(nativeHandle = result, scope = scope) } public override fun Matrix.dot(vector: Point): GslVector { @@ -141,7 +147,7 @@ public object GslComplexMatrixContext : GslMatrixContext.times(value: Complex): GslMatrix { diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt index 4c6aa17d7..d3544874d 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt @@ -2,8 +2,14 @@ package kscience.kmath.gsl import kotlinx.cinterop.CPointer import kotlinx.cinterop.CStructVar -import kotlinx.io.Closeable +import kotlinx.cinterop.DeferScope -public abstract class GslMemoryHolder internal constructor() : Closeable { +public abstract class GslMemoryHolder internal constructor(internal val scope: DeferScope) { internal abstract val nativeHandle: CPointer + + init { + scope.defer(::close) + } + + internal abstract fun close() } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt index 87fbce607..65b81f0d7 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt @@ -1,9 +1,11 @@ package kscience.kmath.gsl import kotlinx.cinterop.CStructVar +import kotlinx.cinterop.DeferScope import kscience.kmath.linear.Point -public abstract class GslVector internal constructor() : GslMemoryHolder(), Point { +public abstract class GslVector internal constructor(scope: DeferScope) : + GslMemoryHolder(scope), Point { internal abstract operator fun set(index: Int, value: T) internal abstract fun copy(): GslVector diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt index 06a9eb75e..a38534515 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt @@ -6,8 +6,9 @@ import org.gnu.gsl.* internal class GslRealMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -17,7 +18,7 @@ internal class GslRealMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslRealMatrix = - GslRealMatrix(nativeHandle, this.features + features) + GslRealMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): Double = gsl_matrix_get(nativeHandle, i.toULong(), j.toULong()) @@ -27,7 +28,7 @@ internal class GslRealMatrix( override fun copy(): GslRealMatrix { val new = requireNotNull(gsl_matrix_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_memcpy(new, nativeHandle) - return GslRealMatrix(new, features) + return GslRealMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_free(nativeHandle) @@ -40,8 +41,9 @@ internal class GslRealMatrix( internal class GslFloatMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -51,7 +53,7 @@ internal class GslFloatMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslFloatMatrix = - GslFloatMatrix(nativeHandle, this.features + features) + GslFloatMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): Float = gsl_matrix_float_get(nativeHandle, i.toULong(), j.toULong()) @@ -61,7 +63,7 @@ internal class GslFloatMatrix( override fun copy(): GslFloatMatrix { val new = requireNotNull(gsl_matrix_float_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_float_memcpy(new, nativeHandle) - return GslFloatMatrix(new, features) + return GslFloatMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_float_free(nativeHandle) @@ -74,8 +76,9 @@ internal class GslFloatMatrix( internal class GslShortMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -85,7 +88,7 @@ internal class GslShortMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslShortMatrix = - GslShortMatrix(nativeHandle, this.features + features) + GslShortMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): Short = gsl_matrix_short_get(nativeHandle, i.toULong(), j.toULong()) @@ -95,7 +98,7 @@ internal class GslShortMatrix( override fun copy(): GslShortMatrix { val new = requireNotNull(gsl_matrix_short_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_short_memcpy(new, nativeHandle) - return GslShortMatrix(new, features) + return GslShortMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_short_free(nativeHandle) @@ -108,8 +111,9 @@ internal class GslShortMatrix( internal class GslUShortMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -119,7 +123,7 @@ internal class GslUShortMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslUShortMatrix = - GslUShortMatrix(nativeHandle, this.features + features) + GslUShortMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): UShort = gsl_matrix_ushort_get(nativeHandle, i.toULong(), j.toULong()) @@ -129,7 +133,7 @@ internal class GslUShortMatrix( override fun copy(): GslUShortMatrix { val new = requireNotNull(gsl_matrix_ushort_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_ushort_memcpy(new, nativeHandle) - return GslUShortMatrix(new, features) + return GslUShortMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_ushort_free(nativeHandle) @@ -142,8 +146,9 @@ internal class GslUShortMatrix( internal class GslLongMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -153,7 +158,7 @@ internal class GslLongMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslLongMatrix = - GslLongMatrix(nativeHandle, this.features + features) + GslLongMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): Long = gsl_matrix_long_get(nativeHandle, i.toULong(), j.toULong()) @@ -163,7 +168,7 @@ internal class GslLongMatrix( override fun copy(): GslLongMatrix { val new = requireNotNull(gsl_matrix_long_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_long_memcpy(new, nativeHandle) - return GslLongMatrix(new, features) + return GslLongMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_long_free(nativeHandle) @@ -176,8 +181,9 @@ internal class GslLongMatrix( internal class GslULongMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -187,7 +193,7 @@ internal class GslULongMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslULongMatrix = - GslULongMatrix(nativeHandle, this.features + features) + GslULongMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): ULong = gsl_matrix_ulong_get(nativeHandle, i.toULong(), j.toULong()) @@ -197,7 +203,7 @@ internal class GslULongMatrix( override fun copy(): GslULongMatrix { val new = requireNotNull(gsl_matrix_ulong_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_ulong_memcpy(new, nativeHandle) - return GslULongMatrix(new, features) + return GslULongMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_ulong_free(nativeHandle) @@ -210,8 +216,9 @@ internal class GslULongMatrix( internal class GslIntMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -221,7 +228,7 @@ internal class GslIntMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslIntMatrix = - GslIntMatrix(nativeHandle, this.features + features) + GslIntMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): Int = gsl_matrix_int_get(nativeHandle, i.toULong(), j.toULong()) @@ -231,7 +238,7 @@ internal class GslIntMatrix( override fun copy(): GslIntMatrix { val new = requireNotNull(gsl_matrix_int_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_int_memcpy(new, nativeHandle) - return GslIntMatrix(new, features) + return GslIntMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_int_free(nativeHandle) @@ -244,8 +251,9 @@ internal class GslIntMatrix( internal class GslUIntMatrix( override val nativeHandle: CPointer, - features: Set = emptySet() -) : GslMatrix() { + features: Set = emptySet(), + scope: DeferScope +) : GslMatrix(scope) { override val rowNum: Int get() = nativeHandle.pointed.size1.toInt() @@ -255,7 +263,7 @@ internal class GslUIntMatrix( override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslUIntMatrix = - GslUIntMatrix(nativeHandle, this.features + features) + GslUIntMatrix(nativeHandle, this.features + features, scope) override operator fun get(i: Int, j: Int): UInt = gsl_matrix_uint_get(nativeHandle, i.toULong(), j.toULong()) @@ -265,7 +273,7 @@ internal class GslUIntMatrix( override fun copy(): GslUIntMatrix { val new = requireNotNull(gsl_matrix_uint_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_uint_memcpy(new, nativeHandle) - return GslUIntMatrix(new, features) + return GslUIntMatrix(new, features, scope) } override fun close(): Unit = gsl_matrix_uint_free(nativeHandle) diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt index 918fca825..8990416b3 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt @@ -3,7 +3,8 @@ package kscience.kmath.gsl import kotlinx.cinterop.* import org.gnu.gsl.* -internal class GslRealVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslRealVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -13,7 +14,7 @@ internal class GslRealVector(override val nativeHandle: CPointer) : override fun copy(): GslRealVector { val new = requireNotNull(gsl_vector_alloc(size.toULong())) gsl_vector_memcpy(new, nativeHandle) - return GslRealVector(new) + return GslRealVector(new, scope) } override fun equals(other: Any?): Boolean { @@ -24,7 +25,8 @@ internal class GslRealVector(override val nativeHandle: CPointer) : override fun close(): Unit = gsl_vector_free(nativeHandle) } -internal class GslFloatVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslFloatVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -34,7 +36,7 @@ internal class GslFloatVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslShortVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -55,7 +58,7 @@ internal class GslShortVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslUShortVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -76,7 +80,7 @@ internal class GslUShortVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslLongVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -97,7 +102,7 @@ internal class GslLongVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslULongVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -118,7 +124,7 @@ internal class GslULongVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslIntVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -139,7 +146,7 @@ internal class GslIntVector(override val nativeHandle: CPointer) override fun copy(): GslIntVector { val new = requireNotNull(gsl_vector_int_alloc(size.toULong())) gsl_vector_int_memcpy(new, nativeHandle) - return GslIntVector(new) + return GslIntVector(new, scope) } override fun equals(other: Any?): Boolean { @@ -150,7 +157,8 @@ internal class GslIntVector(override val nativeHandle: CPointer) override fun close(): Unit = gsl_vector_int_free(nativeHandle) } -internal class GslUIntVector(override val nativeHandle: CPointer) : GslVector() { +internal class GslUIntVector(override val nativeHandle: CPointer, scope: DeferScope) + : GslVector(scope) { override val size: Int get() = nativeHandle.pointed.size.toInt() @@ -160,7 +168,7 @@ internal class GslUIntVector(override val nativeHandle: CPointer 0.1 } - val mb = (ma * 20.0) - assertEquals(mb[0, 1], 2.0) - mb.close() - ma.close() + fun testScale() = memScoped { + (GslRealMatrixContext(this)) { + val ma = produce(10, 10) { _, _ -> 0.1 } + val mb = (ma * 20.0) + assertEquals(mb[0, 1], 2.0) + } } @Test - fun testDotOfMatrixAndVector() { - val ma = GslRealMatrixContext.produce(2, 2) { _, _ -> 100.0 } - val vb = RealBuffer(2) { 0.1 } - val res1 = GslRealMatrixContext { ma dot vb } - val res2 = RealMatrixContext { ma dot vb } - println(res1.asSequence().toList()) - println(res2.asSequence().toList()) - assertTrue(res1.contentEquals(res2)) - res1.close() + fun testDotOfMatrixAndVector() = memScoped { + (GslRealMatrixContext(this)) { + val ma = produce(2, 2) { _, _ -> 100.0 } + val vb = RealBuffer(2) { 0.1 } + val res1 = ma dot vb + val res2 = RealMatrixContext { ma dot vb } + println(res1.asSequence().toList()) + println(res2.asSequence().toList()) + assertTrue(res1.contentEquals(res2)) + } } @Test - fun testDotOfMatrixAndMatrix() { - val ma = GslRealMatrixContext.produce(2, 2) { _, _ -> 100.0 } - val mb = GslRealMatrixContext.produce(2, 2) { _, _ -> 100.0 } - val res1 = GslRealMatrixContext { ma dot mb } - val res2 = RealMatrixContext { ma dot mb } - println(res1.rows.asIterable().map { it.asSequence() }.flatMap(Sequence<*>::toList)) - println(res2.rows.asIterable().map { it.asSequence() }.flatMap(Sequence<*>::toList)) - assertEquals(res1, res2) - ma.close() - mb.close() + fun testDotOfMatrixAndMatrix() = memScoped { + (GslRealMatrixContext(this)) { + val ma = produce(2, 2) { _, _ -> 100.0 } + val mb = produce(2, 2) { _, _ -> 100.0 } + val res1 = ma dot mb + val res2 = RealMatrixContext { ma dot mb } + println(res1.rows.asIterable().map { it.asSequence() }.flatMap(Sequence<*>::toList)) + println(res2.rows.asIterable().map { it.asSequence() }.flatMap(Sequence<*>::toList)) + assertEquals(res1, res2) + } } }