Skip to content

Commit ffe8c38

Browse files
authored
Merge pull request #15 from nadnein/Nadja
finalized TDP table for plugin
2 parents 65ab150 + 362a8b5 commit ffe8c38

19 files changed

Lines changed: 11861 additions & 7822 deletions

app/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ repositories {
2020
mavenCentral()
2121
}
2222

23+
sourceSets {
24+
main.resources.srcDir('src/resources')
25+
}
26+
2327
dependencies {
2428
// Use the latest Groovy version for building this library
2529
implementation libs.groovy.all

app/src/main/groovy/org/cpuInfoFetcher/AmpereSpecificationsFetcher.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ class AmpereSpecificationsFetcher extends SpecificationsFetcher {
8181
)
8282

8383
// Load local specifications file as it is only available as .png on the website
84-
DataFrame spec_file = Csv.load(Paths.get('..', 'input_data', 'Ampere_One_Family_Specifications_2025-03-20.csv'))
84+
DataFrame spec_file = Csv.load(
85+
Paths.get(this.class.getResource('/Ampere_One_Family_Specifications_2025-03-20.csv').toURI())
86+
)
8587
specifications = manually_add_processor_specifications(specifications, spec_file)
8688

8789
return specifications

app/src/main/groovy/org/cpuInfoFetcher/Main.groovy

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
package org.cpuinfofetcher
22

3+
import org.cpuinfofetcher.utils.Helpers
34
import org.cpuinfofetcher.utils.UnitsAdapter
5+
import org.dflib.Exp
6+
import org.dflib.Series
7+
import org.dflib.Printers
8+
9+
import static org.dflib.Exp.*
10+
import java.time.LocalDateTime
11+
412

513
import java.nio.file.Files
614
import java.util.logging.Logger
@@ -81,10 +89,13 @@ class Main {
8189
return specifications.rows().selectUnique('name')
8290
}
8391

92+
93+
8494
static void main(String[] args) {
8595
this.days_until_outdated = args.length > 0 ? Integer.parseInt(args[0]) : 28
8696

8797
Files.createDirectories(Paths.get('..', 'specifications_out'))
98+
Files.createDirectories(Paths.get('..', 'nf-co2footprint'))
8899

89100
// Collecting Info
90101
LOGGER.entering('Main', 'main')
@@ -111,11 +122,21 @@ class Main {
111122
selected_specifications = ua.unitToColumnName(selected_specifications, this.units_mapping)
112123
LOGGER.info('Extracted units from data.')
113124

125+
// adjusts format of tdp values to make them uniform
126+
selected_specifications = ua.extractFirstNumber(selected_specifications)
127+
128+
// add default TDPs
129+
selected_specifications = ProcessSpecificationsTable.computeDefaultTdps(selected_specifications)
130+
LOGGER.info('Added default TDP values.')
131+
114132
Csv.save(selected_specifications, Paths.get('..', 'specifications_out', 'specifications_filtered.csv'))
133+
Csv.save(selected_specifications, Paths.get('..', 'nf-co2footprint', 'CPU_TDP.csv'))
134+
115135
this.selected_specifications = selected_specifications
116136
LOGGER.info('Saved final results.')
117137

118138

139+
119140
LOGGER.exiting('Main', 'main')
120141
}
121142

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.cpuinfofetcher
2+
import org.cpuinfofetcher.utils.Helpers
3+
import org.dflib.DataFrame
4+
import java.time.LocalDateTime
5+
import static org.dflib.Exp.$col
6+
7+
/**
8+
* Adds default TDP values to the specifications DataFrame.
9+
*
10+
* Groups by 'intended_usage', computes averages for cores, threads,
11+
* and TDP, adds a row for "unknown" usage, and updates the DataFrame with default entries.
12+
*
13+
* @param specifications the input DataFrame
14+
* @return the updated DataFrame with default TDP values
15+
*/
16+
static DataFrame computeDefaultTdps(DataFrame specifications) {
17+
DataFrame aggregatedDf = specifications.group('intended_usage').agg(
18+
$col('intended_usage').first().as('intended_usage'),
19+
$col('cores').castAsInt().avg().as("avg_cores"),
20+
$col('threads').castAsInt().avg().as("avg_threads"),
21+
$col('tdp (W)').castAsDouble().avg().as("avg_tdp"))
22+
23+
DataFrame local_server_rows = aggregatedDf.rows({ it.get('intended_usage') == 'local' || it.get('intended_usage') == 'server' })
24+
.select()
25+
26+
Double unknown_avg_cores = (local_server_rows.sum { it.get('avg_cores') } as Double) / local_server_rows.height()
27+
Double unknown_avg_threads = (local_server_rows.sum { it.get('avg_threads') } as Double) / local_server_rows.height()
28+
Double unknown_avg_tdp = (local_server_rows.sum { it.get('avg_tdp') } as Double) / local_server_rows.height()
29+
30+
aggregatedDf = aggregatedDf.addRow([
31+
"intended_usage": "unknown",
32+
"avg_cores": unknown_avg_cores,
33+
"avg_threads": unknown_avg_threads,
34+
"avg_tdp": unknown_avg_tdp
35+
36+
])
37+
38+
for (int i = 0; i < aggregatedDf.height(); i++) {
39+
DataFrame row = aggregatedDf.rows(i).select()
40+
Double avgThreads = row.get("avg_threads", 0) as Double
41+
Double avgCores = row.get("avg_cores", 0) as Double
42+
Double avgtdp = row.get("avg_tdp", 0) as Double
43+
Double computedThreads = avgCores != 0 ? avgThreads / avgCores : 0
44+
String intended_usage = row.get("intended_usage", 0)
45+
specifications = specifications.addRow([
46+
'product_id': "default $intended_usage",
47+
'name': "default $intended_usage",
48+
"time": LocalDateTime.now().toString(),
49+
'source': "default $intended_usage",
50+
"intended_usage": "default $intended_usage",
51+
'tdp (W)': Helpers.round(avgtdp),
52+
"cores": 1,
53+
"threads": Helpers.round(computedThreads)
54+
])
55+
}
56+
57+
return specifications
58+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.cpuinfofetcher.utils
2+
3+
import org.dflib.DataFrame
4+
5+
static boolean assertEqualDF(DataFrame df1, DataFrame df2) {
6+
assert df1.size() == df2.size()
7+
assert df1.getColumnsIndex().toArray() == df2.getColumnsIndex().toArray()
8+
for (int i = 0; i < df1.width(); i++) {
9+
for (int j = 0; j < df1.height(); j++) {
10+
assert df1.get(i, j) == df2.get(i, j)
11+
}
12+
}
13+
return true
14+
}
15+
16+
/**
17+
* Rounds a Double value to two decimal places.
18+
*
19+
* @param value the Double to round
20+
* @return the value rounded to two decimal places
21+
*/
22+
static Double round(Double value) {
23+
Double rounded_value = Math.round(value * 100.0) / 100.0
24+
return rounded_value
25+
}
26+

app/src/main/groovy/org/cpuInfoFetcher/utils/UnitsAdapter.groovy

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import org.dflib.DataFrame
77
*/
88
class UnitsAdapter {
99

10-
DataFrame unitToColumnName(DataFrame df, Map<String, String[]> unit_mapping) {
10+
static DataFrame unitToColumnName(DataFrame df, Map<String, String[]> unit_mapping) {
1111
List<String> old_col_names = df.getColumnsIndex().toArray()
1212
// Define new column names with units
1313
List<String> new_col_names = []
@@ -42,4 +42,32 @@ class UnitsAdapter {
4242
return new_df
4343
}
4444

45+
/**
46+
* Extracts the first numeric value from the 'tdp (W)' column and updates the DataFrame.
47+
*
48+
* Examples of extraction:
49+
* - "15-30" --> 15
50+
* - "1.5/20" --> 1.5
51+
* - "3.1--6" --> 3.1
52+
*
53+
* @param df the input DataFrame
54+
* @return a DataFrame with the updated 'tdp (W)' column containing only the first numeric value
55+
*/
56+
static DataFrame extractFirstNumber(DataFrame df) {
57+
DataFrame old_df = df.cols().selectAs(Map.of("tdp (W)", "tdp old"))
58+
def new_df = DataFrame.empty("tdp (W)")
59+
60+
for (int i = 0; i < old_df.height(); i++) {
61+
String tdp_value = old_df.rows(i).select().get("tdp old", 0)
62+
// Use the matcher to extract the first number
63+
def matcher = tdp_value =~ /^[0-9]*\.?[0-9]+/ // Regex to match the first number (integer or decimal)
64+
def new_tdp_value = matcher.find() ? Double.parseDouble(matcher.group(0)) : null
65+
new_df = new_df.addRow("tdp (W)": new_tdp_value)
66+
67+
}
68+
new_df = old_df.hConcat(new_df).colsExcept('tdp old').select()
69+
70+
return new_df
71+
}
72+
4573
}

input_data/Ampere_One_Family_Specifications_2025-03-20.csv renamed to app/src/resources/Ampere_One_Family_Specifications_2025-03-20.csv

File renamed without changes.

app/src/test/groovy/org/cpuInfoFetcher/AMDSpecificationsFetcherTest.groovy renamed to app/src/test/groovy/org/cpuinfofetcher/AMDSpecificationsFetcherTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class AMDSpecificationsFetcherTest extends Specification {
5858
DataFrame specifications = Csv.load(this.tempPath.resolve('AMD_processor_specifications.csv'))
5959

6060
then:
61-
specifications.getColumnsIndex().toArray() == [
61+
specifications.getColumnsIndex().toList() == [
6262
'time', 'source', 'intended_usage', 'name', 'Family', 'Series', 'Form Factor', '# of CPU Cores', '# of Threads',
6363
'Max. Boost Clock', 'Base Clock', 'L2 Cache', 'L3 Cache', 'Default TDP', 'L1 Cache',
6464
'AMD Configurable TDP (cTDP)', 'Processor Technology for CPU Cores', 'Unlocked for Overclocking',

app/src/test/groovy/org/cpuInfoFetcher/AmpereSpecificationsFetcherTest.groovy renamed to app/src/test/groovy/org/cpuinfofetcher/AmpereSpecificationsFetcherTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class AmpereSpecificationsFetcherTest extends Specification {
5252
DataFrame specifications = Csv.load(this.tempPath.resolve('Ampere_cpu_specifications.csv'))
5353

5454
then:
55-
specifications.getColumnsIndex().toArray() == [
55+
specifications.getColumnsIndex().toList() == [
5656
'time', 'source' , 'intended_usage', 'name', 'CORES', 'SUSTAINED FREQUENCY (GHz)', 'USAGE POWER (W)', 'product_id'
5757
]
5858
}

app/src/test/groovy/org/cpuInfoFetcher/CPUSpecificationsSummarizerTest.groovy renamed to app/src/test/groovy/org/cpuinfofetcher/CPUSpecificationsSummarizerTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class CPUSpecificationsSummarizerTest extends Specification {
1818
private final CPUSpecificationsSummarizer summarizer = new CPUSpecificationsSummarizer()
1919

2020
private final DataFrame exampleDF = DataFrame.foldByRow('A', 'B').of('1', '2')
21-
private final Map<String, String[]> aliases = ['A': ['A'], 'C': ['X', 'B'], 'B': ['C']]
21+
private final Map<String, String[]> aliases = ['A': ['A'], 'C': ['X', 'B'], 'B': ['C']] as Map<String, String[]>
2222

2323
boolean assertEqualDF(DataFrame df1, DataFrame df2) {
2424
assert df1.size() == df2.size()

0 commit comments

Comments
 (0)