Skip to main content

A high-performance array storage and manipulation library

Project description

NumPack

NumPack is a lightning-fast array manipulation engine that revolutionizes how you handle large-scale NumPy arrays. By combining Rust's raw performance with Python's ease of use, NumPack delivers up to 20x faster operations than traditional methods, while using minimal memory. Whether you're working with gigabyte-sized matrices or performing millions of array operations, NumPack makes it effortless with its zero-copy architecture and intelligent memory management.

Key highlights:

  • 🚀 Up to 20x faster than traditional NumPy storage methods
  • 💾 Zero-copy operations for minimal memory footprint
  • 🔄 Seamless integration with existing NumPy workflows
  • 🛠 Battle-tested in production with arrays exceeding 1 billion rows

Features

  • High Performance: Optimized for both reading and writing large numerical arrays
  • Lazy Loading Support: Efficient memory usage through on-demand data loading
  • Selective Loading: Load only the arrays you need, when you need them
  • In-place Operations: Support for in-place array modifications without full file rewrite
  • Parallel I/O: Utilizes parallel processing for improved performance
  • Multiple Data Types: Supports various numerical data types including:
    • Boolean
    • Unsigned integers (8-bit to 64-bit)
    • Signed integers (8-bit to 64-bit)
    • Floating point (32-bit and 64-bit)

Installation

From PyPI (Recommended)

Prerequisites

  • Python >= 3.9
  • NumPy >= 1.26.0
pip install numpack

From Source

To build and install NumPack from source, you need to meet the following requirements:

Prerequisites

  • Python >= 3.9
  • Rust >= 1.70.0
  • NumPy >= 1.26.0
  • Appropriate C/C++ compiler (depending on your operating system)
    • Linux: GCC or Clang
    • macOS: Clang (via Xcode Command Line Tools)
    • Windows: MSVC (via Visual Studio or Build Tools)

Build Steps

  1. Clone the repository:
git clone https://github.com/BirchKwok/NumPack.git
cd NumPack
  1. Install maturin (for building Rust and Python hybrid projects):
pip install maturin>=1.0,<2.0
  1. Build and install:
# Install in development mode
maturin develop

# Or build wheel package
maturin build --release
pip install target/wheels/numpack-*.whl

Platform-Specific Notes

  • Linux Users:

    • Ensure python3-dev (Ubuntu/Debian) or python3-devel (Fedora/RHEL) is installed
    • If using conda environment, make sure the appropriate compiler toolchain is installed
  • macOS Users:

    • Make sure Xcode Command Line Tools are installed: xcode-select --install
    • Supports both Intel and Apple Silicon architectures
  • Windows Users:

    • Visual Studio or Visual Studio Build Tools required
    • Ensure "Desktop development with C++" workload is installed

Usage

Basic Operations

import numpy as np
from numpack import NumPack

# Create a NumPack instance
npk = NumPack("data_directory")

# Save arrays
arrays = {
    'array1': np.random.rand(1000, 100).astype(np.float32),
    'array2': np.random.rand(500, 200).astype(np.float32)
}
npk.save(arrays)

# Load arrays
# Normal mode
loaded = npk.load("array1")

# lazy load
lazy_array = npk.load("arr1", lazy=True)

Advanced Operations

# Replace specific rows
replacement = np.random.rand(10, 100).astype(np.float32)
npk.replace({'array1': replacement}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])  # Using list indices
npk.replace({'array1': replacement}, slice(0, 10))  # Using slice notation

# Append new arrays
new_arrays = {
    'array3': np.random.rand(200, 100).astype(np.float32)
}
npk.append(new_arrays)

# Drop arrays or specific rows
npk.drop('array1')  # Drop entire array
npk.drop(['array1', 'array2'])  # Drop multiple arrays
npk.drop('array2', [0, 1, 2])  # Drop specific rows

# Random access operations
data = npk.getitem('array1', [0, 1, 2])  # Access specific rows
data = npk.getitem('array1', slice(0, 10))  # Access using slice
data = npk['array1']  # Dictionary-style access for entire array

# Metadata operations
shapes = npk.get_shape()  # Get shapes of all arrays
shapes = npk.get_shape('array1')  # Get shape of specific array
members = npk.get_member_list()  # Get list of array names
mtime = npk.get_modify_time('array1')  # Get modification time
metadata = npk.get_metadata()  # Get complete metadata

# Stream loading for large arrays
for batch in npk.stream_load('array1', buffer_size=1000):
    # Process 1000 rows at a time
    process_batch(batch)

# Reset/clear storage
npk.reset()  # Clear all arrays

