Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

Commit

Permalink
Benchmarks: Move project configuration to a separate plugin
Browse files Browse the repository at this point in the history
This patch moves benchmark configuration logic described in
performance/gradle/benchmark.gradle to a separate plugin located
in the buildSrc project.
  • Loading branch information
ilmat192 committed Jun 18, 2019
1 parent 487f623 commit 8600e4b
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 195 deletions.
12 changes: 11 additions & 1 deletion buildSrc/plugins/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ buildscript {

apply plugin: 'kotlin'
apply plugin: 'kotlinx-serialization'
apply plugin: 'java-gradle-plugin'

/* don't use repositories: gradle will ignore it anyway, but may confuse gradle build engineer, see outer build.gradle */

Expand Down Expand Up @@ -57,4 +58,13 @@ rootProject.dependencies {
compileGroovy {
// Add Kotlin classes to a classpath for the Groovy compiler
classpath += project.files(compileKotlin.destinationDir)
}
}

gradlePlugin {
plugins {
benchmarkPlugin {
id = 'benchmarking'
implementationClass = 'org.jetbrains.kotlin.benchmark.BenchmarkingPlugin'
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.file.*

internal class ExecClang(private val project: Project) {
class ExecClang(private val project: Project) {

private val platformManager = project.rootProject.findProperty("platformManager") as PlatformManager

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ fun getNativeProgramExtension(): String = when {
else -> error("Unknown host")
}

fun getKotlinNativeExecutable(target: KotlinNativeTarget, buildType: String) =
target.binaries.getExecutable("benchmark", buildType).outputFile.getAbsolutePath()

fun getFileSize(filePath: String): Long? {
val file = File(filePath)
return if (file.exists()) file.length() else null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package org.jetbrains.kotlin.benchmark

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetPreset
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.konan.target.HostManager
import javax.inject.Inject

private val NamedDomainObjectContainer<KotlinSourceSet>.commonMain
get() = maybeCreate("commonMain")

private val NamedDomainObjectContainer<KotlinSourceSet>.nativeMain
get() = maybeCreate("nativeMain")

private val NamedDomainObjectContainer<KotlinSourceSet>.jvmMain
get() = maybeCreate("jvmMain")

private val Project.benchmark: BenchmarkExtension
get() = extensions.getByName(BenchmarkingPlugin.BENCHMARK_EXTENSION_NAME) as BenchmarkExtension

private val Project.nativeWarmup: Int
get() = (property("nativeWarmup") as String).toInt()

private val Project.jvmWarmup: Int
get() = (property("jvmWarmup") as String).toInt()

private val Project.attempts: Int
get() = (property("attempts") as String).toInt()

private val Project.nativeBenchResults: String
get() = property("nativeBenchResults") as String

private val Project.jvmBenchResults: String
get() = property("jvmBenchResults") as String

private val Project.compilerArgs: List<String>
get() = (findProperty("compilerArgs") as String?)?.split("\\s").orEmpty()

internal val Project.kotlinVersion: String
get() = property("kotlinVersion") as String

internal val Project.konanVersion: String
get() = property("konanVersion") as String

internal val Project.nativeJson: String
get() = project.property("nativeJson") as String

internal val Project.commonBenchmarkProperties: Map<String, Any>
get() = mapOf(
"cpu" to System.getProperty("os.arch"),
"os" to System.getProperty("os.name"),
"jdkVersion" to System.getProperty("java.version"),
"jdkVendor" to System.getProperty("java.vendor"),
"kotlinVersion" to kotlinVersion
)

open class BenchmarkExtension @Inject constructor(val project: Project) {
var applicationName: String = project.name
var commonSrcDirs: Collection<Any> = emptyList()
var jvmSrcDirs: Collection<Any> = emptyList()
var nativeSrcDirs: Collection<Any> = emptyList()
var linkerOpts: Collection<String> = emptyList()
}

/**
* A plugin configuring a benchmark Kotlin/Native project.
*/
open class BenchmarkingPlugin: Plugin<Project> {

private val mingwPath: String = System.getenv("MINGW64_DIR") ?: "c:/msys64/mingw64"

private fun Project.determinePreset(): KotlinNativeTargetPreset =
defaultHostPreset(this).also { preset ->
logger.quiet("$project has been configured for ${preset.name} platform.")
} as KotlinNativeTargetPreset

private fun Project.configureSourceSets(kotlinVersion: String) {
with(kotlin.sourceSets) {
commonMain.dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion")
}

jvmMain.dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
}

// Add sources specified by a user in the benchmark DSL.
afterEvaluate {
benchmark.let {
commonMain.kotlin.srcDirs(*it.commonSrcDirs.toTypedArray())
nativeMain.kotlin.srcDirs(*it.nativeSrcDirs.toTypedArray())
jvmMain.kotlin.srcDirs(*it.jvmSrcDirs.toTypedArray())
}
}
}
}

private fun Project.configureJVMTarget() {
kotlin.jvm {
compilations.all {
it.compileKotlinTask.kotlinOptions {
jvmTarget = "1.8"
suppressWarnings = true
freeCompilerArgs = project.compilerArgs
}
}
}
}

private fun Project.configureNativeTarget(hostPreset: KotlinNativeTargetPreset) {
kotlin.targetFromPreset(hostPreset, NATIVE_TARGET_NAME) {
compilations.getByName("main").kotlinOptions.freeCompilerArgs = project.compilerArgs + "-opt"
binaries.executable(NATIVE_EXECUTABLE_NAME, listOf(RELEASE)) {
if (HostManager.hostIsMingw) {
linkerOpts.add("-L${mingwPath}/lib")
}

// Specify settings configured by a user in the benchmark extension.
afterEvaluate {
linkerOpts.addAll(benchmark.linkerOpts)
runTask!!.args(
"-w", nativeWarmup,
"-r", attempts,
"-o", buildDir.resolve(nativeBenchResults).absolutePath,
"-p", "${benchmark.applicationName}::"
)
}

}
}
}


private fun Project.configureMPPExtension() {
configureSourceSets(kotlinVersion)
configureJVMTarget()
configureNativeTarget(determinePreset())
}


private fun Project.configureTasks() {
// Native run task.
val nativeTarget = kotlin.targets.getByName(NATIVE_TARGET_NAME) as KotlinNativeTarget
val nativeExecutable = nativeTarget.binaries.getExecutable(NATIVE_EXECUTABLE_NAME, NativeBuildType.RELEASE)
val konanRun = createRunTask(this, "konanRun", nativeExecutable.runTask!!)

// JVM run task.
val jvmRun = tasks.create("jvmRun", RunJvmTask::class.java) { task ->
task.dependsOn("build")
val mainCompilation = kotlin.jvm().compilations.getByName("main")
val runtimeDependencies = configurations.getByName(mainCompilation.runtimeDependencyConfigurationName)
task.classpath(files(mainCompilation.output.allOutputs, runtimeDependencies))
task.main = "MainKt"

// Specify settings configured by a user in the benchmark extension.
afterEvaluate {
task.args(
"-w", jvmWarmup,
"-r", attempts,
"-o", buildDir.resolve(jvmBenchResults),
"-p", "${benchmark.applicationName}::"
)
}
}

// Native report task.
val konanJsonReport = tasks.create("konanJsonReport") {
it.doLast {
val applicationName = benchmark.applicationName
val nativeCompileTime = getNativeCompileTime(applicationName)
val benchContents = buildDir.resolve(nativeBenchResults).readText()

val properties = commonBenchmarkProperties + mapOf(
"type" to "native",
"compilerVersion" to konanVersion,
"flags" to nativeTarget.compilations.main.kotlinOptions.freeCompilerArgs.map { "\"$it\"" },
"benchmarks" to benchContents,
"compileTime" to listOf(nativeCompileTime),
"codeSize" to getCodeSizeBenchmark(applicationName, nativeExecutable.outputFile.absolutePath)
)

val output = createJsonReport(properties)
buildDir.resolve(nativeJson).writeText(output)
}
}

// JVM report task.
val jvmJsonReport = tasks.create("jvmJsonReport") {
it.doLast {
val applicationName = benchmark.applicationName
val jarPath = (tasks.getByName("jvmJar") as Jar).archiveFile.get().asFile
val jvmCompileTime = getJvmCompileTime(applicationName)
val benchContents = buildDir.resolve(jvmBenchResults).readText()

val properties: Map<String, Any> = commonBenchmarkProperties + mapOf(
"type" to "jvm",
// TODO: We had buildKotlinVersion here!!!!
"compilerVersion" to kotlinVersion,
"benchmarks" to benchContents,
"compileTime" to listOf(jvmCompileTime),
"codeSize" to getCodeSizeBenchmark(applicationName, jarPath.absolutePath)
)

val output = createJsonReport(properties)
buildDir.resolve(project.property("jvmJson") as String).writeText(output)
}

jvmRun.finalizedBy(it)
}
}

override fun apply(target: Project) = with(target) {
pluginManager.apply("kotlin-multiplatform")
extensions.create(BENCHMARK_EXTENSION_NAME, BenchmarkExtension::class.java, this)
configureMPPExtension()
addTimeListener(this)
configureTasks()
}

companion object {
const val NATIVE_TARGET_NAME = "native"
const val NATIVE_EXECUTABLE_NAME = "benchmark"
const val BENCHMARK_EXTENSION_NAME = "benchmark"
}
}
12 changes: 0 additions & 12 deletions performance/cinterop/build.gradle

This file was deleted.

24 changes: 24 additions & 0 deletions performance/cinterop/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.gradle.plugin.mpp.KotlinNativeTarget

plugins {
id("benchmarking")
}

benchmark {
applicationName = "Cinterop"
commonSrcDirs = listOf("../../tools/benchmarks/shared/src", "src/main/kotlin", "../shared/src/main/kotlin", "../../tools/kliopt")
jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm")
nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native")
}

val native = kotlin.targets.getByName("native") as KotlinNativeTarget
native.compilations["main"].cinterops {
create("macros")
create("struct")
create("types")
}
Loading

0 comments on commit 8600e4b

Please sign in to comment.