nsight-python 1.1.0__py3-none-any.whl → 1.1.1__py3-none-any.whl

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.
nsight/annotation.py CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  import functools
5
5
  import threading
6
+ import warnings
6
7
  from collections.abc import Callable
7
8
  from typing import Any
8
9
 
@@ -112,7 +113,9 @@ class annotate:
112
113
  ignore_failures: Flag indicating whether to ignore
113
114
  failures in the annotate context. If set to ``True``, any exceptions
114
115
  raised within the context will be ignored, and the profiling will
115
- continue. The measured metric for this run will be set to NaN.
116
+ continue. The measured metric for this run will be set to NaN, and
117
+ a ``RuntimeWarning`` naming the annotation and the ignored exception
118
+ is emitted.
116
119
  Default: ``False``
117
120
 
118
121
  Raises:
@@ -179,6 +182,16 @@ class annotate:
179
182
  if exc_type and not self.ignore_failures:
180
183
  return False # propagate the exception
181
184
 
185
+ if exc_type:
186
+ # The failed run only shows up as NaN in the results, so report why
187
+ # it failed rather than discarding the exception.
188
+ warnings.warn(
189
+ f"Ignored failure in annotation '{self.name}': "
190
+ f"{exc_type.__name__}: {exc_value}",
191
+ category=RuntimeWarning,
192
+ stacklevel=2,
193
+ )
194
+
182
195
  return True
183
196
 
184
197
  def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]:
nsight/collection/core.py CHANGED
@@ -7,7 +7,6 @@ import functools
7
7
  import importlib.util
8
8
  import inspect
9
9
  import os
10
- import pickle
11
10
  import threading
12
11
  import time
13
12
  import warnings
