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/ target/
.bsp/

View File

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

View File

@ -3,7 +3,7 @@ lazy val mainCls = Some("scalastream.App")
lazy val root = (project in file(".")) lazy val root = (project in file("."))
.enablePlugins(NativeImagePlugin) .enablePlugins(NativeImagePlugin)
.settings( .settings(
scalaVersion := "3.0.0", scalaVersion := "3.3.1",
version := "4.0", version := "4.0",
organization := "uk.ac.bristol.uob-hpc", organization := "uk.ac.bristol.uob-hpc",
organizationName := "University of Bristol", organizationName := "University of Bristol",
@ -11,6 +11,11 @@ lazy val root = (project in file("."))
assembly / mainClass := mainCls, assembly / mainClass := mainCls,
scalacOptions ~= filterConsoleScalacOptions, scalacOptions ~= filterConsoleScalacOptions,
assembly / assemblyJarName := "scala-stream.jar", 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( nativeImageOptions := Seq(
"--no-fallback", "--no-fallback",
"-H:ReflectionConfigurationFiles=../../reflect-config.json" "-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 // 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), ("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 // 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", "org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.4",
"net.openhft" % "affinity" % "3.21ea1", "net.openhft" % "affinity" % "3.23.2",
"org.slf4j" % "slf4j-simple" % "1.7.30" // for affinity "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("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("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("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 config: Config[A]
def initArrays(): Unit def initArrays(): Unit
def readArrays(): Unit = ()
def copy(): Unit def copy(): Unit
def mul(): Unit def mul(): Unit
def add(): Unit def add(): Unit
@ -27,6 +28,8 @@ transparent trait ScalaStream[@specialized(Float, Double) A]:
val end = System.nanoTime() val end = System.nanoTime()
FiniteDuration(end - start, TimeUnit.NANOSECONDS) -> r 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) = inline def runAll(times: Int)(using Fractional[A]): (Timings[Vector[FiniteDuration]], A) =
val copy = ArrayBuffer.fill[FiniteDuration](times)(Duration.Zero) val copy = ArrayBuffer.fill[FiniteDuration](times)(Duration.Zero)
val mul = 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] def data(): Data[A]
trait Fractional[@specialized(Double, Float) A]: trait Fractional[@specialized(Double, Float) A]:
def toFractional(f: Float): A def toFractional(f: Float): A
def toFractional(f: Double): A def toFractional(f: Double): A
@ -204,7 +206,7 @@ object App:
validateXs("c", vec.c, goldC) validateXs("c", vec.c, goldC)
dotSum.foreach { sum => 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_ val error = ((sum - goldSum) / goldSum).abs_
if error > 1.fractional / 100000000.fractional then if error > 1.fractional / 100000000.fractional then
Console.err.println( Console.err.println(
@ -288,11 +290,38 @@ object App:
println(header.map(_._1.padTo(padding, ' ')).mkString(sep)) println(header.map(_._1.padTo(padding, ' ')).mkString(sep))
println(rows.map(_.map(_._2.padTo(padding, ' ')).mkString(sep)).mkString("\n")) 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) val stream = mkStream(config)
stream.initArrays() val init = stream.runInitArrays()
config.benchmark match config.benchmark match
case Benchmark.All => case Benchmark.All =>
val (results, sum) = stream.runAll(opt.numtimes) val (results, sum) = stream.runAll(opt.numtimes)
val read = stream.runReadArrays()
showInit(init, read)
validate(stream.data(), config, Some(sum)) validate(stream.data(), config, Some(sum))
tabulate( tabulate(
mkRow(results.copy, "Copy", 2 * arrayBytes), mkRow(results.copy, "Copy", 2 * arrayBytes),
@ -303,10 +332,14 @@ object App:
) )
case Benchmark.NStream => case Benchmark.NStream =>
val result = stream.runNStream(opt.numtimes) val result = stream.runNStream(opt.numtimes)
val read = stream.runReadArrays()
showInit(init, read)
validate(stream.data(), config) validate(stream.data(), config)
tabulate(mkRow(result, "Nstream", 4 * arrayBytes)) tabulate(mkRow(result, "Nstream", 4 * arrayBytes))
case Benchmark.Triad => 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 totalBytes = 3 * arrayBytes * opt.numtimes
val bandwidth = megaScale * (totalBytes / results.seconds) val bandwidth = megaScale * (totalBytes / results.seconds)
println(f"Runtime (seconds): ${results.seconds}%.5f") println(f"Runtime (seconds): ${results.seconds}%.5f")