Skip to content

Commit

Permalink
Teads CPU Model
Browse files Browse the repository at this point in the history
Fixes #101

Signed-off-by: Gnanakeethan Balasubramaniam <[email protected]>
  • Loading branch information
gnanakeethan committed Aug 30, 2023
1 parent 0fe293f commit 3d0f6a7
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 1 deletion.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"email": "[email protected]"
},
"bundledDependencies": [
"typescript-cubic-spline",
"node-fetch",
"axios",
"typescript",
Expand All @@ -20,7 +21,8 @@
"axios": "^1.4.0",
"node-fetch": "^3.3.1",
"ts-sync-request": "^1.4.1",
"typescript": "^5.1.6"
"typescript": "^5.1.6",
"typescript-cubic-spline": "^1.0.1"
},
"devDependencies": {
"@babel/core": "7.22.10",
Expand Down
73 changes: 73 additions & 0 deletions src/lib/teads-cpu/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {describe, expect, jest, test} from '@jest/globals';
import {TeadsCPUModel} from './index';

jest.setTimeout(30000);

describe('teads:configure test', () => {
test('initialize with params', async () => {
const impactModel = new TeadsCPUModel();
await impactModel.configure('test', {
tdp: 200,
});
await expect(
impactModel.calculate([
{
duration: 3600,
cpu: 0.5,
datetime: '2021-01-01T00:00:00Z'

Check failure on line 17 in src/lib/teads-cpu/index.test.ts

View workflow job for this annotation

GitHub Actions / build

Insert `,`
},
])
).resolves.toStrictEqual([
{
energy: 0.15,
duration: 3600,
cpu: 0.5,
datetime: '2021-01-01T00:00:00Z',
},
]);
});
test('teads:initialize with params', async () => {
const impactModel = new TeadsCPUModel();
await impactModel.configure('test', {
tdp: 300,
});
await expect(
impactModel.calculate([
{
duration: 3600,
cpu: 0.1,
datetime: '2021-01-01T00:00:00Z',
},
{
duration: 3600,
cpu: 0.5,
datetime: '2021-01-01T00:00:00Z',
},
{
duration: 3600,
cpu: 1,
datetime: '2021-01-01T00:00:00Z',
},
])
).resolves.toStrictEqual([
{
duration: 3600,
cpu: 0.1,
datetime: '2021-01-01T00:00:00Z',
energy: 0.096,
},
{
duration: 3600,
cpu: 0.5,
datetime: '2021-01-01T00:00:00Z',
energy: 0.225,
},
{
duration: 3600,
cpu: 1,
datetime: '2021-01-01T00:00:00Z',
energy: 0.306,
},
]);
});
});
134 changes: 134 additions & 0 deletions src/lib/teads-cpu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {IImpactModelInterface} from '../interfaces';
import Spline from 'typescript-cubic-spline';
import {KeyValuePair} from '../../types/boavizta';

export class TeadsCPUModel implements IImpactModelInterface {
// Defined for compatibility. Not used in TEADS.
authParams: object | undefined;
// name of the data source
name: string | undefined;
// tdp of the chip being measured
tdp: number = 100;

Check failure on line 11 in src/lib/teads-cpu/index.ts

View workflow job for this annotation

GitHub Actions / build

Type number trivially inferred from a number literal, remove type annotation
// default power curve provided by the Teads Team
curve: number[] = [0.12, 0.32, 0.75, 1.02];
// default percentage points
points: number[] = [0, 10, 50, 100];
// spline interpolation of the power curve
spline: Spline = new Spline(this.points, this.curve);

/**
* Defined for compatibility. Not used in TEADS.
*/
authenticate(authParams: object): void {
this.authParams = authParams;
}

/**
* Configures the TEADS Plugin for IEF
* @param {string} name name of the resource
* @param {Object} staticParams static parameters for the resource
* @param {number} staticParams.tdp Thermal Design Power in Watts
*/
async configure(
name: string,
staticParams: object | undefined = undefined
): Promise<IImpactModelInterface> {
this.name = name;

if (staticParams === undefined) {
throw new Error('Required Parameters not provided');
}

if ('tdp' in staticParams) {
this.tdp = staticParams?.tdp as number;
} else {
throw new Error('`tdp` Thermal Design Power not provided. Can not compute energy.');

Check failure on line 45 in src/lib/teads-cpu/index.ts

View workflow job for this annotation

GitHub Actions / build

Replace `'`tdp`·Thermal·Design·Power·not·provided.·Can·not·compute·energy.'` with `⏎········'`tdp`·Thermal·Design·Power·not·provided.·Can·not·compute·energy.'⏎······`
}

if ('curve' in staticParams) {
this.curve = staticParams?.curve as number[];
this.spline = new Spline(this.points, this.curve);
}

Check failure on line 51 in src/lib/teads-cpu/index.ts

View workflow job for this annotation

GitHub Actions / build

Delete `⏎`


return this;
}

/**
* Calculate the total emissions for a list of observations
*
* Each Observation require:
* @param {Object[]} observations ISO 8601 datetime string
* @param {string} observations[].datetime ISO 8601 datetime string
* @param {number} observations[].duration observation duration in seconds
* @param {number} observations[].cpu percentage cpu usage
*/
async calculate(
observations: object | object[] | undefined
): Promise<object> {
if (observations === undefined) {
throw new Error('Required Parameters not provided');
}

const results: KeyValuePair[] = [];
if (Array.isArray(observations)) {
observations.forEach((observation: KeyValuePair) => {
const e = this.calculateEnergy(observation);
results.push({
energy: e,

Check failure on line 78 in src/lib/teads-cpu/index.ts

View workflow job for this annotation

GitHub Actions / build

Delete `·············`
...observation

Check failure on line 79 in src/lib/teads-cpu/index.ts

View workflow job for this annotation

GitHub Actions / build

Replace `·······················...observation` with `··········...observation,`
});

Check failure on line 80 in src/lib/teads-cpu/index.ts

View workflow job for this annotation

GitHub Actions / build

Delete `·············`
});
}

return results;
}

Check failure on line 85 in src/lib/teads-cpu/index.ts

View workflow job for this annotation

GitHub Actions / build

Delete `⏎`


/**
* Calculates the energy consumption for a single observation
* requires
*
* duration: duration of the observation in seconds
* cpu: cpu usage in percentage
* datetime: ISO 8601 datetime string
*
* Uses a spline method on the teads cpu wattage data
*/
private calculateEnergy(observation: KeyValuePair) {
if (
!('duration' in observation) ||
!('cpu' in observation) ||
!('datetime' in observation)
) {
throw new Error(
'Required Parameters duration,cpu,datetime not provided for observation'
);
}

// duration is in seconds
const duration = observation['duration'];

// convert cpu usage to percentage
const cpu = observation['cpu'] * 100.0;

const wattage = this.spline.at(cpu) * this.tdp;
// duration is in seconds
// wattage is in watts
// eg: 30W x 300s = 9000 J
// 1 Wh = 3600 J
// 9000 J / 3600 = 2.5 Wh
// J / 3600 = Wh
// 2.5 Wh / 1000 = 0.0025 kWh
// Wh / 1000 = kWh
// (wattage * duration) / (seconds in an hour) / 1000 = kWh
return (wattage * duration) / 3600 / 1000;
}

/**
* Returns model identifier
*/
modelIdentifier(): string {
return 'teads.cpu';
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5035,6 +5035,11 @@ types-ramda@^0.29.4:
dependencies:
ts-toolbelt "^9.6.0"

typescript-cubic-spline@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/typescript-cubic-spline/-/typescript-cubic-spline-1.0.1.tgz#340ef0f4f068fa28be0a0c3b4484e11f55b40610"
integrity sha512-h1dvp2YK66CU/p1thrBjQ61/CBSmkZw4Uh28ay8v9UjAA0gQdCQ+Etkie9sdj74WjYuYHEom5qLHjrci1IVMPA==

typescript@^5.1.6, typescript@~5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274"
Expand Down

0 comments on commit 3d0f6a7

Please sign in to comment.