Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Sort.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Sorter.h (C) 2000-2024 */
9/* */
10/* Algorithme de tri. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_ACCELERATOR_SORTER_H
13#define ARCANE_ACCELERATOR_SORTER_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ArrayView.h"
18#include "arcane/utils/FatalErrorException.h"
19#include "arcane/utils/NumArray.h"
20
21#include "arcane/accelerator/AcceleratorGlobal.h"
22#include "arcane/accelerator/core/RunQueue.h"
23#include "arcane/accelerator/CommonUtils.h"
24
25#include <algorithm>
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane::Accelerator::impl
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35/*!
36 * \internal
37 * \brief Classe de base pour effectuer un tri.
38 *
39 * Contient les arguments nécessaires pour effectuer le tri.
40 */
41class ARCANE_ACCELERATOR_EXPORT GenericSorterBase
42{
43 friend class GenericSorterMergeSort;
44
45 public:
46
47 explicit GenericSorterBase(const RunQueue& queue);
48
49 protected:
50
51 RunQueue m_queue;
52 GenericDeviceStorage m_algo_storage;
53};
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57/*!
58 * \internal
59 * \brief Classe pour effectuer le tri d'une liste.
60 *
61 * La classe utilisateur associée est GenericSorter
62 */
64{
65 // TODO: Faire le malloc sur le device associé à la queue.
66 // et aussi regarder si on peut utiliser mallocAsync().
67
68 public:
69
70 template <typename CompareLambda, typename InputIterator, typename OutputIterator>
71 void apply(GenericSorterBase& s, Int32 nb_item, InputIterator input_iter,
72 OutputIterator output_iter, const CompareLambda& compare_lambda)
73 {
74 RunQueue queue = s.m_queue;
75 eExecutionPolicy exec_policy = queue.executionPolicy();
76 switch (exec_policy) {
77#if defined(ARCANE_COMPILING_CUDA)
79 size_t temp_storage_size = 0;
80 cudaStream_t stream = impl::CudaUtils::toNativeStream(&queue);
81 // Premier appel pour connaitre la taille pour l'allocation
82 ARCANE_CHECK_CUDA(::cub::DeviceMergeSort::SortKeysCopy(nullptr, temp_storage_size,
83 input_iter, output_iter, nb_item,
84 compare_lambda, stream));
85
86 s.m_algo_storage.allocate(temp_storage_size);
87 ARCANE_CHECK_CUDA(::cub::DeviceMergeSort::SortKeysCopy(s.m_algo_storage.address(), temp_storage_size,
88 input_iter, output_iter, nb_item,
89 compare_lambda, stream));
90 } break;
91#endif
92#if defined(ARCANE_COMPILING_HIP)
94 size_t temp_storage_size = 0;
95 hipStream_t stream = impl::HipUtils::toNativeStream(&queue);
96 // Premier appel pour connaitre la taille pour l'allocation
97 ARCANE_CHECK_HIP(rocprim::merge_sort(nullptr, temp_storage_size, input_iter, output_iter,
98 nb_item, compare_lambda, stream));
99
100 s.m_algo_storage.allocate(temp_storage_size);
101
102 ARCANE_CHECK_HIP(rocprim::merge_sort(s.m_algo_storage.address(), temp_storage_size, input_iter, output_iter,
103 nb_item, compare_lambda, stream));
104 } break;
105#endif
107 // Pas encore implémenté en multi-thread
108 [[fallthrough]];
110 // Copie input dans output
111 auto output_iter_begin = output_iter;
112 for (Int32 i = 0; i < nb_item; ++i) {
113 *output_iter = *input_iter;
114 ++output_iter;
115 ++input_iter;
116 }
117 std::sort(output_iter_begin, output_iter, compare_lambda);
118 } break;
119 default:
120 ARCANE_FATAL(getBadPolicyMessage(exec_policy));
121 }
122 }
123};
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
128} // namespace Arcane::Accelerator::impl
129
130namespace Arcane::Accelerator
131{
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135/*!
136 * \brief Algorithme générique de tri sur accélérateur.
137 *
138 * \warning API en cours de développement. Ne pas utiliser en dehors d'Arcane
139 */
142{
143 public:
144
145 explicit GenericSorter(const RunQueue& queue)
147 {
148 }
149
150 public:
151
152 /*!
153 * \brief Tri les entités.
154 *
155 * Remplit \a output avec les valeurs de \a input triées via le comparateur
156 * par défaut pour le type \a DataType. Le tableau \a input n'est pas modifié.
157 *
158 * \pre output.size() >= input.size()
159 */
160 template <typename DataType>
162 {
163 impl::GenericSorterBase* base_ptr = this;
165 Int32 nb_item = input.size();
166 if (output.size() < nb_item)
167 ARCANE_FATAL("Output size '{0}' is smaller than input size '{1}'",
168 output.size(), nb_item);
169 auto compare_lambda = [] ARCCORE_HOST_DEVICE(const DataType& a, const DataType& b) {
170 return a < b;
171 };
172 gf.apply(*base_ptr, nb_item, input.data(), output.data(), compare_lambda);
173 }
174};
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
179} // namespace Arcane::Accelerator
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
184#endif
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Algorithme générique de tri sur accélérateur.
Definition Sort.h:142
void apply(SmallSpan< const DataType > input, SmallSpan< DataType > output)
Tri les entités.
Definition Sort.h:161
File d'exécution pour un accélérateur.
eExecutionPolicy executionPolicy() const
Politique d'exécution de la file.
Definition RunQueue.cc:168
Vue d'un tableau d'éléments de type T.
Definition Span.h:670
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:209
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:419
Espace de nom pour l'utilisation des accélérateurs.
eExecutionPolicy
Politique d'exécution pour un Runner.
@ HIP
Politique d'exécution utilisant l'environnement HIP.
@ CUDA
Politique d'exécution utilisant l'environnement CUDA.
@ Sequential
Politique d'exécution séquentielle.
@ Thread
Politique d'exécution multi-thread.
std::int32_t Int32
Type entier signé sur 32 bits.