forked from kscience/kmath
Viktor prototype
This commit is contained in:
parent
bf2f4db468
commit
f9836a6477
@ -4,7 +4,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
plugins {
|
||||
java
|
||||
kotlin("jvm")
|
||||
kotlin("plugin.allopen") version "1.3.60"
|
||||
kotlin("plugin.allopen") version "1.3.61"
|
||||
id("kotlinx.benchmark") version "0.2.0-dev-5"
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ dependencies {
|
||||
implementation(project(":kmath-coroutines"))
|
||||
implementation(project(":kmath-commons"))
|
||||
implementation(project(":kmath-koma"))
|
||||
implementation(project(":kmath-viktor"))
|
||||
implementation("com.kyonifer:koma-core-ejml:0.12")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:${Scientifik.ioVersion}")
|
||||
|
||||
|
@ -4,7 +4,13 @@ import kotlinx.coroutines.GlobalScope
|
||||
import scientifik.kmath.operations.RealField
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
internal inline fun measureAndPrint(title: String, block: () -> Unit) {
|
||||
val time = measureTimeMillis(block)
|
||||
println("$title completed in $time millis")
|
||||
}
|
||||
|
||||
|
||||
fun main() {
|
||||
val dim = 1000
|
||||
val n = 1000
|
||||
|
||||
@ -15,8 +21,7 @@ fun main(args: Array<String>) {
|
||||
//A generic boxing field. It should be used for objects, not primitives.
|
||||
val genericField = NDField.boxing(RealField, dim, dim)
|
||||
|
||||
|
||||
val autoTime = measureTimeMillis {
|
||||
measureAndPrint("Automatic field addition") {
|
||||
autoField.run {
|
||||
var res = one
|
||||
repeat(n) {
|
||||
@ -25,18 +30,14 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
println("Automatic field addition completed in $autoTime millis")
|
||||
|
||||
val elementTime = measureTimeMillis {
|
||||
measureAndPrint("Element addition"){
|
||||
var res = genericField.one
|
||||
repeat(n) {
|
||||
res += 1.0
|
||||
}
|
||||
}
|
||||
|
||||
println("Element addition completed in $elementTime millis")
|
||||
|
||||
val specializedTime = measureTimeMillis {
|
||||
measureAndPrint("Specialized addition") {
|
||||
specializedField.run {
|
||||
var res: NDBuffer<Double> = one
|
||||
repeat(n) {
|
||||
@ -45,10 +46,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
println("Specialized addition completed in $specializedTime millis")
|
||||
|
||||
|
||||
val lazyTime = measureTimeMillis {
|
||||
measureAndPrint("Lazy addition") {
|
||||
val res = specializedField.one.mapAsync(GlobalScope) {
|
||||
var c = 0.0
|
||||
repeat(n) {
|
||||
@ -60,9 +58,7 @@ fun main(args: Array<String>) {
|
||||
res.elements().forEach { it.second }
|
||||
}
|
||||
|
||||
println("Lazy addition completed in $lazyTime millis")
|
||||
|
||||
val genericTime = measureTimeMillis {
|
||||
measureAndPrint("Generic addition") {
|
||||
//genericField.run(action)
|
||||
genericField.run {
|
||||
var res: NDBuffer<Double> = one
|
||||
@ -72,6 +68,4 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
println("Generic addition completed in $genericTime millis")
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package scientifik.kmath.structures
|
||||
|
||||
import org.jetbrains.bio.viktor.F64Array
|
||||
import scientifik.kmath.operations.RealField
|
||||
import scientifik.kmath.viktor.ViktorNDField
|
||||
|
||||
fun main() {
|
||||
val dim = 1000
|
||||
val n = 400
|
||||
|
||||
// automatically build context most suited for given type.
|
||||
val autoField = NDField.auto(RealField, dim, dim)
|
||||
|
||||
val viktorField = ViktorNDField(intArrayOf(dim, dim))
|
||||
|
||||
|
||||
measureAndPrint("Automatic field addition") {
|
||||
autoField.run {
|
||||
var res = one
|
||||
repeat(n) {
|
||||
res += 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
measureAndPrint("Raw Viktor") {
|
||||
val one = F64Array.full(init = 1.0, shape = *intArrayOf(dim, dim))
|
||||
var res = one
|
||||
repeat(n) {
|
||||
res = res + one
|
||||
}
|
||||
}
|
||||
|
||||
measureAndPrint("Viktor field addition") {
|
||||
viktorField.run {
|
||||
var res = one
|
||||
repeat(n) {
|
||||
res += 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,4 @@ dependencies {
|
||||
api(project(":kmath-coroutines"))
|
||||
api(project(":kmath-prob"))
|
||||
api("org.apache.commons:commons-math3:3.6.1")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
|
||||
}
|
@ -2,7 +2,6 @@ package scientifik.kmath.structures
|
||||
|
||||
import scientifik.kmath.operations.*
|
||||
|
||||
|
||||
interface ExtendedNDField<T : Any, F, N : NDStructure<T>> :
|
||||
NDField<T, F, N>,
|
||||
TrigonometricOperations<N>,
|
||||
|
10
kmath-viktor/build.gradle.kts
Normal file
10
kmath-viktor/build.gradle.kts
Normal file
@ -0,0 +1,10 @@
|
||||
plugins {
|
||||
id("scientifik.jvm")
|
||||
}
|
||||
|
||||
description = "Binding for https://github.com/JetBrains-Research/viktor"
|
||||
|
||||
dependencies {
|
||||
api(project(":kmath-core"))
|
||||
api("org.jetbrains.bio:viktor:1.0.1")
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package scientifik.kmath.viktor
|
||||
|
||||
import org.jetbrains.bio.viktor.F64FlatArray
|
||||
import scientifik.kmath.structures.MutableBuffer
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE")
|
||||
inline class ViktorBuffer(val flatArray: F64FlatArray) : MutableBuffer<Double> {
|
||||
override val size: Int get() = flatArray.size
|
||||
|
||||
override inline fun get(index: Int): Double = flatArray[index]
|
||||
override inline fun set(index: Int, value: Double) {
|
||||
flatArray[index] = value
|
||||
}
|
||||
|
||||
override fun copy(): MutableBuffer<Double> {
|
||||
return ViktorBuffer(flatArray.copy().flatten())
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<Double> = flatArray.data.iterator()
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package scientifik.kmath.viktor
|
||||
|
||||
import org.jetbrains.bio.viktor.F64Array
|
||||
import scientifik.kmath.operations.RealField
|
||||
import scientifik.kmath.structures.DefaultStrides
|
||||
import scientifik.kmath.structures.MutableNDStructure
|
||||
import scientifik.kmath.structures.NDField
|
||||
|
||||
inline class ViktorNDStructure(val f64Buffer: F64Array) : MutableNDStructure<Double> {
|
||||
|
||||
override val shape: IntArray get() = f64Buffer.shape
|
||||
|
||||
override fun get(index: IntArray): Double = f64Buffer.get(*index)
|
||||
|
||||
override fun set(index: IntArray, value: Double) {
|
||||
f64Buffer.set(value = value, indices = *index)
|
||||
}
|
||||
|
||||
override fun elements(): Sequence<Pair<IntArray, Double>> {
|
||||
return DefaultStrides(shape).indices().map { it to get(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun F64Array.asStructure(): ViktorNDStructure = ViktorNDStructure(this)
|
||||
|
||||
class ViktorNDField(override val shape: IntArray) : NDField<Double, RealField, ViktorNDStructure> {
|
||||
override val zero: ViktorNDStructure
|
||||
get() = F64Array.full(init = 0.0, shape = *shape).asStructure()
|
||||
override val one: ViktorNDStructure
|
||||
get() = F64Array.full(init = 1.0, shape = *shape).asStructure()
|
||||
|
||||
val strides = DefaultStrides(shape)
|
||||
|
||||
override val elementContext: RealField get() = RealField
|
||||
|
||||
override fun produce(initializer: RealField.(IntArray) -> Double): ViktorNDStructure = F64Array(*shape).apply {
|
||||
this@ViktorNDField.strides.indices().forEach { index ->
|
||||
set(value = RealField.initializer(index), indices = *index)
|
||||
}
|
||||
}.asStructure()
|
||||
|
||||
override fun map(arg: ViktorNDStructure, transform: RealField.(Double) -> Double): ViktorNDStructure =
|
||||
F64Array(*shape).apply {
|
||||
this@ViktorNDField.strides.indices().forEach { index ->
|
||||
set(value = RealField.transform(arg[index]), indices = *index)
|
||||
}
|
||||
}.asStructure()
|
||||
|
||||
override fun mapIndexed(
|
||||
arg: ViktorNDStructure,
|
||||
transform: RealField.(index: IntArray, Double) -> Double
|
||||
): ViktorNDStructure = F64Array(*shape).apply {
|
||||
this@ViktorNDField.strides.indices().forEach { index ->
|
||||
set(value = RealField.transform(index, arg[index]), indices = *index)
|
||||
}
|
||||
}.asStructure()
|
||||
|
||||
override fun combine(
|
||||
a: ViktorNDStructure,
|
||||
b: ViktorNDStructure,
|
||||
transform: RealField.(Double, Double) -> Double
|
||||
): ViktorNDStructure = F64Array(*shape).apply {
|
||||
this@ViktorNDField.strides.indices().forEach { index ->
|
||||
set(value = RealField.transform(a[index], b[index]), indices = *index)
|
||||
}
|
||||
}.asStructure()
|
||||
|
||||
override fun ViktorNDStructure.plus(b: ViktorNDStructure): ViktorNDStructure =
|
||||
(f64Buffer + b.f64Buffer).asStructure()
|
||||
|
||||
override fun ViktorNDStructure.minus(b: ViktorNDStructure): ViktorNDStructure =
|
||||
(f64Buffer - b.f64Buffer).asStructure()
|
||||
}
|
@ -33,6 +33,7 @@ include(
|
||||
":kmath-coroutines",
|
||||
":kmath-histograms",
|
||||
":kmath-commons",
|
||||
":kmath-viktor",
|
||||
":kmath-koma",
|
||||
":kmath-prob",
|
||||
":kmath-io",
|
||||
|
Loading…
Reference in New Issue
Block a user