Merge pull request #357 from therealansh/kmathJafama

integrate: Jafama + KMath
This commit is contained in:
Alexander Nozik 2021-06-12 10:25:25 +03:00 committed by GitHub
commit c1b105db2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 294 additions and 1 deletions

View File

@ -200,6 +200,12 @@ One can still use generic algebras though.
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
<hr/> <hr/>
* ### [kmath-jafama](kmath-jafama)
>
>
> **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-jupyter](kmath-jupyter) * ### [kmath-jupyter](kmath-jupyter)
> >
> >

View File

@ -30,6 +30,7 @@ kotlin {
implementation(project(":kmath-stat")) implementation(project(":kmath-stat"))
implementation(project(":kmath-dimensions")) implementation(project(":kmath-dimensions"))
implementation(project(":kmath-for-real")) implementation(project(":kmath-for-real"))
implementation(project(":kmath-jafama"))
implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.3.0") implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.3.0")
} }
} }
@ -42,7 +43,6 @@ kotlin {
implementation(project(":kmath-kotlingrad")) implementation(project(":kmath-kotlingrad"))
implementation(project(":kmath-viktor")) implementation(project(":kmath-viktor"))
implementation("org.nd4j:nd4j-native:1.0.0-beta7") implementation("org.nd4j:nd4j-native:1.0.0-beta7")
// uncomment if your system supports AVX2 // uncomment if your system supports AVX2
// val os = System.getProperty("os.name") // val os = System.getProperty("os.name")
// //
@ -95,6 +95,11 @@ benchmark {
commonConfiguration() commonConfiguration()
include("BigIntBenchmark") include("BigIntBenchmark")
} }
configurations.register("jafamaDouble") {
commonConfiguration()
include("JafamaBenchmark")
}
} }
// Fix kotlinx-benchmarks bug // Fix kotlinx-benchmarks bug

View File

@ -0,0 +1,56 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.benchmarks
import kotlinx.benchmark.Blackhole
import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
import space.kscience.kmath.jafama.JafamaDoubleField
import space.kscience.kmath.jafama.StrictJafamaDoubleField
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke
import kotlin.math.cos
import kotlin.math.exp
import kotlin.math.pow
@State(Scope.Benchmark)
internal class JafamaBenchmark {
@Benchmark
fun jafamaBench(blackhole: Blackhole) = invokeBenchmarks(jafama, blackhole)
@Benchmark
fun coreBench(blackhole: Blackhole) = invokeBenchmarks(core,blackhole)
@Benchmark
fun strictJafamaBench(blackhole: Blackhole) = invokeBenchmarks(strictJafama,blackhole)
@Benchmark
fun kotlinMathBench(blackhole: Blackhole) = invokeBenchmarks(kotlinMath, blackhole)
private fun invokeBenchmarks(expr: Double, blackhole: Blackhole) {
blackhole.consume(expr)
}
private companion object {
private val x: Double = Double.MAX_VALUE
private val jafama = JafamaDoubleField{
x * power(x, 1_000_000) * exp(x) / cos(x)
}
private val kotlinMath = x * x.pow(1_000_000) * exp(x) / cos(x)
private val core = DoubleField {
x * power(x, 1_000_000) * exp(x) / cos(x)
}
private val strictJafama = StrictJafamaDoubleField {
x * power(x, 1_000_000) * exp(x) / cos(x)
}
}
}

View File

