Skip to main content

Efficient and parallelized algorithms for fine point cloud registration

Project description

small_gicp

small_gicp is a header-only C++ library providing efficient and parallelized algorithms for fine point cloud registration (ICP, Point-to-Plane ICP, GICP, VGICP, etc.). It is a refined and optimized version of its predecessor, fast_gicp, re-written from scratch with the following features.

  • Highly Optimized : The core registration algorithm implementation has been further optimized from fast_gicp, achieving up to 2x speed gain.
  • Fully parallerized : small_gicp offers parallel implementations of several preprocessing algorithms, making the entire registration process parallelized (e.g., Downsampling, KdTree construction, Normal/Covariance estimation). It supports OpenMP and Intel TBB as parallelism backends.
  • Minimum dependencies : The library requires only Eigen along with the bundled nanoflann and Sophus. Optionally, it supports a PCL registration interface for use as a drop-in replacement
  • Customizable : small_gicp allows the integration of any custom point cloud class into the registration algorithm via traits. Its template-based implementation enables customization of the registration process with original correspondence estimators and registration factors.
  • Python bindings : By being isolated from PCL, small_gicp's Python bindings are more portable and can be used seamlessly with other libraries such as Open3D.

Note that GPU-based implementations are NOT included in this package.

If you find this package useful for your project, please consider leaving a comment here. It would help the author receive recognition in his organization and keep working on this project.

Build(Linux) macos Build(Windows) Test codecov

Requirements

This library uses C++17 features. The PCL interface is not compatible with PCL older than 1.11 that uses boost::shared_ptr.

Dependencies

Installation

C++

small_gicp is a header-only library. You can just download and drop it in your project directory to use it.

If you need only basic point cloud registration functions, you can build and install the helper library as follows.

sudo apt-get install libeigen3-dev libomp-dev

cd small_gicp
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release && make -j
sudo make install

Python (Linux / Windows / MacOS)

Install from PyPI

pip install small_gicp

Install from source

cd small_gicp
pip install .

# [Optional (linux)] Install stubs for autocomplete (If you know a better way, let me know...)
pip install pybind11-stubgen
cd ~/.local/lib/python3.10/site-packages
pybind11-stubgen -o . --ignore-invalid=all small_gicp

Documentation

Usage (C++)

The following examples assume using namespace small_gicp is placed somewhere.

Using helper library (01_basic_registration.cpp)

The helper library (registration_helper.hpp) enables easily processing point clouds represented as std::vector<Eigen::Vector(3|4)(f|d)>.

Expand

small_gicp::align takes two point clouds (std::vectors of Eigen::Vector(3|4)(f|d)) and returns a registration result (estimated transformation and some information on the optimization result). This is the easiest way to use small_gicp but causes an overhead for duplicated preprocessing.

#include <small_gicp/registration/registration_helper.hpp>

std::vector<Eigen::Vector3d> target_points = ...;   // Any of Eigen::Vector(3|4)(f|d) can be used
std::vector<Eigen::Vector3d> source_points = ...;   // 

RegistrationSetting setting;
setting.num_threads = 4;                    // Number of threads to be used
setting.downsampling_resolution = 0.25;     // Downsampling resolution
setting.max_correspondence_distance = 1.0;  // Maximum correspondence distance between points (e.g., triming threshold)

Eigen::Isometry3d init_T_target_source = Eigen::Isometry3d::Identity();
RegistrationResult result = align(target_points, source_points, init_T_target_source, setting);

Eigen::Isometry3d T = result.T_target_source;  // Estimated transformation
size_t num_inliers = result.num_inliers;       // Number of inlier source points
Eigen::Matrix<double, 6, 6> H = result.H;      // Final Hessian matrix (6x6)

There is also a way to perform preprocessing and registration separately. This enables saving time for preprocessing in case registration is performed several times for the same point cloud (e.g., typical odometry estimation based on scan-to-scan matching).

#include <small_gicp/registration/registration_helper.hpp>

std::vector<Eigen::Vector3d> target_points = ...;   // Any of Eigen::Vector(3|4)(f|d) can be used
std::vector<Eigen::Vector3d> source_points = ...;   // 