# Iterate over all arrays
for array_name in npk:
    data = npk[array_name]
    print(f"{array_name} shape: {data.shape}")

Lazy Loading and Buffer Operations

NumPack supports lazy loading and buffer operations, which are particularly useful for handling large-scale datasets. Using the lazy=True parameter enables data to be loaded only when actually needed, making it ideal for streaming processing or scenarios where only partial data access is required.

from numpack import NumPack
import numpy as np

# Create NumPack instance and save large-scale data
npk = NumPack("test_data/", drop_if_exists=True)
a = np.random.random((1000000, 128))  # Create a large array
npk.save({"arr1": a})

# Lazy loading - keeps data in buffer
lazy_array = npk.load("arr1", lazy=True)  # LazyArray Object

# Perform computations with lazy-loaded data
# Only required data is loaded into memory
similarity_scores = np.inner(a[0], npk.load("arr1", lazy=True))

Performance

NumPack offers significant performance improvements compared to traditional NumPy storage methods, especially in data modification operations and random access. Below are detailed benchmark results:

Benchmark Results

The following benchmarks were performed on an MacBook Pro (Apple Silicon) with arrays of size 1M x 10 and 500K x 5 (float32).

Storage Operations

Operation NumPack NumPy NPZ NumPy NPY
Save 0.015s (0.93x NPZ, 0.53x NPY) 0.014s 0.008s
Full Load 0.008s (1.75x NPZ, 1.00x NPY) 0.014s 0.008s
Selective Load 0.006s (1.67x NPZ, -) 0.010s -

Data Modification Operations

Operation NumPack NumPy NPZ NumPy NPY
Single Row Replace 0.000s (≥40x NPZ, ≥30x NPY) 0.022s 0.015s
Continuous Rows (10K) 0.001s (24.00x NPZ, 14.00x NPY) 0.024s 0.014s
Random Rows (10K) 0.015s (1.53x NPZ, 0.93x NPY) 0.023s 0.014s
Large Data Replace (500K) 0.020s (1.10x NPZ, 0.75x NPY) 0.022s 0.015s

Drop Operations

Operation (1M rows, float32) NumPack NumPy NPZ NumPy NPY
Drop Array 0.001s (24.00x NPZ, 1.00x NPY) 0.024s 0.001s
Drop First Row 0.014s (3.29x NPZ, 1.93x NPY) 0.046s 0.027s
Drop Last Row 0.000s (∞x NPZ, ∞x NPY) 0.046s 0.027s
Drop Middle Row 0.014s (3.29x NPZ, 1.93x NPY) 0.046s 0.027s
Drop Front Continuous (10K rows) 0.015s (3.07x NPZ, 1.80x NPY) 0.046s 0.027s
Drop Middle Continuous (10K rows) 0.015s (3.07x NPZ, 1.80x NPY) 0.046s 0.027s
Drop End Continuous (10K rows) 0.001s (46.00x NPZ, 27.00x NPY) 0.046s 0.027s
Drop Random Rows (10K rows) 0.018s (2.56x NPZ, 1.50x NPY) 0.046s 0.027s
Drop Near Non-continuous (10K rows) 0.015s (3.07x NPZ, 1.80x NPY) 0.046s 0.027s

Append Operations

Operation NumPack NumPy NPZ NumPy NPY
Small Append (1K rows) 0.000s (≥80x NPZ, ≥60x NPY) 0.025s 0.017s
Large Append (500K rows) 0.003s (11.33x NPZ, 7.67x NPY) 0.034s 0.023s

Random Access Performance (10K indices)

Operation NumPack NumPy NPZ NumPy NPY
Random Access 0.008s (2.38x NPZ, 1.50x NPY) 0.019s 0.012s

Matrix Computation Performance (1M rows x 128 columns, Float32)

Operation NumPack NumPy NPZ NumPy NPY In-Memory
Inner Product 0.021s (6.62x NPZ, 1.05x NPY) 0.139s 0.022s 0.011s

File Size Comparison

Format Size Ratio
NumPack 47.68 MB 1.0x
NPZ 47.68 MB 1.0x
NPY 47.68 MB 1.0x

Large-scale Data Operations (>1B rows, Float32)

Operation NumPack NumPy NPZ NumPy NPY
Replace Zero-copy in-place modification Memory exceeded Memory exceeded
Drop Zero-copy in-place deletion Memory exceeded Memory exceeded
Append Zero-copy in-place addition Memory exceeded Memory exceeded
Random Access Near-hardware I/O speed Memory exceeded Memory exceeded

