From ba4fde666c1338ad35d1d20c9ff7b34e059e2353 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Tue, 11 Jun 2019 17:11:43 +0700 Subject: [PATCH] Benchmarks: Add compile benchmark plugin This patch moves benchmark configuration logic described in performance/gradle/compileBenchmark.gradle to a separate plugin located in the buildSrc project. --- buildSrc/plugins/build.gradle | 8 +- .../kotlin/benchmark/BenchmarkingPlugin.kt | 5 +- .../benchmark/CompileBenchmarkingPlugin.kt | 111 ++++++++++++++++++ performance/helloworld/build.gradle | 12 -- performance/helloworld/build.gradle.kts | 22 ++++ performance/videoplayer/build.gradle | 53 --------- performance/videoplayer/build.gradle.kts | 73 ++++++++++++ 7 files changed, 215 insertions(+), 69 deletions(-) create mode 100644 buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/CompileBenchmarkingPlugin.kt delete mode 100644 performance/helloworld/build.gradle create mode 100644 performance/helloworld/build.gradle.kts delete mode 100644 performance/videoplayer/build.gradle create mode 100644 performance/videoplayer/build.gradle.kts diff --git a/buildSrc/plugins/build.gradle b/buildSrc/plugins/build.gradle index 7c77177becb..b2c8022cfc9 100644 --- a/buildSrc/plugins/build.gradle +++ b/buildSrc/plugins/build.gradle @@ -63,8 +63,12 @@ compileGroovy { gradlePlugin { plugins { benchmarkPlugin { - id = 'benchmarking' - implementationClass = 'org.jetbrains.kotlin.benchmark.BenchmarkingPlugin' + id = "benchmarking" + implementationClass = "org.jetbrains.kotlin.benchmark.BenchmarkingPlugin" + } + compileBenchmarking { + id = "compile-benchmarking" + implementationClass = "org.jetbrains.kotlin.benchmark.CompileBenchmarkingPlugin" } } } diff --git a/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/BenchmarkingPlugin.kt b/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/BenchmarkingPlugin.kt index 177bb5d0b02..4405229121f 100644 --- a/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/BenchmarkingPlugin.kt +++ b/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/BenchmarkingPlugin.kt @@ -68,6 +68,8 @@ open class BenchmarkExtension @Inject constructor(val project: Project) { var linkerOpts: Collection = emptyList() } +// TODO: Override kotlin compiler with a correct version. + /** * A plugin configuring a benchmark Kotlin/Native project. */ @@ -197,10 +199,9 @@ open class BenchmarkingPlugin: Plugin { val jarPath = (tasks.getByName("jvmJar") as Jar).archiveFile.get().asFile val jvmCompileTime = getJvmCompileTime(applicationName) val benchContents = buildDir.resolve(jvmBenchResults).readText() - + val properties: Map = commonBenchmarkProperties + mapOf( "type" to "jvm", - // TODO: We had buildKotlinVersion here!!!! "compilerVersion" to kotlinVersion, "benchmarks" to benchContents, "compileTime" to listOf(jvmCompileTime), diff --git a/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/CompileBenchmarkingPlugin.kt b/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/CompileBenchmarkingPlugin.kt new file mode 100644 index 00000000000..0a4dacaeebf --- /dev/null +++ b/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/benchmark/CompileBenchmarkingPlugin.kt @@ -0,0 +1,111 @@ +package org.jetbrains.kotlin.benchmark + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.Delete +import org.gradle.api.tasks.Exec +import org.jetbrains.kotlin.* +import javax.inject.Inject + +private typealias CommandList = List + +open class CompileBenchmarkExtension @Inject constructor(val project: Project) { + var applicationName = project.name + var repeatNumber: Int = 1 + var buildSteps: Map = emptyMap() +} + +open class CompileBenchmarkingPlugin : Plugin { + + private val exitCodes: MutableMap = mutableMapOf() + + private fun Project.configureUtilityTasks() { + tasks.create("configureBuild") { + it.doLast { mkdir(buildDir) } + } + + tasks.create("clean", Delete::class.java) { + it.delete(buildDir) + } + } + + private fun Project.configureKonanRun( + benchmarkExtension: CompileBenchmarkExtension + ): Unit = with(benchmarkExtension) { + // Aggregate task. + val konanRun = tasks.create("konanRun") { task -> + task.dependsOn("configureBuild") + } + + // Compile tasks. + afterEvaluate { + for (number in 1..repeatNumber) { + buildSteps.forEach { (taskName, command) -> + tasks.create("$taskName$number", Exec::class.java).apply { + commandLine(command) + isIgnoreExitValue = true + konanRun.dependsOn(this) + doLast { + exitCodes[name] = execResult.exitValue + } + } + } + } + } + + // Report task. + tasks.create("konanJsonReport").apply { + doLast { + val nativeCompileTime = getCompileBenchmarkTime( + applicationName, + buildSteps.keys, + repeatNumber, + exitCodes + ) + val nativeExecutable = buildDir.resolve("program${getNativeProgramExtension()}") + val properties = commonBenchmarkProperties + mapOf( + "type" to "native", + "compilerVersion" to konanVersion, + "benchmarks" to "[]", + "compileTime" to nativeCompileTime, + "codeSize" to getCodeSizeBenchmark(applicationName, nativeExecutable.absolutePath) + ) + val output = createJsonReport(properties) + buildDir.resolve(nativeJson).writeText(output) + } + konanRun.finalizedBy(this) + } + } + + private fun Project.configureJvmRun( + benchmarkExtension: CompileBenchmarkExtension + ) { + val jvmRun = tasks.create("jvmRun") { + it.doLast { println("JVM run isn't supported") } + } + + tasks.create("jvmJsonReport") { + it.doLast { println("JVM run isn't supported") } + jvmRun.finalizedBy(it) + } + } + + override fun apply(target: Project): Unit = with(target) { + addTimeListener(this) + + val benchmarkExtension = extensions.create( + COMPILE_BENCHMARK_EXTENSION_NAME, + CompileBenchmarkExtension::class.java, + this + ) + + // Create tasks. + configureUtilityTasks() + configureKonanRun(benchmarkExtension) + configureJvmRun(benchmarkExtension) + } + + companion object { + const val COMPILE_BENCHMARK_EXTENSION_NAME = "compileBenchmark" + } +} diff --git a/performance/helloworld/build.gradle b/performance/helloworld/build.gradle deleted file mode 100644 index 6faab469276..00000000000 --- a/performance/helloworld/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -import org.jetbrains.kotlin.MPPTools - -def dist = findProperty('org.jetbrains.kotlin.native.home') ?: 'dist' -dist = (new File(dist)).isAbsolute() ? dist : "${project.getProjectDir()}/$dist" -def toolExtension = System.getProperty("os.name").startsWith('Windows') ? ".bat" : "" -project.ext { - applicationName = 'HelloWorld' - repeatNumber = 10 - buildSteps = ["runKonanc": ["$dist/bin/konanc$toolExtension", "${project.getProjectDir()}/src/main/kotlin/main.kt", "-o", - "${buildDir.absolutePath}/program${MPPTools.getNativeProgramExtension()}"]] -} -apply from: rootProject.file("${rootProject.rootDir}/performance/gradle/compileBenchmark.gradle") \ No newline at end of file diff --git a/performance/helloworld/build.gradle.kts b/performance/helloworld/build.gradle.kts new file mode 100644 index 00000000000..f3739120976 --- /dev/null +++ b/performance/helloworld/build.gradle.kts @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +import org.jetbrains.kotlin.getNativeProgramExtension + +plugins { + id("compile-benchmarking") +} + +val dist = file(findProperty("org.jetbrains.kotlin.native.home") ?: "dist") +val toolSuffix = if (System.getProperty("os.name").startsWith("Windows")) ".bat" else "" +val binarySuffix = getNativeProgramExtension() + +compileBenchmark { + applicationName = "HelloWorld" + repeatNumber = 10 + buildSteps = mapOf( + "runKonanc" to listOf("$dist/bin/konanc$toolSuffix", "$projectDir/src/main/kotlin/main.kt", "-o", "$buildDir/program$binarySuffix") + ) +} diff --git a/performance/videoplayer/build.gradle b/performance/videoplayer/build.gradle deleted file mode 100644 index 06a322c8224..00000000000 --- a/performance/videoplayer/build.gradle +++ /dev/null @@ -1,53 +0,0 @@ -import org.jetbrains.kotlin.PlatformInfo -import org.jetbrains.kotlin.MPPTools - -def dist = findProperty('org.jetbrains.kotlin.native.home') ?: 'dist' -dist = (new File(dist)).isAbsolute() ? dist : "${project.getProjectDir()}/$dist" -def toolExtension = System.getProperty("os.name").startsWith('Windows') ? ".bat" : "" - -def linkerOpts = [] -if (PlatformInfo.isMac()) { - linkerOpts += ['-linker-options','-L/opt/local/lib', '-linker-options', '-L/usr/local/lib'] -} else if (PlatformInfo.isLinux()) { - linkerOpts += ['-linker-options', '-L/usr/lib/x86_64-linux-gnu', '-linker-options', '-L/usr/lib64'] -} else if (PlatformInfo.isWindows()) { - linkerOpts += ['-linker-options', "-L${MPPTools.mingwPath()}/lib"] -} - -def includeDirsFfmpeg = [] -def filterDirsFfmpeg = [] -if (PlatformInfo.isMac()) { - filterDirsFfmpeg += ['-headerFilterAdditionalSearchPrefix', '/opt/local/include', - '-headerFilterAdditionalSearchPrefix', '/usr/local/include'] -} else if (PlatformInfo.isLinux()) { - filterDirsFfmpeg += ['-headerFilterAdditionalSearchPrefix', '/usr/include', - '-headerFilterAdditionalSearchPrefix', '/usr/include/x86_64-linux-gnu', - '-headerFilterAdditionalSearchPrefix', '/usr/include/ffmpeg'] -} else if (PlatformInfo.isWindows()) { - includeDirsFfmpeg += ['-compiler-option', "-I${MPPTools.mingwPath()}/include"] -} - -def includeDirsSdl = [] -if (PlatformInfo.isMac()) { - includeDirsSdl += ['-compiler-option', '-I/opt/local/include/SDL2', - '-compiler-option', '-I/usr/local/include/SDL2'] -} else if (PlatformInfo.isLinux()) { - includeDirsSdl += ['-compiler-option', '-I/usr/include/SDL2'] -} else if (PlatformInfo.isWindows()) { - includeDirsSdl += ['-compiler-option', "-I${MPPTools.mingwPath()}/include/SDL2"] -} - -project.ext { - applicationName = 'Videoplayer' - repeatNumber = 10 - buildSteps = ["runCinteropFfmpeg": ["$dist/bin/cinterop$toolExtension", "-o", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-ffmpeg.klib", - "-def", "$dist/../samples/videoplayer/src/nativeInterop/cinterop/ffmpeg.def"] + filterDirsFfmpeg + includeDirsFfmpeg, - "runCinteropSdl": ["$dist/bin/cinterop$toolExtension", "-o", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-sdl.klib", - "-def", "$dist/../samples/videoplayer/src/nativeInterop/cinterop/sdl.def"] + includeDirsSdl, - "runKonanProgram": ["$dist/bin/konanc$toolExtension", "-ea", "-p", "program", "-o", "${buildDir.absolutePath}/program${MPPTools.getNativeProgramExtension()}", - "-l", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-ffmpeg.klib", - "-l", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-sdl.klib", - "-Xmulti-platform", "$dist/../samples/videoplayer/src/videoPlayerMain/kotlin", - "-entry", "sample.videoplayer.main"] + linkerOpts] -} -apply from: rootProject.file("${rootProject.rootDir}/performance/gradle/compileBenchmark.gradle") \ No newline at end of file diff --git a/performance/videoplayer/build.gradle.kts b/performance/videoplayer/build.gradle.kts new file mode 100644 index 00000000000..8a373327b69 --- /dev/null +++ b/performance/videoplayer/build.gradle.kts @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +import org.jetbrains.kotlin.PlatformInfo +import org.jetbrains.kotlin.getNativeProgramExtension +import org.jetbrains.kotlin.mingwPath + +plugins { + id("compile-benchmarking") +} + +val dist = file(findProperty("org.jetbrains.kotlin.native.home") ?: "dist") +val toolSuffix = if (System.getProperty("os.name").startsWith("Windows")) ".bat" else "" +val binarySuffix = getNativeProgramExtension() + +val linkerOpts = when { + PlatformInfo.isMac() -> listOf("-linker-options","-L/opt/local/lib", "-linker-options", "-L/usr/local/lib") + PlatformInfo.isLinux() -> listOf("-linker-options", "-L/usr/lib/x86_64-linux-gnu", "-linker-options", "-L/usr/lib64") + PlatformInfo.isWindows() -> listOf("-linker-options", "-L$mingwPath/lib") + else -> error("Unsupported platform") +} + +var includeDirsFfmpeg = emptyList() +var filterDirsFfmpeg = emptyList() +when { + PlatformInfo.isMac() -> filterDirsFfmpeg = listOf( + "-headerFilterAdditionalSearchPrefix", "/opt/local/include", + "-headerFilterAdditionalSearchPrefix", "/usr/local/include" + ) + PlatformInfo.isLinux() -> filterDirsFfmpeg = listOf( + "-headerFilterAdditionalSearchPrefix", "/usr/include", + "-headerFilterAdditionalSearchPrefix", "/usr/include/x86_64-linux-gnu", + "-headerFilterAdditionalSearchPrefix", "/usr/include/ffmpeg" + ) + PlatformInfo.isWindows() -> includeDirsFfmpeg = listOf("-compiler-option", "-I$mingwPath/include") +} + +var includeDirsSdl = when { + PlatformInfo.isMac() -> listOf( + "-compiler-option", "-I/opt/local/include/SDL2", + "-compiler-option", "-I/usr/local/include/SDL2" + ) + PlatformInfo.isLinux() -> listOf("-compiler-option", "-I/usr/include/SDL2") + PlatformInfo.isWindows() -> listOf("-compiler-option", "-I$mingwPath/include/SDL2") + else -> error("Unsupported platform") +} + +compileBenchmark { + applicationName = "Videoplayer" + repeatNumber = 10 + buildSteps = mapOf( + "runCinteropFfmpeg" to listOf("$dist/bin/cinterop$toolSuffix", + "-o", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-ffmpeg.klib", + "-def", "$dist/../samples/videoplayer/src/nativeInterop/cinterop/ffmpeg.def" + ) + filterDirsFfmpeg + includeDirsFfmpeg, + + "runCinteropSdl" to listOf("$dist/bin/cinterop$toolSuffix", + "-o", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-sdl.klib", + "-def", "$dist/../samples/videoplayer/src/nativeInterop/cinterop/sdl.def" + ) + includeDirsSdl, + + "runKonanProgram" to listOf("$dist/bin/konanc$toolSuffix", + "-ea", "-p", "program", + "-o", "${buildDir.absolutePath}/program$binarySuffix", + "-l", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-ffmpeg.klib", + "-l", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-sdl.klib", + "-Xmulti-platform", "$dist/../samples/videoplayer/src/videoPlayerMain/kotlin", + "-entry", "sample.videoplayer.main" + ) + linkerOpts + ) +}