int num_threads = 4;                    // Number of threads to be used
double downsampling_resolution = 0.25;  // Downsampling resolution
int num_neighbors = 10;                 // Number of neighbor points used for normal and covariance estimation

// std::pair<PointCloud::Ptr, KdTree<PointCloud>::Ptr>
auto [target, target_tree] = preprocess_points(target_points, downsampling_resolution, num_neighbors, num_threads);
auto [source, source_tree] = preprocess_points(source_points, downsampling_resolution, num_neighbors, num_threads);

RegistrationSetting setting;
setting.num_threads = num_threads;
setting.max_correspondence_distance = 1.0;  // Maximum correspondence distance between points (e.g., triming threshold)

Eigen::Isometry3d init_T_target_source = Eigen::Isometry3d::Identity();
RegistrationResult result = align(*target, *source, *target_tree, init_T_target_source, setting);

Eigen::Isometry3d T = result.T_target_source;  // Estimated transformation
size_t num_inliers = result.num_inliers;       // Number of inlier source points
Eigen::Matrix<double, 6, 6> H = result.H;      // Final Hessian matrix (6x6)

Using PCL interface (02_basic_registration_pcl.cpp)

The PCL interface allows using small_gicp as a drop-in replacement for pcl::Registration. It is also possible to directly feed pcl::PointCloud to algorithms implemented in small_gicp.

Expand
#include <small_gicp/pcl/pcl_registration.hpp>

pcl::PointCloud<pcl::PointXYZ>::Ptr raw_target = ...;
pcl::PointCloud<pcl::PointXYZ>::Ptr raw_source = ...;

// small_gicp::voxelgrid_downsampling can directly operate on pcl::PointCloud.
pcl::PointCloud<pcl::PointXYZ>::Ptr target = voxelgrid_sampling_omp(*raw_target, 0.25);
pcl::PointCloud<pcl::PointXYZ>::Ptr source = voxelgrid_sampling_omp(*raw_source, 0.25);

// RegistrationPCL is derived from pcl::Registration and has mostly the same interface as pcl::GeneralizedIterativeClosestPoint.
RegistrationPCL<pcl::PointXYZ, pcl::PointXYZ> reg;
reg.setNumThreads(4);
reg.setCorrespondenceRandomness(20);
reg.setMaxCorrespondenceDistance(1.0);
reg.setVoxelResolution(1.0);
reg.setRegistrationType("VGICP");  // or "GICP" (default = "GICP")

// Set input point clouds.
reg.setInputTarget(target);
reg.setInputSource(source);

// Align point clouds.
auto aligned = pcl::make_shared<pcl::PointCloud<pcl::PointXYZ>>();
reg.align(*aligned);

// Swap source and target and align again.
// This is useful when you want to re-use preprocessed point clouds for successive registrations (e.g., odometry estimation).
reg.swapSourceAndTarget();
reg.align(*aligned);

It is also possible to directly feed pcl::PointCloud to small_gicp::Registration. Because all preprocessed data are exposed in this way, you can easily re-use them to obtain the best efficiency.

#include <small_gicp/pcl/pcl_point.hpp>
#include <small_gicp/pcl/pcl_point_traits.hpp>

pcl::PointCloud<pcl::PointXYZ>::Ptr raw_target = ...;
pcl::PointCloud<pcl::PointXYZ>::Ptr raw_source = ...;

// Downsample points and convert them into pcl::PointCloud<pcl::PointCovariance>.
pcl::PointCloud<pcl::PointCovariance>::Ptr target = voxelgrid_sampling_omp<pcl::PointCloud<pcl::PointXYZ>, pcl::PointCloud<pcl::PointCovariance>>(*raw_target, 0.25);
pcl::PointCloud<pcl::PointCovariance>::Ptr source = voxelgrid_sampling_omp<pcl::PointCloud<pcl::PointXYZ>, pcl::PointCloud<pcl::PointCovariance>>(*raw_source, 0.25);

// Estimate covariances of points.
const int num_threads = 4;
const int num_neighbors = 20;
estimate_covariances_omp(*target, num_neighbors, num_threads);
estimate_covariances_omp(*source, num_neighbors, num_threads);