@@ -235,112 +234,6 @@ def _sanitize_configs(
235
234
  return configs # type: ignore[return-value]
236
235
 
237
236
 
238
- def _picklable_or_none(value: Any) -> Any:
239
- """Return ``value`` if it can be pickled, otherwise None."""
240
- try:
241
- pickle.dumps(value)
242
- return value
243
- except Exception:
244
- return None
245
-
246
-
247
- def _sanitize_for_pickle(runs: Sequence[Mapping[str, Any]]) -> list[dict[str, Any]]:
248
- """Replace any non-picklable collected value with None, preserving structure.
249
-
250
- Used as a fallback when serializing the full collected-info list fails
251
- because a collector returned something unserializable (a CUDA stream, file
252
- handle, lambda, ...). Degrading the offending value to None keeps the rest of
253
- the run's data instead of losing everything.
254
- """
255
- sanitized: list[dict[str, Any]] = []
256
- for run in runs:
257
- new = dict(run)
258
- new["config"] = _picklable_or_none(run.get("config"))
259
- new["once_info"] = {
260
- k: _picklable_or_none(v) for k, v in run.get("once_info", {}).items()
261
- }
262
- new["config_info"] = {
263
- k: _picklable_or_none(v) for k, v in run.get("config_info", {}).items()
264
- }
265
- annotation_info = []
266
- for entry in run.get("annotation_info", []):
267
- new_entry = dict(entry)
268
- new_entry["config"] = _picklable_or_none(entry.get("config"))
269
- new_entry["data"] = {
270
- k: _picklable_or_none(v) for k, v in entry.get("data", {}).items()
271
- }
272
- annotation_info.append(new_entry)
273
- new["annotation_info"] = annotation_info
274
- sanitized.append(new)
275
- return sanitized
276
-
277
-
278
- def _serialize_collected_info(
279
- runs: Sequence[Mapping[str, Any]],
280
- ) -> tuple[bytes, bool] | None:
281
- """Serialize collected info, replacing only non-picklable values.
282
-
283
- Serialization is completed in memory before opening the output file. This
284
- keeps collector-value failures separate from filesystem failures such as a
285
- full disk or an unwritable output directory.
286
-
287
- Returns:
288
- The serialized payload and whether sanitization was required, or
289
- ``None`` when the sanitized data still cannot be serialized.
290
- """
291
- try:
292
- return pickle.dumps(runs), False
293
- except Exception as exc:
294
- sanitized = _sanitize_for_pickle(runs)
295
- try:
296
- payload = pickle.dumps(sanitized)
297
- except Exception as fallback_exc:
298
- warnings.warn(
299
- "Failed to serialize custom info after replacing non-picklable "
300
- f"values ({type(fallback_exc).__name__}: {fallback_exc}).",
301
- category=RuntimeWarning,
302
- stacklevel=2,
303
- )
304
- return None
305
-
306
- warnings.warn(
307
- f"Some collected info was not picklable ({type(exc).__name__}: {exc}); "
308
- "non-picklable collector values have been replaced with None.",
309
- category=RuntimeWarning,
310
- stacklevel=2,
311
- )
312
- return payload, True
313
-
314
-
315
- def _save_collected_info(
316
- info_file: str,
317
- runs: Sequence[Mapping[str, Any]],
318
- verbosity: VerbosityLevel,
319
- ) -> bool:
320
- """Serialize and save collected info without conflating failure causes."""
321
- serialized = _serialize_collected_info(runs)
322
- if serialized is None:
323
- return False
324
-
325
- payload, sanitized = serialized
326
- try:
327
- with open(info_file, "wb") as output_file:
328
- output_file.write(payload)
329
- except OSError as exc:
330
- warnings.warn(
331
- f"Failed to save custom info to {info_file} "
332
- f"({type(exc).__name__}: {exc}).",
333
- category=RuntimeWarning,
334
- stacklevel=2,
335
- )
336
- return False
337
-
338
- if verbosity >= VerbosityLevel.INFO:
339
- suffix = " (sanitized)" if sanitized else ""
340
- print(f"[NSIGHT-PYTHON] Saved collected info{suffix} to {info_file}")
341
- return True
342
-
343
-
344
237
  def run_profile_session(
345
238
  func: Callable[..., None],
346
239
  configs: list[Sequence[Any]],
@@ -352,8 +245,13 @@ def run_profile_session(
352
245
  thermal_timeout: int | None = None,
353
246
  thermal_device: int | None = None,
354
247
  info_collectors_list: list[NormalizedInfoCollector] | None = None,
355
- output_prefix: str | None = None,
356
- ) -> None:
248
+ ) -> list[dict[str, Any]]:
249
+ """Run ``func`` for every config and run inside a profiling session.
250
+
251
+ Returns:
252
+ The custom info collected for each run, in run order, for the caller
253
+ to pass to extraction.
254
+ """
357
255
 
358
256
  if verbosity >= VerbosityLevel.INFO:
359
257
  print("")
@@ -385,8 +283,13 @@ def run_profile_session(
385
283
  bar_length = 100
386
284
  progress_time: float = 0
387
285
 
388
- # overwrite flag: we do not overwrite when output mode is debug
389
- overwrite_output = verbosity < VerbosityLevel.DEBUG
286
+ # overwrite flag: we do not overwrite when output mode is debug, or when
287
+ # stdout is not a terminal (overwriting relies on cursor-movement codes)
288
+ is_terminal = utils.stdout_is_terminal()
289
+ overwrite_output = verbosity < VerbosityLevel.DEBUG and is_terminal
290
+ # Without a terminal to overwrite in place, intermediate progress bars would
291
+ # each become a new line, so only the final one is printed (except in debug)
292
+ show_intermediate_progress = is_terminal or verbosity >= VerbosityLevel.DEBUG
390
293
  show_return_type_warning = False
391
294
  config_lengths: list[int] = list()
392
295
 
@@ -439,7 +342,7 @@ def run_profile_session(
439
342
  )
440
343
 
441
344
  # Store collected info for each run
442
- collected_info_per_run = []
345
+ collected_info_per_run: list[dict[str, Any]] = []
443
346
 
444
347
  for c in configs:
445
348
  sig = inspect.signature(func)
@@ -560,7 +463,7 @@ def run_profile_session(
560
463
 
561
464
  # Update time estimates every half second
562
465
  if time.time() - progress_time > 0.5:
563
- if verbosity >= VerbosityLevel.INFO:
466
+ if verbosity >= VerbosityLevel.INFO and show_intermediate_progress:
564
467
  utils.print_progress_bar(
565
468
  total_runs,
566
469
  curr_run,
@@ -594,10 +497,7 @@ def run_profile_session(
594
497
  stacklevel=external_stacklevel,
595
498
  )
596
499
 
597
- # Save collected info to a file if we have collectors
598
- if info_collectors_list and output_prefix:
599
- info_file = f"{output_prefix}collected_info.pkl"
600
- _save_collected_info(info_file, collected_info_per_run, verbosity)
500
+ return collected_info_per_run
601
501
 
602
502
 
603
503
  @dataclasses.dataclass
@@ -365,7 +365,7 @@ class CUPTICollector(core.NsightCollector):
365
365
  for cbid in _LAUNCH_CBIDS:
366
366
  cupti.activity_enable_driver_api(cbid, 1)
367
367
 
368
- core.run_profile_session(
368
+ collected_info_per_run = core.run_profile_session(
369
369
  func,
370
370
  configs_list,
371
371
  settings.runs,
@@ -376,7 +376,6 @@ class CUPTICollector(core.NsightCollector):
376
376
  settings.thermal_timeout,
377
377
  settings.thermal_device,
378
378
  settings.info_collectors,
379
- settings.output_prefix,
380
379
  )
381
380
 
382
381
  # A kernel's activity record only exists once it has finished, so
@@ -443,7 +442,7 @@ class CUPTICollector(core.NsightCollector):
443
442
  settings.info_collectors,
444
443
  config_scope_columns,
445
444
  annotation_scope_columns,
446
- info_prefix=settings.output_prefix or "",
445
+ collected_info_per_run=collected_info_per_run,
447
446
  )
448
447
 
449
448
  return df
nsight/collection/ncu.py CHANGED
@@ -492,7 +492,7 @@ class NCUCollector(core.NsightCollector):
492
492
  f"{len(configs_list)} configurations, {settings.runs} runs each",
493
493
  )
494
494
 
495
- core.run_profile_session(
495
+ collected_info_per_run = core.run_profile_session(
496
496
  func,
497
497
  configs_list,
498
498
  settings.runs,
@@ -503,7 +503,6 @@ class NCUCollector(core.NsightCollector):
503
503
  settings.thermal_timeout,
504
504
  settings.thermal_device,
505
505
  settings.info_collectors,
506
- settings.output_prefix,
507
506
  )
508
507
  finally:
509
508
  try:
@@ -557,7 +556,7 @@ class NCUCollector(core.NsightCollector):
557
556
  settings.info_collectors,
558
557
  config_scope_columns,
559
558
  annotation_scope_columns,
560
- info_prefix=settings.output_prefix or "",
559
+ collected_info_per_run=collected_info_per_run,
561
560
  )
562
561
 
563
562
  return df
nsight/extraction.py CHANGED
@@ -47,6 +47,14 @@ DERIVED_METRIC_MISSING_UNIT_WARNING = (
47
47
  "np.nan will be added to the 'Unit' column in the dataframe."
48
48
  )
49
49
 
50
+ # Hint appended to kernel-count errors. Autotuning and other first-call work
51
+ # launch extra kernels only on the first run.
52
+ _WARMUP_HINT = (
53
+ "If the code in the annotation autotunes or does other work only on its "
54
+ "first call, run it once for every configuration before calling the "
55
+ "profiled function, so that every run launches the same kernels.\n"
56
+ )
57
+
50
58
 
51
59
  def extract_ncu_action_data(action: Any, metrics: Sequence[str]) -> utils.ActionData:
52
60
  """
@@ -114,8 +122,13 @@ def extract_data_from_report(
114
122
  report: ncu_report.IContext = ncu_report.load_report(report_path)
115
123
  except FileNotFoundError:
116
124
  raise exceptions.ProfilerException(
117
- "No NVIDIA Nsight Compute report found. Please run nsight-python with `@nsight.analyze.kernel(verbosity=nsight.VerbosityLevel.DEBUG)`"
118
- "to identify the issue."
125
+ f"No NVIDIA Nsight Compute report found at {report_path}. NVIDIA Nsight "
126
+ "Compute writes a report only if it profiled at least one kernel, so "
127
+ "the most likely cause is that no kernel was launched inside any "
128
+ "nsight.annotate region (for example, the annotated code only creates "
129
+ "a view, is a no-op, or returns a cached result). Otherwise, run with "
130
+ "`@nsight.analyze.kernel(verbosity=nsight.VerbosityLevel.DEBUG)` and "
131
+ "check the NVIDIA Nsight Compute log to identify the issue."
119
132
  )
120
133
 
121
134
  # Extract all profiling data
@@ -158,7 +171,7 @@ def extract_df_from_data(
158
171
  info_collectors_list: List[Tuple[str, Callable[..., Any], str]] | None = None,
159
172
  config_scope_columns: List[str] | None = None,
160
173
  annotation_scope_columns: List[str] | None = None,
161
- info_prefix: str | None = None,
174
+ collected_info_per_run: Sequence[Mapping[str, Any]] | None = None,
162
175
  ) -> pd.DataFrame:
163
176
  """
164
177
  Aggregates raw per-annotation measurements (from either tool) into a pandas
@@ -173,6 +186,11 @@ def extract_df_from_data(
173
186
  derive_metric: Function to transform the raw metric values with config values.
174
187
  verbosity: Controls display of extraction progress.
175
188
  combine_kernel_metrics: Function to merge multiple kernel metrics.
189
+ info_collectors_list: Custom info collectors as ``(name, callback, scope)``.
190
+ config_scope_columns: Collector columns that vary per config or run.
191
+ annotation_scope_columns: Collector columns that vary per annotation.
192
+ collected_info_per_run: Custom info collected for each run, in run order,
193
+ as returned by :func:`nsight.collection.core.run_profile_session`.
176
194
 
177
195
  Returns:
178
196
  A DataFrame containing the extracted and transformed performance data.
@@ -206,46 +224,28 @@ def extract_df_from_data(
206
224
  not in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD)
207
225
  }
208
226
 
209
- # Load collected info from the pickle file if it exists
210
- collected_info_per_run = []
211
227
  custom_info_names = set()
212
228
  if info_collectors_list:
213
- # The caller supplies the prefix so the read path matches the
214
- # collection-session write path exactly.
215
- if info_prefix is None:
216
- info_prefix = ""
217
-
218
229
  # Column names come from the collector metadata (authoritative), not from
219
230
  # the first run's collected data. Deriving from run 0 dropped any
220
231
  # annotation-scope collector whose annotation was not entered on run 0.
221
232
  custom_info_names = {name for name, _callback, _scope in info_collectors_list}
222
-
223
- info_file = f"{info_prefix}collected_info.pkl"
224
- if os.path.exists(info_file):
225
- import pickle
226
-
227
- with open(info_file, "rb") as f:
228
- collected_info_per_run = pickle.load(f)
229
- if not isinstance(collected_info_per_run, list):
230
- warnings.warn(
231
- f"Collected info file {info_file} is malformed "
232
- f"(expected a list, got {type(collected_info_per_run).__name__}); "
233
- "ignoring custom info.",
234
- category=RuntimeWarning,
235
- stacklevel=2,
236
- )
237
- collected_info_per_run = []
238
- elif verbosity >= VerbosityLevel.INFO:
239
- print(f"[NSIGHT-PYTHON] Loaded collected info from {info_file}")
240
- else:
241
- if verbosity >= VerbosityLevel.INFO:
242
- print(
243
- f"[NSIGHT-PYTHON] Warning: No collected info file found at {info_file}"
244
- )
233
+ else:
234
+ collected_info_per_run = None
245
235
 
246
236
  # Create arrays for custom info collectors
247
237
  custom_info_arrays: dict[str, list[Any]] = {name: [] for name in custom_info_names}
248
238
 
239
+ # Without this check, a session in which no kernel could be attributed to
240
+ # any annotation would silently return an empty DataFrame.
241
+ if not profiling_data:
242
+ raise RuntimeError(
243
+ "No kernels were profiled: no kernel launch could be attributed to "
244
+ "any nsight.annotate region. Check that each annotated region "
245
+ "launches at least one kernel and that no kernel launched in it is "
246
+ "listed in ignore_kernel_list."
247
+ )
248
+
249
249
  for annotation, annotation_data in profiling_data.items():
250
250
  if verbosity >= VerbosityLevel.INFO:
251
251
  print(f"[NSIGHT-PYTHON] Extracting {annotation} profiling data")
@@ -261,7 +261,9 @@ def extract_df_from_data(
261
261
  if len(annotation_data) % len(configs_repeated) != 0:
262
262
  raise RuntimeError(
263
263
  "Expect same number of kernels per run. "
264
- f"Got average of {len(annotation_data) / len(configs_repeated)} per run"
264
+ f"Got average of {len(annotation_data) / len(configs_repeated)} per run "
265
+ f"in the {annotation} annotation.\n"
266
+ f"{_WARMUP_HINT}"
265
267
  )
266
268
  num_kernels = len(annotation_data) // len(configs_repeated)
267
269
 
@@ -269,12 +271,15 @@ def extract_df_from_data(
269
271
  if combine_kernel_metrics is None:
270
272
  raise RuntimeError(
271
273
  (
272
- f"More than one (total={num_kernels}) kernel is launched within the {annotation} annotation.\n"
274
+ f"More than one ({len(annotation_data)} in {len(configs_repeated)} "
275
+ f"runs, {num_kernels} per run on average) kernel is launched "
276
+ f"within the {annotation} annotation.\n"
273
277
  "We expect one kernel per annotation.\n"
274
278
  "Try one of the following solutions:\n"
275
279
  " - Use `replay_mode='range'` to profile the entire annotated range instead of individual kernels\n"
276
280
  " - Use `combine_kernel_metrics = lambda x, y: ...` to combine the metrics of multiple kernels\n"
277
281
  " - Add some of the kernels to the ignore_kernel_list\n"
282
+ f"{_WARMUP_HINT}"
278
283
  "Kernels are:\n"
279
284
  + "\n".join(sorted(set(x.name for x in annotation_data)))
280
285
  )
@@ -395,13 +400,12 @@ def extract_df_from_data(
395
400
  if (
396
401
  collected_info_per_run
397
402
  and idx < len(collected_info_per_run)
398
- and isinstance(collected_info_per_run[idx], dict)
403
+ and isinstance(collected_info_per_run[idx], Mapping)
399
404
  ):
400
405
  run_info = collected_info_per_run[idx]
401
- # Add once info. Guard against pickle keys that are not in the
402
- # metadata-derived custom_info_names (e.g. a stale collected_info
403
- # .pkl written by a different set of collectors); such keys have
404
- # no column and are ignored rather than raising KeyError.
406
+ # Add once info. Guard against keys that are not in the
407
+ # metadata-derived custom_info_names; such keys have no column
408
+ # and are ignored rather than raising KeyError.
405
409
  for name, value in run_info.get("once_info", {}).items():
406
410
  if name in custom_info_arrays:
407
411
  custom_info_arrays[name].append(value)
@@ -515,7 +519,7 @@ def extract_df_from_report(
515
519
  info_collectors_list: List[Tuple[str, Callable[..., Any], str]] | None = None,
516
520
  config_scope_columns: List[str] | None = None,
517
521
  annotation_scope_columns: List[str] | None = None,
518
- info_prefix: str | None = None,
522
+ collected_info_per_run: Sequence[Mapping[str, Any]] | None = None,
519
523
  ) -> pd.DataFrame:
520
524
  """
521
525
  Extracts and aggregates profiling results from an NVIDIA Nsight Compute report.
@@ -529,6 +533,11 @@ def extract_df_from_report(
529
533
  derive_metric: Function to transform the raw metric values with config values.
530
534
  ignore_kernel_list: Kernel names to ignore in the analysis.
531
535
  combine_kernel_metrics: Function to merge multiple kernel metrics.
536
+ info_collectors_list: Custom info collectors as ``(name, callback, scope)``.
537
+ config_scope_columns: Collector columns that vary per config or run.
538
+ annotation_scope_columns: Collector columns that vary per annotation.
539
+ collected_info_per_run: Custom info collected for each run, in run order,
540
+ as returned by :func:`nsight.collection.core.run_profile_session`.
532
541
  verbosity: Controls display of extraction progress.
533
542
 
534
543
  Returns:
@@ -546,12 +555,6 @@ def extract_df_from_report(
546
555
  verbosity,
547
556
  )
548
557
 
549
- # Fall back to reconstructing the info prefix from the report directory for
550
- # direct callers that did not supply one.
551
- if info_collectors_list and info_prefix is None:
552
- report_dir = os.path.dirname(report_path)
553
- info_prefix = os.path.join(report_dir, "") if report_dir else ""
554
-
555
558
  return extract_df_from_data(
556
559
  profiling_data,
557
560
  metrics,
@@ -564,5 +567,5 @@ def extract_df_from_report(
564
567
  info_collectors_list,
565
568
  config_scope_columns,
566
569
  annotation_scope_columns,
567
- info_prefix,
570
+ collected_info_per_run,
568
571
  )
nsight/utils.py CHANGED
@@ -78,8 +78,23 @@ class Colors:
78
78
  UNDERLINE = "\033[4m"
79
79
 
80
80
 
81
+ def stdout_is_terminal() -> bool:
82
+ """
83
+ Returns whether stdout is an interactive terminal.
84
+
85
+ ANSI color and cursor-movement codes are only emitted when this is true, so
86
+ that output redirected to a file, a pipe, or a captured log stays plain text.
87
+ """
88
+ try:
89
+ return sys.stdout.isatty()
90
+ except (AttributeError, ValueError):
91
+ return False
92
+
93
+
81
94
  def purple(msg: str) -> str: # pragma: no cover
82
95
  """Prints ``msg`` in purple."""
96
+ if not stdout_is_terminal():
97
+ return msg
83
98
  return Colors.PURPLE + msg + Colors.ENDC
84
99
 
85
100
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: nsight-python
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: Python GPU kernel profiling interface
5
5
  Project-URL: Repository, https://github.com/NVIDIA/nsight-python
6
6
  Project-URL: License, https://docs.nvidia.com/nsight-python/license.html
@@ -1,20 +1,20 @@
1
1
  nsight/__init__.py,sha256=LrDF8j_emdbwNNsqSrABCRsDanTGzfRWfCjj8H2MbsI,1471
2
2
  nsight/analyze.py,sha256=91BFc7SdR9JXQER6hBK2USGP43Ile_d9l3nVFVOME2E,35548
3
- nsight/annotation.py,sha256=9untg0pRI3FR-gRQKCmHrbFgv1zEdooZgfGAzuocYAY,6730
3
+ nsight/annotation.py,sha256=-dLOQS0wn54rKEmk-Mu3frINUDQqLkVNlxDaITV4CJo,7249
4
4
  nsight/exceptions.py,sha256=LhtCtaOBP6m9KVWv9RjEqx3pGP2trLObC2aqEvE4fuE,2634
5
5
  nsight/experimental.py,sha256=iE24Whb6Jo48f_tTNvZm8aLWyEabnB8xL8nUk2Ps9ik,2611
6
- nsight/extraction.py,sha256=Wp4tDwnu895U5zldhxoT_qpEpiC9325zMS6_get692A,24455
6
+ nsight/extraction.py,sha256=kh-BZdNhngZZWmctPA7VcqOXWUvQ1y8jkTLQ4LGPzhs,25226
7
7
  nsight/info_collector.py,sha256=hGJgFoC--UKYvGeUm76j_g32CUNd-HpseGt4wE3YJxI,12871
8
8
  nsight/thermovision.py,sha256=z5_WvFbYLWb1jyuMPSfS1Ia58vdq3_tAtRPJzwg2sIc,14836
9
9
  nsight/tools_manager.py,sha256=ZT0MrzBZK1l6HAIwBmAv54veBWbo0ZOxxvD5xhY1Xx4,3353
10
10
  nsight/transformation.py,sha256=-Myr51srFaQzGAoFxFScQ7SsKrRpv4rVzW7Ob0yKH7k,8604
11
- nsight/utils.py,sha256=W_n5eKFAMzZiqB0hTku161zTJKoUfBuJ2ucsUO0qa6A,12080
11
+ nsight/utils.py,sha256=MU2cVPsuA7sv-RuHECDvA3V9OS70duIFseNsU35NIcA,12508
12
12
  nsight/visualization.py,sha256=OJpFVGXQuTPD2Tl2EsEuOO4rj8L-F_0OZczADPBwknk,20341
13
13
  nsight/collection/__init__.py,sha256=a4C7kKg9WDdgmOwS-GpgLyXTwv2BVZNd1mjB3Ppax_g,335
14
- nsight/collection/core.py,sha256=pmINh39_CBhoMsm13psoawSfDXEjww4OjLZAeXQM57Y,34471
15
- nsight/collection/cupti.py,sha256=nK5PkWftictdMBHPDGuZchYmymwexZ6_iSQXNLqc3lQ,17446
16
- nsight/collection/ncu.py,sha256=dGLVaNGD9muRdTLskOS2SWrP2yrO7oh-aQYldrfIhmA,21671
17
- nsight_python-1.1.0.dist-info/METADATA,sha256=YHFoemld9oY7FPmmOdd4GudRLc5hJW1TgmLVPrCcoyU,15121
18
- nsight_python-1.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
19
- nsight_python-1.1.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
20
- nsight_python-1.1.0.dist-info/RECORD,,
14
+ nsight/collection/core.py,sha256=ykUCwUERY3EAd0_vNCbXF9IaOANiKka_eIYB7q7kb9Y,31112
15
+ nsight/collection/cupti.py,sha256=Sdq7_kjWa-vMVT2vZY5Bt5nuh9NB7SNQfnAuV4ylj6Q,17436
16
+ nsight/collection/ncu.py,sha256=ZT3HjjBMLUnYz5XlxJAmVs_ZsoZ1NIj-3FOsYxz6pnw,21661
17
+ nsight_python-1.1.1.dist-info/METADATA,sha256=UzuCstAbx72oaSYWoU8l0CXwUwWmiN8BvPm_7wcopkU,15121
18
+ nsight_python-1.1.1.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
19
+ nsight_python-1.1.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
20
+ nsight_python-1.1.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.32.4
2
+ Generator: hatchling 1.33.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any