Key Advantage: NumPack achieves the same performance as NumPy's NPY mmap (0.021s) for matrix computations, with several implementation advantages:

  • Uses Arc for reference counting, ensuring automatic resource cleanup
  • Implements MMAP_CACHE to avoid redundant data loading
  • Linux-specific optimizations with huge pages and sequential access hints
  • Supports parallel I/O operations for improved data throughput
  • Optimizes memory usage through Buffer Pool to reduce fragmentation

Key Performance Highlights

  1. Data Modification:

    • Single row replacement: NumPack is ≥40x faster than NPZ and ≥30x faster than NPY
    • Continuous rows: NumPack is 24x faster than NPZ and 14x faster than NPY
    • Random rows: NumPack is 1.53x faster than NPZ but 0.93x slower than NPY
    • Large data replacement: NumPack is 1.10x faster than NPZ but 0.75x slower than NPY
  2. Drop Operations:

    • Drop array: NumPack is 24x faster than NPZ and comparable to NPY
    • Drop rows: NumPack is now ~3x faster than NPZ and ~2x faster than NPY in typical scenarios
    • NumPack continues to support efficient in-place row deletion without full file rewrite
  3. Append Operations:

    • Small append (1K rows): NumPack is ≥80x faster than NPZ and ≥60x faster than NPY
    • Large append (500K rows): NumPack is 11x faster than NPZ and 8x faster than NPY
    • Performance improvements in append operations are attributed to optimized buffer management
  4. Loading Performance:

    • Full load: NumPack is 1.75x faster than NPZ and on par with NPY
    • Lazy load (memory-mapped): NumPack is ~2.0x faster than NPZ mmap and close to NPY mmap
    • Selective load: NumPack is 1.67x faster than NPZ
  5. Random Access:

    • NumPack is 2.38x faster than NPZ and 1.50x faster than NPY for random index access
  6. Storage Efficiency:

    • All formats achieve identical compression ratios (47.68 MB)
    • NumPack maintains high performance while keeping file sizes competitive
  7. Matrix Computation:

    • NumPack remains on par with NPY mmap performance while providing better resource management
    • 6.62x faster than NPZ mmap for matrix operations
    • Only 1.91x slower than pure in-memory computation
    • Zero risk of file descriptor leaks or resource exhaustion

Note: All benchmarks were performed with float32 arrays. Performance may vary depending on data types, array sizes, and system configurations. Numbers greater than 1.0x indicate faster performance, while numbers less than 1.0x indicate slower performance.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.

Copyright 2024 NumPack Contributors

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

