Simplify MC C++ hashing logic

Summary: To be consistent with CUDA hashing, the diff replaces boost hasher with a simplified hasher for storing unique global edge_ids.

Reviewed By: kjchalup

Differential Revision: D41140382

fbshipit-source-id: 2ce598e5edcf6369fe13bd15d1f5e014b252027b
This commit is contained in:
Jiali Duan 2022-11-15 19:42:04 -08:00 committed by Facebook GitHub Bot
parent 8b8291830e
commit 1706eb8216
2 changed files with 12 additions and 40 deletions

View File

@ -36,8 +36,6 @@ std::tuple<at::Tensor, at::Tensor, at::Tensor> MarchingCubesCpu(
// Create tensor accessors // Create tensor accessors
auto vol_a = vol.accessor<float, 3>(); auto vol_a = vol.accessor<float, 3>();
// vpair_to_edge maps a pair of vertex ids to its corresponding edge id
std::unordered_map<std::pair<int, int>, int64_t> vpair_to_edge;
// edge_id_to_v maps from an edge id to a vertex position // edge_id_to_v maps from an edge id to a vertex position
std::unordered_map<int64_t, Vertex> edge_id_to_v; std::unordered_map<int64_t, Vertex> edge_id_to_v;
// uniq_edge_id: used to remove redundant edge ids // uniq_edge_id: used to remove redundant edge ids
@ -64,12 +62,7 @@ std::tuple<at::Tensor, at::Tensor, at::Tensor> MarchingCubesCpu(
const int e = _FACE_TABLE[cube.cubeindex][j]; const int e = _FACE_TABLE[cube.cubeindex][j];
interp_points[e] = cube.VertexInterp(isolevel, e, vol_a); interp_points[e] = cube.VertexInterp(isolevel, e, vol_a);
auto vpair = cube.GetVPairFromEdge(e, W, H); int64_t edge = cube.HashVpair(e, W, H, D);
if (!vpair_to_edge.count(vpair)) {
vpair_to_edge[vpair] = vpair_to_edge.size();
}
int64_t edge = vpair_to_edge[vpair];
tri.push_back(edge); tri.push_back(edge);
ps.push_back(interp_points[e]); ps.push_back(interp_points[e]);

View File

@ -122,45 +122,24 @@ struct Cube {
return p1 * (1 - ratio) + p2 * ratio; return p1 * (1 - ratio) + p2 * ratio;
} }
// Get a tuple of global vertex ID from a local edge ID // Hash an edge into a global edge_id. The function binds an
// Global vertex ID is calculated as (x + dx) + (y + dy) * W + (z + dz) * W * // edge with an integer to address floating point precision issue.
// H //
// Args: // Args:
// edge: local edge ID in the cube // v1_id: global id of vertex 1
// W: width of x dimension // v2_id: global id of vertex 2
// H: height of y dimension // W: width of the 3d grid
// H: height of the 3d grid
// D: depth of the 3d grid
// //
// Returns: // Returns:
// a pair of global vertex ID // hashing for a pair of vertex ids
// //
std::pair<int, int> GetVPairFromEdge(const int edge, int W, int H) { int64_t HashVpair(const int edge, int W, int H, int D) {
const int v1 = _EDGE_TO_VERTICES[edge][0]; const int v1 = _EDGE_TO_VERTICES[edge][0];
const int v2 = _EDGE_TO_VERTICES[edge][1]; const int v2 = _EDGE_TO_VERTICES[edge][1];
const int v1_id = p[v1].x + p[v1].y * W + p[v1].z * W * H; const int v1_id = p[v1].x + p[v1].y * W + p[v1].z * W * H;
const int v2_id = p[v2].x + p[v2].y * W + p[v2].z * W * H; const int v2_id = p[v2].x + p[v2].y * W + p[v2].z * W * H;
return std::make_pair(v1_id, v2_id); return (int64_t)v1_id * (W + W * H + W * H * D) + (int64_t)v2_id;
} }
}; };
// helper functions for hashing
namespace std {
// Taken from boost library to combine several hash functions
template <class T>
inline void hash_combine(size_t& s, const T& v) {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
// Function for hashing a pair of vertices
template <>
struct hash<std::pair<int, int>> {
size_t operator()(const std::pair<int, int>& p) const {
size_t res = 0;
hash_combine(res, p.first);
hash_combine(res, p.second);
return res;
}
};
} // namespace std