{"id":13686287,"url":"https://github.com/morton-nd/morton-nd","last_synced_at":"2025-05-01T09:30:51.793Z","repository":{"id":49159599,"uuid":"138655970","full_name":"morton-nd/morton-nd","owner":"morton-nd","description":"A header-only compile-time Morton encoding / decoding library for N dimensions.","archived":false,"fork":false,"pushed_at":"2023-06-12T13:00:45.000Z","size":139,"stargazers_count":98,"open_issues_count":5,"forks_count":5,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-11-12T09:48:19.897Z","etag":null,"topics":["bmi2","coding","decoding","dimensions","encoding","lookup-table","lut","morton","morton-code","morton-encoding-library","morton-order","multiple"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/morton-nd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-25T22:20:30.000Z","updated_at":"2024-10-28T00:19:34.000Z","dependencies_parsed_at":"2024-11-12T09:42:27.605Z","dependency_job_id":null,"html_url":"https://github.com/morton-nd/morton-nd","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morton-nd%2Fmorton-nd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morton-nd%2Fmorton-nd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morton-nd%2Fmorton-nd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morton-nd%2Fmorton-nd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/morton-nd","download_url":"https://codeload.github.com/morton-nd/morton-nd/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251852639,"owners_count":21654440,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bmi2","coding","decoding","dimensions","encoding","lookup-table","lut","morton","morton-code","morton-encoding-library","morton-order","multiple"],"created_at":"2024-08-02T15:00:27.640Z","updated_at":"2025-05-01T09:30:51.504Z","avatar_url":"https://github.com/morton-nd.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"z-order.png\" alt=\"Z-Order Curve\" height=\"250\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eMorton ND\u003c/h1\u003e\n\nA header-only Morton encode/decode library (C++14) capable of encoding from and decoding to N-dimensional space.\n\nAll algorithms are **generated** at compile-time for the number of dimensions and field width used. This way, loops and branches are not required.\n\nIncludes a hardware-based approach (using Intel BMI2) for most Intel CPUs, as well as another fast approach based on Lookup Table (LUT) methods for other CPU variants. \n\n### Status\n[![Build Status](https://github.com/kevinhartman/morton-nd/actions/workflows/cmake.yml/badge.svg)](https://github.com/kevinhartman/morton-nd/actions/workflows/cmake.yml) [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://opensource.org/licenses/MIT)\n\n## Features\n\n### Encode/Decode Support\n- any number of dimensions (e.g. `2D, 3D, 4D ... ND`).\n- built-in support for up to 128-bit native results (`__uint128_t`). Unlimited using a user-supplied \"big integer\" class (not yet tested).\n- `constexpr` encoding and decoding, allowing Morton coding to be expressed at compile-time.\n\n## Encoders and Decoders\n\n### Hardware (Intel BMI2)\nSupports encoding and decoding in N dimensions, using Intel's BMI2 ISA extension (available in Haswell (Intel), Excavator (AMD) and newer).\n\nSee the [Morton ND BMI2 Usage Guide](docs/MortonND_BMI2.md) for details.\n\n```c++\nusing MortonND_4D = mortonnd::MortonNDBmi\u003c4, uint64_t\u003e;\n\n// Encodes 4 fields into a uint64_t result.\nauto encoding = MortonND_4D::Encode(f1, f2, f3, f4);\n\n// Decodes 4 fields.\nstd::tie(f1, f2, f3, f4) = MortonND_4D::Decode(encoding);\n```\n\n### Lookup Table (LUT)\nSupports encoding and decoding in N dimensions, using compiler-generated LUTs.\n\nLUTs are defined with constant expressions and thus can be generated (and even used) at compile-time.\n\nBoth the encoder and decoder support chunking, allowing a LUT smaller than the input field width when encoding, or smaller than the Morton code width when decoding, to be used internally. This is useful for applications which require faster compilation times and smaller binaries (at the expense of extra bit manipulation operations required to combine chunks at runtime).\n\nSee the [Morton ND LUT Usage Guide](docs/MortonND_LUT.md) for details.\n\n#### Encoding\n```c++\n// Generates a 4D LUT encoder (4 fields, 16 bits each, 8-bit LUT) using the compiler.\nconstexpr auto MortonND_4D_Enc = mortonnd::MortonNDLutEncoder\u003c4, 16, 8\u003e();\n\n// Encodes 4 fields. Can be done at run-time or compile-time.\nauto encoding = MortonND_4D_Enc.Encode(f1, f2, f3, f4);\n```\n\n#### Decoding\n```c++\n// Generates a 4D LUT decoder (4 fields, 16 bits each, 8-bit LUT) using the compiler.\nconstexpr auto MortonND_4D_Dec = mortonnd::MortonNDLutDecoder\u003c4, 16, 8\u003e();\n\n// Decodes 4 fields. Can be done at run-time or compile-time (just not with std::tie in C++14).\nstd::tie(f1, f2, f3, f4) = MortonND_4D_Dec.Decode(encoding);\n```\n\n## Testing and Performance\nValidation testing specific to MortonND is located in the `/tests` folder, covering N-dimensional configurations where `N ∈ { 1, 2, 3, 4, 5, 8, 16, 32, 64 }` for common field sizes, and is run as part of Travis CI.\n\nPerformance benchmark tests (and additional validation) for 2D and 3D use cases are located in a separate repository. See [this fork](https://github.com/kevinhartman/libmorton#fork-changes) of @Forceflow's [Libmorton](https://github.com/Forceflow/libmorton), which integrates Morton ND into Libmorton's existing test framework.\n\n### Benchmarks\nThe snippets below show performance comparisons between various 3D configurations of Morton ND. Comparisons to the 3D algorithms found in Libmorton are also included to demonstrate that Morton ND's generated algorithms are as efficient as hand-coded algorithms.\n\nTo run these tests (and more!) on your own machine, clone the fork linked above.\n\nThe following metrics (sorted by random access time, ascending) were collected on an I9-9980HK, compiled with GCC 11.1.0 on macOS 11.1 using `-O3 -DNDEBUG`. Results include data from both linearly increasing and random inputs to demonstrate the performance impact of cache (hit or miss) under each algorithm / configuration. Results are averaged over 5 runs (each algorithm is run 5 times consecutively before moving on to the next).\n\n#### 32-bit\n```\n++ Running each performance test 5 times and averaging results\n++ Encoding 512^3 morton codes (134217728 in total)\n\n    Linear      Random\n    ======      ======\n    524.178 ms  515.768 ms : 32-bit (MortonND)    LUT: 1 chunks, 10 bit LUT\n    530.421 ms  536.726 ms : 32-bit (lib-morton)  BMI2 instruction set\n    539.061 ms  530.954 ms : 32-bit (MortonND)    BMI2\n    629.888 ms  628.029 ms : 32-bit (lib-morton)  LUT Shifted\n    647.075 ms  646.281 ms : 32-bit (MortonND)    LUT: 2 chunks, 8 bit LUT\n    658.859 ms  667.313 ms : 32-bit (MortonND)    LUT: 2 chunks, 5 bit LUT\n    668.371 ms  665.673 ms : 32-bit (lib-morton)  LUT\n    \n++ Decoding 512^3 morton codes (134217728 in total)\n\n    Linear      Random\n    ======      ======\n    560.478 ms  3159.143 ms : 32-bit (lib-morton)  BMI2 Instruction set\n    569.632 ms  3188.762 ms : 32-bit (MortonND)    MortonND: BMI2\n    807.765 ms  3386.069 ms : 32-bit (MortonND)    LUT: 3 chunks, 10 bit LUT\n    870.854 ms  3479.404 ms : 32-bit (lib-morton)  LUT Shifted\n    902.272 ms  3516.063 ms : 32-bit (MortonND)    LUT: 4 chunks, 8 bit LUT\n    1033.880 ms 3605.081 ms : 32-bit (lib-morton)  LUT\n    1162.954 ms 3755.352 ms : 32-bit (MortonND)    LUT: 6 chunks, 5 bit LUT\n```\n\n#### 64-bit\n```\n++ Running each performance test 5 times and averaging results\n++ Encoding 512^3 morton codes (134217728 in total)\n\n    Linear      Random\n    ======      ======\n    524.044 ms  563.434 ms : 64-bit (lib-morton)  BMI2 instruction set\n    536.608 ms  587.632 ms : 64-bit (MortonND)    BMI2\n    632.564 ms  639.866 ms : 64-bit (MortonND)    LUT: 2 chunks, 11 bit LUT\n    812.262 ms  817.026 ms : 64-bit (MortonND)    LUT: 3 chunks, 8 bit LUT\n    812.683 ms  823.962 ms : 64-bit (MortonND)    LUT: 3 chunks, 7 bit LUT\n    828.591 ms  845.098 ms : 64-bit (lib-morton)  LUT Shifted\n    612.973 ms  863.919 ms : 64-bit (MortonND)    LUT: 2 chunks, 16 bit LUT\n    909.336 ms  929.829 ms : 64-bit (lib-morton)  LUT\n    516.114 ms 1003.164 ms : 64-bit (MortonND)    LUT: 1 chunks, 21 bit LUT\n    \n++ Decoding 512^3 morton codes (134217728 in total)\n\n    Linear      Random\n    ======      ======\n    575.827 ms  3195.522 ms : 64-bit (MortonND)    BMI2\n    560.200 ms  3204.435 ms : 64-bit (lib-morton)  BMI2 Instruction set\n    932.061 ms  3600.856 ms : 64-bit (MortonND)    LUT: 4 chunks, 16 bit LUT\n    1164.335 ms 3758.155 ms : 64-bit (MortonND)    LUT: 6 chunks, 11 bit LUT\n    1300.058 ms 3912.560 ms : 64-bit (lib-morton)  LUT Shifted\n    1518.749 ms 4144.474 ms : 64-bit (MortonND)    LUT: 9 chunks, 7 bit LUT\n    1387.119 ms 4039.352 ms : 64-bit (MortonND)    LUT: 8 chunks, 8 bit LUT\n    1564.913 ms 4150.859 ms : 64-bit (lib-morton)  LUT\n    833.821 ms  4496.993 ms : 64-bit (MortonND)    LUT: 3 chunks, 21 bit LUT\n```\n\n## Installation\n### CMake\nMorton ND provides a CMake integration, making it easy to use from your CMake project.\n\n#### Adding the dependency\nIf you've installed Morton ND to your `CMAKE_MODULE_PATH` (e.g. with [vcpkg](https://github.com/microsoft/vcpkg)), find and link it like this:\n\n```cmake\nfind_package(morton-nd CONFIG REQUIRED)\ntarget_link_libraries(main PRIVATE morton-nd::MortonND)\n```\n\nOtherwise, if you're using Morton ND as a Git submodule:\n```cmake\nadd_subdirectory(morton-nd)\ntarget_link_libraries(main PRIVATE morton-nd::MortonND)\n```\n\n#### Including library headers\nBy using `target_link_libraries(...)` as above, Morton ND's headers will be automatically available for use by your target:\n\n```c++\n// main.cpp\n#include \u003cmorton-nd/mortonND_BMI2.h\u003e\n#include \u003cmorton-nd/mortonND_LUT.h\u003e\n```\n\n## Thanks\n* Jeroen Baert (@Forceflow)\n  - [Morton encoding/decoding through bit interleaving: Implementations](https://www.forceflow.be/2013/10/07/morton-encodingdecoding-through-bit-interleaving-implementations/)\n  - [libmorton](https://github.com/Forceflow/libmorton), a C++11 header-only library for 2D and 3D Morton encoding and decoding.\n\n## License\nThis project is licensed under the MIT license.\n\nAttribution is appreciated where applicable, and as such, a NOTICE file is included which may be distributed in the credits of derivative software.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorton-nd%2Fmorton-nd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorton-nd%2Fmorton-nd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorton-nd%2Fmorton-nd/lists"}