Back to home page

EIC code displayed by LXR

 
 

    


Warning, /acts/Traccc/device/hip/src/gbts_seeding/gbts_seeding_algorithm.hip is written in an unsupported language. File is not indexed.

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 // Local include(s).
0010 #include "../utils/barrier.hpp"
0011 #include "../utils/hip_error_handling.hpp"
0012 #include "../utils/thread_id.hpp"
0013 #include "../utils/utils.hpp"
0014 #include "traccc/hip/gbts_seeding/gbts_seeding_algorithm.hpp"
0015 
0016 // Project include(s).
0017 #include "traccc/gbts_seeding/device/gbts_bid_seeds_for_hits.hpp"
0018 #include "traccc/gbts_seeding/device/gbts_bin_spacepoints.hpp"
0019 #include "traccc/gbts_seeding/device/gbts_build_edge_work_list.hpp"
0020 #include "traccc/gbts_seeding/device/gbts_compress_graph.hpp"
0021 #include "traccc/gbts_seeding/device/gbts_convert_seeds.hpp"
0022 #include "traccc/gbts_seeding/device/gbts_count_graph_edges.hpp"
0023 #include "traccc/gbts_seeding/device/gbts_count_paths.hpp"
0024 #include "traccc/gbts_seeding/device/gbts_fill_graph_edges.hpp"
0025 #include "traccc/gbts_seeding/device/gbts_fill_path_store.hpp"
0026 #include "traccc/gbts_seeding/device/gbts_find_minmax_radius.hpp"
0027 #include "traccc/gbts_seeding/device/gbts_finish_cca.hpp"
0028 #include "traccc/gbts_seeding/device/gbts_match_graph_edges.hpp"
0029 #include "traccc/gbts_seeding/device/gbts_run_cca_iteration.hpp"
0030 #include "traccc/gbts_seeding/device/gbts_sort_nodes.hpp"
0031 #include "traccc/gbts_seeding/gbts_types.hpp"
0032 
0033 // VecMem include(s).
0034 #include <vecmem/containers/data/vector_view.hpp>
0035 
0036 // (Roc)Thrust include(s).
0037 #include <thrust/execution_policy.h>
0038 #include <thrust/scan.h>
0039 #include <thrust/sort.h>
0040 
0041 // System include(s).
0042 #include <algorithm>
0043 #include <memory_resource>
0044 
0045 namespace traccc::hip {
0046 
0047 namespace kernels {
0048 
0049 using float4 = traccc::float4;
0050 using uint2 = traccc::uint2;
0051 using int2 = traccc::int2;
0052 
0053 // ---------------------------------------------------------------------------
0054 // Stage 1 — nodes-making kernels
0055 // ---------------------------------------------------------------------------
0056 
0057 /// HIP kernel for running @c traccc::device::gbts_bin_spacepoints
0058 __global__ void gbts_bin_spacepoints(
0059     const device::gbts_bin_spacepoints_payload payload) {
0060   device::gbts_bin_spacepoints(details::thread_id1{}, payload);
0061 }
0062 
0063 /// HIP kernel for running @c traccc::device::gbts_sort_nodes
0064 __global__ void gbts_sort_nodes(const device::gbts_sort_nodes_payload payload) {
0065   device::gbts_sort_nodes(details::thread_id1{}, payload);
0066 }
0067 
0068 /// HIP kernel for running @c traccc::device::gbts_find_minmax_radius
0069 __global__ void gbts_find_minmax_radius(
0070     const device::gbts_find_minmax_radius_payload payload) {
0071   device::gbts_find_minmax_radius(details::thread_id1{}, payload);
0072 }
0073 
0074 // ---------------------------------------------------------------------------
0075 // Stage 2 — graph-making kernels
0076 // ---------------------------------------------------------------------------
0077 
0078 /// HIP kernel for running @c traccc::device::gbts_build_edge_work_list
0079 __global__ void gbts_build_edge_work_list(
0080     const device::gbts_build_edge_work_list_payload payload) {
0081   __shared__ unsigned int scratch[device::gbts_build_edge_work_list_block_size];
0082   const traccc::hip::barrier barrier;
0083   device::gbts_build_edge_work_list(
0084       details::thread_id1{}, barrier, payload,
0085       {vecmem::data::vector_view<unsigned int>(
0086           device::gbts_build_edge_work_list_block_size, scratch)});
0087 }
0088 
0089 /// HIP kernel for running @c traccc::device::gbts_count_graph_edges
0090 __global__ void gbts_count_graph_edges(
0091     const device::gbts_count_graph_edges_payload payload) {
0092   device::gbts_count_graph_edges(details::thread_id1{}, payload);
0093 }
0094 
0095 /// HIP kernel for running @c traccc::device::gbts_fill_graph_edges
0096 __global__ void gbts_fill_graph_edges(
0097     const device::gbts_fill_graph_edges_payload payload) {
0098   device::gbts_fill_graph_edges(details::thread_id1{}, payload);
0099 }
0100 
0101 /// HIP kernel for running @c traccc::device::gbts_match_graph_edges
0102 __global__ void gbts_match_graph_edges(
0103     const device::gbts_match_graph_edges_payload payload) {
0104   device::gbts_match_graph_edges(details::thread_id1{}, payload);
0105 }
0106 
0107 /// HIP kernel for running @c traccc::device::gbts_compress_graph
0108 __global__ void gbts_compress_graph(
0109     const device::gbts_compress_graph_payload payload) {
0110   device::gbts_compress_graph(details::thread_id1{}, payload);
0111 }
0112 
0113 // ---------------------------------------------------------------------------
0114 // Stage 3 — graph-processing kernels
0115 // ---------------------------------------------------------------------------
0116 
0117 /// HIP kernel for running @c traccc::device::gbts_run_cca_iteration
0118 __global__ void gbts_run_cca_iteration(
0119     const device::gbts_run_cca_iteration_payload payload) {
0120   device::gbts_run_cca_iteration(details::thread_id1{}, payload);
0121 }
0122 
0123 /// HIP kernel for running @c traccc::device::gbts_finish_cca
0124 __global__ void gbts_finish_cca(const device::gbts_finish_cca_payload payload) {
0125   device::gbts_finish_cca(details::thread_id1{}, payload);
0126 }
0127 
0128 /// HIP kernel for running @c traccc::device::gbts_count_paths
0129 __global__ void gbts_count_paths(
0130     const device::gbts_count_paths_payload payload) {
0131   device::gbts_count_paths(details::thread_id1{}, payload);
0132 }
0133 
0134 /// HIP kernel for running @c traccc::device::gbts_fill_path_store
0135 __global__ void gbts_fill_path_store(
0136     const device::gbts_fill_path_store_payload payload) {
0137   device::gbts_fill_path_store(details::thread_id1{}, payload);
0138 }
0139 
0140 /// HIP kernel for running @c traccc::device::gbts_bid_seeds_for_hits
0141 __global__ void gbts_bid_seeds_for_hits(
0142     const device::gbts_bid_seeds_for_hits_payload payload) {
0143   device::gbts_bid_seeds_for_hits(details::thread_id1{}, payload);
0144 }
0145 
0146 /// HIP kernel for running @c traccc::device::gbts_convert_seeds
0147 __global__ void gbts_convert_seeds(
0148     const device::gbts_convert_seeds_payload payload) {
0149   device::gbts_convert_seeds(details::thread_id1{}, payload);
0150 }
0151 
0152 }  // namespace kernels
0153 
0154 // ===========================================================================
0155 // gbts_seeding_algorithm: kernel launchers
0156 // ===========================================================================
0157 
0158 gbts_seeding_algorithm::gbts_seeding_algorithm(
0159     const gbts_seedfinder_config& cfg, const memory_resource& mr,
0160     const vecmem::copy& copy, const stream_wrapper& str,
0161     std::unique_ptr<const Logger> logger, await_function_type await_func)
0162     : device::gbts_seeding_algorithm(cfg, mr, copy, std::move(logger)),
0163       hip::algorithm_base{str, std::move(await_func)} {}
0164 
0165 void gbts_seeding_algorithm::gbts_bin_spacepoints_kernel(
0166     const device::gbts_bin_spacepoints_payload& payload) const {
0167   const unsigned int n_threads = 128;
0168   const unsigned int n_blocks = 1 + (payload.nSp - 1) / n_threads;
0169   hipLaunchKernelGGL(kernels::gbts_bin_spacepoints, n_blocks, n_threads, 0,
0170                      details::get_stream(stream()), payload);
0171   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0172 }
0173 
0174 void gbts_seeding_algorithm::gbts_sort_nodes_kernel(
0175     const device::gbts_sort_nodes_payload& payload) const {
0176   // Order the nodes by their (eta bin, phi, spacepoint index bits) keys,
0177   // carrying the full spacepoint index along as the value.
0178   vecmem::device_vector<unsigned long long int> d_sort_keys(payload.sort_keys);
0179   vecmem::device_vector<unsigned int> d_sort_values(payload.sort_values);
0180   // Set up the Thrust execution policy. Unfortunately this has to be done in
0181   // a backend specific way. :-(
0182 #if defined(__HIP_PLATFORM_AMD__)
0183   auto policy =
0184       thrust::hip::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0185           .on(details::get_stream(stream()));
0186 #elif defined(__HIP_PLATFORM_NVIDIA__)
0187   auto policy =
0188       thrust::cuda::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0189           .on(details::get_stream(stream()));
0190 #else
0191 #error "Unrecognised HIP platform."
0192 #endif
0193   thrust::sort_by_key(policy, d_sort_keys.begin(),
0194                       d_sort_keys.begin() + static_cast<int>(payload.nSp),
0195                       d_sort_values.begin());
0196 
0197   const unsigned int n_threads = 256;
0198   const unsigned int n_blocks = 1 + (payload.nSp - 1) / n_threads;
0199   hipLaunchKernelGGL(kernels::gbts_sort_nodes, n_blocks, n_threads, 0,
0200                      details::get_stream(stream()), payload);
0201   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0202 }
0203 
0204 void gbts_seeding_algorithm::gbts_find_minmax_radius_kernel(
0205     const device::gbts_find_minmax_radius_payload& payload) const {
0206   const unsigned int n_threads = 128;
0207   const unsigned int n_blocks = 1 + (payload.nEtaBins - 1) / n_threads;
0208   hipLaunchKernelGGL(kernels::gbts_find_minmax_radius, n_blocks, n_threads, 0,
0209                      details::get_stream(stream()), payload);
0210   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0211 }
0212 
0213 void gbts_seeding_algorithm::gbts_build_edge_work_list_kernel(
0214     const device::gbts_build_edge_work_list_payload& payload) const {
0215   hipLaunchKernelGGL(kernels::gbts_build_edge_work_list, 1,
0216                      device::gbts_build_edge_work_list_block_size, 0,
0217                      details::get_stream(stream()), payload);
0218   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0219 }
0220 
0221 void gbts_seeding_algorithm::gbts_count_graph_edges_kernel(
0222     const device::gbts_count_graph_edges_payload& payload) const {
0223   // One thread per inner node of a chunk. The blocks stride over the work
0224   // items.
0225   const unsigned int n_threads = device::gbts_consts::edge_chunk_size;
0226   const unsigned int n_blocks =
0227       std::min(payload.nWorkMax, device::gbts_count_graph_edges_max_blocks);
0228   hipLaunchKernelGGL(kernels::gbts_count_graph_edges, n_blocks, n_threads, 0,
0229                      details::get_stream(stream()), payload);
0230   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0231 
0232   // Turn the per-node counts into the edge buckets.
0233   vecmem::device_vector<unsigned int> d_num_outgoing_edges(
0234       payload.num_outgoing_edges);
0235   // Set up the Thrust execution policy. Unfortunately this has to be done in
0236   // a backend specific way. :-(
0237 #if defined(__HIP_PLATFORM_AMD__)
0238   auto policy =
0239       thrust::hip::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0240           .on(details::get_stream(stream()));
0241 #elif defined(__HIP_PLATFORM_NVIDIA__)
0242   auto policy =
0243       thrust::cuda::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0244           .on(details::get_stream(stream()));
0245 #else
0246 #error "Unrecognised HIP platform."
0247 #endif
0248   thrust::inclusive_scan(policy, d_num_outgoing_edges.begin(),
0249                          d_num_outgoing_edges.end(),
0250                          d_num_outgoing_edges.begin());
0251 }
0252 
0253 void gbts_seeding_algorithm::gbts_fill_graph_edges_kernel(
0254     const device::gbts_fill_graph_edges_payload& payload) const {
0255   const unsigned int n_threads = device::gbts_consts::edge_chunk_size;
0256   const unsigned int n_blocks =
0257       std::min(payload.nWorkMax, device::gbts_fill_graph_edges_max_blocks);
0258   hipLaunchKernelGGL(kernels::gbts_fill_graph_edges, n_blocks, n_threads, 0,
0259                      details::get_stream(stream()), payload);
0260   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0261 }
0262 
0263 void gbts_seeding_algorithm::gbts_match_graph_edges_kernel(
0264     const device::gbts_match_graph_edges_payload& payload) const {
0265   const unsigned int n_threads = 256;
0266   const unsigned int n_blocks = 1u + (payload.nEdgesMax - 1u) / n_threads;
0267   hipLaunchKernelGGL(kernels::gbts_match_graph_edges, n_blocks, n_threads, 0,
0268                      details::get_stream(stream()), payload);
0269   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0270 
0271   // Compact the kept edges with a prefix sum over their 0/1 flags.
0272   // Set up the Thrust execution policy. Unfortunately this has to be done in
0273   // a backend specific way. :-(
0274 #if defined(__HIP_PLATFORM_AMD__)
0275   auto policy =
0276       thrust::hip::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0277           .on(details::get_stream(stream()));
0278 #elif defined(__HIP_PLATFORM_NVIDIA__)
0279   auto policy =
0280       thrust::cuda::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0281           .on(details::get_stream(stream()));
0282 #else
0283 #error "Unrecognised HIP platform."
0284 #endif
0285   thrust::inclusive_scan(policy, payload.kept.ptr(),
0286                          payload.kept.ptr() + payload.nEdgesMax,
0287                          payload.reIndexer.ptr());
0288 }
0289 
0290 void gbts_seeding_algorithm::gbts_compress_graph_kernel(
0291     const device::gbts_compress_graph_payload& payload) const {
0292   const unsigned int n_threads = 256;
0293   const unsigned int n_blocks = 1u + (payload.nEdgesMax - 1u) / n_threads;
0294   hipLaunchKernelGGL(kernels::gbts_compress_graph, n_blocks, n_threads, 0,
0295                      details::get_stream(stream()), payload);
0296   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0297 }
0298 
0299 void gbts_seeding_algorithm::gbts_run_cca_iteration_kernel(
0300     const device::gbts_run_cca_iteration_payload& payload) const {
0301   const unsigned int n_threads = 256;
0302   const unsigned int n_blocks = 1 + (payload.nConnectedEdges - 1) / n_threads;
0303   hipLaunchKernelGGL(kernels::gbts_run_cca_iteration, n_blocks, n_threads, 0,
0304                      details::get_stream(stream()), payload);
0305   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0306 }
0307 
0308 void gbts_seeding_algorithm::gbts_finish_cca_kernel(
0309     const device::gbts_finish_cca_payload& payload) const {
0310   const unsigned int n_threads = 256;
0311   const unsigned int n_blocks = 1 + (payload.nConnectedEdges - 1) / n_threads;
0312   hipLaunchKernelGGL(kernels::gbts_finish_cca, n_blocks, n_threads, 0,
0313                      details::get_stream(stream()), payload);
0314   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0315 }
0316 
0317 void gbts_seeding_algorithm::gbts_count_paths_kernel(
0318     const device::gbts_count_paths_payload& payload) const {
0319   const unsigned int n_threads = 128;
0320   const unsigned int n_blocks = 1 + (payload.nConnectedEdges - 1) / n_threads;
0321   hipLaunchKernelGGL(kernels::gbts_count_paths, n_blocks, n_threads, 0,
0322                      details::get_stream(stream()), payload);
0323   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0324 
0325   // Path offsets of the path store.
0326   vecmem::device_vector<unsigned int> d_path_counts(payload.path_counts);
0327   // Set up the Thrust execution policy. Unfortunately this has to be done in
0328   // a backend specific way. :-(
0329 #if defined(__HIP_PLATFORM_AMD__)
0330   auto policy =
0331       thrust::hip::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0332           .on(details::get_stream(stream()));
0333 #elif defined(__HIP_PLATFORM_NVIDIA__)
0334   auto policy =
0335       thrust::cuda::par_nosync(std::pmr::polymorphic_allocator(&(mr().main)))
0336           .on(details::get_stream(stream()));
0337 #else
0338 #error "Unrecognised HIP platform."
0339 #endif
0340   thrust::inclusive_scan(policy, d_path_counts.begin(),
0341                          d_path_counts.begin() + payload.nConnectedEdges,
0342                          d_path_counts.begin());
0343 }
0344 
0345 void gbts_seeding_algorithm::gbts_fill_path_store_kernel(
0346     const device::gbts_fill_path_store_payload& payload) const {
0347   const unsigned int n_threads = 128;
0348   const unsigned int n_blocks = 1 + (payload.nPathsGrid - 1) / n_threads;
0349   hipLaunchKernelGGL(kernels::gbts_fill_path_store, n_blocks, n_threads, 0,
0350                      details::get_stream(stream()), payload);
0351   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0352 }
0353 
0354 void gbts_seeding_algorithm::gbts_bid_seeds_for_hits_kernel(
0355     const device::gbts_bid_seeds_for_hits_payload& payload) const {
0356   const unsigned int n_threads = 128;
0357   const unsigned int n_blocks = 1 + (payload.nPathsGrid - 1) / n_threads;
0358   hipLaunchKernelGGL(kernels::gbts_bid_seeds_for_hits, n_blocks, n_threads, 0,
0359                      details::get_stream(stream()), payload);
0360   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0361 }
0362 
0363 void gbts_seeding_algorithm::gbts_convert_seeds_kernel(
0364     const device::gbts_convert_seeds_payload& payload) const {
0365   const unsigned int n_threads = 128;
0366   const unsigned int n_blocks = 1 + (payload.nPathsGrid - 1) / n_threads;
0367   hipLaunchKernelGGL(kernels::gbts_convert_seeds, n_blocks, n_threads, 0,
0368                      details::get_stream(stream()), payload);
0369   TRACCC_HIP_ERROR_CHECK(hipGetLastError());
0370 }
0371 
0372 void gbts_seeding_algorithm::synchronize() const {
0373   stream().synchronize();
0374 }
0375 
0376 }  // namespace traccc::hip