Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
Quafadas committed Sep 26, 2024
1 parent 70947b0 commit 7769bbe
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 37 deletions.
8 changes: 8 additions & 0 deletions benchmark/src/Benchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ abstract class BLASBenchmark:
return res;
end randomDoubleArray

protected def randomBooleanArray(n: Int): Array[Boolean] =
val res = new Array[Boolean](n);

for i <- 0 until n do res(i) = rand.nextDouble() < 0.5;
end for
return res;
end randomBooleanArray

protected def randomFloat(): Float =
return rand.nextFloat();

Expand Down
83 changes: 83 additions & 0 deletions benchmark/src/and.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2020, 2021, Ludovic Henry
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Please contact git@ludovic.dev or visit ludovic.dev if you need additional
* information or have any questions.
*/

package vecxt.benchmark

import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
// import vecxt.Matrix.*
import vecxt.BoundsCheck
import scala.compiletime.uninitialized
import vecxt.*
import jdk.incubator.vector.VectorSpecies
import jdk.incubator.vector.VectorOperators
import jdk.incubator.vector.DoubleVector

@State(Scope.Thread)
class AndBooleanBenchmark extends BLASBenchmark:

@Param(Array("3", "128", "100000"))
var len: String = uninitialized;

var arr: Array[Boolean] = uninitialized
var arr2: Array[Boolean] = uninitialized

// format: off
@Setup(Level.Trial)
def setup: Unit =
arr = randomBooleanArray(len.toInt);
arr2 = randomBooleanArray(len.toInt);
()
end setup

extension (vec: Array[Boolean])
inline def and2(thatIdx: Array[Boolean]) =
val result: Array[Boolean] = new Array[Boolean](vec.length)
var i = 0

while i < vec.length do
result(i) = vec(i) && thatIdx(i)
i += 1
end while
result
end extension

@Benchmark
def and_loop(bh: Blackhole) =
val r = arr.and2(arr2)
bh.consume(r);
end and_loop


@Benchmark
def and_loop_vec(bh: Blackhole) =
val r = arr && arr2
bh.consume(r);
end and_loop_vec

end AndBooleanBenchmark



40 changes: 20 additions & 20 deletions benchmark/src/countTrue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,44 +36,44 @@ import jdk.incubator.vector.VectorOperators
import jdk.incubator.vector.DoubleVector

@State(Scope.Thread)
class IncrementBenchmark extends BLASBenchmark:
class CountTrueBenchmark extends BLASBenchmark:

@Param(Array("3", "100", "100000"))
@Param(Array("3", "128", "100000"))
var len: String = uninitialized;

var arr: Array[Double] = uninitialized
var arr: Array[Boolean] = uninitialized

// format: off
@Setup(Level.Trial)
def setup: Unit =
arr = randomDoubleArray(len.toInt);
arr = randomBooleanArray(len.toInt);
()
end setup

extension (vec: Array[Double])
inline def increments_loop: Array[Double] =
val out = new Array[Double](vec.length)
out(0) = vec(0)
var i = 1
extension (vec: Array[Boolean])
inline def countTrue2: Int =
var sum = 0
var i = 0
while i < vec.length do
out(i) = vec(i) - vec(i - 1)
i = i + 1
if vec(i) then sum += 1
end if
i += 1
end while
out
end increments_loop
sum

end extension

@Benchmark
def increment_normal(bh: Blackhole) =
val r = arr.increments_loop
def countTrue_loop(bh: Blackhole) =
val r = arr.countTrue2
bh.consume(r);
end increment_normal
end countTrue_loop


@Benchmark
def increment_vec(bh: Blackhole) =
val r = arr.increments
def countTrue_loop_vec(bh: Blackhole) =
val r = arr.countTrue
bh.consume(r);
end increment_vec
end countTrue_loop_vec
end CountTrueBenchmark

end IncrementBenchmark
78 changes: 78 additions & 0 deletions benchmark/src/or.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2020, 2021, Ludovic Henry
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Please contact git@ludovic.dev or visit ludovic.dev if you need additional
* information or have any questions.
*/

package vecxt.benchmark

import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
// import vecxt.Matrix.*
import vecxt.BoundsCheck
import scala.compiletime.uninitialized
import vecxt.*
import jdk.incubator.vector.VectorSpecies
import jdk.incubator.vector.VectorOperators
import jdk.incubator.vector.DoubleVector

@State(Scope.Thread)
class OrBooleanBenchmark extends BLASBenchmark:

@Param(Array("3", "128", "100000"))
var len: String = uninitialized;

var arr: Array[Boolean] = uninitialized
var arr2: Array[Boolean] = uninitialized

