Arcane  v3.15.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
GenericFilterer.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/* GenericFilterer.h (C) 2000-2024 */
9/* */
10/* Algorithme de filtrage. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_ACCELERATOR_GENERICFILTERER_H
13#define ARCANE_ACCELERATOR_GENERICFILTERER_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ArrayView.h"
18#include "arcane/utils/FatalErrorException.h"
19#include "arcane/utils/NumArray.h"
20#include "arcane/utils/TraceInfo.h"
21
22#include "arcane/accelerator/core/RunQueue.h"
23
24#include "arcane/accelerator/AcceleratorGlobal.h"
25#include "arcane/accelerator/CommonUtils.h"
26#include "arcane/accelerator/RunCommandLaunchInfo.h"
28#include "arcane/accelerator/ScanImpl.h"
29#include "arcane/accelerator/MultiThreadAlgo.h"
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::Accelerator::impl
35{
36//#define ARCANE_USE_SCAN_ONEDPL
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40/*!
41 * \internal
42 * \brief Classe de base pour effectuer un filtrage.
43 *
44 * Contient les arguments nécessaires pour effectuer le filtrage.
45 */
46class ARCANE_ACCELERATOR_EXPORT GenericFilteringBase
47{
48 template <typename DataType, typename FlagType, typename OutputDataType>
49 friend class GenericFilteringFlag;
50 friend class GenericFilteringIf;
51 friend class SyclGenericFilteringImpl;
52
53 public:
54
55
56 protected:
57
59
60 protected:
61
62 Int32 _nbOutputElement() const;
63 void _allocate();
64 void _allocateTemporaryStorage(size_t size);
65 int* _getDeviceNbOutPointer();
66 void _copyDeviceNbOutToHostNbOut();
67
68 protected:
69
70 //! File d'exécution. Ne doit pas être nulle.
72 // Mémoire de travail pour l'algorithme de filtrage.
73 GenericDeviceStorage m_algo_storage;
74 //! Mémoire sur le device du nombre de valeurs filtrées
76 //! Mémoire hôte pour le nombre de valeurs filtrées
78 /*!
79 * \brief Indique quelle mémoire est utilisée pour le nombre de valeurs filtrées.
80 *
81 * Si vrai utilise directement \a m_host_nb_out_storage. Sinon, utilise
82 * m_device_nb_out_storage et fait une copie asynchrone après le filtrage pour
83 * recopier la valeur dans m_host_nb_out_storage.
84 */
85 bool m_use_direct_host_storage = true;
86};
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91#if defined(ARCANE_COMPILING_SYCL)
92//! Implémentation pour SYCL
93class SyclGenericFilteringImpl
94{
95 public:
96
97 template <typename SelectLambda, typename InputIterator, typename OutputIterator>
98 static void apply(GenericFilteringBase& s, Int32 nb_item, InputIterator input_iter,
99 OutputIterator output_iter, SelectLambda select_lambda)
100 {
101 RunQueue queue = s.m_queue;
102 using DataType = std::iterator_traits<OutputIterator>::value_type;
103#if defined(ARCANE_USE_SCAN_ONEDPL) && defined(__INTEL_LLVM_COMPILER)
104 sycl::queue true_queue = AcceleratorUtils::toSyclNativeStream(queue);
105 auto policy = oneapi::dpl::execution::make_device_policy(true_queue);
106 auto out_iter = oneapi::dpl::copy_if(policy, input_iter, input_iter + nb_item, output_iter, select_lambda);
107 Int32 nb_output = out_iter - output_iter;
108 s.m_host_nb_out_storage[0] = nb_output;
109#else
110 NumArray<Int32, MDDim1> scan_input_data(nb_item);
111 NumArray<Int32, MDDim1> scan_output_data(nb_item);
112 SmallSpan<Int32> in_scan_data = scan_input_data.to1DSmallSpan();
113 SmallSpan<Int32> out_scan_data = scan_output_data.to1DSmallSpan();
114 {
115 auto command = makeCommand(queue);
116 command << RUNCOMMAND_LOOP1(iter, nb_item)
117 {
118 auto [i] = iter();
119 in_scan_data[i] = select_lambda(input_iter[i]) ? 1 : 0;
120 };
121 }
122 queue.barrier();
123 SyclScanner<false /*is_exclusive*/, Int32, ScannerSumOperator<Int32>> scanner;
124 scanner.doScan(queue, in_scan_data, out_scan_data, 0);
125 // La valeur de 'out_data' pour le dernier élément (nb_item-1) contient la taille du filtre
126 Int32 nb_output = out_scan_data[nb_item - 1];
127 s.m_host_nb_out_storage[0] = nb_output;
128
129 const bool do_verbose = false;
130 if (do_verbose && nb_item < 1500)
131 for (int i = 0; i < nb_item; ++i) {
132 std::cout << "out_data i=" << i << " out_data=" << out_scan_data[i]
133 << " in_data=" << in_scan_data[i] << " value=" << input_iter[i] << "\n ";
134 }
135 // Copie depuis 'out_data' vers 'in_data' les indices correspondant au filtre
136 // Comme 'output_iter' et 'input_iter' peuvent se chevaucher, il
137 // faut faire une copie intermédiaire
138 // TODO: détecter cela et ne faire la copie que si nécessaire.
139 NumArray<DataType,MDDim1> out_copy(eMemoryRessource::Device);
140 out_copy.resize(nb_output);
141 auto out_copy_view = out_copy.to1DSpan();
142 {
143 auto command = makeCommand(queue);
144 command << RUNCOMMAND_LOOP1(iter, nb_item)
145 {
146 auto [i] = iter();
147 if (in_scan_data[i] == 1)
148 out_copy_view[out_scan_data[i] - 1] = input_iter[i];
149 };
150 }
151 {
152 auto command = makeCommand(queue);
153 command << RUNCOMMAND_LOOP1(iter, nb_output)
154 {
155 auto [i] = iter();
156 output_iter[i] = out_copy_view[i];
157 };
158 }
159 // Obligatoire à cause de 'out_copy'. On pourra le supprimer avec une
160 // allocation temporaire.
161 queue.barrier();
162#endif
163 }
164};
165#endif
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169/*!
170 * \internal
171 * \brief Classe pour effectuer un filtrage
172 *
173 * \a DataType est le type de donnée.
174 * \a FlagType est le type du tableau de filtre.
175 */
176template <typename DataType, typename FlagType, typename OutputDataType>
178{
179 public:
180
183 {
184 const Int32 nb_item = input.size();
185 if (output.size() != nb_item)
186 ARCANE_FATAL("Sizes are not equals: input={0} output={1}", nb_item, output.size());
187 [[maybe_unused]] const DataType* input_data = input.data();
188 [[maybe_unused]] DataType* output_data = output.data();
189 [[maybe_unused]] const FlagType* flag_data = flag.data();
191 RunQueue queue = s.m_queue;
192 exec_policy = queue.executionPolicy();
193 switch (exec_policy) {
194#if defined(ARCANE_COMPILING_CUDA)
196 size_t temp_storage_size = 0;
197 cudaStream_t stream = AcceleratorUtils::toCudaNativeStream(queue);
198 // Premier appel pour connaitre la taille pour l'allocation
199 int* nb_out_ptr = nullptr;
200 ARCANE_CHECK_CUDA(::cub::DeviceSelect::Flagged(nullptr, temp_storage_size,
201 input_data, flag_data, output_data, nb_out_ptr, nb_item, stream));
202
203 s._allocateTemporaryStorage(temp_storage_size);
204 nb_out_ptr = s._getDeviceNbOutPointer();
205 ARCANE_CHECK_CUDA(::cub::DeviceSelect::Flagged(s.m_algo_storage.address(), temp_storage_size,
206 input_data, flag_data, output_data, nb_out_ptr, nb_item, stream));
207 s._copyDeviceNbOutToHostNbOut();
208 } break;
209#endif
210#if defined(ARCANE_COMPILING_HIP)
212 size_t temp_storage_size = 0;
213 // Premier appel pour connaitre la taille pour l'allocation
214 hipStream_t stream = AcceleratorUtils::toHipNativeStream(queue);
215 int* nb_out_ptr = nullptr;
216 ARCANE_CHECK_HIP(rocprim::select(nullptr, temp_storage_size, input_data, flag_data, output_data,
217 nb_out_ptr, nb_item, stream));
218
219 s._allocateTemporaryStorage(temp_storage_size);
220 nb_out_ptr = s._getDeviceNbOutPointer();
221
222 ARCANE_CHECK_HIP(rocprim::select(s.m_algo_storage.address(), temp_storage_size, input_data, flag_data, output_data,
223 nb_out_ptr, nb_item, stream));
224 s._copyDeviceNbOutToHostNbOut();
225 } break;
226#endif
227#if defined(ARCANE_COMPILING_SYCL)
229 impl::IndexIterator iter2(0);
230 auto filter_lambda = [=](Int32 input_index) -> bool { return flag[input_index] != 0; };
231 auto setter_lambda = [=](Int32 input_index, Int32 output_index) { output[output_index] = input[input_index]; };
232 impl::SetterLambdaIterator<decltype(setter_lambda)> out(setter_lambda);
233 SyclGenericFilteringImpl::apply(s, nb_item, iter2, out, filter_lambda);
234 } break;
235#endif
237 // Pas encore implémenté en multi-thread
238 [[fallthrough]];
240 Int32 index = 0;
241 for (Int32 i = 0; i < nb_item; ++i) {
242 if (flag[i] != 0) {
243 output[index] = input[i];
244 ++index;
245 }
246 }
247 s.m_host_nb_out_storage[0] = index;
248 } break;
249 default:
250 ARCANE_FATAL(getBadPolicyMessage(exec_policy));
251 }
252 }
253};
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257/*!
258 * \internal
259 * \brief Classe pour effectuer un filtrage
260 *
261 * \a DataType est le type de donnée.
262 * \a FlagType est le type du tableau de filtre.
263 */
265{
266 public:
267
268 /*!
269 * \brief Applique le filtre.
270 *
271 * Si \a InPlace est vrai, alors OutputIterator vaut InputIterator et on
272 * met à jour directement \a input_iter.
273 */
274 template <bool InPlace, typename SelectLambda, typename InputIterator, typename OutputIterator>
275 void apply(GenericFilteringBase& s, Int32 nb_item, InputIterator input_iter, OutputIterator output_iter,
276 const SelectLambda& select_lambda, const TraceInfo& trace_info)
277 {
279 RunQueue queue = s.m_queue;
280 exec_policy = queue.executionPolicy();
281 RunCommand command = makeCommand(queue);
282 command << trace_info;
283 impl::RunCommandLaunchInfo launch_info(command, nb_item);
284 launch_info.beginExecute();
285 switch (exec_policy) {
286#if defined(ARCANE_COMPILING_CUDA)
288 size_t temp_storage_size = 0;
289 cudaStream_t stream = impl::CudaUtils::toNativeStream(queue);
290 // Premier appel pour connaitre la taille pour l'allocation
291 int* nb_out_ptr = nullptr;
292 if constexpr (InPlace)
293 ARCANE_CHECK_CUDA(::cub::DeviceSelect::If(nullptr, temp_storage_size,
294 input_iter, nb_out_ptr, nb_item,
295 select_lambda, stream));
296 else
297 ARCANE_CHECK_CUDA(::cub::DeviceSelect::If(nullptr, temp_storage_size,
298 input_iter, output_iter, nb_out_ptr, nb_item,
299 select_lambda, stream));
300
301 s._allocateTemporaryStorage(temp_storage_size);
302 nb_out_ptr = s._getDeviceNbOutPointer();
303 if constexpr (InPlace)
304 ARCANE_CHECK_CUDA(::cub::DeviceSelect::If(s.m_algo_storage.address(), temp_storage_size,
305 input_iter, nb_out_ptr, nb_item,
306 select_lambda, stream));
307 else
308 ARCANE_CHECK_CUDA(::cub::DeviceSelect::If(s.m_algo_storage.address(), temp_storage_size,
309 input_iter, output_iter, nb_out_ptr, nb_item,
310 select_lambda, stream));
311
312 s._copyDeviceNbOutToHostNbOut();
313 } break;
314#endif
315#if defined(ARCANE_COMPILING_HIP)
317 size_t temp_storage_size = 0;
318 // Premier appel pour connaitre la taille pour l'allocation
319 hipStream_t stream = impl::HipUtils::toNativeStream(queue);
320 int* nb_out_ptr = nullptr;
321 // NOTE: il n'y a pas de version spécifique de 'select' en-place.
322 // A priori il est possible que \a input_iter et \a output_iter
323 // aient la même valeur.
324 ARCANE_CHECK_HIP(rocprim::select(nullptr, temp_storage_size, input_iter, output_iter,
325 nb_out_ptr, nb_item, select_lambda, stream));
326 s._allocateTemporaryStorage(temp_storage_size);
327 nb_out_ptr = s._getDeviceNbOutPointer();
328 ARCANE_CHECK_HIP(rocprim::select(s.m_algo_storage.address(), temp_storage_size, input_iter, output_iter,
329 nb_out_ptr, nb_item, select_lambda, 0));
330 s._copyDeviceNbOutToHostNbOut();
331 } break;
332#endif
333#if defined(ARCANE_COMPILING_SYCL)
335 SyclGenericFilteringImpl::apply(s, nb_item, input_iter, output_iter, select_lambda);
336 } break;
337#endif
339 if (nb_item > 500) {
340 MultiThreadAlgo scanner;
341 Int32 v = scanner.doFilter<InPlace>(launch_info.loopRunInfo(), nb_item, input_iter, output_iter, select_lambda);
342 s.m_host_nb_out_storage[0] = v;
343 break;
344 }
345 [[fallthrough]];
347 Int32 index = 0;
348 for (Int32 i = 0; i < nb_item; ++i) {
349 if (select_lambda(*input_iter)) {
350 *output_iter = *input_iter;
351 ++index;
352 ++output_iter;
353 }
354 ++input_iter;
355 }
356 s.m_host_nb_out_storage[0] = index;
357 } break;
358 default:
359 ARCANE_FATAL(getBadPolicyMessage(exec_policy));
360 }
361 launch_info.endExecute();
362 }
363};
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
368} // namespace Arcane::Accelerator::impl
369
370namespace Arcane::Accelerator
371{
372
373/*---------------------------------------------------------------------------*/
374/*---------------------------------------------------------------------------*/
375/*!
376 * \brief Algorithme générique de filtrage sur accélérateur.
377 */
380{
381
382 public:
383
384 /*!
385 * \brief Créé une instance.
386 *
387 * \pre queue!=nullptr
388 */
389 ARCANE_DEPRECATED_REASON("Y2024: Use GenericFilterer(const RunQueue&) instead")
390 explicit GenericFilterer(RunQueue* queue)
391 {
393 m_queue = *queue;
394 _allocate();
395 }
396
397 /*!
398 * \brief Créé une instance.
399 *
400 * \pre queue!=nullptr
401 */
402 explicit GenericFilterer(const RunQueue& queue)
403 {
404 m_queue = queue;
405 _allocate();
406 }
407
408 public:
409
410 /*!
411 * \brief Applique un filtre.
412 *
413 * Filtre tous les éléments de \a input pour lesquels \a flag est différent de 0 et
414 * remplit \a output avec les valeurs filtrées. \a output doit avoir une taille assez
415 * grande pour contenir tous les éléments filtrés.
416 *
417 * L'algorithme séquentiel est le suivant:
418 *
419 * \code
420 * Int32 index = 0;
421 * for (Int32 i = 0; i < nb_item; ++i) {
422 * if (flag[i] != 0) {
423 * output[index] = input[i];
424 * ++index;
425 * }
426 * }
427 * return index;
428 * \endcode
429 *
430 * Il faut appeler la méthode nbOutputElement() pour obtenir le nombre d'éléments
431 * après filtrage.
432 */
433 template <typename InputDataType, typename OutputDataType, typename FlagType>
435 {
436 const Int32 nb_value = input.size();
437 if (output.size() != nb_value)
438 ARCANE_FATAL("Sizes are not equals: input={0} output={1}", nb_value, output.size());
439 if (flag.size() != nb_value)
440 ARCANE_FATAL("Sizes are not equals: input={0} flag={1}", nb_value, flag.size());
441
442 _setCalled();
443 if (_checkEmpty(nb_value))
444 return;
445 impl::GenericFilteringBase* base_ptr = this;
447 gf.apply(*base_ptr, input, output, flag);
448 }
449
450 /*!
451 * \brief Applique un filtre.
452 *
453 * Filtre tous les éléments de \a input pour lesquels \a select_lambda vaut \a true et
454 * remplit \a output avec les valeurs filtrées. \a output doit avoir une taille assez
455 * grande pour contenir tous les éléments filtrés.
456 * Les zones mémoire associées à \a input et \a output ne doivent pas se chevaucher.
457 *
458 * \a select_lambda doit avoir un opérateur `ARCCORE_HOST_DEVICE bool operator()(const DataType& v) const`.
459 *
460 * Par exemple la lambda suivante permet de ne garder que les éléments dont
461 * la valeur est supérieure à 569.
462 *
463 * \code
464 * auto filter_lambda = [] ARCCORE_HOST_DEVICE (const DataType& x) -> bool {
465 * return (x > 569.0);
466 * };
467 * \endcode
468 *
469 * L'algorithme séquentiel est le suivant:
470 *
471 * \code
472 * Int32 index = 0;
473 * for (Int32 i = 0; i < nb_item; ++i) {
474 * if (select_lambda(input[i])) {
475 * output[index] = input[i];
476 * ++index;
477 * }
478 * }
479 * return index;
480 * \endcode
481 *
482 * Il faut appeler la méthode nbOutputElement() pour obtenir le nombre d'éléments
483 * après filtrage.
484 */
485 template <typename DataType, typename SelectLambda>
487 const SelectLambda& select_lambda, const TraceInfo& trace_info = TraceInfo())
488 {
489 const Int32 nb_value = input.size();
490 if (output.size() != nb_value)
491 ARCANE_FATAL("Sizes are not equals: input={0} output={1}", nb_value, output.size());
492 if (input.data() == output.data())
493 ARCANE_FATAL("Input and Output are the same. Use in place overload instead");
494 _setCalled();
495 if (_checkEmpty(nb_value))
496 return;
497 impl::GenericFilteringBase* base_ptr = this;
499 gf.apply<false>(*base_ptr, nb_value, input.data(), output.data(), select_lambda, trace_info);
500 }
501
502 /*!
503 * \brief Applique un filtre en place.
504 *
505 * Cette méthode est identique à applyIf(SmallSpan<const DataType>, SmallSpan<DataType>,
506 * const SelectLambda&, const TraceInfo& trace_info) mais les valeurs filtrées sont
507 * directement recopié dans le tableau \a input_output.
508 */
509 template <typename DataType, typename SelectLambda>
510 void applyIf(SmallSpan<DataType> input_output, const SelectLambda& select_lambda,
511 const TraceInfo& trace_info = TraceInfo())
512 {
513 const Int32 nb_value = input_output.size();
514 if (nb_value <= 0)
515 return;
516 _setCalled();
517 if (_checkEmpty(nb_value))
518 return;
519 impl::GenericFilteringBase* base_ptr = this;
521 gf.apply<true>(*base_ptr, nb_value, input_output.data(), input_output.data(), select_lambda, trace_info);
522 }
523
524 /*!
525 * \brief Applique un filtre.
526 *
527 * Cette méthode est identique à Filterer::applyIf(SmallSpan<const DataType> input,
528 * SmallSpan<DataType> output, const SelectLambda& select_lambda) mais permet de spécifier un
529 * itérateur \a input_iter pour l'entrée et \a output_iter pour la sortie.
530 * Le nombre d'entité en entrée est donné par \a nb_value.
531 *
532 * Les zones mémoire associées à \a input_iter et \a output_iter ne doivent pas se chevaucher.
533 */
534 template <typename InputIterator, typename OutputIterator, typename SelectLambda>
535 void applyIf(Int32 nb_value, InputIterator input_iter, OutputIterator output_iter,
536 const SelectLambda& select_lambda, const TraceInfo& trace_info = TraceInfo())
537 {
538 _setCalled();
539 if (_checkEmpty(nb_value))
540 return;
541 impl::GenericFilteringBase* base_ptr = this;
543 gf.apply<false>(*base_ptr, nb_value, input_iter, output_iter, select_lambda, trace_info);
544 }
545
546 /*!
547 * \brief Applique un filtre avec une sélection suivant un index.
548 *
549 * Cette méthode permet de filtrer en spécifiant une fonction lambda à la fois
550 * pour la sélection et l'affection. Le prototype de ces lambda est:
551 *
552 * \code
553 * auto select_lambda = [=] ARCCORE_HOST_DEVICE (Int32 index) -> bool;
554 * auto setter_lambda = [=] ARCCORE_HOST_DEVICE (Int32 input_index,Int32 output_index) -> void;
555 * \endcode
556 *
557 * Par exemple, si on souhaite recopier dans \a output le tableau \a input dont les
558 * valeurs sont supérieures à 25.0.
559 *
560 * \code
561 * SmallSpan<Real> input = ...;
562 * SmallSpan<Real> output = ...;
563 * auto select_lambda = [=] ARCCORE_HOST_DEVICE (Int32 index) -> bool
564 * {
565 * return input[index] > 25.0;
566 * };
567 * auto setter_lambda = [=] ARCCORE_HOST_DEVICE (Int32 input_index,Int32 output_index)
568 * {
569 * output[output_index] = input[input_index];
570 * };
571 * Arcane::Accelerator::RunQueue* queue = ...;
572 * Arcane::Accelerator::GenericFilterer filterer(queue);
573 * filterer.applyWithIndex(input.size(), select_lambda, setter_lambda);
574 * Int32 nb_out = filterer.nbOutputElement();
575 * \endcode
576 *
577 * Les zones mémoire associées aux valeurs d'entrée et de sortie ne doivent pas se chevaucher.
578 */
579 template <typename SelectLambda, typename SetterLambda>
580 void applyWithIndex(Int32 nb_value, const SelectLambda& select_lambda,
581 const SetterLambda& setter_lambda, const TraceInfo& trace_info = TraceInfo())
582 {
583 _setCalled();
584 if (_checkEmpty(nb_value))
585 return;
586 impl::GenericFilteringBase* base_ptr = this;
588 impl::IndexIterator input_iter;
590 gf.apply<false>(*base_ptr, nb_value, input_iter, out, select_lambda, trace_info);
591 }
592
593 //! Nombre d'éléments en sortie.
595 {
596 m_is_already_called = false;
597 return _nbOutputElement();
598 }
599
600 private:
601
602 bool m_is_already_called = false;
603
604 private:
605
606 void _setCalled()
607 {
608 if (m_is_already_called)
609 ARCANE_FATAL("apply() has already been called for this instance");
610 m_is_already_called = true;
611 }
612 bool _checkEmpty(Int32 nb_value)
613 {
614 if (nb_value == 0) {
616 return true;
617 }
618 return false;
619 }
620};
621
622/*---------------------------------------------------------------------------*/
623/*---------------------------------------------------------------------------*/
624
625} // namespace Arcane::Accelerator
626
627/*---------------------------------------------------------------------------*/
628/*---------------------------------------------------------------------------*/
629
630#endif
631
632/*---------------------------------------------------------------------------*/
633/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour gérer les boucles sur les accélérateurs.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle sur accélérateur avec arguments supplémentaires pour les réductions.
Algorithme générique de filtrage sur accélérateur.
void applyIf(Int32 nb_value, InputIterator input_iter, OutputIterator output_iter, const SelectLambda &select_lambda, const TraceInfo &trace_info=TraceInfo())
Applique un filtre.
void applyWithIndex(Int32 nb_value, const SelectLambda &select_lambda, const SetterLambda &setter_lambda, const TraceInfo &trace_info=TraceInfo())
Applique un filtre avec une sélection suivant un index.
void applyIf(SmallSpan< DataType > input_output, const SelectLambda &select_lambda, const TraceInfo &trace_info=TraceInfo())
Applique un filtre en place.
void apply(SmallSpan< const InputDataType > input, SmallSpan< OutputDataType > output, SmallSpan< const FlagType > flag)
Applique un filtre.
void applyIf(SmallSpan< const DataType > input, SmallSpan< DataType > output, const SelectLambda &select_lambda, const TraceInfo &trace_info=TraceInfo())
Applique un filtre.
Int32 nbOutputElement()
Nombre d'éléments en sortie.
GenericFilterer(const RunQueue &queue)
Créé une instance.
Gestion d'une commande sur accélérateur.
File d'exécution pour un accélérateur.
void barrier() const
Bloque tant que toutes les commandes associées à la file ne sont pas terminées.
Definition RunQueue.cc:159
eExecutionPolicy executionPolicy() const
Politique d'exécution de la file.
Definition RunQueue.cc:169
DeviceStorage< int > m_device_nb_out_storage
Mémoire sur le device du nombre de valeurs filtrées.
NumArray< Int32, MDDim1 > m_host_nb_out_storage
Mémoire hôte pour le nombre de valeurs filtrées.
RunQueue m_queue
File d'exécution. Ne doit pas être nulle.
void apply(GenericFilteringBase &s, Int32 nb_item, InputIterator input_iter, OutputIterator output_iter, const SelectLambda &select_lambda, const TraceInfo &trace_info)
Applique le filtre.
Algorithmes avancée en mode multi-thread.
void beginExecute()
Indique qu'on commence l'exécution de la commande.
void endExecute()
Signale la fin de l'exécution.
const ForLoopRunInfo & loopRunInfo() const
Informations d'exécution de la boucle.
Itérateur sur une lambda pour positionner une valeur via un index.
Tableaux multi-dimensionnels pour les types numériques accessibles sur accélérateurs.
Span< const DataType > to1DSpan() const
Vue 1D constante sur l'instance.
constexpr SmallSpan< DataType > to1DSmallSpan()
Vue 1D sur l'instance (uniquement si rank == 1)
void resize(Int32 dim1_size)
Modifie la taille du tableau en gardant pas les valeurs actuelles.
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.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
eExecutionPolicy
Politique d'exécution pour un Runner.
@ SYCL
Politique d'exécution utilisant l'environnement SYCL.
@ 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.