@parca/profile 0.19.79 → 0.19.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.19.81](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.80...@parca/profile@0.19.81) (2025-11-24)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
10
+ ## [0.19.80](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.79...@parca/profile@0.19.80) (2025-11-20)
11
+
12
+ **Note:** Version bump only for package @parca/profile
13
+
6
14
  ## [0.19.79](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.78...@parca/profile@0.19.79) (2025-11-19)
7
15
 
8
16
  **Note:** Version bump only for package @parca/profile
@@ -170,6 +170,6 @@ const AreaChart = ({ transmitData, receiveData, addLabelMatcher, setTimeRange, u
170
170
  const contextMenuItems = useMemo(() => {
171
171
  return createThroughputContextMenuItems(addLabelMatcher, transmitData, receiveData);
172
172
  }, [addLabelMatcher, transmitData, receiveData]);
173
- return (_jsx(AnimatePresence, { children: _jsx(motion.div, { className: "w-full relative", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: utilizationMetricsLoading === true ? (_jsx(MetricsGraphSkeleton, { heightStyle: heightStyle, isDarkMode: isDarkMode, isMini: true })) : (_jsx(RawAreaChart, { transmitData: transmitData, receiveData: receiveData, transformedData: transformedData, addLabelMatcher: addLabelMatcher, setTimeRange: setTimeRange, width: width, height: height, margin: margin, name: name, humanReadableName: humanReadableName, from: from, to: to, selectedSeries: selectedSeries, onSeriesClick: onSeriesClick, contextMenuItems: contextMenuItems })) }, "area-chart-graph-loaded") }));
173
+ return (_jsx(AnimatePresence, { children: _jsx(motion.div, { className: "w-full relative", initial: false, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: utilizationMetricsLoading === true ? (_jsx(MetricsGraphSkeleton, { heightStyle: heightStyle, isDarkMode: isDarkMode, isMini: true })) : (_jsx(RawAreaChart, { transmitData: transmitData, receiveData: receiveData, transformedData: transformedData, addLabelMatcher: addLabelMatcher, setTimeRange: setTimeRange, width: width, height: height, margin: margin, name: name, humanReadableName: humanReadableName, from: from, to: to, selectedSeries: selectedSeries, onSeriesClick: onSeriesClick, contextMenuItems: contextMenuItems })) }, "area-chart-graph-loaded") }));
174
174
  };
175
175
  export default AreaChart;
@@ -181,6 +181,6 @@ const UtilizationMetrics = ({ data, setTimeRange, utilizationMetricsLoading, hum
181
181
  const contextMenuItems = useMemo(() => {
182
182
  return addLabelMatcher != null ? createUtilizationContextMenuItems(addLabelMatcher, data) : [];
183
183
  }, [addLabelMatcher, data]);
184
- return (_jsx(AnimatePresence, { children: _jsx(motion.div, { className: "w-full relative", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: utilizationMetricsLoading === true ? (_jsx(MetricsGraphSkeleton, { heightStyle: heightStyle, isDarkMode: isDarkMode, isMini: true })) : (_jsx(RawUtilizationMetrics, { data: transformedData, originalData: data, setTimeRange: setTimeRange, width: width, height: height, margin: margin, humanReadableName: humanReadableName, from: from, to: to, yAxisUnit: yAxisUnit, contextMenuItems: contextMenuItems, onSeriesClick: onSeriesClick })) }, "utilization-metrics-graph-loaded") }));
184
+ return (_jsx(AnimatePresence, { children: _jsx(motion.div, { className: "w-full relative", initial: false, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: utilizationMetricsLoading === true ? (_jsx(MetricsGraphSkeleton, { heightStyle: heightStyle, isDarkMode: isDarkMode, isMini: true })) : (_jsx(RawUtilizationMetrics, { data: transformedData, originalData: data, setTimeRange: setTimeRange, width: width, height: height, margin: margin, humanReadableName: humanReadableName, from: from, to: to, yAxisUnit: yAxisUnit, contextMenuItems: contextMenuItems, onSeriesClick: onSeriesClick })) }, "utilization-metrics-graph-loaded") }));
185
185
  };
186
186
  export default UtilizationMetrics;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileMetricsGraph/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EACL,KAAK,EAGL,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EAId,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAqH5D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,eAAO,MAAM,wBAAwB,GAAI,aAAW,6BAA6B,KAAG,GAAG,CAAC,OAMvF,CAAC;AAEF,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,CACf,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KACvE,IAAI,CAAC;IACV,YAAY,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,KAAK,EAAE,EACf,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,KACb,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,QAAA,MAAM,mBAAmB,GAAI,qHAW1B,wBAAwB,KAAG,GAAG,CAAC,OA+YjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileMetricsGraph/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EACL,KAAK,EAGL,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EAId,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAqH5D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,eAAO,MAAM,wBAAwB,GAAI,aAAW,6BAA6B,KAAG,GAAG,CAAC,OAMvF,CAAC;AAEF,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,CACf,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KACvE,IAAI,CAAC;IACV,YAAY,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,KAAK,EAAE,EACf,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,KACb,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,QAAA,MAAM,mBAAmB,GAAI,qHAW1B,wBAAwB,KAAG,GAAG,CAAC,OA+ZjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -142,11 +142,25 @@ const ProfileMetricsGraph = ({ queryClient, queryExpression, profile, from, to,
142
142
  if (response?.series != null) {
143
143
  // Check if user wants ALL series for THIS specific response
144
144
  const userWantsAllForThisResponse = showAllSeriesForResponse === response;
145
- // Limit the number of series to 100 to avoid performance issues (unless user opts to show all)
146
- if (response.series.length > 100 && !userWantsAllForThisResponse) {
145
+ const maxSeriesLimit = 100;
146
+ // Limit the number of series to maxSeriesLimit to avoid performance issues (unless user opts to show all)
147
+ if (response.series.length > maxSeriesLimit && !userWantsAllForThisResponse) {
148
+ // Select top `maxSeriesLimit` series based on their max value (to catch series with large spikes)
149
+ const seriesWithMaxValue = response.series.map(series => {
150
+ const maxValue = series.samples.reduce((max, sample) => {
151
+ const value = sample.valuePerSecond ?? 0;
152
+ return value > max ? value : max;
153
+ }, 0);
154
+ return { series, maxValue };
155
+ });
156
+ // Sort by max value descending and take top `maxSeriesLimit` series
157
+ const topSeries = seriesWithMaxValue
158
+ .sort((a, b) => b.maxValue - a.maxValue)
159
+ .slice(0, maxSeriesLimit)
160
+ .map(item => item.series);
147
161
  return [
148
- response.series.slice(0, 100),
149
- { isTrimmed: true, beforeTrim: response.series.length, afterTrim: 100 },
162
+ topSeries,
163
+ { isTrimmed: true, beforeTrim: response.series.length, afterTrim: maxSeriesLimit },
150
164
  ];
151
165
  }
152
166
  return [response.series, { isTrimmed: false, beforeTrim: 0, afterTrim: 0 }];
@@ -103,7 +103,7 @@ export function MetricsGraphSection({ showMetricsGraph, setDisplayHideMetricsGra
103
103
  } }, name));
104
104
  }
105
105
  return null;
106
- }), throughputMetrics.length > 0 && (_jsx(AreaChart, { transmitData: transmitData, receiveData: receiveData, addLabelMatcher: addLabelMatcher, setTimeRange: handleTimeRangeChange, name: throughputMetrics[0].name, humanReadableName: throughputMetrics[0].humanReadableName, from: querySelection.from, to: querySelection.to, utilizationMetricsLoading: utilizationMetricsLoading, selectedSeries: undefined, onSeriesClick: (name, seriesIndex) => {
106
+ }), throughputMetrics.length > 0 && (_jsx(AreaChart, { transmitData: transmitData, receiveData: receiveData, addLabelMatcher: addLabelMatcher, setTimeRange: handleTimeRangeChange, name: throughputMetrics[0].name, humanReadableName: throughputMetrics[0].humanReadableName, from: querySelection.from, to: querySelection.to, utilizationMetricsLoading: utilizationMetricsLoading, selectedSeries: undefined, onSeriesClick: (_, seriesIndex) => {
107
107
  // For throughput metrics, just pass the series index
108
108
  if (onUtilizationSeriesSelect != null) {
109
109
  let name = 'gpu_pcie_throughput_transmit_bytes';
@@ -1 +1 @@
1
- {"version":3,"file":"filterPresets.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/filterPresets.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,eAAO,MAAM,aAAa,EAAE,YAAY,EA6IvC,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,OAEzC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAE3D,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,cAAc,MAAM,KAAG,YAAY,EAO3E,CAAC"}
1
+ {"version":3,"file":"filterPresets.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/filterPresets.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,eAAO,MAAM,aAAa,EAAE,YAAY,EAyJvC,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,OAEzC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAE3D,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,cAAc,MAAM,KAAG,YAAY,EAO3E,CAAC"}
@@ -97,19 +97,31 @@ export const filterPresets = [
97
97
  type: 'frame',
98
98
  field: 'binary',
99
99
  matchType: 'not_contains',
100
- value: 'libparcgpcupti.so',
100
+ value: 'libcudart.so',
101
101
  },
102
102
  {
103
103
  type: 'frame',
104
104
  field: 'binary',
105
105
  matchType: 'not_contains',
106
- value: 'libcudart.so',
106
+ value: 'libcuda.so',
107
107
  },
108
108
  {
109
109
  type: 'frame',
110
110
  field: 'binary',
111
111
  matchType: 'not_contains',
112
- value: 'libcuda.so',
112
+ value: 'libcudnn.so',
113
+ },
114
+ {
115
+ type: 'frame',
116
+ field: 'binary',
117
+ matchType: 'not_contains',
118
+ value: 'libcudnn_graph.so',
119
+ },
120
+ {
121
+ type: 'frame',
122
+ field: 'binary',
123
+ matchType: 'not_contains',
124
+ value: 'libparcagpucupti.so',
113
125
  },
114
126
  ],
115
127
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.19.79",
3
+ "version": "0.19.81",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@floating-ui/react": "^0.27.12",
@@ -79,5 +79,5 @@
79
79
  "access": "public",
80
80
  "registry": "https://registry.npmjs.org/"
81
81
  },
82
- "gitHead": "a16568e3b3edb645958372f4e0e4d76fa4fc5408"
82
+ "gitHead": "13b76b4d7b3667414d84855eb7ba55cab034a3e1"
83
83
  }
@@ -372,7 +372,7 @@ const AreaChart = ({
372
372
  <motion.div
373
373
  className="w-full relative"
374
374
  key="area-chart-graph-loaded"
375
- initial={{display: 'none', opacity: 0}}
375
+ initial={false}
376
376
  animate={{display: 'block', opacity: 1}}
377
377
  transition={{duration: 0.5}}
378
378
  >
@@ -396,7 +396,7 @@ const UtilizationMetrics = ({
396
396
  <motion.div
397
397
  className="w-full relative"
398
398
  key="utilization-metrics-graph-loaded"
399
- initial={{display: 'none', opacity: 0}}
399
+ initial={false}
400
400
  animate={{display: 'block', opacity: 1}}
401
401
  transition={{duration: 0.5}}
402
402
  >
@@ -239,12 +239,28 @@ const ProfileMetricsGraph = ({
239
239
  if (response?.series != null) {
240
240
  // Check if user wants ALL series for THIS specific response
241
241
  const userWantsAllForThisResponse = showAllSeriesForResponse === response;
242
+ const maxSeriesLimit = 100;
243
+
244
+ // Limit the number of series to maxSeriesLimit to avoid performance issues (unless user opts to show all)
245
+ if (response.series.length > maxSeriesLimit && !userWantsAllForThisResponse) {
246
+ // Select top `maxSeriesLimit` series based on their max value (to catch series with large spikes)
247
+ const seriesWithMaxValue = response.series.map(series => {
248
+ const maxValue = series.samples.reduce((max, sample) => {
249
+ const value = sample.valuePerSecond ?? 0;
250
+ return value > max ? value : max;
251
+ }, 0);
252
+ return {series, maxValue};
253
+ });
254
+
255
+ // Sort by max value descending and take top `maxSeriesLimit` series
256
+ const topSeries = seriesWithMaxValue
257
+ .sort((a, b) => b.maxValue - a.maxValue)
258
+ .slice(0, maxSeriesLimit)
259
+ .map(item => item.series);
242
260
 
243
- // Limit the number of series to 100 to avoid performance issues (unless user opts to show all)
244
- if (response.series.length > 100 && !userWantsAllForThisResponse) {
245
261
  return [
246
- response.series.slice(0, 100),
247
- {isTrimmed: true, beforeTrim: response.series.length, afterTrim: 100},
262
+ topSeries,
263
+ {isTrimmed: true, beforeTrim: response.series.length, afterTrim: maxSeriesLimit},
248
264
  ];
249
265
  }
250
266
  return [response.series, {isTrimmed: false, beforeTrim: 0, afterTrim: 0}];
@@ -213,7 +213,7 @@ export function MetricsGraphSection({
213
213
  to={querySelection.to}
214
214
  utilizationMetricsLoading={utilizationMetricsLoading}
215
215
  selectedSeries={undefined}
216
- onSeriesClick={(name, seriesIndex) => {
216
+ onSeriesClick={(_, seriesIndex) => {
217
217
  // For throughput metrics, just pass the series index
218
218
  if (onUtilizationSeriesSelect != null) {
219
219
  let name = 'gpu_pcie_throughput_transmit_bytes';
@@ -108,19 +108,31 @@ export const filterPresets: FilterPreset[] = [
108
108
  type: 'frame',
109
109
  field: 'binary',
110
110
  matchType: 'not_contains',
111
- value: 'libparcgpcupti.so',
111
+ value: 'libcudart.so',
112
112
  },
113
113
  {
114
114
  type: 'frame',
115
115
  field: 'binary',
116
116
  matchType: 'not_contains',
117
- value: 'libcudart.so',
117
+ value: 'libcuda.so',
118
118
  },
119
119
  {
120
120
  type: 'frame',
121
121
  field: 'binary',
122
122
  matchType: 'not_contains',
123
- value: 'libcuda.so',
123
+ value: 'libcudnn.so',
124
+ },
125
+ {
126
+ type: 'frame',
127
+ field: 'binary',
128
+ matchType: 'not_contains',
129
+ value: 'libcudnn_graph.so',
130
+ },
131
+ {
132
+ type: 'frame',
133
+ field: 'binary',
134
+ matchType: 'not_contains',
135
+ value: 'libparcagpucupti.so',
124
136
  },
125
137
  ],
126
138
  },