Add init/read timing for Scala

This commit is contained in:
Tom Lin 2023-10-07 12:10:08 +01:00
parent 512a6fac0c
commit 971d1e8ac7
7 changed files with 63 additions and 25 deletions

View File

@ -1 +0,0 @@
{"name":"sbt","version":"1.5.2","bspVersion":"2.0.0-M5","languages":["scala"],"argv":["/usr/lib/jvm/java-11-openjdk-11.0.11.0.9-2.fc33.x86_64/bin/java","-Xms100m","-Xmx100m","-classpath","/home/tom/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/211.7142.45.plugins/Scala/launcher/sbt-launch.jar","xsbt.boot.Boot","-bsp","--sbt-launch-jar=/home/tom/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/211.7142.45.plugins/Scala/launcher/sbt-launch.jar"]}

View File

@ -1 +1,2 @@
target/
.bsp/

View File

@ -1,4 +1,4 @@
version = "3.0.0-RC2"
version = "3.7.14"
runner.dialect = scala3
style = defaultWithAlign

View File

@ -3,7 +3,7 @@ lazy val mainCls = Some("scalastream.App")
lazy val root = (project in file("."))
.enablePlugins(NativeImagePlugin)
.settings(
scalaVersion := "3.0.0",
scalaVersion := "3.3.1",
version := "4.0",
organization := "uk.ac.bristol.uob-hpc",
organizationName := "University of Bristol",
@ -11,6 +11,11 @@ lazy val root = (project in file("."))
assembly / mainClass := mainCls,
scalacOptions ~= filterConsoleScalacOptions,
assembly / assemblyJarName := "scala-stream.jar",
assembly / assemblyMergeStrategy := {
case PathList("module-info.class") => MergeStrategy.discard
case PathList("META-INF", "versions", xs @ _, "module-info.class") => MergeStrategy.discard
case x => (ThisBuild / assemblyMergeStrategy).value(x)
},
nativeImageOptions := Seq(
"--no-fallback",
"-H:ReflectionConfigurationFiles=../../reflect-config.json"
@ -22,8 +27,8 @@ lazy val root = (project in file("."))
// Lazy val implementation in Scala 3 triggers an exception in nativeImage, use 2_13 for arg parsing for now otherwise we can't get to the benchmarking part
("com.github.scopt" %% "scopt" % "4.0.1").cross(CrossVersion.for3Use2_13),
// par also uses lazy val at some point, so it doesn't work in nativeImage
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.3",
"net.openhft" % "affinity" % "3.21ea1",
"org.slf4j" % "slf4j-simple" % "1.7.30" // for affinity
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.4",
"net.openhft" % "affinity" % "3.23.2",
"org.slf4j" % "slf4j-simple" % "2.0.5" // for affinity
)
)

View File

@ -1 +1 @@
sbt.version=1.5.2
sbt.version=1.9.2

View File

@ -1,6 +1,6 @@
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.5.3")
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.17")
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.20")
addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.3")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.27")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3")

View File

