From 97c4b817173637818f1b496580afc688af8825d2 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 13 May 2021 11:02:20 +0300 Subject: [PATCH] Introduce PerformancePitfall annotation --- CHANGELOG.md | 1 + LICENSE | 201 ------------------ .../space/kscience/kmath/data/ColumnarData.kt | 2 + .../kscience/kmath/data/XYColumnarData.kt | 2 + .../kmath/linear/BufferedLinearSpace.kt | 3 + .../space/kscience/kmath/misc/annotations.kt | 12 ++ .../space/kscience/kmath/nd/BufferND.kt | 2 + .../space/kscience/kmath/nd/Structure1D.kt | 21 +- .../space/kscience/kmath/nd/Structure2D.kt | 8 +- .../space/kscience/kmath/nd/StructureND.kt | 4 + .../kmath/linear/DoubleLUSolverTest.kt | 2 + .../space/kscience/kmath/linear/MatrixTest.kt | 2 + .../kmath/structures/NumberNDFieldTest.kt | 2 + .../kmath/structures/LazyStructureND.kt | 2 + .../kscience/kmath/ejml/EjmlMatrixTest.kt | 2 + .../space/kscience/kmath/real/RealMatrix.kt | 4 + .../kaceince/kmath/real/DoubleMatrixTest.kt | 2 + .../kscience/kmath/jupyter/KMathJupyter.kt | 4 +- .../kscience/kmath/nd4j/Nd4jArrayStructure.kt | 2 + .../kmath/tensors/core/BufferedTensor.kt | 6 +- .../kmath/viktor/ViktorStructureND.kt | 2 + 21 files changed, 75 insertions(+), 211 deletions(-) delete mode 100644 LICENSE diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fba361d5..286be25e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Integration for any Field element - Extended operations for ND4J fields - Jupyter Notebook integration module (kmath-jupyter) +- `@PerformancePitfall` annotation to mark possibly slow API ### Changed - Exponential operations merged with hyperbolic functions diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt index abbb46583..febf615a8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.data +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.Symbol import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.Structure2D @@ -25,6 +26,7 @@ public interface ColumnarData { * A zero-copy method to represent a [Structure2D] as a two-column x-y data. * There could more than two columns in the structure. */ +@OptIn(PerformancePitfall::class) @UnstableKMathAPI public fun Structure2D.asColumnarData(mapping: Map): ColumnarData { require(shape[1] >= mapping.maxOf { it.value }) { "Column index out of bounds" } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt index 663908e90..56bb59826 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.data +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.Symbol import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.Structure2D @@ -49,6 +50,7 @@ public fun XYColumnarData(x: Buffer, y: Buffer): XYColum * A zero-copy method to represent a [Structure2D] as a two-column x-y data. * There could more than two columns in the structure. */ +@OptIn(PerformancePitfall::class) @UnstableKMathAPI public fun Structure2D.asXYData(xIndex: Int = 0, yIndex: Int = 1): XYColumnarData { require(shape[1] >= max(xIndex, yIndex)) { "Column index out of bounds" } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt index 62d2408e3..9b4451a62 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.linear +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke @@ -50,6 +51,7 @@ public class BufferedLinearSpace>( this } + @OptIn(PerformancePitfall::class) override fun Matrix.dot(other: Matrix): Matrix { require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" } return elementAlgebra { @@ -67,6 +69,7 @@ public class BufferedLinearSpace>( } } + @OptIn(PerformancePitfall::class) override fun Matrix.dot(vector: Point): Point { require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" } return elementAlgebra { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt index 7f53d96ce..18718de97 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt @@ -15,3 +15,15 @@ package space.kscience.kmath.misc @Retention(value = AnnotationRetention.BINARY) @RequiresOptIn("This API is unstable and could change in future", RequiresOptIn.Level.WARNING) public annotation class UnstableKMathAPI + +/** + * Marks API which could cause performance problems. The code, marked by this API is not necessary slow, but could cause + * slow-down in some cases. Refer to the documentation and benchmark it to be sure. + */ +@MustBeDocumented +@Retention(value = AnnotationRetention.BINARY) +@RequiresOptIn( + "Refer to the documentation to use this API in performance-critical code", + RequiresOptIn.Level.WARNING +) +public annotation class PerformancePitfall diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt index 1f608f478..425808aeb 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.nd +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory import space.kscience.kmath.structures.MutableBuffer @@ -32,6 +33,7 @@ public open class BufferND( override val shape: IntArray get() = strides.shape + @PerformancePitfall override fun elements(): Sequence> = strides.indices().map { it to this[it] } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt index 8ea6d0f02..cc0528793 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.nd +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.asMutableBuffer @@ -46,6 +47,8 @@ private value class Structure1DWrapper(val structure: StructureND) : Struc override val size: Int get() = structure.shape[0] override operator fun get(index: Int): T = structure[index] + + @PerformancePitfall override fun elements(): Sequence> = structure.elements() } @@ -55,6 +58,8 @@ private value class Structure1DWrapper(val structure: StructureND) : Struc private class MutableStructure1DWrapper(val structure: MutableStructureND) : MutableStructure1D { override val shape: IntArray get() = structure.shape override val size: Int get() = structure.shape[0] + + @PerformancePitfall override fun elements(): Sequence> = structure.elements() override fun get(index: Int): T = structure[index] @@ -62,8 +67,8 @@ private class MutableStructure1DWrapper(val structure: MutableStructureND) structure[intArrayOf(index)] = value } - override fun copy(): MutableBuffer = - structure.elements().map { it.second }.toMutableList().asMutableBuffer() + @PerformancePitfall + override fun copy(): MutableBuffer = structure.elements().map { it.second }.toMutableList().asMutableBuffer() } @@ -75,8 +80,10 @@ private value class Buffer1DWrapper(val buffer: Buffer) : Structure1D { override val shape: IntArray get() = intArrayOf(buffer.size) override val size: Int get() = buffer.size - override fun elements(): Sequence> = - buffer.asSequence().mapIndexed { index, value -> intArrayOf(index) to value } + @PerformancePitfall + override fun elements(): Sequence> = buffer.asSequence().mapIndexed { index, value -> + intArrayOf(index) to value + } override operator fun get(index: Int): T = buffer[index] } @@ -85,8 +92,10 @@ internal class MutableBuffer1DWrapper(val buffer: MutableBuffer) : Mutable override val shape: IntArray get() = intArrayOf(buffer.size) override val size: Int get() = buffer.size - override fun elements(): Sequence> = - buffer.asSequence().mapIndexed { index, value -> intArrayOf(index) to value } + @PerformancePitfall + override fun elements(): Sequence> = buffer.asSequence().mapIndexed { index, value -> + intArrayOf(index) to value + } override operator fun get(index: Int): T = buffer[index] override fun set(index: Int, value: T) { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index 28ae07a3c..8dce4ad6b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -5,10 +5,11 @@ package space.kscience.kmath.nd +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.VirtualBuffer import space.kscience.kmath.structures.MutableListBuffer +import space.kscience.kmath.structures.VirtualBuffer import kotlin.jvm.JvmInline import kotlin.reflect.KClass @@ -33,12 +34,14 @@ public interface Structure2D : StructureND { /** * The buffer of rows of this structure. It gets elements from the structure dynamically. */ + @PerformancePitfall public val rows: List> get() = List(rowNum) { i -> VirtualBuffer(colNum) { j -> get(i, j) } } /** * The buffer of columns of this structure. It gets elements from the structure dynamically. */ + @PerformancePitfall public val columns: List> get() = List(colNum) { j -> VirtualBuffer(rowNum) { i -> get(i, j) } } @@ -80,12 +83,14 @@ public interface MutableStructure2D : Structure2D, MutableStructureND { /** * The buffer of rows of this structure. It gets elements from the structure dynamically. */ + @PerformancePitfall override val rows: List> get() = List(rowNum) { i -> MutableBuffer1DWrapper(MutableListBuffer(colNum) { j -> get(i, j) })} /** * The buffer of columns of this structure. It gets elements from the structure dynamically. */ + @PerformancePitfall override val columns: List> get() = List(colNum) { j -> MutableBuffer1DWrapper(MutableListBuffer(rowNum) { i -> get(i, j) }) } } @@ -105,6 +110,7 @@ private value class Structure2DWrapper(val structure: StructureND) : Struc @UnstableKMathAPI override fun getFeature(type: KClass): F? = structure.getFeature(type) + @PerformancePitfall override fun elements(): Sequence> = structure.elements() } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index a3331d71a..b9f1a063a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.nd +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory @@ -48,6 +49,7 @@ public interface StructureND { * * @return the lazy sequence of pairs of indices to values. */ + @PerformancePitfall public fun elements(): Sequence> /** @@ -61,6 +63,7 @@ public interface StructureND { /** * Indicates whether some [StructureND] is equal to another one. */ + @PerformancePitfall public fun contentEquals(st1: StructureND, st2: StructureND): Boolean { if (st1 === st2) return true @@ -169,6 +172,7 @@ public interface MutableStructureND : StructureND { /** * Transform a structure element-by element in place. */ +@OptIn(PerformancePitfall::class) public inline fun MutableStructureND.mapInPlace(action: (IntArray, T) -> T): Unit = elements().forEach { (index, oldValue) -> this[index] = action(index, oldValue) } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index ebbbbe392..2d2a0952b 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -5,12 +5,14 @@ package space.kscience.kmath.linear +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.StructureND import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue +@OptIn(PerformancePitfall::class) fun assertMatrixEquals(expected: StructureND, actual: StructureND) { assertTrue { StructureND.contentEquals(expected, actual) } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index 250fa3433..170f9caf4 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.linear +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.as2D @@ -13,6 +14,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue @UnstableKMathAPI +@OptIn(PerformancePitfall::class) @Suppress("UNUSED_VARIABLE") class MatrixTest { @Test diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt index 99743d879..57393fadd 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.structures import space.kscience.kmath.linear.LinearSpace +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.invoke @@ -74,6 +75,7 @@ class NumberNDFieldTest { } object L2Norm : Norm, Double> { + @OptIn(PerformancePitfall::class) override fun norm(arg: StructureND): Double = kotlin.math.sqrt(arg.elements().sumOf { it.second.toDouble() }) } diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt index e2ecb4b2f..1cd16054a 100644 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.structures import kotlinx.coroutines.* import space.kscience.kmath.coroutines.Math +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.DefaultStrides import space.kscience.kmath.nd.StructureND @@ -24,6 +25,7 @@ public class LazyStructureND( public suspend fun await(index: IntArray): T = deferred(index).await() public override operator fun get(index: IntArray): T = runBlocking { deferred(index).await() } + @OptIn(PerformancePitfall::class) public override fun elements(): Sequence> { val strides = DefaultStrides(shape) val res = runBlocking { strides.indices().toList().map { index -> index to await(index) } } diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt index 485c53c38..50675bdac 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -12,12 +12,14 @@ import org.ejml.dense.row.factory.DecompositionFactory_DDRM import space.kscience.kmath.linear.DeterminantFeature import space.kscience.kmath.linear.LupDecompositionFeature import space.kscience.kmath.linear.getFeature +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.StructureND import kotlin.random.Random import kotlin.random.asJavaRandom import kotlin.test.* +@OptIn(PerformancePitfall::class) fun assertMatrixEquals(expected: StructureND, actual: StructureND) { assertTrue { StructureND.contentEquals(expected, actual) } } diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index c4656dd8a..8023236ea 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -3,9 +3,13 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +@file:OptIn(PerformancePitfall::class) +@file:Suppress("unused") + package space.kscience.kmath.real import space.kscience.kmath.linear.* +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.structures.Buffer diff --git a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleMatrixTest.kt b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleMatrixTest.kt index 84e604b18..b3e129c2e 100644 --- a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleMatrixTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleMatrixTest.kt @@ -7,6 +7,7 @@ package kaceince.kmath.real import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.matrix +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.StructureND import space.kscience.kmath.real.* @@ -15,6 +16,7 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue +@OptIn(PerformancePitfall::class) fun assertMatrixEquals(expected: StructureND, actual: StructureND) { assertTrue { StructureND.contentEquals(expected, actual) } } diff --git a/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt b/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt index 78b25af47..f3d553f2e 100644 --- a/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt +++ b/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt @@ -8,11 +8,12 @@ import org.jetbrains.kotlinx.jupyter.api.DisplayResult import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration -import space.kscience.kmath.expressions.MST import space.kscience.kmath.ast.rendering.FeaturedMathRendererWithPostProcess import space.kscience.kmath.ast.rendering.MathMLSyntaxRenderer import space.kscience.kmath.ast.rendering.renderWithStringBuilder import space.kscience.kmath.complex.Complex +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.operations.GroupOperations import space.kscience.kmath.operations.RingOperations @@ -55,6 +56,7 @@ internal class KMathJupyter : JupyterIntegration() { } } + @OptIn(PerformancePitfall::class) override fun Builder.onLoaded() { import( "space.kscience.kmath.ast.*", diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt index 79db86fcc..d37c91cb6 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.nd4j import org.nd4j.linalg.api.ndarray.INDArray +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.MutableStructureND import space.kscience.kmath.nd.StructureND @@ -24,6 +25,7 @@ public sealed class Nd4jArrayStructure : MutableStructureND { internal abstract fun elementsIterator(): Iterator> internal fun indicesIterator(): Iterator = ndArray.indicesIterator() + @PerformancePitfall public override fun elements(): Sequence> = Sequence(::elementsIterator) } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt index 858532abc..315dc4505 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt @@ -1,7 +1,8 @@ package space.kscience.kmath.tensors.core +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.Strides -import space.kscience.kmath.structures.* +import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.core.internal.TensorLinearStructure @@ -32,7 +33,8 @@ public open class BufferedTensor internal constructor( mutableBuffer[bufferStart + linearStructure.offset(index)] = value } + @PerformancePitfall override fun elements(): Sequence> = linearStructure.indices().map { - it to this[it] + it to get(it) } } diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt index dc1b45f5d..b7abf4304 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.viktor import org.jetbrains.bio.viktor.F64Array +import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.* import space.kscience.kmath.operations.DoubleField @@ -23,6 +24,7 @@ public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructur f64Buffer.set(*index, value = value) } + @PerformancePitfall public override fun elements(): Sequence> = DefaultStrides(shape).indices().map { it to get(it) } }