etops


Nameetops JSON
Version 25.7.0 PyPI version JSON
download
home_pageNone
SummaryEinsum tree operations.
upload_time2025-07-24 21:34:19
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords einsum trees tensor operations
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            etops
=====

The `etops` package provides a Python interface for einsum tree operations. It enables users to define, configure, optimize, and execute complex tensor contractions and elementwise operations. The package is built on top of the einsum_ir C++ backend and exposes advanced features such as dimension fusion, dimension splitting, and backend-specific optimizations.

Main Features
-------------
- Abstractions for tensor operations and configuration
- Support for multiple data types (float32, float64)
- Primitive operations: zero, copy, relu, gemm, brgemm, etc.
- Dimension execution strategies: primitive, sequential, shared, space-filling curve (SFC)
- Dimension and stride configuration for advanced memory layouts
- Interface for built-in contraction optimizer
- Pythonic API with dataclass-based configuration

Installation
------------
Install the package using pip:

.. code-block:: bash

    pip install etops

Quick Example
-------------
Below is a minimal example showing how to configure and execute tensor operations:

.. code-block:: python

    import etops

    # -----------------------------------------
    # First example:
    #   Column-major GEMM operation
    #   Compares the result with NumPy's einsum
    # -----------------------------------------
    # Define a column-major GEMM configuration
    top_config = etops.TensorOperationConfig(
        data_type  = etops.float32,
        prim_first = etops.prim.zero,
        prim_main  = etops.prim.gemm,
        prim_last  = etops.prim.none,
        dim_types  = (etops.dim.m,     etops.dim.n,     etops.dim.k    ),
        exec_types = (etops.exec.prim, etops.exec.prim, etops.exec.prim),
        dim_sizes  = (64,              32,              128            ),
        strides_in0= (1,               0,               64             ),
        strides_in1= (0,               128,             1              ),
        strides_out= (1,               64,              0              )
    )

    # Create the TensorOperation instance
    top = etops.TensorOperation(top_config)

    # Create input and output arrays
    import numpy as np
    A = np.random.randn(128,64).astype(np.float32)
    B = np.random.randn(32,128).astype(np.float32)
    C = np.random.randn(32, 64).astype(np.float32)

    # Execute the operation
    top.execute(A, B, C)

    C_np = np.einsum("km,nk->nm", A, B)

    # Compute absolute and relative errors
    error_abs = np.max( np.abs(C - C_np) )
    error_rel = np.max( np.abs(C - C_np) / (np.abs(C_np) + 1e-8) )
    print("Column-major GEMM operation:")
    print(f"  Max absolute error: {error_abs:.6e}")
    print(f"  Max relative error: {error_rel:.6e}")

    # -----------------------------------------
    # Second example:
    #   Batched GEMM operation
    #   Compares the result with torch's einsum
    # -----------------------------------------
    # Define a batched GEMM configuration
    batched_config = etops.TensorOperationConfig(
        data_type  = etops.float32,
        prim_first = etops.prim.zero,
        prim_main  = etops.prim.gemm,
        prim_last  = etops.prim.none,
        dim_types  = (etops.dim.c,       etops.dim.m,     etops.dim.n,     etops.dim.k    ),
        exec_types = (etops.exec.shared, etops.exec.prim, etops.exec.prim, etops.exec.prim),
        dim_sizes  = (48,                64,              32,              128            ),
        strides_in0= (128*64,            1,               0,               64             ),
        strides_in1= (32*128,            0,               128,             1              ),
        strides_out= (32*64,             1,               64,              0              )
    )
    # Create the batched TensorOperation instance
    top = etops.TensorOperation(batched_config)

    import torch
    # Create input and output arrays
    A = torch.randn(48, 128, 64, dtype=torch.float32)
    B = torch.randn(48, 32, 128, dtype=torch.float32)
    C = torch.randn(48, 32, 64,  dtype=torch.float32)

    # Execute the operation
    top.execute(A, B, C)

    C_torch = torch.einsum("bkm,bnk->bnm", A, B)

    # Compute absolute and relative errors
    error_abs = torch.max(torch.abs(C - C_torch))
    error_rel = torch.max(torch.abs(C - C_torch) / (torch.abs(C_torch) + 1e-8))

    print("Batched GEMM operation:")
    print(f"  Max absolute error: {error_abs:.6e}")
    print(f"  Max relative error: {error_rel:.6e}")

    # -----------------------------------------------
    # Third example:
    #   Batch-reduce GEMM operation with optimization
    #   Compares the result with torch's einsum
    # -----------------------------------------------
    # Define a batch-reduce GEMM configuration
    batched_config = etops.TensorOperationConfig(
        data_type  = etops.float32,
        prim_first = etops.prim.zero,
        prim_main  = etops.prim.gemm,
        prim_last  = etops.prim.none,
        dim_types  = (etops.dim.k,    etops.dim.m,    etops.dim.n,    etops.dim.k   ),
        exec_types = (etops.exec.seq, etops.exec.seq, etops.exec.seq, etops.exec.seq),
        dim_sizes  = (48,             64,             32,             128           ),
        strides_in0= (128*64,         1,              0,              64            ),
        strides_in1= (32*128,         0,              128,            1             ),
        strides_out= (0,              1,              64,             0             )
    )

    # Optimize the configuration
    optimized_config = etops.optimize( batched_config,
                                       target_m=16,
                                       target_n=12,
                                       target_k=64,
                                       num_threads=1,
                                       br_gemm_support=True,
                                       packed_gemm_support=True )

    # Create the optimized TensorOperation instance
    top = etops.TensorOperation(optimized_config)

    import torch
    # Create input and output arrays
    A = torch.randn(48, 128, 64, dtype=torch.float32)
    B = torch.randn(48, 32, 128, dtype=torch.float32)
    C = torch.randn(    32, 64,  dtype=torch.float32)

    # Execute the operation
    top.execute(A, B, C)

    C_torch = torch.einsum("bkm,bnk->nm", A, B)

    # Compute absolute and relative errors
    error_abs = torch.max(torch.abs(C - C_torch))
    error_rel = torch.max(torch.abs(C - C_torch) / (torch.abs(C_torch) + 1e-8))
    print("Batch-reduce GEMM operation:")
    print(f"  Max absolute error: {error_abs:.6e}")
    print(f"  Max relative error: {error_rel:.6e}")