@ -14,6 +14,7 @@ transparent trait ScalaStream[@specialized(Float, Double) A]:
def config: Config[A]
def initArrays(): Unit
def readArrays(): Unit = ()
def copy(): Unit
def mul(): Unit
def add(): Unit
@ -27,6 +28,8 @@ transparent trait ScalaStream[@specialized(Float, Double) A]:
val end = System.nanoTime()
FiniteDuration(end - start, TimeUnit.NANOSECONDS) -> r
inline def runInitArrays(): FiniteDuration = timed(initArrays())._1
inline def runReadArrays(): FiniteDuration = timed(readArrays())._1
inline def runAll(times: Int)(using Fractional[A]): (Timings[Vector[FiniteDuration]], A) =
val copy = ArrayBuffer.fill[FiniteDuration](times)(Duration.Zero)
val mul = ArrayBuffer.fill[FiniteDuration](times)(Duration.Zero)
@ -62,7 +65,6 @@ transparent trait ScalaStream[@specialized(Float, Double) A]:
def data(): Data[A]
trait Fractional[@specialized(Double, Float) A]:
def toFractional(f: Float): A
def toFractional(f: Double): A
@ -77,13 +79,13 @@ trait Fractional[@specialized(Double, Float) A]:
extension (x: Int) inline def fractional = toFractional(x.toFloat)
extension (x: Long) inline def fractional = toFractional(x.toDouble)
extension (x: A)
inline def +(y: A) = add(x, y)
inline def -(y: A) = sub(x, y)
inline def *(y: A) = mul(x, y)
inline def /(y: A) = div(x, y)
inline def >(y: A) = compare(x, y) > 0
inline def <(y: A) = compare(x, y) < 0
inline def abs_ = abs(x)
inline def +(y: A) = add(x, y)
inline def -(y: A) = sub(x, y)
inline def *(y: A) = mul(x, y)
inline def /(y: A) = div(x, y)
inline def >(y: A) = compare(x, y) > 0
inline def <(y: A) = compare(x, y) < 0
inline def abs_ = abs(x)
end Fractional
given FloatFractional: Fractional[Float] with
@ -204,7 +206,7 @@ object App:
validateXs("c", vec.c, goldC)
dotSum.foreach { sum =>
val goldSum = (goldA * goldB) * (config.options.arraysize).fractional
val goldSum = (goldA * goldB) * config.options.arraysize.fractional
val error = ((sum - goldSum) / goldSum).abs_
if error > 1.fractional / 100000000.fractional then
Console.err.println(
@ -238,10 +240,10 @@ object App:
)
println(s"Running ${config.benchmark match {
case Benchmark.All => "kernels"
case Benchmark.Triad => "triad"
case Benchmark.NStream => "nstream"
}} ${opt.numtimes} times")
case Benchmark.All => "kernels"
case Benchmark.Triad => "triad"
case Benchmark.NStream => "nstream"
}} ${opt.numtimes} times")
if config.benchmark == Benchmark.Triad then println(s"Number of elements: ${opt.arraysize}")
@ -288,11 +290,38 @@ object App:
println(header.map(_._1.padTo(padding, ' ')).mkString(sep))
println(rows.map(_.map(_._2.padTo(padding, ' ')).mkString(sep)).mkString("\n"))
def showInit(init: FiniteDuration, read: FiniteDuration): Unit = {
val setup =
Vector(("Init", init.seconds, 3 * arrayBytes), ("Read", read.seconds, 3 * arrayBytes))
if opt.csv then
tabulate(
setup.map((name, elapsed, totalBytes) =>
Vector(
"phase" -> name,
"n_elements" -> opt.arraysize.toString,
"sizeof" -> arrayBytes.toString,
s"max_m${if opt.mibibytes then "i" else ""}bytes_per_sec" ->
(megaScale * totalBytes.toDouble / elapsed).toString,
"runtime" -> elapsed.toString
)
): _*
)
else
for (name, elapsed, totalBytes) <- setup do
println(
f"$name: $elapsed%.5f s (=${megaScale * totalBytes.toDouble / elapsed}%.5f M${
if opt.mibibytes then "i" else ""
}Bytes/sec)"
)
}
val stream = mkStream(config)
stream.initArrays()
val init = stream.runInitArrays()
config.benchmark match
case Benchmark.All =>
val (results, sum) = stream.runAll(opt.numtimes)
val read = stream.runReadArrays()
showInit(init, read)
validate(stream.data(), config, Some(sum))
tabulate(
mkRow(results.copy, "Copy", 2 * arrayBytes),
@ -303,10 +332,14 @@ object App:
)
case Benchmark.NStream =>
val result = stream.runNStream(opt.numtimes)
val read = stream.runReadArrays()
showInit(init, read)
validate(stream.data(), config)
tabulate(mkRow(result, "Nstream", 4 * arrayBytes))
case Benchmark.Triad =>
val results = stream.runTriad(opt.numtimes)
val results = stream.runTriad(opt.numtimes)
val read = stream.runReadArrays()
showInit(init, read)
val totalBytes = 3 * arrayBytes * opt.numtimes
val bandwidth = megaScale * (totalBytes / results.seconds)
println(f"Runtime (seconds): ${results.seconds}%.5f")