// format: off
@Setup(Level.Trial)
def setup: Unit =
arr = randomBooleanArray(len.toInt);
arr2 = randomBooleanArray(len.toInt);
()
end setup

extension (vec: Array[Boolean])
inline def or2(thatIdx: Array[Boolean]) =
val result: Array[Boolean] = new Array[Boolean](vec.length)
var i = 0

while i < vec.length do
result(i) = vec(i) || thatIdx(i)
i += 1
end while
result
end extension

@Benchmark
def or_loop(bh: Blackhole) =
val r = arr.or2(arr2)
bh.consume(r);
end or_loop

@Benchmark
def or_vec(bh: Blackhole) =
val r = arr || arr2
bh.consume(r);
end or_vec
end OrBooleanBenchmark
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ benchmark:
mill benchmark.runJmh -jvmArgs --add-modules=jdk.incubator.vector -rf json

benchmarkOnly:
mill benchmark.runJmh -jvmArgs --add-modules=jdk.incubator.vector -rf json vecxt.benchmark.AddScalarBenchmark
mill benchmark.runJmh -jvmArgs --add-modules=jdk.incubator.vector -rf json vecxt.benchmark.OrBooleanBenchmark

setJvm:
eval "$(cs java --jvm 21 --env)"
80 changes: 68 additions & 12 deletions vecxt/jvm/src/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package vecxt
import dev.ludovic.netlib.blas.JavaBLAS.getInstance as blas
import scala.util.chaining.*
import vecxt.Matrix.*

import jdk.incubator.vector.VectorMask
import jdk.incubator.vector.ByteVector
import jdk.incubator.vector.DoubleVector
import jdk.incubator.vector.VectorSpecies
Expand Down Expand Up @@ -76,35 +78,89 @@ object extensions:
end countTrue

inline def &&(thatIdx: Array[Boolean]): Array[Boolean] =
val species = ByteVector.SPECIES_PREFERRED
val l = species.length()
val result: Array[Boolean] = new Array[Boolean](vec.length)
for i <- 0 until vec.length do result(i) = vec(i) && thatIdx(i)
end for
var i = 0

while i < species.loopBound(vec.length) do
ByteVector
.fromBooleanArray(species, vec, i)
.and(ByteVector.fromBooleanArray(species, thatIdx, i))
.intoBooleanArray(result, i)
i += l
end while

while i < vec.length do
result(i) = vec(i) && thatIdx(i)
i += 1
end while
result
end &&

inline def ||(thatIdx: Array[Boolean]): Array[Boolean] =
val species = ByteVector.SPECIES_PREFERRED
val l = species.length()
val result: Array[Boolean] = new Array[Boolean](vec.length)
for i <- 0 until vec.length do result(i) = vec(i) || thatIdx(i)
end for
var i = 0

while i < species.loopBound(vec.length) do
ByteVector
.fromBooleanArray(species, vec, i)
.or(ByteVector.fromBooleanArray(species, thatIdx, i))
.intoBooleanArray(result, i)
i += l
end while

while i < vec.length do
result(i) = vec(i) || thatIdx(i)
i += 1
end while
result
end ||
end extension

extension (vec: Array[Double])

inline def idxBoolean(index: Array[Boolean])(using inline boundsCheck: BoundsCheck) =
inline def apply(index: Array[Boolean])(using inline boundsCheck: BoundsCheck): Array[Double] =
dimCheck(vec, index)
val trues = index.countTrue
val newVec: Array[Double] = new Array[Double](trues)
val newVec: Array[Double] = new Array[Double](index.length)
val out = new Array[Double](vec.length)
val sp = Matrix.doubleSpecies
val l = sp.length()

var i = 0
var j = 0
for i <- 0 until index.length do
// println(s"i: $i || j: $j || ${index(i)} ${vec(i)} ")
while i < sp.loopBound(vec.length) do
println(s"i: $i || j: $j")
val mask = VectorMask.fromArray[java.lang.Double](sp, index, i)

val vals = DoubleVector
.fromArray(sp, vec, i)

// val selected = vals.selectFrom(vals, mask)

println(s"mask: ${mask.toArray().print}")
println(s"vals: ${vals.toArray().print}")
vals.intoArray(newVec, j, mask)
println(newVec.print)

i += l
j = j + mask.trueCount()

end while

while i < vec.length do
if index(i) then
newVec(j) = vec(i)
j = 1 + j
end for
j += 1
end if
i += 1
end while

newVec
end idxBoolean

end apply

inline def increments: Array[Double] =
val out = new Array[Double](vec.length)
Expand Down
Loading

0 comments on commit 7769bbe

Please sign in to comment.