From 97b2f2e606a92d36d74c6c30ff6d5da12690707b Mon Sep 17 00:00:00 2001 From: ZCWang <1627343141@qq.com> Date: Sun, 20 Oct 2024 23:27:00 +0800 Subject: [PATCH] fully implementation of LUT. Since it is confirmed that use constexpr will blow-up the stack of compilers, we have to use an init function to read LUT from disk. TODO: write a simple program to confirm that the init LUT function works properly. --- implicit_arrangements/include/lut.hpp | 4 +- .../interface/implicit_arrangement.h | 1 + implicit_arrangements/src/lut.cpp | 123 ++++++++++++++++++ implicit_arrangements/test_lut/main.cpp | 0 implicit_arrangements/xmake.lua | 13 +- 5 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 implicit_arrangements/test_lut/main.cpp diff --git a/implicit_arrangements/include/lut.hpp b/implicit_arrangements/include/lut.hpp index 01997e9..c2d7e63 100644 --- a/implicit_arrangements/include/lut.hpp +++ b/implicit_arrangements/include/lut.hpp @@ -5,8 +5,8 @@ #include // Lookup table for simplicial arrangement -extern std::vector ia_data; -extern std::vector ia_indices; +extern std::vector ia_data; +extern std::vector ia_indices; // For 1 plane arrangement lookup. uint32_t ia_compute_outer_index(const Plane3D& p0); diff --git a/implicit_arrangements/interface/implicit_arrangement.h b/implicit_arrangements/interface/implicit_arrangement.h index 28eee72..4add639 100644 --- a/implicit_arrangements/interface/implicit_arrangement.h +++ b/implicit_arrangements/interface/implicit_arrangement.h @@ -98,6 +98,7 @@ struct Arrangement3DResult { bool is_runtime_computed; }; +EXTERN_C API bool load_lut(); EXTERN_C API Arrangement2DResult compute_arrangement_2d(const Plane2D* planes, const uint32_t num_planes); EXTERN_C API Arrangement3DResult compute_arrangement_3d(const Plane3D* planes, const uint32_t num_planes); EXTERN_C API void free_arrangement_2d(Arrangement2DResult* arr); diff --git a/implicit_arrangements/src/lut.cpp b/implicit_arrangements/src/lut.cpp index 754d99a..023178d 100644 --- a/implicit_arrangements/src/lut.cpp +++ b/implicit_arrangements/src/lut.cpp @@ -1,9 +1,132 @@ #include +#include +#include #include +#include +#include #include "lut.hpp" #include "common_structure.hpp" +#include "implicit_arrangement.h" + +/* POD data of ia_data */ +std::vector ia_vertices{}; +std::vector> ia_face_vertices{}; +std::vector ia_faces_ptr{}; +std::vector ia_face_vertices_count{}; +std::vector ia_supporting_planes{}; +std::vector ia_positive_cells{}; +std::vector ia_negative_cells{}; +std::vector> ia_cell_faces{}; +std::vector ia_cells_ptr{}; +std::vector ia_cell_faces_count{}; +std::vector ia_num_vertices{}; +std::vector ia_num_faces{}; +std::vector ia_num_cells{}; +/* global variables */ +std::vector ia_data{}; +std::vector ia_indices{}; + +inline void from_json(const nlohmann::json& j, Point3D& p) +{ + p.i0 = j[0].get(); + p.i1 = j[1].get(); + p.i2 = j[2].get(); +} + +inline void parse_ia_into_pods(const nlohmann::json& j) +{ + const auto& vertices = j[0].get>(); + ia_num_vertices.emplace_back(vertices.size()); + ia_vertices.insert(ia_vertices.end(), vertices.begin(), vertices.end()); + assert(ia_num_vertices.back() > 0); + + ia_num_faces.emplace_back(j[1].size()); + for (const auto& face_entry : j[1]) { + ia_face_vertices_count.emplace_back(face_entry[0].size()); + ia_face_vertices.emplace_back(face_entry[0].get>()); + ia_faces_ptr.emplace_back(ia_face_vertices.back().data()); + ia_supporting_planes.emplace_back(face_entry[1].get()); + ia_positive_cells.emplace_back(face_entry[2].get()); + ia_negative_cells.emplace_back(face_entry[3].get()); + } + assert(ia_num_faces.back() > 0); + + ia_num_cells.emplace_back(j[2].size()); + for (const auto& cell_entry : j[2]) { + ia_cell_faces_count.emplace_back(cell_entry.size()); + ia_cell_faces.emplace_back(cell_entry.get>()); + ia_cells_ptr.emplace_back(ia_cell_faces.back().data()); + } + assert(ia_num_cells.back() > 0); +} + +EXTERN_C API bool load_lut() +{ + if (!ia_data.empty() && !ia_indices.empty()) return true; + + auto deserialize_ia = [](const nlohmann::json& json) { + auto& ia = ia_data.emplace_back(Arrangement3D{}); + const auto& vertices = json[0].get>(); + }; + + auto t0 = tbb::tick_count::now(); + + std::ifstream file("ia_lut.msgpack", std::ios::in | std::ios::binary); + if (!file.is_open()) { + std::cerr << "Error: IA LUT file does not exist!" << std::endl; + return false; + } + std::vector msgpack(std::istreambuf_iterator(file), {}); + nlohmann::json json = nlohmann::json::from_msgpack(msgpack); + file.close(); + + ia_indices = json["start_index"].get>(); + /* a tet has at least 4 vertices and 4 faces, and we'll use this assumption to reverse space for POD data */ + ia_vertices.reserve(json["data"].size() * 4); + ia_face_vertices.reserve(json["data"].size() * 4 * 3); // 3 vertices per triangle face + ia_faces_ptr.reserve(json["data"].size() * 4); + ia_face_vertices_count.reserve(json["data"].size() * 4); + ia_supporting_planes.reserve(json["data"].size() * 4); + ia_positive_cells.reserve(json["data"].size() * 4); + ia_negative_cells.reserve(json["data"].size() * 4); + ia_cell_faces.reserve(json["data"].size() * 4); + ia_cells_ptr.reserve(json["data"].size()); + ia_cell_faces_count.reserve(json["data"].size()); + ia_num_vertices.reserve(json["data"].size()); + ia_num_faces.reserve(json["data"].size()); + ia_num_cells.reserve(json["data"].size()); + + // HINT: change of capcity may happen here. + for (const auto& entry : json["data"]) parse_ia_into_pods(entry); + + ia_data.resize(json["data"].size()); + uint32_t vertices_offset{}, faces_offset{}, cells_offset{}; + for (size_t i = 0; i < json["data"].size(); i++) { + auto& ia = ia_data[i]; + + ia.num_vertices = ia_num_vertices[i]; + ia.points = ia_vertices.data() + vertices_offset; + + ia.num_faces = ia_num_faces[i]; + ia.vertices = ia_faces_ptr.data() + faces_offset; + ia.edge_vertices_count = ia_face_vertices_count.data() + faces_offset; + ia.supporting_planes = ia_supporting_planes.data() + faces_offset; + ia.positive_cells = ia_positive_cells.data() + faces_offset; + ia.negative_cells = ia_negative_cells.data() + faces_offset; + + ia.num_cells = ia_num_cells[i]; + ia.faces = ia_cells_ptr.data() + cells_offset; + ia.cell_faces_count = ia_cell_faces_count.data() + cells_offset; + + ia.num_unique_planes = 0; + } + + auto t1 = tbb::tick_count::now(); + std::cout << "Loading LUT took " << std::fixed << std::setprecision(10) << (t1 - t0).seconds() << " seconds." << std::endl; + return true; +} uint32_t ia_compute_outer_index(const Plane3D& p0) { diff --git a/implicit_arrangements/test_lut/main.cpp b/implicit_arrangements/test_lut/main.cpp new file mode 100644 index 0000000..e69de29 diff --git a/implicit_arrangements/xmake.lua b/implicit_arrangements/xmake.lua index 84c141a..c1c5eb5 100644 --- a/implicit_arrangements/xmake.lua +++ b/implicit_arrangements/xmake.lua @@ -1,4 +1,4 @@ --- add_requires("nlohmann_json") +add_requires("nlohmann_json") target("implicit_arrangements") add_rules("library.shared") @@ -8,7 +8,7 @@ target("implicit_arrangements") add_includedirs("./interface", {public = true}) add_includedirs("./include") add_files("./src/*.cpp") - -- add_packages("nlohmann_json") + add_packages("nlohmann_json") target_end() -- target("implicit_arrangements.LUT.generator") @@ -19,4 +19,11 @@ target_end() -- add_includedirs("./include", "./interface") -- add_files("./src/lut_generator.cpp") -- add_packages("nlohmann_json") --- target_end() \ No newline at end of file +-- target_end() + +target("implicit_arrangements.LUT.load_test") + set_kind("binary") + add_rules("config.indirect_predicates.flags") + add_deps("implicit_arrangements") + add_files("./test_lut/main.cpp") +target_end() \ No newline at end of file