summaryrefslogtreecommitdiff
path: root/opendc-trace/opendc-trace-swf/src
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-10-25 14:53:54 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-10-25 14:53:54 +0200
commitaa9b32f8cd1467e9718959f400f6777e5d71737d (patch)
treeb88bbede15108c6855d7f94ded4c7054df186a72 /opendc-trace/opendc-trace-swf/src
parenteb0e0a3bc557c05a70eead388797ab850ea87366 (diff)
parentb7a71e5b4aa77b41ef41deec2ace42b67a5a13a7 (diff)
merge: Integrate v2.1 progress into public repository
This pull request integrates the changes planned for the v2.1 release of OpenDC into the public Github repository in order to sync the progress of both repositories.
Diffstat (limited to 'opendc-trace/opendc-trace-swf/src')
-rw-r--r--opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt150
-rw-r--r--opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt76
-rw-r--r--opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat1
-rw-r--r--opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt74
-rw-r--r--opendc-trace/opendc-trace-swf/src/test/resources/trace.swf6
5 files changed, 307 insertions, 0 deletions
diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt
new file mode 100644
index 00000000..2f6ea6ee
--- /dev/null
+++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * 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.
+ */
+
+package org.opendc.trace.swf
+
+import org.opendc.trace.*
+import java.io.BufferedReader
+import java.time.Duration
+import java.time.Instant
+
+/**
+ * A [TableReader] implementation for the SWF format.
+ */
+internal class SwfTaskTableReader(private val reader: BufferedReader) : TableReader {
+ /**
+ * The current row.
+ */
+ private var fields = emptyList<String>()
+
+ /**
+ * A [Regex] object to match whitespace.
+ */
+ private val whitespace = "\\s+".toRegex()
+
+ override fun nextRow(): Boolean {
+ var line: String
+ var num = 0
+
+ while (true) {
+ line = reader.readLine() ?: return false
+ num++
+
+ if (line.isBlank()) {
+ // Ignore empty lines
+ continue
+ } else if (line.startsWith(";")) {
+ // Ignore comments for now
+ continue
+ }
+
+ break
+ }
+
+ fields = line.trim().split(whitespace)
+
+ if (fields.size < 18) {
+ throw IllegalArgumentException("Invalid format at line $line")
+ }
+
+ return true
+ }
+
+ override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1
+
+ override fun isNull(index: Int): Boolean {
+ require(index in columns.values) { "Invalid column index" }
+ return false
+ }
+
+ override fun get(index: Int): Any? {
+ return when (index) {
+ COL_JOB_ID -> fields[index]
+ COL_SUBMIT_TIME -> Instant.ofEpochSecond(fields[index].toLong(10))
+ COL_WAIT_TIME, COL_RUN_TIME -> Duration.ofSeconds(fields[index].toLong(10))
+ COL_REQ_NCPUS, COL_ALLOC_NCPUS, COL_STATUS, COL_GROUP_ID, COL_USER_ID -> getInt(index)
+ COL_PARENT_JOB -> {
+ val parent = fields[index].toLong(10)
+ if (parent < 0) emptySet() else setOf(parent)
+ }
+ else -> throw IllegalArgumentException("Invalid column")
+ }
+ }
+
+ override fun getBoolean(index: Int): Boolean {
+ throw IllegalArgumentException("Invalid column")
+ }
+
+ override fun getInt(index: Int): Int {
+ return when (index) {
+ COL_REQ_NCPUS, COL_ALLOC_NCPUS, COL_STATUS, COL_GROUP_ID, COL_USER_ID -> fields[index].toInt(10)
+ else -> throw IllegalArgumentException("Invalid column")
+ }
+ }
+
+ override fun getLong(index: Int): Long {
+ throw IllegalArgumentException("Invalid column")
+ }
+
+ override fun getDouble(index: Int): Double {
+ throw IllegalArgumentException("Invalid column")
+ }
+
+ override fun close() {
+ reader.close()
+ }
+
+ /**
+ * Default column indices for the SWF format.
+ */
+ private val COL_JOB_ID = 0
+ private val COL_SUBMIT_TIME = 1
+ private val COL_WAIT_TIME = 2
+ private val COL_RUN_TIME = 3
+ private val COL_ALLOC_NCPUS = 4
+ private val COL_AVG_CPU_TIME = 5
+ private val COL_USED_MEM = 6
+ private val COL_REQ_NCPUS = 7
+ private val COL_REQ_TIME = 8
+ private val COL_REQ_MEM = 9
+ private val COL_STATUS = 10
+ private val COL_USER_ID = 11
+ private val COL_GROUP_ID = 12
+ private val COL_EXEC_NUM = 13
+ private val COL_QUEUE_NUM = 14
+ private val COL_PART_NUM = 15
+ private val COL_PARENT_JOB = 16
+ private val COL_PARENT_THINK_TIME = 17
+
+ private val columns = mapOf(
+ TASK_ID to COL_JOB_ID,
+ TASK_SUBMIT_TIME to COL_SUBMIT_TIME,
+ TASK_WAIT_TIME to COL_WAIT_TIME,
+ TASK_RUNTIME to COL_RUN_TIME,
+ TASK_ALLOC_NCPUS to COL_ALLOC_NCPUS,
+ TASK_REQ_NCPUS to COL_REQ_NCPUS,
+ TASK_STATUS to COL_STATUS,
+ TASK_USER_ID to COL_USER_ID,
+ TASK_GROUP_ID to COL_GROUP_ID,
+ TASK_PARENTS to COL_PARENT_JOB
+ )
+}
diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt
new file mode 100644
index 00000000..1fd076d5
--- /dev/null
+++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2020 AtLarge Research
+ *
+ * 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.
+ */
+
+package org.opendc.trace.swf
+
+import org.opendc.trace.*
+import org.opendc.trace.spi.TableDetails
+import org.opendc.trace.spi.TraceFormat
+import java.nio.file.Path
+import kotlin.io.path.bufferedReader
+
+/**
+ * Support for the Standard Workload Format (SWF) in OpenDC.
+ *
+ * The standard is defined by the PWA, see here: https://www.cse.huji.ac.il/labs/parallel/workload/swf.html
+ */
+public class SwfTraceFormat : TraceFormat {
+ override val name: String = "swf"
+
+ override fun create(path: Path) {
+ throw UnsupportedOperationException("Writing not supported for this format")
+ }
+
+ override fun getTables(path: Path): List<String> = listOf(TABLE_TASKS)
+
+ override fun getDetails(path: Path, table: String): TableDetails {
+ return when (table) {
+ TABLE_TASKS -> TableDetails(
+ listOf(
+ TASK_ID,
+ TASK_SUBMIT_TIME,
+ TASK_WAIT_TIME,
+ TASK_RUNTIME,
+ TASK_REQ_NCPUS,
+ TASK_ALLOC_NCPUS,
+ TASK_PARENTS,
+ TASK_STATUS,
+ TASK_GROUP_ID,
+ TASK_USER_ID
+ ),
+ emptyList()
+ )
+ else -> throw IllegalArgumentException("Table $table not supported")
+ }
+ }
+
+ override fun newReader(path: Path, table: String): TableReader {
+ return when (table) {
+ TABLE_TASKS -> SwfTaskTableReader(path.bufferedReader())
+ else -> throw IllegalArgumentException("Table $table not supported")
+ }
+ }
+
+ override fun newWriter(path: Path, table: String): TableWriter {
+ throw UnsupportedOperationException("Writing not supported for this format")
+ }
+}
diff --git a/opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat
new file mode 100644
index 00000000..6c6b0eb2
--- /dev/null
+++ b/opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat
@@ -0,0 +1 @@
+org.opendc.trace.swf.SwfTraceFormat
diff --git a/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt
new file mode 100644
index 00000000..4dcd43f6
--- /dev/null
+++ b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * 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.
+ */
+
+package org.opendc.trace.swf
+
+import org.junit.jupiter.api.*
+import org.junit.jupiter.api.Assertions.*
+import org.opendc.trace.TABLE_TASKS
+import org.opendc.trace.TASK_ALLOC_NCPUS
+import org.opendc.trace.TASK_ID
+import java.nio.file.Paths
+
+/**
+ * Test suite for the [SwfTraceFormat] class.
+ */
+internal class SwfTraceFormatTest {
+ private val format = SwfTraceFormat()
+
+ @Test
+ fun testTables() {
+ val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI())
+
+ assertEquals(listOf(TABLE_TASKS), format.getTables(path))
+ }
+
+ @Test
+ fun testTableExists() {
+ val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI())
+ assertDoesNotThrow { format.getDetails(path, TABLE_TASKS) }
+ }
+
+ @Test
+ fun testTableDoesNotExist() {
+ val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI())
+
+ assertThrows<IllegalArgumentException> { format.getDetails(path, "test") }
+ }
+
+ @Test
+ fun testReader() {
+ val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI())
+ val reader = format.newReader(path, TABLE_TASKS)
+
+ assertAll(
+ { assertTrue(reader.nextRow()) },
+ { assertEquals("1", reader.get(TASK_ID)) },
+ { assertEquals(306, reader.getInt(TASK_ALLOC_NCPUS)) },
+ { assertTrue(reader.nextRow()) },
+ { assertEquals("2", reader.get(TASK_ID)) },
+ { assertEquals(17, reader.getInt(TASK_ALLOC_NCPUS)) },
+ )
+
+ reader.close()
+ }
+}
diff --git a/opendc-trace/opendc-trace-swf/src/test/resources/trace.swf b/opendc-trace/opendc-trace-swf/src/test/resources/trace.swf
new file mode 100644
index 00000000..c3ecf890
--- /dev/null
+++ b/opendc-trace/opendc-trace-swf/src/test/resources/trace.swf
@@ -0,0 +1,6 @@
+; Excerpt from the PWA: CTC-SP2-1996-3.1-cln.swf
+ 1 0 588530 937 306 142.00 -1 -1 35100 -1 1 97 -1 307 3 -1 -1 -1
+ 2 164472 356587 75 17 2.00 -1 -1 300 -1 1 81 -1 195 3 -1 -1 -1
+ 3 197154 459987 35268 306 32792 -1 -1 35100 -1 0 97 -1 307 3 -1 -1 -1
+ 4 310448 50431 29493 64 28745 -1 -1 64800 -1 1 38 -1 38 1 -1 -1 -1
+ 5 310541 50766 29063 64 28191 -1 -1 64800 -1 1 38 -1 69 1 -1 -1 -1