See the source code and inline documentation for more advanced usage.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "etops",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "einsum trees, tensor operations",
    "author": null,
    "author_email": null,
    "download_url": null,
    "platform": null,
    "description": "etops\n=====\n\nThe `etops` package provides a Python interface for einsum tree operations. It enables users to define, configure, optimize, and execute complex tensor contractions and elementwise operations. The package is built on top of the einsum_ir C++ backend and exposes advanced features such as dimension fusion, dimension splitting, and backend-specific optimizations.\n\nMain Features\n-------------\n- Abstractions for tensor operations and configuration\n- Support for multiple data types (float32, float64)\n- Primitive operations: zero, copy, relu, gemm, brgemm, etc.\n- Dimension execution strategies: primitive, sequential, shared, space-filling curve (SFC)\n- Dimension and stride configuration for advanced memory layouts\n- Interface for built-in contraction optimizer\n- Pythonic API with dataclass-based configuration\n\nInstallation\n------------\nInstall the package using pip:\n\n.. code-block:: bash\n\n    pip install etops\n\nQuick Example\n-------------\nBelow is a minimal example showing how to configure and execute tensor operations:\n\n.. code-block:: python\n\n    import etops\n\n    # -----------------------------------------\n    # First example:\n    #   Column-major GEMM operation\n    #   Compares the result with NumPy's einsum\n    # -----------------------------------------\n    # Define a column-major GEMM configuration\n    top_config = etops.TensorOperationConfig(\n        data_type  = etops.float32,\n        prim_first = etops.prim.zero,\n        prim_main  = etops.prim.gemm,\n        prim_last  = etops.prim.none,\n        dim_types  = (etops.dim.m,     etops.dim.n,     etops.dim.k    ),\n        exec_types = (etops.exec.prim, etops.exec.prim, etops.exec.prim),\n        dim_sizes  = (64,              32,              128            ),\n        strides_in0= (1,               0,               64             ),\n        strides_in1= (0,               128,             1              ),\n        strides_out= (1,               64,              0              )\n    )\n\n    # Create the TensorOperation instance\n    top = etops.TensorOperation(top_config)\n\n    # Create input and output arrays\n    import numpy as np\n    A = np.random.randn(128,64).astype(np.float32)\n    B = np.random.randn(32,128).astype(np.float32)\n    C = np.random.randn(32, 64).astype(np.float32)\n\n    # Execute the operation\n    top.execute(A, B, C)\n\n    C_np = np.einsum(\"km,nk->nm\", A, B)\n\n    # Compute absolute and relative errors\n    error_abs = np.max( np.abs(C - C_np) )\n    error_rel = np.max( np.abs(C - C_np) / (np.abs(C_np) + 1e-8) )\n    print(\"Column-major GEMM operation:\")\n    print(f\"  Max absolute error: {error_abs:.6e}\")\n    print(f\"  Max relative error: {error_rel:.6e}\")\n\n    # -----------------------------------------\n    # Second example:\n    #   Batched GEMM operation\n    #   Compares the result with torch's einsum\n    # -----------------------------------------\n    # Define a batched GEMM configuration\n    batched_config = etops.TensorOperationConfig(\n        data_type  = etops.float32,\n        prim_first = etops.prim.zero,\n        prim_main  = etops.prim.gemm,\n        prim_last  = etops.prim.none,\n        dim_types  = (etops.dim.c,       etops.dim.m,     etops.dim.n,     etops.dim.k    ),\n        exec_types = (etops.exec.shared, etops.exec.prim, etops.exec.prim, etops.exec.prim),\n        dim_sizes  = (48,                64,              32,              128            ),\n        strides_in0= (128*64,            1,               0,               64             ),\n        strides_in1= (32*128,            0,               128,             1              ),\n        strides_out= (32*64,             1,               64,              0              )\n    )\n    # Create the batched TensorOperation instance\n    top = etops.TensorOperation(batched_config)\n\n    import torch\n    # Create input and output arrays\n    A = torch.randn(48, 128, 64, dtype=torch.float32)\n    B = torch.randn(48, 32, 128, dtype=torch.float32)\n    C = torch.randn(48, 32, 64,  dtype=torch.float32)\n\n    # Execute the operation\n    top.execute(A, B, C)\n\n    C_torch = torch.einsum(\"bkm,bnk->bnm\", A, B)\n\n    # Compute absolute and relative errors\n    error_abs = torch.max(torch.abs(C - C_torch))\n    error_rel = torch.max(torch.abs(C - C_torch) / (torch.abs(C_torch) + 1e-8))\n\n    print(\"Batched GEMM operation:\")\n    print(f\"  Max absolute error: {error_abs:.6e}\")\n    print(f\"  Max relative error: {error_rel:.6e}\")\n\n    # -----------------------------------------------\n    # Third example:\n    #   Batch-reduce GEMM operation with optimization\n    #   Compares the result with torch's einsum\n    # -----------------------------------------------\n    # Define a batch-reduce GEMM configuration\n    batched_config = etops.TensorOperationConfig(\n        data_type  = etops.float32,\n        prim_first = etops.prim.zero,\n        prim_main  = etops.prim.gemm,\n        prim_last  = etops.prim.none,\n        dim_types  = (etops.dim.k,    etops.dim.m,    etops.dim.n,    etops.dim.k   ),\n        exec_types = (etops.exec.seq, etops.exec.seq, etops.exec.seq, etops.exec.seq),\n        dim_sizes  = (48,             64,             32,             128           ),\n        strides_in0= (128*64,         1,              0,              64            ),\n        strides_in1= (32*128,         0,              128,            1             ),\n        strides_out= (0,              1,              64,             0             )\n    )\n\n    # Optimize the configuration\n    optimized_config = etops.optimize( batched_config,\n                                       target_m=16,\n                                       target_n=12,\n                                       target_k=64,\n                                       num_threads=1,\n                                       br_gemm_support=True,\n                                       packed_gemm_support=True )\n\n    # Create the optimized TensorOperation instance\n    top = etops.TensorOperation(optimized_config)\n\n    import torch\n    # Create input and output arrays\n    A = torch.randn(48, 128, 64, dtype=torch.float32)\n    B = torch.randn(48, 32, 128, dtype=torch.float32)\n    C = torch.randn(    32, 64,  dtype=torch.float32)\n\n    # Execute the operation\n    top.execute(A, B, C)\n\n    C_torch = torch.einsum(\"bkm,bnk->nm\", A, B)\n\n    # Compute absolute and relative errors\n    error_abs = torch.max(torch.abs(C - C_torch))\n    error_rel = torch.max(torch.abs(C - C_torch) / (torch.abs(C_torch) + 1e-8))\n    print(\"Batch-reduce GEMM operation:\")\n    print(f\"  Max absolute error: {error_abs:.6e}\")\n    print(f\"  Max relative error: {error_rel:.6e}\")\n\nSee the source code and inline documentation for more advanced usage.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Einsum tree operations.",
    "version": "25.7.0",
    "project_urls": {
        "Homepage": "https://github.com/scalable-analyses/einsum_ir",
        "Issues": "https://github.com/scalable-analyses/einsum_ir/issues",
        "Source": "https://github.com/scalable-analyses/einsum_ir"
    },
    "split_keywords": [
        "einsum trees",
        " tensor operations"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5af041a5d9f6ee1ad576e5c75011d15fe450750f372e78315e006a8ba3185f5e",
                "md5": "a2e9af9006846af19abd979d235727c3",
                "sha256": "5bccd13e04201bf71ef1b1e60ac36652208dd5c397b97ff987aed7d1c45b0c31"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp310-cp310-macosx_14_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "a2e9af9006846af19abd979d235727c3",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 702427,
            "upload_time": "2025-07-24T21:34:19",
            "upload_time_iso_8601": "2025-07-24T21:34:19.563630Z",
            "url": "https://files.pythonhosted.org/packages/5a/f0/41a5d9f6ee1ad576e5c75011d15fe450750f372e78315e006a8ba3185f5e/etops-25.7.0-cp310-cp310-macosx_14_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "aa07c4fcc7f16a33408095ba572d7179d4e6ea37132b1a526edcaa4834d112f2",
                "md5": "b4ff0ef238c02a03bebce2f98a29f1ba",
                "sha256": "2149da55f18933909cfca8338cbf7c940ada22eb0ed1cf37fb8942cbe27d611f"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "b4ff0ef238c02a03bebce2f98a29f1ba",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 1223232,
            "upload_time": "2025-07-24T21:34:21",
            "upload_time_iso_8601": "2025-07-24T21:34:21.144988Z",
            "url": "https://files.pythonhosted.org/packages/aa/07/c4fcc7f16a33408095ba572d7179d4e6ea37132b1a526edcaa4834d112f2/etops-25.7.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5f206d95512f4d363e0719a3aa48b8d2f232d4cb7a58911241352396faaedc26",
                "md5": "c2aa29e864e28b63fd9f4d2dc44fc987",
                "sha256": "aff4825f69275335d32020a2cbb55eabc416980c90af70df56938a47855f7b68"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c2aa29e864e28b63fd9f4d2dc44fc987",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 1264607,
            "upload_time": "2025-07-24T21:34:22",
            "upload_time_iso_8601": "2025-07-24T21:34:22.815798Z",
            "url": "https://files.pythonhosted.org/packages/5f/20/6d95512f4d363e0719a3aa48b8d2f232d4cb7a58911241352396faaedc26/etops-25.7.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6bb8ae581b85926c5f67a9eba79fd563f3df1bad7bb3300496c7cca6208eef75",
                "md5": "eba93411addd7d25c82e69f7d3bb8d99",
                "sha256": "1768c08a53c9587ff67dfbf5ae7b1b8b2e3cd0ca65f34c43fe1406cb27ef2562"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp311-cp311-macosx_14_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "eba93411addd7d25c82e69f7d3bb8d99",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 703613,
            "upload_time": "2025-07-24T21:34:24",
            "upload_time_iso_8601": "2025-07-24T21:34:24.510143Z",
            "url": "https://files.pythonhosted.org/packages/6b/b8/ae581b85926c5f67a9eba79fd563f3df1bad7bb3300496c7cca6208eef75/etops-25.7.0-cp311-cp311-macosx_14_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7208efceb91f5676b33f6e1f4ff3cb73ea6b11d616ec6048bdf85886c86f5cb9",
                "md5": "b57b48020083379f7114943548145e77",
                "sha256": "e0447b4727d33257193fc800aebe0dfde6d9998aad1f64c02b99a3e69c480fef"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "b57b48020083379f7114943548145e77",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 1224177,
            "upload_time": "2025-07-24T21:34:26",
            "upload_time_iso_8601": "2025-07-24T21:34:26.109474Z",
            "url": "https://files.pythonhosted.org/packages/72/08/efceb91f5676b33f6e1f4ff3cb73ea6b11d616ec6048bdf85886c86f5cb9/etops-25.7.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3185c9052b7af150f89e25572189d1c06ae634f301d6daa0e488d8b66e4d8040",
                "md5": "831b813a0ab373e5b942d871807bb31c",
                "sha256": "782e60bc9b389910289c39115d28b4e1b7bfd88dd462644c9cb336595622a6c3"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "831b813a0ab373e5b942d871807bb31c",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 1265926,
            "upload_time": "2025-07-24T21:34:27",
            "upload_time_iso_8601": "2025-07-24T21:34:27.821716Z",
            "url": "https://files.pythonhosted.org/packages/31/85/c9052b7af150f89e25572189d1c06ae634f301d6daa0e488d8b66e4d8040/etops-25.7.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a6b033100e7a725653067a83b39dfffed323eeeae947c810e4a10f2b0d877626",
                "md5": "cf4fccaef330d4d6c9cd1700e25cbfcf",
                "sha256": "18c88c003fe4dfebfa1f3623a8a7364a47af078dfbf8d09c119d95291af7dde1"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp312-cp312-macosx_14_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "cf4fccaef330d4d6c9cd1700e25cbfcf",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 705113,
            "upload_time": "2025-07-24T21:34:29",
            "upload_time_iso_8601": "2025-07-24T21:34:29.523045Z",
            "url": "https://files.pythonhosted.org/packages/a6/b0/33100e7a725653067a83b39dfffed323eeeae947c810e4a10f2b0d877626/etops-25.7.0-cp312-cp312-macosx_14_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f6b9fe9b88618b1ed284c1648cbee9292c979aa579b373675665e663eb88a3f5",
                "md5": "2ec54c116d8be0dda3bdf51b1df5979a",
                "sha256": "91a2a53adf4c4d26801a086a9d6c4ae852054e035d3240dcb891b0d1ce88b4d9"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "2ec54c116d8be0dda3bdf51b1df5979a",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 1224566,
            "upload_time": "2025-07-24T21:34:31",
            "upload_time_iso_8601": "2025-07-24T21:34:31.186877Z",
            "url": "https://files.pythonhosted.org/packages/f6/b9/fe9b88618b1ed284c1648cbee9292c979aa579b373675665e663eb88a3f5/etops-25.7.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0134d543c24521f973c95af1959e782b3d2d429eeb2d863ef90efc597a017f2e",
                "md5": "e10448d2f3f4e85760f67202d4d49781",
                "sha256": "03b0bfe3298ac107743b1cc48579f5d7127b1902c90f8aa40296630e488bf264"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e10448d2f3f4e85760f67202d4d49781",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 1267835,
            "upload_time": "2025-07-24T21:34:32",
            "upload_time_iso_8601": "2025-07-24T21:34:32.740093Z",
            "url": "https://files.pythonhosted.org/packages/01/34/d543c24521f973c95af1959e782b3d2d429eeb2d863ef90efc597a017f2e/etops-25.7.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b54a466c2508f142e7546b4fe4eeca67786d2c4275bddd5c920b4ba27c21c705",
                "md5": "8aa8eb2bc0a17c979c7caadce018723b",
                "sha256": "5b471b26db195e37c01e452c3d3fb15c35aea11f25acb8534ef7315824bc04fa"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp313-cp313-macosx_14_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "8aa8eb2bc0a17c979c7caadce018723b",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 705164,
            "upload_time": "2025-07-24T21:34:34",
            "upload_time_iso_8601": "2025-07-24T21:34:34.718753Z",
            "url": "https://files.pythonhosted.org/packages/b5/4a/466c2508f142e7546b4fe4eeca67786d2c4275bddd5c920b4ba27c21c705/etops-25.7.0-cp313-cp313-macosx_14_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b4d9452cf2d8c74be2903d82ec2a1cc0461fce5e7eabece46fbf47ad7e2faf94",
                "md5": "123489387640914e96613b022015e8b0",
                "sha256": "5880aab0fea99522732bf9793cbb44ab489dd6e57757b35e09977dc21ea98c13"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "123489387640914e96613b022015e8b0",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 1224585,
            "upload_time": "2025-07-24T21:34:36",
            "upload_time_iso_8601": "2025-07-24T21:34:36.205760Z",
            "url": "https://files.pythonhosted.org/packages/b4/d9/452cf2d8c74be2903d82ec2a1cc0461fce5e7eabece46fbf47ad7e2faf94/etops-25.7.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6973c16750864d98fbbf25a1f4d123c15a5fae06c09812ca73b0a7a3484bee48",
                "md5": "729dcfa3d5b305763fb2e0889e9e1426",
                "sha256": "2954c3398cf9d55b0f61579cf4d717409324c4cec8360999aebafb6dcb9de5b9"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "729dcfa3d5b305763fb2e0889e9e1426",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 1267968,
            "upload_time": "2025-07-24T21:34:37",
            "upload_time_iso_8601": "2025-07-24T21:34:37.646303Z",
            "url": "https://files.pythonhosted.org/packages/69/73/c16750864d98fbbf25a1f4d123c15a5fae06c09812ca73b0a7a3484bee48/etops-25.7.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3373c4e96433dcb6dbe0da011486a0d78e19c2882b403cd4c479cccf8c51401c",
                "md5": "079b85e9d495f62c4f88af28d0c568f8",
                "sha256": "15c522ca5e4fef1399dd977b9a68c8acb3b381a1dec85e509300657ae8db4659"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp314-cp314-macosx_14_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "079b85e9d495f62c4f88af28d0c568f8",
            "packagetype": "bdist_wheel",
            "python_version": "cp314",
            "requires_python": ">=3.9",
            "size": 705659,
            "upload_time": "2025-07-24T21:34:39",
            "upload_time_iso_8601": "2025-07-24T21:34:39.011806Z",
            "url": "https://files.pythonhosted.org/packages/33/73/c4e96433dcb6dbe0da011486a0d78e19c2882b403cd4c479cccf8c51401c/etops-25.7.0-cp314-cp314-macosx_14_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "775bd6339adf0adbd619340b57953a14a8322f2f4a5ab80223ddf681519a0418",
                "md5": "a264874b79389150f2da30c248a66eba",
                "sha256": "61cd2447dc7d5eb187bcb5b5ea308593c926027f61b17a1f5453b04cffcfa36e"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "a264874b79389150f2da30c248a66eba",
            "packagetype": "bdist_wheel",
            "python_version": "cp314",
            "requires_python": ">=3.9",
            "size": 1225515,
            "upload_time": "2025-07-24T21:34:40",
            "upload_time_iso_8601": "2025-07-24T21:34:40.262738Z",
            "url": "https://files.pythonhosted.org/packages/77/5b/d6339adf0adbd619340b57953a14a8322f2f4a5ab80223ddf681519a0418/etops-25.7.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "dd0397cd84de55875323a0e21f758bdcfbd2070e0bb1d139dcdf47cbacfe2e81",
                "md5": "83a013bac20836765387654e051c4c1a",
                "sha256": "d060e4675cbc2f935ee62c335a86d17876ac8299503e4b1b32185a507c9d24b4"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "83a013bac20836765387654e051c4c1a",
            "packagetype": "bdist_wheel",
            "python_version": "cp314",
            "requires_python": ">=3.9",
            "size": 1268232,
            "upload_time": "2025-07-24T21:34:42",
            "upload_time_iso_8601": "2025-07-24T21:34:42.797586Z",
            "url": "https://files.pythonhosted.org/packages/dd/03/97cd84de55875323a0e21f758bdcfbd2070e0bb1d139dcdf47cbacfe2e81/etops-25.7.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b78310336aea055698d942400140d7ad00f5d459951d520585b34736d3d44463",
                "md5": "482e4529f714f64e6ad90db7531658cf",
                "sha256": "524660bf42d78252adf73a4b7b989e67ce36c61df5a6f863a5ad2c6418d3aea7"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp314-cp314t-macosx_14_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "482e4529f714f64e6ad90db7531658cf",
            "packagetype": "bdist_wheel",
            "python_version": "cp314",
            "requires_python": ">=3.9",
            "size": 713821,
            "upload_time": "2025-07-24T21:34:44",
            "upload_time_iso_8601": "2025-07-24T21:34:44.231677Z",
            "url": "https://files.pythonhosted.org/packages/b7/83/10336aea055698d942400140d7ad00f5d459951d520585b34736d3d44463/etops-25.7.0-cp314-cp314t-macosx_14_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "550c6a6a5113bb2ee27574da9ba0aa169a1a5ea56ed88804ea5582d046cac489",
                "md5": "136cdbd72880a937c68554b59adf4132",
                "sha256": "4713f462764785b84583f52a7872daab1a29f59fd3eea2a195593d62931f20e0"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "136cdbd72880a937c68554b59adf4132",
            "packagetype": "bdist_wheel",
            "python_version": "cp314",
            "requires_python": ">=3.9",
            "size": 1229678,
            "upload_time": "2025-07-24T21:34:45",
            "upload_time_iso_8601": "2025-07-24T21:34:45.620159Z",
            "url": "https://files.pythonhosted.org/packages/55/0c/6a6a5113bb2ee27574da9ba0aa169a1a5ea56ed88804ea5582d046cac489/etops-25.7.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "561bb5cbbd3411856002510f12f65b295a3a0b0ee26a9e1da61499025f4900bc",
                "md5": "313bc382f1edc1b4008aeae1bbf85d78",
                "sha256": "9431cc21922b457c6ded60e22f1c5e942898b00d78be4ad15680d8a48e3ee2f6"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "313bc382f1edc1b4008aeae1bbf85d78",
            "packagetype": "bdist_wheel",
            "python_version": "cp314",
            "requires_python": ">=3.9",
            "size": 1273461,
            "upload_time": "2025-07-24T21:34:47",
            "upload_time_iso_8601": "2025-07-24T21:34:47.647734Z",
            "url": "https://files.pythonhosted.org/packages/56/1b/b5cbbd3411856002510f12f65b295a3a0b0ee26a9e1da61499025f4900bc/etops-25.7.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "249d48112c632d24e298428555a4eb6e133cf0117c3285b5f17093df85101cc2",
                "md5": "cbc5b9080269a168e96339523e180d24",
                "sha256": "87be8a5f5af35eb45c242d7b023b58182cc4f8ab54e6086ed1395ddf4aeaf4cb"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp38-cp38-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "cbc5b9080269a168e96339523e180d24",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.9",
            "size": 1223100,
            "upload_time": "2025-07-24T21:34:49",
            "upload_time_iso_8601": "2025-07-24T21:34:49.357602Z",
            "url": "https://files.pythonhosted.org/packages/24/9d/48112c632d24e298428555a4eb6e133cf0117c3285b5f17093df85101cc2/etops-25.7.0-cp38-cp38-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7b430fb301d23cba892166b2d59cb9f3ecae32c6cb670b8c0f892667a8a560b4",
                "md5": "ac6e71e19c329e827f996bd1d239ffb6",
                "sha256": "431c64ed7ab442c80182a1f915c95c7ef45e17a3670a97a55e745ea3927fbe00"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp38-cp38-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "ac6e71e19c329e827f996bd1d239ffb6",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.9",
            "size": 1264313,
            "upload_time": "2025-07-24T21:34:51",
            "upload_time_iso_8601": "2025-07-24T21:34:51.028400Z",
            "url": "https://files.pythonhosted.org/packages/7b/43/0fb301d23cba892166b2d59cb9f3ecae32c6cb670b8c0f892667a8a560b4/etops-25.7.0-cp38-cp38-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3b54a112c3bdbf3719492c9eb963b259e9d3b6c609705903707f5b386202da44",
                "md5": "472b23674960932791eab82a5f802d16",
                "sha256": "cf79cdb71e65317b30792ca809ceaf5d8ad8c494cd9e1e115556b636643f7170"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp39-cp39-macosx_14_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "472b23674960932791eab82a5f802d16",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 702530,
            "upload_time": "2025-07-24T21:34:52",
            "upload_time_iso_8601": "2025-07-24T21:34:52.320143Z",
            "url": "https://files.pythonhosted.org/packages/3b/54/a112c3bdbf3719492c9eb963b259e9d3b6c609705903707f5b386202da44/etops-25.7.0-cp39-cp39-macosx_14_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5895ec0a06cbe331a65c3d94ac72136f4efff408ed5b4f875e621f833e1d3463",
                "md5": "774eed667fd4690ca052398b25339d87",
                "sha256": "e3c6eed386162fce636d41f7e4e045a1b407244dad1ae796e83410449c15549f"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "774eed667fd4690ca052398b25339d87",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 1223354,
            "upload_time": "2025-07-24T21:34:53",
            "upload_time_iso_8601": "2025-07-24T21:34:53.858257Z",
            "url": "https://files.pythonhosted.org/packages/58/95/ec0a06cbe331a65c3d94ac72136f4efff408ed5b4f875e621f833e1d3463/etops-25.7.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6eb4a454094dfd27362fc4230861e0db4afa8f25bf2e4e3a84454c48441a9e24",
                "md5": "453d940d16f7f8070156ba99e31c6ffe",
                "sha256": "b87ef5570d72ce51d6c21924e041de81759f4845a86a9bc6ed0d0ecda67cec3a"
            },
            "downloads": -1,
            "filename": "etops-25.7.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "453d940d16f7f8070156ba99e31c6ffe",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 1264436,
            "upload_time": "2025-07-24T21:34:55",
            "upload_time_iso_8601": "2025-07-24T21:34:55.177581Z",
            "url": "https://files.pythonhosted.org/packages/6e/b4/a454094dfd27362fc4230861e0db4afa8f25bf2e4e3a84454c48441a9e24/etops-25.7.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-24 21:34:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "scalable-analyses",
    "github_project": "einsum_ir",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "etops"
}
        
Elapsed time: 0.97581s