@ -44,6 +44,8 @@ dependencies {
implementation("org.slf4j:slf4j-simple:1.7.30") implementation("org.slf4j:slf4j-simple:1.7.30")
// plotting // plotting
implementation("space.kscience:plotlykt-server:0.4.0") implementation("space.kscience:plotlykt-server:0.4.0")
//jafama
implementation(project(":kmath-jafama"))
} }
kotlin.sourceSets.all { kotlin.sourceSets.all {

View File

@ -0,0 +1,17 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.jafama
import net.jafama.FastMath
fun main(){
val a = JafamaDoubleField.number(2.0)
val b = StrictJafamaDoubleField.power(FastMath.E,a)
println(JafamaDoubleField.add(b,a))
println(StrictJafamaDoubleField.ln(b))
}

80
kmath-jafama/README.md Normal file
View File

@ -0,0 +1,80 @@
# Module kmath-jafama
Jafama based implementation of DoubleField of kmath-operations.
- JafamaDoubleField : DoubleField implementation using FastMath
- StrictJafamaDoubleField - DoubleField implementation using StrictFastMath
## Examples
Different Operations on DoubleField
```kotlin
package space.kscience.kmath.jafama
import net.jafama.FastMath
fun main(){
val a = JafamaDoubleField.number(2.0)
val b = StrictJafamaDoubleField.power(FastMath.E,a)
println(JafamaDoubleField.add(b,a))
println(StrictJafamaDoubleField.ln(b))
}
```
## Benchmarks
Comparing Operations on DoubleField and JafamaDoubleField
```bash
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.coreBench
Warm-up 1: 384414358.081 ops/s
Iteration 1: 374827571.951 ops/s
Iteration 2: 479335182.332 ops/s
Iteration 3: 475483069.577 ops/s
Iteration 4: 478235949.414 ops/s
Iteration 5: 472256385.114 ops/s
456027631.678 ±(99.9%) 175106815.384 ops/s [Average]
(min, avg, max) = (374827571.951, 456027631.678, 479335182.332), stdev = 45474683.880
CI (99.9%): [280920816.294, 631134447.061] (assumes normal distribution)
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.jafamaBench
Warm-up 1: 359418665.041 ops/s
Iteration 1: 335704885.798 ops/s
Iteration 2: 427684801.542 ops/s
Iteration 3: 452193034.265 ops/s
Iteration 4: 433855064.931 ops/s
Iteration 5: 453863386.566 ops/s
420660234.620 ±(99.9%) 188028426.875 ops/s [Average]
(min, avg, max) = (335704885.798, 420660234.620, 453863386.566), stdev = 48830385.349
CI (99.9%): [232631807.746, 608688661.495] (assumes normal distribution)
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.kotlinMathBench
Warm-up 1: 371570418.113 ops/s
Iteration 1: 379281146.127 ops/s
Iteration 2: 465234403.109 ops/s
Iteration 3: 470621634.240 ops/s
Iteration 4: 467074553.006 ops/s
Iteration 5: 466424840.144 ops/s
449727315.325 ±(99.9%) 151837475.500 ops/s [Average]
(min, avg, max) = (379281146.127, 449727315.325, 470621634.240), stdev = 39431710.207
CI (99.9%): [297889839.825, 601564790.825] (assumes normal distribution)
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.strictJafamaBench
Warm-up 1: 371241281.065 ops/s
Iteration 1: 374490259.387 ops/s
Iteration 2: 464995837.424 ops/s
Iteration 3: 469788706.385 ops/s
Iteration 4: 469528470.682 ops/s
Iteration 5: 456727921.978 ops/s
447106239.171 ±(99.9%) 157629035.980 ops/s [Average]
(min, avg, max) = (374490259.387, 447106239.171, 469788706.385), stdev = 40935760.071
CI (99.9%): [289477203.192, 604735275.151] (assumes normal distribution)
```

View File

@ -0,0 +1,20 @@
plugins {
id("ru.mipt.npm.gradle.jvm")
}
dependencies {
api(project(":kmath-core"))
api("net.jafama:jafama:2.3.2")
}
repositories {
mavenCentral()
}
readme {
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
}
kotlin.sourceSets.all {
languageSettings.useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI")
}

View File

@ -0,0 +1,106 @@
package space.kscience.kmath.jafama
import space.kscience.kmath.operations.*
import net.jafama.*
/**
* A field for [Double] (using FastMath) without boxing. Does not produce appropriate field element.
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
public override val zero: Double get() = 0.0
public override val one: Double get() = 1.0
public override fun number(value: Number): Double = value.toDouble()
public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
when (operation) {
PowerOperations.POW_OPERATION -> ::power
else -> super<ExtendedField>.binaryOperationFunction(operation)
}
public override fun add(a: Double, b: Double): Double = a + b
public override fun multiply(a: Double, b: Double): Double = a * b
public override fun divide(a: Double, b: Double): Double = a / b
public override fun scale(a: Double, value: Double): Double = a * value
public override fun sin(arg: Double): Double = FastMath.sin(arg)
public override fun cos(arg: Double): Double = FastMath.cos(arg)
public override fun tan(arg: Double): Double = FastMath.tan(arg)
public override fun acos(arg: Double): Double = FastMath.acos(arg)
public override fun asin(arg: Double): Double = FastMath.asin(arg)
public override fun atan(arg: Double): Double = FastMath.atan(arg)
public override fun sinh(arg: Double): Double = FastMath.sinh(arg)
public override fun cosh(arg: Double): Double = FastMath.cosh(arg)
public override fun tanh(arg: Double): Double = FastMath.tanh(arg)
public override fun asinh(arg: Double): Double = FastMath.asinh(arg)
public override fun acosh(arg: Double): Double = FastMath.acosh(arg)
public override fun atanh(arg: Double): Double = FastMath.atanh(arg)
public override fun power(arg: Double, pow: Number): Double = FastMath.pow(arg, pow.toDouble())
public override fun exp(arg: Double): Double = FastMath.exp(arg)
public override fun ln(arg: Double): Double = FastMath.log(arg)
public override fun norm(arg: Double): Double = FastMath.abs(arg)
public override fun Double.unaryMinus(): Double = -this
public override fun Double.plus(b: Double): Double = this + b
public override fun Double.minus(b: Double): Double = this - b
public override fun Double.times(b: Double): Double = this * b
public override fun Double.div(b: Double): Double = this / b
}
/**
* A field for [Double] (using StrictMath) without boxing. Does not produce appropriate field element.
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object StrictJafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
public override val zero: Double get() = 0.0
public override val one: Double get() = 1.0
public override fun number(value: Number): Double = value.toDouble()
public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
when (operation) {
PowerOperations.POW_OPERATION -> ::power
else -> super<ExtendedField>.binaryOperationFunction(operation)
}
public override fun add(a: Double, b: Double): Double = a + b
public override fun multiply(a: Double, b: Double): Double = a * b
public override fun divide(a: Double, b: Double): Double = a / b
public override fun scale(a: Double, value: Double): Double = a * value
public override fun sin(arg: Double): Double = StrictFastMath.sin(arg)
public override fun cos(arg: Double): Double = StrictFastMath.cos(arg)
public override fun tan(arg: Double): Double = StrictFastMath.tan(arg)
public override fun acos(arg: Double): Double = StrictFastMath.acos(arg)
public override fun asin(arg: Double): Double = StrictFastMath.asin(arg)
public override fun atan(arg: Double): Double = StrictFastMath.atan(arg)
public override fun sinh(arg: Double): Double = StrictFastMath.sinh(arg)
public override fun cosh(arg: Double): Double = StrictFastMath.cosh(arg)
public override fun tanh(arg: Double): Double = StrictFastMath.tanh(arg)
public override fun asinh(arg: Double): Double = StrictFastMath.asinh(arg)
public override fun acosh(arg: Double): Double = StrictFastMath.acosh(arg)
public override fun atanh(arg: Double): Double = StrictFastMath.atanh(arg)
public override fun power(arg: Double, pow: Number): Double = StrictFastMath.pow(arg, pow.toDouble())
public override fun exp(arg: Double): Double = StrictFastMath.exp(arg)
public override fun ln(arg: Double): Double = StrictFastMath.log(arg)
public override fun norm(arg: Double): Double = StrictFastMath.abs(arg)
public override fun Double.unaryMinus(): Double = -this
public override fun Double.plus(b: Double): Double = this + b
public override fun Double.minus(b: Double): Double = this - b
public override fun Double.times(b: Double): Double = this * b
public override fun Double.div(b: Double): Double = this / b
}

View File

@ -43,6 +43,7 @@ include(
":kmath-tensors", ":kmath-tensors",
":kmath-jupyter", ":kmath-jupyter",
":kmath-symja", ":kmath-symja",
":kmath-jafama",
":examples", ":examples",
":benchmarks" ":benchmarks"
) )