diff --git a/analysis/src/test/java/ComputeTest.java b/analysis/src/test/java/ComputeTest.java index 81d55c2..87f6005 100644 --- a/analysis/src/test/java/ComputeTest.java +++ b/analysis/src/test/java/ComputeTest.java @@ -3,6 +3,7 @@ import java.util.Random; import java.util.random.RandomGenerator; +import net.laprun.sustainability.power.SensorUnit; import org.junit.jupiter.api.Test; import net.laprun.sustainability.power.SensorMetadata; @@ -13,9 +14,9 @@ public class ComputeTest { private final static SensorMetadata metadata = SensorMetadata - .withNewComponent("cp1", null, true, "mW", false) - .withNewComponent("cp2", null, true, "mW", false) - .withNewComponent("cp3", null, true, "mW", false) + .withNewComponent("cp1", null, true, SensorUnit.mW) + .withNewComponent("cp2", null, true, SensorUnit.mW) + .withNewComponent("cp3", null, true, "mW") .build(); @Test diff --git a/if-manifest-export/src/test/java/net/laprun/sustainability/power/impactframework/export/IFExporterTest.java b/if-manifest-export/src/test/java/net/laprun/sustainability/power/impactframework/export/IFExporterTest.java index f5616f9..cd75d27 100644 --- a/if-manifest-export/src/test/java/net/laprun/sustainability/power/impactframework/export/IFExporterTest.java +++ b/if-manifest-export/src/test/java/net/laprun/sustainability/power/impactframework/export/IFExporterTest.java @@ -13,9 +13,9 @@ class IFExporterTest { public static final String COMPONENT2_NAME = "c2"; public static final String COMPONENT3_NAME = "c3"; private final static SensorMetadata metadata = SensorMetadata - .withNewComponent(COMPONENT1_NAME, "component 1", true, "mW", true) - .withNewComponent(COMPONENT2_NAME, "component 2", true, "mW", true) - .withNewComponent(COMPONENT3_NAME, "component 3", true, "mW", true) + .withNewComponent(COMPONENT1_NAME, "component 1", true, "mW") + .withNewComponent(COMPONENT2_NAME, "component 2", true, "mW") + .withNewComponent(COMPONENT3_NAME, "component 3", true, "mW") .build(); @Test diff --git a/measure/src/test/java/net/laprun/sustainability/power/analysis/TotalMeasureProcessorTest.java b/measure/src/test/java/net/laprun/sustainability/power/analysis/TotalMeasureProcessorTest.java index 03ca479..b078d57 100644 --- a/measure/src/test/java/net/laprun/sustainability/power/analysis/TotalMeasureProcessorTest.java +++ b/measure/src/test/java/net/laprun/sustainability/power/analysis/TotalMeasureProcessorTest.java @@ -15,8 +15,8 @@ class TotalMeasureProcessorTest { void totalShouldFailIfAllComponentsAreNotCommensurable() { final var inError = "cp2"; final var metadata = SensorMetadata - .withNewComponent("cp1", null, true, "mW", true) - .withNewComponent(inError, null, true, "mJ", true) + .withNewComponent("cp1", null, true, "mW") + .withNewComponent(inError, null, true, "mJ") .build(); final var expectedResultUnit = SensorUnit.W; @@ -29,9 +29,9 @@ void totalShouldFailIfAllComponentsAreNotCommensurable() { @Test void testTotal() { final var metadata = SensorMetadata - .withNewComponent("cp1", null, true, "mW", true) - .withNewComponent("cp2", null, true, "mW", true) - .withNewComponent("cp3", null, true, "mW", true) + .withNewComponent("cp1", null, true, "mW") + .withNewComponent("cp2", null, true, "mW") + .withNewComponent("cp3", null, true, "mW") .build(); final var m1c1 = 10.0; diff --git a/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java b/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java index 80685a7..8926d25 100644 --- a/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java +++ b/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java @@ -14,22 +14,11 @@ public class OngoingPowerMeasureTest { private final static SensorMetadata metadata = SensorMetadata - .withNewComponent("cp1", null, true, "mW", true) - .withNewComponent("cp2", null, true, "mW", true) - .withNewComponent("cp3", null, true, "mW", true) + .withNewComponent("cp1", null, true, "mW") + .withNewComponent("cp2", null, true, "mW") + .withNewComponent("cp3", null, true, "mW") .build(); - @Test - void checkThatTotalComponentIsProperlyAdded() { - final var metadata = SensorMetadata - .withNewComponent("cp1", null, true, "mW", false) - .withNewComponent("cp2", null, true, "mW", false) - .withNewComponent("cp3", null, true, "mW", false) - .build(); - var measure = new OngoingPowerMeasure(metadata); - assertThat(measure.metadata().totalComponents()).isEmpty(); - } - @Test void testBasics() { final var m1c1 = 10.0; diff --git a/metadata/src/main/java/net/laprun/sustainability/power/SensorMetadata.java b/metadata/src/main/java/net/laprun/sustainability/power/SensorMetadata.java index 7687b9f..7ab81f7 100644 --- a/metadata/src/main/java/net/laprun/sustainability/power/SensorMetadata.java +++ b/metadata/src/main/java/net/laprun/sustainability/power/SensorMetadata.java @@ -1,7 +1,6 @@ package net.laprun.sustainability.power; import java.util.ArrayList; -import java.util.Arrays; import java.util.BitSet; import java.util.Collections; import java.util.Comparator; @@ -22,9 +21,6 @@ public class SensorMetadata { private final Map components; @JsonProperty("documentation") private final String documentation; - // todo: remove - @JsonProperty("totalComponents") - private final int[] totalComponents; /** * Initializes sensor metadata information @@ -36,24 +32,23 @@ public class SensorMetadata { */ public SensorMetadata(List components, String documentation) { Objects.requireNonNull(components, "Must provide components"); + if (components.isEmpty()) { + throw new IllegalArgumentException("Must provide at least one component"); + } + final var cardinality = components.size(); this.components = new HashMap<>(cardinality); this.documentation = documentation; final var errors = new Errors(); final var indices = new BitSet(cardinality); - final var totalIndices = new BitSet(cardinality); - final var baseUnit = new SensorUnit[1]; components.forEach(component -> { // check that index is valid final var index = component.index; - boolean indexValid = true; if (index < 0 || index >= cardinality) { errors.addError(index + " is not a valid index: must be between 0 and " + (cardinality - 1)); - indexValid = false; } else if (indices.get(index)) { errors.addError("Multiple components are using index " + index + ": " + components.stream().filter(cm -> index == cm.index).toList()); - indexValid = false; } else { // record index as known indices.set(index); @@ -78,35 +73,29 @@ public SensorMetadata(List components, String documentation) if (errors.hasErrors()) { throw new IllegalArgumentException(errors.formatErrors()); } - - this.totalComponents = totalIndices.stream().toArray(); } @JsonCreator - SensorMetadata(Map components, String documentation, int[] totalComponents) { + SensorMetadata(Map components, String documentation) { this.components = components; this.documentation = documentation; - this.totalComponents = totalComponents; } public static SensorMetadata.Builder withNewComponent(String name, String description, boolean isAttributed, - String unitSymbol, - boolean participatesInTotal) { - return new SensorMetadata.Builder().withNewComponent(name, description, isAttributed, unitSymbol, participatesInTotal); + String unitSymbol) { + return new SensorMetadata.Builder().withNewComponent(name, description, isAttributed, unitSymbol); } public static SensorMetadata.Builder withNewComponent(String name, String description, boolean isAttributed, - SensorUnit unit, - boolean participatesInTotal) { - return new SensorMetadata.Builder().withNewComponent(name, description, isAttributed, unit, participatesInTotal); + SensorUnit unit) { + return new SensorMetadata.Builder().withNewComponent(name, description, isAttributed, unit); } public static SensorMetadata.Builder from(SensorMetadata sensorMetadata) { final var builder = new Builder(); sensorMetadata.components.values().stream().sorted(Comparator.comparing(ComponentMetadata::index)) .forEach(component -> builder.withNewComponent(component.name, component.description, component.isAttributed, - component.unit, - component.isIncludedInTotal)); + component.unit)); return builder; } @@ -117,8 +106,7 @@ public String toString() { .forEach(cm -> sb.append("- ").append(cm).append("\n")); return "components:\n" + sb - + "documentation: " + documentation + "\n" - + "totalComponents: " + Arrays.toString(totalComponents); + + "documentation: " + documentation; } /** @@ -174,15 +162,6 @@ public String documentation() { return documentation; } - /** - * Retrieves the indices of the components that can be used to compute a total - * - * @return the indices of the components that can be used to compute a total - */ - public int[] totalComponents() { - return totalComponents; - } - /** * Retrieves the metadata associated with the specified component index if it exists. * @@ -203,16 +182,14 @@ public static class Builder { private int currentIndex = 0; private String documentation; - public Builder withNewComponent(String name, String description, boolean isAttributed, String unitSymbol, - boolean isIncludedInTotal) { + public Builder withNewComponent(String name, String description, boolean isAttributed, String unitSymbol) { components - .add(new ComponentMetadata(name, currentIndex++, description, isAttributed, unitSymbol, isIncludedInTotal)); + .add(new ComponentMetadata(name, currentIndex++, description, isAttributed, unitSymbol)); return this; } - public Builder withNewComponent(String name, String description, boolean isAttributed, SensorUnit unit, - boolean isIncludedInTotal) { - components.add(new ComponentMetadata(name, currentIndex++, description, isAttributed, unit, isIncludedInTotal)); + public Builder withNewComponent(String name, String description, boolean isAttributed, SensorUnit unit) { + components.add(new ComponentMetadata(name, currentIndex++, description, isAttributed, unit)); return this; } @@ -239,12 +216,8 @@ public SensorMetadata build() { * attributed share for each process needs to be performed. This is needed because some sensors only provide * system-wide measures instead of on a per-process basis. * @param unit a textual representation of the unit used for measures associated with this component (e.g. mW) - * @param isIncludedInTotal whether or not this component takes part in the computation to get a total power consumption - * metric for that sensor. Components that take part of the total computation must use a unit commensurable with - * {@link SensorUnit#W} */ - public record ComponentMetadata(String name, int index, String description, boolean isAttributed, SensorUnit unit, - boolean isIncludedInTotal) { + public record ComponentMetadata(String name, int index, String description, boolean isAttributed, SensorUnit unit) { public ComponentMetadata { if (name == null) { @@ -255,9 +228,8 @@ public record ComponentMetadata(String name, int index, String description, bool } } - public ComponentMetadata(String name, int index, String description, boolean isAttributed, String unitSymbol, - boolean isIncludedInTotal) { - this(name, index, description, isAttributed, SensorUnit.of(unitSymbol), isIncludedInTotal); + public ComponentMetadata(String name, int index, String description, boolean isAttributed, String unitSymbol) { + this(name, index, description, isAttributed, SensorUnit.of(unitSymbol)); } } } diff --git a/metadata/src/test/java/net/laprun/sustainability/power/SensorMetadataTest.java b/metadata/src/test/java/net/laprun/sustainability/power/SensorMetadataTest.java index 49b9528..306f972 100644 --- a/metadata/src/test/java/net/laprun/sustainability/power/SensorMetadataTest.java +++ b/metadata/src/test/java/net/laprun/sustainability/power/SensorMetadataTest.java @@ -13,7 +13,7 @@ void shouldFailIfTotalComponentsAreOutOfRange() { final var name = "comp0"; final var e = assertThrows(IllegalArgumentException.class, () -> new SensorMetadata( - List.of(new SensorMetadata.ComponentMetadata(name, -1, null, true, SensorUnit.W, true)), "")); + List.of(new SensorMetadata.ComponentMetadata(name, -1, null, true, SensorUnit.W)), "")); final var message = e.getMessage(); assertTrue(message.contains("range")); assertTrue(message.contains("-1")); @@ -23,7 +23,7 @@ void shouldFailIfTotalComponentsAreOutOfRange() { void shouldFailIfComponentHasNullName() { final var e = assertThrows(IllegalArgumentException.class, () -> new SensorMetadata( - List.of(new SensorMetadata.ComponentMetadata(null, -1, null, true, (SensorUnit) null, true)), "")); + List.of(new SensorMetadata.ComponentMetadata(null, -1, null, true, (SensorUnit) null)), "")); final var message = e.getMessage(); assertTrue(message.contains("Component name cannot be null")); } @@ -32,7 +32,7 @@ void shouldFailIfComponentHasNullName() { void shouldFailIfComponentHasNullUnit() { final var e = assertThrows(IllegalArgumentException.class, () -> new SensorMetadata( - List.of(new SensorMetadata.ComponentMetadata("invalid", -1, null, true, (SensorUnit) null, true)), "")); + List.of(new SensorMetadata.ComponentMetadata("invalid", -1, null, true, (SensorUnit) null)), "")); final var message = e.getMessage(); assertTrue(message.contains("Component unit cannot be null")); } @@ -42,8 +42,8 @@ void shouldFailOnDuplicatedComponentNames() { final var name = "component"; final var e = assertThrows(IllegalArgumentException.class, () -> new SensorMetadata(List.of( - new SensorMetadata.ComponentMetadata(name, 0, null, true, "mW", false), - new SensorMetadata.ComponentMetadata(name, 1, null, true, "mW", false)), "")); + new SensorMetadata.ComponentMetadata(name, 0, null, true, "mW"), + new SensorMetadata.ComponentMetadata(name, 1, null, true, "mW")), "")); final var message = e.getMessage(); assertTrue(message.contains(name) && message.contains("0") && message.contains("1")); } @@ -52,8 +52,8 @@ void shouldFailOnDuplicatedComponentNames() { void shouldFailIfComponentsDoNotCoverFullRange() { final var e = assertThrows(IllegalArgumentException.class, () -> new SensorMetadata(List.of( - new SensorMetadata.ComponentMetadata("foo", 0, null, true, "mW", false), - new SensorMetadata.ComponentMetadata("component2", 0, null, true, "mW", false)), "")); + new SensorMetadata.ComponentMetadata("foo", 0, null, true, "mW"), + new SensorMetadata.ComponentMetadata("component2", 0, null, true, "mW")), "")); final var message = e.getMessage(); assertTrue(message.contains("Multiple components are using index 0")); assertTrue(message.contains("foo")); @@ -64,8 +64,11 @@ void shouldFailIfComponentsDoNotCoverFullRange() { @Test void shouldFailIfNoComponentsAreProvided() { final var e = assertThrows(NullPointerException.class, - () -> new SensorMetadata(null, "")); - final var message = e.getMessage(); - assertTrue(message.contains("Must provide components")); + () -> new SensorMetadata((List) null, "")); + assertEquals("Must provide components", e.getMessage()); + + final var e2 = assertThrows(IllegalArgumentException.class, + () -> new SensorMetadata(List.of(), "")); + assertEquals("Must provide at least one component", e2.getMessage()); } } diff --git a/server/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java b/server/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java index ff8a224..fe2656f 100644 --- a/server/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java +++ b/server/src/main/java/net/laprun/sustainability/power/sensors/linux/rapl/IntelRAPLSensor.java @@ -66,10 +66,10 @@ private IntelRAPLSensor(SortedMap files) { final var metadata = new ArrayList(rawOffset * 2); int fileNb = 0; for (String name : files.keySet()) { - metadata.add(new SensorMetadata.ComponentMetadata(name, fileNb, name, false, mW, true)); + metadata.add(new SensorMetadata.ComponentMetadata(name, fileNb, name, false, mW)); final var rawName = name + "_uj"; metadata.add(new SensorMetadata.ComponentMetadata(rawName, fileNb + rawOffset, - name + " (raw micro Joule data)", false, µJ, false)); + name + " (raw micro Joule data)", false, µJ)); fileNb++; } this.metadata = new SensorMetadata(metadata, diff --git a/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/AppleSiliconCPU.java b/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/AppleSiliconCPU.java index a1a6804..b07f2f4 100644 --- a/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/AppleSiliconCPU.java +++ b/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/AppleSiliconCPU.java @@ -10,13 +10,13 @@ class AppleSiliconCPU extends CPU { private static final SensorMetadata.ComponentMetadata cpuComponent = new SensorMetadata.ComponentMetadata(CPU, 0, - "CPU power", true, mW, true); + "CPU power", true, mW); private static final SensorMetadata.ComponentMetadata gpuComponent = new SensorMetadata.ComponentMetadata(GPU, 1, - "GPU power", true, mW, true); + "GPU power", true, mW); private static final SensorMetadata.ComponentMetadata aneComponent = new SensorMetadata.ComponentMetadata(ANE, 2, - "Apple Neural Engine power", false, mW, true); + "Apple Neural Engine power", false, mW); private static final SensorMetadata.ComponentMetadata cpuShareComponent = new SensorMetadata.ComponentMetadata(CPU_SHARE, 3, - "Computed share of CPU", false, decimalPercentage, false); + "Computed share of CPU", false, decimalPercentage); private static final String COMBINED = "Combined"; private static final String POWER_INDICATOR = " Power: "; private static final int POWER_INDICATOR_LENGTH = POWER_INDICATOR.length(); @@ -44,7 +44,7 @@ private void addComponentTo(String name, List break; default: final var index = components.size(); - components.add(new SensorMetadata.ComponentMetadata(name, index, name, false, mW, true)); + components.add(new SensorMetadata.ComponentMetadata(name, index, name, false, mW)); } } diff --git a/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/IntelCPU.java b/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/IntelCPU.java index c59f38d..e17319b 100644 --- a/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/IntelCPU.java +++ b/server/src/main/java/net/laprun/sustainability/power/sensors/macos/powermetrics/IntelCPU.java @@ -12,9 +12,9 @@ class IntelCPU extends CPU { private static final SensorMetadata.ComponentMetadata packageComponent = new SensorMetadata.ComponentMetadata(PACKAGE, 0, - "Intel energy model derived package power (CPUs+GT+SA)", true, W, true); + "Intel energy model derived package power (CPUs+GT+SA)", true, W); private static final SensorMetadata.ComponentMetadata cpuShareComponent = new SensorMetadata.ComponentMetadata(CPU_SHARE, 1, - "Computed share of CPU", false, decimalPercentage, false); + "Computed share of CPU", false, decimalPercentage); @Override public boolean doneExtractingPowerComponents(String line, HashMap powerComponents) { diff --git a/server/src/main/java/net/laprun/sustainability/power/sensors/test/TestPowerSensor.java b/server/src/main/java/net/laprun/sustainability/power/sensors/test/TestPowerSensor.java index 8c654b5..8d7a191 100644 --- a/server/src/main/java/net/laprun/sustainability/power/sensors/test/TestPowerSensor.java +++ b/server/src/main/java/net/laprun/sustainability/power/sensors/test/TestPowerSensor.java @@ -14,7 +14,7 @@ public class TestPowerSensor extends AbstractPowerSensor { public static final String CPU = "cpu"; public static final SensorMetadata DEFAULT = new SensorMetadata( - List.of(new SensorMetadata.ComponentMetadata(CPU, 0, "CPU", true, mW, true)), + List.of(new SensorMetadata.ComponentMetadata(CPU, 0, "CPU", true, mW)), "Test PowerSensor returning random values for a single 'cpu' component"); private final SensorMetadata metadata; private boolean started;