diff --git a/.gitignore b/.gitignore index a8ace37e..8aa6c979 100644 --- a/.gitignore +++ b/.gitignore @@ -71,14 +71,16 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser -### Example user template template -### Example user template - +### Lounres's template # IntelliJ project files .idea +!.idea/icon.svg +!.idea/scopes +!.idea/copyright *.iml out gen + ### Gradle template .gradle **/build/ diff --git a/.idea/copyright/Kone.xml b/.idea/copyright/Kone.xml new file mode 100644 index 00000000..dbe382ea --- /dev/null +++ b/.idea/copyright/Kone.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000..c4054f8b --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 00000000..377869c9 --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/.idea/scopes/Kone_sources.xml b/.idea/scopes/Kone_sources.xml new file mode 100644 index 00000000..7e1062a4 --- /dev/null +++ b/.idea/scopes/Kone_sources.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index ccbe2a23..2f53db79 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,18 +1,27 @@ @file:Suppress("SuspiciousCollectionReassignment") import io.kotest.framework.multiplatform.gradle.KotestMultiplatformCompilerGradlePlugin +import kotlinx.benchmark.gradle.BenchmarksExtension +import kotlinx.benchmark.gradle.BenchmarksPlugin import org.jetbrains.dokka.gradle.DokkaPlugin import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask +import org.jetbrains.kotlin.allopen.gradle.AllOpenExtension +import org.jetbrains.kotlin.allopen.gradle.AllOpenGradleSubplugin import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Warning import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper +import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilationToRunnableFiles +import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget @Suppress("DSL_SCOPE_VIOLATION") plugins { with(libs.plugins) { alias(kotlin.multiplatform) apply false + alias(allopen) apply false + alias(kotlinx.benchmark) apply false alias(kotest.multiplatform) apply false alias(dokka) } @@ -44,6 +53,7 @@ val jvmTargetApi = properties["jvmTarget"] as String fun PluginManager.withPlugin(pluginDep: PluginDependency, block: AppliedPlugin.() -> Unit) = withPlugin(pluginDep.pluginId, block) fun PluginManager.withPlugin(pluginDepProvider: Provider, block: AppliedPlugin.() -> Unit) = withPlugin(pluginDepProvider.get().pluginId, block) +inline fun Iterable.withEach(action: T.() -> Unit) = forEach { it.action() } publishing { @@ -64,7 +74,8 @@ featuresManagement { kotlinOptions { jvmTarget = jvmTargetApi } - compileKotlinTask.apply { + compileTaskProvider.apply { + // TODO: Check if really is necessary kotlinOptions { jvmTarget = jvmTargetApi } @@ -84,17 +95,13 @@ featuresManagement { on("kotlin multiplatform") { apply() configure { -// explicitApi = Warning - jvm { compilations.all { kotlinOptions { jvmTarget = jvmTargetApi - } - compileKotlinTask.apply { - kotlinOptions { - jvmTarget = jvmTargetApi - } + freeCompilerArgs += listOf( +// "-Xlambdas=indy" + ) } } testRuns.all { @@ -169,15 +176,13 @@ featuresManagement { configure { @Suppress("UNUSED_VARIABLE") sourceSets { - all { - if (name.endsWith("test", ignoreCase = true)) { - dependencies { - with(rootProject.libs.kotest) { - implementation(framework.engine) - implementation(framework.datatest) - implementation(assertions.core) - implementation(property) - } + val commonTest by getting { + dependencies { + with(rootProject.libs.kotest) { + implementation(framework.engine) + implementation(framework.datatest) + implementation(assertions.core) + implementation(property) } } } @@ -190,6 +195,111 @@ featuresManagement { } } } + on("examples") { + @Suppress("UNUSED_VARIABLE") + fun NamedDomainObjectContainer>.configureExamples() { + val main by getting + val examples by creating { + defaultSourceSet { + dependsOn(main.defaultSourceSet) + kotlin.setSrcDirs(listOf("src/examples/kotlin")) + resources.setSrcDirs(listOf("src/examples/resources")) + } + + task("runJvmExample") { + group = "examples" + classpath = output.classesDirs + compileDependencyFiles + runtimeDependencyFiles + mainClass.set("com.lounres.${project.extra["artifactPrefix"]}${project.name}.examples.MainKt") + } + } + } + pluginManager.withPlugin(rootProject.libs.plugins.kotlin.jvm) { + configure { + @Suppress("UNUSED_VARIABLE") + target.compilations.configureExamples() + } + } + pluginManager.withPlugin(rootProject.libs.plugins.kotlin.multiplatform) { + configure { + @Suppress("UNUSED_VARIABLE") + targets.getByName("jvm").compilations.configureExamples() + } + } + } + on("benchmark") { + apply() + apply() + the().annotation("org.openjdk.jmh.annotations.State") + + pluginManager.withPlugin(rootProject.libs.plugins.kotlin.jvm) { + logger.error("kotlinx.benchmark plugging in and setting is not yet implemented for Kotlin/JVM plug-in") +// configure { +// // ... +// } + } + pluginManager.withPlugin(rootProject.libs.plugins.kotlin.multiplatform) { + val kotlinxBenchmarkDebug = (property("kotlinx.benchmark.debug") as String?).toBoolean() + val benchmarksExtension = the() + @Suppress("UNUSED_VARIABLE") + configure { + val commonBenchmarks by sourceSets.creating { + dependencies { + implementation(rootProject.libs.kotlinx.benchmark.runtime) + } + } + targets.filter { it.platformType != KotlinPlatformType.common }.withEach { + compilations { + val main by getting + val benchmarks by creating { + defaultSourceSet { + dependsOn(main.defaultSourceSet) + dependsOn(commonBenchmarks) + } + } + + val benchmarksSourceSetName = benchmarks.defaultSourceSet.name + + // TODO: For now js target causes problems with tasks initialisation + // Looks similar to + // 1. https://github.com/Kotlin/kotlinx-benchmark/issues/101 + // 2. https://github.com/Kotlin/kotlinx-benchmark/issues/93 + // TODO: For now native targets work unstable + // May be similar to https://github.com/Kotlin/kotlinx-benchmark/issues/94 + // Because of all the issues, only JVM targets are registered for now + if (platformType == KotlinPlatformType.jvm) { + benchmarksExtension.targets.register(benchmarksSourceSetName) + // Fix kotlinx-benchmarks bug + if (platformType == KotlinPlatformType.jvm) afterEvaluate { + val jarTaskName = "${benchmarksSourceSetName}BenchmarkJar" + tasks.findByName(jarTaskName).let { if (it is org.gradle.jvm.tasks.Jar) it else null }?.apply { + if (kotlinxBenchmarkDebug) logger.warn("Corrected kotlinx.benchmark task $jarTaskName") + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + } + } + } + } + } + } + } + + @Suppress("UNUSED_VARIABLE") + configure { + configurations { + // TODO: Create my own configurations + val main by getting { + warmups = 20 + iterations = 10 + iterationTime = 3 + } + val smoke by creating { + warmups = 5 + iterations = 3 + iterationTime = 500 + iterationTimeUnit = "ms" + } + } + } + } on("dokka") { apply() dependencies { diff --git a/gradle.properties b/gradle.properties index e12303de..cb6f8ade 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,12 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.native.ignoreDisabledTargets=true +kotlin.incremental.js.ir=true jvmTarget=11 +kotlinx.benchmark.debug=false + #org.gradle.configureondemand=true org.gradle.parallel=true org.gradle.jvmargs=-XX:MaxMetaspaceSize=2G \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 60aa7159..efd0ed11 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,25 +1,40 @@ [versions] kotlin = "1.8.0" + +kmath = "0.3.0" + kotlinx-coroutines = "1.6.4" +kotlinx-atomicfu = "0.18.5" +kotlinx-serialization = "1.4.1" kotlinx-datetime = "0.4.0" +kotlinx-kover = "0.6.0" +kotlinx-benchmark = "0.4.6" +kotlinx-binary-compatibility-validator = "0.12.0" +kotlinx-knit = "0.4.0" + kotest = "5.5.1" dokka = "1.7.20" mkdocs-gradle-plugin = "2.4.0" -kover = "0.6.0" -benchmark = "0.4.4" -binary-compatibility-validator = "0.12.0" -kmath = "0.3.0" [plugins] +# Kotlin plugins kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +# Kotlin side plugins +allopen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin" } + +# kotlinx plugins +kotlinx-atomicfu = { id = "org.jetbrains.kotlinx:atomicfu-gradle-plugin", version.ref = "kotlinx-atomicfu" } +kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +kotlinx-kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kotlinx-kover" } +kotlinx-benchmark = { id = "org.jetbrains.kotlinx.benchmark", version.ref = "kotlinx-benchmark" } +kotlinx-binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "kotlinx-binary-compatibility-validator" } +kotlinx-knit = { id = "org.jetbrains.kotlinx:kotlinx-knit", version.ref = "kotlinx-knit" } + kotest-multiplatform = { id = "io.kotest.multiplatform", version.ref = "kotest" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } mkdocs = { id = "ru.vyarus.mkdocs", version.ref = "mkdocs-gradle-plugin" } -kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } -benchmark = { id = "org.jetbrains.kotlinx.benchmark", version.ref = "benchmark" } -binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" } [libraries] # kotlinx.coroutines @@ -27,9 +42,15 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-c kotlinx-coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } +# kotlinx.serialization +kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } + # kotlinx.datetime kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } +# kotlinx.benchmark +kotlinx-benchmark-runtime = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime", version.ref = "kotlinx-benchmark" } + # Kotest kotest-assertions-core = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" } kotest-framework-engine = { module = "io.kotest:kotest-framework-engine", version.ref = "kotest" } diff --git a/libs/main/polynomial/src/commonBenchmarks/kotlin/main.kt b/libs/main/polynomial/src/commonBenchmarks/kotlin/main.kt new file mode 100644 index 00000000..2f0f9160 --- /dev/null +++ b/libs/main/polynomial/src/commonBenchmarks/kotlin/main.kt @@ -0,0 +1,18 @@ +@file:Suppress("unused") + +package com.lounres.kone.polynomial.benchmarks + +//import com.lounres.kone.algebraic.field +//import com.lounres.kone.polynomial.ListPolynomial +//import com.lounres.kone.polynomial.listPolynomialSpace +//import kotlinx.benchmark.* +// +//@State(Scope.Benchmark) +//class ListPolynomialBenchmark { +// @Benchmark +// fun stupidTest(blackhole: Blackhole) = Double.field.listPolynomialSpace { +// val polynomial = ListPolynomial(1.1, 1.1) +// blackhole.consume(polynomial pow 16u) +// } +//} +// \ No newline at end of file diff --git a/libs/main/polynomial/src/examples/kotlin/main.kt b/libs/main/polynomial/src/examples/kotlin/main.kt new file mode 100644 index 00000000..65155ffa --- /dev/null +++ b/libs/main/polynomial/src/examples/kotlin/main.kt @@ -0,0 +1,11 @@ +package com.lounres.kone.polynomial.examples + +import com.lounres.kone.algebraic.field +import com.lounres.kone.polynomial.labeledPolynomialSpace +import space.kscience.kmath.expressions.Symbol + + +fun main() = Double.field.labeledPolynomialSpace { + val x = Symbol.x + println(x * (x - 1) * (x - 2)) +} \ No newline at end of file diff --git a/libs/main/polynomial/src/jvmBenchmarks/kotlin/main.kt b/libs/main/polynomial/src/jvmBenchmarks/kotlin/main.kt new file mode 100644 index 00000000..be56252c --- /dev/null +++ b/libs/main/polynomial/src/jvmBenchmarks/kotlin/main.kt @@ -0,0 +1,24 @@ +@file:Suppress("unused") + +package com.lounres.kone.polynomial.benchmarks + +import com.lounres.kone.algebraic.invoke +import com.lounres.kone.algebraic.field +import com.lounres.kone.polynomial.ListPolynomial +import com.lounres.kone.polynomial.listPolynomialSpace +import kotlinx.benchmark.* +import java.util.concurrent.TimeUnit + +@State(Scope.Benchmark) +class ListPolynomialBenchmark { + val listPolynomialContext = Double.field.listPolynomialSpace + + val polynomial = ListPolynomial(1.1, 1.1) + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + fun Blackhole.stupidTest() = listPolynomialContext { + consume(polynomial pow 16u) + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 49aa716c..81f6773d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -42,7 +42,9 @@ featuresManagement { "libs public" since { hasAnyOfTags("libs main", "libs misc") } "libs" since { hasAnyOfTags("libs main", "libs misc", "libs util") } "kotlin multiplatform" since { hasAnyOfTags("libs") } - "kotlin common settings" since { hasAnyOfTags("kotlin jvm", "kotlin multiplatform") } + "kotlin common settings" since { hasTag("libs") } + "examples" since { hasTag("libs") } + "benchmark" since { hasTag("libs") } "kotest" since { hasTag("libs") } "publishing" since { hasAnyOfTags("libs") } "dokka" since { hasTag("publishing") }