diff --git a/.gitignore b/.gitignore index 779b76f9..031afdc2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,12 @@ +# Non-default Workspace Locations /workspaces/* !/workspaces/public_datasets !workspaces/CMS_project_v1/CMS_project_v1/config/CMS_project_v1_config.py !workspaces/CFD_workspace/CFD_project_animation/config/CFD_project_animation_config.py +# Information Tracking Files +*.csv + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/baler/baler.py b/baler/baler.py index f7bcfb2e..e7516404 100644 --- a/baler/baler.py +++ b/baler/baler.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,28 +57,33 @@ def main(): project_path = os.path.join("workspaces", workspace_name, project_name) output_path = os.path.join(project_path, "output") - if mode == "newProject": - helper.create_new_project(workspace_name, project_name, verbose) - elif mode == "train": - perform_training(output_path=output_path, config=config, verbose=verbose) - elif mode == "diagnose": - perform_diagnostics(output_path, verbose) - elif mode == "compress": - perform_compression(output_path, config, verbose) - elif mode == "decompress": - perform_decompression(output_path, config, verbose) - elif mode == "plot": - perform_plotting(output_path, config, verbose) - elif mode == "info": - print_info(output_path, config) - elif mode == "convert_with_hls4ml": - helper.perform_hls4ml_conversion(output_path, config) - else: - raise NameError( - "Baler mode " - + mode - + " not recognised. Use baler --help to see available modes." - ) + tracker_title = f"Baler {mode} {workspace_name}-{project_name}" + if mode != "newProject": + tracker_title += f", Model: {config.model_name}" + tracker = helper.setup_green_tracker() + with tracker.time(tracker_title, verbose=verbose): + if mode == "newProject": + helper.create_new_project(workspace_name, project_name, verbose) + elif mode == "train": + perform_training(output_path=output_path, config=config, verbose=verbose) + elif mode == "diagnose": + perform_diagnostics(output_path, verbose) + elif mode == "compress": + perform_compression(output_path, config, verbose) + elif mode == "decompress": + perform_decompression(output_path, config, verbose) + elif mode == "plot": + perform_plotting(output_path, config, verbose) + elif mode == "info": + print_info(output_path, config) + elif mode == "convert_with_hls4ml": + helper.perform_hls4ml_conversion(output_path, config) + else: + raise NameError( + "Baler mode " + + mode + + " not recognised. Use baler --help to see available modes." + ) def perform_training(output_path, config, verbose: bool): @@ -255,7 +260,7 @@ def perform_compression(output_path, config, verbose: bool): - Normalization features if `config.apply_normalization=True` """ print("Compressing...") - start = time.time() + start = time.perf_counter() normalization_features = [] if config.apply_normalization: @@ -283,9 +288,9 @@ def perform_compression(output_path, config, verbose: bool): config=config, ) - end = time.time() + end = time.perf_counter() - print("Compression took:", f"{(end - start) / 60:.3} minutes") + print("Compression took:", f"{(end - start):.3} seconds") names = np.load(config.input_path)["names"] @@ -351,7 +356,7 @@ def perform_decompression(output_path, config, verbose: bool): """ print("Decompressing...") - start = time.time() + start = time.perf_counter() model_name = config.model_name data_before = np.load(config.input_path)["data"] if config.separate_model_saving: @@ -434,8 +439,8 @@ def perform_decompression(output_path, config, verbose: bool): except AttributeError: pass - end = time.time() - print("Decompression took:", f"{(end - start) / 60:.3} minutes") + end = time.perf_counter() + print("Decompression took:", f"{(end - start):.3} seconds") if config.extra_compression: if verbose: diff --git a/baler/modules/data_processing.py b/baler/modules/data_processing.py index d14d9958..6d6a9ec0 100644 --- a/baler/modules/data_processing.py +++ b/baler/modules/data_processing.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/baler/modules/green_code.py b/baler/modules/green_code.py new file mode 100644 index 00000000..058ac32f --- /dev/null +++ b/baler/modules/green_code.py @@ -0,0 +1,202 @@ +# Copyright 2022-2025 Baler Contributors + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import csv +import os +import time +from datetime import datetime +from time import perf_counter +import contextlib +import psutil +import cpuinfo +import shutil + +# Attempt to use pynvml for NVIDIA GPU tracking +try: + import pynvml + + pynvml.nvmlInit() + NVIDIA_SMI_AVAILABLE = True +except ImportError: + NVIDIA_SMI_AVAILABLE = False + if shutil.which("nvidia-smi") is not None: + print("\n" + "=" * 80) + print("WARNING: NVIDIA GPU detected, but 'pynvml' is not installed.") + print("To enable GPU tracking, please install the optional 'gpu' dependencies:") + print("\n poetry install --with gpu\n") + print("=" * 80 + "\n") +except pynvml.NVMLError: + # if pynvml is installed but driver communication fails + NVIDIA_SMI_AVAILABLE = False + print( + "\nWARNING: 'pynvml' is installed, but could not connect to the NVIDIA driver." + ) + print("GPU tracking will be disabled. Check your driver installation.\n") + + +class GreenCodeTracker: + """ + A class to track function run times and system specs, saving the data to a CSV file. + + This class can be used as a context manager to easily time blocks of code. + It records hardware specifications like CPU and GPU models, core counts, and + available memory, along with the runtime of the specified code block. + + Attributes: + file_name (str): The name of the CSV file where tracking data is stored. + headers (list): The column headers for the CSV file. + system_specs (dict): A dictionary containing details about the system's hardware. + """ + + def __init__(self, file_path="green_code_tracking.csv"): + """ + Initializes the GreenCodeTracker. + + Args: + + """ + self.file_name = file_path + self.headers = [ + "Timestamp", + "Runtime(format HH:MM:SS)", + "Title", + "CPUmodel", + "GPU model", + "Number of CPU cores", + "Number of GPU cores", + "Memory available (GB)", + ] + self.system_specs = self._get_system_specs() + self._ensure_header() + + def _get_system_specs(self): + """ + Gathers system hardware specifications. + + Collects information about the CPU, GPU (if available), and memory. + + Returns: + dict: A dictionary containing system specifications. + """ + cpu_model = cpuinfo.get_cpu_info().get("brand_raw", "N/A") + cpu_cores = psutil.cpu_count(logical=True) + gpu_model, gpu_cores = "N/A", "N/A" + if NVIDIA_SMI_AVAILABLE: + try: + device_count = pynvml.nvmlDeviceGetCount() + if device_count > 0: + handle = pynvml.nvmlDeviceGetHandleByIndex(0) + gpu_model = pynvml.nvmlDeviceGetName(handle) + try: + gpu_cores = pynvml.nvmlDeviceGetMultiProcessorCount(handle) + except pynvml.NVMLError: + gpu_cores = "N/A (older card)" + except pynvml.NVMLError: + gpu_model = "NVIDIA driver issue" + memory_gb = round(psutil.virtual_memory().total / (1024**3), 2) + return { + "CPUmodel": cpu_model, + "Number of CPU cores": cpu_cores, + "GPU model": gpu_model, + "Number of GPU cores": gpu_cores, + "Memory available (GB)": memory_gb, + } + + def _ensure_header(self): + """ + Ensures the CSV file exists and has a header row. + + If the file does not exist, it is created and the headers defined in + `self.headers` are written to it. + """ + if not os.path.exists(self.file_name): + with open(self.file_name, "w", newline="", encoding="utf-8") as f: + writer = csv.DictWriter(f, fieldnames=self.headers) + writer.writeheader() + + def track(self, start, end, title, verbose=False): + """ + Records a single tracking entry to the CSV file. + + Args: + start (float): The start time (from `time.perf_counter()`). + end (float): The end time (from `time.perf_counter()`). + title (str): A descriptive title for the tracked event. + verbose (bool, optional): If True, prints a summary to the console. + Defaults to False. + """ + runtime_seconds = end - start + runtime_formatted = time.strftime("%H:%M:%S", time.gmtime(runtime_seconds)) + data_row = { + "Timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + "Runtime(format HH:MM:SS)": runtime_formatted, + "Title": title, + **self.system_specs, + } + with open(self.file_name, "a", newline="", encoding="utf-8") as f: + writer = csv.DictWriter(f, fieldnames=self.headers) + writer.writerow(data_row) + if verbose: + self._print_verbose_summary(title, runtime_seconds, runtime_formatted) + + @contextlib.contextmanager + def time(self, title, verbose=False): + """ + A context manager to time a block of code. + + Example: + tracker = GreenCodeTracker() + with tracker.time("data_processing", verbose=True): + # Code to be timed + time.sleep(1) + + Args: + title (str): A descriptive title for the timed block. + verbose (bool, optional): If True, prints a summary to the console + upon exiting the context. Defaults to False. + """ + start_time = perf_counter() + try: + yield + finally: + end_time = perf_counter() + self.track(start_time, end_time, title, verbose=verbose) + + def _print_verbose_summary(self, title, runtime_seconds, runtime_formatted): + """ + Prints a formatted summary of the tracking results to the console. + + Args: + title (str): The title of the tracked event. + runtime_seconds (float): The total runtime in seconds. + runtime_formatted (str): The runtime formatted as HH:MM:SS. + """ + print("\n" + "=" * 150) + print( + f" GREEN CODE INITIATIVE - {title} " + ) + print("-" * 150) + print( + f"Total time taken for {title}: {runtime_seconds:.3f} seconds ({runtime_formatted})" + ) + print( + f"CPU: {self.system_specs['CPUmodel']} ({self.system_specs['Number of CPU cores']} cores)" + ) + if self.system_specs["GPU model"] != "N/A": + print( + f"GPU: {self.system_specs['GPU model']} ({self.system_specs['Number of GPU cores']} multiprocessors)" + ) + print(f"Memory: {self.system_specs['Memory available (GB)']} GB") + print(f"\n{title} complete. All results saved to {self.file_name}") + print("=" * 150 + "\n") diff --git a/baler/modules/helper.py b/baler/modules/helper.py index dcacdc21..f8fe53e2 100644 --- a/baler/modules/helper.py +++ b/baler/modules/helper.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ import importlib import os import sys +from datetime import datetime from dataclasses import dataclass from math import ceil import gzip - from tqdm import tqdm sys.path.append(os.getcwd()) @@ -28,7 +28,7 @@ from torch.utils.data import DataLoader from sklearn.model_selection import train_test_split -from ..modules import training, plotting, data_processing, diagnostics +from ..modules import training, plotting, data_processing, diagnostics, green_code def get_arguments(): @@ -849,3 +849,10 @@ def perform_hls4ml_conversion(output_path, config): hls_model.build( csim=config.csim, synth=config.synth, cosim=config.cosim, export=config.export ) + + +def setup_green_tracker(): + """ + Initializes and returns an instance of the GreenCodeTracker. + """ + return green_code.GreenCodeTracker() diff --git a/baler/modules/models.py b/baler/modules/models.py index 62075b92..67e368d2 100644 --- a/baler/modules/models.py +++ b/baler/modules/models.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/baler/modules/plotting.py b/baler/modules/plotting.py index aa59656f..52898e24 100644 --- a/baler/modules/plotting.py +++ b/baler/modules/plotting.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/baler/modules/training.py b/baler/modules/training.py index ca189def..0c6472fd 100644 --- a/baler/modules/training.py +++ b/baler/modules/training.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -280,7 +280,7 @@ def train(model, variables, train_data, test_data, project_path, config): # Training and Validation of the model train_loss = [] val_loss = [] - start = time.time() + start = time.perf_counter() # Registering hooks for activation extraction if config.activation_extraction: @@ -328,7 +328,7 @@ def train(model, variables, train_data, test_data, project_path, config): path = os.path.join(project_path, f"model_{epoch}.pt") helper.model_saver(model, path) - end = time.time() + end = time.perf_counter() # Saving activations values if config.activation_extraction: @@ -336,7 +336,7 @@ def train(model, variables, train_data, test_data, project_path, config): model.detach_hooks(hooks) np.save(os.path.join(project_path, "activations.npy"), activations) - print(f"{(end - start) / 60:.3} minutes") + print(f"{(end - start):.3} seconds") np.save( os.path.join(project_path, "loss_data.npy"), np.array([train_loss, val_loss]) ) diff --git a/baler/modules/utils.py b/baler/modules/utils.py index 23b63687..7bb7a233 100644 --- a/baler/modules/utils.py +++ b/baler/modules/utils.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/poetry.lock b/poetry.lock index 7b949e57..267eb68b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. [[package]] name = "absl-py" @@ -6,6 +6,8 @@ version = "1.4.0" description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"}, {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"}, @@ -17,6 +19,8 @@ version = "1.6.3" description = "An AST unparser for Python" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, @@ -32,6 +36,7 @@ version = "23.12.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, @@ -68,7 +73,7 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +d = ["aiohttp (>=3.7.4) ; sys_platform != \"win32\" or implementation_name != \"pypy\"", "aiohttp (>=3.7.4,!=3.9.0) ; sys_platform == \"win32\" and implementation_name == \"pypy\""] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] @@ -78,6 +83,8 @@ version = "5.3.3" description = "Extensible memoizing collections and decorators" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, @@ -89,6 +96,8 @@ version = "1.3.1" description = "Various parsers for ECMA standards." optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "calmjs.parse-1.3.1-py2-none-any.whl", hash = "sha256:9d3cec13fcc914f635c4940d2bfe007800093435b4ad4ef7d4e91d81dda66c80"}, {file = "calmjs.parse-1.3.1-py3-none-any.whl", hash = "sha256:34e087b2a7a3117264df416d7d6793000bc59773e182ffef7da2dd7820f88028"}, @@ -105,6 +114,8 @@ version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, @@ -116,6 +127,8 @@ version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = true python-versions = ">=3.7.0" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, @@ -215,6 +228,7 @@ version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -229,10 +243,12 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main", "dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +markers = {main = "platform_system == \"Windows\" or sys_platform == \"win32\"", dev = "sys_platform == \"win32\" or platform_system == \"Windows\""} [[package]] name = "contourpy" @@ -240,6 +256,7 @@ version = "1.1.1" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"}, {file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"}, @@ -311,6 +328,7 @@ version = "0.12.1" description = "Composable style cycles" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, @@ -326,6 +344,8 @@ version = "0.1.8" description = "Tree is a library for working with nested data structures." optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "dm-tree-0.1.8.tar.gz", hash = "sha256:0fcaabbb14e7980377439e7140bd05552739ca5e515ecb3119f234acee4b9430"}, {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35cc164a79336bfcfafb47e5f297898359123bbd3330c1967f0c4994f9cf9f60"}, @@ -381,6 +401,8 @@ version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] +markers = "python_version <= \"3.10\"" files = [ {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, @@ -395,6 +417,7 @@ version = "3.13.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, @@ -403,7 +426,7 @@ files = [ [package.extras] docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] -typing = ["typing-extensions (>=4.8)"] +typing = ["typing-extensions (>=4.8) ; python_version < \"3.11\""] [[package]] name = "flatbuffers" @@ -411,6 +434,8 @@ version = "23.5.26" description = "The FlatBuffers serialization format for Python" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1"}, {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"}, @@ -422,6 +447,7 @@ version = "4.49.0" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d970ecca0aac90d399e458f0b7a8a597e08f95de021f17785fb68e2dc0b99717"}, {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac9a745b7609f489faa65e1dc842168c18530874a5f5b742ac3dd79e26bca8bc"}, @@ -468,18 +494,18 @@ files = [ ] [package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "pycairo", "scipy"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] repacker = ["uharfbuzz (>=0.23.0)"] symfont = ["sympy"] -type1 = ["xattr"] +type1 = ["xattr ; sys_platform == \"darwin\""] ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] +unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] [[package]] name = "fsspec" @@ -487,6 +513,7 @@ version = "2024.2.0" description = "File-system specification" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "fsspec-2024.2.0-py3-none-any.whl", hash = "sha256:817f969556fa5916bc682e02ca2045f96ff7f586d45110fcb76022063ad2c7d8"}, {file = "fsspec-2024.2.0.tar.gz", hash = "sha256:b6ad1a679f760dda52b1168c859d01b7b80648ea6f7f7c7f5a8a91dc3f3ecb84"}, @@ -522,6 +549,8 @@ version = "0.4.0" description = "Python AST that abstracts the underlying Python version" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "gast-0.4.0-py3-none-any.whl", hash = "sha256:b7adcdd5adbebf1adf17378da5ba3f543684dbec47b1cda1f3997e573cd542c4"}, {file = "gast-0.4.0.tar.gz", hash = "sha256:40feb7b8b8434785585ab224d1568b857edb18297e5a3047f1ba012bc83b42c1"}, @@ -533,6 +562,8 @@ version = "2.28.1" description = "Google Authentication Library" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "google-auth-2.28.1.tar.gz", hash = "sha256:34fc3046c257cedcf1622fc4b31fc2be7923d9b4d44973d481125ecc50d83885"}, {file = "google_auth-2.28.1-py2.py3-none-any.whl", hash = "sha256:25141e2d7a14bfcba945f5e9827f98092716e99482562f15306e5b026e21aa72"}, @@ -556,6 +587,8 @@ version = "1.0.0" description = "Google Authentication Library" optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "google-auth-oauthlib-1.0.0.tar.gz", hash = "sha256:e375064964820b47221a7e1b7ee1fd77051b6323c3f9e3e19785f78ab67ecfc5"}, {file = "google_auth_oauthlib-1.0.0-py2.py3-none-any.whl", hash = "sha256:95880ca704928c300f48194d1770cf5b1462835b6e49db61445a520f793fd5fb"}, @@ -574,6 +607,8 @@ version = "0.2.0" description = "pasta is an AST-based Python refactoring library" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "google-pasta-0.2.0.tar.gz", hash = "sha256:c9f2c8dfc8f96d0d5808299920721be30c9eec37f2389f28904f454565c8a16e"}, {file = "google_pasta-0.2.0-py2-none-any.whl", hash = "sha256:4612951da876b1a10fe3960d7226f0c7682cf901e16ac06e473b267a5afa8954"}, @@ -589,6 +624,8 @@ version = "1.62.0" description = "HTTP/2-based RPC framework" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "grpcio-1.62.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:136ffd79791b1eddda8d827b607a6285474ff8a1a5735c4947b58c481e5e4271"}, {file = "grpcio-1.62.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d6a56ba703be6b6267bf19423d888600c3f574ac7c2cc5e6220af90662a4d6b0"}, @@ -655,6 +692,8 @@ version = "3.10.0" description = "Read and write HDF5 files from Python" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "h5py-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b963fb772964fc1d1563c57e4e2e874022ce11f75ddc6df1a626f42bd49ab99f"}, {file = "h5py-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:012ab448590e3c4f5a8dd0f3533255bc57f80629bf7c5054cf4c87b30085063c"}, @@ -692,6 +731,8 @@ version = "0.7.1" description = "Machine learning in FPGAs using HLS" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "hls4ml-0.7.1-py3-none-any.whl", hash = "sha256:086c578c192908c12e1e579632faeb97635aeb0a31cd844ca8e7978cd0069df7"}, {file = "hls4ml-0.7.1.tar.gz", hash = "sha256:a2ef3754243987f0295c3c123207405e96834541373aed4e4a4369f002199097"}, @@ -717,6 +758,8 @@ version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = true python-versions = ">=3.5" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, @@ -728,6 +771,8 @@ version = "7.0.1" description = "Read metadata from Python packages" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\" and python_version <= \"3.9\"" files = [ {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, @@ -739,7 +784,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7) ; platform_python_implementation != \"PyPy\"", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\"", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "importlib-resources" @@ -747,6 +792,8 @@ version = "6.1.2" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.9\"" files = [ {file = "importlib_resources-6.1.2-py3-none-any.whl", hash = "sha256:9a0a862501dc38b68adebc82970140c9e4209fc99601782925178f8386339938"}, {file = "importlib_resources-6.1.2.tar.gz", hash = "sha256:308abf8474e2dba5f867d279237cd4076482c3de7104a40b41426370e891549b"}, @@ -757,7 +804,7 @@ zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy ; platform_python_implementation != \"PyPy\"", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -765,6 +812,7 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -776,6 +824,8 @@ version = "0.4.13" description = "Differentiate, compile, and transform Numpy code." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "jax-0.4.13.tar.gz", hash = "sha256:03bfe6749dfe647f16f15f6616638adae6c4a7ca7167c75c21961ecfd3a3baaa"}, ] @@ -806,6 +856,7 @@ version = "3.1.3" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, @@ -823,6 +874,7 @@ version = "1.3.2" description = "Lightweight pipelining with Python functions" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9"}, {file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1"}, @@ -834,6 +886,8 @@ version = "2.12.0" description = "Deep learning for humans." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "keras-2.12.0-py2.py3-none-any.whl", hash = "sha256:35c39534011e909645fb93515452e98e1a0ce23727b55d4918b9c58b2308c15e"}, ] @@ -844,6 +898,8 @@ version = "1.4.7" description = "A Hyperparameter Tuning Library for Keras" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "keras-tuner-1.4.7.tar.gz", hash = "sha256:6befd25ee81476e6207d8ca7ed7dc674b8194437cfa0b127294cd00da905ff22"}, {file = "keras_tuner-1.4.7-py3-none-any.whl", hash = "sha256:0bcf0220eccc74e7a6a9bd7c8e58531a1af8515019e6bc2dc495833155c07fe2"}, @@ -868,6 +924,7 @@ version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, @@ -981,6 +1038,8 @@ version = "1.0.5" description = "Legacy import names for Keras Tuner" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "kt-legacy-1.0.5.tar.gz", hash = "sha256:dbbade58f12c6a6da6062f4b045a6395a8d4195815e3e064bc3e609b69c8a26c"}, {file = "kt_legacy-1.0.5-py3-none-any.whl", hash = "sha256:8d5c5b3dccf348367fe9ca5b006e7ad2d1babcce62976cfc199e831ea699dcd3"}, @@ -992,6 +1051,8 @@ version = "16.0.6" description = "Clang Python Bindings, mirrored from the official LLVM repo: https://github.com/llvm/llvm-project/tree/main/clang/bindings/python, to make the installation process easier." optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "libclang-16.0.6-1-py2.py3-none-manylinux2014_aarch64.whl", hash = "sha256:88bc7e7b393c32e41e03ba77ef02fdd647da1f764c2cd028e69e0837080b79f6"}, {file = "libclang-16.0.6-1-py2.py3-none-manylinux2014_armv7l.whl", hash = "sha256:d80ed5827736ed5ec2bcedf536720476fd9d4fa4c79ef0cb24aea4c59332f361"}, @@ -1012,6 +1073,8 @@ version = "3.5.2" description = "Python implementation of John Gruber's Markdown." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "Markdown-3.5.2-py3-none-any.whl", hash = "sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd"}, {file = "Markdown-3.5.2.tar.gz", hash = "sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8"}, @@ -1030,6 +1093,7 @@ version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, @@ -1099,6 +1163,7 @@ version = "3.7.5" description = "Python plotting package" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:4a87b69cb1cb20943010f63feb0b2901c17a3b435f75349fd9865713bfa63925"}, {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d3ce45010fefb028359accebb852ca0c21bd77ec0f281952831d235228f15810"}, @@ -1167,6 +1232,8 @@ version = "0.2.0" description = "" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "ml_dtypes-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df6a76e1c8adf484feb138ed323f9f40a7b6c21788f120f7c78bec20ac37ee81"}, {file = "ml_dtypes-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc29a0524ef5e23a7fbb8d881bdecabeb3fc1d19d9db61785d077a86cb94fab2"}, @@ -1203,6 +1270,7 @@ version = "1.3.0" description = "Python library for arbitrary-precision floating-point arithmetic" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, @@ -1211,7 +1279,7 @@ files = [ [package.extras] develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] docs = ["sphinx"] -gmpy = ["gmpy2 (>=2.1.0a4)"] +gmpy = ["gmpy2 (>=2.1.0a4) ; platform_python_implementation != \"PyPy\""] tests = ["pytest (>=4.6)"] [[package]] @@ -1220,6 +1288,7 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" +groups = ["dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -1231,6 +1300,7 @@ version = "3.1" description = "Python package for creating and manipulating graphs and networks" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"}, {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"}, @@ -1249,6 +1319,7 @@ version = "1.23.5" description = "NumPy is the fundamental package for array computing with Python." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "numpy-1.23.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63"}, {file = "numpy-1.23.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d"}, @@ -1286,6 +1357,8 @@ version = "12.1.3.1" description = "CUBLAS native runtime libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728"}, {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906"}, @@ -1297,6 +1370,8 @@ version = "12.1.105" description = "CUDA profiling tools runtime libs." optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e"}, {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4"}, @@ -1308,6 +1383,8 @@ version = "12.1.105" description = "NVRTC native runtime libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2"}, {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed"}, @@ -1319,6 +1396,8 @@ version = "12.1.105" description = "CUDA Runtime native Libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40"}, {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344"}, @@ -1330,6 +1409,8 @@ version = "8.9.2.26" description = "cuDNN runtime libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl", hash = "sha256:5ccb288774fdfb07a7e7025ffec286971c06d8d7b4fb162525334616d7629ff9"}, ] @@ -1343,6 +1424,8 @@ version = "11.0.2.54" description = "CUFFT native runtime libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56"}, {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253"}, @@ -1354,6 +1437,8 @@ version = "10.3.2.106" description = "CURAND native runtime libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0"}, {file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a"}, @@ -1365,6 +1450,8 @@ version = "11.4.5.107" description = "CUDA solver native runtime libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd"}, {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5"}, @@ -1381,6 +1468,8 @@ version = "12.1.0.106" description = "CUSPARSE native runtime libraries" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c"}, {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a"}, @@ -1389,12 +1478,27 @@ files = [ [package.dependencies] nvidia-nvjitlink-cu12 = "*" +[[package]] +name = "nvidia-ml-py" +version = "12.575.51" +description = "Python Bindings for the NVIDIA Management Library" +optional = false +python-versions = "*" +groups = ["gpu"] +markers = "python_version > \"3.9\"" +files = [ + {file = "nvidia_ml_py-12.575.51-py3-none-any.whl", hash = "sha256:eb8641800d98ce40a22f479873f34b482e214a7e80349c63be51c3919845446e"}, + {file = "nvidia_ml_py-12.575.51.tar.gz", hash = "sha256:6490e93fea99eb4e966327ae18c6eec6256194c921f23459c8767aee28c54581"}, +] + [[package]] name = "nvidia-nccl-cu12" version = "2.19.3" description = "NVIDIA Collective Communication Library (NCCL) Runtime" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_nccl_cu12-2.19.3-py3-none-manylinux1_x86_64.whl", hash = "sha256:a9734707a2c96443331c1e48c717024aa6678a0e2a4cb66b2c364d18cee6b48d"}, ] @@ -1405,7 +1509,10 @@ version = "12.4.99" description = "Nvidia JIT LTO Library" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ + {file = "nvidia_nvjitlink_cu12-12.4.99-py3-none-manylinux2014_aarch64.whl", hash = "sha256:75d6498c96d9adb9435f2bbdbddb479805ddfb97b5c1b32395c694185c20ca57"}, {file = "nvidia_nvjitlink_cu12-12.4.99-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c6428836d20fe7e327191c175791d38570e10762edc588fb46749217cd444c74"}, {file = "nvidia_nvjitlink_cu12-12.4.99-py3-none-win_amd64.whl", hash = "sha256:991905ffa2144cb603d8ca7962d75c35334ae82bf92820b6ba78157277da1ad2"}, ] @@ -1416,6 +1523,8 @@ version = "12.1.105" description = "NVIDIA Tools Extension" optional = false python-versions = ">=3" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5"}, {file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82"}, @@ -1427,6 +1536,8 @@ version = "3.2.2" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, @@ -1443,6 +1554,8 @@ version = "1.15.0" description = "Open Neural Network Exchange" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "onnx-1.15.0-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:51cacb6aafba308aaf462252ced562111f6991cdc7bc57a6c554c3519453a8ff"}, {file = "onnx-1.15.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:0aee26b6f7f7da7e840de75ad9195a77a147d0662c94eaa6483be13ba468ffc1"}, @@ -1484,6 +1597,8 @@ version = "3.3.0" description = "Optimizing numpys einsum function" optional = true python-versions = ">=3.5" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"}, {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"}, @@ -1502,6 +1617,7 @@ version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, @@ -1513,6 +1629,8 @@ version = "1.6.5" description = "parse() is the opposite of format()" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "parse-1.6.5.tar.gz", hash = "sha256:c9545154ba6b0ede5b52c2877443a463dfc02f14fe43525d15255311939c3a72"}, ] @@ -1523,6 +1641,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -1534,6 +1653,7 @@ version = "10.2.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"}, {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"}, @@ -1610,7 +1730,7 @@ docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -typing = ["typing-extensions"] +typing = ["typing-extensions ; python_version < \"3.10\""] xmp = ["defusedxml"] [[package]] @@ -1619,6 +1739,7 @@ version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, @@ -1634,6 +1755,7 @@ version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, @@ -1649,6 +1771,8 @@ version = "3.11" description = "Python Lex & Yacc" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, @@ -1660,6 +1784,8 @@ version = "4.25.3" description = "" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, @@ -1674,12 +1800,50 @@ files = [ {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, ] +[[package]] +name = "psutil" +version = "7.0.0" +description = "Cross-platform lib for process and system monitoring in Python. NOTE: the syntax of this script MUST be kept compatible with Python 2.7." +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25"}, + {file = "psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da"}, + {file = "psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91"}, + {file = "psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34"}, + {file = "psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993"}, + {file = "psutil-7.0.0-cp36-cp36m-win32.whl", hash = "sha256:84df4eb63e16849689f76b1ffcb36db7b8de703d1bc1fe41773db487621b6c17"}, + {file = "psutil-7.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1e744154a6580bc968a0195fd25e80432d3afec619daf145b9e5ba16cc1d688e"}, + {file = "psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99"}, + {file = "psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553"}, + {file = "psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456"}, +] + +[package.extras] +dev = ["abi3audit", "black (==24.10.0)", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest", "pytest-cov", "pytest-xdist", "requests", "rstcheck", "ruff", "setuptools", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + +[[package]] +name = "py-cpuinfo" +version = "9.0.0" +description = "Get CPU info with pure Python" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690"}, + {file = "py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5"}, +] + [[package]] name = "pyasn1" version = "0.5.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "pyasn1-0.5.1-py2.py3-none-any.whl", hash = "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58"}, {file = "pyasn1-0.5.1.tar.gz", hash = "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c"}, @@ -1691,6 +1855,8 @@ version = "0.3.0" description = "A collection of ASN.1-based protocols modules" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"}, {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"}, @@ -1705,17 +1871,53 @@ version = "1.1" description = "Library for operations with VCD and other digital wave files" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "pyDigitalWaveTools-1.1-py3-none-any.whl", hash = "sha256:aa1c3b2447786afab3412baa4d86bb4d1df9723a8df7076a1d9976ebdda1874c"}, {file = "pyDigitalWaveTools-1.1.tar.gz", hash = "sha256:c7f0e06f7ed543a2f5f7110a4a8f2aae9e3ae328bb67ebd5b2a6db862efe7d33"}, ] +[[package]] +name = "pynvml" +version = "11.5.3" +description = "Python utilities for the NVIDIA Management Library" +optional = false +python-versions = ">=3.6" +groups = ["gpu"] +markers = "python_version <= \"3.9\"" +files = [ + {file = "pynvml-11.5.3-py3-none-any.whl", hash = "sha256:a5fba3ab14febda50d19dbda012ef62ae0aed45b7ccc07af0bc5be79223e450c"}, + {file = "pynvml-11.5.3.tar.gz", hash = "sha256:183d223ae487e5f00402d8da06c68c978ef8a9295793ee75559839c6ade7b229"}, +] + +[[package]] +name = "pynvml" +version = "12.0.0" +description = "Python utilities for the NVIDIA Management Library" +optional = false +python-versions = ">=3.9" +groups = ["gpu"] +markers = "python_version > \"3.9\"" +files = [ + {file = "pynvml-12.0.0-py3-none-any.whl", hash = "sha256:fdff84b62a27dbe98e08e1a647eb77342bef1aebe0878bcd15e99a83fcbecb9e"}, + {file = "pynvml-12.0.0.tar.gz", hash = "sha256:299ce2451a6a17e6822d6faee750103e25b415f06f59abb8db65d30f794166f5"}, +] + +[package.dependencies] +nvidia-ml-py = ">=12.0.0,<13.0.0a0" + +[package.extras] +test = ["pytest (>=3.6)", "pytest-cov", "pytest-runner"] + [[package]] name = "pyparser" version = "1.0" description = "pyparser is a collection of classes to make it easier to parse text data in a pythonic way." optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "pyparser-1.0.tar.gz", hash = "sha256:d1b76e2dabdd2952cadfd545229cc144afee6130bf171a031d5bf53f11b912f5"}, ] @@ -1729,6 +1931,7 @@ version = "3.1.2" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" +groups = ["main"] files = [ {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, @@ -1743,6 +1946,7 @@ version = "7.4.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, @@ -1759,12 +1963,31 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-mock" +version = "3.14.1" +description = "Thin-wrapper around the mock package for easier use with pytest" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0"}, + {file = "pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e"}, +] + +[package.dependencies] +pytest = ">=6.2.5" + +[package.extras] +dev = ["pre-commit", "pytest-asyncio", "tox"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -1779,6 +2002,8 @@ version = "6.0.1" description = "YAML parser and emitter for Python" optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, @@ -1839,6 +2064,8 @@ version = "0.9.0" description = "Quantization package for Keras" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "QKeras-0.9.0-py3-none-any.whl", hash = "sha256:087d9973725c285e4be69ba71b0aa92b5c5dab36c41ad8e8f1480b9a0d6397c8"}, {file = "QKeras-0.9.0.tar.gz", hash = "sha256:b30f751420fa9172e53bab59ed65275ff9ec4085124491f3f5c89b7563d00b2a"}, @@ -1861,6 +2088,8 @@ version = "2.31.0" description = "Python HTTP for Humans." optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, @@ -1882,6 +2111,8 @@ version = "1.3.1" description = "OAuthlib authentication support for Requests." optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, @@ -1900,6 +2131,8 @@ version = "4.9" description = "Pure-Python RSA implementation" optional = true python-versions = ">=3.6,<4" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -1914,6 +2147,7 @@ version = "1.3.2" description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "scikit-learn-1.3.2.tar.gz", hash = "sha256:a2f54c76accc15a34bfb9066e6c7a56c1e7235dda5762b990792330b52ccfb05"}, {file = "scikit_learn-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e326c0eb5cf4d6ba40f93776a20e9a7a69524c4db0757e7ce24ba222471ee8a1"}, @@ -1961,6 +2195,7 @@ version = "1.10.1" description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = "<3.12,>=3.8" +groups = ["main"] files = [ {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, @@ -1999,6 +2234,8 @@ version = "69.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, @@ -2006,7 +2243,7 @@ files = [ [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov ; platform_python_implementation != \"PyPy\"", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\"", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -2015,6 +2252,7 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["main"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -2026,6 +2264,7 @@ version = "1.12" description = "Computer algebra system (CAS) in Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, @@ -2040,6 +2279,8 @@ version = "0.9.0" description = "Pretty-print tabular data" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, @@ -2054,6 +2295,8 @@ version = "2.12.3" description = "TensorBoard lets you watch Tensors Flow" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "tensorboard-2.12.3-py3-none-any.whl", hash = "sha256:b4a69366784bc347e02fbe7d847e01896a649ca52f8948a11005e205dcf724fb"}, ] @@ -2078,6 +2321,8 @@ version = "0.7.2" description = "Fast data loading for TensorBoard" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "tensorboard_data_server-0.7.2-py3-none-any.whl", hash = "sha256:7e0610d205889588983836ec05dc098e80f97b7e7bbff7e994ebb78f578d0ddb"}, {file = "tensorboard_data_server-0.7.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:9fe5d24221b29625dbc7328b0436ca7fc1c23de4acf4d272f1180856e32f9f60"}, @@ -2090,6 +2335,8 @@ version = "2.12.0" description = "TensorFlow is an open source machine learning framework for everyone." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "tensorflow-2.12.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:be4ac0dfcc7a16f6df2bc19bd322e312235ab3f7b0c7297f96c92c44bb14d2a1"}, {file = "tensorflow-2.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5193ddb3bb5120cb445279beb08ed9e74a85a4eeb2485550d6fb707a89d9a88"}, @@ -2139,6 +2386,8 @@ version = "2.12.0" description = "TensorFlow Estimator." optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "tensorflow_estimator-2.12.0-py2.py3-none-any.whl", hash = "sha256:59b191bead4883822de3d63ac02ace11a83bfe6c10d64d0c4dfde75a50e60ca1"}, ] @@ -2149,6 +2398,8 @@ version = "0.36.0" description = "TensorFlow IO" optional = true python-versions = ">=3.7, <3.12" +groups = ["main"] +markers = "(platform_machine != \"arm64\" or platform_system != \"Darwin\") and extra == \"hls4ml\"" files = [ {file = "tensorflow_io_gcs_filesystem-0.36.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:702c6df62b38095ff613c433546d9424d4f33902a5ab26b00fd26457e27a99fa"}, {file = "tensorflow_io_gcs_filesystem-0.36.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e9b8aaca2789af356c42afda0f52380f82e5abb2f3c0b85087833fcfe03875d8"}, @@ -2178,6 +2429,8 @@ version = "0.8.0" description = "A suite of tools that users, both novice and advanced can use to optimize machine learning models for deployment and execution." optional = true python-versions = ">=3" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "tensorflow_model_optimization-0.8.0-py2.py3-none-any.whl", hash = "sha256:50303e6ed6d07c1a7801215f5cc854dad388ea8de319e46746ca35789e4ee7b3"}, ] @@ -2194,6 +2447,8 @@ version = "2.4.0" description = "ANSI color formatting for output in terminal" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, {file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"}, @@ -2208,6 +2463,7 @@ version = "3.3.0" description = "threadpoolctl" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "threadpoolctl-3.3.0-py3-none-any.whl", hash = "sha256:6155be1f4a39f31a18ea70f94a77e0ccd57dced08122ea61109e7da89883781e"}, {file = "threadpoolctl-3.3.0.tar.gz", hash = "sha256:5dac632b4fa2d43f42130267929af3ba01399ef4bd1882918e92dbc30365d30c"}, @@ -2219,6 +2475,8 @@ version = "2.0.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] +markers = "python_version <= \"3.10\"" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, @@ -2230,6 +2488,7 @@ version = "2.2.1" description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "torch-2.2.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:8d3bad336dd2c93c6bcb3268e8e9876185bda50ebde325ef211fb565c7d15273"}, {file = "torch-2.2.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:5297f13370fdaca05959134b26a06a7f232ae254bf2e11a50eddec62525c9006"}, @@ -2288,6 +2547,7 @@ version = "4.66.2" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, @@ -2308,6 +2568,8 @@ version = "2.2.0" description = "A language and compiler for custom Deep Learning operations" optional = false python-versions = "*" +groups = ["main"] +markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" files = [ {file = "triton-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2294514340cfe4e8f4f9e5c66c702744c4a117d25e618bd08469d0bfed1e2e5"}, {file = "triton-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da58a152bddb62cafa9a857dd2bc1f886dbf9f9c90a2b5da82157cd2b34392b0"}, @@ -2331,10 +2593,12 @@ version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] +markers = {dev = "python_version <= \"3.10\""} [[package]] name = "urllib3" @@ -2342,13 +2606,15 @@ version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -2359,6 +2625,8 @@ version = "3.0.1" description = "The comprehensive WSGI web application library." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"}, {file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"}, @@ -2376,6 +2644,8 @@ version = "0.42.0" description = "A built-package format for Python" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "wheel-0.42.0-py3-none-any.whl", hash = "sha256:177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d"}, {file = "wheel-0.42.0.tar.gz", hash = "sha256:c45be39f7882c9d34243236f2d63cbd58039e360f85d0913425fbd7ceea617a8"}, @@ -2390,6 +2660,8 @@ version = "1.14.1" description = "Module for decorators, wrappers and monkey patching." optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +groups = ["main"] +markers = "extra == \"hls4ml\"" files = [ {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, @@ -2473,6 +2745,8 @@ version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.9\"" files = [ {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, @@ -2480,12 +2754,12 @@ files = [ [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7) ; platform_python_implementation != \"PyPy\"", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\"", "pytest-ruff"] [extras] hls4ml = ["hls4ml", "tensorflow"] [metadata] -lock-version = "2.0" +lock-version = "2.1" python-versions = ">=3.8, <3.11.10" -content-hash = "0b0cf4871b8e171e15c6001e9f68266ef3585ecf750d1aee374b68f94ee3cf72" +content-hash = "d92bcb1cf70c320cf057901aa97b8e11cda81b1c4bd60d3d561c455a20429007" diff --git a/pyproject.toml b/pyproject.toml index 193d2759..2553ff10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,9 @@ scikit-learn = "^1.2.0" hls4ml = { version = "^0.7.1", optional = true } tensorflow = { version = "^2.12.0", optional = true } numpy = "1.23.5" +py-cpuinfo = "^9.0.0" +psutil = "^7.0.0" +pytest-mock = "^3.14.1" [tool.poetry.group.dev.dependencies] pytest = "^7.2.1" @@ -28,3 +31,9 @@ hls4ml = [ "hls4ml", "tensorflow" ] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.poetry.group.gpu] +optional = true + +[tool.poetry.group.gpu.dependencies] +pynvml = ">=11.0.0" # This adds pynvml to the 'gpu' group \ No newline at end of file diff --git a/tests/test_data_processing.py b/tests/test_data_processing.py index 1cfc479e..d1f3d3ce 100644 --- a/tests/test_data_processing.py +++ b/tests/test_data_processing.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/test_green_code.py b/tests/test_green_code.py new file mode 100644 index 00000000..b30e0872 --- /dev/null +++ b/tests/test_green_code.py @@ -0,0 +1,111 @@ +import os +import csv +import time +from unittest.mock import MagicMock, patch +import pytest +from baler.modules.green_code import GreenCodeTracker + +@pytest.fixture +def mock_specs(): + """A fixture to provide a consistent, fake set of system specs.""" + return { + "CPUmodel": "Fake CPU v1", + "Number of CPU cores": 8, + "GPU model": "Fake GPU v1", + "Number of GPU cores": 1024, + "Memory available (GB)": 16.0, + } + +class TestGreenCodeTracker: + """Group of tests for the GreenCodeTracker class.""" + + def test_init_creates_file_and_header(self, tmp_path, mock_specs, mocker): + """ + Test that the constructor creates a CSV file with the correct header. + We mock _get_system_specs to isolate the test from the hardware. + """ + mocker.patch.object(GreenCodeTracker, '_get_system_specs', return_value=mock_specs) + test_file = tmp_path / "green_code_tracking_test.csv" + tracker = GreenCodeTracker(file_path=str(test_file)) + + + assert os.path.exists(test_file) + with open(test_file, 'r') as f: + reader = csv.reader(f) + header = next(reader) + assert header == tracker.headers + + def test_track_method_writes_correct_row(self, tmp_path, mock_specs, mocker): + """Test that the track() method appends a correctly formatted row.""" + mocker.patch.object(GreenCodeTracker, '_get_system_specs', return_value=mock_specs) + test_file = tmp_path / "green_code_tracking_test.csv" + tracker = GreenCodeTracker(file_path=str(test_file)) + + tracker.track(start=100.0, end=102.5, title="Test Task") + + with open(tracker.file_name, 'r') as f: + reader = list(csv.DictReader(f)) + assert len(reader) == 1 + row = reader[0] + assert row["Title"] == "Test Task" + assert row["Runtime(format HH:MM:SS)"] == "00:00:02" + assert row["CPUmodel"] == "Fake CPU v1" + assert row["GPU model"] == "Fake GPU v1" + + def test_time_context_manager(self, tmp_path, mock_specs, mocker): + """Test that the time() context manager works as expected.""" + mocker.patch.object(GreenCodeTracker, '_get_system_specs', return_value=mock_specs) + test_file = tmp_path / "green_code_tracking_test.csv" + tracker = GreenCodeTracker(file_path=str(test_file)) + + with tracker.time("Context Task"): + time.sleep(0.01) + + with open(tracker.file_name, 'r') as f: + reader = list(csv.DictReader(f)) + assert len(reader) == 1 + assert reader[0]["Title"] == "Context Task" + assert reader[0]["Runtime(format HH:MM:SS)"] == "00:00:00" + + def test_get_system_specs_with_gpu(self, tmp_path, mocker): + """Test spec gathering on a mocked system WITH an NVIDIA GPU.""" + # Mock all external calls + mocker.patch('cpuinfo.get_cpu_info', return_value={'brand_raw': 'Mocked Intel CPU'}) + mocker.patch('psutil.cpu_count', return_value=12) + mocker.patch('psutil.virtual_memory', return_value=MagicMock(total=32 * 1024**3)) + + # Mock pynvml to simulate a detected GPU + mock_pynvml = MagicMock() + mock_pynvml.nvmlDeviceGetCount.return_value = 1 + mock_pynvml.nvmlDeviceGetHandleByIndex.return_value = "handle_0" + mock_pynvml.nvmlDeviceGetName.return_value = "Mocked NVIDIA GPU" + mock_pynvml.nvmlDeviceGetMultiProcessorCount.return_value = 40 + mocker.patch('baler.modules.green_code.pynvml', mock_pynvml, create=True) + mocker.patch('baler.modules.green_code.NVIDIA_SMI_AVAILABLE', True) + + test_file = tmp_path / "green_code_tracking_test.csv" + tracker = GreenCodeTracker(file_path=str(test_file)) + specs = tracker._get_system_specs() + + assert specs["CPUmodel"] == "Mocked Intel CPU" + assert specs["Number of CPU cores"] == 12 + assert specs["GPU model"] == "Mocked NVIDIA GPU" + assert specs["Number of GPU cores"] == 40 + assert specs["Memory available (GB)"] == 32.0 + + def test_get_system_specs_without_gpu(self, tmp_path, mocker): + """Test spec gathering on a mocked system WITHOUT an NVIDIA GPU.""" + mocker.patch('cpuinfo.get_cpu_info', return_value={'brand_raw': 'Mocked AMD CPU'}) + mocker.patch('psutil.cpu_count', return_value=4) + mocker.patch('psutil.virtual_memory', return_value=MagicMock(total=8 * 1024**3)) + + # Simulate pynvml not being available + mocker.patch('baler.modules.green_code.NVIDIA_SMI_AVAILABLE', False) + + test_file = tmp_path / "green_code_tracking_test.csv" + tracker = GreenCodeTracker(file_path=str(test_file)) + specs = tracker._get_system_specs() + + assert specs["GPU model"] == "N/A" + assert specs["Number of GPU cores"] == "N/A" + assert specs["CPUmodel"] == "Mocked AMD CPU" \ No newline at end of file diff --git a/tests/test_helper.py b/tests/test_helper.py index 44023099..9b1bdc55 100644 --- a/tests/test_helper.py +++ b/tests/test_helper.py @@ -1,4 +1,4 @@ -# Copyright 2022 Baler Contributors +# Copyright 2022-2025 Baler Contributors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -49,3 +49,11 @@ def test_create_new_project(): # Clean up after the test shutil.rmtree(base_path) + +def test_helper_setup_tracker(mocker): + """Test that the helper function correctly initializes the tracker.""" + mock_tracker_class = mocker.patch('baler.modules.green_code.GreenCodeTracker') + + helper.setup_green_tracker() + + mock_tracker_class.assert_called_once_with() \ No newline at end of file