// Create KdTree for target and source.
auto target_tree = std::make_shared<KdTree<pcl::PointCloud<pcl::PointCovariance>>>(target, KdTreeBuilderOMP(num_threads));
auto source_tree = std::make_shared<KdTree<pcl::PointCloud<pcl::PointCovariance>>>(source, KdTreeBuilderOMP(num_threads));

Registration<GICPFactor, ParallelReductionOMP> registration;
registration.reduction.num_threads = num_threads;
registration.rejector.max_dist_sq = 1.0;

// Align point clouds. Note that the input point clouds are pcl::PointCloud<pcl::PointCovariance>.
auto result = registration.align(*target, *source, *target_tree, Eigen::Isometry3d::Identity());

Using Registration template (03_registration_template.cpp)

If you want to fine-control and customize the registration process, use small_gicp::Registration template that allows modifying the inner algorithms and parameters.

Expand
#include <small_gicp/ann/kdtree_omp.hpp>
#include <small_gicp/points/point_cloud.hpp>
#include <small_gicp/factors/gicp_factor.hpp>
#include <small_gicp/util/normal_estimation_omp.hpp>
#include <small_gicp/registration/reduction_omp.hpp>
#include <small_gicp/registration/registration.hpp>

std::vector<Eigen::Vector3d> target_points = ...;   // Any of Eigen::Vector(3|4)(f|d) can be used
std::vector<Eigen::Vector3d> source_points = ...;   // 

int num_threads = 4;
double downsampling_resolution = 0.25;
int num_neighbors = 10;
double max_correspondence_distance = 1.0;

// Convert to small_gicp::PointCloud
auto target = std::make_shared<PointCloud>(target_points);
auto source = std::make_shared<PointCloud>(source_points);

// Downsampling
target = voxelgrid_sampling_omp(*target, downsampling_resolution, num_threads);
source = voxelgrid_sampling_omp(*source, downsampling_resolution, num_threads);

// Create KdTree
auto target_tree = std::make_shared<KdTree<PointCloud>>(target, KdTreeBuilderOMP(num_threads));
auto source_tree = std::make_shared<KdTree<PointCloud>>(source, KdTreeBuilderOMP(num_threads));

// Estimate point covariances
estimate_covariances_omp(*target, *target_tree, num_neighbors, num_threads);
estimate_covariances_omp(*source, *source_tree, num_neighbors, num_threads);

// GICP + OMP-based parallel reduction
Registration<GICPFactor, ParallelReductionOMP> registration;
registration.reduction.num_threads = num_threads;
registration.rejector.max_dist_sq = max_correspondence_distance * max_correspondence_distance;

// Align point clouds
Eigen::Isometry3d init_T_target_source = Eigen::Isometry3d::Identity();
auto result = registration.align(*target, *source, *target_tree, init_T_target_source);

Eigen::Isometry3d T = result.T_target_source;  // Estimated transformation
size_t num_inliers = result.num_inliers;       // Number of inlier source points
Eigen::Matrix<double, 6, 6> H = result.H;      // Final Hessian matrix (6x6)

See 03_registration_template.cpp for more detailed customization examples.

Cookbook

Usage (Python) basic_registration.py

Expand

Example A : Perform registration with numpy arrays

# Align two point clouds using various ICP-like algorithms.
# 
# Parameters
# ----------
# target_points : NDArray[np.float64]
#     Nx3 or Nx4 matrix representing the target point cloud.
# source_points : NDArray[np.float64]
#     Nx3 or Nx4 matrix representing the source point cloud.
# init_T_target_source : np.ndarray[np.float64]
#     4x4 matrix representing the initial transformation from target to source.
# registration_type : str = 'GICP'
#     Type of registration algorithm to use ('ICP', 'PLANE_ICP', 'GICP', 'VGICP').
# voxel_resolution : float = 1.0
#     Resolution of voxels used for correspondence search (used only in VGICP).
# downsampling_resolution : float = 0.25
#     Resolution for downsampling the point clouds.
# max_correspondence_distance : float = 1.0
#     Maximum distance for matching points between point clouds.
# num_threads : int = 1
#     Number of threads to use for parallel processing.
# 
# Returns
# -------
# RegistrationResult
#     Object containing the final transformation matrix and convergence status.
result = small_gicp.align(target_raw_numpy, source_raw_numpy, downsampling_resolution=0.25)

