From 29eeb75a00de6ae5f346e9b98c7937ec06efbe21 Mon Sep 17 00:00:00 2001 From: clams-bot Date: Sat, 26 Jul 2025 17:50:16 +0000 Subject: [PATCH 1/2] adding HTML documentation for publication --- docs/.doctrees/environment.pickle | Bin 2308881 -> 2308881 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle index 30a34dfddfac33aac8067a3fdaccde6b37eeb856..e11b07cfe25148a199586297b78b9f7bf4672241 100644 GIT binary patch delta 4979 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 delta 4974 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 From c366c9a5c5e737ea9a5a9b3e3043881ae8cc8d93 Mon Sep 17 00:00:00 2001 From: Keigh Rim Date: Sun, 10 Aug 2025 21:57:44 -0400 Subject: [PATCH 2/2] added cuda vram profiling to viewmetadata --- clams/app/__init__.py | 76 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/clams/app/__init__.py b/clams/app/__init__.py index d6c6dcf..6550327 100644 --- a/clams/app/__init__.py +++ b/clams/app/__init__.py @@ -148,7 +148,7 @@ def annotate(self, mmif: Union[str, dict, Mmif], **runtime_params: List[str]) -> pretty = refined.get('pretty', False) t = datetime.now() with warnings.catch_warnings(record=True) as ws: - annotated = self._annotate(mmif, **refined) + annotated, cuda_profiler = self._profile_cuda_memory(self._annotate)(mmif, **refined) if ws: issued_warnings.extend(ws) if issued_warnings: @@ -164,11 +164,21 @@ def annotate(self, mmif: Union[str, dict, Mmif], **runtime_params: List[str]) -> runtime_recs['architecture'] = platform.machine() # runtime_recs['processor'] = platform.processor() # this only works on Windows runtime_recs['cuda'] = [] - if shutil.which('nvidia-smi'): + # Use cuda_profiler data if available, otherwise fallback to nvidia-smi + if cuda_profiler: + for gpu_info, peak_memory_bytes in cuda_profiler.items(): + # Convert peak memory to human-readable format + peak_memory_mb = peak_memory_bytes / (1000 * 1000) + if peak_memory_mb >= 1000: + peak_memory_str = f"{peak_memory_mb / 1000:.2f} GiB" + else: + peak_memory_str = f"{peak_memory_mb:.1f} MiB" + runtime_recs['cuda'].append(f"{gpu_info}, Used {self._cuda_memory_to_str(peak_memory_bytes)}") + elif shutil.which('nvidia-smi'): for gpu in subprocess.run(['nvidia-smi', '--query-gpu=name,memory.total', '--format=csv,noheader'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip().split('\n'): name, mem = gpu.split(', ') - runtime_recs['cuda'].append(f'{name} ({mem})') + runtime_recs['cuda'].append(self._cuda_device_name_concat(name, mem)) for annotated_view in annotated.views: if annotated_view.metadata.app == self.metadata.identifier: if runningTime: @@ -321,6 +331,66 @@ def validate_document_locations(mmif: Union[str, Mmif]) -> None: # (https://github.com/clamsproject/mmif/issues/150) , here is a good place for additional check for # file integrity + @staticmethod + def _cuda_memory_to_str(mem) -> str: + mib = mem / (1024 * 1024) + if mib >= 1024: + return f"{mib / 1024:.2f} GiB" + else: + return f"{mib:.1f} MiB" + + @staticmethod + def _cuda_device_name_concat(name, mem): + if type(mem) in (bytes, int): + mem = ClamsApp._cuda_memory_to_str(mem) + return f"{name}, With {mem}" + + @staticmethod + def _profile_cuda_memory(func): + """ + Decorator for profiling CUDA memory usage during _annotate execution. + + :param func: The function to wrap (typically _annotate) + :return: Decorated function that returns (result, cuda_profiler) + where cuda_profiler is dict with ", " keys + and peak memory usage values + """ + def wrapper(*args, **kwargs): + cuda_profiler = {} + torch_available = False + cuda_available = False + device_count = 0 + + try: + import torch # pytype: disable=import-error + torch_available = True + cuda_available = torch.cuda.is_available() + device_count = torch.cuda.device_count() + if cuda_available: + # Reset peak memory stats for all devices + torch.cuda.reset_peak_memory_stats('cuda') + except ImportError: + pass + + try: + result = func(*args, **kwargs) + + if torch_available and cuda_available and device_count > 0: + for device_id in range(device_count): + device_id = f'cuda:{device_id}' + peak_memory = torch.cuda.max_memory_allocated(device_id) + gpu_name = torch.cuda.get_device_name(device_id) + gpu_total_memory = torch.cuda.get_device_properties(device_id).total_memory + key = ClamsApp._cuda_device_name_concat(gpu_name, gpu_total_memory) + cuda_profiler[key] = peak_memory + + return result, cuda_profiler + finally: + if torch_available and cuda_available: + torch.cuda.empty_cache() + + return wrapper + @staticmethod @contextmanager def open_document_location(document: Union[str, Document], opener: Any = open, **openerargs):