Skip to content

Commit

Permalink
feat: add raw sensor values to Intel sensor, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
metacosm committed Mar 29, 2024
1 parent e99e729 commit 5d53474
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,57 @@ public class IntelRAPLSensor implements PowerSensor {
* Initializes the RAPL sensor
*/
public IntelRAPLSensor() {
this(defaultRAPLFiles());
}

protected IntelRAPLSensor(String... raplFilePaths) {
this(fromPaths(raplFilePaths));
}

private static SortedMap<String, RAPLFile> fromPaths(String... raplFilePaths) {
if (raplFilePaths == null || raplFilePaths.length == 0) {
throw new IllegalArgumentException("Must provide at least one RAPL file");
}

final var files = new TreeMap<String, RAPLFile>();
for (String raplFilePath : raplFilePaths) {
addFileIfReadable(raplFilePath, files);
}
return files;
}

private static SortedMap<String, RAPLFile> defaultRAPLFiles() {
// if we total system energy is not available, read package and DRAM if possible
// todo: check Intel doc
final var files = new TreeMap<String, RAPLFile>();
if (!addFileIfReadable("/sys/class/powercap/intel-rapl/intel-rapl:1/energy_uj", files)) {
addFileIfReadable("/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj", files);
addFileIfReadable("/sys/class/powercap/intel-rapl/intel-rapl:0/intel-rapl:0:2/energy_uj", files);
}
return files;
}

private IntelRAPLSensor(SortedMap<String, RAPLFile> files) {
if (files.isEmpty())
throw new RuntimeException("Failed to get RAPL energy readings, probably due to lack of read access ");

raplFiles = files.values().toArray(new RAPLFile[0]);
final var metadata = new HashMap<String, SensorMetadata.ComponentMetadata>(files.size());
final var rawOffset = files.size();
final var metadata = new HashMap<String, SensorMetadata.ComponentMetadata>(rawOffset * 2);
int fileNb = 0;
for (String name : files.keySet()) {
metadata.put(name, new SensorMetadata.ComponentMetadata(name, fileNb++, name, false, "µJ"));
metadata.put(name, new SensorMetadata.ComponentMetadata(name, fileNb, name, false, "mW"));
final var rawName = name + "_uj";
metadata.put(rawName, new SensorMetadata.ComponentMetadata(rawName, fileNb + rawOffset,
name + " (raw micro Joule data)", false, "µJ"));
fileNb++;
}
this.metadata = new SensorMetadata(metadata,
"Linux RAPL derived information, see https://www.kernel.org/doc/html/latest/power/powercap/powercap.html");
lastMeasuredSensorValues = new double[raplFiles.length];
}

private boolean addFileIfReadable(String raplFileAsString, SortedMap<String, RAPLFile> files) {
private static boolean addFileIfReadable(String raplFileAsString, SortedMap<String, RAPLFile> files) {
final var raplFile = Path.of(raplFileAsString);
if (isReadable(raplFile)) {
// get metric name
Expand Down Expand Up @@ -82,6 +110,7 @@ public void start(long frequency) {

/**
* Computes the power in mW based on the current, previous energy (in micro Joules) measures and sampling frequency.
*
* @param componentIndex the index of the component being measured
* @param sensorValue the micro Joules energy reading
* @return the power over the interval defined by the sampling frequency in mW
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import io.quarkus.test.junit.TestProfile;

@QuarkusTest
@TestProfile(CIQuarkusTestProfile.class)
@TestProfile(CIQuarkusTestProfile.class) // only activated when quarkus.test.profile.tags='ci', uses @Mock annotated beans
public class CIPowerResourceTest {

protected long getPid() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package net.laprun.sustainability.power.sensors.linux.rapl;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.File;
import java.util.Arrays;

import org.junit.jupiter.api.Test;

import net.laprun.sustainability.power.SensorMetadata;

public class IntelRAPLSensorTest {
@Test
void checkMetadata() {
var metadata = loadMetadata("rapl/intel-rapl_1/energy_uj", "rapl/intel-rapl_2/energy_uj");
assertEquals(4, metadata.componentCardinality());
checkComponent(metadata, "CPU", 0);
checkComponent(metadata, "GPU", 1);
checkComponent(metadata, "CPU_uj", 2);
checkComponent(metadata, "GPU_uj", 3);
}

private SensorMetadata loadMetadata(String... fileNames) {
final var files = Arrays.stream(fileNames)
.map(name -> new File(getClass().getClassLoader().getResource(name).getFile()).getAbsolutePath())
.toArray(String[]::new);
return new IntelRAPLSensor(files).metadata();
}

private static void checkComponent(SensorMetadata metadata, String name, int index) {
// check string instead of constants to ensure "API" compatibility as these keys will be published
final var component = metadata.metadataFor(name);
assertEquals(name, component.name());
assertEquals(index, component.index());
}
}
1 change: 1 addition & 0 deletions server/src/test/resources/rapl/intel-rapl_1/energy_uj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12345
1 change: 1 addition & 0 deletions server/src/test/resources/rapl/intel-rapl_1/name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CPU
1 change: 1 addition & 0 deletions server/src/test/resources/rapl/intel-rapl_2/energy_uj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
67890
1 change: 1 addition & 0 deletions server/src/test/resources/rapl/intel-rapl_2/name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GPU

0 comments on commit 5d53474

Please sign in to comment.