From 90d6ba08367940335eac0868ba8768eb2b5b0025 Mon Sep 17 00:00:00 2001 From: Stan Brubaker <120737309+stanbrub@users.noreply.github.com> Date: Tue, 5 Nov 2024 19:20:50 -0700 Subject: [PATCH] feat: Add Hardware, Memory, Java Opts, Dependency Versions to Platform Detail (#380) --- .../benchmark/api/BenchPlatform.java | 129 +++++++++++++----- .../benchmark/api/BenchPlatformTest.java | 16 ++- 2 files changed, 104 insertions(+), 41 deletions(-) diff --git a/src/main/java/io/deephaven/benchmark/api/BenchPlatform.java b/src/main/java/io/deephaven/benchmark/api/BenchPlatform.java index fa2b3ad0..8ace5667 100644 --- a/src/main/java/io/deephaven/benchmark/api/BenchPlatform.java +++ b/src/main/java/io/deephaven/benchmark/api/BenchPlatform.java @@ -13,7 +13,6 @@ import java.util.concurrent.atomic.AtomicReference; import io.deephaven.benchmark.connect.ResultTable; import io.deephaven.benchmark.util.Filer; -import io.deephaven.benchmark.util.Numbers; import io.deephaven.engine.exceptions.ArgumentException; /** @@ -92,7 +91,7 @@ protected ResultTable fetchResult(String query) { api.setName("# Write Platform Details"); // # means skip adding to results file var tbl = new AtomicReference(); - api.query(query).fetchAfter("benchApiProps", table -> { + api.query(query).fetchAfter("bench_api_platform", table -> { tbl.set(table); }).execute(); api.close(); @@ -143,7 +142,6 @@ private void addTestRunnerProps(Map benchApiProps) { var benchApiOrigin = "test-runner"; var deephavenVersion = getDeephavenVersion(dhInst, "/META-INF/maven/io.deephaven/deephaven-benchmark/pom.xml"); - // Java Properties (These match the Python calls in addEngineProps benchApiAddProperty(benchApiProps, benchApiOrigin, "java.version", System.getProperty("java.version")); benchApiAddProperty(benchApiProps, benchApiOrigin, "java.vm.name", System.getProperty("java.vm.name")); benchApiAddProperty(benchApiProps, benchApiOrigin, "java.class.version", @@ -158,38 +156,100 @@ private void addTestRunnerProps(Map benchApiProps) { private void addEngineProps(Map benchApiProps) { var query = """ - import jpy, sys - from deephaven import new_table, input_table - from deephaven import dtypes as dht - from deephaven.column import string_col + import jpy, sys, os, re + from deephaven import new_table, input_table, dtypes as dht, perfmon as pm + from deephaven.column import string_col as sc - def benchApiAddProperty(prop_table, origin, name, value): - t = new_table([string_col('origin', [origin]), string_col('name', [name]), string_col('value', [str(value)])]) - prop_table.add(t) - - System = jpy.get_type('java.lang.System') Runtime = jpy.get_type('java.lang.Runtime') + bench_api_platform = input_table({'origin':dht.string, 'name':dht.string, 'value':dht.string}) - dhInst = jpy.get_type('io.deephaven.engine.exceptions.ArgumentException')() - benchApiOrigin = 'deephaven-engine' - deephavenVersion = dhInst.getClass().getPackage().getImplementationVersion() + def bench_api_add_platform(name, value): + name = str(name).strip(); value = str(value).strip() + t = new_table([sc('origin', ['deephaven-engine']), sc('name', [name]), sc('value', [value])]) + bench_api_platform.add(t) + + def bench_api_get_proc_info(proctype, prockey): + info = pm.process_info_log().where(['Type.equals(proctype)','Key.equals(prockey)']) + return info.j_table.columnIterator('Value').next() - benchApiProps = input_table({'origin':dht.string, 'name':dht.string, 'value':dht.string}) + def bench_api_add_proc_info(name, proctype, prockeys, delim=' '): + values = [] + for prockey in prockeys: + value = bench_api_get_proc_info(proctype, prockey) + values.append(value) + bench_api_add_platform(name, delim.join(values)) + def bench_api_add_proc_args(name, proctype, len_name, includes=(), excludes=()): + prockeys = [] + for i in range(int(bench_api_get_proc_info(proctype,len_name))): + value = bench_api_get_proc_info('runtime-mx.jvm-args',str(i)) + if(value.startswith(includes) and not value.startswith(excludes)): + prockeys.append(str(i)) + bench_api_add_proc_info(name, proctype, prockeys) + + bench_api_add_proc_info('system.os.version','system-info.os',['family','version.version','version.name']) + bench_api_add_proc_info('system.kernel.version','system-info.os',['version.build']) + bench_api_add_proc_info('system.manufacturer','system-info.sys',['manufacturer','model']) + bench_api_add_proc_info('system.physical.memory','system-info.memory',['physical']) + bench_api_add_proc_info('system.baseboard.maker','system-info.sys',['baseboard.manufacturer','baseboard.model']) + bench_api_add_proc_info('system.cpu.model','system-info.cpu',['name']) + bench_api_add_proc_info('system.cpu.cores','system-info.cpu',['physical','logical'],'/') + bench_api_add_proc_info('java.version','runtime-mx.sys-props',['java.vendor.version']) + bench_api_add_proc_info('java.max.heap','memory-mx.heap',['max']) + bench_api_add_platform('java.available.processors',Runtime.getRuntime().availableProcessors()) + bench_api_add_proc_args('java.xx.args','runtime-mx.jvm-args','len',('-XX'),('-XX:CompilerDirectivesFile=','-XX:+UnlockD')) + dhInst = jpy.get_type('io.deephaven.engine.exceptions.ArgumentException')() + deephaven_version = dhInst.getClass().getPackage().getImplementationVersion() + bench_api_add_platform('deephaven.version', deephaven_version) python_version = '.'.join([str(sys.version_info.major), str(sys.version_info.minor), str(sys.version_info.micro)]) - benchApiAddProperty(benchApiProps, benchApiOrigin, "python.version", python_version); + bench_api_add_platform('python.version', python_version) - # Java Properties - benchApiAddProperty(benchApiProps, benchApiOrigin, "java.version", System.getProperty("java.version")); - benchApiAddProperty(benchApiProps, benchApiOrigin, "java.vm.name", System.getProperty("java.vm.name")); - benchApiAddProperty(benchApiProps, benchApiOrigin, "java.class.version", - System.getProperty("java.class.version")); - benchApiAddProperty(benchApiProps, benchApiOrigin, "os.name", System.getProperty("os.name")); - benchApiAddProperty(benchApiProps, benchApiOrigin, "os.version", System.getProperty("os.version")); - benchApiAddProperty(benchApiProps, benchApiOrigin, "available.processors", - Runtime.getRuntime().availableProcessors()); - benchApiAddProperty(benchApiProps, benchApiOrigin, "java.max.memory", Runtime.getRuntime().maxMemory()); - benchApiAddProperty(benchApiProps, benchApiOrigin, "deephaven.version", deephavenVersion); + # Java Dependency Versions + classpath = bench_api_get_proc_info('runtime-mx.sys-props','java.class.path') + from collections import defaultdict + jar_versions = defaultdict(list) + total_jar_size = 0 + engine_artifact=None + for f in sorted(re.split(':|;|,',classpath)): + artifact_full = os.path.basename(f) + if re.search('deephaven-engine-api-.*[.]jar',artifact_full): + engine_artifact = os.path.abspath(f) + if(os.path.exists(f)): + total_jar_size = total_jar_size + os.path.getsize(f) + artifact_name = re.sub('[-][0-9]+[.].*jar$','',artifact_full) + artifact_vers = re.sub('(^-)|([.]jar$)','',artifact_full.replace(artifact_name,'')) + if not (artifact_name.startswith('deephaven-') and artifact_vers == deephaven_version): + jar_versions[artifact_name + '.jar'].append(artifact_vers) + + for key, value in jar_versions.items(): + value.sort(key=lambda x: x.count('.')) + bench_api_add_platform(key,' : '.join(value)) + bench_api_add_platform('dependency.jar.size',total_jar_size) + + # Get the class version Deephaven was compiled with + engine_class='io/deephaven/engine/table/Table' + command=f'javap -cp {engine_artifact} -v {engine_class} | grep -E "(minor .*: [0-9]+)|(major .*: [0-9]+)" | sort' + class_vers = '.'.join(re.findall('[0-9]+',os.popen(command).read())) + bench_api_add_platform('java.class.version',class_vers) + + # Python Dependency Versions + import importlib.metadata + package_dists = {} + package_locations = {} + for dist in sorted(importlib.metadata.distributions(), key=lambda x: x.name): + if(os.path.basename(dist.locate_file('')) == 'site-packages'): + package_dists[dist.name] = dist.version + package_locations[dist.locate_file('')] = None + + for key, value in sorted(package_dists.items()): + bench_api_add_platform(key + '.py', value) + + from pathlib import Path + total_python_size = 0 + for location in package_locations: + total_python_size = sum(p.stat().st_size for p in Path(location).rglob('*')) + + bench_api_add_platform('dependency.python.size',total_python_size) """; ResultTable t = fetchResult(query); @@ -203,27 +263,22 @@ def benchApiAddProperty(prop_table, origin, name, value): } private void benchApiAddProperty(Map properties, String origin, String name, Object value) { - var v = formatValue(name, value); + var v = value.toString(); var prop = new Property(origin, name, v, new AtomicBoolean(false)); properties.putIfAbsent(prop.getName(), prop); } static void writeLine(Property prop, Path file) { try (BufferedWriter out = Files.newBufferedWriter(file, StandardOpenOption.CREATE, StandardOpenOption.APPEND)) { - out.write(String.join(",", prop.origin(), prop.name(), prop.value())); + out.write(String.join(",", normalize(prop.origin()), normalize(prop.name()), normalize(prop.value()))); out.newLine(); } catch (Exception ex) { throw new RuntimeException("Failed to write result to file: " + file, ex); } } - private String formatValue(String name, Object value) { - switch (name) { - case "java.max.memory": - return Numbers.formatBytesToGigs(value); - default: - return value.toString(); - } + static String normalize(String value) { + return value.replaceAll("[\"',]", " ").replaceAll("\\s+", " ").trim(); } record Property(String origin, String name, String value, AtomicBoolean isWritten) { diff --git a/src/test/java/io/deephaven/benchmark/api/BenchPlatformTest.java b/src/test/java/io/deephaven/benchmark/api/BenchPlatformTest.java index 165c5ded..0c70f45b 100644 --- a/src/test/java/io/deephaven/benchmark/api/BenchPlatformTest.java +++ b/src/test/java/io/deephaven/benchmark/api/BenchPlatformTest.java @@ -13,7 +13,7 @@ public class BenchPlatformTest { @Test - public void commit() throws Exception { + void commit() throws Exception { Path outParent = Paths.get(getClass().getResource("test-profile.properties").toURI()).getParent(); var platform = new LocalPlatform(outParent, "platform-test.out"); platform.commit(); @@ -23,11 +23,11 @@ public void commit() throws Exception { assertEquals("origin,name,value", lines.get(0), "Wrong header"); assertTrue(lines.get(1).matches("test-runner,java.version,[0-9.]+"), "Wrong values: " + lines.get(1)); assertTrue(lines.get(3).matches("test-runner,java.class.version,[0-9.]+"), "Wrong values: " + lines.get(3)); - assertTrue(lines.get(7).matches("test-runner,java.max.memory,[0-9]+g"), "Wrong values: " + lines.get(7)); + assertTrue(lines.get(7).matches("test-runner,java.max.memory,[0-9]+"), "Wrong values: " + lines.get(7)); assertEquals("test-runner,profile.prop2,prop2", lines.get(9), "Wrong values"); assertEquals("deephaven-engine,java.version,17.0.5", lines.get(11), "Wrong values"); assertEquals("deephaven-engine,java.class.version,61.0", lines.get(13), "Wrong values"); - assertEquals("deephaven-engine,java.max.memory,24g", lines.get(17), "Wrong values"); + assertEquals("deephaven-engine,java.max.memory,25769803776", lines.get(17), "Wrong values"); platform.add("deephaven-engine", "no.repeat.no.overwrite", "100"); platform.add("deephaven-engine", "no.repeat.no.overwrite", "200"); @@ -38,13 +38,21 @@ public void commit() throws Exception { } @Test - public void getDeephavenVersionFromPom() throws Exception { + void getDeephavenVersionFromPom() throws Exception { Path outParent = Paths.get(getClass().getResource("test-profile.properties").toURI()).getParent(); var platform = new LocalPlatform(outParent, "platform-test.out"); assertEquals("0.22.0", platform.getDeephavenVersion(outParent, "platform-test-pom.xml")); assertEquals("Unknown", platform.getDeephavenVersion(outParent, "test-profile.properties")); } + @Test + void nomalize() { + assertEquals("one", BenchPlatform.normalize("one")); + assertEquals("one two", BenchPlatform.normalize("one,two")); + assertEquals("one two", BenchPlatform.normalize("one, \"two\"")); + assertEquals("one two", BenchPlatform.normalize(" one, 'two' ")); + } + static class LocalPlatform extends BenchPlatform { LocalPlatform(Path dir, String fileName) {