numpack-0.2.0.tar.gz (46.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

numpack-0.2.0-py3-none-any.whl (45.4 kB view details)

Uploaded Python 3

numpack-0.2.0-cp313-cp313-manylinux_2_34_x86_64.whl (809.0 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

numpack-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (725.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

numpack-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl (758.3 kB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

numpack-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl (809.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

numpack-0.2.0-cp312-cp312-macosx_11_0_arm64.whl (725.5 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

numpack-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl (759.1 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

numpack-0.2.0-cp311-cp311-manylinux_2_34_x86_64.whl (806.5 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

numpack-0.2.0-cp311-cp311-macosx_11_0_arm64.whl (729.3 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

numpack-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl (764.2 kB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

numpack-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl (806.6 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

numpack-0.2.0-cp310-cp310-macosx_11_0_arm64.whl (728.9 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

numpack-0.2.0-cp310-cp310-macosx_10_12_x86_64.whl (764.3 kB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

numpack-0.2.0-cp39-cp39-manylinux_2_34_x86_64.whl (807.8 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ x86-64

numpack-0.2.0-cp39-cp39-macosx_11_0_arm64.whl (729.7 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

numpack-0.2.0-cp39-cp39-macosx_10_12_x86_64.whl (764.8 kB view details)

Uploaded CPython 3.9macOS 10.12+ x86-64

File details

Details for the file numpack-0.2.0.tar.gz.

File metadata

  • Download URL: numpack-0.2.0.tar.gz
  • Upload date:
  • Size: 46.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for numpack-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5ff30a8c2b2b84cde79df69432b851487b05da1e852792fb76edef5c023aac65
MD5 133b967b7646db1af54fc2ee02f9e10a
BLAKE2b-256 d15794e3f0031a2489cbbcae400712cb54e611ece4cc66a68ed53170a2c3fa6a

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: numpack-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 45.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for numpack-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5c582eccdc7f1da2cf049bf5c68242b0957704f59308d5fd94b6586c249a8b01
MD5 bac0a3862eb5113d192678c440a5d508
BLAKE2b-256 7e0e49ca0ab3a489224c56f39ed89dd40fe96a01a726efa0c014fd79854cb276

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 e501096381c955aa1faaa03f45bff321a641f66c5c341003e585848cdf2573d3
MD5 a4fc757a59d20d0781e961490c2cb1fd
BLAKE2b-256 a60e4e4004cf8e89adbe10333d299a9fb7bb27f82222c47d2561befddfebf3b5

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c3bc575751f59ef8d3a2ca31b2169e510be93d21382dbef3af15abcc99bbc0b7
MD5 58035b21510eef0c1c582f60ea23ca82
BLAKE2b-256 4d48485e9683d0f64b190d44afa60e40accb7a9dfd7dbd6893dbb00ceb511c55

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d5141f043a39982031a0740865b9c3eb378142c4954949e10ba278ae320e6b72
MD5 721420f615de3929ee5bb32c07f69885
BLAKE2b-256 ef07998a9a30485d155cb1c10c49e5dbec92972a49e0f681cd97d5a21f733486

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 8e7f733d828799898b729f1c6d3e80e8c18d58ce705c49e4e24effbd0dcac97c
MD5 7b6771e2e7f78c479ddddb3755b19965
BLAKE2b-256 7315aa27faa1d7c08cad0b215a58d25dfa4310d7cd13444594e5850162acbde2

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fd475d669e508de659e39017d92c2a11f247921af87cec5d17f475a06167262f
MD5 50ffc7a9ea652c11958e818d6c85ffbf
BLAKE2b-256 8c05d9710854eb52a16b0be8468778a05f1ca6a24d69b70bcda34074de29d415

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3d54b567a385ad3cf636aafa2db469df5f344ba6b8e305dc0b094b899aaebe69
MD5 dba93f345b612d00d47433ab82cf0541
BLAKE2b-256 0630a87830584ca3f5fda156d502de88ccf78f1347df5de208451d99727faa48

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 2ad79a37b93d9478b748c39688f338e7750179deec8505edaa1234160fa7602f
MD5 762d23ef5341b0524ce74b0258f8f8da
BLAKE2b-256 5d0c6ef310925d25c811b21c5f4d8a3d555424c99ee30ea27e09775dc0cf478f

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a0ef9aaf2c9ce2548577e41acd1c2cc74279e87a8b6871c2d6765c33d947c029
MD5 dbf7e502988721762da9eb7164395b42
BLAKE2b-256 c5efaaaa478e676ec9b700f34775024c996ba4ae75646c826e4bb10148120f90

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ac27f426e5a614a47367d397805427b6ecd2d1cfcf6d88ccff24c8b4868c043a
MD5 347a576b55a76a57cbce122df2da23b6
BLAKE2b-256 d8eb78e3c5f34536b058581138910278829c30c8b01a7ebc0cfec181b4325db4

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 5b70db93578ee104be97e75c5decf64e2d840ef4497b53793c21fcad6a685600
MD5 bc6e42d44f03cfc8c58b4788b9f3548c
BLAKE2b-256 02ba640654638a0b5adaa157c85fe7cc633e70d74e5189855ddcc756f1554ae3

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ab302e0049a03fd13b1b0fa8bad6b28c89e2f93f7858786b8a555c31154db519
MD5 d126692b6a273b1614d9649a6a84362f
BLAKE2b-256 8e40ba108de4863648b5d2f12b3e4319349c59671a4b439429b4115f74ebefe6

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0ef4fc908dcf3be258556cba5accdf04129d25df9fb4273b279ced247aa6628e
MD5 5da5823874e964af60af61a401bd4650
BLAKE2b-256 213695a8f068f0b626395bcdfdb5cc73204c735561e61b7d5bae466e064a0351

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp39-cp39-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 b7417bb66e21233fd1924770811ed0c291f600a406b5e5a40dbd055bd239a39e
MD5 326f55773f7a1b7ea67a78cc9d0426df
BLAKE2b-256 ce8200ab08e074a1803bc4f53dc6f25b7a5e0a0375fcdeab70bf94b1a1b748b3

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ce1815c66fb0da4522b453402889b96253e5086c29acdf69d22253c0ae31f615
MD5 29ec2c308547cefe190876e7b484e237
BLAKE2b-256 fbb811cdce5305b9b4d33b776788dabc8e39563cbe0ff431340ba962462410f4

See more details on using hashes here.

File details

Details for the file numpack-0.2.0-cp39-cp39-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for numpack-0.2.0-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c376e6f7c972871a4c7ea7e6fd7aa0f9a2b8931cf3611615927beeec096ad016
MD5 f346959df98d62f3a4c83af0b1e3a03a
BLAKE2b-256 024ecc8c634a986d9d94230e59603d969493c642e9b0f61119a8b5072fde3aa3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page