Arcane  v3.16.7.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
HybridMachineMemoryWindowBaseInternalCreator.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* HybridMachineMemoryWindowBaseInternalCreator.cc (C) 2000-2025 */
9/* */
10/* Classe permettant de créer des objets de type */
11/* HybridMachineMemoryWindowBaseInternal. Une instance de cet objet doit */
12/* être partagée par tous les threads d'un processus. */
13/*---------------------------------------------------------------------------*/
14
15#include "arcane/utils/FatalErrorException.h"
16
17#include "arcane/parallel/mpithread/internal/HybridMachineMemoryWindowBaseInternalCreator.h"
18
19#include "arcane/parallel/mpi/MpiParallelMng.h"
20#include "arcane/parallel/mpithread/internal/HybridMachineMemoryWindowBaseInternal.h"
21#include "arcane/parallel/mpithread/HybridMessageQueue.h"
22
23#include "arccore/concurrency/IThreadBarrier.h"
24#include "arccore/message_passing_mpi/internal/MpiAdapter.h"
25#include "arccore/message_passing_mpi/internal/MpiMachineMemoryWindowBaseInternalCreator.h"
26#include "arccore/message_passing_mpi/internal/MpiMachineMemoryWindowBaseInternal.h"
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
32{
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37HybridMachineMemoryWindowBaseInternalCreator::
38HybridMachineMemoryWindowBaseInternalCreator(Int32 nb_rank_local_proc, IThreadBarrier* barrier)
39: m_nb_rank_local_proc(nb_rank_local_proc)
40, m_sizeof_segment_local_proc(0)
41, m_barrier(barrier)
42{}
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47HybridMachineMemoryWindowBaseInternal* HybridMachineMemoryWindowBaseInternalCreator::
48createWindow(Int32 my_rank_global, Int64 sizeof_segment, Int32 sizeof_type, MpiParallelMng* mpi_parallel_mng)
49{
50 // On est dans un contexte où chaque processus doit avoir plusieurs segments, un par thread.
51 // Pour que chaque processus puisse avoir accès à toutes les positions des segments de tous les
52 // threads de tous les processus, chaque processus doit partager les positions de ces segments avec
53 // les autres processus. Pour faire ça, on utilise des fenêtres mémoire MPI.
54
55 FullRankInfo my_fri = FullRankInfo::compute(MP::MessageRank(my_rank_global), m_nb_rank_local_proc);
56 Int32 my_rank_local_proc = my_fri.localRankValue();
57 Int32 my_rank_mpi = my_fri.mpiRankValue();
58
59 Mpi::MpiMachineMemoryWindowBaseInternalCreator* mpi_window_creator = nullptr;
60
61 if (my_rank_local_proc == 0) {
62 mpi_window_creator = mpi_parallel_mng->adapter()->windowCreator();
63 _buildMachineRanksArray(mpi_window_creator);
64
65 // Le nombre d'éléments de chaque segment. Cette fenêtre fera une taille de nb_thread * nb_proc_sur_le_même_noeud.
66 m_sizeof_sub_segments = makeRef(mpi_window_creator->createWindow(m_nb_rank_local_proc * static_cast<Int64>(sizeof(Int64)), sizeof(Int64)));
67 m_sum_sizeof_sub_segments = makeRef(mpi_window_creator->createWindow(m_nb_rank_local_proc * static_cast<Int64>(sizeof(Int64)), sizeof(Int64)));
68 }
69 m_barrier->wait();
70
71 // nb_elem est le segment de notre processus (qui contient les segments de tous nos threads).
72 Span<Int64> sizeof_sub_segments = asSpan<Int64>(m_sizeof_sub_segments->segment());
73
74 sizeof_sub_segments[my_rank_local_proc] = sizeof_segment;
75 m_barrier->wait();
76
77 if (my_rank_local_proc == 0) {
78 m_sizeof_segment_local_proc = 0;
79 Span<Int64> sum_sizeof_sub_segments = asSpan<Int64>(m_sum_sizeof_sub_segments->segment());
80
81 for (Int32 i = 0; i < m_nb_rank_local_proc; ++i) {
82 sum_sizeof_sub_segments[i] = m_sizeof_segment_local_proc;
83 m_sizeof_segment_local_proc += sizeof_sub_segments[i];
84 }
85 }
86 m_barrier->wait();
87
88
89 if (my_rank_local_proc == 0) {
90 m_window = makeRef(mpi_window_creator->createWindow(m_sizeof_segment_local_proc, sizeof_type));
91 }
92 m_barrier->wait();
93
94 auto* window_obj = new HybridMachineMemoryWindowBaseInternal(my_rank_mpi, my_rank_local_proc, m_nb_rank_local_proc, m_machine_ranks, sizeof_type, m_sizeof_sub_segments, m_sum_sizeof_sub_segments, m_window, m_barrier);
95 m_barrier->wait();
96
97 // Ces tableaux doivent être delete par HybridMachineMemoryWindowBaseInternal (rang 0 uniquement).
98 m_sizeof_sub_segments.reset();
99 m_sum_sizeof_sub_segments.reset();
100 m_sizeof_segment_local_proc = 0;
101 m_window.reset();
102
103 return window_obj;
104}
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108
109void HybridMachineMemoryWindowBaseInternalCreator::
110_buildMachineRanksArray(const Mpi::MpiMachineMemoryWindowBaseInternalCreator* mpi_window_creator)
111{
112 ConstArrayView<Int32> mpi_ranks(mpi_window_creator->machineRanks());
113 m_machine_ranks.resize(mpi_ranks.size() * m_nb_rank_local_proc);
114
115 Int32 iter = 0;
116 for (Int32 mpi_rank : mpi_ranks) {
117 for (Int32 thread_rank = 0; thread_rank < m_nb_rank_local_proc; ++thread_rank) {
118 m_machine_ranks[iter++] = thread_rank + m_nb_rank_local_proc * mpi_rank;
119 }
120 }
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126} // namespace Arcane::MessagePassing
127
128/*---------------------------------------------------------------------------*/
129/*---------------------------------------------------------------------------*/
Déclarations des types et méthodes utilisés par les mécanismes d'échange de messages.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.