diff --git a/.clang-tidy b/.clang-tidy index 4ba1f835..24e964dd 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -2,7 +2,6 @@ Checks: 'clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*,bugprone-*,-bugprone-macro-parentheses,bugprone-narrowing-conversions,-bugprone-easily-swappable-parameters,performance-*,portability-*,security-*,moderize*,-clang-analyzer-optin.portability.UnixAPI,-clang-analyzer-optin.mpi.MPI-Checker' WarningsAsErrors: '' HeaderFilterRegex: '(\./include.*)|(.*pressio.*)' -AnalyzeTemporaryDtors: false FormatStyle: none User: runderwood CheckOptions: diff --git a/.dagger/.gitattributes b/.dagger/.gitattributes new file mode 100644 index 00000000..82741846 --- /dev/null +++ b/.dagger/.gitattributes @@ -0,0 +1 @@ +/sdk/** linguist-generated diff --git a/.dagger/.gitignore b/.dagger/.gitignore new file mode 100644 index 00000000..2343dfc8 --- /dev/null +++ b/.dagger/.gitignore @@ -0,0 +1,4 @@ +/.venv +/**/__pycache__ +/sdk +/.env diff --git a/.dagger/pyproject.toml b/.dagger/pyproject.toml new file mode 100644 index 00000000..525a8edc --- /dev/null +++ b/.dagger/pyproject.toml @@ -0,0 +1,17 @@ +[project] +name = "libpressio" +version = "0.1.0" +requires-python = ">=3.13" +dependencies = [ + "dagger-io", + "pandas>=2.3.3", + "pandas-stubs>=2.3.2.250926", + "rich>=14.2.0", +] + +[build-system] +requires = ["uv_build>=0.8.4,<0.9.0"] +build-backend = "uv_build" + +[tool.uv.sources] +dagger-io = { path = "sdk", editable = true } diff --git a/.dagger/src/libpressio/__init__.py b/.dagger/src/libpressio/__init__.py new file mode 100644 index 00000000..8e476bbd --- /dev/null +++ b/.dagger/src/libpressio/__init__.py @@ -0,0 +1,16 @@ +"""A generated module for Libpressio functions + +This module has been generated via dagger init and serves as a reference to +basic module structure as you get started with Dagger. + +Two functions have been pre-created. You can modify, delete, or add to them, +as needed. They demonstrate usage of arguments and return types using simple +echo and grep commands. The functions can be called from the dagger CLI or +from one of the SDKs. + +The first line in this comment block is a short description line and the +rest is a long description with more detail on the module's purpose or usage, +if appropriate. All modules should have a short description. +""" + +from .main import Libpressio as Libpressio diff --git a/.dagger/src/libpressio/main.py b/.dagger/src/libpressio/main.py new file mode 100644 index 00000000..fe60cf33 --- /dev/null +++ b/.dagger/src/libpressio/main.py @@ -0,0 +1,462 @@ +import asyncio +import os +import typing as t +import pandas as pd +import dagger +import xml.etree.ElementTree as ET +from rich.console import Console +from rich.table import Table +from collections import abc +from dagger import dag, function, object_type, Doc, DefaultPath, ReturnType +from contextlib import asynccontextmanager +from opentelemetry import trace +tracer = trace.get_tracer("dagger.io/util/parallel") + +# SUPPORTED VERSIONS +UBUNTU = ["ubuntu:24.04", "ubuntu:26.04"] +FEDORA = ["fedora:43", "fedora:44"] +CENTOS = ["almalinux:9", "almalinux:10"] +PYTHON_VERSIONS = ["python3.14", "python3.13", "python3.12", "python3.11"] + +#DEFAULT VERSIONS +DEFAULT_BUILD_TYPE = "Release" +DEFAULT_UBUNTU = UBUNTU[-1] +DEFAULT_FEDORA = FEDORA[-1] +DEFAULT_CENTOS = CENTOS[-1] + +class ParallelTaskContext: + def __init__(self, max_width: int|None = None): + self.pending: set[asyncio.Task[t.Any]] = set() + self.running : set[asyncio.Task[t.Any]]= set() + self.completed : list[asyncio.Task[t.Any]]= [] + self.max_width: int|None = max_width + + def create_job[T](self, name :str, coro: abc.Coroutine[None, None, T]) -> asyncio.Task[T]: + with tracer.start_as_current_span(name): + task = asyncio.Task(coro) + self.pending.add(task) + return task + async def run(self): + if self.max_width is None: + self.running = self.pending.copy() + self.pending.clear() + else: + for _ in range(self.max_width): + try: + self.running.add(self.pending.pop()) + except IndexError: + break + while len(self.pending) > 0: + done, self.running = await asyncio.wait(self.running, return_when=asyncio.FIRST_COMPLETED) + for d in done: + try: + await d.result() + except: + pass + if len(self.pending) > 0: + for _ in range(t.cast(int,self.max_width) - len(self.running)): + try: + self.running.add(self.pending.pop()) + except IndexError: + break + while len(self.running) > 0: + done, self.running = await asyncio.wait(self.running, return_when=asyncio.FIRST_COMPLETED) + for d in done: + try: + await d.result() + except: + pass + +@asynccontextmanager +async def ParallelTasks(max_width: int|None = None): + tc = ParallelTaskContext(max_width) + yield tc + await tc.run() + + +def format_table(df: pd.DataFrame): + df = df[["version", "classname", "output", "passed"]] + failures = df[df.passed != True] + if len(failures) > 0: + table = Table(title="test failures") + table.add_column("index") + for col in failures.columns: + table.add_column(col) + row : tuple[str] + for row in failures.itertuples(name=None): + table.add_row(*[str(r) for r in row]) + console = Console(width=120) + with console.capture() as capture: + console.print(table) + return capture.get() + else: + return f"All {len(df)} Tests Passed!" + + +@object_type +class Libpressio: + + async def manylinux_base_alma(self, image: str = "quay.io/pypa/manylinux_2_28_x86_64") -> dagger.Container: + dnf_cache = dag.cache_volume(f"manylinux-dnf-{image}") + ccache = dag.cache_volume(f"manylinux-ccache-{image}") + return ( + dag.container() + .from_(image) + .with_mounted_cache("/var/cache/dnf", dnf_cache, sharing=dagger.CacheSharingMode.LOCKED) + .with_mounted_cache("/var/ccache/cache", ccache, sharing=dagger.CacheSharingMode.LOCKED) + .with_exec( + [ + "dnf", + "install", + "-y", + "boost-devel", + "ccache", + ] + ) + ) + + @function + async def export_docs(self, src: t.Annotated[dagger.Directory, Doc("Source Directory"), DefaultPath("/")], build_jobs: int = -1) -> dagger.Directory: + """export the documentation""" + return (await self.build_docs(src, build_jobs)).directory("/build/html") + + @function + async def build_docs(self, src: t.Annotated[dagger.Directory, Doc("Source Directory"), DefaultPath("/")], build_jobs: int = -1) -> dagger.Container: + """build a container capable of building the documentation""" + base = ((await self.fedora_base(DEFAULT_FEDORA)) + .with_exec( [ "dnf", "install", "-y", "doxygen", "graphviz" ]) + ) + return await self.common_build(base , src=src, tests=False, build_jobs=build_jobs, build_type="Debug", + extra_cmake=["-DBUILD_DOCS=ON"], extra_build=["docs"]) + + @function + async def manylinux_all(self, src: t.Annotated[dagger.Directory, Doc("Source Directory"), DefaultPath("/")], image: str = "quay.io/pypa/manylinux_2_28_x86_64", build_jobs: int = -1, build_type:str="Release"): + """build all wheels for all supported python versions""" + try: + n_jobs = len(os.sched_getaffinity(0)) + n_tasks = len(PYTHON_VERSIONS) + async with ParallelTasks() as tg: + for py_version in PYTHON_VERSIONS: + tg.create_job(py_version, self.manylinux(src, image=image, build_jobs=n_jobs//n_tasks, build_type=build_type, python_version=py_version)) + except* asyncio.CancelledError: + pass + + + + @function + async def manylinux(self, src: t.Annotated[dagger.Directory, Doc("Source Directory"), DefaultPath("/")], image: str = "quay.io/pypa/manylinux_2_28_x86_64", build_jobs: int = -1, build_type:str="Release", python_version: str = "python3.14") -> dagger.Container: + """build all wheels for the specified python version""" + has_ccache=True + container = await self.manylinux_base_alma(image) + stdcompat = dag.git("https://github.com/robertu94/std_compat").ref("master").tree() + is_static = True + generator = "Unix Makefiles" + build_cmd = "make" + build_jobs = len(os.sched_getaffinity(0)) if build_jobs == -1 else build_jobs + r = ( + container.with_directory("/deps/stdcompat", stdcompat) + .with_workdir("/deps/stdcompat") + .with_exec(["mkdir", "/deps/stdcompat/build/"]) + .with_exec( + [ + "cmake", + "-S/deps/stdcompat", + "-B/deps/stdcompat/build/", + "-G", + generator, + *(["-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", + "-DCMAKE_C_COMPILER_LAUNCHER=ccache"] if has_ccache else []), + "-DBUILD_TESTING=OFF", + f"-DCMAKE_BUILD_TYPE={build_type}", + f"-DBUILD_SHARED_LIBS={is_static}", + f"-DSTDCOMPAT_CXX_VERSION=20", + ] + ) + .with_exec([build_cmd, "-C", "/deps/stdcompat/build/", "-j", str(build_jobs)]) + .with_exec(["cmake", "--install", "/deps/stdcompat/build/"]) + .with_directory("/src/", src) + .with_workdir("/src/") + .with_exec([python_version, "-m", "build", "."]) + .with_env_variable("LD_LIBRARY_PATH", "/usr/local/lib64:${LD_LIBRARY_PATH}", expand=True) + .with_exec(["sh", "-c", "auditwheel repair dist/*.whl",]) + ) + return r + + async def ubuntu_base(self, image: str = "ubuntu:24.04") -> dagger.Container: + apt_cache = dag.cache_volume(f"apt-{image}") + ccache = dag.cache_volume(f"ccache-{image}") + return ( + dag.container() + .from_(image) + .with_exec(["rm", "/etc/apt/apt.conf.d/docker-clean"]) + .with_mounted_cache("/var/apt/cache", apt_cache) + .with_mounted_cache("/var/ccache/cache", ccache) + .with_env_variable("CCACHE_DIR", "/var/ccache/cache") + .with_exec(["apt-get", "update", "-y"]) + .with_env_variable("DEBIAN_FRONTEND", "noninteractive") + .with_exec( + [ + "apt-get", + "install", + "-y", + "cmake", + "gcc", + "g++", + "ninja-build", + "ccache", + "git", + "pkg-config", + ] + ) + .without_env_variable("DEBIAN_FRONTEND") + ) + + + async def centos_base(self, image: str = "almalinux:9", powertools_repo: str="powertools") -> dagger.Container: + """Build a CentOS style container base image""" + dnf_cache = dag.cache_volume(f"centos-dnf-{image}") + ccache = dag.cache_volume(f"centos-ccache-{image}") + return ( + dag.container() + .from_(image) + .with_mounted_cache("/var/cache/dnf", dnf_cache, sharing=dagger.CacheSharingMode.LOCKED) + .with_mounted_cache("/var/ccache/cache", ccache, sharing=dagger.CacheSharingMode.LOCKED) + .with_env_variable("CCACHE_DIR", "/var/ccache/cache") + .with_exec( + [ + "dnf", + "install", + "-y", + "dnf-plugins-core", + ] + ) + .with_exec( + [ + "dnf", + "install", + "-y", + "epel-release", + ] + ) + .with_exec( + [ + "dnf", + "config-manager", + "--set-enabled", + powertools_repo, + ] + ) + .with_exec( + [ + "dnf", + "install", + "-y", + "cmake", + "gcc", + "gcc-c++", + "ninja-build", + "boost-devel", + "ccache", + "git", + "pkg-config", + ] + ) + ) + async def fedora_base(self, image: str = "fedora:42"): + """Build a Fedora style container base image""" + dnf_cache = dag.cache_volume(f"fedora-dnf-{image}") + ccache = dag.cache_volume(f"fedora-ccache-{image}") + return ( + dag.container() + .from_(image) + .with_mounted_cache("/var/cache/dnf", dnf_cache, sharing=dagger.CacheSharingMode.LOCKED) + .with_mounted_cache("/var/ccache/cache", ccache, sharing=dagger.CacheSharingMode.LOCKED) + .with_env_variable("CCACHE_DIR", "/var/ccache/cache") + .with_exec( + [ + "dnf", + "install", + "-y", + "cmake", + "gcc", + "g++", + "ninja-build", + "ccache", + "git", + "pkg-config", + ] + ) + ) + async def common_test(self, container: dagger.Container, name: str, filter_rgx: str|None =None) -> pd.DataFrame: + args = ["ctest", "--output-on-failure", "--output-junit", "/junit"] + if filter_rgx is not None: + args.extend(["-R",filter_rgx]) + r = await container.with_exec(args, expect=ReturnType.ANY) + junit_xml = await r.file("/junit").contents() + tree = ET.ElementTree(ET.fromstring(junit_xml)) + root = tree.getroot() + if root is None: + return pd.DataFrame() + rows: list[dict[str, t.Any]] = [] + for testcase in root.iter("testcase"): + skipped = False + skip_elm = testcase.find("skipped") + if skip_elm is not None: + skipped = skip_elm.attrib.get("message", "unknown") + passed = True + failed = False + fail_elm = testcase.find("failure") + if fail_elm is not None: + passed = False + failed = fail_elm.attrib.get("message", "unknown") + rows.append({ + "version" : name, + "casename" : testcase.attrib.get("name"), + "classname" : testcase.attrib.get("classname"), + "time" : float(testcase.attrib.get("time", 0.0)), + "output" : testcase.findtext("system-out", ""), + "passed" : passed, + "failed" : failed, + "skipped" : skipped, + }) + + df = pd.DataFrame(rows) + return df + + + async def common_build(self, container: dagger.Container, src: t.Annotated[dagger.Directory, Doc("source directory")], static_build: bool = False, generator: str = "Ninja", + has_ccache: bool = True, tests: bool = False, build_jobs:int= -1, build_type:str="Release", extra_cmake: list[str]|None = None, + extra_build: list[str]|None = None + ) -> dagger.Container: + extra_cmake = extra_cmake or [] + extra_build = extra_build or [] + build_cmd = { + "Ninja": "ninja", + "Unix Makefiles": "make" + }[generator] + is_static = "OFF" if static_build else "ON" + build_tests = "ON" if tests else "OFF" + build_jobs = len(os.sched_getaffinity(0)) if build_jobs == -1 else build_jobs + stdcompat = dag.git("https://github.com/robertu94/std_compat").ref("master").tree() + r = ( + container.with_directory("/deps/stdcompat", stdcompat) + .with_workdir("/deps/stdcompat") + .with_exec(["mkdir", "/deps/stdcompat/build/"]) + .with_exec( + [ + "cmake", + "-S/deps/stdcompat", + "-B/deps/stdcompat/build/", + "-G", + generator, + *(["-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", + "-DCMAKE_C_COMPILER_LAUNCHER=ccache"] if has_ccache else []), + "-DBUILD_TESTING=OFF", + f"-DCMAKE_BUILD_TYPE={build_type}", + f"-DBUILD_SHARED_LIBS={is_static}", + ] + ) + .with_exec([build_cmd, "-C", "/deps/stdcompat/build/", "-j", str(build_jobs)]) + .with_exec(["cmake", "--install", "/deps/stdcompat/build/"]) + .with_directory("/src/", src) + .with_workdir("/src/") + .with_exec(["mkdir", "/build"]) + .with_exec( + [ + "cmake", + "-S/src", + "-B/build/", + "-G", + generator, + *(["-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", + "-DCMAKE_C_COMPILER_LAUNCHER=ccache"] if has_ccache else []), + f"-DBUILD_TESTING={build_tests}", + f"-DCMAKE_BUILD_TYPE={build_type}", + f"-DBUILD_SHARED_LIBS={is_static}", + *extra_cmake + ] + ) + .with_exec( + [ + build_cmd, + "-C", + "/build/", + "-j", + str(build_jobs), + *extra_build + ] + ) + .with_workdir("/build/") + ) + return r + + @function + async def build_centos(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version:str= DEFAULT_CENTOS, tests: bool = False, build_jobs:int = -1, build_type:str=DEFAULT_BUILD_TYPE) -> dagger.Container: + "build a CentOS container with libpressio" + if int(version.split(":")[1]) <= 8: + return await self.common_build(await self.centos_base(version), src=src, tests=tests, build_jobs=build_jobs, build_type=build_type) + else: + return await self.common_build(await self.centos_base(version, powertools_repo="crb"), src=src, tests=tests, build_jobs=build_jobs, build_type=build_type) + + @function + async def build_ubuntu(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version: str=DEFAULT_UBUNTU, tests:bool=False, build_jobs:int = -1, build_type:str=DEFAULT_BUILD_TYPE) -> dagger.Container: + "build a Ubuntu container with libpressio" + return await self.common_build(await self.ubuntu_base(version), src=src, tests=tests, build_jobs=build_jobs, build_type=build_type) + + @function + async def build_fedora(self, src: t.Annotated[dagger.Directory, DefaultPath("/")],version: str = DEFAULT_FEDORA, tests:bool = False, build_jobs: int = -1, build_type:str=DEFAULT_BUILD_TYPE) -> dagger.Container: + "build a Fedora container with libpressio" + return await self.common_build(await self.fedora_base(version), src=src, tests=tests, build_jobs=build_jobs, build_type=build_type) + + + async def test_centos_df(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version: str=DEFAULT_CENTOS, build_jobs: int = -1, filter_rgx: str|None = None, build_type:str=DEFAULT_BUILD_TYPE) -> pd.DataFrame: + "run tests on a CentOS container" + return await self.common_test(await self.build_centos(src, version, tests=True, build_jobs=build_jobs, build_type=build_type), version, filter_rgx=filter_rgx) + + + @function + async def test_centos(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version: str=DEFAULT_CENTOS, build_jobs: int = -1, filter_rgx: str|None = None, build_type:str=DEFAULT_BUILD_TYPE) -> str: + "run tests on a CentOS container" + return format_table(await self.test_centos_df(src, version, build_jobs, filter_rgx=filter_rgx, build_type=build_type)) + + async def test_fedora_df(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version: str = DEFAULT_FEDORA, build_jobs: int = -1, filter_rgx: str|None = None, build_type:str=DEFAULT_BUILD_TYPE) -> pd.DataFrame: + "run tests on a Fedora container" + return await self.common_test(await self.build_fedora(src, version, tests=True, build_jobs=build_jobs, build_type=build_type), version, filter_rgx=filter_rgx) + + @function + async def test_fedora(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version: str = DEFAULT_FEDORA, build_jobs: int = -1, filter_rgx: str|None = None, build_type:str=DEFAULT_BUILD_TYPE) -> str: + "run tests on a Fedora container" + return format_table(await self.test_fedora_df(src, version, build_jobs, filter_rgx=filter_rgx, build_type=build_type)) + + async def test_ubuntu_df(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version: str= DEFAULT_UBUNTU, build_jobs: int = -1, filter_rgx: str|None = None, build_type:str=DEFAULT_BUILD_TYPE) -> pd.DataFrame: + "run tests on a Ubuntu container" + return await self.common_test(await self.build_ubuntu(src, version, tests=True, build_jobs=build_jobs, build_type=build_type), version, filter_rgx=filter_rgx) + + @function + async def test_ubuntu(self, src: t.Annotated[dagger.Directory, DefaultPath("/")], version: str= DEFAULT_UBUNTU, build_jobs: int = -1, filter_rgx: str|None = None, build_type:str=DEFAULT_BUILD_TYPE) -> str: + "run tests on a Ubuntu container" + return format_table(await self.test_ubuntu_df(src, version, build_jobs, filter_rgx=filter_rgx, build_type=build_type)) + + @function + async def test_all(self, src: t.Annotated[dagger.Directory, DefaultPath("/")]) -> str: + """run all tests""" + results: list[asyncio.Task[pd.DataFrame]] = [] + try: + n_jobs = len(os.sched_getaffinity(0)) + n_tasks = len(CENTOS) + len(FEDORA) + len(UBUNTU) + async with ParallelTasks() as tg: + for version in CENTOS: + results.append(tg.create_job(f"test {version}", self.test_centos_df(src,version, build_jobs=n_jobs//n_tasks))) + for version in FEDORA: + results.append(tg.create_job(f"test {version}", self.test_fedora_df(src,version, build_jobs=n_jobs//n_tasks))) + for version in UBUNTU: + results.append(tg.create_job(f"test {version}", self.test_ubuntu_df(src,version, build_jobs=n_jobs//n_tasks))) + except* asyncio.CancelledError: + pass + return format_table(pd.concat(r.result() for r in results)) + + + @function + async def play_fifo(self, svc: dagger.Service) -> dagger.Container: + return await dag.container().from_("fedora:42").with_service_binding("svc", svc) + diff --git a/.dagger/uv.lock b/.dagger/uv.lock new file mode 100644 index 00000000..cbeea0d8 --- /dev/null +++ b/.dagger/uv.lock @@ -0,0 +1,937 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[package]] +name = "anyio" +version = "4.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, +] + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "backoff" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/d7/5bbeb12c44d7c4f2fb5b56abce497eb5ed9f34d85701de869acedd602619/backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", size = 17001, upload-time = "2022-10-05T19:19:32.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" }, +] + +[[package]] +name = "beartype" +version = "0.22.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/51/97f0d11d613d3b9650bd75588ff5206a408afcdc337ab7108dafb4c8d1ec/beartype-0.22.3.tar.gz", hash = "sha256:391c457bd6463d6fb0ec5d7e28ad44c336ae02dbaaae0fc55c053b071554855b", size = 1571548, upload-time = "2025-10-23T06:20:03.783Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/03/1faffcbda0c872a299f0c54a5be91a738e2f6cee6ff8143c481fa51f1f0a/beartype-0.22.3-py3-none-any.whl", hash = "sha256:2f36eb8ea8d5eb693d2307639756c43db73c3d1153dbba62261d8c08dbe2946d", size = 1312115, upload-time = "2025-10-23T06:20:01.136Z" }, +] + +[[package]] +name = "cattrs" +version = "25.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6e/00/2432bb2d445b39b5407f0a90e01b9a271475eea7caf913d7a86bcb956385/cattrs-25.3.0.tar.gz", hash = "sha256:1ac88d9e5eda10436c4517e390a4142d88638fe682c436c93db7ce4a277b884a", size = 509321, upload-time = "2025-10-07T12:26:08.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/2b/a40e1488fdfa02d3f9a653a61a5935ea08b3c2225ee818db6a76c7ba9695/cattrs-25.3.0-py3-none-any.whl", hash = "sha256:9896e84e0a5bf723bc7b4b68f4481785367ce07a8a02e7e9ee6eb2819bc306ff", size = 70738, upload-time = "2025-10-07T12:26:06.603Z" }, +] + +[[package]] +name = "certifi" +version = "2025.10.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "dagger-io" +version = "0.0.0" +source = { editable = "sdk" } +dependencies = [ + { name = "anyio" }, + { name = "beartype" }, + { name = "cattrs" }, + { name = "exceptiongroup" }, + { name = "gql", extra = ["httpx"] }, + { name = "opentelemetry-exporter-otlp-proto-http" }, + { name = "opentelemetry-instrumentation-logging" }, + { name = "opentelemetry-sdk" }, + { name = "platformdirs" }, + { name = "rich" }, + { name = "typing-extensions" }, +] + +[package.metadata] +requires-dist = [ + { name = "anyio", specifier = ">=3.6.2" }, + { name = "beartype", specifier = ">=0.18.2" }, + { name = "cattrs", specifier = ">=25.1.0" }, + { name = "exceptiongroup", specifier = ">=1.3.0" }, + { name = "gql", extras = ["httpx"], specifier = ">=4.0" }, + { name = "opentelemetry-exporter-otlp-proto-http", specifier = ">=1.23.0" }, + { name = "opentelemetry-instrumentation-logging", specifier = ">=0.54b1" }, + { name = "opentelemetry-sdk", specifier = ">=1.23.0" }, + { name = "platformdirs", specifier = ">=2.6.2" }, + { name = "rich", specifier = ">=10.11.0" }, + { name = "typing-extensions", specifier = ">=4.13.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "aiohttp", specifier = ">=3.9.3" }, + { name = "codegen", editable = "sdk/codegen" }, + { name = "mypy", specifier = ">=1.8.0" }, + { name = "pytest", specifier = ">=8.0.2" }, + { name = "pytest-httpx", specifier = ">=0.30.0" }, + { name = "pytest-mock", specifier = ">=3.12.0" }, + { name = "pytest-subprocess", specifier = ">=1.5.0" }, + { name = "ruff", specifier = ">=0.3.4" }, + { name = "sphinx", specifier = ">=7.2.6" }, + { name = "sphinx-rtd-theme", specifier = ">=2.0.0" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, +] + +[[package]] +name = "googleapis-common-protos" +version = "1.71.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/43/b25abe02db2911397819003029bef768f68a974f2ece483e6084d1a5f754/googleapis_common_protos-1.71.0.tar.gz", hash = "sha256:1aec01e574e29da63c80ba9f7bbf1ccfaacf1da877f23609fe236ca7c72a2e2e", size = 146454, upload-time = "2025-10-20T14:58:08.732Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/e8/eba9fece11d57a71e3e22ea672742c8f3cf23b35730c9e96db768b295216/googleapis_common_protos-1.71.0-py3-none-any.whl", hash = "sha256:59034a1d849dc4d18971997a72ac56246570afdd17f9369a0ff68218d50ab78c", size = 294576, upload-time = "2025-10-20T14:56:21.295Z" }, +] + +[[package]] +name = "gql" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "backoff" }, + { name = "graphql-core" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/9f/cf224a88ed71eb223b7aa0b9ff0aa10d7ecc9a4acdca2279eb046c26d5dc/gql-4.0.0.tar.gz", hash = "sha256:f22980844eb6a7c0266ffc70f111b9c7e7c7c13da38c3b439afc7eab3d7c9c8e", size = 215644, upload-time = "2025-08-17T14:32:35.397Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/94/30bbd09e8d45339fa77a48f5778d74d47e9242c11b3cd1093b3d994770a5/gql-4.0.0-py3-none-any.whl", hash = "sha256:f3beed7c531218eb24d97cb7df031b4a84fdb462f4a2beb86e2633d395937479", size = 89900, upload-time = "2025-08-17T14:32:34.029Z" }, +] + +[package.optional-dependencies] +httpx = [ + { name = "httpx" }, +] + +[[package]] +name = "graphql-core" +version = "3.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/16/7574029da84834349b60ed71614d66ca3afe46e9bf9c7b9562102acb7d4f/graphql_core-3.2.6.tar.gz", hash = "sha256:c08eec22f9e40f0bd61d805907e3b3b1b9a320bc606e23dc145eebca07c8fbab", size = 505353, upload-time = "2025-01-26T16:36:27.374Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/4f/7297663840621022bc73c22d7d9d80dbc78b4db6297f764b545cd5dd462d/graphql_core-3.2.6-py3-none-any.whl", hash = "sha256:78b016718c161a6fb20a7d97bbf107f331cd1afe53e45566c59f776ed7f0b45f", size = 203416, upload-time = "2025-01-26T16:36:24.868Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "8.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, +] + +[[package]] +name = "libpressio" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "dagger-io" }, + { name = "pandas" }, + { name = "pandas-stubs" }, + { name = "rich" }, +] + +[package.metadata] +requires-dist = [ + { name = "dagger-io", editable = "sdk" }, + { name = "pandas", specifier = ">=2.3.3" }, + { name = "pandas-stubs", specifier = ">=2.3.2.250926" }, + { name = "rich", specifier = ">=14.2.0" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, + { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, + { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, + { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, + { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, + { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, + { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, + { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, + { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, + { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, + { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, + { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, + { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, + { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, + { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, + { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, + { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, + { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, + { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, + { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, + { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, + { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, + { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, + { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, + { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, + { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, + { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, + { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, + { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187, upload-time = "2025-10-15T16:18:11.77Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335, upload-time = "2025-10-15T16:16:10.304Z" }, + { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878, upload-time = "2025-10-15T16:16:12.595Z" }, + { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673, upload-time = "2025-10-15T16:16:14.877Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438, upload-time = "2025-10-15T16:16:16.805Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290, upload-time = "2025-10-15T16:16:18.764Z" }, + { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543, upload-time = "2025-10-15T16:16:21.072Z" }, + { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117, upload-time = "2025-10-15T16:16:23.369Z" }, + { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788, upload-time = "2025-10-15T16:16:27.496Z" }, + { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620, upload-time = "2025-10-15T16:16:29.811Z" }, + { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672, upload-time = "2025-10-15T16:16:31.589Z" }, + { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702, upload-time = "2025-10-15T16:16:33.902Z" }, + { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003, upload-time = "2025-10-15T16:16:36.101Z" }, + { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980, upload-time = "2025-10-15T16:16:39.124Z" }, + { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472, upload-time = "2025-10-15T16:16:41.168Z" }, + { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342, upload-time = "2025-10-15T16:16:43.777Z" }, + { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338, upload-time = "2025-10-15T16:16:46.081Z" }, + { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392, upload-time = "2025-10-15T16:16:48.455Z" }, + { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998, upload-time = "2025-10-15T16:16:51.114Z" }, + { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574, upload-time = "2025-10-15T16:16:53.429Z" }, + { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135, upload-time = "2025-10-15T16:16:55.992Z" }, + { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582, upload-time = "2025-10-15T16:16:57.943Z" }, + { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691, upload-time = "2025-10-15T16:17:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580, upload-time = "2025-10-15T16:17:02.509Z" }, + { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056, upload-time = "2025-10-15T16:17:04.873Z" }, + { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555, upload-time = "2025-10-15T16:17:07.499Z" }, + { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581, upload-time = "2025-10-15T16:17:09.774Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186, upload-time = "2025-10-15T16:17:11.937Z" }, + { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601, upload-time = "2025-10-15T16:17:14.391Z" }, + { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219, upload-time = "2025-10-15T16:17:17.058Z" }, + { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702, upload-time = "2025-10-15T16:17:19.379Z" }, + { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136, upload-time = "2025-10-15T16:17:22.886Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542, upload-time = "2025-10-15T16:17:24.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213, upload-time = "2025-10-15T16:17:26.935Z" }, + { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280, upload-time = "2025-10-15T16:17:29.638Z" }, + { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930, upload-time = "2025-10-15T16:17:32.384Z" }, + { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504, upload-time = "2025-10-15T16:17:34.515Z" }, + { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405, upload-time = "2025-10-15T16:17:36.128Z" }, + { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866, upload-time = "2025-10-15T16:17:38.884Z" }, + { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296, upload-time = "2025-10-15T16:17:41.564Z" }, + { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046, upload-time = "2025-10-15T16:17:43.901Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691, upload-time = "2025-10-15T16:17:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782, upload-time = "2025-10-15T16:17:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301, upload-time = "2025-10-15T16:17:50.938Z" }, + { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532, upload-time = "2025-10-15T16:17:53.48Z" }, +] + +[[package]] +name = "opentelemetry-api" +version = "1.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/08/d8/0f354c375628e048bd0570645b310797299754730079853095bf000fba69/opentelemetry_api-1.38.0.tar.gz", hash = "sha256:f4c193b5e8acb0912b06ac5b16321908dd0843d75049c091487322284a3eea12", size = 65242, upload-time = "2025-10-16T08:35:50.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/a2/d86e01c28300bd41bab8f18afd613676e2bd63515417b77636fc1add426f/opentelemetry_api-1.38.0-py3-none-any.whl", hash = "sha256:2891b0197f47124454ab9f0cf58f3be33faca394457ac3e09daba13ff50aa582", size = 65947, upload-time = "2025-10-16T08:35:30.23Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-proto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/83/dd4660f2956ff88ed071e9e0e36e830df14b8c5dc06722dbde1841accbe8/opentelemetry_exporter_otlp_proto_common-1.38.0.tar.gz", hash = "sha256:e333278afab4695aa8114eeb7bf4e44e65c6607d54968271a249c180b2cb605c", size = 20431, upload-time = "2025-10-16T08:35:53.285Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/9e/55a41c9601191e8cd8eb626b54ee6827b9c9d4a46d736f32abc80d8039fc/opentelemetry_exporter_otlp_proto_common-1.38.0-py3-none-any.whl", hash = "sha256:03cb76ab213300fe4f4c62b7d8f17d97fcfd21b89f0b5ce38ea156327ddda74a", size = 18359, upload-time = "2025-10-16T08:35:34.099Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-http" +version = "1.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/81/0a/debcdfb029fbd1ccd1563f7c287b89a6f7bef3b2902ade56797bfd020854/opentelemetry_exporter_otlp_proto_http-1.38.0.tar.gz", hash = "sha256:f16bd44baf15cbe07633c5112ffc68229d0edbeac7b37610be0b2def4e21e90b", size = 17282, upload-time = "2025-10-16T08:35:54.422Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/77/154004c99fb9f291f74aa0822a2f5bbf565a72d8126b3a1b63ed8e5f83c7/opentelemetry_exporter_otlp_proto_http-1.38.0-py3-none-any.whl", hash = "sha256:84b937305edfc563f08ec69b9cb2298be8188371217e867c1854d77198d0825b", size = 19579, upload-time = "2025-10-16T08:35:36.269Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation" +version = "0.59b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "packaging" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/ed/9c65cd209407fd807fa05be03ee30f159bdac8d59e7ea16a8fe5a1601222/opentelemetry_instrumentation-0.59b0.tar.gz", hash = "sha256:6010f0faaacdaf7c4dff8aac84e226d23437b331dcda7e70367f6d73a7db1adc", size = 31544, upload-time = "2025-10-16T08:39:31.959Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/f5/7a40ff3f62bfe715dad2f633d7f1174ba1a7dd74254c15b2558b3401262a/opentelemetry_instrumentation-0.59b0-py3-none-any.whl", hash = "sha256:44082cc8fe56b0186e87ee8f7c17c327c4c2ce93bdbe86496e600985d74368ee", size = 33020, upload-time = "2025-10-16T08:38:31.463Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-logging" +version = "0.59b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/88/9c5f70fa8b8d96d30be378fc6eb1776e13aea456db15009f4eaef4928847/opentelemetry_instrumentation_logging-0.59b0.tar.gz", hash = "sha256:1b51116444edc74f699daf9002ded61529397100c9bc903c8b9aaa75a5218c76", size = 9969, upload-time = "2025-10-16T08:39:51.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/a0/340cc45d71437c2f7e27f13c1d2e335b18bbc7a24fd7d174018500b3c7ba/opentelemetry_instrumentation_logging-0.59b0-py3-none-any.whl", hash = "sha256:fdd4eddbd093fc421df8f7d356ecb15b320a1f3396b56bce5543048a5c457eea", size = 12577, upload-time = "2025-10-16T08:38:58.064Z" }, +] + +[[package]] +name = "opentelemetry-proto" +version = "1.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/51/14/f0c4f0f6371b9cb7f9fa9ee8918bfd59ac7040c7791f1e6da32a1839780d/opentelemetry_proto-1.38.0.tar.gz", hash = "sha256:88b161e89d9d372ce723da289b7da74c3a8354a8e5359992be813942969ed468", size = 46152, upload-time = "2025-10-16T08:36:01.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/6a/82b68b14efca5150b2632f3692d627afa76b77378c4999f2648979409528/opentelemetry_proto-1.38.0-py3-none-any.whl", hash = "sha256:b6ebe54d3217c42e45462e2a1ae28c3e2bf2ec5a5645236a490f55f45f1a0a18", size = 72535, upload-time = "2025-10-16T08:35:45.749Z" }, +] + +[[package]] +name = "opentelemetry-sdk" +version = "1.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/cb/f0eee1445161faf4c9af3ba7b848cc22a50a3d3e2515051ad8628c35ff80/opentelemetry_sdk-1.38.0.tar.gz", hash = "sha256:93df5d4d871ed09cb4272305be4d996236eedb232253e3ab864c8620f051cebe", size = 171942, upload-time = "2025-10-16T08:36:02.257Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/2e/e93777a95d7d9c40d270a371392b6d6f1ff170c2a3cb32d6176741b5b723/opentelemetry_sdk-1.38.0-py3-none-any.whl", hash = "sha256:1c66af6564ecc1553d72d811a01df063ff097cdc82ce188da9951f93b8d10f6b", size = 132349, upload-time = "2025-10-16T08:35:46.995Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.59b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/bc/8b9ad3802cd8ac6583a4eb7de7e5d7db004e89cb7efe7008f9c8a537ee75/opentelemetry_semantic_conventions-0.59b0.tar.gz", hash = "sha256:7a6db3f30d70202d5bf9fa4b69bc866ca6a30437287de6c510fb594878aed6b0", size = 129861, upload-time = "2025-10-16T08:36:03.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/7d/c88d7b15ba8fe5c6b8f93be50fc11795e9fc05386c44afaf6b76fe191f9b/opentelemetry_semantic_conventions-0.59b0-py3-none-any.whl", hash = "sha256:35d3b8833ef97d614136e253c1da9342b4c3c083bbaf29ce31d572a1c3825eed", size = 207954, upload-time = "2025-10-16T08:35:48.054Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "pandas-stubs" +version = "2.3.2.250926" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "types-pytz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1b/3b/32be58a125db39d0b5f62cc93795f32b5bb2915bd5c4a46f0e35171985e2/pandas_stubs-2.3.2.250926.tar.gz", hash = "sha256:c64b9932760ceefb96a3222b953e6a251321a9832a28548be6506df473a66406", size = 102147, upload-time = "2025-09-26T19:50:39.522Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/96/1e4a035eaf4dce9610aac6e43026d0c6baa05773daf6d21e635a4fe19e21/pandas_stubs-2.3.2.250926-py3-none-any.whl", hash = "sha256:81121818453dcfe00f45c852f4dceee043640b813830f6e7bd084a4ef7ff7270", size = 159995, upload-time = "2025-09-26T19:50:38.241Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "protobuf" +version = "6.33.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, + { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, + { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, + { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, + { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "pytz" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "types-pytz" +version = "2025.2.0.20250809" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/07/e2/c774f754de26848f53f05defff5bb21dd9375a059d1ba5b5ea943cf8206e/types_pytz-2025.2.0.20250809.tar.gz", hash = "sha256:222e32e6a29bb28871f8834e8785e3801f2dc4441c715cd2082b271eecbe21e5", size = 10876, upload-time = "2025-08-09T03:14:17.453Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/d0/91c24fe54e565f2344d7a6821e6c6bb099841ef09007ea6321a0bac0f808/types_pytz-2025.2.0.20250809-py3-none-any.whl", hash = "sha256:4f55ed1b43e925cf851a756fe1707e0f5deeb1976e15bf844bcaa025e8fbd0db", size = 10095, upload-time = "2025-08-09T03:14:16.674Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "tzdata" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, +] + +[[package]] +name = "urllib3" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, +] + +[[package]] +name = "wrapt" +version = "1.17.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" }, + { url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" }, + { url = "https://files.pythonhosted.org/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", size = 88072, upload-time = "2025-08-12T05:52:37.53Z" }, + { url = "https://files.pythonhosted.org/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", size = 88214, upload-time = "2025-08-12T05:52:15.886Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", size = 87105, upload-time = "2025-08-12T05:52:17.914Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", size = 87766, upload-time = "2025-08-12T05:52:39.243Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" }, + { url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" }, + { url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" }, + { url = "https://files.pythonhosted.org/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", size = 54132, upload-time = "2025-08-12T05:51:49.864Z" }, + { url = "https://files.pythonhosted.org/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", size = 39091, upload-time = "2025-08-12T05:51:38.935Z" }, + { url = "https://files.pythonhosted.org/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", size = 39172, upload-time = "2025-08-12T05:51:59.365Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", size = 87163, upload-time = "2025-08-12T05:52:40.965Z" }, + { url = "https://files.pythonhosted.org/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", size = 87963, upload-time = "2025-08-12T05:52:20.326Z" }, + { url = "https://files.pythonhosted.org/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", size = 86945, upload-time = "2025-08-12T05:52:21.581Z" }, + { url = "https://files.pythonhosted.org/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", size = 86857, upload-time = "2025-08-12T05:52:43.043Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", size = 37178, upload-time = "2025-08-12T05:53:12.605Z" }, + { url = "https://files.pythonhosted.org/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", size = 39310, upload-time = "2025-08-12T05:53:11.106Z" }, + { url = "https://files.pythonhosted.org/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", size = 37266, upload-time = "2025-08-12T05:52:56.531Z" }, + { url = "https://files.pythonhosted.org/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", size = 56544, upload-time = "2025-08-12T05:51:51.109Z" }, + { url = "https://files.pythonhosted.org/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", size = 40283, upload-time = "2025-08-12T05:51:39.912Z" }, + { url = "https://files.pythonhosted.org/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", size = 40366, upload-time = "2025-08-12T05:52:00.693Z" }, + { url = "https://files.pythonhosted.org/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", size = 108571, upload-time = "2025-08-12T05:52:44.521Z" }, + { url = "https://files.pythonhosted.org/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", size = 113094, upload-time = "2025-08-12T05:52:22.618Z" }, + { url = "https://files.pythonhosted.org/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", size = 110659, upload-time = "2025-08-12T05:52:24.057Z" }, + { url = "https://files.pythonhosted.org/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", size = 106946, upload-time = "2025-08-12T05:52:45.976Z" }, + { url = "https://files.pythonhosted.org/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", size = 38717, upload-time = "2025-08-12T05:53:15.214Z" }, + { url = "https://files.pythonhosted.org/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", size = 41334, upload-time = "2025-08-12T05:53:14.178Z" }, + { url = "https://files.pythonhosted.org/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", size = 38471, upload-time = "2025-08-12T05:52:57.784Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] + +[[package]] +name = "zipp" +version = "3.23.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, +] diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 00000000..6fe1e3db --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,57 @@ +# This CITATION.cff file was generated with cffinit. +# Visit https://bit.ly/cffinit to generate yours today! + +cff-version: 1.2.0 +title: LibPressio +message: >- + A library to abstract between different lossless and lossy + compressors +type: software +authors: + - given-names: Robert + family-names: Underwood + email: runderwood@anl.gov + orcid: 'https://orcid.org/0000-0002-1464-729X' + affiliation: Argonne National Laboratory + - name: Argonne National Laboratory + address: 9700 S. Cass Avenue + city: Lemont + country: US + post-code: '60439' + region: Illinois + tel: 1-630-252-2000 + website: 'https://anl.gov' +identifiers: + - type: doi + value: 10.1109/DRBSD754563.2021.00005 + description: Paper introducing the library +repository-code: 'https://github.com/robertu94/libpressio' +url: 'https://robertu94.github.io/libpressio/' +abstract: >- + In recent years, lossless and lossy compressors have been + developed to cope with the ever increasing volume of + scientific floating point data. However not all + compression techniques are appropriate for all data-sets, + and determining which one to use can be time consuming + requiring code modifications and trial and error. We + present LibPressio - a generic library for the compression + of dense tensors that minimizes the code changes + scientists need to make to take advantage of new and + improved compression techniques. We compare LibPressio to + 9 different competing libraries and measure the overhead + of their design decisions as well as overall run time + overhead showing insignificant overhead. We further show + an improvement in usability as measured by a reduction in + lines of code compared to native code by 50–90 %. The + value of this tool can be seen by integration into + Z-Checker and ADIOS2. +keywords: + - Lossy compresion + - Lossless compression + - C + - C++ + - Python + - Library + - High Performance Computing (HPC) + - Scientific Computing +license: BSD-4-Clause diff --git a/CMakeLists.txt b/CMakeLists.txt index 936c206c..14031872 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,14 @@ option(BUILD_SHARED_LIBS "build libpressio as a shared library" ON) option(CMAKE_POSITION_INDEPENDENT_CODE "build libpressio with position indpendent code" ON) -include(GNUInstallDirs) +if(NOT DEFINED SKBUILD) + include(GNUInstallDirs) +else() + set(CMAKE_INSTALL_INCLUDEDIR ${SKBUILD_HEADERS_DIR}) + set(CMAKE_INSTALL_LIBDIR ${SKBUILD_PLATLIB_DIR}) + set(CMAKE_INSTALL_PREFIX ${SKBUILD_DATA_DIR}) +endif() + include(CheckCXXCompilerFlag) include(CMakeDependentOption) @@ -375,6 +382,7 @@ if(LIBPRESSIO_HAS_CUSZ) set(LIBPRESSIO_COMPRESSORS "${LIBPRESSIO_COMPRESSORS} cusz") find_package(CUSZ REQUIRED) libpressio_plugin_file(/compressors/cusz.cc) + libpressio_plugin_file(/compressors/eip.cc) target_link_libraries(libpressio PRIVATE CUSZ::cusz CUDA::cuda_driver CUDA::cudart) endif() @@ -565,6 +573,13 @@ if(LIBPRESSIO_HAS_CUSZP) libpressio_plugin_file(/compressors/cuszp.cc) target_link_libraries(libpressio PRIVATE cuSZp::cuSZp_shared) endif() +option(LIBPRESSIO_HAS_LSCOMP "build the LSCOMP plugin" OFF) +if(LIBPRESSIO_HAS_LSCOMP) + set(LIBPRESSIO_COMPRESSORS "${LIBPRESSIO_COMPRESSORS} LSCOMP") + find_package(cuLSZ REQUIRED) + libpressio_plugin_file(/compressors/lscomp.cc) + target_link_libraries(libpressio PRIVATE cuLSZ::cuLSZ) +endif() option(LIBPRESSIO_HAS_FPZIP "build the fpzip plugin" OFF) if(LIBPRESSIO_HAS_FPZIP) @@ -618,10 +633,15 @@ if(LIBPRESSIO_HAS_LUA) target_link_libraries(libpressio PRIVATE PkgConfig::Lua) else() message(INFO "lua from cmake") - find_package(Lua) - target_link_libraries(libpressio PRIVATE ${LUA_LIBRARIES}) - target_include_directories(libpressio PRIVATE ${LUA_INCLUDE_DIR}) + find_package(Lua REQUIRED) + if(TARGET Lua::Lua) + target_link_libraries(libpressio PRIVATE Lua::Lua) + else() + target_link_libraries(libpressio PRIVATE ${LUA_LIBRARIES}) + target_include_directories(libpressio PRIVATE ${LUA_INCLUDE_DIRS}) + endif() endif() + libpressio_plugin_file( /compressors/lambda_fn.cc) endif() @@ -833,7 +853,7 @@ if(BUILD_DOCS) ) add_custom_command( OUTPUT "Compressors.md" - COMMAND generate_docs -m c -o "${CMAKE_BINARY_DIR}/Compressors.md" + COMMAND ${CMAKE_COMMAND} -E env LIBPRESSIO_GENERATE_DOCS_OUTPUT="${CMAKE_BINARY_DIR}/Compressors.md" ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_SOURCE_DIR}/tools/docs/generate_compressors_docs.cmake" DEPENDS generate_docs libpressio COMMENT "Documenting Compressors" ) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1acef5f2..2cf79042 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -22,7 +22,7 @@ Thanks for you interest in LibPressio! Here are a few things you can do to spee LibPressio uses a key-value system to refer to configuration settings. -Each compressor may find specific configuration settings for its specific compressor with settings beginning with its compressor id as prefix (i.e. configurations for SZ begin with `sz:`). [Refer to the specific compressors documentation](build/Compressors.md) for further documentation for each settings. +Each compressor may find specific configuration settings for its specific compressor with settings beginning with its compressor id as prefix (i.e. configurations for SZ begin with `sz:`). Refer to the generated compressor documentation for further documentation for each setting. + Use the `io:`, `metrics:` and `pressio:` where appropriate. + Avoid unnecessary casts. Prefer C++ style casts where required. diff --git a/LibPressioConfig.cmake.in b/LibPressioConfig.cmake.in index 96ecbc47..854fd4aa 100644 --- a/LibPressioConfig.cmake.in +++ b/LibPressioConfig.cmake.in @@ -190,22 +190,4 @@ if(@LIBPRESSIO_HAS_GRIB@) find_package(eccodes REQUIRED) endif() -if(@BUILD_PYTHON_WRAPPER@) - find_package(Python3 COMPONENTS Interpreter Development NumPy) - find_package(SWIG) -endif() - -if(@BUILD_MIGRATION_TOOLS@) - find_package(Clang REQUIRED) - find_package(fmt REQUIRED) - list(APPEND CMAKE_MODULE_PATH "${CLANG_CMAKE_DIR}") - list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") - include(AddLLVM) - include(AddClang) -endif() - -if(@BUILD_DOCS@) - find_package(Doxygen REQUIRED dot) -endif() - check_required_components(LibPressio) diff --git a/README.md b/README.md index d3bc1f55..50b2ba00 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LibPressio -Pressio is latin for compression. LibPressio is a C++ library with C compatible bindings to abstract between different lossless and lossy compressors and their configurations. It solves the problem of having to having to write separate application level code for each lossy compressor that is developed. Instead, users write application level code using LibPressio, and the library will make the correct underlying calls to the compressors. It provides interfaces to represent data, compressors settings, and compressors. +Pressio is Latin for compression. LibPressio is a C++ library with C compatible bindings to abstract between different lossless and lossy compressors and their configurations. It solves the problem of having to having to write separate application level code for each lossy compressor that is developed. Instead, users write application level code using LibPressio, and the library will make the correct underlying calls to the compressors. It provides interfaces to represent data, compressors settings, and compressors. Documentation for the `master` branch can be [found here](https://robertu94.github.io/libpressio/) @@ -16,12 +16,23 @@ pressio -i ~/git/datasets/hurricane/100x500x500/CLOUDf48.bin.f32 \ -w /path/to/output.dec ``` -The reccomended way to learn LibPressio is with self-paced [LibPressio Tutorial](https://github.com/robertu94/libpressio_tutorial). +Using the CLI from [`pressio-tools`](https://github.com/robertu94/pressio-tools) you can use +the `pressio_new` command to generate scaffolding code for new projects. + +```bash +#list available templates +pressio_new + +#generate a python sample code using SZ3 +pressio_new client:python sz3 ~/path/to/data +``` + +The recommended way to learn LibPressio is with self-paced [LibPressio Tutorial](https://github.com/robertu94/libpressio_tutorial). Here you will find examples of how to use LibPressio in a series of lessons for several common languages. You can also find a [recording of the tutorial on YouTube](https://youtu.be/hZ_dFCMxmGw). -## Getting Started +## Overview of the library After skimming the example, LibPressio has 6 major headers that you will need to use: @@ -34,47 +45,51 @@ Type | Use `pressio_metrics.h` | A set of metrics to run while compressors run `pressio_io.h` | An extension header that provides methods to load or store data from/to persistent storage -All of these are included by the convience header `libpressio.h`. + +All of these are included by the convenience header `libpressio.h`. + +There is also a C++ interface that can be bound in `libpressio_ext/cpp/libpressio.h` which provides access to unstable features +and the ability to extend the library. You can pick up the more advanced features as you need them. -You can also find more examples in `test/` or in the [LibPressio intresting scripts collection](https://github.com/robertu94/libpressio-interesting-scripts) which catalogs intresting higher-level use cases. +You can also find more examples in `test/` or in the [LibPressio interesting scripts collection](https://github.com/robertu94/libpressio-interesting-scripts) which catalogs interesting higher-level use cases. ## Supported Compressors and Metrics -Libpressio provides a number of builtin compressor and metrics modules. +LibPressio provides a number of builtin compressor and metrics modules. All of these are **disabled by default**. They can be enabled by passing the corresponding `LIBPRESSIO_HAS_*` variable to CMake. -Additionally, Libpressio is extensible. +Additionally, LibPressio is extensible. For information on writing a compressor plugin see [Writing a Compressor Plugin](docs/WritingACompressorPlugin.md) For information on writing a metrics plugin see [Writing a Metrics Plugin](docs/WritingAMetricsPlugin.md) ### Compressor Plugins -1st party compressors plugins can be found in [src/plugins/compressors](https://github.com/robertu94/libpressio/tree/master/src/plugins/compressors) +First party compressors plugins can be found in [src/plugins/compressors](https://github.com/robertu94/libpressio/tree/master/src/plugins/compressors) -See the [compressor settings page](build/Compressors.md) for information on how to configure them. +See the compressor settings page in the generated documentation for information on how to configure them. ### Metrics Plugins -1st party compressors plugins can be found in [src/plugins/metrics](https://github.com/robertu94/libpressio/tree/master/src/plugins/metrics) +First party compressors plugins can be found in [src/plugins/metrics](https://github.com/robertu94/libpressio/tree/master/src/plugins/metrics) -See the [metrics results page](build/Metrics.md) for information on what they produce +See the metrics results page in the generated documentation for information on what they produce. ### IO Plugins -1st party compressors plugins can be found in [src/plugins/io](https://github.com/robertu94/libpressio/tree/master/src/plugins/io) +First party compressors plugins can be found in [src/plugins/io](https://github.com/robertu94/libpressio/tree/master/src/plugins/io) -See the [io settings page](build/IO.md) for information on how to configure them +See the IO settings page in the generated documentation for information on how to configure them. # Installation ## Installing LibPressio using Spack -LibPressio can be built using [spack](https://github.com/spack/spack/). This example will install libpressio with only the SZ3 plugin. +LibPressio can be built using [spack](https://github.com/spack/spack/). This example will install LibPressio with only the SZ3 plugin. ```bash git clone https://github.com/spack/spack @@ -82,7 +97,7 @@ source ./spack/share/spack/setup-env.sh spack install libpressio+sz3 ``` -More information on spack can be found in the [spack documentation](https://spack.readthedocs.io/en/latest/) or [my quick start guides for systems that I use](https://robertu94.github.io/guides) +More information on Spack can be found in the [Spack documentation](https://spack.readthedocs.io/en/latest/) or [my quick start guides for systems that I use](https://robertu94.github.io/guides) You can see the other available versions and compilation options by calling `spack info libpressio` @@ -90,10 +105,10 @@ The following language bindings are in this repository. + `C` -- (default) if you need a stable interface + `C++` -- (default) if you want a more productive interface, or want to extend LibPressio -+ `Python` -- (`+python`; BUILD_PYTHON_WRAPPER) if you know or want to intergate Python ++ `Python` -- (`+python`; BUILD_PYTHON_WRAPPER) if you know or want to integrate Python + `HDF5` -- (`+hdf5+json`; LIBPRESSIO_HAS_HDF AND LIBPRESSIO_HAS_JSON) you already use HDF5 -The following bindings must be installed seperately: +The following bindings must be installed separately: + `R` -- [r-libpressio](https://github.com/robertu94/libpressio-r) if you know or want to integrate with R + `Bash/CLI` -- [libpressio-tools](https://github.com/robertu94/pressio-tools) if you want to quickly prototype from the CLI @@ -103,16 +118,19 @@ The following bindings are experimental and can be installed manually: + `Julia` -- [libpressio-jl](https://github.com/robertu94/LibPressio.jl) if you know or want to integrate with Julia + `Rust` -- [libpressio-rs](https://github.com/robertu94/libpressio-rs) if you know or want to integrate with Rust -## Doing a development build with spack +## Doing a development build with Spack -The easiest way to do a development build of libpressio is to use Spack envionments. +The easiest way to do a development build of LibPressio is to use Spack environments. ```bash -# one time setup: create an envionment +# one time setup: install the Spack repo for pre-release versions +spack repo add https://github.com/robertu94/spack_packages + +# one time setup: create an environment spack env create -d mydevenviroment spack env activate mydevenvionment -# one time setup: tell spack to set LD_LIBRARY_PATH with the spack envionment's library paths +# one time setup: tell Spack to set LD_LIBRARY_PATH with the Spack environment's library paths spack config add modules:prefix_inspections:lib64:[LD_LIBRARY_PATH] spack config add modules:prefix_inspections:lib:[LD_LIBRARY_PATH] @@ -137,16 +155,16 @@ Libpressio unconditionally requires: + `gcc-4.8.5` or later + `clang-7.0.0` or later using either `libc++` or `libstdc++`. Beware that system libraries may need to be recompiled with `libc++` if using `libc++` -Dependency versions and optional dependencies are documented [in the spack package](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/libpressio/package.py). +Dependency versions and optional dependencies are documented [in the Spack package](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/libpressio/package.py). ## Configuring LibPressio Manually -LibPressio uses a fairly standard CMake buildsystem. +LibPressio uses a fairly standard CMake build-system. For more information on [CMake refer to these docs](https://robertu94.github.io/learning/cmake) The set of configuration options for LibPressio can be found using `cmake -L $BUILD_DIR`. -For information on what these settings do, see the [spack package](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/libpressio/package.py) +For information on what these settings do, see the [Spack package](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/libpressio/package.py) # API Stability @@ -158,13 +176,13 @@ Please refer to [CONTRIBUTORS.md](CONTRIBUTORS.md) for a list of contributors, s # Bug Reports -Please files bugs to the Github Issues page on the CODARCode libpressio repository. +Please files bugs to the GitHub Issues page on the CODARCode libpressio repository. Please read this post on [how to file a good bug report](https://codingnest.com/how-to-file-a-good-bug-report/).  After reading this post, please provide the following information specific to libpressio: + Your OS version and distribution information, usually this can be found in `/etc/os-release` + the output of `cmake -L $BUILD_DIR` -+ the version of each of libpressio's dependencies listed in the README that you have installed. Where possible, please provide the commit hashes. ++ the version of each of LibPressio's dependencies listed in the README that you have installed. Where possible, please provide the commit hashes. # Citing LibPressio diff --git a/ci/test.py b/ci/test.py deleted file mode 100755 index 22656379..00000000 --- a/ci/test.py +++ /dev/null @@ -1,286 +0,0 @@ -#!/usr/bin/env python - -import sys -import argparse -import dagger -import os -import anyio - - -def many_linux(client): - pass - - return ( - client.container() - .from_("quay.io/pypa/manylinux2014_x86_64") - ) - - -def spack_base(client): - return (client.container() - .from_("ecpe4s/ubuntu20.04") - .with_new_file("/build_libpressio.sh", - contents=""" - #!/usr/bin/env bash - source /spack/share/spack/setup-env.sh - spack install libpressio - """ - ) - .with_exec(["/build_libpressio.sh"])) - - -def fedora_base(client, image): - dnf_cache = client.cache_volume(f"dnf-{image}") - ccache = client.cache_volume(f"ccache-{image}") - return ( - client.container() - .from_(image) - .with_mounted_cache("/var/cache/dnf", dnf_cache, sharing=dagger.CacheSharingMode.LOCKED) - .with_mounted_cache("/var/ccache/cache", ccache, sharing=dagger.CacheSharingMode.LOCKED) - .with_env_variable("CCACHE_DIR", "/var/ccache/cache") - .with_exec( - [ - "dnf", - "install", - "-y", - "cmake", - "gcc", - "g++", - "ninja-build", - "ccache", - "git", - "pkg-config", - ] - ) - ) - - -def centos_base(client, image, powertools_repo="powertools"): - dnf_cache = client.cache_volume(f"dnf-{image}") - ccache = client.cache_volume(f"ccache-{image}") - container = ( - client.container() - .from_(image) - .with_mounted_cache("/var/cache/dnf", dnf_cache, sharing=dagger.CacheSharingMode.LOCKED) - .with_mounted_cache("/var/ccache/cache", ccache, sharing=dagger.CacheSharingMode.LOCKED) - .with_env_variable("CCACHE_DIR", "/var/ccache/cache") - .with_exec( - [ - "dnf", - "install", - "-y", - "dnf-plugins-core", - ] - ) - .with_exec( - [ - "dnf", - "install", - "-y", - "epel-release", - ] - ) - .with_exec( - [ - "dnf", - "config-manager", - "--set-enabled", - powertools_repo, - ] - ) - ) - container = ( - container.with_exec( - [ - "dnf", - "install", - "-y", - "cmake", - "gcc", - "gcc-c++", - "ninja-build", - "boost-devel", - "ccache", - "git", - "pkg-config", - ] - ) - ) - return container - - -def ubuntu_base(client, image): - apt_cache = client.cache_volume(f"apt-{image}") - ccache = client.cache_volume(f"ccache-{image}") - return ( - client.container() - .from_(image) - .with_exec(["rm", "/etc/apt/apt.conf.d/docker-clean"]) - .with_mounted_cache("/var/apt/cache", apt_cache) - .with_mounted_cache("/var/ccache/cache", ccache) - .with_env_variable("CCACHE_DIR", "/var/ccache/cache") - .with_exec(["apt-get", "update", "-y"]) - .with_env_variable("DEBIAN_FRONTEND", "noninteractive") - .with_exec( - [ - "apt-get", - "install", - "-y", - "cmake", - "gcc", - "g++", - "ninja-build", - "ccache", - "git", - "pkg-config", - ] - ) - .without_env_variable("DEBIAN_FRONTEND") - ) - - -async def test(args): - async with dagger.Connection(dagger.Config(log_output=sys.stderr)) as client: - # get reference to the local project - src = client.host().directory( - ".", exclude=["build*", "test/CMakeFiles*", "CMakeFiles*", "Testing*", "ci"] - ) - stdcompat = ( - client.git("https://github.com/robertu94/std_compat") - .branch("master") - .tree() - ) - - def common_steps(container, static: bool = False, generator: str = "Ninja", - has_ccache: bool = True, tests: bool = True): - build_cmd = { - "Ninja": "ninja", - "Unix Makefiles": "make" - }[generator] - is_static = "OFF" if static else "ON" - build_tests = "ON" if tests else "OFF" - build_jobs = str(len(os.sched_getaffinity(0))) - r = ( - container.with_directory("/deps/stdcompat", stdcompat) - .with_workdir("/deps/stdcompat") - .with_exec(["mkdir", "/deps/stdcompat/build/"]) - .with_exec( - [ - "cmake", - "-S/deps/stdcompat", - "-B/deps/stdcompat/build/", - "-G", - generator, - *(["-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", - "-DCMAKE_C_COMPILER_LAUNCHER=ccache"] if has_ccache else []), - "-DBUILD_TESTING=OFF", - f"-DBUILD_SHARED_LIBS={is_static}", - ] - ) - .with_exec([build_cmd, "-C", "/deps/stdcompat/build/", "-l", - build_jobs, "-j", build_jobs]) - .with_exec(["cmake", "--install", "/deps/stdcompat/build/"]) - .with_directory("/src/", src) - .with_workdir("/src/") - .with_exec(["mkdir", "/build"]) - .with_exec( - [ - "cmake", - "-S/src", - "-B/build/", - "-G", - generator, - *(["-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", - "-DCMAKE_C_COMPILER_LAUNCHER=ccache"] if has_ccache else []), - f"-DBUILD_TESTING={build_tests}", - f"-DBUILD_SHARED_LIBS={is_static}", - ] - ) - .with_exec( - [ - build_cmd, - "-C", - "/build/", - "-l", - build_jobs, - "-j", - build_jobs, - ] - ) - .with_workdir("/build/") - ) - if build_tests: - return (r - .with_exec(["ctest", "--output-on-failure"]) - .with_exec(["cmake", "--install", "/build/"])) - else: - return r - - async def test_ubuntu(version): - return await common_steps(ubuntu_base(client, version)).sync() - - async def test_fedora(version): - return await common_steps(fedora_base(client, version)).sync() - - async def test_centos(version): - if int(version.split(":")[1]) <= 8: - return await common_steps(centos_base(client, version)).sync() - else: - return await common_steps(centos_base(client, version, "crb")).sync() - - async def test_spack(): - return await spack_base(client).sync() - - async def build_scip(): - try: - src_access_token = client.set_secret("SRC_ACCESS_TOKEN", os.environ["SRC_ACCESS_TOKEN"]) - build_dir = common_steps(fedora_base(client, "fedora:39")) - scip = client.http("https://github.com/sourcegraph/scip-clang/releases/download/v0.2.7/scip-clang-x86_64-linux") - src = client.http("https://sourcegraph.com/.api/src-cli/src_linux_amd64") - await (build_dir.with_file("/bin/scip-clang", scip, permissions=0o700) - .with_file("/bin/src", src, permissions=0o700) - .with_workdir("/src/") - .with_exec(["/bin/scip-clang", "--compdb-path=/build/compile_commands.json"]) - .with_env_variable("SRC_ENDPOINT", os.environ["SRC_ENDPOINT"]) - .with_secret_variable("SRC_ACCESS_TOKEN", src_access_token) - .with_exec(["src", "login", os.environ["SRC_ENDPOINT"]]) - .with_exec(["src", "code-intel", "upload", "-file=index.scip"]) - ) - except KeyError: - print("no sourcegraph token, skipping scip upload", file=sys.stderr) - - - - async def build_container(): - return await (client - .host() - .directory("./docker") - .docker_build() - .publish("ghcr.io/robertu94/libpressio:latest") - ) - - # run the builds we con control the load average for together - async with anyio.create_task_group() as tg: - for version in ["almalinux:8", "almalinux:9"]: - tg.start_soon(test_centos, version) - for version in ["fedora:38", "fedora:39"]: - tg.start_soon(test_fedora, version) - for version in ["ubuntu:20.04", "ubuntu:22.04"]: - tg.start_soon(test_ubuntu, version) - tg.start_soon(build_scip) - - # run the builds were we cannot control the load average separately - async with anyio.create_task_group() as tg: - tg.start_soon(test_spack) - pass - if args.build_container: - async with anyio.create_task_group() as tg: - tg.start_soon(build_container) - - print("done!") - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--build_container", action="store_true") - args = parser.parse_args() - anyio.run(test, args) diff --git a/dagger.json b/dagger.json new file mode 100644 index 00000000..a20fd1db --- /dev/null +++ b/dagger.json @@ -0,0 +1,8 @@ +{ + "name": "libpressio", + "engineVersion": "v0.19.3", + "sdk": { + "source": "python" + }, + "source": ".dagger" +} diff --git a/docs/UsingTheExternalMetric.md b/docs/UsingTheExternalMetric.md index 4d256af8..2e5200d5 100644 --- a/docs/UsingTheExternalMetric.md +++ b/docs/UsingTheExternalMetric.md @@ -328,7 +328,7 @@ the the stdout, stderr, and return code are returned via variables `stdout`, `st **limitation** this metric implements thread-safety with a global mutex grabbed at invocation time. -example script (assumes python 3.6 or later)` +example script (assumes python 3.6 or later) ```python import argparse diff --git a/include/libpressio_ext/cpp/configurable.h b/include/libpressio_ext/cpp/configurable.h index fbbdb64d..8b0945c4 100644 --- a/include/libpressio_ext/cpp/configurable.h +++ b/include/libpressio_ext/cpp/configurable.h @@ -11,10 +11,10 @@ * \brief interface for configurable types */ +namespace libpressio { /** * Base interface for configurable objects in libpressio */ -namespace libpressio { class pressio_configurable : public pressio_errorable { public: virtual ~pressio_configurable()=default; diff --git a/include/libpressio_ext/cpp/data.h b/include/libpressio_ext/cpp/data.h index e1e9ba06..cd90608a 100644 --- a/include/libpressio_ext/cpp/data.h +++ b/include/libpressio_ext/cpp/data.h @@ -15,9 +15,46 @@ #include "libpressio_ext/cpp/dtype.h" #include "std_compat/optional.h" #include +#include namespace libpressio { + namespace detail { + /** Compute the total size of the types stored in a tuple. */ + template + size_t tuple_bytes(std::tuple const&) { + return (0 + ... + sizeof(T)); + } + + /** Return the size of each type stored in a tuple. */ + template + std::array>::value> tuple_sizes(std::tuple const&){ + std::array>::value> s {sizeof(T)...}; + return s; + }; + /** Return the size of each type in a type pack. */ + template + std::array>::value> sizes(){ + std::array>::value> s {sizeof(T)...}; + return s; + }; + + + /** Invoke a callback for each tuple element together with its index. */ + template + void tuple_for_each_with_index_impl(Tuple&& t, F&& f, std::index_sequence) { + (f(std::get(t), I),...); + } + + /** Invoke a callback for each tuple element together with its index. */ + template + void tuple_for_each_with_index(Tuple&& t, F&& f) { + return tuple_for_each_with_index_impl(std::forward(t), std::forward(f), + std::make_index_sequence< + std::tuple_size>::value>{}); + } + } + /** * \file * \brief C++ pressio_data interface @@ -57,11 +94,58 @@ size_t data_size_in_bytes(pressio_dtype type, size_t const dimensions, size_t co } +/** Header formats supported by `pressio_data::join()` and `pressio_data::split()`. */ +enum pressio_data_header { + pressio_data_header_none = 0, /*no header, all type info must be stored separately*/ + pressio_data_header_len = 1, /*just the length of each buffer must be stored*/ + pressio_data_header_lentype = 2, /*just the length and type of each buffer must be stored*/ + pressio_data_header_dimstype = 3, /*just the dimension and type of each buffer must be stored*/ +}; + /** * represents a data buffer that may or may not be owned by the class */ struct pressio_data { + /** + * allocates a new buffer with the contents of all of the bufs concatenated together + * \param[in] bufs the data to concatonate + * \param[in] header include a header to aid in restoring + * \param[in] domain which domain to create the buffer in + */ + static pressio_data join(std::vector&& bufs, pressio_data_header header, std::shared_ptr&& domain); + /** + * Concatenate buffers into a single buffer, storing the requested header. + */ + static pressio_data join(std::vector&& bufs, pressio_data_header header); + /** + * Concatenate buffers without storing header metadata. + */ + static pressio_data join(std::vector&& bufs); + + /** + * Splits the buffer created with ::join + * \param[in] input the buffer to be split + * \param[in] header the header format stored in the joined buffer + * \param[out] bufs the split buffers + */ + static void split(pressio_data input, pressio_data_header header, std::vector& bufs); + + /** + * Splits the buffer created with ::join + * \param[in] input the buffer to be split + * \param[out] bufs the split buffers + */ + static void split(pressio_data input, std::vector& bufs); + /** + * allocates a new empty data buffer with a given type in a domain + * + * \param[in] dtype the type the buffer will contain + * \param[in] domain where the data will be allocated if it were provided + * \returns an empty data object (i.e. has no data) + * \see pressio_data_new_empty + * */ + static pressio_data type_domain(const pressio_dtype dtype, std::shared_ptr&& domain); /** * allocates a new empty data buffer * @@ -76,10 +160,23 @@ struct pressio_data { * * \param[in] dtype the type the buffer will contain * \param[in] dimensions the dimensions of the expected buffer + * \param[in] domain the domain that will own the allocation * \returns an empty data object (i.e. has no data) * \see pressio_data_new_empty * */ static pressio_data empty(const pressio_dtype dtype, std::vector const& dimensions, std::shared_ptr&& domain); + + /** + * allocates a new empty data buffer in the specified domain + * + * \param[in] dtype the type the buffer will contain + * \param[in] dimensions the dimensions of the expected buffer + * \param[in] domain the domain that will own the allocation + * \returns an empty data object (i.e. has no data) + * \see pressio_data_new_empty + * */ + static pressio_data empty(const pressio_dtype dtype, std::vector const& dimensions, std::shared_ptr const& domain); + /** * creates a non-owning view of an existing data * @@ -109,17 +206,26 @@ struct pressio_data { * \see pressio_data_new_nonowning * */ static pressio_data nonowning(const pressio_dtype dtype, void* data, std::vector const& dimensions, std::string const& domain_id); - /** + /** * creates a copy of a data buffer; assumes the source is the malloc domain * * \param[in] dtype the type of the buffer - * \param[in] src the buffer to copy \param[in] dimensions the dimensions of the buffer \returns an owning copy of the data object \see pressio_data_new_copy */ + * \param[in] src the buffer to copy + * \param[in] dimensions the dimensions of the buffer + * \returns an owning copy of the data object + * \see pressio_data_new_copy + */ static pressio_data copy(const enum pressio_dtype dtype, const void* src, std::vector const& dimensions); - /** + /** * creates a copy of a data buffer * * \param[in] dtype the type of the buffer - * \param[in] src the buffer to copy \param[in] dimensions the dimensions of the buffer \returns an owning copy of the data object \see pressio_data_new_copy */ + * \param[in] src the buffer to copy + * \param[in] dimensions the dimensions of the buffer + * \param[in] domain_id the destination domain identifier + * \returns an owning copy of the data object + * \see pressio_data_new_copy + */ static pressio_data copy(const enum pressio_dtype dtype, const void* src, std::vector const& dimensions, std::string const& domain_id); /** * creates a new owning data buffer @@ -130,25 +236,25 @@ struct pressio_data { * \see pressio_data_new_owning * */ static pressio_data owning(const pressio_dtype dtype, std::vector const& dimensions); - /** - * creates a copy of a data buffer in the specified domain + /** + * creates an owning data buffer in the specified domain * * \param[in] dtype the type of the buffer * \param[in] dimensions the dimensions of the buffer - * \param[in] domain the dimensions of the buffer + * \param[in] domain the destination allocation domain * \returns an owning data object with uninitialized memory * \see pressio_data_new_owning - * */ + */ static pressio_data owning(const pressio_dtype dtype, std::vector const& dimensions, std::shared_ptr && domain); - /** + /** * creates an owning data buffer in the specified domain * * \param[in] dtype the type of the buffer * \param[in] dimensions the dimensions of the buffer - * \param[in] domain the dimensions of the buffer + * \param[in] domain the destination allocation domain * \returns an owning data object with uninitialized memory * \see pressio_data_new_owning - * */ + */ static pressio_data owning(const pressio_dtype dtype, std::vector const& dimensions, std::shared_ptr const& domain); /** * creates an owning data buffer in the same domain of the same size and type @@ -195,6 +301,7 @@ struct pressio_data { * \param[in] dimensions the dimensions of the buffer * \param[in] deleter the method to call to free the buffer or null to not free the data * \param[in] metadata the metadata passed to the deleter function + * \param[in] accessible domains that can directly access the buffer * \returns an owning data object with uninitialized memory * \see pressio_data_new_move * */ @@ -232,16 +339,18 @@ struct pressio_data { * */ static pressio_data empty(const pressio_dtype dtype, size_t const num_dimensions, size_t const dimensions[]); /** - * allocates a new empty data buffer + * allocates a new empty data buffer in the specified domain * * \param[in] dtype the type the buffer will contain * \param[in] num_dimensions the length of dimensions * \param[in] dimensions the dimensions of the expected buffer + * \param[in] domain the domain that will own the allocation * \returns an empty data object (i.e. has no data) * \see pressio_data_new_empty * */ static pressio_data empty(const pressio_dtype dtype, size_t const num_dimensions, size_t const dimensions[], std::shared_ptr && domain); + /** * creates a non-owning reference to data * @@ -279,18 +388,20 @@ struct pressio_data { static pressio_data copy(const enum pressio_dtype dtype, const void* src, size_t const num_dimensions, size_t const dimensions[]); /** - * creates a copy of a data buffer + * creates a copy of a data buffer in the specified domain * * \param[in] dtype the type of the buffer * \param[in] src the buffer to copy * \param[in] num_dimensions the number of entries in dimensions * \param[in] dimensions the dimensions of the data - * \returns an owning copy of the data object - * \see pressio_data_new_copy - * */ + * \param[in] domain_id the destination domain identifier + * \returns an owning copy of the data object + * \see pressio_data_new_copy + * */ static pressio_data copy(const enum pressio_dtype dtype, const void* src, size_t const num_dimensions, size_t const dimensions[], std::string const& domain_id); + /** * creates a copy of a data buffer * @@ -310,9 +421,11 @@ struct pressio_data { * \param[in] data the buffer * \param[in] num_dimensions the number of entries in dimensions * \param[in] dimensions the dimensions of the data - * \param[in] deleter the method to call to free the buffer or null to not free the data - * \param[in] metadata the metadata passed to the deleter function - * \returns an owning data object with uninitialized memory + * \param[in] deleter the method to call to free the buffer or null to not free the data + * \param[in] metadata the metadata passed to the deleter function + * \param[in] accessible domains that can directly access the buffer + * \returns an owning data object with uninitialized memory + * \see pressio_data_new_move * */ static pressio_data move(const pressio_dtype dtype, @@ -404,6 +517,9 @@ struct pressio_data { return data_dtype; } + /** + * \returns the domain that owns or describes the underlying buffer + */ std::shared_ptr domain() const { return memory.domain(); } @@ -531,6 +647,36 @@ struct pressio_data { } } + /** Pack a tuple into a byte buffer-backed `pressio_data` object. */ + template + pressio_data(std::tupleconst& t): pressio_data(pressio_data::owning(pressio_byte_dtype, {::libpressio::detail::tuple_bytes(t)})) + { + auto sizes = ::libpressio::detail::sizes(); + auto offsets = sizes; + compat::exclusive_scan(sizes.begin(), sizes.end(), offsets.begin(), 0); + auto copy = [this, &offsets, &sizes](auto&& v, size_t i) { + memcpy(static_cast(data()) + offsets[i], &v, sizes[i]); + }; + ::libpressio::detail::tuple_for_each_with_index(t, copy); + + } + /** + * convert a packed binary pressio_data structure into std::tuple + * \returns the tuple containing the data + */ + template + T to_tuple() const { + T t; + auto sizes = ::libpressio::detail::tuple_sizes(t); + auto offsets = sizes; + compat::exclusive_scan(sizes.begin(), sizes.end(), offsets.begin(), 0); + auto copy = [this, &offsets, &sizes](auto&& v, size_t i) { + memcpy(&v, static_cast(data()) + offsets[i], sizes[i]); + }; + ::libpressio::detail::tuple_for_each_with_index(t, copy); + + return t; + } /** * convert a pressio_data structure into a 1d c++ standard vector. If the type doesn't match, it will be casted first * \returns the vector containing the data diff --git a/include/libpressio_ext/cpp/domain.h b/include/libpressio_ext/cpp/domain.h index 6481ad17..d11d9f71 100644 --- a/include/libpressio_ext/cpp/domain.h +++ b/include/libpressio_ext/cpp/domain.h @@ -1,6 +1,7 @@ #ifndef PRESSIO_DOMAIN_H_Z2ALCUZG #define PRESSIO_DOMAIN_H_Z2ALCUZG #include +#include #include #include #include @@ -23,24 +24,30 @@ namespace libpressio { namespace domains { /** * domains accept a subset of options that pressio_options do to break the circular dependency */ +/** Value type used by domain option maps. */ using domain_option = std::variant,bool,std::any>; +/** Map type used to configure domains. */ using domain_options = std::map; +/** Status codes returned by domain option accessors. */ enum class domain_option_key_status { key_set = 0, key_exists = 1, key_does_not_exist = 2, }; +/** Set a domain option by key. */ template domain_option_key_status set(domain_options& opts, std::string const& key, T&& value) { opts[key] = std::forward(value); return domain_option_key_status::key_set; } +/** Set a domain option using a component name and option key. */ template domain_option_key_status set(domain_options& opts, std::string const& name, std::string const& key, T&& value) { std::string full_name = libpressio::names::format_name(name, key); return set(opts, full_name, std::forward(value)); } +/** Retrieve a domain option by key when the stored type matches `T`. */ template domain_option_key_status get(domain_options const& opts, std::string const& key, T& value) { auto it = opts.find(key); @@ -56,6 +63,7 @@ domain_option_key_status get(domain_options const& opts, std::string const& key, return domain_option_key_status::key_does_not_exist; } } +/** Retrieve a named domain option by searching the component hierarchy. */ template domain_option_key_status get(domain_options const& opts, std::string const& name, std::string const& key, T& value) { std::string prefix_key; @@ -68,6 +76,7 @@ domain_option_key_status get(domain_options const& opts, std::string const& name return get(opts, key, value); } +/** Store a nested configurable domain object and its options into a map. */ template domain_option_key_status set_meta(domain_options& opts, std::string const& name, std::string const& key, Wrapper&& current_value) { auto ret = set(opts, name, key, current_value->prefix()); @@ -77,6 +86,7 @@ domain_option_key_status set_meta(domain_options& opts, std::string const& name, } return ret; } +/** Rebuild and configure a nested domain object from an option map. */ template domain_option_key_status get_meta(domain_options& opts, std::string const& name, std::string const& key, Registry const& registry, Wrapper&& current_value) { std::string new_plugin; @@ -103,7 +113,9 @@ domain_option_key_status get_meta(domain_options& opts, std::string const& name, } +/** Format a domain option map as a human-readable string. */ std::string to_string(domain_options const& op); +/** Format a single domain option as a human-readable string. */ std::string to_string(domain_option const& op); @@ -118,6 +130,7 @@ namespace detail { */ template struct maybe_assign { + /** Assign the visited value when the types match. */ template typename std::enable_if< std::is_same< @@ -130,6 +143,7 @@ namespace detail { lhs = rhs; return domain_option_key_status::key_set; } + /** Report that the key exists but holds a different type. */ template typename std::enable_if< !std::is_same< @@ -142,10 +156,12 @@ namespace detail { (void) rhs; return domain_option_key_status::key_exists; } + /** Destination reference used for assignment. */ T&& lhs; }; } +/** Retrieve a domain option by key, assigning into a compatible destination. */ template domain_option_key_status get(domain_options const& opts, std::string const& key, T&& value) { auto it = opts.find(key); @@ -155,6 +171,7 @@ domain_option_key_status get(domain_options const& opts, std::string const& key, return domain_option_key_status::key_does_not_exist; } } +/** Retrieve a named domain option, assigning into a compatible destination. */ template domain_option_key_status get(domain_options const& opts, std::string const& name, std::string const& key, T&& value) { std::string prefix_key; @@ -240,9 +257,6 @@ struct pressio_domain { * name for this particular domain */ void set_name(std::string const&); - /** - * name for this particular domain - */ /** * name for this particular domain */ @@ -318,6 +332,7 @@ struct pressio_domain { virtual domain_options get_configuration_impl() const { return {}; } + /** Callback invoked after the domain name is updated. */ virtual void set_name_impl(std::string const&) { } /** @@ -341,6 +356,7 @@ struct pressio_domain { */ bool is_accessible(pressio_domain const& lhs, pressio_domain const& rhs); } +/** Return the registry of available domain plugins. */ pressio_registry>& domain_plugins(); /** diff --git a/include/libpressio_ext/cpp/domain_manager.h b/include/libpressio_ext/cpp/domain_manager.h index 5069a67c..001bef4e 100644 --- a/include/libpressio_ext/cpp/domain_manager.h +++ b/include/libpressio_ext/cpp/domain_manager.h @@ -13,7 +13,9 @@ namespace libpressio { namespace domains_metrics { * callback class for the domain manager */ struct pressio_domain_manager_metrics_plugin { + /** Construct the default no-op metrics plugin. */ pressio_domain_manager_metrics_plugin()=default; + /** Destroy the metrics plugin. */ virtual ~pressio_domain_manager_metrics_plugin()=default; /** * called before memory is allocated from a domain @@ -63,6 +65,14 @@ struct pressio_domain_manager_metrics_plugin { * called after data is requested to be readable on a domain */ virtual void make_readable_domain_end(std::shared_ptr const& dst, pressio_data const& src) {(void)src; (void)dst;}; + /** + * called before data is copied + */ + virtual void copy_to_begin(std::shared_ptr const& dst, pressio_data const& src) {(void)src; (void)dst;}; + /** + * called after data is copied + */ + virtual void copy_to_end(std::shared_ptr const& dst, pressio_data const& src) {(void)src; (void)dst;}; /** * called before data is copied */ @@ -92,6 +102,7 @@ struct pressio_domain_manager_metrics_plugin { /* * id of the module */ + /** \returns the metrics plugin identifier. */ virtual const char* prefix() const { return "noop"; } @@ -115,6 +126,7 @@ struct pressio_domain_manager_metrics_plugin { virtual void set_name_impl(std::string const&) { } private: + /** Name assigned to this metrics plugin instance. */ std::string name; }; }} @@ -128,29 +140,43 @@ libpressio::pressio_registry(std::move(rhs))) {} + /** Construct with the default no-op metrics plugin. */ pressio_domain_manager_metrics(): plg(std::make_unique()) {} + /** Construct from an owned plugin instance. */ pressio_domain_manager_metrics(std::unique_ptr && rhs): plg(std::move(rhs)) {} + /** Copy by cloning the wrapped plugin. */ pressio_domain_manager_metrics(pressio_domain_manager_metrics const& rhs): plg(rhs.plg->clone()) {} + /** Move the wrapped plugin. */ pressio_domain_manager_metrics(pressio_domain_manager_metrics && rhs) noexcept: plg(std::exchange(rhs.plg, {})) {} + /** Copy-assign by cloning the wrapped plugin. */ pressio_domain_manager_metrics& operator=(pressio_domain_manager_metrics const& rhs) noexcept { if(&rhs == this) return *this; plg = rhs.plg->clone(); return *this; } + /** Move-assign the wrapped plugin. */ pressio_domain_manager_metrics& operator=(pressio_domain_manager_metrics && rhs) noexcept { if(&rhs == this) return *this; plg = std::exchange(rhs.plg, {}); return *this; } + /** Dereference the wrapped metrics plugin. */ libpressio::domains_metrics::pressio_domain_manager_metrics_plugin& operator*() { return *plg; } + /** Access the wrapped metrics plugin. */ libpressio::domains_metrics::pressio_domain_manager_metrics_plugin* operator->() { return plg.operator->(); } + /** Dereference the wrapped metrics plugin. */ libpressio::domains_metrics::pressio_domain_manager_metrics_plugin const& operator*() const { return *plg; } + /** Access the wrapped metrics plugin. */ libpressio::domains_metrics::pressio_domain_manager_metrics_plugin const* operator->() const { return plg.operator->(); } + /** \returns true when a plugin is present. */ operator bool() const { return static_cast(plg); } + /** Owned metrics plugin instance. */ std::unique_ptr plg; }; @@ -190,6 +216,16 @@ struct pressio_domain_manager { metrics->make_readable_domain_end(dst, src); return ret; } + /** + * make data readable using the provided domain + */ + template + pressio_data make_readable(std::shared_ptr const& dst, T&& src) { + metrics->make_readable_domain_begin(dst, src); + auto ret = make_readable_impl(dst, std::forward(src)); + metrics->make_readable_domain_end(dst, src); + return ret; + } /** * copy data to the specified memory, or move if both pointers are in the same domain @@ -197,7 +233,7 @@ struct pressio_domain_manager { template pressio_data copy_to(pressio_data&& dst, T&& src) { metrics->copy_to_begin(dst, src); - auto ret = copy_to_impl(dst, std::forward(src)); + auto ret = copy_to_impl(std::move(dst), std::forward(src)); metrics->copy_to_end(dst, src); return ret; } @@ -207,7 +243,20 @@ struct pressio_domain_manager { */ template pressio_data copy_to(std::shared_ptr&& dst, T&& src) { + metrics->copy_to_begin(dst, src); auto ret = copy_to_impl(std::move(dst), std::forward(src)); + metrics->copy_to_end(dst, src); + return ret; + } + + /** + * copy data to the specified memory, or move if both pointers are in the same domain + */ + template + pressio_data copy_to(std::shared_ptr const& dst, T&& src) { + metrics->copy_to_begin(dst, src); + auto ret = copy_to_impl(dst, std::forward(src)); + metrics->copy_to_end(dst, src); return ret; } @@ -236,6 +285,9 @@ struct pressio_domain_manager { return this->metrics->set_options(opts); } + /** + * set the name used to namespace the domain manager metrics + */ void set_name(std::string const& new_name) { name = new_name; if(new_name.empty()) { @@ -258,6 +310,7 @@ struct pressio_domain_manager { } protected: + /** Send data between two non-accessible domains. */ virtual void send_impl(pressio_data& dst, pressio_data const& src) { auto method = src.domain()->domain_id() + ">" + dst.domain()->domain_id(); auto sender = domain_send_plugins().build(method); @@ -269,6 +322,7 @@ struct pressio_domain_manager { } + /** Make data readable using a destination buffer when possible. */ virtual pressio_data make_readable_impl(pressio_data&& dst, pressio_data const& src) { if(is_accessible(*dst.domain(), *src.domain())) { metrics->view_begin(dst.domain(), src); @@ -289,9 +343,30 @@ struct pressio_domain_manager { } return std::move(dst); } + /** Make data readable using a destination buffer, reusing the source when possible. */ virtual pressio_data make_readable_impl(pressio_data&& dst, pressio_data&& src) { return make_readable_impl(std::move(dst), src); } + /** Make data readable in the requested destination domain. */ + virtual pressio_data make_readable_impl(std::shared_ptr const& dst, pressio_data const& src) { + if(is_accessible(*dst, *src.domain())) { + metrics->view_begin(dst, src); + pressio_data out(pressio_data::nonowning(src)); + metrics->view_end(dst, src); + return out; + } else { + if(src.has_data()) { + metrics->alloc_begin(dst, src.dtype(), src.dimensions()); + pressio_data out(pressio_data::owning(src.dtype(), src.dimensions(), dst)); + metrics->alloc_end(dst, src.dtype(), src.dimensions()); + send(out, src); + return out; + } else { + return pressio_data::empty(src.dtype(), src.dimensions(), dst); + } + } + } + /** Make data readable in the requested destination domain. */ virtual pressio_data make_readable_impl(std::shared_ptr&& dst, pressio_data const& src) { if(is_accessible(*dst, *src.domain())) { metrics->view_begin(dst, src); @@ -310,10 +385,12 @@ struct pressio_domain_manager { } } } + /** Make data readable in the requested destination domain, reusing the source when possible. */ virtual pressio_data make_readable_impl(std::shared_ptr&& dst, pressio_data&& src) { return make_readable_impl(std::move(dst), src); } + /** Copy or move data into a destination buffer. */ virtual pressio_data copy_to_impl(pressio_data&& dst, pressio_data &&src) { if(!src.has_data()) throw std::runtime_error("cannot send from a source that is unallocated"); if(is_accessible(*dst.domain(), *src.domain())) { @@ -329,6 +406,7 @@ struct pressio_domain_manager { return std::move(dst); } } + /** Copy data into a destination buffer. */ virtual pressio_data copy_to_impl(pressio_data&& dst, pressio_data const&src) { if(!src.has_data()) throw std::runtime_error("cannot send from a source that is unallocated"); if(is_accessible(*dst.domain(), *src.domain())) { @@ -345,6 +423,7 @@ struct pressio_domain_manager { return dst; } } + /** Copy or move data into a newly allocated destination domain. */ virtual pressio_data copy_to_impl(std::shared_ptr&& dst, pressio_data &&src) { if(!src.has_data()) throw std::runtime_error("cannot send from a source that is unallocated"); if(is_accessible(*dst, *src.domain())) { @@ -357,6 +436,7 @@ struct pressio_domain_manager { return out; } } + /** Copy data into a newly allocated destination domain. */ virtual pressio_data copy_to_impl(std::shared_ptr&& dst, pressio_data const&src) { if(!src.has_data()) throw std::runtime_error("cannot send from a source that is unallocated"); if(is_accessible(*dst, *src.domain())) { @@ -373,13 +453,66 @@ struct pressio_domain_manager { return out; } } + /** Copy or move data into the requested destination domain. */ + virtual pressio_data copy_to_impl(std::shared_ptr const& dst, pressio_data &&src) { + if(!src.has_data()) throw std::runtime_error("cannot send from a source that is unallocated"); + if(is_accessible(*dst, *src.domain())) { + return std::move(src); + } else { + metrics->alloc_begin(dst, src.dtype(), src.dimensions()); + auto out = pressio_data::owning(src.dtype(), src.dimensions(), dst); + metrics->alloc_end(dst, src.dtype(), src.dimensions()); + send(out, src); + return out; + } + } + /** Copy data into the requested destination domain. */ + virtual pressio_data copy_to_impl(std::shared_ptr const& dst, pressio_data const&src) { + if(!src.has_data()) throw std::runtime_error("cannot send from a source that is unallocated"); + if(is_accessible(*dst, *src.domain())) { + metrics->alloc_begin(dst, src.dtype(), src.dimensions()); + pressio_data out = pressio_data::owning(src.dtype(), src.dimensions(), dst); + metrics->alloc_end(dst, src.dtype(), src.dimensions()); + out = src; + return out; + } else { + metrics->alloc_begin(dst, src.dtype(), src.dimensions()); + auto out = pressio_data::owning(src.dtype(), src.dimensions(), dst); + metrics->alloc_end(dst, src.dtype(), src.dimensions()); + send(out, src); + return out; + } + } + /** Create a writable buffer in the requested destination domain. */ + virtual pressio_data make_writeable_impl(std::shared_ptr const& dst, pressio_data const& src) { + metrics->alloc_begin(dst, src.dtype(), src.dimensions()); + pressio_data out = pressio_data::owning(src.dtype(), src.dimensions(), dst); + metrics->alloc_end(dst, src.dtype(), src.dimensions()); + return out; + } + /** Create a writable buffer or reuse the source when it is already writable. */ + virtual pressio_data make_writeable_impl(std::shared_ptr const& dst, pressio_data && src) { + if(is_accessible(*dst, *src.domain()) && src.has_data()) { + metrics->view_begin(dst, src); + pressio_data out(std::move(src)); + metrics->view_end(dst, src); + return out; + } else { + metrics->alloc_begin(dst, src.dtype(), src.dimensions()); + pressio_data out = pressio_data::owning(src.dtype(), src.dimensions(), dst); + metrics->alloc_end(dst, src.dtype(), src.dimensions()); + return out; + } + } + /** Create a writable buffer in the requested destination domain. */ virtual pressio_data make_writeable_impl(std::shared_ptr&& dst, pressio_data const& src) { metrics->alloc_begin(dst, src.dtype(), src.dimensions()); pressio_data out = pressio_data::owning(src.dtype(), src.dimensions(), std::move(dst)); metrics->alloc_end(dst, src.dtype(), src.dimensions()); return out; } + /** Create a writable buffer or reuse the source when it is already writable. */ virtual pressio_data make_writeable_impl(std::shared_ptr&& dst, pressio_data && src) { if(is_accessible(*dst, *src.domain()) && src.has_data()) { metrics->view_begin(dst, src); @@ -394,7 +527,10 @@ struct pressio_domain_manager { } } + /** Name used to scope the domain manager metrics. */ + /** Name used to scope the domain manager metrics. */ std::string name; + /** Metrics plugin used to observe domain manager operations. */ pressio_domain_manager_metrics metrics; }; diff --git a/include/libpressio_ext/cpp/domain_send.h b/include/libpressio_ext/cpp/domain_send.h index 6bc71b15..62d6fae9 100644 --- a/include/libpressio_ext/cpp/domain_send.h +++ b/include/libpressio_ext/cpp/domain_send.h @@ -8,13 +8,30 @@ struct pressio_data; namespace libpressio { namespace domains { + /** + * a plugin that understands how to transfer data from one memory domain (e.g. malloc, cudamalloc) to another + */ struct pressio_domain_send { + /** + * create an instance of a send plugin + */ pressio_domain_send()=default; + /** + * destroy an instance of a send plugin + */ virtual ~pressio_domain_send()=default; + /** + * copy data from src to dst. Throws an exception on error + * \param[in] src the source data buffer + * \param[in] dst the destination data buffer + */ virtual void send(pressio_data& dst, pressio_data const& src) const = 0; }; } +/** + * registry for all send plugins + */ pressio_registry>& domain_send_plugins(); } diff --git a/include/libpressio_ext/cpp/json.h b/include/libpressio_ext/cpp/json.h index be64a4bf..1a1fa92d 100644 --- a/include/libpressio_ext/cpp/json.h +++ b/include/libpressio_ext/cpp/json.h @@ -10,10 +10,16 @@ struct pressio_data; struct pressio_option; struct pressio_options; +/** Serialize a `pressio_data` object into JSON. */ void to_json(nlohmann::json& j, pressio_data const& data); +/** Serialize a `pressio_option` object into JSON. */ void to_json(nlohmann::json& j, pressio_option const& option); +/** Serialize a `pressio_options` object into JSON. */ void to_json(nlohmann::json& j, pressio_options const& options); +/** Deserialize a `pressio_data` object from JSON. */ void from_json(nlohmann::json const& j, pressio_data& data); +/** Deserialize a `pressio_option` object from JSON. */ void from_json(nlohmann::json const& j, pressio_option& option); +/** Deserialize a `pressio_options` object from JSON. */ void from_json(nlohmann::json const& j, pressio_options& options); #endif /* end of include guard: LIBPRESSIO_CPP_JSON_H */ diff --git a/include/libpressio_ext/cpp/memory.h b/include/libpressio_ext/cpp/memory.h index 954468f3..8134b97b 100644 --- a/include/libpressio_ext/cpp/memory.h +++ b/include/libpressio_ext/cpp/memory.h @@ -9,6 +9,10 @@ * \brief C++ interface to managed memory objects from domaines */ +/** + * an interface to manage linear memories on various domains + * This just tracks the pointer and the capacity, higher level functions can be found in pressio_data + */ class pressio_memory { private: std::shared_ptr data_domain; diff --git a/include/libpressio_ext/cpp/options.h b/include/libpressio_ext/cpp/options.h index 3a74df83..6c563f4d 100644 --- a/include/libpressio_ext/cpp/options.h +++ b/include/libpressio_ext/cpp/options.h @@ -462,19 +462,19 @@ struct pressio_options final { /** * gets a key if it is set and stores it into the pointer value * \param[in] key the option to retrieve - * \param[out] value the value that is in the option + * \param[out] outvalue the value that is in the option * \returns pressio_options_key_does_not_exist if the key does not exist * pressio_options_key_exists if the key exists but has no value * pressio_options_key_set if the key exists and is set */ template - enum pressio_options_key_status get(StringType const& key, compat::optional* value) const { + enum pressio_options_key_status get(StringType const& key, compat::optional* outvalue) const { switch(key_status(key)){ case pressio_options_key_set: { auto variant = get(key); if (variant.template holds_alternative()) { - *value = variant.template get(); + *outvalue = variant.template get(); return pressio_options_key_set; } else { return pressio_options_key_exists; @@ -490,20 +490,20 @@ struct pressio_options final { /** * gets a key if it is set and stores it into the pointer value * \param[in] key the option to retrieve - * \param[out] value the value that is in the option + * \param[out] outvalue the value that is in the option * \returns pressio_options_key_does_not_exist if the key does not exist * pressio_options_key_exists if the key exists but has no value * pressio_options_key_set if the key exists and is set */ template - enum pressio_options_key_status get(StringType const& key, PointerType value) const { + enum pressio_options_key_status get(StringType const& key, PointerType outvalue) const { using ValueType = typename std::remove_pointer::type; switch(key_status(key)){ case pressio_options_key_set: { auto variant = get(key); if (variant.template holds_alternative()) { - *value = variant.template get_value(); + *outvalue = variant.template get_value(); return pressio_options_key_set; } else { return pressio_options_key_exists; @@ -520,34 +520,34 @@ struct pressio_options final { * gets a key if it is set and stores it into the pointer value * \param[in] name the name to use. Checks for the named version first, then the unnamed * \param[in] key the option to retrieve - * \param[out] value the value that is in the option + * \param[out] outvalue the value that is in the option * \returns pressio_options_key_does_not_exist if the key does not exist * pressio_options_key_exists if the key exists but has no value * pressio_options_key_set if the key exists and is set */ template - enum pressio_options_key_status get(StringType const& name, StringType2 const& key, PointerType value) const { + enum pressio_options_key_status get(StringType const& name, StringType2 const& key, PointerType outvalue) const { std::string prefix_key; for (auto path : libpressio::names::search(name)) { prefix_key = libpressio::names::format_name(std::string(path), key); if(options.find(prefix_key) != options.end()) { - return get(prefix_key, value); + return get(prefix_key, outvalue); } } - return get(key, value); + return get(key, outvalue); } /** * gets a key if it is set, attepts to cast it the specified type and stores it into the pointer value * \param[in] key the option to retrieve - * \param[out] value the value that is in the option + * \param[out] outvalue the value that is in the option * \param[in] safety the level of conversions to allow \see pressio_conversion_safety * \returns pressio_options_key_does_not_exist if the key does not exist * pressio_options_key_exists if the key exists but has no value * pressio_options_key_set if the key exists and is set */ template - enum pressio_options_key_status cast(StringType const& key, PointerType value, enum pressio_conversion_safety safety) const { + enum pressio_options_key_status cast(StringType const& key, PointerType outvalue, enum pressio_conversion_safety safety) const { using ValueType = typename std::remove_pointer::type; switch(key_status(key)){ case pressio_options_key_set: @@ -555,7 +555,7 @@ struct pressio_options final { auto variant = get(key); auto converted = pressio_option(variant).as(pressio_type_to_enum(), safety); if(converted.has_value()) { - *value = converted.template get_value(); + *outvalue = converted.template get_value(); return pressio_options_key_set; } else { return pressio_options_key_exists; @@ -572,22 +572,22 @@ struct pressio_options final { * gets a key if it is set, attepts to cast it the specified type and stores it into the pointer value * \param[in] name the name to use. Checks for the named version first, then the unnamed * \param[in] key the option to retrieve - * \param[out] value the value that is in the option + * \param[out] outvalue the value that is in the option * \param[in] safety the level of conversions to allow \see pressio_conversion_safety * \returns pressio_options_key_does_not_exist if the key does not exist * pressio_options_key_exists if the key exists but has no value * pressio_options_key_set if the key exists and is set */ template - enum pressio_options_key_status cast(StringType const& name, StringType2 const& key, PointerType value, enum pressio_conversion_safety safety) const { + enum pressio_options_key_status cast(StringType const& name, StringType2 const& key, PointerType outvalue, enum pressio_conversion_safety safety) const { std::string prefix_key; for (auto path : libpressio::names::search(name)) { prefix_key = libpressio::names::format_name(std::string(path), std::string(key)); if(options.find(prefix_key) != options.end()) { - return cast(prefix_key, value, safety); + return cast(prefix_key, outvalue, safety); } } - return cast(key, value, safety); + return cast(key, outvalue, safety); } /** diff --git a/include/libpressio_ext/cpp/registry.h b/include/libpressio_ext/cpp/registry.h index 091f4845..2d38eb02 100644 --- a/include/libpressio_ext/cpp/registry.h +++ b/include/libpressio_ext/cpp/registry.h @@ -137,10 +137,12 @@ class pressio_register{ do_register(); } + /** Unregister the plugin when this helper is destroyed. */ ~pressio_register(){ unregister(); } + /** Ensure the plugin factory has been registered. */ bool ensure_registered() { return do_register(); } @@ -149,6 +151,7 @@ class pressio_register{ std::string name; /** call to unregister the plugin */ std::function unregister; + /** call to register the plugin */ std::function do_register; }; diff --git a/include/libpressio_ext/cpp/userptr.h b/include/libpressio_ext/cpp/userptr.h index 5dbc8e2c..1c5eb88d 100644 --- a/include/libpressio_ext/cpp/userptr.h +++ b/include/libpressio_ext/cpp/userptr.h @@ -8,12 +8,16 @@ */ extern "C" { +/** No-op deleter for non-owning userdata. */ void static_deleter(void*, void*); +/** No-op copy helper for non-owning userdata. */ void static_copy(void**, void**, const void*, const void*); } +/** Function pointer type used to destroy userdata. */ using userdata_deleter_t = void(*)(void*, void*); template +/** Construct a deleter that destroys userdata with `delete`. */ userdata_deleter_t newdelete_deleter() { return [](void* ptr, void*) { T* ptr_typed = static_cast(ptr); @@ -21,8 +25,10 @@ userdata_deleter_t newdelete_deleter() { }; } +/** Function pointer type used to deep-copy userdata. */ using userdata_copy_t = void(*)(void** dst, void**, const void* src, const void*); template +/** Construct a copier that clones userdata with copy construction. */ userdata_copy_t newdelete_copy() { return [](void** dst, void**, const void* src, const void*) { T const* src_typed = static_cast(src); @@ -115,6 +121,7 @@ class userdata { return ptr == data.ptr; } + /** Release the owned userdata, if any. */ ~userdata() { if(deleter != nullptr) { deleter(ptr, metadata); diff --git a/include/libpressio_ext/hash/libpressio_hash.h b/include/libpressio_ext/hash/libpressio_hash.h index 3b846c32..d89f0681 100644 --- a/include/libpressio_ext/hash/libpressio_hash.h +++ b/include/libpressio_ext/hash/libpressio_hash.h @@ -21,7 +21,7 @@ struct pressio_options; * \param[out] output_size the size of the returned hash * \returns memory containing the hash as bytes, should be freed with free */ -uint8_t* libpressio_options_hashkeys(struct pressio* library, struct pressio_options const* options, size_t* output_size); +uint8_t* pressio_options_hashkeys(struct pressio* library, struct pressio_options const* options, size_t* output_size); /** * hash the entries of a pressio_options value @@ -43,7 +43,7 @@ uint8_t* libpressio_options_hashkeys(struct pressio* library, struct pressio_opt * \param[out] output_size the size of the returned hash * \returns memory containing the hash as bytes, should be freed with free */ -uint8_t* libpressio_options_hashentries(struct pressio* library, struct pressio_options const* options, size_t* output_size); +uint8_t* pressio_options_hashentries(struct pressio* library, struct pressio_options const* options, size_t* output_size); #ifdef __cplusplus } diff --git a/include/libpressio_ext/io/pressio_io.h b/include/libpressio_ext/io/pressio_io.h index 2936fd32..050eb0c7 100644 --- a/include/libpressio_ext/io/pressio_io.h +++ b/include/libpressio_ext/io/pressio_io.h @@ -137,18 +137,17 @@ int pressio_io_patch_version(struct pressio_io const* io); struct pressio_io* pressio_io_clone(struct pressio_io* io); /** - * Assign a new name to a io. Names are used to prefix options in meta-ios. + * Assign a new name to an io. Names are used to prefix options in meta-ios. * - * sub-ios will be renamed either by the of the sub-ios prefix - * or by the $prefix:name configuration option + * Sub-ios are renamed either by their sub-io prefix or by the `$prefix:name` + * configuration option. * - * i.e. for some new_name and a io with prefix foo and subios - * with prefixs "abc", "def", "ghi" respectively + * For example, if `foo:names = ['one', 'two', 'three']`, the resulting names + * become `$new_name/one`, `$new_name/two`, and `$new_name/three`. Otherwise, + * the sub-ios keep their prefixes and become `$new_name/abc`, + * `$new_name/def`, and `$new_name/ghi`. * - * - if foo:names = ['one', 'two', 'three'], then the names will be `$new_name/one, $new_name/two $new_name/three - * - otherwise the names will be $new_name/abc, $new_name/def, $new_name/ghi - * - * \param[in] io the io to get the name of + * \param[in] io the io whose name will be updated * \param[in] new_name the name to set */ void pressio_io_set_name(struct pressio_io* io, const char* new_name); diff --git a/include/libpressio_ext/launch/external_launch.h b/include/libpressio_ext/launch/external_launch.h index 8470105f..71d092fb 100644 --- a/include/libpressio_ext/launch/external_launch.h +++ b/include/libpressio_ext/launch/external_launch.h @@ -40,6 +40,10 @@ struct libpressio_launch_plugin: public pressio_configurable { return ret; } + /** + * expose the command that would be launched to metrics plugins + * \param[in] args the command arguments + */ void view_command(std::vector const& args) const { metrics_plugin->view_command(args); } @@ -176,6 +180,7 @@ struct libpressio_launch_plugin: public pressio_configurable { /** * the registry for launch plugins */ +/** Return the registry of available launch plugins. */ pressio_registry>& launch_plugins(); } diff --git a/include/libpressio_ext/launch/external_launch_metrics.h b/include/libpressio_ext/launch/external_launch_metrics.h index 5f20be87..ca527674 100644 --- a/include/libpressio_ext/launch/external_launch_metrics.h +++ b/include/libpressio_ext/launch/external_launch_metrics.h @@ -85,6 +85,7 @@ struct libpressio_launch_metrics_plugin : public pressio_configurable { } }; } +/** Return the registry of available launch metrics plugins. */ pressio_registry>& launch_metrics_plugins(); } diff --git a/include/pressio_compressor.h b/include/pressio_compressor.h index 9d6c0ee6..01a78673 100644 --- a/include/pressio_compressor.h +++ b/include/pressio_compressor.h @@ -198,18 +198,18 @@ struct pressio_compressor* pressio_compressor_clone(struct pressio_compressor* c const char* pressio_compressor_get_prefix(const struct pressio_compressor* compressor); /** - * Assign a new name to a compressor. Names are used to prefix options in meta-compressors. + * Assign a new name to a compressor. Names are used to prefix options in + * meta-compressors. * - * sub-compressors will be renamed either by the of the sub-compressors prefix - * or by the $prefix:name configuration option + * Sub-compressors are renamed either by their sub-compressor prefix or by the + * `$prefix:name` configuration option. * - * i.e. for some new_name and a compressor with prefix foo and subcompressors - * with prefixs "abc", "def", "ghi" respectively + * For example, if `foo:names = ['one', 'two', 'three']`, the resulting names + * become `$new_name/one`, `$new_name/two`, and `$new_name/three`. Otherwise, + * the sub-compressors keep their prefixes and become `$new_name/abc`, + * `$new_name/def`, and `$new_name/ghi`. * - * - if foo:names = ['one', 'two', 'three'], then the names will be `$new_name/one, $new_name/two $new_name/three - * - otherwise the names will be $new_name/abc, $new_name/def, $new_name/ghi - * - * \param[in] compressor the compressor to get the name of + * \param[in] compressor the compressor whose name will be updated * \param[in] new_name the name to set */ void pressio_compressor_set_name(struct pressio_compressor* compressor, const char* new_name); diff --git a/include/pressio_metrics.h b/include/pressio_metrics.h index bbdf5223..20450072 100644 --- a/include/pressio_metrics.h +++ b/include/pressio_metrics.h @@ -66,18 +66,18 @@ struct pressio_metrics* pressio_metrics_clone(struct pressio_metrics* metrics); /** - * Assign a new name to a metrics. Names are used to prefix options in meta-metrics. + * Assign a new name to a metrics object. Names are used to prefix options in + * meta-metrics. * - * sub-metrics will be renamed either by the of the sub-metricss prefix - * or by the $prefix:name configuration option + * Sub-metrics are renamed either by their sub-metric prefix or by the + * `$prefix:name` configuration option. * - * i.e. for some new_name and a metrics with prefix foo and submetricss - * with prefixs "abc", "def", "ghi" respectively + * For example, if `foo:names = ['one', 'two', 'three']`, the resulting names + * become `$new_name/one`, `$new_name/two`, and `$new_name/three`. Otherwise, + * the sub-metrics keep their prefixes and become `$new_name/abc`, + * `$new_name/def`, and `$new_name/ghi`. * - * - if foo:names = ['one', 'two', 'three'], then the names will be `$new_name/one, $new_name/two $new_name/three - * - otherwise the names will be $new_name/abc, $new_name/def, $new_name/ghi - * - * \param[in] metrics the metrics to get the name of + * \param[in] metrics the metrics object whose name will be updated * \param[in] new_name the name to set */ void pressio_metrics_set_name(struct pressio_metrics* metrics, const char* new_name); diff --git a/include/pressio_options.h b/include/pressio_options.h index 56fb9124..bebce31e 100644 --- a/include/pressio_options.h +++ b/include/pressio_options.h @@ -198,12 +198,12 @@ size_t pressio_options_num_set(struct pressio_options const* options); * pressio_options_get_string returns a newly allocated copy of the string \param[in] options the options structure to modify \param[in] key the key to change - \param[out] value the value retrieved + \param[out] outvalue the value retrieved \returns a status code \see pressio_options_key_status status codes returned */ \ enum pressio_options_key_status pressio_options_get_##name(struct pressio_options \ - const* options, const char* key, type * value); + const* options, const char* key, type * outvalue); /** internal macro used to define casting functions */ #define pressio_options_define_type_cast(name, type) \ @@ -211,25 +211,25 @@ size_t pressio_options_num_set(struct pressio_options const* options); \param[in] options the options structure to modify \param[in] key the key to change \param[in] safety what kind of conversions to allow - \param[out] value the value retrieved, only if it is convertible. If returning a char*, the memory must be freed with free() + \param[out] outvalue the value retrieved, only if it is convertible. If returning a char*, the memory must be freed with free() \returns a status code \see pressio_options_key_status status codes returned */ \ enum pressio_options_key_status pressio_options_cast_##name(struct pressio_options \ const* options, const char* key, const enum pressio_conversion_safety safety, \ - type * value); + type * outvalue); /** internal macro used to define implicit casting functions */ #define pressio_options_define_type_as(name, type) \ /** Gets an particular key in an options structure, casting it if necessary \param[in] options the options structure to modify \param[in] key the key to change - \param[out] value the value retrieved, only if it is convertible. If returning a char*, the memory must be freed with free() + \param[out] outvalue the value retrieved, only if it is convertible. If returning a char*, the memory must be freed with free() \returns a status code \see pressio_options_key_status status codes returned */ \ enum pressio_options_key_status pressio_options_as_##name(struct pressio_options \ - const* options, const char* key, type * value); + const* options, const char* key, type * outvalue); /** * Generate get/set/as/cast functions for the pressio_options class @@ -297,34 +297,35 @@ void pressio_options_set_strings(struct pressio_options* options, const char* ke \param[in] options the options structure to modify \param[in] key the key to change \param[out] size the number of strings returned, 0 on error - \param[out] values the value retrieved, both the values and the pointer must be freed with free() + \param[out] outvalues the value retrieved, both the values and the pointer must be freed with free() \returns a status code \see pressio_options_key_status status codes returned */ -enum pressio_options_key_status pressio_options_get_strings(struct pressio_options const* options, const char* key, size_t* size, const char*** values); +enum pressio_options_key_status pressio_options_get_strings(struct pressio_options const* options, const char* key, size_t* size, const char*** outvalues); /** Gets an particular key in an options structure, casting it if necessary \param[in] options the options structure to modify \param[in] key the key to change \param[in] safety what kind of conversions to allow \param[out] size the number of strings returned. 0 on error - \param[out] values the value retrieved, only if it is convertible. both the values and the pointer must be freed with free() + \param[out] outvalues the value retrieved, only if it is convertible. both the values and the pointer must be freed with free() \returns a status code \see pressio_options_key_status status codes returned */ \ enum pressio_options_key_status pressio_options_cast_strings(struct pressio_options \ const* options, const char* key, const enum pressio_conversion_safety safety, \ - size_t* size, char*** values); - /** Gets an particular key in an options structure, casting it if necessary - \param[in] options the options structure to modify - \param[in] key the key to change - \param[out] size the number of strings returned. 0 on error - \param[out] values the value retrieved, only if it is convertible. both the values and the pointer must be freed with free() - \returns a status code - \see pressio_options_key_status status codes returned - */ \ + size_t* size, char*** outvalues); + /** Gets an particular key in an options structure, casting it if necessary + \param[in] options the options structure to modify + \param[in] key the key to change + \param[out] size the number of strings returned. 0 on error + \param[out] values the value retrieved, only if it is convertible. both the values and the pointer must be freed with free() + \returns a status code + \see pressio_options_key_status status codes returned + */ \ enum pressio_options_key_status pressio_options_as_strings(struct pressio_options \ const* options, const char* key, size_t* size, char*** values); + /** * Create a human readable string for the options passed. * diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..51349ce7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,63 @@ +[build-system] +requires = [ + "setuptools>=42", + "scikit-build-core>=0.10", + "cmake>=3.18", + "ninja", + "swig", +] +build-backend = "scikit_build_core.build" + +[project] +name = "libpressio" +version = "1.0.7" +requires-python = ">= 3.8" +authors = [ + {name ="Robert Underwood", email ="runderwood@anl.gov" }, +] +maintainers = [ + {name ="Robert Underwood", email ="runderwood@anl.gov" }, +] +description= "LibPressio a Generic Abstraction for Compressors" +readme = "README.md" +license = "BSD-4-Clause" +license-files = ["COPYRIGHT.txt"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Topic :: System :: Archiving :: Compression", + "Topic :: Software Development :: Libraries", + "Operating System :: POSIX :: Linux", + "Programming Language :: C", + "Programming Language :: C++", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", +] +keywords = ["libpressio", "compression", "interface"] +dependencies = [ + "numpy", + "numcodecs" +] + +[project.urls] +Homepage = "https://github.com/robertu94/libpressio" +Documentation = "https://robertu94.github.io/libpressio" +Respository = "https://github.com/robertu94/libpressio" + +[tool.scikit-build] +cmake.version = ">=3.18" +cmake.build-type = "Debug" +wheel.packages = [] +minimum-version = "build-system.requires" + +[tool.scikit-build.cmake.define] +BUILD_PYTHON_WRAPPER = true +BUILD_TESTING = false +LIBPRESSIO_BUILD_MODE = "FULL" + diff --git a/src/basic_indexer.h b/src/basic_indexer.h index 6f4fb913..e7f14afe 100644 --- a/src/basic_indexer.h +++ b/src/basic_indexer.h @@ -24,12 +24,12 @@ struct basic_indexer { }(args)) {} template - basic_indexer(It first, It second) noexcept: - max_dims([](It first, It second){ + basic_indexer(It first, It ) noexcept: + max_dims([](It first){ std::array dims; - std::copy(first, second, dims.begin()); + std::copy_n(first, N, dims.begin()); return dims; - }(first, second)) { + }(first)) { } template diff --git a/src/plugins/compressors/MGARDx.cc b/src/plugins/compressors/MGARDx.cc index f2c07cf4..d47a9d5f 100644 --- a/src/plugins/compressors/MGARDx.cc +++ b/src/plugins/compressors/MGARDx.cc @@ -52,6 +52,7 @@ class mgardx_compressor_plugin : public libpressio_compressor_plugin { struct pressio_options options; set(options, "pressio:thread_safe", pressio_thread_safety_multiple); set(options, "pressio:stability", "experimental"); + set(options, "pressio:highlevel", std::vector{"pressio:abs"}); return options; } diff --git a/src/plugins/compressors/arc.cc b/src/plugins/compressors/arc.cc index b900faaf..5a80c3cb 100644 --- a/src/plugins/compressors/arc.cc +++ b/src/plugins/compressors/arc.cc @@ -59,6 +59,7 @@ class arc_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", {&*impl}, {})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", {&*impl}, configs)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", {&*impl}, configs)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", {&*impl}, configs)); return options; } diff --git a/src/plugins/compressors/binning.cc b/src/plugins/compressors/binning.cc index 507ec947..7a99702e 100644 --- a/src/plugins/compressors/binning.cc +++ b/src/plugins/compressors/binning.cc @@ -104,7 +104,7 @@ class binning_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", {&*comp}, {})); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", {&*comp}, {"pressio:nthreads", "binning:nthreads"})); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", {&*comp}, std::vector{"pressio:nthreads"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", {&*comp}, std::vector{"pressio:nthreads", "binning:shape"})); return options; } diff --git a/src/plugins/compressors/bit_grooming.cc b/src/plugins/compressors/bit_grooming.cc index 354b8518..bfb05315 100644 --- a/src/plugins/compressors/bit_grooming.cc +++ b/src/plugins/compressors/bit_grooming.cc @@ -99,6 +99,7 @@ class bit_grooming_plugin : public libpressio_compressor_plugin { set(options, "pressio:stability", "experimental"); set(options, "bit_grooming:mode", bg_keys(bitgroom_mode_str_to_code)); set(options, "bit_grooming:error_control_mode", bg_keys(bitgroom_ec_mode_str_to_code)); + set(options, "pressio:highlevel", std::vector{"bit_grooming:mode_str", "bit_grooming:error_control_mode_str", "bit_grooming:n_sig_digits", "bit_grooming:n_sig_decimals"}); set(options, "predictors:error_agnostic", std::vector{"bit_grooming:mode", "bit_grooming:mode_str", "bit_grooming:error_control_mode", "bit_grooming:n_sig_digits", "bit_grooming:n_sig_decimals"}); set(options, "predictors:error_dependent", std::vector{"bit_grooming:mode", "bit_grooming:mode_str", "bit_grooming:error_control_mode", "bit_grooming:n_sig_digits", "bit_grooming:n_sig_decimals"}); set(options, "predictors:runtime", std::vector{"bit_grooming:mode", "bit_grooming:mode_str", "bit_grooming:error_control_mode", "bit_grooming:n_sig_digits", "bit_grooming:n_sig_decimals"}); diff --git a/src/plugins/compressors/blosc.cc b/src/plugins/compressors/blosc.cc index ea8cc4e5..c5ff0003 100644 --- a/src/plugins/compressors/blosc.cc +++ b/src/plugins/compressors/blosc.cc @@ -71,7 +71,7 @@ class blosc_plugin: public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, {})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:lossless", "pressio:nthreads"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:lossless", "pressio:nthreads", "blosc:compressor"})); return options; } diff --git a/src/plugins/compressors/blosc2.cc b/src/plugins/compressors/blosc2.cc index 1cc980f0..1f1d0496 100644 --- a/src/plugins/compressors/blosc2.cc +++ b/src/plugins/compressors/blosc2.cc @@ -78,7 +78,7 @@ class blosc2_plugin: public libpressio_compressor_plugin { "blosc2:numinternalthreads", }); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", {}, std::vector{"pressio:lossless", "pressio:nthreads"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", {}, std::vector{"pressio:lossless", "pressio:nthreads", "blosc2:compressor"})); return options; } diff --git a/src/plugins/compressors/cast.cc b/src/plugins/compressors/cast.cc index bf2f6b97..ad9d8091 100644 --- a/src/plugins/compressors/cast.cc +++ b/src/plugins/compressors/cast.cc @@ -30,7 +30,7 @@ class cast_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"cast:dtype", "cast:compressor"})); return options; } diff --git a/src/plugins/compressors/chunking.cc b/src/plugins/compressors/chunking.cc index 30e4e7b8..b1a806ac 100644 --- a/src/plugins/compressors/chunking.cc +++ b/src/plugins/compressors/chunking.cc @@ -43,7 +43,7 @@ class chunking_plugin: public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, {})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, std::vector{"chunking:size"})); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads", "chunking:size"})); return options; } diff --git a/src/plugins/compressors/cusz.cc b/src/plugins/compressors/cusz.cc index 508d556a..41592361 100644 --- a/src/plugins/compressors/cusz.cc +++ b/src/plugins/compressors/cusz.cc @@ -9,7 +9,7 @@ #include "libpressio_ext/cpp/domain_manager.h" #include #include -#include +#include #include #include #include @@ -232,27 +232,6 @@ class cusz_compressor_plugin : public libpressio_compressor_plugin { return set_error(12, cudaGetErrorString(ec)); } - int cusz_error(pszerror ec) { - switch(ec) { - case CUSZ_FAIL_ONDISK_FILE_ERROR: - return set_error(3, "ondisk file error"); - case CUSZ_FAIL_DATA_NOT_READY: - return set_error(4, "data not ready"); - case CUSZ_FAIL_GPU_MALLOC: - return set_error(5, "gpu malloc"); - case CUSZ_FAIL_GPU_MEMCPY: - return set_error(6, "gpu memcpy"); - case CUSZ_FAIL_GPU_ILLEGAL_ACCESS: - return set_error(7, "gpu illegal access"); - case CUSZ_FAIL_GPU_OUT_OF_MEMORY: - return set_error(8, "gpu out of memory"); - case CUSZ_FAIL_INCOMPRESSIABLE: - return set_error(9, "incompressible"); - default: - return set_error(10, "unknown error"); - } - } - #define lp_check_cuda_error(call) { \ cudaError ec = (call); \ if(ec != cudaSuccess) \ @@ -316,15 +295,15 @@ class cusz_compressor_plugin : public libpressio_compressor_plugin { T* d_uncomp = (T*)input.data(); psz_header header; - psz::TimeRecord timerecord; psz_len3 uncomp_len = psz_len3{dims[0], dims[1], dims[2]}; psz_compressor* comp = psz_create(to_cuszdtype(input.dtype()), uncomp_len, to_cusz_predictor_type(predictor), radius, Huffman); // codectype Huffman is hardcoded. (v0.10rc) uint8_t* ptr_compressed; size_t compressed_len; + void* ignored = nullptr; psz_compress( comp, d_uncomp, uncomp_len, err_bnd, to_cuszmode(eb_mode), - &ptr_compressed, &compressed_len, &header, &timerecord, *stream.get()); + &ptr_compressed, &compressed_len, &header, ignored, *stream.get()); *output = pressio_data::move(pressio_byte_dtype, ptr_compressed, {compressed_len}, domain_plugins().build("cudamalloc")); *output = domain_manager().make_readable(domain_plugins().build("malloc"), std::move(*output)); @@ -345,14 +324,15 @@ class cusz_compressor_plugin : public libpressio_compressor_plugin { pressio_data cpu_input = domain_manager().make_readable(domain_plugins().build("malloc"), *real_input); psz_header* header = (psz_header*)cpu_input.data(); auto comp_len = pszheader_filesize(header); + psz_len3 decomp_len = psz_len3{dims[0], dims[1], dims[2]}; // x, y, z // pressio_data gpu_input = domain_manager().make_readable(domain_plugins().build("cudamalloc"), *real_input); uint8_t* ptr_compressed = (uint8_t*)gpu_input.data(); - psz::TimeRecord timerecord; + void* ignored = nullptr; psz_compressor* comp = psz_create_from_header(header); - psz_decompress(comp, ptr_compressed, comp_len, d_decomp, decomp_len, (void*)&timerecord, *stream.get()); + psz_decompress(comp, ptr_compressed, comp_len, d_decomp, decomp_len, ignored, *stream.get()); psz_release(comp); return 0; diff --git a/src/plugins/compressors/delta_encoding.cc b/src/plugins/compressors/delta_encoding.cc index b462a344..03c7b77d 100644 --- a/src/plugins/compressors/delta_encoding.cc +++ b/src/plugins/compressors/delta_encoding.cc @@ -74,6 +74,7 @@ y[i] = x[i] - x[i-1]; set(opts, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(opts, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(opts, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(opts, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"delta_encoding:compressor"})); return opts; } diff --git a/src/plugins/compressors/digit_rounding.cc b/src/plugins/compressors/digit_rounding.cc index b74cdd45..d694fb08 100644 --- a/src/plugins/compressors/digit_rounding.cc +++ b/src/plugins/compressors/digit_rounding.cc @@ -40,6 +40,7 @@ class digit_rounding_plugin: public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, invalidations)); return options; } diff --git a/src/plugins/compressors/eip.cc b/src/plugins/compressors/eip.cc new file mode 100644 index 00000000..e4f106f1 --- /dev/null +++ b/src/plugins/compressors/eip.cc @@ -0,0 +1,245 @@ + +#include +#include +#include "std_compat/memory.h" +#include "libpressio_ext/cpp/compressor.h" +#include "libpressio_ext/cpp/data.h" +#include "libpressio_ext/cpp/options.h" +#include "libpressio_ext/cpp/pressio.h" +#include "libpressio_ext/cpp/domain_manager.h" +#include "cusz/config/eip.hh" +#include "cusz/kernel/predictor.hh" +#include "cusz/kernel/spv.hh" +#include "cusz/mem/cxx_backends.h" +#include "cusz/hf_hl.hh" +#include "cusz/mem/compbuf_pbk.hh" + +namespace libpressio { namespace compressors { namespace eip_ns { + + + constexpr size_t Radius = 128; +using T = float; using M = uint32_t; +using E = uint16_t; +template using PC_ref = psz::PredConfig>; +template using GPU_xlrz_ref = psz::module::GPU_x_lorenzo_nd>; +using Buf = psz::CompressorBufferPbk2; +using PC_eip = psz::PredConfig< + T, psz::PredFunc< + Toggle::ZigZagDisabled, Toggle::StatLocalEnabled, Toggle::StatGlobalDisabled, + Toggle::QuantGroupingDisabled, Toggle::FutureEIPEnabled>>; +using GPU_EIP_comp_r128 = psz::module::GPU_c_lorenzo_1d_eip; +using BufToggle = psz::CompressorBufferPbkToggle; + +BufToggle toggle_eip{.pbk_all = true}; + +class eip_compressor_plugin : public libpressio_compressor_plugin { + +private: + std::unique_ptr eip; + std::array dims; + double bound = 1e-4; +public: + eip_compressor_plugin(): libpressio_compressor_plugin(), eip(std::make_unique(1, 1, 1, false /* will revise in the future*/, &toggle_eip)), dims{1,1,1} { + } + eip_compressor_plugin(eip_compressor_plugin const& rhs): libpressio_compressor_plugin(rhs), eip(std::make_unique(rhs.dims[0], rhs.dims[1], rhs.dims[2], false /* will revise in the future*/, &toggle_eip)), dims(rhs.dims) { + // Buffer size need to be deteremined on intialization. + eip = std::make_unique(1, 1, 1, false /* will revise in the future*/, &toggle_eip); + } + eip_compressor_plugin& operator=(eip_compressor_plugin const& rhs){ + // Buffer size need to be deteremined on intialization. + dims = rhs.dims; + eip = std::make_unique(dims[0], dims[1], dims[2], false /* will revise in the future*/, &toggle_eip); + return *this; + } + + + struct pressio_options get_options_impl() const override + { + struct pressio_options options; + set(options, "pressio:abs", bound); + return options; + } + + struct pressio_options get_configuration_impl() const override + { + struct pressio_options options; + set(options, "pressio:thread_safe", pressio_thread_safety_multiple); + set(options, "pressio:stability", "experimental"); + std::vector invalidations {}; + std::vector invalidation_children {}; + set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); + set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); + set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{})); + return options; + } + + struct pressio_options get_documentation_impl() const override + { + struct pressio_options options; + set(options, "pressio:description", R"()"); + return options; + } + + + int set_options_impl(struct pressio_options const& options) override + { + get(options, "pressio:abs", &bound); + return 0; + } + + + int compress_impl(const pressio_data* real_input, + struct pressio_data* output) override + { + if(real_input->dtype() != pressio_float_dtype) return set_error(1, "unsupported type"); + auto input = domain_manager().make_readable(domain_plugins().build("cudamalloc"), *real_input); + + auto i_dims = input.normalized_dims(3,1); + if(!std::equal(i_dims.begin(), i_dims.end(), dims.begin())) { + eip = std::make_unique(i_dims[0], i_dims[1], i_dims[2], false /* will revise in the future*/, &toggle_eip); + } + + cudaStream_t stream; + cudaStreamCreate(&stream); + + GPU_EIP_comp_r128::kernel( + (float*)input.data(), input.num_elements(), (void*)eip->outlier(), bound, eip->pbk_books(), + eip->pbk_book_IDs(), eip->pbk_bitstream(), eip->pbk_bits(), + eip->pbk_entries(), eip->pbk_loc(), eip->pbk_break(), stream); + + auto endloc = eip->pbk_encoding_endloc(); // contains a d2h copy of one size_t + auto brlen = eip->host_get_pbk_break_num(); + auto splen = eip->host_get_unpredictable_num(); + + // right now, the errno is arbirarily defined. + std::stringstream ss; + if (brlen >= eip->pbk_break_num_max() - 1) { + ss << "[psz::warning::pbk_run::EIP] max allowed enc-breaking (" + << eip->pbk_break_num_max() << ") exceeded"; + return set_error(1, ss.str()); + } + if (splen >= eip->unpredictable_num_max() - 1) { + ss << "[psz::warning::pbk_run::EIP] max allowed unpredictable (" + << eip->outlier_ratio() << " * input-len) exceeded"; + return set_error(1, ss.str()); + } + + *output = pressio_data::join({ + pressio_data(std::make_tuple(endloc, brlen, splen)), + pressio_data::nonowning(pressio_dtype_from_typepbk_book_IDs())>>(), eip->pbk_book_IDs(), {eip->num_chunk()}, "cudamalloc"), + pressio_data::nonowning(pressio_dtype_from_typepbk_entries())>>(), eip->pbk_entries(), {eip->num_chunk()}, "cudamalloc"), + pressio_data::nonowning(pressio_dtype_from_typepbk_bits())>>(), eip->pbk_bits(), {eip->num_chunk()}, "cudamalloc"), + pressio_data::nonowning(pressio_dtype_from_typepbk_bitstream())>>(), eip->pbk_bitstream(), {endloc}, "cudamalloc"), + pressio_data::nonowning(pressio_dtype_from_typepbk_break_val())>>(), eip->pbk_break_val(), {brlen}, "cudamalloc"), + pressio_data::nonowning(pressio_dtype_from_typepbk_break_idx())>>(), eip->pbk_break_idx(), {brlen}, "cudamalloc"), + pressio_data::nonowning(pressio_dtype_from_typeunpredictable_val())>>(), eip->unpredictable_val(), {splen}, "cudamalloc"), + pressio_data::nonowning(pressio_dtype_from_typeunpredictable_idx())>>(), eip->unpredictable_idx(), {splen}, "cudamalloc"), + }); + + + return 0; + } + + int decompress_impl(const pressio_data* real_input, + struct pressio_data* output) override + { + auto input = domain_manager().make_readable(domain_plugins().build("cudamalloc"), *real_input); + + auto i_dims = output->normalized_dims(3,1); + if(!std::equal(i_dims.begin(), i_dims.end(), dims.begin())) { + eip = std::make_unique(i_dims[0], i_dims[1], i_dims[2], false /* will revise in the future*/, &toggle_eip); + } + + + std::vector restore{ + pressio_data(), + pressio_data::type_domain(pressio_dtype_from_typepbk_book_IDs())>>(), domain_plugins().build("cudamalloc")), + pressio_data::type_domain(pressio_dtype_from_typepbk_entries())>>(), domain_plugins().build( "cudamalloc")), + pressio_data::type_domain(pressio_dtype_from_typepbk_bits())>>(), domain_plugins().build( "cudamalloc")), + pressio_data::type_domain(pressio_dtype_from_typepbk_bitstream())>>(), domain_plugins().build( "cudamalloc")), + pressio_data::type_domain(pressio_dtype_from_typepbk_break_val())>>(), domain_plugins().build( "cudamalloc")), + pressio_data::type_domain(pressio_dtype_from_typepbk_break_idx())>>(), domain_plugins().build( "cudamalloc")), + pressio_data::type_domain(pressio_dtype_from_typeunpredictable_val())>>(), domain_plugins().build( "cudamalloc")), + pressio_data::type_domain(pressio_dtype_from_typeunpredictable_idx())>>(), domain_plugins().build( "cudamalloc")), + }; + pressio_data::split(input, restore); + auto metadata = std::move(restore.at(0)); + auto book_ids = std::move(restore.at(1)); + auto entries = std::move(restore.at(2)); + auto bits = std::move(restore.at(3)); + auto bitstream = std::move(restore.at(4)); + auto break_val = std::move(restore.at(5)); + auto break_idx = std::move(restore.at(6)); + auto unpred_val = std::move(restore.at(7)); + auto unpred_idx = std::move(restore.at(8)); + *output = domain_manager().make_writeable(domain_plugins().build("cudamalloc"), std::move(*output)); + + // The following variables are from the compression archive: + // len (the original #elements), splen, brlen) + + // Also, assume mem_eip buffer is reused. + + size_t splen, brlen, endloc; + std::tie(endloc, brlen, splen) = restore.at(0).to_tuple>(); + + + cudaStream_t stream; + cudaStreamCreate(&stream); + if (splen) + psz::spv_scatter_naive( + (T*)unpred_val.data(), (uint32_t*)unpred_idx.data(), splen, (float*)output->data(), + nullptr, stream); + cudaStreamSynchronize(stream); + + size_t len = output->num_elements(); + pressio_data ectrl_eip(pressio_data::owning(pressio_dtype_from_type(), {len})); + phf::cuhip::modules::CPU_pbk_coarse_decode( + (uint32_t*)bitstream.data(), endloc, eip->pbk_revbooks_h(), eip->PBK_RVBK_BYTES(), + (uint8_t*)book_ids.data(), (uint16_t*)bits.data(), (uint32_t*)entries.data(), + (E*)ectrl_eip.data(), len); + + // request an h2d copy: use host buffer for Huffman decoding + ectrl_eip = domain_manager().make_readable(domain_plugins().build("cudamalloc"), std::move(ectrl_eip)); + + // Then fix the breakings during parallel encoding + if (brlen) + psz::spv_scatter_naive( + (uint16_t*)break_val.data(), (uint32_t*)break_idx.data(), brlen, (uint16_t*)ectrl_eip.data(), nullptr, + stream); + cudaStreamSynchronize(stream); + + auto d_space = (T*)output->data(), d_xdata = (T*)output->data(); // aliases + + std::array len3_std; + GPU_xlrz_ref::kernel(eip->ectrl(), d_space, d_xdata, len3_std, bound, Radius, stream); + cudaStreamSynchronize(stream); + + + + return 0; + } + + int major_version() const override { return 0; } + int minor_version() const override { return 0; } + int patch_version() const override { return 1; } + const char* version() const override { return "0.0.1"; } + const char* prefix() const override { return "eip"; } + + pressio_options get_metrics_results_impl() const override { + return {}; + } + + std::shared_ptr clone() override + { + return compat::make_unique(*this); + } + +}; + +pressio_register registration(compressor_plugins(), "eip", []() { + return compat::make_unique(); +}); + +} } } + diff --git a/src/plugins/compressors/external.cc b/src/plugins/compressors/external.cc index fe1c79a8..28cb5da1 100644 --- a/src/plugins/compressors/external.cc +++ b/src/plugins/compressors/external.cc @@ -299,6 +299,7 @@ class external_compressor_compressor_plugin : public libpressio_compressor_plugi set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"external_compressor:launch"})); return options; } diff --git a/src/plugins/compressors/lambda_fn.cc b/src/plugins/compressors/lambda_fn.cc index 2c11a6f9..4de9e33d 100644 --- a/src/plugins/compressors/lambda_fn.cc +++ b/src/plugins/compressors/lambda_fn.cc @@ -1,5 +1,3 @@ -#define SOL_ALL_SAFETIES_ON 1 -#define SOL_PRINT_ERRORS 1 #include #include #include @@ -16,6 +14,22 @@ enum class lambda_fn_event { class lambda_fn_compressor_plugin : public libpressio_compressor_plugin { public: + static sol::table make_options_table(sol::state_view lua, pressio_options const& opts) { + auto table = lua.create_table(); + for (auto const& option : opts) { + auto as_double = option.second.as(pressio_option_double_type, pressio_conversion_explicit); + if(as_double.has_value()) { + table[option.first] = as_double.get_value(); + continue; + } + auto as_string = option.second.as(pressio_option_charptr_type, pressio_conversion_explicit); + if(as_string.has_value()) { + table[option.first] = as_string.get_value(); + } + } + return table; + } + struct pressio_options get_options_impl() const override { struct pressio_options options; @@ -39,6 +53,7 @@ class lambda_fn_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"lambda_fn:script"})); return options; } @@ -320,12 +335,6 @@ class lambda_fn_compressor_plugin : public libpressio_compressor_plugin { "dtype", &pressio_data::dtype, "to_vector", &pressio_data::to_vector ); - lua.new_usertype( - "pressio_options", - "key_status", static_cast(&pressio_options::key_status), - "get", static_cast(&pressio_options::get), - "set", static_cast(&pressio_options::set) - ); lua.new_usertype( "pressio_option", "type", &pressio_option::type, @@ -362,7 +371,7 @@ class lambda_fn_compressor_plugin : public libpressio_compressor_plugin { void run_options_script(pressio_options const& set_opts, lambda_fn_event event) { run_script_common(event, [&set_opts](sol::state& lua){ - lua["set_options"] = std::ref(set_opts); + lua["set_options"] = make_options_table(lua, set_opts); }); } void run_compress_script(compat::span const& inputs, compat::span & outputs, lambda_fn_event event) { @@ -391,8 +400,8 @@ class lambda_fn_compressor_plugin : public libpressio_compressor_plugin { sol::state lua; lua.open_libraries(sol::lib::base, sol::lib::math); bind_pressio(lua); - lua["persist"] = std::ref(persist); - lua["options"] = std::ref(opts); + lua["persist"] = make_options_table(lua, persist); + lua["options"] = make_options_table(lua, opts); lua["name"] = get_name(); lua["is_compress"] = event == lambda_fn_event::compress; lua["is_decompress"] = event == lambda_fn_event::decompress; diff --git a/src/plugins/compressors/log_transform.cc b/src/plugins/compressors/log_transform.cc index 83040a8e..2d6613e1 100644 --- a/src/plugins/compressors/log_transform.cc +++ b/src/plugins/compressors/log_transform.cc @@ -81,6 +81,7 @@ y[0] = log(x[0]); set(opts, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(opts, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(opts, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(opts, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"log_transform:compressor"})); return opts; } diff --git a/src/plugins/compressors/lscomp.cc b/src/plugins/compressors/lscomp.cc new file mode 100644 index 00000000..6774e628 --- /dev/null +++ b/src/plugins/compressors/lscomp.cc @@ -0,0 +1,149 @@ + +#include "cuda_runtime.h" +#include "std_compat/memory.h" +#include "libpressio_ext/cpp/compressor.h" +#include "libpressio_ext/cpp/data.h" +#include "libpressio_ext/cpp/options.h" +#include "libpressio_ext/cpp/pressio.h" +#include "libpressio_ext/cpp/domain_manager.h" +#include +#include +#include + + + +namespace libpressio { namespace compressors { namespace lscomp_ns { + +class lscomp_compressor_plugin : public libpressio_compressor_plugin { +public: + struct pressio_options get_options_impl() const override + { + struct pressio_options options; + set(options, "lscomp:pooling_threshold", poolingTH); + set(options, "lscomp:quantization_bins", quantBinsData); + return options; + } + + struct pressio_options get_configuration_impl() const override + { + struct pressio_options options; + set(options, "pressio:thread_safe", pressio_thread_safety_multiple); + set(options, "pressio:stability", "experimental"); + std::vector invalidations {}; + std::vector invalidation_children {}; + set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); + set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); + set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{})); + return options; + } + + struct pressio_options get_documentation_impl() const override + { + struct pressio_options options; + set(options, "pressio:description", R"(A specialized compressors for lightsources focusing on CSSI beamlines + described in detail in "lsCOMP: Efficient Light Source Compression" published at SC25)"); + set(options, "lscomp:pooling_threshold", "the pooling threhsold"); + set(options, "lscomp:quantization_bins", "the quantization bins for the 4 top levels, x<=y<=z<=w"); + return options; + } + + + int set_options_impl(struct pressio_options const& options) override + { + get(options, "lscomp:pooling_threshold", &poolingTH); + pressio_data tmp; + if(get(options, "lscomp:quantization_bins", &tmp) == pressio_options_key_set) { + tmp = tmp.cast(pressio_uint32_dtype); + std::vector v = tmp.to_vector(); + if(v.size() != 4) return set_error(1, "size of quantization bins must be 4"); + if(!std::is_sorted(v.begin(), v.end())) return set_error(1, "quantization bins values must be increasing"); + quantBinsData = tmp; + } + return 0; + } + + int compress_impl(const pressio_data* real_input, + struct pressio_data* output) override + { + if(real_input->dtype() != pressio_uint32_dtype || real_input->dtype() != pressio_uint16_dtype) return set_error(1, "unsupported datatype"); + auto input = domain_manager().make_readable(domain_plugins().build("cudamalloc"), *real_input); + auto dims_sizet = input.normalized_dims(3,1); + size_t cmpSize = 0; + uint3 dims {(uint)dims_sizet[0], (uint)dims_sizet[1], (uint)dims_sizet[2]}; + std::vector quantBinsV = quantBinsData.to_vector(); + uint4 quantBins {quantBinsV[0], quantBinsV[1], quantBinsV[2], quantBinsV[3]}; + cudaStream_t stream; + cudaStreamCreate(&stream); + + pressio_data comp_bytes(pressio_data::owning(input.dtype(), {input.num_elements()})); + switch(input.dtype()) { + case pressio_uint32_dtype: + cuLSZ_compression_uint32_bsize64((uint32_t*)input.data(), (uint8_t*)comp_bytes.data(), &cmpSize, dims, quantBins, poolingTH, stream); + break; + case pressio_uint16_dtype: + cuLSZ_compression_uint16_bsize64((uint16_t*)input.data(), (uint8_t*)comp_bytes.data(), &cmpSize, dims, quantBins, poolingTH, stream); + break; + default: + cudaStreamDestroy(stream); + return set_error(1, "unsupported datatype"); + } + *output = std::move(comp_bytes); + output->reshape({cmpSize}); + output->set_dtype(pressio_byte_dtype); + cudaStreamDestroy(stream); + *output = std::move(input); + return 0; + } + + int decompress_impl(const pressio_data* real_input, + struct pressio_data* real_output) override + { + auto input = domain_manager().make_readable(domain_plugins().build("cudamalloc"), std::move(*real_input)); + auto output = domain_manager().make_writeable(domain_plugins().build("cudamalloc"), std::move(*real_output)); + auto dims_sizet = output.normalized_dims(3,1); + uint3 dims {(uint)dims_sizet[0], (uint)dims_sizet[1], (uint)dims_sizet[2]}; + std::vector quantBinsV = quantBinsData.to_vector(); + uint4 quantBins {quantBinsV[0], quantBinsV[1], quantBinsV[2], quantBinsV[3]}; + cudaStream_t stream; + cudaStreamCreate(&stream); + switch(output.dtype()) { + case pressio_uint32_dtype: + cuLSZ_decompression_uint32_bsize64((uint32_t*)output.data(), (uint8_t*)input.data(), input.size_in_bytes(), dims, quantBins, poolingTH, stream); + break; + case pressio_uint16_dtype: + cuLSZ_decompression_uint16_bsize64((uint16_t*)output.data(), (uint8_t*)input.data(), input.size_in_bytes(), dims, quantBins, poolingTH, stream); + break; + default: + cudaStreamDestroy(stream); + return set_error(1, "unsupported datatype"); + } + cudaStreamDestroy(stream); + return 0; + } + + int major_version() const override { return 0; } + int minor_version() const override { return 0; } + int patch_version() const override { return 1; } + const char* version() const override { return "0.0.1"; } + const char* prefix() const override { return "lscomp"; } + + pressio_options get_metrics_results_impl() const override { + return {}; + } + + std::shared_ptr clone() override + { + return compat::make_unique(*this); + } + + float poolingTH=0.5f; + pressio_data quantBinsData{3u, 5u, 10u, 15u}; +}; + +pressio_register registration(compressor_plugins(), "lscomp", []() { + return compat::make_unique(); +}); + +} } } + diff --git a/src/plugins/compressors/magick.cc b/src/plugins/compressors/magick.cc index f4ba8963..eec2e107 100644 --- a/src/plugins/compressors/magick.cc +++ b/src/plugins/compressors/magick.cc @@ -99,6 +99,7 @@ class magick_plugin: public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, invalidations)); return options; } diff --git a/src/plugins/compressors/manifest.cc b/src/plugins/compressors/manifest.cc index ded558aa..f1b4f3b0 100644 --- a/src/plugins/compressors/manifest.cc +++ b/src/plugins/compressors/manifest.cc @@ -38,7 +38,7 @@ class manifest_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, {})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); - set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, {})); return options; } diff --git a/src/plugins/compressors/many_dependent.cc b/src/plugins/compressors/many_dependent.cc index 3307c15c..a8a80659 100644 --- a/src/plugins/compressors/many_dependent.cc +++ b/src/plugins/compressors/many_dependent.cc @@ -48,6 +48,7 @@ class many_dependent_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, invalidations)); return options; } diff --git a/src/plugins/compressors/many_independent.cc b/src/plugins/compressors/many_independent.cc index 34c843f3..953ffcc1 100644 --- a/src/plugins/compressors/many_independent.cc +++ b/src/plugins/compressors/many_independent.cc @@ -61,6 +61,7 @@ class many_independent_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, {})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, {})); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, {})); return options; } diff --git a/src/plugins/compressors/mask_interpolation.cc b/src/plugins/compressors/mask_interpolation.cc index ccebc4c4..88d647ae 100644 --- a/src/plugins/compressors/mask_interpolation.cc +++ b/src/plugins/compressors/mask_interpolation.cc @@ -41,7 +41,7 @@ class mask_interpolation_compressor_plugin : public libpressio_compressor_plugin set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, runtime_invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads", "mask_interpolation:mask_mode", "mask_interpolation:fill", "mask_interpolation:mask"})); return options; } diff --git a/src/plugins/compressors/masked_binning.cc b/src/plugins/compressors/masked_binning.cc index 99be1e24..4018ad2d 100644 --- a/src/plugins/compressors/masked_binning.cc +++ b/src/plugins/compressors/masked_binning.cc @@ -110,7 +110,7 @@ class binning_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, std::vector{"pressio:nthreads", "mask_binning:nthreads"})); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads", "mask_binning:shape", "mask_binning:mask"})); return options; } diff --git a/src/plugins/compressors/mgard_1_3.cc b/src/plugins/compressors/mgard_1_3.cc index fadd1021..ae3464d1 100644 --- a/src/plugins/compressors/mgard_1_3.cc +++ b/src/plugins/compressors/mgard_1_3.cc @@ -271,7 +271,8 @@ Reference [6] covers the design and implementation on GPU heterogeneous systems. void* output_data = output->data(); size_t compressed_size; bool pre_allocated = output->has_data(); - auto const& dims = input->normalized_dims(); + auto input_dims = input->normalized_dims(); + std::vector dims(input_dims.begin(), input_dims.end()); // as of CODARCode/mgard@1.4, MGARD expects inputs to // if cuda, use Cuda Unified Virtual Addressing infers the kind of the copy based on the pointer attributes // if sycl, use Sycl Unified Shared Memory allows memory shared between src and target automatically with the OS diff --git a/src/plugins/compressors/pipeline.cc b/src/plugins/compressors/pipeline.cc index 8ad010e8..45a3bdaa 100644 --- a/src/plugins/compressors/pipeline.cc +++ b/src/plugins/compressors/pipeline.cc @@ -28,7 +28,7 @@ class pipeline_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pipeline:pipeline"})); return options; } diff --git a/src/plugins/compressors/pw_rel.cc b/src/plugins/compressors/pw_rel.cc index 64eff1b1..f3502153 100644 --- a/src/plugins/compressors/pw_rel.cc +++ b/src/plugins/compressors/pw_rel.cc @@ -196,7 +196,7 @@ class pw_rel_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, {})); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:pw_rel"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:pw_rel", "pw_rel:abs_comp", "pw_rel:sign_comp"})); return options; } diff --git a/src/plugins/compressors/remove_background.cc b/src/plugins/compressors/remove_background.cc index 727fd295..38e534ce 100644 --- a/src/plugins/compressors/remove_background.cc +++ b/src/plugins/compressors/remove_background.cc @@ -27,7 +27,7 @@ class remove_background_compressor_plugin : public libpressio_compressor_plugin set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"remove_background:compressor", "remove_background:background"})); return options; } diff --git a/src/plugins/compressors/repeat.cc b/src/plugins/compressors/repeat.cc index e085304f..ba938c0b 100644 --- a/src/plugins/compressors/repeat.cc +++ b/src/plugins/compressors/repeat.cc @@ -32,6 +32,7 @@ class repeat_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, {})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, {})); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"repeat:count"})); return options; } diff --git a/src/plugins/compressors/resize.cc b/src/plugins/compressors/resize.cc index 048825a5..e7e1636e 100644 --- a/src/plugins/compressors/resize.cc +++ b/src/plugins/compressors/resize.cc @@ -38,6 +38,7 @@ class resize_meta_compressor_plugin : public libpressio_compressor_plugin set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, {})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, {})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"resize:compressed_dims", "resize:decompressed_dims", "resize:compressor"})); return options; } diff --git a/src/plugins/compressors/roibin.cc b/src/plugins/compressors/roibin.cc index d754422c..1bbb5778 100644 --- a/src/plugins/compressors/roibin.cc +++ b/src/plugins/compressors/roibin.cc @@ -46,7 +46,7 @@ class roibin_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, runtime_invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads"})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:nthreads", "roibin:background", "roibin:roi", "roibin:roi_strategy", "roibin:centers", "roibin:roi_size"})); return options; } diff --git a/src/plugins/compressors/roibin_impl.h b/src/plugins/compressors/roibin_impl.h index 1fbf9ab5..4b13ff82 100644 --- a/src/plugins/compressors/roibin_impl.h +++ b/src/plugins/compressors/roibin_impl.h @@ -625,13 +625,9 @@ void restore_omp(indexer<1> const& id, indexer<1> const& binned_storage, indexe for (size_t i_s = 0; i_s < binned_storage[0]; i_s++) { size_t i = i_s * bins[0]; auto value = binned[binned_storage(i_s)]; - for (size_t b_l = 0; b_l < bins[3]; ++b_l) { - for (size_t b_k = 0; b_k < bins[2]; ++b_k) { - for (size_t b_i = 0; b_i < bins[0]; ++b_i) { - if (b_i + i < id[0]) { - restored[id(i + b_i)] = value; - } - } + for (size_t b_i = 0; b_i < bins[0]; ++b_i) { + if (b_i + i < id[0]) { + restored[id(i + b_i)] = value; } } } @@ -645,15 +641,11 @@ void restore_omp(indexer<2> const& id, indexer<2> const& binned_storage, indexe size_t j = j_s * bins[1]; size_t i = i_s * bins[0]; auto value = binned[binned_storage(i_s, j_s)]; - for (size_t b_l = 0; b_l < bins[3]; ++b_l) { - for (size_t b_k = 0; b_k < bins[2]; ++b_k) { - for (size_t b_j = 0; b_j < bins[1]; ++b_j) { - if (b_j + j < id[1]) { - for (size_t b_i = 0; b_i < bins[0]; ++b_i) { - if (b_i + i < id[0]) { - restored[id(i + b_i, j + b_j)] = value; - } - } + for (size_t b_j = 0; b_j < bins[1]; ++b_j) { + if (b_j + j < id[1]) { + for (size_t b_i = 0; b_i < bins[0]; ++b_i) { + if (b_i + i < id[0]) { + restored[id(i + b_i, j + b_j)] = value; } } } diff --git a/src/plugins/compressors/sampling.cc b/src/plugins/compressors/sampling.cc index 0964d84b..5a9b6601 100644 --- a/src/plugins/compressors/sampling.cc +++ b/src/plugins/compressors/sampling.cc @@ -36,6 +36,7 @@ class sample_compressor_plugin: public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, invalidations)); return options; } diff --git a/src/plugins/compressors/switch.cc b/src/plugins/compressors/switch.cc index 9b828f1d..7661ea28 100644 --- a/src/plugins/compressors/switch.cc +++ b/src/plugins/compressors/switch.cc @@ -49,6 +49,7 @@ for (auto const& child : compressors) { set(opts, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(opts, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(opts, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); + set(opts, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, invalidations)); return opts; } diff --git a/src/plugins/compressors/sz.cc b/src/plugins/compressors/sz.cc index 9f5777f8..00205521 100644 --- a/src/plugins/compressors/sz.cc +++ b/src/plugins/compressors/sz.cc @@ -429,7 +429,7 @@ class sz_plugin: public libpressio_compressor_plugin { set(sz_metrics, "sz:quantization_intervals", sz_stat.quantization_intervals); #endif #if PRESSIO_SZ_VERSION_GREATEREQ(2,1,12,4) - set(sz_metrics, "sz:pre_encoding_size", sz_stat.pre_encoding_size); + set(sz_metrics, "sz:pre_encoding_size", static_cast(sz_stat.pre_encoding_size)); #endif #endif return sz_metrics; diff --git a/src/plugins/compressors/sz3.cc b/src/plugins/compressors/sz3.cc index 23cab9c5..141a55d4 100644 --- a/src/plugins/compressors/sz3.cc +++ b/src/plugins/compressors/sz3.cc @@ -7,6 +7,7 @@ #include "iless.h" #include "cleanup.h" +#include #include @@ -80,34 +81,34 @@ class sz3_compressor_plugin : public libpressio::compressors::libpressio_compres { struct pressio_options options; if(config.errorBoundMode == SZ3::EB_ABS) { - set(options, "pressio:abs", config.absErrorBound); + this->set(options, "pressio:abs", config.absErrorBound); } else { - set_type(options, "pressio:abs", pressio_option_double_type); + this->set_type(options, "pressio:abs", pressio_option_double_type); } if(config.errorBoundMode == SZ3::EB_REL) { - set(options, "pressio:rel", config.relErrorBound); + this->set(options, "pressio:rel", config.relErrorBound); } else { - set_type(options, "pressio:rel", pressio_option_double_type); + this->set_type(options, "pressio:rel", pressio_option_double_type); } - set(options, "pressio:nthreads", nthreads); - set(options, "sz3:abs_error_bound", config.absErrorBound); - set(options, "sz3:rel_error_bound", config.relErrorBound); - set(options, "sz3:psnr_error_bound", config.psnrErrorBound); - set(options, "sz3:l2_norm_error_bound", config.l2normErrorBound); - set(options, "sz3:error_bound_mode", config.errorBoundMode); - set(options, "sz3:algorithm", config.cmprAlgo); - set(options, "sz3:lorenzo", config.lorenzo); - set(options, "sz3:lorenzo2", config.lorenzo2); - set(options, "sz3:regression", config.regression); - set(options, "sz3:regression2", config.regression2); - set(options, "sz3:openmp", config.openmp); - set(options, "sz3:interp_algo", config.interpAlgo); - set(options, "sz3:interp_direction", config.interpDirection); - set(options, "sz3:quant_bin_size", config.quantbinCnt); - set(options, "sz3:pred_dim", config.predDim); - set_type(options, "sz3:error_bound_mode_str", pressio_option_charptr_type); - set_type(options, "sz3:intrep_algo_str", pressio_option_charptr_type); - set_type(options, "sz3:algorithm_str", pressio_option_charptr_type); + this->set(options, "pressio:nthreads", nthreads); + this->set(options, "sz3:abs_error_bound", config.absErrorBound); + this->set(options, "sz3:rel_error_bound", config.relErrorBound); + this->set(options, "sz3:psnr_error_bound", config.psnrErrorBound); + this->set(options, "sz3:l2_norm_error_bound", config.l2normErrorBound); + this->set(options, "sz3:error_bound_mode", config.errorBoundMode); + this->set(options, "sz3:algorithm", config.cmprAlgo); + this->set(options, "sz3:lorenzo", config.lorenzo); + this->set(options, "sz3:lorenzo2", config.lorenzo2); + this->set(options, "sz3:regression", config.regression); + this->set(options, "sz3:regression2", config.regression2); + this->set(options, "sz3:openmp", config.openmp); + this->set(options, "sz3:interp_algo", config.interpAlgo); + this->set(options, "sz3:interp_direction", config.interpDirection); + this->set(options, "sz3:quant_bin_size", config.quantbinCnt); + this->set_type(options, "sz3:error_bound_mode_str", pressio_option_charptr_type); + this->set_type(options, "sz3:intrep_algo_str", pressio_option_charptr_type); + this->set_type(options, "sz3:algorithm_str", pressio_option_charptr_type); + return options; } @@ -120,8 +121,8 @@ class sz3_compressor_plugin : public libpressio::compressors::libpressio_compres set(options, "sz3:intrep_algo_str", keys(sz3_options().interp_algo)); set(options, "sz3:algorithm_str", keys(sz3_options().algo)); - std::vector invalidations {"sz3:abs_error_bound", "sz3:rel_error_bound", "sz3:psnr_error_bound", "sz3:l2_norm_error_bound", "sz3:error_bound_mode", "sz3:algorithm", "sz3:lorenzo", "sz3:lorenzo2", "sz3:regression", "sz3:regression2", "sz3:openmp", "sz3:lossless", "sz3:encoder", "sz3:interp_algo", "sz3:interp_direction", "sz3:interp_block_size", "sz3:quant_bin_size", "sz3:stride", "sz3:pred_dim", "pressio:abs", "pressio:rel", "sz3:error_bound_mode_str", "sz3:intrep_algo_str", "sz3:algorithm_str"}; - std::vector runtime_invalidations {"sz3:abs_error_bound", "sz3:rel_error_bound", "sz3:psnr_error_bound", "sz3:l2_norm_error_bound", "sz3:error_bound_mode", "sz3:algorithm", "sz3:lorenzo", "sz3:lorenzo2", "sz3:regression", "sz3:regression2", "sz3:openmp", "sz3:lossless", "sz3:encoder", "sz3:interp_algo", "sz3:interp_direction", "sz3:interp_block_size", "sz3:quant_bin_size", "sz3:stride", "sz3:pred_dim", "pressio:abs", "pressio:rel", "pressio:nthreads", "sz3:error_bound_mode_str", "sz3:intrep_algo_str", "sz3:algorithm_str"}; + std::vector invalidations {"sz3:abs_error_bound", "sz3:rel_error_bound", "sz3:psnr_error_bound", "sz3:l2_norm_error_bound", "sz3:error_bound_mode", "sz3:algorithm", "sz3:lorenzo", "sz3:lorenzo2", "sz3:regression", "sz3:regression2", "sz3:openmp", "sz3:interp_algo", "sz3:interp_direction", "sz3:quant_bin_size", "pressio:abs", "pressio:rel", "sz3:error_bound_mode_str", "sz3:intrep_algo_str", "sz3:algorithm_str"}; + std::vector runtime_invalidations {"sz3:abs_error_bound", "sz3:rel_error_bound", "sz3:psnr_error_bound", "sz3:l2_norm_error_bound", "sz3:error_bound_mode", "sz3:algorithm", "sz3:lorenzo", "sz3:lorenzo2", "sz3:regression", "sz3:regression2", "sz3:openmp", "sz3:interp_algo", "sz3:interp_direction", "sz3:quant_bin_size", "pressio:abs", "pressio:rel", "pressio:nthreads", "sz3:error_bound_mode_str", "sz3:intrep_algo_str", "sz3:algorithm_str"}; std::vector invalidation_children {}; set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); @@ -149,14 +150,9 @@ class sz3_compressor_plugin : public libpressio::compressors::libpressio_compres set(options, "sz3:regression", "use the regression predictor"); set(options, "sz3:regression2", "use the 2nd order regression predictor"); set(options, "sz3:openmp", "use openmp parallelization"); - set(options, "sz3:lossless", "lossless compression method to apply; 1 bypass lossless, 1 zstd"); - set(options, "sz3:encoder", "which encoder to use, 0 skip encoder, 1 huffman, 2 arithmatic"); set(options, "sz3:interp_algo", "which intrepolation algorithm to use"); set(options, "sz3:interp_direction", "which interpolation direction to use"); - set(options, "sz3:interp_block_size", "what block size to use for interpolation to use"); set(options, "sz3:quant_bin_size", "number of quantization bins"); - set(options, "sz3:stride", "stride between items"); - set(options, "sz3:pred_dim", "prediction dimension"); set(options, "sz3:algorithm_str", "compression algorithm"); set(options, "sz3:error_bound_mode_str", "error bound"); set(options, "sz3:intrep_algo_str", "interpolation algorithm mode"); @@ -334,6 +330,10 @@ class sz3_compressor_plugin : public libpressio::compressors::libpressio_compres uint32_t nthreads = 1; SZ3::Config config{}; + enum class comp_metrics { + prediction, + }; + std::setcollect_metrics = {}; }; pressio_register registration(compressor_plugins(), "sz3", []() { diff --git a/src/plugins/compressors/szp.cc b/src/plugins/compressors/szp.cc index 3b6d3091..06076fe4 100644 --- a/src/plugins/compressors/szp.cc +++ b/src/plugins/compressors/szp.cc @@ -83,7 +83,7 @@ class szp_compressor_plugin : public libpressio::compressors::libpressio_compres set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"pressio:abs", "pressio:rel"})); return options; } @@ -133,8 +133,12 @@ class szp_compressor_plugin : public libpressio::compressors::libpressio_compres } auto input = domain_manager().make_readable(domain_plugins().build("malloc"), *real_input); size_t outSize = 0; - unsigned char *bytes = szp_compress(fastMode, to_dtype(input.dtype()), input.data(), &outSize, errBoundMode, absBound, relBound, input.num_elements(), block_size); - *output = pressio_data::move(pressio_byte_dtype, bytes, {outSize}, domain_plugins().build("malloc")); + try { + unsigned char *bytes = szp_compress(fastMode, to_dtype(input.dtype()), input.data(), &outSize, errBoundMode, absBound, relBound, input.num_elements(), block_size); + *output = pressio_data::move(pressio_byte_dtype, bytes, {outSize}, domain_plugins().build("malloc")); + } catch (std::runtime_error const& ex) { + return set_error(1, ex.what()); + } return 0; } @@ -148,8 +152,12 @@ class szp_compressor_plugin : public libpressio::compressors::libpressio_compres num_threads = [old_threads]{omp_set_num_threads(old_threads);}; } auto input = domain_manager().make_readable(domain_plugins().build("malloc"), *real_input); - void* data = (void*)szp_decompress(fastMode, to_dtype(output->dtype()), reinterpret_cast(input.data()), input.num_elements(), output->num_elements(), block_size); - *output = pressio_data::move(output->dtype(), data, output->dimensions(), domain_plugins().build("malloc")); + try { + void* data = (void*)szp_decompress(fastMode, to_dtype(output->dtype()), reinterpret_cast(input.data()), input.num_elements(), output->num_elements(), block_size); + *output = pressio_data::move(output->dtype(), data, output->dimensions(), domain_plugins().build("malloc")); + } catch(std::runtime_error const& ex) { + return set_error(1, ex.what()); + } return 0; } diff --git a/src/plugins/compressors/threshold_small.cc b/src/plugins/compressors/threshold_small.cc index 941fee34..96ec0c28 100644 --- a/src/plugins/compressors/threshold_small.cc +++ b/src/plugins/compressors/threshold_small.cc @@ -28,7 +28,7 @@ class threshold_small_compressor_plugin : public libpressio_compressor_plugin { set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", invalidation_children, invalidations)); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", invalidation_children, invalidations)); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", invalidation_children, invalidations)); - set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", invalidation_children, std::vector{"threshold_small:threshold"})); return options; } diff --git a/src/plugins/compressors/transpose.cc b/src/plugins/compressors/transpose.cc index dee90aba..b921b7da 100644 --- a/src/plugins/compressors/transpose.cc +++ b/src/plugins/compressors/transpose.cc @@ -32,6 +32,7 @@ class transpose_meta_compressor_plugin : public libpressio_compressor_plugin set(options, "predictors:error_dependent", get_accumulate_configuration("predictors:error_dependent", {&*compressor}, {"transpose:axis"})); set(options, "predictors:error_agnostic", get_accumulate_configuration("predictors:error_agnostic", {&*compressor}, {})); set(options, "predictors:runtime", get_accumulate_configuration("predictors:runtime", {&*compressor}, {})); + set(options, "pressio:highlevel", get_accumulate_configuration("pressio:highlevel", {&*compressor}, std::vector{"transpose:axis"})); return options; } diff --git a/src/plugins/domains_metrics/print.cc b/src/plugins/domains_metrics/print.cc index 8e7bf484..91afce34 100644 --- a/src/plugins/domains_metrics/print.cc +++ b/src/plugins/domains_metrics/print.cc @@ -112,6 +112,14 @@ struct print_plugin: public pressio_domain_manager_metrics_plugin { copy.stop(); std::cout << "copy_to_end(" << prefix_or_name(*dst.domain()) << "<-" << prefix_or_name(src.domain()) << ") " << copy << std::endl; } + void copy_to_begin(std::shared_ptr const& dst, pressio_data const& src) override { + copy = timer(); + std::cout << "copy_to_begin(" << prefix_or_name(dst) << "<-" << prefix_or_name(src.domain()) << ") " << src << std::endl; + } + void copy_to_end(std::shared_ptr const& dst, pressio_data const& src) override { + copy.stop(); + std::cout << "copy_to_end(" << prefix_or_name(dst) << "<-" << prefix_or_name(src.domain()) << ") " << copy << std::endl; + } void make_writeable_begin(std::shared_ptr const& dst, pressio_data const& src) override { std::cout << "writeable_begin(" << prefix_or_name(dst) << "<-" << prefix_or_name(src.domain()) << ") " << src << std::endl; writeable = timer(); diff --git a/src/plugins/metrics/composite.cc b/src/plugins/metrics/composite.cc index 7104e53b..2373bd94 100644 --- a/src/plugins/metrics/composite.cc +++ b/src/plugins/metrics/composite.cc @@ -10,8 +10,6 @@ #include "std_compat/string_view.h" #include "pressio_version.h" #if LIBPRESSIO_HAS_LUA -#define SOL_ALL_SAFETIES_ON 1 -#define SOL_PRINT_ERRORS 1 #include #endif @@ -318,33 +316,40 @@ class composite_plugin : public libpressio_metrics_plugin { } } for (auto const& script : scripts) { - try { - //create a new state for each object to ensure it is clean - sol::state lua; - lua.open_libraries(sol::lib::base); - lua.open_libraries(sol::lib::math); - lua["metrics"] = metrics; - - sol::optional>> lua_result = lua.safe_script(script, - [this](lua_State*, sol::protected_function_result pfr) { - sol::error err = pfr; - set_error(1, std::string("lua error: ") + err.what()); - return pfr; - }); - if(lua_result) { - auto const& lua_result_v = *lua_result; - std::string name = std::string("composite:") + std::get<0>(lua_result_v); - if(std::get<1>(lua_result_v)) { - set(opt, name, *std::get<1>(lua_result_v)); - metrics[name] = *std::get<1>(lua_result_v); - } else { - set_type(opt, name, pressio_option_double_type); - } - } else { - return error_code(); - } - } catch (sol::error& err) { - return set_error(1, std::string("lua error; ") + err.what()); + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::math); + + auto metrics_table = lua.create_table(); + for (auto const& metric : metrics) { + metrics_table[metric.first] = metric.second; + } + lua["metrics"] = metrics_table; + + auto result = lua.safe_script(script, sol::script_pass_on_error); + if(!result.valid()) { + sol::error err = result; + return set_error(1, std::string("lua error: ") + err.what()); + } + + if(result.return_count() < 2) { + return set_error(1, "lua error: script must return name and value"); + } + + sol::object name_obj = result.get(0); + sol::object value_obj = result.get(1); + if(name_obj.get_type() != sol::type::string) { + return set_error(1, "lua error: first return value must be a string"); + } + + std::string name = std::string("composite:") + name_obj.as(); + if(value_obj == sol::lua_nil) { + set_type(opt, name, pressio_option_double_type); + } else if(value_obj.is()) { + double value = value_obj.as(); + set(opt, name, value); + metrics[name] = value; + } else { + return set_error(1, "lua error: second return value must be a number or nil"); } } #endif diff --git a/src/plugins/metrics/out_of_bounds.cc b/src/plugins/metrics/out_of_bounds.cc index 90856b64..8a197b01 100644 --- a/src/plugins/metrics/out_of_bounds.cc +++ b/src/plugins/metrics/out_of_bounds.cc @@ -111,23 +111,38 @@ class out_of_bounds_plugin : public libpressio_metrics_plugin { } struct pressio_options get_configuration_impl() const override { - pressio_options opts; - set(opts, "pressio:stability", "experimental"); - set(opts, "pressio:thread_safe", pressio_thread_safety_multiple); - set(opts, "predictors:requires_decompress", true); - set(opts, "predictors:invalidate", std::vector{"predictors:error_dependent"}); - return opts; + pressio_options opts; + set(opts, "pressio:stability", "experimental"); + set(opts, "pressio:thread_safe", pressio_thread_safety_multiple); + set(opts, "predictors:requires_decompress", true); + set(opts, "predictors:invalidate", std::vector{"predictors:error_dependent"}); + return opts; } struct pressio_options get_documentation_impl() const override { - pressio_options opt; - set(opt, "pressio:description", R"(produces a report of the values that are out of bounds)"); - set(opt, "out_of_bounds:oob", "a 3xN array where [i*3]= input, [i*3+1]=output, [i*3+2]=error"); - set(opt, "out_of_bounds:index", "a length N array containing the indexes of the out of range values"); - set(opt, "out_of_bounds:print_first_k", - "print the first k entries that are out of range in a human-focused unstable format for " - "debugging"); - return opt; + pressio_options opt; + set(opt, "pressio:description", R"(produces a report of the values that are out of bounds)"); + set(opt, "out_of_bounds:oob", "a 3xN array where [i*3]= input, [i*3+1]=output, [i*3+2]=error"); + set(opt, "out_of_bounds:index", "a length N array containing the indexes of the out of range values"); + set(opt, "out_of_bounds:print_first_k", + "print the first k entries that are out of range in a human-focused unstable format for " + "debugging"); + set(opt, "pressio:abs", R"(a pointwise absolute error bound + + compressors may provide this value without supporting abs=0. + compressors that support abs=0, additionally should also define pressio:lossless + )"); + set(opt, "pressio:rel", R"(a pointwise value-range relative error bound + + compressors may provide this value without supporting rel=0. + compressors that support rel=0, additionally should also define pressio:lossless + )"); + set(opt, "pressio:pw_rel", R"(a pointwise relative error bound + + compressors may provide this value without supporting pw_rel=0. + compressors that support pw_rel=0, additionally should also define pressio:lossless + )"); + return opt; } pressio_options get_metrics_results(pressio_options const &) override { diff --git a/src/plugins/metrics/series.cc b/src/plugins/metrics/series.cc new file mode 100644 index 00000000..2dff4eb2 --- /dev/null +++ b/src/plugins/metrics/series.cc @@ -0,0 +1,80 @@ + +#include "pressio_data.h" +#include "pressio_compressor.h" +#include "pressio_options.h" +#include "libpressio_ext/cpp/metrics.h" +#include "libpressio_ext/cpp/pressio.h" +#include "libpressio_ext/cpp/options.h" +#include "libpressio_ext/cpp/domain_manager.h" +#include "std_compat/memory.h" + +namespace libpressio { namespace metrics { namespace series_metrics_ns { + +class series_plugin : public libpressio_metrics_plugin { + public: + int end_compress_impl(struct pressio_data const* real_input, pressio_data const* real_output, int rc) override { + child->end_compress(real_input, real_output, rc); + return 0; + } + + int end_decompress_impl(struct pressio_data const* real_input, pressio_data const* real_output, int rc) override { + child->end_decompress(real_input, real_output, rc); + return 0; + } + + int end_compress_many_impl(compat::span const& inputs, + compat::span const& outputs, int rc) override { + child->end_compress_many(inputs, outputs, rc); + return 0; + } + + int end_decompress_many_impl(compat::span const& inputs, + compat::span const& outputs, int rc) override { + child->end_decompress_many(inputs, outputs, rc); + return 0; + } + + + struct pressio_options get_configuration_impl() const override { + pressio_options opts; + set(opts, "pressio:stability", "experimental"); + set(opts, "pressio:thread_safe", pressio_thread_safety_multiple); + set(opts, "predictors:requires_decompress", true); + set(opts, "predictors:invalidate", std::vector{"predictors:error_dependent"}); + return opts; + } + + struct pressio_options get_documentation_impl() const override { + pressio_options opt; + set(opt, "pressio:description", R"()"); + return opt; + } + + pressio_options get_metrics_results(pressio_options const &) override { + pressio_options opt; + opt.copy_from(child->get_metrics_results(opt)); + pressio_data qoi_data; + if(get(opt, qoi, &qoi_data) == pressio_options_key_set) { + //compute p90, p99, p999, median, mean, max, wasstinedistance + //qoi_data + } + + return opt; + } + + std::unique_ptr clone() override { + return compat::make_unique(*this); + } + const char* prefix() const override { + return "series"; + } + + private: + std::string qoi; + pressio_metric child; + +}; + +static pressio_register libpressio_metrics_series_plugin(metrics_plugins(), "series", [](){ return compat::make_unique(); }); +}}} + diff --git a/src/pressio_data.cc b/src/pressio_data.cc index ddac6d76..932d723e 100644 --- a/src/pressio_data.cc +++ b/src/pressio_data.cc @@ -8,6 +8,8 @@ #include "libpressio_ext/cpp/data.h" #include "./plugins/domains/user.h" #include "libpressio_ext/cpp/domain.h" +#include "libpressio_ext/cpp/domain_manager.h" +#include "std_compat/numeric.h" #if LIBPRESSIO_HAS_CUDA #include @@ -175,6 +177,217 @@ namespace { }; } +pressio_data pressio_data::join(std::vector&& bufs, pressio_data_header header, std::shared_ptr&& domain) { + std::vector sizes (bufs.size()); + std::transform(bufs.begin(), bufs.end(), sizes.begin(), [](pressio_data const& d){return d.size_in_bytes(); }); + + size_t header_size = 0; + switch(header) { + case pressio_data_header_dimstype: + header_size = bufs.size() * (sizeof(uint64_t) + sizeof(uint8_t)); + for(auto const& buf: bufs) { + header_size += (sizeof(uint64_t) * buf.num_dimensions()); + } + break; + case pressio_data_header_lentype: + header_size = bufs.size() * (sizeof(uint64_t) + sizeof(uint8_t)); + break; + case pressio_data_header_len: + header_size = bufs.size() * sizeof(uint64_t); + break; + case pressio_data_header_none: + break; + } + + std::vector offsets (sizes.size()); + compat::exclusive_scan(sizes.begin(), sizes.end(), offsets.begin(), header_size); + size_t total_size = offsets.back() + sizes.back(); + pressio_data out = pressio_data::owning(pressio_byte_dtype, {total_size}, domain->clone()); + + pressio_data header_buf; + switch(header) { + case pressio_data_header_dimstype: + { + header_buf = pressio_data::owning(pressio_byte_dtype, {header_size}); + auto* dims_ptr = reinterpret_cast(header_buf.data()); + for(auto const& buf: bufs) { + *dims_ptr++ = buf.num_dimensions(); + } + auto* types_ptr = reinterpret_cast(dims_ptr); + for(auto const& buf: bufs) { + *types_ptr++ = static_cast(buf.dtype()); + } + auto* shape_ptr = reinterpret_cast(types_ptr); + for(auto const& buf: bufs) { + shape_ptr = std::copy(buf.dims.begin(), buf.dims.end(), shape_ptr); + } + } + break; + case pressio_data_header_lentype: + header_buf = pressio_data::owning(pressio_byte_dtype, {header_size}); + std::copy(sizes.begin(), sizes.end(), (uint64_t*)header_buf.data()); + std::transform(bufs.begin(), bufs.end(), (uint8_t*)header_buf.data()+(sizeof(uint64_t)*bufs.size()), + [](pressio_data const& buf) {return (uint8_t)buf.dtype();}); + break; + case pressio_data_header_len: + header_buf = pressio_data(sizes.begin(), sizes.end()); + break; + case pressio_data_header_none: + break; + } + if(header != pressio_data_header_none) { + auto dom_buf = domain_manager().copy_to(domain->clone(), header_buf); + domain->memcpy(static_cast(out.data()),dom_buf.data(),header_size); + } + for(size_t i = 0; i < offsets.size(); ++i) { + auto dom_buf = domain_manager().make_readable(domain->clone(), bufs[i]); + domain->memcpy(static_cast(out.data())+offsets[i],dom_buf.data(),sizes[i]); + } + return out; + +} +pressio_data pressio_data::join(std::vector&& bufs, pressio_data_header header) { + if(bufs.empty()) throw std::runtime_error("inferring domain for pressio_data::join requires at least one buffer"); + return pressio_data::join(std::move(bufs), header, bufs.front().domain()->clone()); +} +pressio_data pressio_data::join(std::vector&& bufs) { + return pressio_data::join(std::move(bufs), pressio_data_header_dimstype); +} + +void pressio_data::split(pressio_data input, pressio_data_header header, std::vector& bufs) { + switch(header) { + case pressio_data_header_dimstype: + { + //first copy enough to determine the full header size + const size_t inital_header = bufs.size()* (sizeof(uint64_t)+sizeof(uint8_t)); + auto header = pressio_data::nonowning(pressio_uint8_dtype, input.data(), {inital_header}, input.domain()->domain_id()); + auto cpu_header = domain_manager().make_readable(libpressio::domain_plugins().build("malloc"), header); + auto header_ptr = static_cast(cpu_header.data()); + std::vector n_dims(header_ptr, header_ptr+bufs.size()); + size_t header_size = bufs.size()*(sizeof(uint64_t)+sizeof(uint8_t)); + for(size_t i = 0; i < bufs.size(); ++i) { + header_size += (sizeof(uint64_t)* n_dims[i]); + } + + //then copy the entire header + header = pressio_data::nonowning(pressio_uint8_dtype, input.data(), {header_size}, input.domain()->domain_id()); + cpu_header = domain_manager().make_readable(libpressio::domain_plugins().build("malloc"), header); + header_ptr = static_cast(cpu_header.data()); + + std::vector types(bufs.size()); + std::vector> dims(bufs.size()); + std::transform( + reinterpret_cast(header_ptr) + (bufs.size() * sizeof(uint64_t)), + reinterpret_cast(header_ptr) + (bufs.size() * (sizeof(uint64_t)+ sizeof(uint8_t))), + types.data(), + [](uint8_t i) { return static_cast(i); } + ); + auto ndims_ptr = reinterpret_cast(reinterpret_cast(header_ptr) + (bufs.size() * (sizeof(uint64_t)+sizeof(uint8_t)))); + + + for(size_t i = 0; i < bufs.size(); ++i) { + dims[i].resize(n_dims[i]); + std::copy( + ndims_ptr, + ndims_ptr+n_dims[i], + dims[i].begin()); + ndims_ptr += n_dims[i]; + } + std::vector offsets(bufs.size()); + std::vector sizes(bufs.size()); + for(size_t i = 0; i < bufs.size(); ++i) { + sizes[i] = libpressio::data_size_in_bytes(types[i], dims[i].size(), dims[i].data()); + } + compat::exclusive_scan(sizes.begin(), sizes.end(), offsets.begin(), header_size); + for(size_t i = 0; i< bufs.size(); ++i) { + if(bufs[i].has_data()) { + if(bufs[i].size_in_bytes() != sizes[i]) throw std::runtime_error("size of dst and src do not match"); + } + auto src = pressio_data::nonowning(types[i], static_cast(input.data()) + offsets[i], dims[i], input.domain()->domain_id()); + if(bufs[i].has_data()) { + bufs[i] = domain_manager().copy_to(std::move(bufs[i]), src); + } else { + bufs[i] = pressio_data::copy(types[i], src.data(), dims[i]); + } + } + } + break; + case pressio_data_header_lentype: + { + const size_t header_size = bufs.size()*(sizeof(uint64_t)+sizeof(uint8_t)); + auto header = pressio_data::nonowning(pressio_uint8_dtype, input.data(), {bufs.size()}, input.domain()->domain_id()); + auto cpu_header = domain_manager().make_readable(libpressio::domain_plugins().build("malloc"), header); + auto header_ptr = static_cast(cpu_header.data()); + std::vector sizes(header_ptr, header_ptr+bufs.size()); + std::vector types(bufs.size()); + std::transform( + (uint8_t*)header_ptr+(bufs.size() * sizeof(uint64_t)), + (uint8_t*)header_ptr+(bufs.size() * (sizeof(uint64_t)+ sizeof(uint8_t))), + types.data(), + [](uint8_t i) { return static_cast(i); } + ); + std::vector offsets(bufs.size()); + compat::exclusive_scan(sizes.begin(), sizes.end(), offsets.begin(), header_size); + for(size_t i = 0; i< bufs.size(); ++i) { + size_t n = sizes[i]/pressio_dtype_size(types[i]); + if(bufs[i].has_data()) { + if(bufs[i].size_in_bytes() != sizes[i]) throw std::runtime_error("size of dst and src do not match"); + } + auto src = pressio_data::nonowning(types[i], static_cast(input.data()) + offsets[i], {n}, input.domain()->domain_id()); + if(bufs[i].has_data()) { + bufs[i] = domain_manager().copy_to(std::move(bufs[i]), src); + } else { + bufs[i] = pressio_data::copy(types[i], src.data(), {n}); + } + } + } + break; + case pressio_data_header_len: { + auto header = pressio_data::nonowning(pressio_uint64_dtype, input.data(), {bufs.size()}, input.domain()->domain_id()); + auto cpu_header = domain_manager().make_readable(libpressio::domain_plugins().build("malloc"), header); + auto header_ptr = static_cast(cpu_header.data()); + const size_t header_size = bufs.size()*sizeof(uint64_t); + std::vector sizes(header_ptr, header_ptr+bufs.size()); + std::vector offsets(bufs.size()); + compat::exclusive_scan(sizes.begin(), sizes.end(), offsets.begin(), header_size); + for(size_t i = 0; i< bufs.size(); ++i) { + size_t n = sizes[i]/pressio_dtype_size(bufs[i].dtype()); + if(bufs[i].has_data()) { + if(bufs[i].size_in_bytes() != sizes[i]) throw std::runtime_error("size of dst and src do not match"); + } + auto src = pressio_data::nonowning(bufs[i].dtype(), static_cast(input.data()) + offsets[i], {n}, input.domain()->domain_id()); + if(bufs[i].has_data()) { + bufs[i] = domain_manager().copy_to(std::move(bufs[i]), src); + } else { + bufs[i] = pressio_data::copy(bufs[i].dtype(), src.data(), {n}); + } + } + } + break; + case pressio_data_header_none: + { + //sizes come from bufs + std::vector sizes(bufs.size()); + std::vector offsets(bufs.size()); + std::transform(bufs.begin(), bufs.end(), sizes.begin(), [](pressio_data& d) { return d.size_in_bytes(); }); + compat::exclusive_scan(sizes.begin(), sizes.end(), offsets.begin(), 0); + for(size_t i = 0; i< bufs.size(); ++i) { + bufs[i] = domain_manager().copy_to(std::move(bufs[i]).domain(), pressio_data::nonowning(bufs[i].dtype(), static_cast(input.data()) + offsets[i], bufs[i].dimensions(), input.domain()->domain_id())); + } + } + break; + } +} +void pressio_data::split(pressio_data input, std::vector& bufs) { + return pressio_data::split(input, pressio_data_header_dimstype, bufs); +} + +pressio_data pressio_data::type_domain(const pressio_dtype dtype, std::shared_ptr && domain) { + return pressio_data(dtype, {}, pressio_memory(std::move(domain))); + } +pressio_data pressio_data::empty(const pressio_dtype dtype, std::vector const& dimensions, std::shared_ptr const& domain) { + return pressio_data(dtype, dimensions, pressio_memory(domain)); + } pressio_data pressio_data::empty(const pressio_dtype dtype, std::vector const& dimensions, std::shared_ptr && domain) { return pressio_data(dtype, dimensions, pressio_memory(std::move(domain))); } diff --git a/src/pressio_hash.cc b/src/pressio_hash.cc index 4189d20a..99f3217c 100644 --- a/src/pressio_hash.cc +++ b/src/pressio_hash.cc @@ -91,13 +91,13 @@ static uint8_t* libpressio_options_hashimpl(struct pressio* library, struct pres } extern "C" { - uint8_t* libpressio_options_hashkeys(struct pressio* library, struct pressio_options const* options, size_t* output_size) { + uint8_t* pressio_options_hashkeys(struct pressio* library, struct pressio_options const* options, size_t* output_size) { return libpressio_options_hashimpl(library, options, output_size, [](hasher& h, pressio_options::value_type const& i){ h(i.first); }); } - uint8_t* libpressio_options_hashentries(struct pressio* library, struct pressio_options const* options, size_t* output_size) { + uint8_t* pressio_options_hashentries(struct pressio* library, struct pressio_options const* options, size_t* output_size) { return libpressio_options_hashimpl(library, options, output_size, [](hasher& h, pressio_options::value_type const& i){ h(i.first); h(i.second.type()); diff --git a/src/pressio_options.cc b/src/pressio_options.cc index 29f4c099..d746c3e7 100644 --- a/src/pressio_options.cc +++ b/src/pressio_options.cc @@ -55,16 +55,16 @@ size_t pressio_options_num_set(struct pressio_options const* options) { options->set(key, value); \ } #define pressio_options_define_type_impl_set(name, type) \ - enum pressio_options_key_status pressio_options_get_##name(struct pressio_options const* options, const char* key, type* value) { \ - return options->get(key, value); \ + enum pressio_options_key_status pressio_options_get_##name(struct pressio_options const* options, const char* key, type* outvalue) { \ + return options->get(key, outvalue); \ } #define pressio_options_define_type_impl_cast(name, type) \ enum pressio_options_key_status pressio_options_cast_##name(struct pressio_options const* options, const char* key, const enum pressio_conversion_safety safety, type* value) { \ return options->cast(key, value, safety); \ } #define pressio_options_define_type_impl_as(name, type) \ - enum pressio_options_key_status pressio_options_as_##name(struct pressio_options const* options, const char* key, type* value) { \ - return options->cast(key, value, pressio_conversion_implicit); \ + enum pressio_options_key_status pressio_options_as_##name(struct pressio_options const* options, const char* key, type* outvalue) { \ + return options->cast(key, outvalue, pressio_conversion_implicit); \ } #define pressio_options_define_type_impl(name, type) \ @@ -100,15 +100,15 @@ void pressio_options_set_userptr_managed(struct pressio_options* options, } //special case: string -- for memory management -void pressio_options_set_string(struct pressio_options* options, const char* key, const char* value) { \ - std::string value_tmp = value; +void pressio_options_set_string(struct pressio_options* options, const char* key, const char* outvalue) { \ + std::string value_tmp = outvalue; options->set(key, value_tmp); } -enum pressio_options_key_status pressio_options_get_string(struct pressio_options const* options, const char* key, const char** value) { \ +enum pressio_options_key_status pressio_options_get_string(struct pressio_options const* options, const char* key, const char** outvalue) { \ std::string value_tmp; auto status = options->get(key, &value_tmp); if(status == pressio_options_key_set) { - *value = strndup(value_tmp.c_str(), value_tmp.size()); + *outvalue = strndup(value_tmp.c_str(), value_tmp.size()); } return status; } @@ -128,8 +128,8 @@ enum pressio_options_key_status pressio_options_as_string(struct pressio_options void pressio_options_set_data(struct pressio_options* options, const char* key, struct pressio_data* value) { options->set(key, *value); } -enum pressio_options_key_status pressio_options_get_data(struct pressio_options const* options, const char* key, struct pressio_data** value) { \ - return options->get(key, *value); +enum pressio_options_key_status pressio_options_get_data(struct pressio_options const* options, const char* key, struct pressio_data** outvalue) { \ + return options->get(key, *outvalue); } enum pressio_options_key_status pressio_options_cast_data(struct pressio_options const* options, const char* key, const enum pressio_conversion_safety safety, struct pressio_data** value) { @@ -144,17 +144,17 @@ void pressio_options_set_strings(struct pressio_options* options, const char* ke std::vector strings(values, values+size); return options->set(key, strings); } -enum pressio_options_key_status pressio_options_get_strings(struct pressio_options const* options, const char* key, size_t* size, const char*** values) { +enum pressio_options_key_status pressio_options_get_strings(struct pressio_options const* options, const char* key, size_t* outsize, const char*** outvalues) { std::vector strings; auto status = options->get(key, &strings); if(status == pressio_options_key_set) { - *size = strings.size(); - *values = static_cast(malloc(sizeof(const char*)**size)); - for (size_t i = 0; i < *size; ++i) { - (*values)[i] = strndup(strings[i].c_str(), strings[i].size()); + *outsize = strings.size(); + *outvalues = static_cast(malloc(sizeof(const char*)**outsize)); + for (size_t i = 0; i < *outsize; ++i) { + (*outvalues)[i] = strndup(strings[i].c_str(), strings[i].size()); } } else { - *size = 0; + *outsize = 0; } return status; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 14394f4d..c3a7c899 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,6 @@ find_package(GTest) if(NOT GTEST_FOUND) + message(INFO "Google Test Not Found, installing from source") configure_file(GTestCMakeLists.txt.in googletest-download/CMakeLists.txt) execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . @@ -27,13 +28,15 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src ${CMAKE_CURRENT_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL) +else() + message(INFO "Google Test Found!") endif() include(GoogleTest) function(add_gtest) get_filename_component(test_name ${ARGV0} NAME_WE) add_executable(${test_name} ${ARGV}) - target_link_libraries(${test_name} PRIVATE libpressio gtest_main gtest gmock) + target_link_libraries(${test_name} PRIVATE libpressio GTest::gtest_main GTest::gtest GTest::gmock) gtest_discover_tests(${test_name}) endfunction() @@ -50,7 +53,7 @@ if(LIBPRESSIO_HAS_CUDA) endif() add_executable(test_compressor_integration ./test_compressor_integration.cc mpi_test_main.cc) -target_link_libraries(test_compressor_integration PRIVATE libpressio gtest gmock ${CMAKE_DL_LIBS}) +target_link_libraries(test_compressor_integration PRIVATE libpressio GTest::gtest GTest::gmock ${CMAKE_DL_LIBS}) if(LIBPRESSIO_HAS_MPI) target_link_libraries(test_compressor_integration PRIVATE MPI::MPI_CXX) endif() diff --git a/test/GTestCMakeLists.txt.in b/test/GTestCMakeLists.txt.in index c46f8e7c..765c6605 100644 --- a/test/GTestCMakeLists.txt.in +++ b/test/GTestCMakeLists.txt.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.15) project(googletest-download NONE) diff --git a/test/test_compressor_integration.cc b/test/test_compressor_integration.cc index 9ee55311..f5952ade 100644 --- a/test/test_compressor_integration.cc +++ b/test/test_compressor_integration.cc @@ -9,6 +9,9 @@ using namespace libpressio; std::set> skip_list { {"SZauto", "3d float zeros"}, {"qoz", "1d float"}, + {"szp", "1d int"}, + {"szp", "2d int"}, + {"szp", "3d int"}, {"qoz", "1d int"}, {"qoz", "3d int"}, {"qoz", "3d float zeros"}, @@ -19,6 +22,7 @@ std::set> skip_list { {"cusz", "2d float"}, {"cusz", "2d 0-1 float"}, {"cusz", "3d float zeros"}, + {"tthresh", "3d float zeros"}, }; template @@ -147,6 +151,7 @@ std::vector supported(Registry const& registry) { [](decltype(*registry.begin()) i) { return i.first; }); + ids.erase(std::remove(ids.begin(), ids.end(), "rcpp"), ids.end()); return ids; } @@ -364,9 +369,16 @@ template void test_no_matching_descriptions(Registry const& registry) { std::map> ids_by_desc; for (auto& entry : registry) { + if(entry.first == "rcpp") continue; std::string description; - auto compressor = entry.second(); - compressor->get_documentation().get("pressio:description", &description); + auto plugin = entry.second(); + if(!plugin) continue; + // Some plugins require additional runtime dependencies to fully materialize + // their documentation, which should not make the registry-wide uniqueness + // check crash. + if(plugin->get_documentation().get("pressio:description", &description) != pressio_options_key_set) { + continue; + } ids_by_desc[description].emplace_back(entry.first); } @@ -390,10 +402,11 @@ TEST(AllLaunch, NoMatchingDescriptions) { template void test_no_matching_prefixes(Registry const& registry) { std::map> ids_by_desc; - for (auto& entry : compressor_plugins()) { - std::string description; - auto compressor = entry.second(); - auto prefix = compressor->prefix(); + for (auto& entry : registry) { + if(entry.first == "rcpp") continue; + auto plugin = entry.second(); + if(!plugin) continue; + auto prefix = plugin->prefix(); ids_by_desc[prefix].emplace_back(entry.first); } diff --git a/test/test_pressio_data.cc b/test/test_pressio_data.cc index bfadc426..440b1bef 100644 --- a/test/test_pressio_data.cc +++ b/test/test_pressio_data.cc @@ -316,3 +316,39 @@ TEST(test_mulit_dimensional_array, test_mulit_dimensional_array_operator) { pressio_data_free(data); } + +TEST(test_to_from_tuple, test_to_from_tuple) { + std::tuple t{ + 3, 4.2f, 3.7, 'x' + }; + auto tuple_data = pressio_data(t); + EXPECT_EQ(tuple_data.size_in_bytes(), 4+4+8+1); + auto result = tuple_data.to_tuple(); + EXPECT_EQ(t, result); +} +TEST(test_join_split, test_join_split_headerlen) { + pressio_data a{1,2,3}; + pressio_data b{1.2,2.3,3.4}; + pressio_data c{1.2f,2.3f}; + pressio_data joined = pressio_data::join({a,b,c}, pressio_data_header_len); + std::vector s{ + pressio_data::empty(pressio_int32_dtype, {}), + pressio_data::empty(pressio_double_dtype, {}), + pressio_data::empty(pressio_float_dtype, {}), + }; + pressio_data::split(joined, pressio_data_header_len, s); + EXPECT_EQ(s[0], a); + EXPECT_EQ(s[1], b); + EXPECT_EQ(s[2], c); +} +TEST(test_join_split, test_join_split_dimstype) { + pressio_data a{1,2,3}; + pressio_data b{1.2,2.3,3.4}; + pressio_data c{1.2f,2.3f}; + pressio_data joined = pressio_data::join({a,b,c}, pressio_data_header_dimstype); + std::vector s(3); + pressio_data::split(joined, pressio_data_header_dimstype, s); + EXPECT_EQ(s[0], a); + EXPECT_EQ(s[1], b); + EXPECT_EQ(s[2], c); +} diff --git a/test/test_python.py b/test/test_python.py index 618b9c0a..d55c8e74 100755 --- a/test/test_python.py +++ b/test/test_python.py @@ -26,7 +26,7 @@ data = np.random.rand(300, 300, 300) -input_data = pressio.io_data_from_numpy(data) +input_data = pressio._from_dlpack(data) compressed_data = pressio.data_new_empty(pressio.byte_dtype, pressio.vector_uint64_t()) @@ -42,7 +42,7 @@ pressio.options_get_double(metric_results, b"size:compression_ratio", compression_ratio) print("compression ratio", pressio.double_value(compression_ratio)) -result = pressio.io_data_to_numpy(decompressed_data) +result = pressio.io_data_to_python(decompressed_data) pressio.delete_double(compression_ratio) pressio.data_free(input_data) pressio.data_free(compressed_data) diff --git a/tools/docs/generate_compressors_docs.cmake b/tools/docs/generate_compressors_docs.cmake new file mode 100644 index 00000000..42c8dc73 --- /dev/null +++ b/tools/docs/generate_compressors_docs.cmake @@ -0,0 +1,9 @@ +execute_process( + COMMAND "${CMAKE_BINARY_DIR}/tools/docs/generate_docs" -m c -o "$ENV{LIBPRESSIO_GENERATE_DOCS_OUTPUT}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + RESULT_VARIABLE gen_result +) + +if(NOT gen_result EQUAL 0) + file(WRITE "$ENV{LIBPRESSIO_GENERATE_DOCS_OUTPUT}" "# Compressors Modules {#compressors}\n\nCompressor documentation generation failed on this platform during build.\n") +endif() diff --git a/tools/docs/generate_docs.cc b/tools/docs/generate_docs.cc index 110791c6..0ba5ecd8 100644 --- a/tools/docs/generate_docs.cc +++ b/tools/docs/generate_docs.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -67,9 +68,18 @@ void for_each_options(struct pressio_options* options, Func f) { } void document_compressor(std::ostream& out, std::string const& compressor_id, const pressio_compressor* c) { + if(c == nullptr) { + return; + } pressio_options* docs = pressio_compressor_get_documentation(c); pressio_options* options = pressio_compressor_get_options(c); pressio_options* configuration = pressio_compressor_get_configuration(c); + if(docs == nullptr || options == nullptr || configuration == nullptr) { + pressio_options_free(docs); + pressio_options_free(options); + pressio_options_free(configuration); + return; + } // out << *configuration << std::endl; // out << *options << std::endl; @@ -633,6 +643,9 @@ int main(int argc, char* const argv[]) auto compressors = metas_list([]{return pressio_supported_compressors();}); for (auto const& compressor : compressors) { pressio_compressor* c = pressio_get_compressor(instance, compressor.c_str()); + if(c == nullptr) { + continue; + } pressio_compressor_set_name(c, name); document_compressor(out, compressor, c); pressio_compressor_release(c); diff --git a/tools/hdf5_filter/src/libpressio_hdf5_filter.cc b/tools/hdf5_filter/src/libpressio_hdf5_filter.cc index fbb2be86..084f82b2 100644 --- a/tools/hdf5_filter/src/libpressio_hdf5_filter.cc +++ b/tools/hdf5_filter/src/libpressio_hdf5_filter.cc @@ -6,7 +6,7 @@ #include #include #include -#include +#include compression_options get_options_from_cd_values(size_t cd_nelmts, const unsigned int* cd_values) { compression_options options; diff --git a/tools/swig/CMakeLists.txt b/tools/swig/CMakeLists.txt index 9e6a7bc3..cca3ecb0 100644 --- a/tools/swig/CMakeLists.txt +++ b/tools/swig/CMakeLists.txt @@ -1,49 +1,84 @@ -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) -find_package(Python3 COMPONENTS Interpreter Development NumPy) -find_package(SWIG) +cmake_minimum_required(VERSION 3.18 FATAL_ERROR) +find_package(Python3 COMPONENTS Interpreter Development.Module) +find_package(SWIG COMPONENTS python REQUIRED) +find_package(dlpack) + +if(NOT dlpack_FOUND) + include(FetchContent) + FetchContent_Declare( + dlpack + GIT_REPOSITORY https://github.com/dmlc/dlpack + GIT_TAG 93c8f2a3c774b84af6f652b1992c48164fae60fc #git version 1.2 + ) + FetchContent_MakeAvailable(dlpack) +endif() + if(SWIG_FOUND AND PYTHON3_FOUND) include(UseSWIG) set(CMAKE_SWIG_FLAGS "-doxygen") if(NOT LIBPRESSIO_PYTHON_SITELIB) - set(LIBPRESSIO_PYTHON_SITELIB ${Python3_SITELIB} CACHE PATH "path to install python libraries to") + if(DEFINED SKBUILD) + set(LIBPRESSIO_PYTHON_SITELIB ${SKBUILD_PLATLIB_DIR} CACHE PATH "path to install python libraries to") + else() + set(LIBPRESSIO_PYTHON_SITELIB ${Python3_SITELIB} CACHE PATH "path to install python libraries to") + endif() endif() - function(build_pressio_swig_module) - get_filename_component(filelibname ${ARGV0} NAME_WE) - set_property(SOURCE ${ARGV0} PROPERTY CPLUSPLUS ON) - set_property(SOURCE ${ARGV0} PROPERTY USE_TARGET_INCLUDE_DIRECTORIES ON) - set_property(SOURCE ${ARGV0}.i PROPERTY SWIG_MODULE_NAME ${filelibname}) - swig_add_library( - ${filelibname} - LANGUAGE python - SOURCES ${ARGV} + set_property(SOURCE pressio.i PROPERTY CPLUSPLUS ON) + set_property(SOURCE pressio.i PROPERTY USE_TARGET_INCLUDE_DIRECTORIES ON) + set_property(SOURCE pressio.i PROPERTY SWIG_MODULE_NAME pressio) + if(DEFINED SKBUILD) + swig_add_library( + pressio + LANGUAGE python OUTPUT_DIR "${SKBUILD_PLATLIB_DIR}" + SOURCES pressio.i + ) + if(WIN32) + set_property(TARGET pressio PROPERTY SUFFIX ".${SKBUILD_SOABI}.pyd") + else() + set_property(TARGET pressio + PROPERTY SUFFIX ".${SKBUILD_SOABI}${CMAKE_SHARED_MODULE_SUFFIX}") + endif() + if(APPLE) + set(origin_token "@loader_path") + else() + set(origin_token "$ORIGIN") + endif() + set_property(TARGET pressio PROPERTY INSTALL_RPATH + "${origin_token}/" + ) + else() + swig_add_library( + pressio + LANGUAGE python + SOURCES pressio.i ) - set_property(TARGET ${filelibname} PROPERTY SWIG_COMPILE_DEFINITIONS "SWIGWORDSIZE64") - target_link_libraries(${filelibname} PUBLIC libpressio Python3::Python Python3::NumPy) - target_include_directories(${filelibname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - if(LIBPRESSIO_HAS_MPI4PY) + endif() + set_property(TARGET pressio PROPERTY SWIG_COMPILE_DEFINITIONS "SWIGWORDSIZE64") + target_link_libraries(pressio PUBLIC libpressio Python3::Module dlpack::dlpack) + target_sources(pressio PRIVATE pypressio.cc) + target_include_directories(pressio PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + if(LIBPRESSIO_HAS_MPI4PY) execute_process( - COMMAND ${Python3_EXECUTABLE} -c "import mpi4py; print(mpi4py.get_include())" - OUTPUT_VARIABLE MPI4PY_SWIG_DIR - RESULT_VARIABLE MPI4PY_FOUND - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND ${Python3_EXECUTABLE} -c "import mpi4py; print(mpi4py.get_include())" + OUTPUT_VARIABLE MPI4PY_SWIG_DIR + RESULT_VARIABLE MPI4PY_FOUND + OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT ${MPI4PY_FOUND} EQUAL "0") - message(FATAL_ERROR "Could not locate mpi4py") + message(FATAL_ERROR "Could not locate mpi4py") endif() - target_include_directories(${filelibname} PRIVATE ${MPI4PY_SWIG_DIR} ${MPI_CXX_INCLUDE_DIRS}) - endif() - get_property(swig_generated_module TARGET ${filelibname} PROPERTY SWIG_SUPPORT_FILES) + target_include_directories(pressio PRIVATE ${MPI4PY_SWIG_DIR} ${MPI_CXX_INCLUDE_DIRS}) + endif() + get_property(swig_generated_module TARGET pressio PROPERTY SWIG_SUPPORT_FILES) - install(TARGETS ${filelibname} DESTINATION ${LIBPRESSIO_PYTHON_SITELIB}) - install(FILES ${swig_generated_module} DESTINATION ${LIBPRESSIO_PYTHON_SITELIB}) + install(TARGETS pressio DESTINATION ${LIBPRESSIO_PYTHON_SITELIB}) + install(FILES ${swig_generated_module} DESTINATION ${LIBPRESSIO_PYTHON_SITELIB}) - endfunction() - build_pressio_swig_module(pressio.i pypressio.h) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/libpressio.py" DESTINATION ${LIBPRESSIO_PYTHON_SITELIB}) endif() diff --git a/tools/swig/libpressio.py b/tools/swig/libpressio.py index 2dfc7093..bc7eb9cf 100644 --- a/tools/swig/libpressio.py +++ b/tools/swig/libpressio.py @@ -99,6 +99,12 @@ def from_metric(cls, metrics): error_code = pressio.metrics_error_code(metrics) return cls(msg, error_code) +def io_data_from_numpy(x): + return python_to_new_pressio_data(x) + +def _from_dlpack(x): + return python_to_new_pressio_data(x) + def python_to_new_pressio_data(x): if hasattr(x, "__cuda_array_interface__"): info = x.__cuda_array_interface__ @@ -128,8 +134,6 @@ def python_to_new_pressio_data(x): ) elif is_pressio_data(x): return pressio.data_new_nonowning_from_data(x) - elif isinstance(x, np.ndarray): - return pressio.io_data_from_numpy(x) else: raise NotImplementedError() @@ -145,7 +149,10 @@ def pressio_data_to_python(x, out=None): return ret, True def pressio_dtype_to_python(dtype) -> np.dtype: - return np.dtype(pressio.dtype_to_typestr(dtype)) + typestr = pressio.dtype_to_typestr(dtype) + if isinstance(typestr, bytes): + typestr = typestr.decode() + return np.dtype(typestr) def pressio_dtype_from_python(d : np.dtype) -> int: return pressio.dtype_from_typestr(np.dtype(d).str.encode()) diff --git a/tools/swig/numpy.i b/tools/swig/numpy.i deleted file mode 100644 index 36bb55c9..00000000 --- a/tools/swig/numpy.i +++ /dev/null @@ -1,3183 +0,0 @@ -/* -*- C -*- (not really, but good for syntax highlighting) */ - -/* - * Copyright (c) 2005-2015, NumPy Developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of the NumPy Developers nor the names of any - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef SWIGPYTHON - -%{ -#ifndef SWIG_FILE_WITH_INIT -#define NO_IMPORT_ARRAY -#endif -#include "stdio.h" -#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION -#include -%} - -/**********************************************************************/ - -%fragment("NumPy_Backward_Compatibility", "header") -{ -%#if NPY_API_VERSION < 0x00000007 -%#define NPY_ARRAY_DEFAULT NPY_DEFAULT -%#define NPY_ARRAY_FARRAY NPY_FARRAY -%#define NPY_FORTRANORDER NPY_FORTRAN -%#endif -} - -/**********************************************************************/ - -/* The following code originally appeared in - * enthought/kiva/agg/src/numeric.i written by Eric Jones. It was - * translated from C++ to C by John Hunter. Bill Spotz has modified - * it to fix some minor bugs, upgrade from Numeric to numpy (all - * versions), add some comments and functionality, and convert from - * direct code insertion to SWIG fragments. - */ - -%fragment("NumPy_Macros", "header") -{ -/* Macros to extract array attributes. - */ -%#if NPY_API_VERSION < 0x00000007 -%#define is_array(a) ((a) && PyArray_Check((PyArrayObject*)a)) -%#define array_type(a) (int)(PyArray_TYPE((PyArrayObject*)a)) -%#define array_numdims(a) (((PyArrayObject*)a)->nd) -%#define array_dimensions(a) (((PyArrayObject*)a)->dimensions) -%#define array_size(a,i) (((PyArrayObject*)a)->dimensions[i]) -%#define array_strides(a) (((PyArrayObject*)a)->strides) -%#define array_stride(a,i) (((PyArrayObject*)a)->strides[i]) -%#define array_data(a) (((PyArrayObject*)a)->data) -%#define array_descr(a) (((PyArrayObject*)a)->descr) -%#define array_flags(a) (((PyArrayObject*)a)->flags) -%#define array_clearflags(a,f) (((PyArrayObject*)a)->flags) &= ~f -%#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f -%#define array_is_fortran(a) (PyArray_ISFORTRAN((PyArrayObject*)a)) -%#else -%#define is_array(a) ((a) && PyArray_Check(a)) -%#define array_type(a) PyArray_TYPE((PyArrayObject*)a) -%#define array_numdims(a) PyArray_NDIM((PyArrayObject*)a) -%#define array_dimensions(a) PyArray_DIMS((PyArrayObject*)a) -%#define array_strides(a) PyArray_STRIDES((PyArrayObject*)a) -%#define array_stride(a,i) PyArray_STRIDE((PyArrayObject*)a,i) -%#define array_size(a,i) PyArray_DIM((PyArrayObject*)a,i) -%#define array_data(a) PyArray_DATA((PyArrayObject*)a) -%#define array_descr(a) PyArray_DESCR((PyArrayObject*)a) -%#define array_flags(a) PyArray_FLAGS((PyArrayObject*)a) -%#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f) -%#define array_clearflags(a,f) PyArray_CLEARFLAGS((PyArrayObject*)a,f) -%#define array_is_fortran(a) (PyArray_IS_F_CONTIGUOUS((PyArrayObject*)a)) -%#endif -%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a)) -%#define array_is_native(a) (PyArray_ISNOTSWAPPED((PyArrayObject*)a)) -} - -/**********************************************************************/ - -%fragment("NumPy_Utilities", - "header") -{ - /* Given a PyObject, return a string describing its type. - */ - const char* pytype_string(PyObject* py_obj) - { - if (py_obj == NULL ) return "C NULL value"; - if (py_obj == Py_None ) return "Python None" ; - if (PyCallable_Check(py_obj)) return "callable" ; - if (PyString_Check( py_obj)) return "string" ; - if (PyInt_Check( py_obj)) return "int" ; - if (PyFloat_Check( py_obj)) return "float" ; - if (PyDict_Check( py_obj)) return "dict" ; - if (PyList_Check( py_obj)) return "list" ; - if (PyTuple_Check( py_obj)) return "tuple" ; -%#if PY_MAJOR_VERSION < 3 - if (PyFile_Check( py_obj)) return "file" ; - if (PyModule_Check( py_obj)) return "module" ; - if (PyInstance_Check(py_obj)) return "instance" ; -%#endif - - return "unknown type"; - } - - /* Given a NumPy typecode, return a string describing the type. - */ - const char* typecode_string(int typecode) - { - static const char* type_names[25] = {"bool", - "byte", - "unsigned byte", - "short", - "unsigned short", - "int", - "unsigned int", - "long", - "unsigned long", - "long long", - "unsigned long long", - "float", - "double", - "long double", - "complex float", - "complex double", - "complex long double", - "object", - "string", - "unicode", - "void", - "ntypes", - "notype", - "char", - "unknown"}; - return typecode < 24 ? type_names[typecode] : type_names[24]; - } - - /* Make sure input has correct numpy type. This now just calls - PyArray_EquivTypenums(). - */ - int type_match(int actual_type, - int desired_type) - { - return PyArray_EquivTypenums(actual_type, desired_type); - } - -%#ifdef SWIGPY_USE_CAPSULE - void free_cap(PyObject * cap) - { - void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME); - if (array != NULL) free(array); - } -%#endif - - -} - -/**********************************************************************/ - -%fragment("NumPy_Object_to_Array", - "header", - fragment="NumPy_Backward_Compatibility", - fragment="NumPy_Macros", - fragment="NumPy_Utilities") -{ - /* Given a PyObject pointer, cast it to a PyArrayObject pointer if - * legal. If not, set the python error string appropriately and - * return NULL. - */ - PyArrayObject* obj_to_array_no_conversion(PyObject* input, - int typecode) - { - PyArrayObject* ary = NULL; - if (is_array(input) && (typecode == NPY_NOTYPE || - PyArray_EquivTypenums(array_type(input), typecode))) - { - ary = (PyArrayObject*) input; - } - else if is_array(input) - { - const char* desired_type = typecode_string(typecode); - const char* actual_type = typecode_string(array_type(input)); - PyErr_Format(PyExc_TypeError, - "Array of type '%s' required. Array of type '%s' given", - desired_type, actual_type); - ary = NULL; - } - else - { - const char* desired_type = typecode_string(typecode); - const char* actual_type = pytype_string(input); - PyErr_Format(PyExc_TypeError, - "Array of type '%s' required. A '%s' was given", - desired_type, - actual_type); - ary = NULL; - } - return ary; - } - - /* Convert the given PyObject to a NumPy array with the given - * typecode. On success, return a valid PyArrayObject* with the - * correct type. On failure, the python error string will be set and - * the routine returns NULL. - */ - PyArrayObject* obj_to_array_allow_conversion(PyObject* input, - int typecode, - int* is_new_object) - { - PyArrayObject* ary = NULL; - PyObject* py_obj; - if (is_array(input) && (typecode == NPY_NOTYPE || - PyArray_EquivTypenums(array_type(input),typecode))) - { - ary = (PyArrayObject*) input; - *is_new_object = 0; - } - else - { - py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT); - /* If NULL, PyArray_FromObject will have set python error value.*/ - ary = (PyArrayObject*) py_obj; - *is_new_object = 1; - } - return ary; - } - - /* Given a PyArrayObject, check to see if it is contiguous. If so, - * return the input pointer and flag it as not a new object. If it is - * not contiguous, create a new PyArrayObject using the original data, - * flag it as a new object and return the pointer. - */ - PyArrayObject* make_contiguous(PyArrayObject* ary, - int* is_new_object, - int min_dims, - int max_dims) - { - PyArrayObject* result; - if (array_is_contiguous(ary)) - { - result = ary; - *is_new_object = 0; - } - else - { - result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary, - array_type(ary), - min_dims, - max_dims); - *is_new_object = 1; - } - return result; - } - - /* Given a PyArrayObject, check to see if it is Fortran-contiguous. - * If so, return the input pointer, but do not flag it as not a new - * object. If it is not Fortran-contiguous, create a new - * PyArrayObject using the original data, flag it as a new object - * and return the pointer. - */ - PyArrayObject* make_fortran(PyArrayObject* ary, - int* is_new_object) - { - PyArrayObject* result; - if (array_is_fortran(ary)) - { - result = ary; - *is_new_object = 0; - } - else - { - Py_INCREF(array_descr(ary)); - result = (PyArrayObject*) PyArray_FromArray(ary, - array_descr(ary), -%#if NPY_API_VERSION < 0x00000007 - NPY_FORTRANORDER); -%#else - NPY_ARRAY_F_CONTIGUOUS); -%#endif - *is_new_object = 1; - } - return result; - } - - /* Convert a given PyObject to a contiguous PyArrayObject of the - * specified type. If the input object is not a contiguous - * PyArrayObject, a new one will be created and the new object flag - * will be set. - */ - PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input, - int typecode, - int* is_new_object) - { - int is_new1 = 0; - int is_new2 = 0; - PyArrayObject* ary2; - PyArrayObject* ary1 = obj_to_array_allow_conversion(input, - typecode, - &is_new1); - if (ary1) - { - ary2 = make_contiguous(ary1, &is_new2, 0, 0); - if ( is_new1 && is_new2) - { - Py_DECREF(ary1); - } - ary1 = ary2; - } - *is_new_object = is_new1 || is_new2; - return ary1; - } - - /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the - * specified type. If the input object is not a Fortran-ordered - * PyArrayObject, a new one will be created and the new object flag - * will be set. - */ - PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input, - int typecode, - int* is_new_object) - { - int is_new1 = 0; - int is_new2 = 0; - PyArrayObject* ary2; - PyArrayObject* ary1 = obj_to_array_allow_conversion(input, - typecode, - &is_new1); - if (ary1) - { - ary2 = make_fortran(ary1, &is_new2); - if (is_new1 && is_new2) - { - Py_DECREF(ary1); - } - ary1 = ary2; - } - *is_new_object = is_new1 || is_new2; - return ary1; - } -} /* end fragment */ - -/**********************************************************************/ - -%fragment("NumPy_Array_Requirements", - "header", - fragment="NumPy_Backward_Compatibility", - fragment="NumPy_Macros") -{ - /* Test whether a python object is contiguous. If array is - * contiguous, return 1. Otherwise, set the python error string and - * return 0. - */ - int require_contiguous(PyArrayObject* ary) - { - int contiguous = 1; - if (!array_is_contiguous(ary)) - { - PyErr_SetString(PyExc_TypeError, - "Array must be contiguous. A non-contiguous array was given"); - contiguous = 0; - } - return contiguous; - } - - /* Test whether a python object is (C_ or F_) contiguous. If array is - * contiguous, return 1. Otherwise, set the python error string and - * return 0. - */ - int require_c_or_f_contiguous(PyArrayObject* ary) - { - int contiguous = 1; - if (!(array_is_contiguous(ary) || array_is_fortran(ary))) - { - PyErr_SetString(PyExc_TypeError, - "Array must be contiguous (C_ or F_). A non-contiguous array was given"); - contiguous = 0; - } - return contiguous; - } - - /* Require that a numpy array is not byte-swapped. If the array is - * not byte-swapped, return 1. Otherwise, set the python error string - * and return 0. - */ - int require_native(PyArrayObject* ary) - { - int native = 1; - if (!array_is_native(ary)) - { - PyErr_SetString(PyExc_TypeError, - "Array must have native byteorder. " - "A byte-swapped array was given"); - native = 0; - } - return native; - } - - /* Require the given PyArrayObject to have a specified number of - * dimensions. If the array has the specified number of dimensions, - * return 1. Otherwise, set the python error string and return 0. - */ - int require_dimensions(PyArrayObject* ary, - int exact_dimensions) - { - int success = 1; - if (array_numdims(ary) != exact_dimensions) - { - PyErr_Format(PyExc_TypeError, - "Array must have %d dimensions. Given array has %d dimensions", - exact_dimensions, - array_numdims(ary)); - success = 0; - } - return success; - } - - /* Require the given PyArrayObject to have one of a list of specified - * number of dimensions. If the array has one of the specified number - * of dimensions, return 1. Otherwise, set the python error string - * and return 0. - */ - int require_dimensions_n(PyArrayObject* ary, - int* exact_dimensions, - int n) - { - int success = 0; - int i; - char dims_str[255] = ""; - char s[255]; - for (i = 0; i < n && !success; i++) - { - if (array_numdims(ary) == exact_dimensions[i]) - { - success = 1; - } - } - if (!success) - { - for (i = 0; i < n-1; i++) - { - sprintf(s, "%d, ", exact_dimensions[i]); - strcat(dims_str,s); - } - sprintf(s, " or %d", exact_dimensions[n-1]); - strcat(dims_str,s); - PyErr_Format(PyExc_TypeError, - "Array must have %s dimensions. Given array has %d dimensions", - dims_str, - array_numdims(ary)); - } - return success; - } - - /* Require the given PyArrayObject to have a specified shape. If the - * array has the specified shape, return 1. Otherwise, set the python - * error string and return 0. - */ - int require_size(PyArrayObject* ary, - npy_intp* size, - int n) - { - int i; - int success = 1; - size_t len; - char desired_dims[255] = "["; - char s[255]; - char actual_dims[255] = "["; - for(i=0; i < n;i++) - { - if (size[i] != -1 && size[i] != array_size(ary,i)) - { - success = 0; - } - } - if (!success) - { - for (i = 0; i < n; i++) - { - if (size[i] == -1) - { - sprintf(s, "*,"); - } - else - { - sprintf(s, "%ld,", (long int)size[i]); - } - strcat(desired_dims,s); - } - len = strlen(desired_dims); - desired_dims[len-1] = ']'; - for (i = 0; i < n; i++) - { - sprintf(s, "%ld,", (long int)array_size(ary,i)); - strcat(actual_dims,s); - } - len = strlen(actual_dims); - actual_dims[len-1] = ']'; - PyErr_Format(PyExc_TypeError, - "Array must have shape of %s. Given array has shape of %s", - desired_dims, - actual_dims); - } - return success; - } - - /* Require the given PyArrayObject to to be Fortran ordered. If the - * the PyArrayObject is already Fortran ordered, do nothing. Else, - * set the Fortran ordering flag and recompute the strides. - */ - int require_fortran(PyArrayObject* ary) - { - int success = 1; - int nd = array_numdims(ary); - int i; - npy_intp * strides = array_strides(ary); - if (array_is_fortran(ary)) return success; - int n_non_one = 0; - /* Set the Fortran ordered flag */ - const npy_intp *dims = array_dimensions(ary); - for (i=0; i < nd; ++i) - n_non_one += (dims[i] != 1) ? 1 : 0; - if (n_non_one > 1) - array_clearflags(ary,NPY_ARRAY_CARRAY); - array_enableflags(ary,NPY_ARRAY_FARRAY); - /* Recompute the strides */ - strides[0] = strides[nd-1]; - for (i=1; i < nd; ++i) - strides[i] = strides[i-1] * array_size(ary,i-1); - return success; - } -} - -/* Combine all NumPy fragments into one for convenience */ -%fragment("NumPy_Fragments", - "header", - fragment="NumPy_Backward_Compatibility", - fragment="NumPy_Macros", - fragment="NumPy_Utilities", - fragment="NumPy_Object_to_Array", - fragment="NumPy_Array_Requirements") -{ -} - -/* End John Hunter translation (with modifications by Bill Spotz) - */ - -/* %numpy_typemaps() macro - * - * This macro defines a family of 75 typemaps that allow C arguments - * of the form - * - * 1. (DATA_TYPE IN_ARRAY1[ANY]) - * 2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) - * 3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) - * - * 4. (DATA_TYPE IN_ARRAY2[ANY][ANY]) - * 5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - * 6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) - * 7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - * 8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) - * - * 9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) - * 10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - * 11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - * 12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) - * 13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - * 14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) - * - * 15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) - * 16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - * 17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - * 18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) - * 19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - * 20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) - * - * 21. (DATA_TYPE INPLACE_ARRAY1[ANY]) - * 22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) - * 23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) - * - * 24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) - * 25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - * 26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) - * 27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - * 28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) - * - * 29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) - * 30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - * 31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - * 32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) - * 33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - * 34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) - * - * 35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) - * 36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - * 37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - * 38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) - * 39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - * 40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) - * - * 41. (DATA_TYPE ARGOUT_ARRAY1[ANY]) - * 42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) - * 43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) - * - * 44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) - * - * 45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) - * - * 46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) - * - * 47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) - * 48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) - * - * 49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - * 50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) - * 51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - * 52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) - * - * 53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) - * 54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) - * 55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) - * 56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) - * - * 57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) - * 58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4) - * 59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) - * 60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4) - * - * 61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) - * 62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) - * - * 63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - * 64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) - * 65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - * 66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) - * - * 67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) - * 68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3) - * 69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) - * 70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3) - * - * 71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) - * 72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) - * 73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) - * 74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) - * - * 75. (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) - * - * where "DATA_TYPE" is any type supported by the NumPy module, and - * "DIM_TYPE" is any int-like type suitable for specifying dimensions. - * The difference between "ARRAY" typemaps and "FARRAY" typemaps is - * that the "FARRAY" typemaps expect Fortran ordering of - * multidimensional arrays. In python, the dimensions will not need - * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1" - * typemaps). The IN_ARRAYs can be a numpy array or any sequence that - * can be converted to a numpy array of the specified type. The - * INPLACE_ARRAYs must be numpy arrays of the appropriate type. The - * ARGOUT_ARRAYs will be returned as new numpy arrays of the - * appropriate type. - * - * These typemaps can be applied to existing functions using the - * %apply directive. For example: - * - * %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)}; - * double prod(double* series, int length); - * - * %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2) - * {(int rows, int cols, double* matrix )}; - * void floor(int rows, int cols, double* matrix, double f); - * - * %apply (double IN_ARRAY3[ANY][ANY][ANY]) - * {(double tensor[2][2][2] )}; - * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY]) - * {(double low[2][2][2] )}; - * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY]) - * {(double upp[2][2][2] )}; - * void luSplit(double tensor[2][2][2], - * double low[2][2][2], - * double upp[2][2][2] ); - * - * or directly with - * - * double prod(double* IN_ARRAY1, int DIM1); - * - * void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f); - * - * void luSplit(double IN_ARRAY3[ANY][ANY][ANY], - * double ARGOUT_ARRAY3[ANY][ANY][ANY], - * double ARGOUT_ARRAY3[ANY][ANY][ANY]); - */ - -%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE) - -/************************/ -/* Input Array Typemaps */ -/************************/ - -/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE IN_ARRAY1[ANY]) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE IN_ARRAY1[ANY]) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[1] = { $1_dim0 }; - array = obj_to_array_contiguous_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 1) || - !require_size(array, size, 1)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(freearg) - (DATA_TYPE IN_ARRAY1[ANY]) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[1] = { -1 }; - array = obj_to_array_contiguous_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 1) || - !require_size(array, size, 1)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); -} -%typemap(freearg) - (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[1] = {-1}; - array = obj_to_array_contiguous_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 1) || - !require_size(array, size, 1)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DATA_TYPE*) array_data(array); -} -%typemap(freearg) - (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE IN_ARRAY2[ANY][ANY]) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE IN_ARRAY2[ANY][ANY]) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[2] = { $1_dim0, $1_dim1 }; - array = obj_to_array_contiguous_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 2) || - !require_size(array, size, 2)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(freearg) - (DATA_TYPE IN_ARRAY2[ANY][ANY]) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[2] = { -1, -1 }; - array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 2) || - !require_size(array, size, 2)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); -} -%typemap(freearg) - (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[2] = { -1, -1 }; - array = obj_to_array_contiguous_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 2) || - !require_size(array, size, 2)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DATA_TYPE*) array_data(array); -} -%typemap(freearg) - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[2] = { -1, -1 }; - array = obj_to_array_fortran_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 2) || - !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); -} -%typemap(freearg) - (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[2] = { -1, -1 }; - array = obj_to_array_fortran_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 2) || - !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DATA_TYPE*) array_data(array); -} -%typemap(freearg) - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 }; - array = obj_to_array_contiguous_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 3) || - !require_size(array, size, 3)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(freearg) - (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[3] = { -1, -1, -1 }; - array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 3) || - !require_size(array, size, 3)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); -} -%typemap(freearg) - (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - /* for now, only concerned with lists */ - $1 = PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL) -{ - npy_intp size[2] = { -1, -1 }; - PyArrayObject* temp_array; - Py_ssize_t i; - int is_new_object; - - /* length of the list */ - $2 = PyList_Size($input); - - /* the arrays */ - array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); - object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); - is_new_object_array = (int *)calloc($2,sizeof(int)); - - if (array == NULL || object_array == NULL || is_new_object_array == NULL) - { - SWIG_fail; - } - - for (i=0; i<$2; i++) - { - temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object); - - /* the new array must be stored so that it can be destroyed in freearg */ - object_array[i] = temp_array; - is_new_object_array[i] = is_new_object; - - if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail; - - /* store the size of the first array in the list, then use that for comparison. */ - if (i == 0) - { - size[0] = array_size(temp_array,0); - size[1] = array_size(temp_array,1); - } - - if (!require_size(temp_array, size, 2)) SWIG_fail; - - array[i] = (DATA_TYPE*) array_data(temp_array); - } - - $1 = (DATA_TYPE**) array; - $3 = (DIM_TYPE) size[0]; - $4 = (DIM_TYPE) size[1]; -} -%typemap(freearg) - (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - Py_ssize_t i; - - if (array$argnum!=NULL) free(array$argnum); - - /*freeing the individual arrays if needed */ - if (object_array$argnum!=NULL) - { - if (is_new_object_array$argnum!=NULL) - { - for (i=0; i<$2; i++) - { - if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i]) - { Py_DECREF(object_array$argnum[i]); } - } - free(is_new_object_array$argnum); - } - free(object_array$argnum); - } -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, - * DATA_TYPE* IN_ARRAY3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[3] = { -1, -1, -1 }; - array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 3) || - !require_size(array, size, 3)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DATA_TYPE*) array_data(array); -} -%typemap(freearg) - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[3] = { -1, -1, -1 }; - array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 3) || - !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); -} -%typemap(freearg) - (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, - * DATA_TYPE* IN_FARRAY3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[3] = { -1, -1, -1 }; - array = obj_to_array_fortran_allow_conversion($input, - DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 3) || - !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DATA_TYPE*) array_data(array); -} -%typemap(freearg) - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3}; - array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 4) || - !require_size(array, size, 4)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(freearg) - (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3, DIM_TYPE DIM4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[4] = { -1, -1, -1, -1 }; - array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 4) || - !require_size(array, size, 4)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); - $5 = (DIM_TYPE) array_size(array,3); -} -%typemap(freearg) - (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3, DIM_TYPE DIM4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - /* for now, only concerned with lists */ - $1 = PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL) -{ - npy_intp size[3] = { -1, -1, -1 }; - PyArrayObject* temp_array; - Py_ssize_t i; - int is_new_object; - - /* length of the list */ - $2 = PyList_Size($input); - - /* the arrays */ - array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); - object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); - is_new_object_array = (int *)calloc($2,sizeof(int)); - - if (array == NULL || object_array == NULL || is_new_object_array == NULL) - { - SWIG_fail; - } - - for (i=0; i<$2; i++) - { - temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object); - - /* the new array must be stored so that it can be destroyed in freearg */ - object_array[i] = temp_array; - is_new_object_array[i] = is_new_object; - - if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail; - - /* store the size of the first array in the list, then use that for comparison. */ - if (i == 0) - { - size[0] = array_size(temp_array,0); - size[1] = array_size(temp_array,1); - size[2] = array_size(temp_array,2); - } - - if (!require_size(temp_array, size, 3)) SWIG_fail; - - array[i] = (DATA_TYPE*) array_data(temp_array); - } - - $1 = (DATA_TYPE**) array; - $3 = (DIM_TYPE) size[0]; - $4 = (DIM_TYPE) size[1]; - $5 = (DIM_TYPE) size[2]; -} -%typemap(freearg) - (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - Py_ssize_t i; - - if (array$argnum!=NULL) free(array$argnum); - - /*freeing the individual arrays if needed */ - if (object_array$argnum!=NULL) - { - if (is_new_object_array$argnum!=NULL) - { - for (i=0; i<$2; i++) - { - if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i]) - { Py_DECREF(object_array$argnum[i]); } - } - free(is_new_object_array$argnum); - } - free(object_array$argnum); - } -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, - * DATA_TYPE* IN_ARRAY4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[4] = { -1, -1, -1 , -1}; - array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 4) || - !require_size(array, size, 4)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DIM_TYPE) array_size(array,3); - $5 = (DATA_TYPE*) array_data(array); -} -%typemap(freearg) - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3, DIM_TYPE DIM4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[4] = { -1, -1, -1, -1 }; - array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 4) || - !require_size(array, size, 4) | !require_fortran(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); - $5 = (DIM_TYPE) array_size(array,3); -} -%typemap(freearg) - (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, - * DATA_TYPE* IN_FARRAY4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) -{ - $1 = is_array($input) || PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) - (PyArrayObject* array=NULL, int is_new_object=0) -{ - npy_intp size[4] = { -1, -1, -1 , -1 }; - array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, - &is_new_object); - if (!array || !require_dimensions(array, 4) || - !require_size(array, size, 4) || !require_fortran(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DIM_TYPE) array_size(array,3); - $5 = (DATA_TYPE*) array_data(array); -} -%typemap(freearg) - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) -{ - if (is_new_object$argnum && array$argnum) - { Py_DECREF(array$argnum); } -} - -/***************************/ -/* In-Place Array Typemaps */ -/***************************/ - -/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE INPLACE_ARRAY1[ANY]) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE INPLACE_ARRAY1[ANY]) - (PyArrayObject* array=NULL) -{ - npy_intp size[1] = { $1_dim0 }; - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) || - !require_contiguous(array) || !require_native(array)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} - -/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) - (PyArrayObject* array=NULL, int i=1) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,1) || !require_contiguous(array) - || !require_native(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = 1; - for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i); -} - -/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) - (PyArrayObject* array=NULL, int i=0) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,1) || !require_contiguous(array) - || !require_native(array)) SWIG_fail; - $1 = 1; - for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i); - $2 = (DATA_TYPE*) array_data(array); -} - -/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) - (PyArrayObject* array=NULL) -{ - npy_intp size[2] = { $1_dim0, $1_dim1 }; - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) || - !require_contiguous(array) || !require_native(array)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} - -/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,2) || !require_contiguous(array) - || !require_native(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,2) || !require_contiguous(array) || - !require_native(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DATA_TYPE*) array_data(array); -} - -/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,2) || !require_contiguous(array) - || !require_native(array) || !require_fortran(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,2) || !require_contiguous(array) || - !require_native(array) || !require_fortran(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DATA_TYPE*) array_data(array); -} - -/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) - (PyArrayObject* array=NULL) -{ - npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 }; - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) || - !require_contiguous(array) || !require_native(array)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} - -/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,3) || !require_contiguous(array) || - !require_native(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); -} - -/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - $1 = PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL) -{ - npy_intp size[2] = { -1, -1 }; - PyArrayObject* temp_array; - Py_ssize_t i; - - /* length of the list */ - $2 = PyList_Size($input); - - /* the arrays */ - array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); - object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); - - if (array == NULL || object_array == NULL) - { - SWIG_fail; - } - - for (i=0; i<$2; i++) - { - temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE); - - /* the new array must be stored so that it can be destroyed in freearg */ - object_array[i] = temp_array; - - if ( !temp_array || !require_dimensions(temp_array, 2) || - !require_contiguous(temp_array) || - !require_native(temp_array) || - !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE) - ) SWIG_fail; - - /* store the size of the first array in the list, then use that for comparison. */ - if (i == 0) - { - size[0] = array_size(temp_array,0); - size[1] = array_size(temp_array,1); - } - - if (!require_size(temp_array, size, 2)) SWIG_fail; - - array[i] = (DATA_TYPE*) array_data(temp_array); - } - - $1 = (DATA_TYPE**) array; - $3 = (DIM_TYPE) size[0]; - $4 = (DIM_TYPE) size[1]; -} -%typemap(freearg) - (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - if (array$argnum!=NULL) free(array$argnum); - if (object_array$argnum!=NULL) free(object_array$argnum); -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, - * DATA_TYPE* INPLACE_ARRAY3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,3) || !require_contiguous(array) - || !require_native(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DATA_TYPE*) array_data(array); -} - -/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,3) || !require_contiguous(array) || - !require_native(array) || !require_fortran(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, - * DATA_TYPE* INPLACE_FARRAY3) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,3) || !require_contiguous(array) - || !require_native(array) || !require_fortran(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DATA_TYPE*) array_data(array); -} - -/* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) - (PyArrayObject* array=NULL) -{ - npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 }; - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) || - !require_contiguous(array) || !require_native(array)) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} - -/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3, DIM_TYPE DIM4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,4) || !require_contiguous(array) || - !require_native(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); - $5 = (DIM_TYPE) array_size(array,3); -} - -/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3, DIM_TYPE DIM4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - $1 = PySequence_Check($input); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL) -{ - npy_intp size[3] = { -1, -1, -1 }; - PyArrayObject* temp_array; - Py_ssize_t i; - - /* length of the list */ - $2 = PyList_Size($input); - - /* the arrays */ - array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); - object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); - - if (array == NULL || object_array == NULL) - { - SWIG_fail; - } - - for (i=0; i<$2; i++) - { - temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE); - - /* the new array must be stored so that it can be destroyed in freearg */ - object_array[i] = temp_array; - - if ( !temp_array || !require_dimensions(temp_array, 3) || - !require_contiguous(temp_array) || - !require_native(temp_array) || - !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE) - ) SWIG_fail; - - /* store the size of the first array in the list, then use that for comparison. */ - if (i == 0) - { - size[0] = array_size(temp_array,0); - size[1] = array_size(temp_array,1); - size[2] = array_size(temp_array,2); - } - - if (!require_size(temp_array, size, 3)) SWIG_fail; - - array[i] = (DATA_TYPE*) array_data(temp_array); - } - - $1 = (DATA_TYPE**) array; - $3 = (DIM_TYPE) size[0]; - $4 = (DIM_TYPE) size[1]; - $5 = (DIM_TYPE) size[2]; -} -%typemap(freearg) - (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - if (array$argnum!=NULL) free(array$argnum); - if (object_array$argnum!=NULL) free(object_array$argnum); -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, - * DATA_TYPE* INPLACE_ARRAY4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,4) || !require_contiguous(array) - || !require_native(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DIM_TYPE) array_size(array,3); - $5 = (DATA_TYPE*) array_data(array); -} - -/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, - * DIM_TYPE DIM3, DIM_TYPE DIM4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,4) || !require_contiguous(array) || - !require_native(array) || !require_fortran(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = (DIM_TYPE) array_size(array,0); - $3 = (DIM_TYPE) array_size(array,1); - $4 = (DIM_TYPE) array_size(array,2); - $5 = (DIM_TYPE) array_size(array,3); -} - -/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, - * DATA_TYPE* INPLACE_FARRAY4) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) - (PyArrayObject* array=NULL) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_dimensions(array,4) || !require_contiguous(array) - || !require_native(array) || !require_fortran(array)) SWIG_fail; - $1 = (DIM_TYPE) array_size(array,0); - $2 = (DIM_TYPE) array_size(array,1); - $3 = (DIM_TYPE) array_size(array,2); - $4 = (DIM_TYPE) array_size(array,3); - $5 = (DATA_TYPE*) array_data(array); -} - -/*************************/ -/* Argout Array Typemaps */ -/*************************/ - -/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY]) - */ -%typemap(in,numinputs=0, - fragment="NumPy_Backward_Compatibility,NumPy_Macros") - (DATA_TYPE ARGOUT_ARRAY1[ANY]) - (PyObject* array = NULL) -{ - npy_intp dims[1] = { $1_dim0 }; - array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); - if (!array) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(argout) - (DATA_TYPE ARGOUT_ARRAY1[ANY]) -{ - $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); -} - -/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) - */ -%typemap(in,numinputs=1, - fragment="NumPy_Fragments") - (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) - (PyObject* array = NULL) -{ - npy_intp dims[1]; - if (!PyInt_Check($input)) - { - const char* typestring = pytype_string($input); - PyErr_Format(PyExc_TypeError, - "Int dimension expected. '%s' given.", - typestring); - SWIG_fail; - } - $2 = (DIM_TYPE) PyInt_AsLong($input); - dims[0] = (npy_intp) $2; - array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); - if (!array) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); -} -%typemap(argout) - (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) -{ - $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); -} - -/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) - */ -%typemap(in,numinputs=1, - fragment="NumPy_Fragments") - (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) - (PyObject* array = NULL) -{ - npy_intp dims[1]; - if (!PyInt_Check($input)) - { - const char* typestring = pytype_string($input); - PyErr_Format(PyExc_TypeError, - "Int dimension expected. '%s' given.", - typestring); - SWIG_fail; - } - $1 = (DIM_TYPE) PyInt_AsLong($input); - dims[0] = (npy_intp) $1; - array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); - if (!array) SWIG_fail; - $2 = (DATA_TYPE*) array_data(array); -} -%typemap(argout) - (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) -{ - $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); -} - -/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) - */ -%typemap(in,numinputs=0, - fragment="NumPy_Backward_Compatibility,NumPy_Macros") - (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) - (PyObject* array = NULL) -{ - npy_intp dims[2] = { $1_dim0, $1_dim1 }; - array = PyArray_SimpleNew(2, dims, DATA_TYPECODE); - if (!array) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(argout) - (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) -{ - $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); -} - -/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) - */ -%typemap(in,numinputs=0, - fragment="NumPy_Backward_Compatibility,NumPy_Macros") - (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) - (PyObject* array = NULL) -{ - npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 }; - array = PyArray_SimpleNew(3, dims, DATA_TYPECODE); - if (!array) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(argout) - (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) -{ - $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); -} - -/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) - */ -%typemap(in,numinputs=0, - fragment="NumPy_Backward_Compatibility,NumPy_Macros") - (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) - (PyObject* array = NULL) -{ - npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 }; - array = PyArray_SimpleNew(4, dims, DATA_TYPECODE); - if (!array) SWIG_fail; - $1 = ($1_ltype) array_data(array); -} -%typemap(argout) - (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) -{ - $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); -} - -/*****************************/ -/* Argoutview Array Typemaps */ -/*****************************/ - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp) -{ - $1 = &data_temp; - $2 = &dim_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) -{ - npy_intp dims[1] = { *$2 }; - PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEW_ARRAY1) - (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim_temp; - $2 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) -{ - npy_intp dims[1] = { *$1 }; - PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) -{ - npy_intp dims[2] = { *$2, *$3 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_ARRAY2) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) -{ - npy_intp dims[2] = { *$1, *$2 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") - (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) -{ - npy_intp dims[2] = { *$2, *$3 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) -{ - npy_intp dims[2] = { *$1, *$2 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) -{ - npy_intp dims[3] = { *$2, *$3, *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, - DATA_TYPE** ARGOUTVIEW_ARRAY3) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) -{ - npy_intp dims[3] = { *$1, *$2, *$3 }; - PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") - (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) -{ - npy_intp dims[3] = { *$2, *$3, *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, - DATA_TYPE** ARGOUTVIEW_FARRAY3) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEW_FARRAY3) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) -{ - npy_intp dims[3] = { *$1, *$2, *$3 }; - PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3, DIM_TYPE* DIM4) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; - $5 = &dim4_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) -{ - npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, - DATA_TYPE** ARGOUTVIEW_ARRAY4) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_ARRAY4) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &dim4_temp; - $5 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4) -{ - npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3, DIM_TYPE* DIM4) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; - $5 = &dim4_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") - (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) -{ - npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, - DATA_TYPE** ARGOUTVIEW_FARRAY4) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_FARRAY4) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &dim4_temp; - $5 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4) -{ - npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - $result = SWIG_Python_AppendOutput($result,obj); -} - -/*************************************/ -/* Managed Argoutview Array Typemaps */ -/*************************************/ - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp) -{ - $1 = &data_temp; - $2 = &dim_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) -{ - npy_intp dims[1] = { *$2 }; - PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEWM_ARRAY1) - (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim_temp; - $2 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) -{ - npy_intp dims[1] = { *$1 }; - PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) -{ - npy_intp dims[2] = { *$2, *$3 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_ARRAY2) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) -{ - npy_intp dims[2] = { *$1, *$2 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) -{ - npy_intp dims[2] = { *$2, *$3 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_FARRAY2) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) -{ - npy_intp dims[2] = { *$1, *$2 }; - PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) -{ - npy_intp dims[3] = { *$2, *$3, *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, - DATA_TYPE** ARGOUTVIEWM_ARRAY3) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_ARRAY3) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3) -{ - npy_intp dims[3] = { *$1, *$2, *$3 }; - PyObject* obj= PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) -{ - npy_intp dims[3] = { *$2, *$3, *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, - DATA_TYPE** ARGOUTVIEWM_FARRAY3) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_FARRAY3) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3) -{ - npy_intp dims[3] = { *$1, *$2, *$3 }; - PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3, DIM_TYPE* DIM4) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; - $5 = &dim4_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) -{ - npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, - DATA_TYPE** ARGOUTVIEWM_ARRAY4) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &dim4_temp; - $5 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) -{ - npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3, DIM_TYPE* DIM4) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; - $5 = &dim4_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) -{ - npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, - DATA_TYPE** ARGOUTVIEWM_FARRAY4) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &dim4_temp; - $5 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) -{ - npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3, DIM_TYPE* DIM4) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; - $5 = &dim4_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) -{ - npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, - DATA_TYPE** ARGOUTVIEWM_ARRAY4) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &dim4_temp; - $5 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) -{ - npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, - DIM_TYPE* DIM3, DIM_TYPE* DIM4) - */ -%typemap(in,numinputs=0) - (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) - (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) -{ - $1 = &data_temp; - $2 = &dim1_temp; - $3 = &dim2_temp; - $4 = &dim3_temp; - $5 = &dim4_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) -{ - npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, - DATA_TYPE** ARGOUTVIEWM_FARRAY4) - */ -%typemap(in,numinputs=0) - (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4) - (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) -{ - $1 = &dim1_temp; - $2 = &dim2_temp; - $3 = &dim3_temp; - $4 = &dim4_temp; - $5 = &data_temp; -} -%typemap(argout, - fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") - (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) -{ - npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; - PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); - PyArrayObject* array = (PyArrayObject*) obj; - - if (!array || !require_fortran(array)) SWIG_fail; - -%#ifdef SWIGPY_USE_CAPSULE - PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); -%#else - PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); -%#endif - -%#if NPY_API_VERSION < 0x00000007 - PyArray_BASE(array) = cap; -%#else - PyArray_SetBaseObject(array,cap); -%#endif - - $result = SWIG_Python_AppendOutput($result,obj); -} - -/**************************************/ -/* In-Place Array Typemap - flattened */ -/**************************************/ - -/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) - */ -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, - fragment="NumPy_Macros") - (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) -{ - $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), - DATA_TYPECODE); -} -%typemap(in, - fragment="NumPy_Fragments") - (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) - (PyArrayObject* array=NULL, int i=1) -{ - array = obj_to_array_no_conversion($input, DATA_TYPECODE); - if (!array || !require_c_or_f_contiguous(array) - || !require_native(array)) SWIG_fail; - $1 = (DATA_TYPE*) array_data(array); - $2 = 1; - for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i); -} - -%enddef /* %numpy_typemaps() macro */ -/* *************************************************************** */ - -/* Concrete instances of the %numpy_typemaps() macro: Each invocation - * below applies all of the typemaps above to the specified data type. - */ -%numpy_typemaps(signed char , NPY_BYTE , int) -%numpy_typemaps(unsigned char , NPY_UBYTE , int) -%numpy_typemaps(short , NPY_SHORT , int) -%numpy_typemaps(unsigned short , NPY_USHORT , int) -%numpy_typemaps(int , NPY_INT , int) -%numpy_typemaps(unsigned int , NPY_UINT , int) -%numpy_typemaps(long , NPY_LONG , int) -%numpy_typemaps(unsigned long , NPY_ULONG , int) -%numpy_typemaps(long long , NPY_LONGLONG , int) -%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int) -%numpy_typemaps(float , NPY_FLOAT , int) -%numpy_typemaps(double , NPY_DOUBLE , int) -%numpy_typemaps(int8_t , NPY_INT8 , int) -%numpy_typemaps(int16_t , NPY_INT16 , int) -%numpy_typemaps(int32_t , NPY_INT32 , int) -%numpy_typemaps(int64_t , NPY_INT64 , int) -%numpy_typemaps(uint8_t , NPY_UINT8 , int) -%numpy_typemaps(uint16_t , NPY_UINT16 , int) -%numpy_typemaps(uint32_t , NPY_UINT32 , int) -%numpy_typemaps(uint64_t , NPY_UINT64 , int) - - -/* *************************************************************** - * The follow macro expansion does not work, because C++ bool is 4 - * bytes and NPY_BOOL is 1 byte - * - * %numpy_typemaps(bool, NPY_BOOL, int) - */ - -/* *************************************************************** - * On my Mac, I get the following warning for this macro expansion: - * 'swig/python detected a memory leak of type 'long double *', no destructor found.' - * - * %numpy_typemaps(long double, NPY_LONGDOUBLE, int) - */ - -#ifdef __cplusplus - -%include - -%numpy_typemaps(std::complex, NPY_CFLOAT , int) -%numpy_typemaps(std::complex, NPY_CDOUBLE, int) - -#endif - -#endif /* SWIGPYTHON */ diff --git a/tools/swig/pressio.i b/tools/swig/pressio.i index b384686f..2c0df6f6 100644 --- a/tools/swig/pressio.i +++ b/tools/swig/pressio.i @@ -29,12 +29,6 @@ python bindings for pressio %} %include -#if SWIGPYTHON -%include "numpy.i" -%init %{ -import_array(); -%} -#endif %include "pressio_version.h" @@ -66,75 +60,17 @@ import_array(); #if LIBPRESSIO_HAS_MPI4PY %include "mpi4py/mpi4py.i" %mpi4py_typemap(Comm, MPI_Comm) +%newobject options_new_comm; #endif #endif %include "pypressio.h" -#if SWIGPYTHON -%numpy_typemaps(bool , NPY_BOOL , size_t) -%numpy_typemaps(signed char , NPY_BYTE , size_t) -%numpy_typemaps(unsigned char , NPY_UBYTE , size_t) -%numpy_typemaps(short , NPY_SHORT , size_t) -%numpy_typemaps(unsigned short , NPY_USHORT , size_t) -%numpy_typemaps(int , NPY_INT , size_t) -%numpy_typemaps(unsigned int , NPY_UINT , size_t) -%numpy_typemaps(long , NPY_LONG , size_t) -%numpy_typemaps(unsigned long , NPY_ULONG , size_t) -%numpy_typemaps(long long , NPY_LONGLONG , size_t) -%numpy_typemaps(unsigned long long, NPY_ULONGLONG, size_t) -%numpy_typemaps(float , NPY_FLOAT , size_t) -%numpy_typemaps(double , NPY_DOUBLE , size_t) -%numpy_typemaps(std::int8_t , NPY_INT8 , size_t) -%numpy_typemaps(std::int16_t , NPY_INT16 , size_t) -%numpy_typemaps(std::int32_t , NPY_INT32 , size_t) -%numpy_typemaps(std::int64_t , NPY_INT64 , size_t) -%numpy_typemaps(std::uint8_t , NPY_UINT8 , size_t) -%numpy_typemaps(std::uint16_t , NPY_UINT16 , size_t) -%numpy_typemaps(std::uint32_t , NPY_UINT32 , size_t) -%numpy_typemaps(std::uint64_t , NPY_UINT64 , size_t) -%numpy_typemaps(bool , NPY_BOOL , long int) -%numpy_typemaps(float , NPY_FLOAT , long int) -%numpy_typemaps(double , NPY_DOUBLE , long int) -%numpy_typemaps(int8_t , NPY_INT8 , long int) -%numpy_typemaps(int16_t , NPY_INT16 , long int) -%numpy_typemaps(int32_t , NPY_INT32 , long int) -%numpy_typemaps(int64_t , NPY_INT64 , long int) -%numpy_typemaps(uint8_t , NPY_UINT8 , long int) -%numpy_typemaps(uint16_t , NPY_UINT16 , long int) -%numpy_typemaps(uint32_t , NPY_UINT32 , long int) -%numpy_typemaps(uint64_t , NPY_UINT64 , long int) -%numpy_typemaps(signed char , NPY_BYTE , long int) -%numpy_typemaps(unsigned char , NPY_UBYTE , long int) -%numpy_typemaps(short , NPY_SHORT , long int) -%numpy_typemaps(unsigned short , NPY_USHORT , long int) -%numpy_typemaps(int , NPY_INT , long int) -%numpy_typemaps(unsigned int , NPY_UINT , long int) -%numpy_typemaps(long , NPY_LONG , long int) -%numpy_typemaps(unsigned long , NPY_ULONG , long int) -%numpy_typemaps(long long , NPY_LONGLONG , long int) -%numpy_typemaps(unsigned long long, NPY_ULONGLONG, long int) %define pressio_numpy_type(type, name) - %apply (type* INPLACE_ARRAY1, size_t DIM1 ) {( type * data, size_t r1)}; - %apply (type* INPLACE_ARRAY2, size_t DIM1, size_t DIM2 ) { ( type * data, size_t r1, size_t r2)}; - %apply (type* INPLACE_ARRAY3, size_t DIM1, size_t DIM2, size_t DIM3 ) {( type* data, size_t r1, size_t r2, size_t r3)}; - %apply (type* INPLACE_ARRAY4, size_t DIM1, size_t DIM2, size_t DIM3, size_t DIM4 ) {( type* data, size_t r1, size_t r2, size_t r3, size_t r4)}; - %apply (type** ARGOUTVIEWM_ARRAY1, long int* DIM1) {( type** ptr_argout, long int* r1)}; - %apply (type** ARGOUTVIEWM_ARRAY2, long int* DIM1, long int* DIM2) {( type** ptr_argout, long int* r1, long int* r2)}; - %apply (type** ARGOUTVIEWM_ARRAY3, long int* DIM1, long int* DIM2, long int* DIM3) {( type** ptr_argout, long int* r1, long int* r2, long int* r3)}; - %apply (type** ARGOUTVIEWM_ARRAY4, long int* DIM1, long int* DIM2, long int* DIM3, long int* DIM4) {( type** ptr_argout, long int* r1, long int* r2, long int* r3, long int* r4)}; namespace std { %template( vector_ ## name ) vector< type >; } - %template( _pressio_io_data_to_numpy_1d_ ## name ) _pressio_io_data_to_numpy_1d< type >; - %template( _pressio_io_data_to_numpy_2d_ ## name ) _pressio_io_data_to_numpy_2d< type >; - %template( _pressio_io_data_to_numpy_3d_ ## name ) _pressio_io_data_to_numpy_3d< type >; - %template( _pressio_io_data_to_numpy_4d_ ## name ) _pressio_io_data_to_numpy_4d< type >; - %template( _pressio_io_data_from_numpy_1d_ ## name ) _pressio_io_data_from_numpy_1d< type >; - %template( _pressio_io_data_from_numpy_2d_ ## name ) _pressio_io_data_from_numpy_2d< type >; - %template( _pressio_io_data_from_numpy_3d_ ## name ) _pressio_io_data_from_numpy_3d< type >; - %template( _pressio_io_data_from_numpy_4d_ ## name ) _pressio_io_data_from_numpy_4d< type >; %enddef pressio_numpy_type(bool, bool); pressio_numpy_type(float, float); @@ -147,7 +83,6 @@ pressio_numpy_type(signed char, int8_t); pressio_numpy_type(short, int16_t); pressio_numpy_type(int, int32_t); pressio_numpy_type(long int, int64_t); -#endif namespace std { %template() vector; @@ -157,199 +92,221 @@ namespace std { %rename("%(strip:[pressio_])s") ""; -%pythoncode %{ -import numpy - -__pressio_to_np_dtype = { - _pressio.float_dtype : numpy.float32, - _pressio.double_dtype : numpy.double, - _pressio.uint8_dtype : numpy.uint8, - _pressio.int8_dtype : numpy.int8, - _pressio.uint16_dtype : numpy.uint16, - _pressio.int16_dtype : numpy.int16, - _pressio.uint32_dtype : numpy.uint32, - _pressio.int32_dtype : numpy.int32, - _pressio.uint64_dtype : numpy.uint64, - _pressio.int64_dtype : numpy.int64, - _pressio.bool_dtype : bool, -} - -__pressio_to_lp_dtype = { - numpy.float32: _pressio.float_dtype, - numpy.double: _pressio.double_dtype, - numpy.uint8: _pressio.uint8_dtype, - numpy.int8: _pressio.int8_dtype, - numpy.uint16: _pressio.uint16_dtype, - numpy.int16: _pressio.int16_dtype, - numpy.uint32: _pressio.uint32_dtype, - numpy.int32: _pressio.int32_dtype, - numpy.uint64: _pressio.uint64_dtype, - numpy.int64: _pressio.int64_dtype, - bool: _pressio.bool_dtype, -} - -def _pressio_io_data_from_numpy_0d(array): - dat = data_new_empty(__pressio_to_lp_dtype[array.dtype], vector_uint64_t([])) - return dat -def _pressio_io_data_to_numpy_0d(array): - dat = numpy.ndarray([], __pressio_to_np_dtype[data_dtype(array)]) - return dat - -__pressio_from_numpy = { - (0, numpy.dtype('bool')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('bool')): _pressio_io_data_from_numpy_1d_bool, - (2, numpy.dtype('bool')): _pressio_io_data_from_numpy_2d_bool, - (3, numpy.dtype('bool')): _pressio_io_data_from_numpy_3d_bool, - (4, numpy.dtype('bool')): _pressio_io_data_from_numpy_4d_bool, - (0, numpy.dtype('float32')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('float32')): _pressio_io_data_from_numpy_1d_float, - (2, numpy.dtype('float32')): _pressio_io_data_from_numpy_2d_float, - (3, numpy.dtype('float32')): _pressio_io_data_from_numpy_3d_float, - (4, numpy.dtype('float32')): _pressio_io_data_from_numpy_4d_float, - (0, numpy.dtype('float64')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('float64')): _pressio_io_data_from_numpy_1d_double, - (2, numpy.dtype('float64')): _pressio_io_data_from_numpy_2d_double, - (3, numpy.dtype('float64')): _pressio_io_data_from_numpy_3d_double, - (4, numpy.dtype('float64')): _pressio_io_data_from_numpy_4d_double, - (0, numpy.dtype('uint8')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('uint8')): _pressio_io_data_from_numpy_1d_uint8_t, - (2, numpy.dtype('uint8')): _pressio_io_data_from_numpy_2d_uint8_t, - (3, numpy.dtype('uint8')): _pressio_io_data_from_numpy_3d_uint8_t, - (4, numpy.dtype('uint8')): _pressio_io_data_from_numpy_4d_uint8_t, - (0, numpy.dtype('int8')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('int8')): _pressio_io_data_from_numpy_1d_int8_t, - (2, numpy.dtype('int8')): _pressio_io_data_from_numpy_2d_int8_t, - (3, numpy.dtype('int8')): _pressio_io_data_from_numpy_3d_int8_t, - (4, numpy.dtype('int8')): _pressio_io_data_from_numpy_4d_int8_t, - (0, numpy.dtype('uint16')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('uint16')): _pressio_io_data_from_numpy_1d_uint16_t, - (2, numpy.dtype('uint16')): _pressio_io_data_from_numpy_2d_uint16_t, - (3, numpy.dtype('uint16')): _pressio_io_data_from_numpy_3d_uint16_t, - (4, numpy.dtype('uint16')): _pressio_io_data_from_numpy_4d_uint16_t, - (0, numpy.dtype('int16')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('int16')): _pressio_io_data_from_numpy_1d_int16_t, - (2, numpy.dtype('int16')): _pressio_io_data_from_numpy_2d_int16_t, - (3, numpy.dtype('int16')): _pressio_io_data_from_numpy_3d_int16_t, - (4, numpy.dtype('int16')): _pressio_io_data_from_numpy_4d_int16_t, - (0, numpy.dtype('uint32')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('uint32')): _pressio_io_data_from_numpy_1d_uint32_t, - (2, numpy.dtype('uint32')): _pressio_io_data_from_numpy_2d_uint32_t, - (3, numpy.dtype('uint32')): _pressio_io_data_from_numpy_3d_uint32_t, - (4, numpy.dtype('uint32')): _pressio_io_data_from_numpy_4d_uint32_t, - (0, numpy.dtype('int32')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('int32')): _pressio_io_data_from_numpy_1d_int32_t, - (2, numpy.dtype('int32')): _pressio_io_data_from_numpy_2d_int32_t, - (3, numpy.dtype('int32')): _pressio_io_data_from_numpy_3d_int32_t, - (4, numpy.dtype('int32')): _pressio_io_data_from_numpy_4d_int32_t, - (0, numpy.dtype('uint64')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('uint64')): _pressio_io_data_from_numpy_1d_uint64_t, - (2, numpy.dtype('uint64')): _pressio_io_data_from_numpy_2d_uint64_t, - (3, numpy.dtype('uint64')): _pressio_io_data_from_numpy_3d_uint64_t, - (4, numpy.dtype('uint64')): _pressio_io_data_from_numpy_4d_uint64_t, - (0, numpy.dtype('int64')): _pressio_io_data_from_numpy_0d, - (1, numpy.dtype('int64')): _pressio_io_data_from_numpy_1d_int64_t, - (2, numpy.dtype('int64')): _pressio_io_data_from_numpy_2d_int64_t, - (3, numpy.dtype('int64')): _pressio_io_data_from_numpy_3d_int64_t, - (4, numpy.dtype('int64')): _pressio_io_data_from_numpy_4d_int64_t, -} -__pressio_to_numpy = { - (0, _pressio.float_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.float_dtype) : _pressio_io_data_to_numpy_1d_float, - (2, _pressio.float_dtype) : _pressio_io_data_to_numpy_2d_float, - (3, _pressio.float_dtype) : _pressio_io_data_to_numpy_3d_float, - (4, _pressio.float_dtype) : _pressio_io_data_to_numpy_4d_float, - (0, _pressio.double_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.double_dtype) : _pressio_io_data_to_numpy_1d_double, - (2, _pressio.double_dtype) : _pressio_io_data_to_numpy_2d_double, - (3, _pressio.double_dtype) : _pressio_io_data_to_numpy_3d_double, - (4, _pressio.double_dtype) : _pressio_io_data_to_numpy_4d_double, - (0, _pressio.int8_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.int8_dtype) : _pressio_io_data_to_numpy_1d_int8_t, - (2, _pressio.int8_dtype) : _pressio_io_data_to_numpy_2d_int8_t, - (3, _pressio.int8_dtype) : _pressio_io_data_to_numpy_3d_int8_t, - (4, _pressio.int8_dtype) : _pressio_io_data_to_numpy_4d_int8_t, - (0, _pressio.int16_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.int16_dtype) : _pressio_io_data_to_numpy_1d_int16_t, - (2, _pressio.int16_dtype) : _pressio_io_data_to_numpy_2d_int16_t, - (3, _pressio.int16_dtype) : _pressio_io_data_to_numpy_3d_int16_t, - (4, _pressio.int16_dtype) : _pressio_io_data_to_numpy_4d_int16_t, - (0, _pressio.int32_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.int32_dtype) : _pressio_io_data_to_numpy_1d_int32_t, - (2, _pressio.int32_dtype) : _pressio_io_data_to_numpy_2d_int32_t, - (3, _pressio.int32_dtype) : _pressio_io_data_to_numpy_3d_int32_t, - (4, _pressio.int32_dtype) : _pressio_io_data_to_numpy_4d_int32_t, - (0, _pressio.int64_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.int64_dtype) : _pressio_io_data_to_numpy_1d_int64_t, - (2, _pressio.int64_dtype) : _pressio_io_data_to_numpy_2d_int64_t, - (3, _pressio.int64_dtype) : _pressio_io_data_to_numpy_3d_int64_t, - (4, _pressio.int64_dtype) : _pressio_io_data_to_numpy_4d_int64_t, - (0, _pressio.byte_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.byte_dtype) : _pressio_io_data_to_numpy_1d_uint8_t, - (2, _pressio.byte_dtype) : _pressio_io_data_to_numpy_2d_uint8_t, - (3, _pressio.byte_dtype) : _pressio_io_data_to_numpy_3d_uint8_t, - (4, _pressio.byte_dtype) : _pressio_io_data_to_numpy_4d_uint8_t, - (0, _pressio.uint8_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.uint8_dtype) : _pressio_io_data_to_numpy_1d_uint8_t, - (2, _pressio.uint8_dtype) : _pressio_io_data_to_numpy_2d_uint8_t, - (3, _pressio.uint8_dtype) : _pressio_io_data_to_numpy_3d_uint8_t, - (4, _pressio.uint8_dtype) : _pressio_io_data_to_numpy_4d_uint8_t, - (0, _pressio.uint16_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.uint16_dtype) : _pressio_io_data_to_numpy_1d_uint16_t, - (2, _pressio.uint16_dtype) : _pressio_io_data_to_numpy_2d_uint16_t, - (3, _pressio.uint16_dtype) : _pressio_io_data_to_numpy_3d_uint16_t, - (4, _pressio.uint16_dtype) : _pressio_io_data_to_numpy_4d_uint16_t, - (0, _pressio.uint32_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.uint32_dtype) : _pressio_io_data_to_numpy_1d_uint32_t, - (2, _pressio.uint32_dtype) : _pressio_io_data_to_numpy_2d_uint32_t, - (3, _pressio.uint32_dtype) : _pressio_io_data_to_numpy_3d_uint32_t, - (4, _pressio.uint32_dtype) : _pressio_io_data_to_numpy_4d_uint32_t, - (0, _pressio.uint64_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.uint64_dtype) : _pressio_io_data_to_numpy_1d_uint64_t, - (2, _pressio.uint64_dtype) : _pressio_io_data_to_numpy_2d_uint64_t, - (3, _pressio.uint64_dtype) : _pressio_io_data_to_numpy_3d_uint64_t, - (4, _pressio.uint64_dtype) : _pressio_io_data_to_numpy_4d_uint64_t, - (0, _pressio.bool_dtype) : _pressio_io_data_to_numpy_0d, - (1, _pressio.bool_dtype) : _pressio_io_data_to_numpy_1d_bool, - (2, _pressio.bool_dtype) : _pressio_io_data_to_numpy_2d_bool, - (3, _pressio.bool_dtype) : _pressio_io_data_to_numpy_3d_bool, - (4, _pressio.bool_dtype) : _pressio_io_data_to_numpy_4d_bool, -} - - -def io_data_from_numpy(array): - length = len(array.shape) - dtype = array.dtype - return __pressio_from_numpy[length, dtype](array) - -def io_data_to_numpy(ptr): - num_dims = data_num_dimensions(ptr) - dtype = data_dtype(ptr) - return __pressio_to_numpy[num_dims, dtype](ptr) - -%} +%ignore pressio_new_metrics; +%newobject pressio_get_compressor; +%newobject pressio_new_metric; +%delobject pressio_release; +//defined in pypressio.h instead +%newobject new_metrics; %include "pressio.h" +%newobject pressio_compressor_get_documentation; +%newobject pressio_compressor_get_configuration; +%newobject pressio_compressor_get_options; +%newobject pressio_compressor_get_metrics_results; +%newobject pressio_compressor_get_metrics; +%newobject pressio_compressor_clone; +%delobject pressio_compressor_release; %include "pressio_compressor.h" +//prefer the versions using std::vector from pypressio.h %ignore pressio_data_new_nonowning; %ignore pressio_data_new_owning; %ignore pressio_data_new_move; %ignore pressio_data_new_copy; %ignore pressio_data_new_empty; +//these are defined in pypressio.h +%newobject data_new_copy; +%newobject data_new_nowning; +%newobject data_new_empty; +%newobject data_new_move; + + +%delobject pressio_data_free; %include "pressio_data.h" %include "pressio_dtype.h" +%newobject pressio_metrics_get_results; +%newobject pressio_metrics_get_options; +%newobject pressio_metrics_get_documentation; +%newobject pressio_metrics_get_configuration; +%newobject pressio_metrics_clone; +%newobject pressio_metrics_evaluate; +%delobject pressio_metrics_free; %include "pressio_metrics.h" %ignore pressio_option_new_strings; +%ignore pressio_option_get_strings; +%newobject pressio_option_new_integer8; +%newobject pressio_option_new_integer16; +%newobject pressio_option_new_integer; +%newobject pressio_option_new_integer64; +%newobject pressio_option_new_uinteger8; +%newobject pressio_option_new_uinteger16; +%newobject pressio_option_new_uinteger; +%newobject pressio_option_new_uinteger64; +%newobject pressio_option_new_float; +%newobject pressio_option_new_double; +%newobject pressio_option_new_bool; +%newobject pressio_option_new_dtype; +%newobject pressio_option_new_threadsafety; +%newobject pressio_option_new_data; +%newobject pressio_option_new_userptr; +%newobject pressio_option_new_userptr_managed; +%newobject pressio_option_new; +%newobject pressio_option_get_data; +// these are defined in pypressio.h +%newobject option_new_string; +%newobject option_new_strings; +%delobject pressio_option_free; %include "pressio_option.h" +%newobject pressio_options_get_iter; +%newobject pressio_options_new; +%delobject pressio_options_free; + %include "pressio_options.h" +%newobject pressio_options_iter_get_value; +%delobject pressio_options_iter_free; %include "pressio_options_iter.h" +%newobject pressio_get_io; +%newobject pressio_io_get_configuration; +%newobject pressio_io_get_documentation; +%newobject pressio_io_get_options; +%newobject pressio_io_read; +%newobject pressio_io_clone; +%delobject pressio_io_free; %include "libpressio_ext/io/pressio_io.h" +%newobject pressio_io_data_fread; +%newobject pressio_io_data_read; +%newobject pressio_io_data_path_read; %include "libpressio_ext/io/posix.h" + #if LIBPRESSIO_HAS_JSON +%newobject pressio_options_new_json; %newobject pressio_options_to_json; %include "libpressio_ext/json/pressio_options_json.h" #endif #if LIBPRESSIO_HAS_OPENSSL +%newobject pressio_options_hashkeys; +%newobject pressio_options_hashentries; %include "libpressio_ext/hash/libpressio_hash.h" #endif +%newobject pressio_highlevel_get_compressor; +%newobject pressio_highlevel_get_io; %include "libpressio_ext/highlevel/libpressio_highlevel.h" + +%include "dlpack/dlpack.h" + +%pythoncode %{ + import numpy as _np + + _dtype_map = { + "f4": float_dtype, + "f8": double_dtype, + "i1": int8_dtype, + "i2": int16_dtype, + "i4": int32_dtype, + "i8": int64_dtype, + "u1": uint8_dtype, + "u2": uint16_dtype, + "u4": uint32_dtype, + "u8": uint64_dtype, + "b1": bool_dtype, + } + _reverse_dtype_map = { + float_dtype: _np.dtype("= (DLPACK_MAJOR_VERSION, DLPACK_MINOR_VERSION): + # Consumer understands us, just return a Capsule with our max version + return data_to_dlpack_versioned(self.ptr, max_version_swig, dl_device_swig, copy_swig) + elif max_version[0] == DLPACK_MAJOR_VERSION: + # major versions match, we should still be fine here - + # return our own max version + return data_to_dlpack_versioned(self.ptr, max_version_swig, dl_device_swig, copy_swig) + else: + # if we're at a higher major version internally, did we + # keep an implementation of the older major version around? + # For example, if the producer is on DLPack 1.x and the consumer + # is 0.y, can the producer still export a capsule containing + # DLManagedTensor and not DLManagedTensorVersioned? + # If so, use that. Else, the producer should raise a BufferError + # here to tell users that the consumer's max_version is too + # old to allow the data exchange to happen. + return data_to_dlpack_managed(self.ptr) +%} diff --git a/tools/swig/pressio_sz.i b/tools/swig/pressio_sz.i deleted file mode 100644 index f0a8200f..00000000 --- a/tools/swig/pressio_sz.i +++ /dev/null @@ -1,15 +0,0 @@ -/* -python bindings for pressio sz extensions -*/ - -%module pressio_sz - -%{ -#define SWIG_FILE_WITH_INIT -#define SWIG_PYTHON_STRICT_BYTE_CHAR -#include -%} - -%rename("%(strip:[SZ_])s") ""; -%include - diff --git a/tools/swig/pressio_zfp.i b/tools/swig/pressio_zfp.i deleted file mode 100644 index 9fffb88b..00000000 --- a/tools/swig/pressio_zfp.i +++ /dev/null @@ -1,18 +0,0 @@ -/* -python bindings for pressio zfp extensions -*/ - -%module pressio_zfp - -%{ -#define SWIG_FILE_WITH_INIT -#define SWIG_PYTHON_STRICT_BYTE_CHAR -#include -%} - -%rename ("zfp_exec") exec; -%rename("%(strip:[ZFP_])s") ""; -%rename("%(strip:[zfp_])s") ""; -%include -%include -%include diff --git a/tools/swig/pypressio.cc b/tools/swig/pypressio.cc index 8b137891..2309d044 100644 --- a/tools/swig/pypressio.cc +++ b/tools/swig/pypressio.cc @@ -1 +1,241 @@ +#include "pypressio.h" +#include +namespace { +#if defined(_WIN32) +constexpr bool native_little_endian = true; +#else +constexpr bool native_little_endian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__; +#endif +} + +void options_set_comm(struct pressio_options* options, const char* key, MPI_Comm comm) { + MPI_Comm* c = new MPI_Comm(comm); + return pressio_options_set_userptr_managed(options, key, c, nullptr, newdelete_deleter(), newdelete_copy()); +} + +pressio_option* option_new_comm(MPI_Comm comm) { + MPI_Comm* c = new MPI_Comm(comm); + return pressio_option_new_userptr_managed(c, nullptr, newdelete_deleter(), newdelete_copy()); +} + +static std::string dtype_to_typestr(pressio_dtype t) { + static std::map const dtypes { + {pressio_float_dtype ,"f4"}, + {pressio_double_dtype,"f8"}, + {pressio_int8_dtype ,"i1"}, + {pressio_int16_dtype ,"i2"}, + {pressio_int32_dtype ,"i4"}, + {pressio_int64_dtype ,"i8"}, + {pressio_uint8_dtype ,"u1"}, + {pressio_uint16_dtype,"u2"}, + {pressio_uint32_dtype,"u4"}, + {pressio_uint64_dtype,"u8"}, + {pressio_bool_dtype ,"b1"}, + {pressio_byte_dtype ,"i1"}, + }; + return ((t == pressio_byte_dtype) + ? "|" + : (native_little_endian ? "<" : ">")) + + dtypes.at(t); +} + +static pressio_dtype dtype_from_typestr(std::string const& typestr) { + static std::map const dtypes { + {"f4", pressio_float_dtype}, + {"f8", pressio_double_dtype}, + {"i1", pressio_int8_dtype}, + {"i2", pressio_int16_dtype}, + {"i4", pressio_int32_dtype}, + {"i8", pressio_int64_dtype}, + {"u1", pressio_uint8_dtype}, + {"u2", pressio_uint16_dtype}, + {"u4", pressio_uint32_dtype}, + {"u8", pressio_uint64_dtype}, + {"b1", pressio_bool_dtype}, + {"i1" ,pressio_byte_dtype}, + }; + pressio_dtype dtype = pressio_byte_dtype; + if(typestr.size() == 3) { + auto endian = typestr[0]; + if (native_little_endian) { + if(endian == '>') { + throw std::runtime_error("cross endian data not supported"); + } + } + dtype = dtypes.at(typestr.substr(1)); + } + return dtype; +} + +numpy_array_interface data_to_array_interface(pressio_data* data) { + numpy_array_interface i; + i.shape = data->dimensions(); + std::reverse(i.shape.begin(), i.shape.end()); + i.typestr = dtype_to_typestr(data->dtype()); + i.read_only = false; + i.ptr = reinterpret_cast(data->data()); + i.version = 3; + return i; +} + + +DLDevice data_to_dlpack_device(pressio_data* data) { + DLDevice d; + auto domain = data->domain(); + + if(domain->domain_id() == "malloc") { + d.device_type = kDLCPU; + d.device_id = 0; + } else if (domain->domain_id() == "cudamalloc") { + d.device_type = kDLCUDA; + d.device_id = 0; // TODO support multiple devices + } else if (domain->domain_id() == "cudamallochost") { + d.device_type = kDLCUDAHost; + d.device_id = 0; // TODO support multiple devices + } + return d; +} + +static DLDataType to_dlpack_dtype(pressio_dtype p) { + DLDataType d; + d.bits = pressio_dtype_size(p)*8; + switch (p) { + case pressio_float_dtype: + case pressio_double_dtype: + d.code = kDLFloat; + break; + case pressio_int8_dtype: + case pressio_int16_dtype: + case pressio_int32_dtype: + case pressio_int64_dtype: + d.code = kDLInt; + break; + case pressio_byte_dtype: + case pressio_uint8_dtype: + case pressio_uint16_dtype: + case pressio_uint32_dtype: + case pressio_uint64_dtype: + d.code = kDLUInt; + break; + case pressio_bool_dtype: + d.code = kDLBool; + break; + } + d.lanes = 1; + return d; +} + +static DLTensor to_dltensor(pressio_data* data) { + DLTensor d; + d.byte_offset = 0; + d.data = data->data(); + d.device = data_to_dlpack_device(data); + d.dtype = to_dlpack_dtype(data->dtype()); + d.ndim = data->num_dimensions(); + + auto dims = data->dimensions(); + d.shape = new int64_t[d.ndim]; + d.strides = new int64_t[d.ndim]; + std::copy(dims.rbegin(), dims.rend(), d.shape); + compat::exclusive_scan(dims.rbegin(), dims.rend(), d.strides, 1, std::multiplies{}); + return d; +} + +static void managed_deleter(DLManagedTensor *self) { + delete[] self->dl_tensor.strides; + delete[] self->dl_tensor.shape; +} + +DLManagedTensor data_to_dlpack_managed(pressio_data* data) { + DLManagedTensor d; + d.dl_tensor = to_dltensor(data); + d.deleter = managed_deleter; + d.manager_ctx = nullptr; + return d; +} + +static void versioned_deleter(struct DLManagedTensorVersioned *self) { + delete[] self->dl_tensor.strides; + delete[] self->dl_tensor.shape; +} + +DLManagedTensorVersioned data_to_dlpack_versioned(pressio_data* data, optional_max_version max_version, optional_dl_device dl_device, optional_copy copy) { + DLManagedTensorVersioned d; + d.version = DLPackVersion(DLPACK_MAJOR_VERSION, DLPACK_MINOR_VERSION); + d.manager_ctx = nullptr; + d.flags = 0; + d.deleter = versioned_deleter; + d.dl_tensor = to_dltensor(data); + return d; +} + +std::vector option_get_strings(pressio_option const* options) { + return options->get_value>(); +} + +void option_set_strings(pressio_option* options, std::vector const& strings) { + *options = strings; +} + +std::vector data_dimensions(const pressio_data* data) { + auto d = data->dimensions(); + return std::vector(d.begin(), d.end()); +} + +intptr_t data_ptr(const pressio_data* data) { + return reinterpret_cast(pressio_data_ptr(data, nullptr)); +} + +struct pressio_option* option_new_strings(std::vector const& strings) { + return new pressio_option(pressio_option(strings)); +} +struct pressio_option* option_new_string(std::string const& string) { + return new pressio_option(pressio_option(string)); +} + +struct pressio_data* data_new_empty(const pressio_dtype dtype, std::vector dimensions) { + std::vector dims(dimensions.begin(), dimensions.end()); + return new pressio_data(pressio_data::empty(dtype, dims)); +} +struct pressio_data* data_new_nonowning(const pressio_dtype dtype, void* data, std::vector dimensions) { + std::vector dims(dimensions.begin(), dimensions.end()); + return new pressio_data(pressio_data::nonowning(dtype, data, dims)); +} +struct pressio_data* data_new_nonowning_ptr(const pressio_dtype dtype, intptr_t data, std::vector dimensions) { + std::vector dims(dimensions.begin(), dimensions.end()); + return new pressio_data(pressio_data::nonowning(dtype, reinterpret_cast(data), dims)); +} +struct pressio_data* data_new_copy(const enum pressio_dtype dtype, void* src, std::vector dimensions) { + std::vector dims(dimensions.begin(), dimensions.end()); + return new pressio_data(pressio_data::copy(dtype, src, dims)); +} +struct pressio_data* data_new_owning(const pressio_dtype dtype, std::vector dimensions) { + std::vector dims(dimensions.begin(), dimensions.end()); + return new pressio_data(pressio_data::owning(dtype, dims)); +} +struct pressio_data* data_new_move(const pressio_dtype dtype, + void* data, + std::vector dimensions, + pressio_data_delete_fn deleter, + void* metadata) { + std::vector dims(dimensions.begin(), dimensions.end()); + return new pressio_data(pressio_data::move(dtype, data, dims, deleter, metadata)); +} + +pressio_metrics* new_metrics(struct pressio* library, std::vector metrics) { + std::vector m; + std::transform(std::begin(metrics), std::end(metrics), std::back_inserter(m), [](std::string& i){ return i.c_str(); }); + return pressio_new_metrics(library, m.data(), m.size()); +} + +int compressor_compress_many(struct pressio_compressor* compressor, std::vector const& inputs, std::vector& outputs) { + return (*compressor)->compress_many(inputs.begin(), inputs.end(), outputs.begin(), outputs.end()); +} +int compressor_decompress_many(struct pressio_compressor* compressor, std::vector const& inputs, std::vector& outputs) { + return (*compressor)->decompress_many(inputs.begin(), inputs.end(), outputs.begin(), outputs.end()); +} + +void options_set_strings(pressio_options* options, std::string const& key, std::vector const& values){ + options->set(key, values); +} diff --git a/tools/swig/pypressio.h b/tools/swig/pypressio.h index faeca854..b57d80e0 100644 --- a/tools/swig/pypressio.h +++ b/tools/swig/pypressio.h @@ -1,245 +1,103 @@ #include "pressio_data.h" #include "pressio_options.h" -#include "libpressio_ext/cpp/dtype.h" #include "libpressio_ext/cpp/data.h" #include "libpressio_ext/cpp/options.h" +#include "pressio.h" #include "libpressio_ext/cpp/compressor.h" #include #include #include -#include #include "pressio_version.h" +#include "dlpack/dlpack.h" #if LIBPRESSIO_HAS_MPI4PY #include -void options_set_comm(struct pressio_options* options, const char* key, MPI_Comm comm) { - MPI_Comm* c = new MPI_Comm(comm); - return pressio_options_set_userptr_managed(options, key, c, nullptr, newdelete_deleter(), newdelete_copy()); -} -pressio_option* option_new_comm(MPI_Comm comm) { - MPI_Comm* c = new MPI_Comm(comm); - return pressio_option_new_userptr_managed(c, nullptr, newdelete_deleter(), newdelete_copy()); -} +void options_set_comm(struct pressio_options* options, const char* key, MPI_Comm comm); + +pressio_option* option_new_comm(MPI_Comm comm); #endif -namespace { - template - pressio_data* - _pressio_io_data_from_numpy_impl(T* data, std::vector dims) { - return pressio_data_new_copy( - libpressio::pressio_dtype_from_type(), - data, - dims.size(), - dims.data() - ); - } -} - -struct lp_cuda_array_interface { - std::vector shape; +struct numpy_array_interface { + std::vector shape; std::string typestr; - intptr_t ptr; bool read_only; + intptr_t ptr; int version; - int stream; }; -std::string dtype_to_typestr(pressio_dtype t) { - static std::map dtypes { - {pressio_float_dtype ,"f4"}, - {pressio_double_dtype,"f8"}, - {pressio_int8_dtype ,"i1"}, - {pressio_int16_dtype ,"i2"}, - {pressio_int32_dtype ,"i4"}, - {pressio_int64_dtype ,"i8"}, - {pressio_uint8_dtype ,"u1"}, - {pressio_uint16_dtype,"u2"}, - {pressio_uint32_dtype,"u4"}, - {pressio_uint64_dtype,"u8"}, - {pressio_bool_dtype ,"b1"}, - {pressio_byte_dtype ,"i1"}, - }; - return ((t == pressio_byte_dtype) - ? "|" - : (compat::endian::native == compat::endian::little ? "<" : ">")) + - dtypes.at(t); -} - -pressio_dtype dtype_from_typestr(std::string const& typestr) { - static std::map dtypes { - {"f4", pressio_float_dtype}, - {"f8", pressio_double_dtype}, - {"i1", pressio_int8_dtype}, - {"i2", pressio_int16_dtype}, - {"i4", pressio_int32_dtype}, - {"i8", pressio_int64_dtype}, - {"u1", pressio_uint8_dtype}, - {"u2", pressio_uint16_dtype}, - {"u4", pressio_uint32_dtype}, - {"u8", pressio_uint64_dtype}, - {"b1", pressio_bool_dtype}, - {"i1" ,pressio_byte_dtype}, - }; - pressio_dtype dtype = pressio_byte_dtype; - if(typestr.size() == 3) { - auto endian = typestr[0]; - if (compat::endian::native == compat::endian::little) { - if(endian == '>') { - throw std::runtime_error("cross endian data not supported"); - } - } - dtype = dtypes.at(typestr.substr(1)); - } - return dtype; -} - -lp_cuda_array_interface io_data_to_cuda_array(struct pressio_data* data) { - lp_cuda_array_interface ret; - auto dims = data->dimensions(); - std::reverse(dims.begin(), dims.end()); - ret.shape = dims; - ret.typestr = dtype_to_typestr(data->dtype()); - ret.ptr = reinterpret_cast(data->data()); - ret.read_only = false; - ret.version = 3; - ret.stream = 1; - return ret; -} - -pressio_data* io_data_from_cuda_array(std::vector shape, std::string const& typestr, intptr_t ptr_asint) { - std::reverse(shape.begin(), shape.end()); - void* ptr = reinterpret_cast(ptr_asint); - return new pressio_data(pressio_data::nonowning(dtype_from_typestr(typestr), ptr, shape, "cudamalloc")); -} - -pressio_data* io_data_from_numpy_array(std::vector shape, std::string const& typestr, intptr_t ptr_asint) { - std::reverse(shape.begin(), shape.end()); - void* ptr = reinterpret_cast(ptr_asint); - return new pressio_data(pressio_data::nonowning(dtype_from_typestr(typestr), ptr, shape)); -} - -template -pressio_data* -_pressio_io_data_from_numpy_1d(T* data, size_t r1) { - std::vector v = {r1}; - return _pressio_io_data_from_numpy_impl(data, v); -} - -template -pressio_data* -_pressio_io_data_from_numpy_2d(T* data, size_t r1, size_t r2) { - std::vector v = {r2, r1}; //numpy presents dimension in C order, reverse them - return _pressio_io_data_from_numpy_impl(data, v); -} - -template -pressio_data* -_pressio_io_data_from_numpy_3d(T* data, size_t r1, size_t r2, size_t r3) { - std::vector v = {r3, r2, r1}; //numpy presents dimension in C order, reverse them - return _pressio_io_data_from_numpy_impl(data, v); -} - -template -pressio_data* -_pressio_io_data_from_numpy_4d(T* data, size_t r1, size_t r2, size_t r3, size_t r4) { - std::vector v = {r4, r3, r2, r1}; //numpy presents dimension in C order, reverse them - return _pressio_io_data_from_numpy_impl(data, v); -} - -template -void _pressio_io_data_to_numpy_1d(pressio_data* ptr, T** ptr_argout, long int*r1) { - *r1 = ptr->get_dimension(0); - *ptr_argout = static_cast(pressio_data_copy(ptr, nullptr)); -} - -template -void _pressio_io_data_to_numpy_2d(pressio_data* ptr, T** ptr_argout, long int*r1, long int* r2) { - *r1 = ptr->get_dimension(1); - *r2 = ptr->get_dimension(0); - *ptr_argout = static_cast(pressio_data_copy(ptr, nullptr)); -} - -template -void _pressio_io_data_to_numpy_3d(pressio_data* ptr, T** ptr_argout, long int*r1, long int* r2, long int* r3) { - *r1 = ptr->get_dimension(2); - *r2 = ptr->get_dimension(1); - *r3 = ptr->get_dimension(0); - *ptr_argout = static_cast(pressio_data_copy(ptr, nullptr)); -} - -template -void _pressio_io_data_to_numpy_4d(pressio_data* ptr, T** ptr_argout, long int*r1, long int* r2, long int* r3, long int* r4) { - *r1 = ptr->get_dimension(3); - *r2 = ptr->get_dimension(2); - *r3 = ptr->get_dimension(1); - *r4 = ptr->get_dimension(0); - *ptr_argout = static_cast(pressio_data_copy(ptr, nullptr)); -} - -std::string io_data_to_bytes(pressio_data* data) { - size_t n_bytes; - const char* bytes = static_cast(pressio_data_ptr(data, &n_bytes)); - - return std::string(bytes, n_bytes); -} - -pressio_data* io_data_from_bytes(const char* buffer, size_t buffer_size) { - return pressio_data_new_copy(pressio_byte_dtype, (void*)buffer, 1, &buffer_size); -} - -std::vector option_get_strings(pressio_option const* options) { - return options->get_value>(); -} - -void option_set_strings(pressio_option* options, std::vector const& strings) { - *options = strings; -} - -std::vector data_dimensions(const pressio_data* data) { - auto d = data->dimensions(); - return std::vector(d.begin(), d.end()); -} - -struct pressio_option* option_new_strings(std::vector const& strings) { - return new pressio_option(pressio_option(strings)); -} - -struct pressio_data* data_new_empty(const pressio_dtype dtype, std::vector dimensions) { - return new pressio_data(pressio_data::empty(dtype, dimensions)); -} -struct pressio_data* data_new_nonowning(const pressio_dtype dtype, void* data, std::vector dimensions) { - return new pressio_data(pressio_data::nonowning(dtype, data, dimensions)); -} -struct pressio_data* data_new_copy(const enum pressio_dtype dtype, void* src, std::vector dimensions) { - return new pressio_data(pressio_data::copy(dtype, src, dimensions)); -} -struct pressio_data* data_new_owning(const pressio_dtype dtype, std::vector dimensions) { - return new pressio_data(pressio_data::owning(dtype, dimensions)); -} +numpy_array_interface data_to_array_interface(pressio_data* data); + +/** + * \returns the DLDevice the data resides on + */ +DLDevice data_to_dlpack_device(pressio_data* data); +/** + * \returns the deprecated dlpack DLManagedTensor for Backwards compatability + */ +DLManagedTensor data_to_dlpack_managed(pressio_data* data); + +/* + * swig doesn't have support for std::optional, when it does optional_max_verison, optional_dl_device, and optional_copy could be replaced + */ + +struct optional_max_version { + optional_max_version(): has_version(false), major(0), minor(0) {} + optional_max_version(int major, int minor): has_version(true), major(major), minor(minor) {} + operator bool() const { return has_version; } + bool has_version; + int major; + int minor; +}; + +struct optional_dl_device { + optional_dl_device(): has_device(false), type(0), index(0) {} + optional_dl_device(int type, int index): has_device(true), type(type), index(index) {} + operator bool() const { return has_device; } + bool has_device; + int type; + int index; +}; + +struct optional_copy { + optional_copy(): has_copy(false), copy(false) {} + optional_copy(bool copy): has_copy(true), copy(true) {} + operator bool() const { return has_copy; } + bool has_copy; + bool copy; +}; + +/** + * \returns the current dlpack versioned tensor + */ +DLManagedTensorVersioned data_to_dlpack_versioned(pressio_data* data, optional_max_version max_version, optional_dl_device dl_device, optional_copy copy); + +std::vector option_get_strings(pressio_option const* options) ; + +void option_set_strings(pressio_option* options, std::vector const& strings) ; + +std::vector data_dimensions(const pressio_data* data) ; +intptr_t data_ptr(const pressio_data* data) ; + +struct pressio_option* option_new_strings(std::vector const& strings) ; +struct pressio_option* option_new_string(std::string const& string) ; + +struct pressio_data* data_new_empty(const pressio_dtype dtype, std::vector dimensions) ; +struct pressio_data* data_new_nonowning(const pressio_dtype dtype, void* data, std::vector dimensions) ; +struct pressio_data* data_new_nonowning_ptr(const pressio_dtype dtype, intptr_t data, std::vector dimensions) ; +struct pressio_data* data_new_copy(const enum pressio_dtype dtype, void* src, std::vector dimensions) ; +struct pressio_data* data_new_owning(const pressio_dtype dtype, std::vector dimensions) ; struct pressio_data* data_new_move(const pressio_dtype dtype, void* data, std::vector dimensions, pressio_data_delete_fn deleter, - void* metadata) { - return new pressio_data(pressio_data::move(dtype, data, dimensions, deleter, metadata)); -} - -pressio_metrics* new_metrics(struct pressio* library, std::vector metrics) { - std::vector m; - std::transform(std::begin(metrics), std::end(metrics), std::back_inserter(m), [](std::string& i){ return i.c_str(); }); - return pressio_new_metrics(library, m.data(), m.size()); -} - -int compressor_compress_many(struct pressio_compressor* compressor, std::vector const& inputs, std::vector& outputs) { - return (*compressor)->compress_many(inputs.begin(), inputs.end(), outputs.begin(), outputs.end()); -} -int compressor_decompress_many(struct pressio_compressor* compressor, std::vector const& inputs, std::vector& outputs) { - return (*compressor)->decompress_many(inputs.begin(), inputs.end(), outputs.begin(), outputs.end()); -} - -void options_set_strings(pressio_options* options, std::string const& key, std::vector const& values){ - options->set(key, values); -} + void* metadata) ; + +pressio_metrics* new_metrics(struct pressio* library, std::vector metrics) ; + +int compressor_compress_many(struct pressio_compressor* compressor, std::vector const& inputs, std::vector& outputs) ; +int compressor_decompress_many(struct pressio_compressor* compressor, std::vector const& inputs, std::vector& outputs) ; + +void options_set_strings(pressio_options* options, std::string const& key, std::vector const& values);