/**************************************************************************** * Copyright (c) 2017-2023 by the ArborX authors * * All rights reserved. * * * * This file is part of the ArborX library. ArborX is * * distributed under a BSD 3-clause license. For the licensing terms see * * the LICENSE file in the top-level directory. * * * * SPDX-License-Identifier: BSD-3-Clause * ****************************************************************************/ #ifndef ARBORX_DETAILS_DENDROGRAM_HPP #define ARBORX_DETAILS_DENDROGRAM_HPP #include // iota #include #include namespace ArborX::Details { struct UnweightedEdge { int source; int target; }; template void dendrogramUnionFindHost(Edges sorted_edges_host, Parents &parents_host) { Kokkos::Profiling::pushRegion( "ArborX::Dendrogram::dendrogram_union_find::union_find_host"); using ExecutionSpace = Kokkos::DefaultHostExecutionSpace; ExecutionSpace host_space; int const num_edges = sorted_edges_host.size(); int const num_vertices = num_edges + 1; auto const vertices_offset = num_edges; Kokkos::View labels( Kokkos::view_alloc(Kokkos::WithoutInitializing, "ArborX::Dendrogram::dendrogram_union_find::labels"), num_vertices); KokkosExt::iota(host_space, labels); UnionFind union_find(labels); Kokkos::View set_edges_host( Kokkos::view_alloc(host_space, Kokkos::WithoutInitializing, "ArborX::Dendrogram::labels"), num_vertices); constexpr int UNDEFINED = -1; Kokkos::deep_copy(host_space, set_edges_host, UNDEFINED); // Fence all execution spaces to make sure all the data is ready Kokkos::fence("ArborX::Dendrogram::dendrogramUnionFindHost" " (global fence before performing union-find on host)"); Kokkos::Profiling::pushRegion( "ArborX::Dendrogram::dendrogram_union_find::union_find"); for (int e = 0; e < num_edges; ++e) { int i = union_find.representative(sorted_edges_host(e).source); int j = union_find.representative(sorted_edges_host(e).target); for (int k : {i, j}) { auto edge_child = set_edges_host(k); if (edge_child != UNDEFINED) parents_host(edge_child) = e; else parents_host(vertices_offset + k) = e; } union_find.merge(i, j); set_edges_host(union_find.representative(i)) = e; } parents_host(num_edges - 1) = -1; // root Kokkos::Profiling::popRegion(); Kokkos::Profiling::popRegion(); } template void dendrogramUnionFind( ExecutionSpace const &exec_space, Kokkos::View sorted_edges, Kokkos::View &parents) { Kokkos::Profiling::pushRegion("ArborX::Dendrogram::dendrogram_union_find"); Kokkos::Profiling::pushRegion( "ArborX::Dendrogram::dendrogram_union_find::copy_to_host"); auto sorted_edges_host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, sorted_edges); auto parents_host = Kokkos::create_mirror_view( Kokkos::view_alloc(Kokkos::WithoutInitializing), parents); Kokkos::Profiling::popRegion(); Kokkos::Profiling::pushRegion( "ArborX::Dendrogram::dendrogram_union_find::union_find"); dendrogramUnionFindHost(sorted_edges_host, parents_host); Kokkos::Profiling::popRegion(); Kokkos::Profiling::pushRegion( "ArborX::Dendrogram::dendrogram_union_find::copy_to_device"); Kokkos::deep_copy(exec_space, parents, parents_host); Kokkos::Profiling::popRegion(); Kokkos::Profiling::popRegion(); } } // namespace ArborX::Details #endif