Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wrappers for gsl_rng and gsl_gaussian #14

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 77 additions & 54 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@file:Suppress("UNUSED_VARIABLE")

import de.undercouch.gradle.tasks.download.Download
import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
import org.jetbrains.kotlin.konan.target.HostManager
import ru.mipt.npm.gradle.Maturity
import space.kscience.kmath.gsl.codegen.matricesCodegen
import space.kscience.kmath.gsl.codegen.vectorsCodegen
Expand All @@ -20,24 +20,22 @@ version = "0.3.0-dev-3"
repositories {
mavenCentral()
maven("https://repo.kotlin.link")
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev")
}

kotlin {
explicitApi()

data class DownloadLinks(val gsl: String?)

val osName = System.getProperty("os.name")
val isWindows = osName.startsWith("Windows")
val nativeTargets = setOf(linuxX64(), mingwX64())

val (nativeTarget, downloadLinks) = when {
osName == "Linux" -> linuxX64() to DownloadLinks(
val downloadLinks = when (HostManager.hostOs()) {
"linux" -> DownloadLinks(
gsl = "https://anaconda.org/conda-forge/gsl/2.7/download/linux-64/gsl-2.7-he838d99_0.tar.bz2",
)

isWindows -> mingwX64() to DownloadLinks(
gsl = null,
)
"windows" -> DownloadLinks(gsl = null)

else -> {
logger.warn("Current OS cannot build any of kmath-gsl targets.")
Expand All @@ -48,55 +46,14 @@ kotlin {
val thirdPartyDir =
File("${System.getProperty("user.home")}/.konan/third-party/kmath-gsl-${project.property("version")}")

val main by nativeTarget.compilations.getting

val test by nativeTarget.compilations.getting {
defaultSourceSet.dependsOn(main.defaultSourceSet)
}

val libgsl by main.cinterops.creating

sourceSets {
all {
with(languageSettings) {
progressiveMode = true
useExperimentalAnnotation("kotlin.time.ExperimentalTime")
}
}

commonMain {
dependencies {
api("space.kscience:kmath-complex:0.3.0-dev-12")
}
}

val nativeMain by creating {
val codegen by tasks.creating {
matricesCodegen(kotlin.srcDirs.first().absolutePath + "/_Matrices.kt")
vectorsCodegen(kotlin.srcDirs.first().absolutePath + "/_Vectors.kt")
}

kotlin.srcDirs(files().builtBy(codegen))
dependsOn(commonMain.get())
}

val nativeTest by creating {
dependsOn(nativeMain)
dependsOn(commonTest.get())
}

main.defaultSourceSet.dependsOn(nativeMain)
test.defaultSourceSet.dependsOn(nativeTest)
}

val downloadGsl by tasks.creating(Download::class) {
if (downloadLinks.gsl == null) {
enabled = false
return@creating
}

src(downloadLinks.gsl)
dest(File(thirdPartyDir, "libgsl.tar.bz2"))
dest(thirdPartyDir.resolve("libgsl.tar.bz2"))
overwrite(false)
}

Expand All @@ -112,14 +69,14 @@ kotlin {
}

val writeDefFile by tasks.creating {
val file = libgsl.defFile
val file = projectDir.resolve("src/nativeInterop/cinterop/libgsl.def")
file.parentFile.mkdirs()
if (!file.exists()) file.createNewFile()

file.writeText(
"""
package=org.gnu.gsl
headers=gsl/gsl_blas.h gsl/gsl_linalg.h gsl/gsl_permute_matrix.h gsl/gsl_matrix.h gsl/gsl_vector.h gsl/gsl_errno.h
headers=gsl/gsl_blas.h gsl/gsl_linalg.h gsl/gsl_permute_matrix.h gsl/gsl_matrix.h gsl/gsl_vector.h gsl/gsl_errno.h gsl/gsl_rng.h gsl/gsl_randist.h gsl/gsl_cdf.h stdint.h

linkerOpts.linux=-L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -lblas
staticLibraries.linux=libgsl.a libgslcblas.a
Expand All @@ -135,13 +92,55 @@ kotlin {
return gsl_matrix_float_scale(a, x);
}

inline void gsl_rng_set2(const gsl_rng * r, uint64_t seed) {
gsl_rng_set(r, seed);
}

""".trimIndent()
)

dependsOn(extractGsl)
}

tasks[libgsl.interopProcessingTaskName].dependsOn(writeDefFile)
sourceSets {
all {
with(languageSettings) {
progressiveMode = true
optIn("kotlin.time.ExperimentalTime")
optIn("kotlin.contracts.ExperimentalContracts")
}
}

commonMain {
dependencies {
api("space.kscience:kmath-complex:0.3.0-dev-14")
api("space.kscience:kmath-stat:0.3.0-dev-14")
}
}

val nativeMain by creating {
val codegen by tasks.creating {
matricesCodegen(kotlin.srcDirs.first().resolve("linear/_Matrices.kt"))
vectorsCodegen(kotlin.srcDirs.first().resolve("linear/_Vectors.kt"))
}

kotlin.srcDirs(files().builtBy(codegen))
dependsOn(commonMain.get())
}

val nativeTest by creating {
dependsOn(commonTest.get())
}

configure(nativeTargets) {
val main by compilations.getting
val test by compilations.getting
main.defaultSourceSet.dependsOn(nativeMain)
test.defaultSourceSet.dependsOn(nativeTest)
val libgsl by main.cinterops.creating
tasks[libgsl.interopProcessingTaskName].dependsOn(writeDefFile)
}
}

targets.all {
compilations.all {
Expand All @@ -150,6 +149,20 @@ kotlin {
}
}

tasks {
withType<org.jetbrains.kotlin.gradle.tasks.CInteropProcess> {
onlyIf {
konanTarget == HostManager.host
}
}

withType<AbstractKotlinNativeCompile<*, *>> {
onlyIf {
compilation.konanTarget == HostManager.host
}
}
}

readme {
description = "Linear Algebra classes implemented with GNU Scientific Library"
maturity = Maturity.PROTOTYPE
Expand Down Expand Up @@ -199,6 +212,16 @@ afterEvaluate {
"https://mipt-npm.github.io/kmath/kmath-complex/",
"https://mipt-npm.github.io/kmath/kmath-complex/kmath-complex/package-list",
)

externalDocumentationLink(
"https://mipt-npm.github.io/kmath/kmath-state/",
"https://mipt-npm.github.io/kmath/kmath-stat/kmath-stat/package-list",
)

externalDocumentationLink(
"https://mipt-npm.github.io/kmath/kmath-coroutines/",
"https://mipt-npm.github.io/kmath/kmath-coroutines/kmath-coroutines/package-list",
)
}
}
}
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/matricesCodegen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ private fun Appendable.createMatrixClass(
/**
* Generates matrices source code for kmath-gsl.
*/
fun matricesCodegen(outputFile: String): Unit = File(outputFile).run {
fun matricesCodegen(outputFile: File): Unit = outputFile.run {
parentFile.mkdirs()
writer().use {
it.appendLine("package space.kscience.kmath.gsl")
it.appendLine("package space.kscience.kmath.gsl.linear")
it.appendLine()
it.appendLine("import kotlinx.cinterop.*")
it.appendLine("import org.gnu.gsl.*")
Expand Down
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/vectorsCodegen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ private fun Appendable.createVectorClass(
/**
* Generates vectors source code for kmath-gsl.
*/
fun vectorsCodegen(outputFile: String): Unit = File(outputFile).run {
fun vectorsCodegen(outputFile: File): Unit = outputFile.run {
parentFile.mkdirs()

writer().use { w ->
w.appendLine("package space.kscience.kmath.gsl")
w.appendLine("package space.kscience.kmath.gsl.linear")
w.appendLine()
w.appendLine("import kotlinx.cinterop.*")
w.appendLine("import org.gnu.gsl.*")
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
kotlin.code.style=official
kotlin.mpp.enableCInteropCommonization=true
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.mpp.stability.nowarn=true
kotlin.native.enableDependencyPropagation=false
kotlin.native.ignoreDisabledTargets=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
org.gradle.parallel=true
systemProp.org.gradle.internal.publish.checksums.insecure=true
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pluginManagement {
plugins {
id("ru.mipt.npm.gradle.project") version "0.10.2-fixrelease-1"
id("de.undercouch.download") version "4.1.2"
kotlin("multiplatform") version "1.5.21"
kotlin("multiplatform") version "1.5.30-RC"
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package space.kscience.kmath.gsl
package space.kscience.kmath.gsl.linear

import kotlinx.cinterop.*
import org.gnu.gsl.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package space.kscience.kmath.gsl
package space.kscience.kmath.gsl.linear

import kotlinx.cinterop.*
import org.gnu.gsl.*
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.complex.toComplex
import space.kscience.kmath.gsl.ensureHasGslErrorHandler
import space.kscience.kmath.linear.*
import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.misc.UnstableKMathAPI
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package space.kscience.kmath.gsl
package space.kscience.kmath.gsl.linear

import kotlinx.cinterop.AutofreeScope
import kotlinx.cinterop.CStructVar
import space.kscience.kmath.gsl.GslObject
import space.kscience.kmath.linear.Matrix
import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.structures.asSequence
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package space.kscience.kmath.gsl
package space.kscience.kmath.gsl.linear

import kotlinx.cinterop.AutofreeScope
import kotlinx.cinterop.CPointer
import kotlinx.cinterop.pointed
import org.gnu.gsl.gsl_permutation
import org.gnu.gsl.gsl_permutation_free
import org.gnu.gsl.gsl_permutation_get
import space.kscience.kmath.gsl.GslObject

internal class GslPermutation(
override val rawNativeHandle: CPointer<gsl_permutation>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package space.kscience.kmath.gsl
package space.kscience.kmath.gsl.linear

import kotlinx.cinterop.AutofreeScope
import kotlinx.cinterop.CStructVar
import space.kscience.kmath.gsl.GslObject
import space.kscience.kmath.linear.Point

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package space.kscience.kmath.gsl
package space.kscience.kmath.gsl.linear

import kotlinx.cinterop.*
import org.gnu.gsl.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package space.kscience.kmath.gsl
package space.kscience.kmath.gsl.linear

import kotlinx.cinterop.*
import org.gnu.gsl.*
Expand Down
25 changes: 25 additions & 0 deletions src/nativeMain/kotlin/stat/GslNormalDistribution.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package space.kscience.kmath.gsl.stat

import org.gnu.gsl.gsl_cdf_gaussian_P
import org.gnu.gsl.gsl_ran_gaussian
import org.gnu.gsl.gsl_ran_gaussian_pdf
import space.kscience.kmath.chains.Chain
import space.kscience.kmath.chains.SimpleChain
import space.kscience.kmath.distributions.UnivariateDistribution
import space.kscience.kmath.stat.RandomGenerator

public class GslNormalDistribution(public val mean: Double, public val standardDeviation: Double) :
UnivariateDistribution<Double> {
override fun probability(arg: Double): Double = gsl_ran_gaussian_pdf(arg - mean, standardDeviation)

@Deprecated("Unsafe function.", level = DeprecationLevel.ERROR)
override fun sample(generator: RandomGenerator): Chain<Double> {
require(generator is GslRandomGenerator) { "Only GslRandomGenerator generators are supported" }
return SimpleChain { gsl_ran_gaussian(generator.nativeHandle, standardDeviation) + mean }
}

@Suppress("DEPRECATION", "DEPRECATION_ERROR")
public fun sample(generator: GslRandomGenerator): Chain<Double> = sample(generator as RandomGenerator)

override fun cumulative(arg: Double): Double = gsl_cdf_gaussian_P(arg - mean, standardDeviation)
}
Loading