result.T_target_source  # Estimated transformation (4x4 numpy array)
result.converged        # If true, the optimization converged successfully
result.iterations       # Number of iterations the optimization took
result.num_inliers      # Number of inlier points
result.H                # Final Hessian matrix (6x6 matrix)
result.b                # Final information vector (6D vector)
result.e                # Final error (float)

Example B : Perform preprocessing and registration separately

# Preprocess point cloud (downsampling, kdtree construction, and normal/covariance estimation)
#
# Parameters
# ----------
# points : NDArray[np.float64]
#     Nx3 or Nx4 matrix representing the point cloud.
# downsampling_resolution : float = 0.1
#     Resolution for downsampling the point clouds.
# num_neighbors : int = 20
#     Number of neighbor points to usefor point normal/covariance estimation.
# num_threads : int = 1
#     Number of threads to use for parallel processing.
# 
# Returns
# -------
# PointCloud
#     Downsampled point cloud with estimated normals and covariances.
# KdTree
#     KdTree for the downsampled point cloud
target, target_tree = small_gicp.preprocess_points(target_raw_numpy, downsampling_resolution=0.25)
source, source_tree = small_gicp.preprocess_points(source_raw_numpy, downsampling_resolution=0.25)

# `target` and `source` are small_gicp.PointCloud with the following methods
target.size()           # Number of points
target.points()         # Nx4 numpy array   [x, y, z, 1] x N
target.normals()        # Nx4 numpy array   [nx, ny, nz, 0] x N
target.covs()           # Array of 4x4 covariance matrices

#  Align two point clouds using specified ICP-like algorithms, utilizing point cloud and KD-tree inputs.
#
#  Parameters
#  ----------
#  target : PointCloud::ConstPtr
#      Pointer to the target point cloud.
#  source : PointCloud::ConstPtr
#      Pointer to the source point cloud.
#  target_tree : KdTree<PointCloud>::ConstPtr, optional
#      Pointer to the KD-tree of the target for nearest neighbor search. If nullptr, a new tree is built.
#  init_T_target_source : NDArray[np.float64]
#      4x4 matrix representing the initial transformation from target to source.
#  registration_type : str = 'GICP'
#      Type of registration algorithm to use ('ICP', 'PLANE_ICP', 'GICP').
#  max_correspondence_distance : float = 1.0
#      Maximum distance for corresponding point pairs.
#  num_threads : int = 1
#      Number of threads to use for computation.
# 
#  Returns
#  -------
#  RegistrationResult
#      Object containing the final transformation matrix and convergence status.
result = small_gicp.align(target, source, target_tree)

Example C : Perform each of preprocessing steps one-by-one

# Convert numpy arrays (Nx3 or Nx4) to small_gicp.PointCloud
target_raw = small_gicp.PointCloud(target_raw_numpy)
source_raw = small_gicp.PointCloud(source_raw_numpy)

# Downsampling
target = small_gicp.voxelgrid_sampling(target_raw, 0.25)
source = small_gicp.voxelgrid_sampling(source_raw, 0.25)

# KdTree construction
target_tree = small_gicp.KdTree(target)
source_tree = small_gicp.KdTree(source)

# Estimate covariances
small_gicp.estimate_covariances(target, target_tree)
small_gicp.estimate_covariances(source, source_tree)

# Align point clouds
result = small_gicp.align(target, source, target_tree)

Example D: Example with Open3D

target_o3d = open3d.io.read_point_cloud('small_gicp/data/target.ply').paint_uniform_color([0, 1, 0])
source_o3d = open3d.io.read_point_cloud('small_gicp/data/source.ply').paint_uniform_color([0, 0, 1])

target, target_tree = small_gicp.preprocess_points(numpy.asarray(target_o3d.points), downsampling_resolution=0.25)
source, source_tree = small_gicp.preprocess_points(numpy.asarray(source_o3d.points), downsampling_resolution=0.25)
result = small_gicp.align(target, source, target_tree)

