-
Notifications
You must be signed in to change notification settings - Fork 142
Expand file tree
/
Copy pathutils.ts
More file actions
155 lines (133 loc) · 4.33 KB
/
Copy pathutils.ts
File metadata and controls
155 lines (133 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Utility to extract params from either GET or POST
import { NextApiRequest } from "next";
/**
* Key-value map describing metadata for a group.
* Example: { dtype: "fp32", arch: "sm80", device: "cuda" }
*/
type GroupInfo = Record<string, string>;
/**
* Represents a subgroup within a larger group.
* Contains its own metadata and a list of data items.
*/
type Subgroup<T> = {
/** Metadata fields for this subgroup (e.g., workflow_id). */
group_info: GroupInfo;
/** The actual list of data items belonging to this subgroup. */
data: T[];
};
/**
* Represents a grouped item at the top level.
* Contains group-level metadata and a collection of subgroups.
*/
type GroupedItem<T> = {
/** Metadata fields for this group (e.g., dtype, arch, compiler). */
group_Info: GroupInfo;
/**
* Rows keyed by a unique identifier string,
* derived from a distinct combination of subgroup `group_Info` fields.
* Each entry corresponds to one subgroup that contains data points.
*/
rows: Record<string, Subgroup<T>>;
};
/**
* Generic parameters map passed into functions or queries.
* Example: { startTime: "2025-08-24", device: "cuda", arch: "h100" }
*/
type Params = Record<string, any>;
// it accepts both ?parameters=<json string> and POST with JSON body
export function readApiGetParams(req: NextApiRequest): Params {
// 1) If POST with parsed JSON body
if (req.method === "POST" && req.body && typeof req.body === "object") {
return req.body as Params;
}
// 2) If POST with raw string body
if (
req.method === "POST" &&
typeof req.body === "string" &&
req.body.trim()
) {
try {
return JSON.parse(req.body) as Params;
} catch {}
}
// 3) If GET with ?parameters=<json string>
const raw = req.query.parameters as string | undefined;
if (raw) {
try {
return JSON.parse(raw) as Params;
} catch {}
}
// 4) Fallback: use query params directly
const q: Params = {};
Object.entries(req.query).forEach(([k, v]) => {
if (k !== "parameters") q[k] = Array.isArray(v) ? v[0] : v;
});
return q;
}
/**
* Group benchmark data by `keys`, and inside each group further subgroup by `subGroupKeys`.
* @param data - benchmark data
* @param keys - keys to group by
* @param subGroupKeys - keys to subgroup by (optional): if not provided, a single subgroup will be created with "_ALL_" data
*/
export function groupByBenchmarkData<T>(
data: T[],
keys: string[],
subGroupKeys: string[] = []
): GroupedItem<T>[] {
const groups = new Map<string, Map<string, Subgroup<T>>>();
const mainInfo = new Map<string, GroupInfo>();
for (const row of data as any[]) {
// build main group key
const mainKeyParts = keys.map((k) => String(getNestedField(row, k)));
const mainKey = mainKeyParts.join("|");
if (!mainInfo.has(mainKey)) {
const info: GroupInfo = {};
keys.forEach((k, i) => (info[k] = mainKeyParts[i]));
mainInfo.set(mainKey, info);
}
// build subgroup key
const subKeyParts =
subGroupKeys.length > 0
? subGroupKeys.map((k) => String(getNestedField(row, k)))
: ["__ALL__"]; // default single subgroup if none provided
const subKey = subKeyParts.join("|");
const subInfo: GroupInfo = {};
subGroupKeys.forEach((k, i) => (subInfo[k] = subKeyParts[i]));
if (!groups.has(mainKey)) groups.set(mainKey, new Map());
const subMap = groups.get(mainKey)!;
if (!subMap.has(subKey)) {
subMap.set(subKey, { group_info: subInfo, data: [] });
}
subMap.get(subKey)!.data.push(row as T);
}
// build result array
const result: GroupedItem<T>[] = [];
for (const [mainKey, subMap] of groups.entries()) {
const rowsObj = Object.fromEntries(subMap.entries());
result.push({
group_Info: mainInfo.get(mainKey)!,
rows: rowsObj,
});
}
return result;
}
export function getNestedField(obj: any, path: string): any {
return path.split(".").reduce((o, key) => (o && key in o ? o[key] : ""), obj);
}
export type BenchmarkTimeSeriesResponse = {
time_series: any[];
time_range: { start: string; end: string };
};
export type CommitRow = {
head_branch: string;
head_sha: string;
id: string;
};
export function toCommitRowMap(rows: CommitRow[]): Record<string, CommitRow> {
const result: Record<string, CommitRow> = {};
for (const row of rows) {
result[row.id] = row;
}
return result;
}