diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LMbenchExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LMbenchExecutorTests.cs index 45a2c23eb4..5ef92c4c10 100644 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LMbenchExecutorTests.cs +++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LMbenchExecutorTests.cs @@ -35,7 +35,8 @@ public void SetupTest() this.Parameters = new Dictionary() { { nameof(LMbenchExecutor.PackageName), "lmbench" }, - { nameof(LMbenchExecutor.CompilerFlags), "CPPFLAGS=\"-I /usr/include/tirpc\"" } + { nameof(LMbenchExecutor.CompilerFlags), "CPPFLAGS=\"-I /usr/include/tirpc\"" }, + { nameof(LMbenchExecutor.Scenario), "Scenario" } }; this.ProcessManager.OnProcessCreated = (process) => @@ -60,6 +61,26 @@ public async Task LMbenchExecutorExecutesTheExpectedWorkloadCommands() } } + [Test] + public async Task LMbenchExecutorExecutesTheExpectedCommandForLatMemRd() + { + this.Parameters[nameof(LMbenchExecutor.BinaryName)] = "lat_mem_rd"; + this.ProcessManager.OnProcessCreated = (process) => + { + string lmbenchOutput = System.IO.File.ReadAllText(this.Combine(LMbenchExecutorTests.Examples, "latmemrd_example_results.txt")); + process.StandardOutput.Append(lmbenchOutput); + }; + using (TestLMbenchExecutor lmbenchExecutor = new TestLMbenchExecutor(this.Dependencies, this.Parameters)) + { + await lmbenchExecutor.ExecuteAsync(EventContext.None, CancellationToken.None); + + Assert.IsTrue(this.ProcessManager.CommandsExecuted( + $"sudo chmod -R 2777 \"/home/user/tools/VirtualClient/packages/lmbench/scripts\"", + $"make build CPPFLAGS=\"-I /usr/include/tirpc\"", + $"/home/user/tools/VirtualClient/packages/lmbench/bin/x86_64-Linux/lat_mem_rd")); + } + } + [Test] public async Task LMbenchExecutorExecutesTheExpectedLMbenchBenchmarks() { diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LatMemRdMetricsParserTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LatMemRdMetricsParserTests.cs index 3fdae8c733..6acfc8795b 100644 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LatMemRdMetricsParserTests.cs +++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/LMbench/LatMemRdMetricsParserTests.cs @@ -37,10 +37,10 @@ public void LMbenchMetricsParserCapturesTheExpectedMetrics_1() IList metrics = parser.Parse(); Assert.IsTrue(metrics.Count == 54); - Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency_StrideBytes_64_Array_512_B" && m.Value == 1.438)); - Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency_StrideBytes_64_Array_1_KiB" && m.Value == 1.438)); - Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency_StrideBytes_32_Array_768_KiB" && m.Value == 1.506)); - Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency_StrideBytes_32_Array_32_MiB" && m.Value == 1.612)); + Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency" && m.Value == 1.438)); + Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency" && m.Value == 1.438)); + Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency" && m.Value == 1.506)); + Assert.IsNotNull(metrics.FirstOrDefault(m => m.Name == "Latency" && m.Value == 1.612)); } } } \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/LMbench/LMbenchExecutor.cs b/src/VirtualClient/VirtualClient.Actions/LMbench/LMbenchExecutor.cs index 2517e973be..e4f5795d98 100644 --- a/src/VirtualClient/VirtualClient.Actions/LMbench/LMbenchExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/LMbench/LMbenchExecutor.cs @@ -170,7 +170,16 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel await this.LogProcessDetailsAsync(executeBinary, telemetryContext); executeBinary.ThrowIfErrored(ProcessProxy.DefaultSuccessCodes, errorReason: ErrorReason.WorkloadFailed); LatMemRdMetricsParser latMemRdMetricsParser = new LatMemRdMetricsParser($"{executeBinary.StandardOutput.ToString()}{executeBinary.StandardError.ToString()}"); - this.CaptureMetrics(executeBinary, latMemRdMetricsParser, telemetryContext, this.BinaryName); + IList metrics = latMemRdMetricsParser.Parse(); + + foreach (Metric metric in metrics) + { + IConvertible arraySize = null, strideSizeInBytes = null; + metric.Metadata.TryGetValue("ArraySize", out arraySize); + metric.Metadata.TryGetValue("StrideSizeInBytes", out strideSizeInBytes); + string scenario = $"StrideSize_{strideSizeInBytes ?? string.Empty}_B_ArraySize_{arraySize ?? string.Empty}"; + this.CaptureMetric(metric, executeBinary, telemetryContext, $"LMBench\\{this.BinaryName}", scenario); + } } } } @@ -238,7 +247,7 @@ private Task BuildSourceCodeAsync(EventContext telemetryContext, CancellationTok }); } - private void CaptureMetrics(IProcessProxy process, MetricsParser metricsParser, EventContext telemetryContext, string scenario) + private void CaptureMetric(Metric metric, IProcessProxy process, EventContext telemetryContext, string toolName, string scenarioName) { this.MetadataContract.AddForScenario( "LMbench", @@ -247,18 +256,18 @@ private void CaptureMetrics(IProcessProxy process, MetricsParser metricsParser, this.MetadataContract.Apply(telemetryContext); - IList metrics = metricsParser.Parse(); - - this.Logger.LogMetrics( - toolName: "LMbench", - scenarioName: scenario, - process.StartTime, - process.ExitTime, - metrics, - metricCategorization: null, - scenarioArguments: process.FullCommand(), - this.Tags, - telemetryContext); + this.Logger.LogMetric( + toolName: toolName, + scenarioName: scenarioName, + process.StartTime, + process.ExitTime, + metric.Name, + metric.Value, + metric.Unit, + metricCategorization: null, + scenarioArguments: process.FullCommand(), + this.Tags, + telemetryContext); } private Task ExecuteWorkloadAsync(EventContext telemetryContext, CancellationToken cancellationToken) @@ -326,7 +335,13 @@ private Task ExecuteWorkloadAsync(EventContext telemetryContext, CancellationTok // The use of the original telemetry context created at the top // is purposeful. LMbenchMetricsParser lmbenchMetricsParser = new LMbenchMetricsParser(process.StandardOutput.ToString()); - this.CaptureMetrics(process, lmbenchMetricsParser, relatedContext, "Memory Benchmark"); + IList metrics = lmbenchMetricsParser.Parse(); + + foreach (Metric metric in metrics) + { + string scenario = "Memory Benchmark"; + this.CaptureMetric(metric, process, telemetryContext, $"LMBench", scenario); + } } }); } diff --git a/src/VirtualClient/VirtualClient.Actions/LMbench/LatMemRdMetricsParser.cs b/src/VirtualClient/VirtualClient.Actions/LMbench/LatMemRdMetricsParser.cs index 3e0ad35c13..aa6218c807 100644 --- a/src/VirtualClient/VirtualClient.Actions/LMbench/LatMemRdMetricsParser.cs +++ b/src/VirtualClient/VirtualClient.Actions/LMbench/LatMemRdMetricsParser.cs @@ -41,11 +41,14 @@ public override IList Parse() { var values = line.Split(' '); string strideSize = section.Key.Split('=')[1]; - var metadata = new Dictionary(); - metadata.Add("StrideSizeBytes", strideSize); - metadata.Add("ArraySizeInMiB", values[0]); long arraySizeInBytes = this.RoundOffToNearest512Multiple(double.Parse(values[0]) * 1024 * 1024) * 512; - metrics.Add(new Metric($"Latency_StrideBytes_{strideSize}_Array_{this.MetricNameSuffix(arraySizeInBytes)}", double.Parse(values[1]), "ns", MetricRelativity.LowerIsBetter, null, $"Latency for memory read operation for Array size in MB {values[0]} & stride size {strideSize} in nano seconds", metadata)); + var metadata = new Dictionary(); + + metadata.Add("StrideSizeInBytes", strideSize); + metadata.Add("ArraySize", this.ArraySizeWithUnit(arraySizeInBytes)); + metadata.Add("ArraySizeInBytes", arraySizeInBytes); + + metrics.Add(new Metric($"Latency", double.Parse(values[1]), "ns", MetricRelativity.LowerIsBetter, null, $"Latency for memory read operation for Array size in MB {values[0]} & stride size {strideSize} in nano seconds", metadata)); } } @@ -65,7 +68,7 @@ private long RoundOffToNearest512Multiple(double number) return (long)Math.Round(number / 512.0); } - private string MetricNameSuffix(double bytes) + private string ArraySizeWithUnit(double bytes) { if (bytes >= 1024 * 1024) { @@ -79,7 +82,6 @@ private string MetricNameSuffix(double bytes) { return $"{bytes}_B"; } - } } } diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-MEM-LATRDMEM.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-MEM-LATRDMEM.json index e23637eb9b..81cf06e8e0 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-MEM-LATRDMEM.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-MEM-LATRDMEM.json @@ -8,8 +8,8 @@ }, "Parameters": { "CompilerName": "gcc", - "CompilerVersion": "10", - "CompilerFlags": "CPPFLAGS=\"-I /usr/include/tirpc\"" + "CompilerVersion": "13", + "CompilerFlags": "CPPFLAGS=\" -O2 -Wall -march=native -I /usr/include/tirpc\"" }, "Actions": [ {