source_o3d.transform(result.T_target_source)
open3d.visualization.draw_geometries([target_o3d, source_o3d])

Cookbook

Running examples

C++

cd small_gicp
mkdir build && cd build
cmake .. -DBUILD_EXAMPLES=ON && make -j

cd ..
./build/01_basic_registration
./build/02_basic_registration_pcl
./build/03_registration_template

Python

cd small_gicp
pip install .

python3 src/example/basic_registration.py

Benchmark

Processing speed comparison between small_gicp and Open3D (youtube). small_comp

Downsampling

  • Single-threaded small_gicp::voxelgrid_sampling is about 1.3x faster than pcl::VoxelGrid.
  • Multi-threaded small_gicp::voxelgrid_sampling_tbb (6 threads) is about 3.2x faster than pcl::VoxelGrid.
  • small_gicp::voxelgrid_sampling provides accurate downsampling results that are nearly identical to those of pcl::VoxelGrid, while pcl::ApproximateVoxelGrid can produce spurious points (up to 2x more points).
  • small_gicp::voxelgrid_sampling can handle larger point clouds with finer voxel resolutions compared to pcl::VoxelGrid. For a point cloud with a width of 1000m, the minimum voxel resolution can be 0.5 mm.

downsampling_comp

KdTree construction

  • Multi-threaded implementation (TBB and OMP) can be up to 6x faster than the single-threaded version. The single-thread version performs almost equivalently to nanoflann.
  • The new KdTree implementation demonstrates good scalability due to its well-balanced task assignment.
  • This benchmark compares only the construction time (query time is not included). Nearest neighbor queries are included and evaluated in the following odometry estimation evaluation.

kdtree_time

Odometry estimation

  • Single-thread small_gicp::GICP is about 2.4x and 1.9x faster than pcl::GICP and fast_gicp::GICP, respectively.
  • small_gicp::(GICP|VGICP) demonstrates better multi-threaded scalability compared to fast_gicp::(GICP|VGICP).
  • small_gicp::GICP parallelized with TBB flow graph shows excellent scalability in many-threads scenarios (~128 threads), though with some latency degradation.
  • Outputs of small_gicp::GICP are almost identical to those of fast_gicp::GICP.

odometry_time

License

This package is released under the MIT license.

If you find this package useful for your project, please consider leaving a comment here. It would help the author receive recognition in his organization and keep working on this project.

Contact

Kenji Koide, National Institute of Advanced Industrial Science and Technology (AIST)

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

small_gicp-1.0.0.tar.gz (2.6 MB view details)

Uploaded Source

Built Distributions

small_gicp-1.0.0-cp312-abi3-win_amd64.whl (223.0 kB view details)

Uploaded CPython 3.12+ Windows x86-64

small_gicp-1.0.0-cp312-abi3-manylinux_2_28_x86_64.whl (337.4 kB view details)

Uploaded CPython 3.12+ manylinux: glibc 2.28+ x86-64

small_gicp-1.0.0-cp312-abi3-manylinux_2_28_aarch64.whl (313.2 kB view details)

Uploaded CPython 3.12+ manylinux: glibc 2.28+ ARM64

small_gicp-1.0.0-cp312-abi3-macosx_11_0_arm64.whl (434.6 kB view details)

Uploaded CPython 3.12+ macOS 11.0+ ARM64

small_gicp-1.0.0-cp311-cp311-win_amd64.whl (221.2 kB view details)

Uploaded CPython 3.11 Windows x86-64

small_gicp-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl (339.1 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.28+ x86-64

small_gicp-1.0.0-cp311-cp311-manylinux_2_28_aarch64.whl (315.4 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.28+ ARM64

small_gicp-1.0.0-cp311-cp311-macosx_11_0_arm64.whl (434.4 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

small_gicp-1.0.0-cp310-cp310-win_amd64.whl (220.2 kB view details)

Uploaded CPython 3.10 Windows x86-64

small_gicp-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl (337.3 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.28+ x86-64

small_gicp-1.0.0-cp310-cp310-manylinux_2_28_aarch64.whl (313.6 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.28+ ARM64

small_gicp-1.0.0-cp310-cp310-macosx_11_0_arm64.whl (433.1 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

small_gicp-1.0.0-cp39-cp39-win_amd64.whl (216.5 kB view details)

Uploaded CPython 3.9 Windows x86-64

small_gicp-1.0.0-cp39-cp39-manylinux_2_28_x86_64.whl (338.7 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.28+ x86-64

small_gicp-1.0.0-cp39-cp39-manylinux_2_28_aarch64.whl (313.7 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.28+ ARM64

small_gicp-1.0.0-cp39-cp39-macosx_11_0_arm64.whl (433.1 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

small_gicp-1.0.0-cp38-cp38-win_amd64.whl (220.2 kB view details)

Uploaded CPython 3.8 Windows x86-64

small_gicp-1.0.0-cp38-cp38-manylinux_2_28_x86_64.whl (338.3 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.28+ x86-64

small_gicp-1.0.0-cp38-cp38-manylinux_2_28_aarch64.whl (313.6 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.28+ ARM64

small_gicp-1.0.0-cp38-cp38-macosx_11_0_arm64.whl (432.9 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

File details

Details for the file small_gicp-1.0.0.tar.gz.

File metadata

  • Download URL: small_gicp-1.0.0.tar.gz
  • Upload date:
  • Size: 2.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.5

File hashes

Hashes for small_gicp-1.0.0.tar.gz
Algorithm Hash digest
SHA256 8fa680ed19023dbd069e69ebc6c03a15ffafc97a6aa062962dcfa0acf65e5443
MD5 d72a756c7957b56a70e2df2c6b1867ef
BLAKE2b-256 c2abcfd2fdb69b49b9554640a5696b2cef5f5d65010cad522e1818fc37b45090

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp312-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a75119bbde852742b86b54cf7e35cede9ea24b6b3335b68c3bdffd6047776258
MD5 d38a488ec7ff9030054a16fafcaab373
BLAKE2b-256 c4c9a6a2ea0f2fb893fd4c213a7e285080383bbb4867331e12d1b94d6c33b5e4

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp312-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f81303a9a05ffa6609c4709f58098632f9239655d17eb66690f4d478dd3c8cb4
MD5 9e142ddb9d7e3df093cb3a0dd8be4eec
BLAKE2b-256 47802070cfeb654ef103c6b5345c5b09e3b597c6c223d170ce10900011facc60

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp312-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp312-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 dcd829e4f9c79899ee0bf47d50c93a36274d906919a90fc7f85587512f1a7654
MD5 a2204ec512e931f9caf80659b7b5f0db
BLAKE2b-256 b77b2f6a0457b51d5dc0c93bc533e8cae3932188ad084f80e159eb67483419a2

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7c9f20d05ae195695a9f76eadd9ef177d9008fb4ba21396caac95f77c8617e4c
MD5 be615f41e5c527ee362f94e0eda8adba
BLAKE2b-256 03c38f952cfd9a6abf025c2739622ba7bebf2d48fbc3212f8c9afc7121ed4e3e

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 303e4daa6e0819cef7041ff2d79d4f9edaa4cefff3eca83160b27b634ab2e5be
MD5 14ed40ce841c0c04166e029bb005c793
BLAKE2b-256 335c72c62b99275a8758cff368dda3cf31790dcfe5248e1942012a433a48966b

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 41c31e9eb0734e06cb52f4aa80a12e6057a9bfc7c2c1f6159cb2ed0bf57b5de5
MD5 5109f5e151f7921db04c03510bf1f613
BLAKE2b-256 1a773511013b533558138216578f1482d96bafc21ca5ffc312d992c50a1837f3

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d052ff22b4ac669d6dafc89aac8401b47db573d085e00ab1388dfe0544ffef56
MD5 c1316b2cc99097cc99919c8e23fac854
BLAKE2b-256 6c3075a109511f297aa160232db4bd95b6b0304e074c364546758c630e51cd83

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e88d5e407f1339c45641057a4ee63974afd6663c539f293237be7fd1d83b26d2
MD5 a9b49e9c865187eb534df005b91f08d9
BLAKE2b-256 a84d7f2a794feb84d352bd5097f3b4fa69812a13b8b3286ed8b19ec1666d9ad4

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 187dba69e4eb67db175f934453254e0ae15b5fdd1a6a9824a3ee6f42e1dcc639
MD5 834765ff315734feaf9ad0d65c5747c1
BLAKE2b-256 76b829c215197efc87355b1fffaa343556d8eb39a3d504272579c4182f3e6215

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3e41800403572bd7f1035186a44670080835e0c172dc790a8fc66935362e4f49
MD5 9a140fd3a1ee7816a3d1447ff7b884fb
BLAKE2b-256 f6957f65bfc15349d566282f1a8d885aaab1fb8ed40c732df6a3457ad47bcccb

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 069f3c3aba716f5aae4de250ca0ef0e26b6ee04efc2e192f9b3fb0be515045d5
MD5 8e01c82572d1565a9382f644062f8425
BLAKE2b-256 21ab019e24cdf30a135c467dc76a06348e407092625be45a7363825a4d5383ab

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fdb7b878091b8e98b03571a256cb240da9756752776ec3d6779b0b197c9ee5d5
MD5 0ab486de8f83ac09a2f5a10a3c3c83e7
BLAKE2b-256 b820a3a8e0ceb0a564ad90b84b504602c38fa23de2fe157e35b48231f0983b19

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: small_gicp-1.0.0-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 216.5 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.5

File hashes

Hashes for small_gicp-1.0.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 330034b6f216e75a584a3dce30695df24b2c324a0e12ab4c6c2d3be65e6b0f7f
MD5 42e8a8587a28a8b2ba1f3568feb995fe
BLAKE2b-256 fac75ec17656f007c0da9f591d76a6487db082ab54d21aaaa993b439cf92d210

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp39-cp39-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5293fa9452f0df46b6161f82db83b8df1e081675e7b80ae60975fe83bfc80fb6
MD5 834b5c568c58a995bfb241b42430afef
BLAKE2b-256 843606cd6c83a1553c296eecd5273c9d3df45c95c09274dc5cfa5bb9b3006c88

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp39-cp39-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2e1736fd1ec596cdaccbb828ce76d96b9dec5a77fd5f3f64dd066530c754441c
MD5 4f161c8fc62efdec272de114feb6e36c
BLAKE2b-256 80d33725ecdd55feb9c487dd8e5f2a3fca456aae3a29c91cad5a53b512815fe3

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cb49b3db73002838ee40c43a994ee3dafe7854992d82bd96a95e7b6af1aa6ab8
MD5 6c94d44509288210cf87b76372a7f08a
BLAKE2b-256 a9a355798b1447f596d7df2ebf123eec5787cc82612d5e35284a9919c437bfa7

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: small_gicp-1.0.0-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 220.2 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.5

File hashes

Hashes for small_gicp-1.0.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 07816f7eaff4cbb464b74406b0fdf3292b3ff34a2fbd5c4528c44d1c17c5a439
MD5 d891e17e86702d05016083c75c21866e
BLAKE2b-256 1f2defafb0507ec9b7d1d04830b2611126975b4fda10f46fe191055fa52037bb

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp38-cp38-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp38-cp38-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 530f27e359ca4619784ac88f263a8d30c10ea65537d2ff2b9fbe5a294aec2f1b
MD5 9b96d5ff7dd3a588e8db40e0252e8ea1
BLAKE2b-256 82dc7373bedc572ed7e43d735268c2d05c66979523458ca7f34266fad28601d5

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp38-cp38-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp38-cp38-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8a73233258a9ef29d85ac3ce0d881c44d69cbdf79221cb77d10393f824c561f8
MD5 c14fb5515f93ed612b83df551e197bd6
BLAKE2b-256 6c9340c32d418b8063b87a03a63cf3d303f663f2cbe4a4b79baa2d6199215475

See more details on using hashes here.

File details

Details for the file small_gicp-1.0.0-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for small_gicp-1.0.0-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5dc6ced8e901fb1a4683b5fc5be791ee0ea7ae071453803fa1f0fb624849cd86
MD5 051209076f62bbb0011b062cf3c859ab
BLAKE2b-256 0b98730639524c3135b357e55b99c9854033fb5e5d54bd227a0df2f218de5d24

See more details on using hashes here.

Supported by

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