diff --git a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc index 1a918d7581..8fd3997d46 100644 --- a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc +++ b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRCartesianMeshTesterModule.cc (C) 2000-2024 */ +/* AMRCartesianMeshTesterModule.cc (C) 2000-2025 */ /* */ /* Module de test du gestionnaire de maillages cartésiens AMR. */ /*---------------------------------------------------------------------------*/ @@ -117,6 +117,7 @@ class AMRCartesianMeshTesterModule Integer _cellsUidAroundCells(UniqueArray& own_cells_uid_around_cells); Integer _cellsUidAroundFaces(UniqueArray& own_cells_uid_around_faces); Integer _nodesUidAroundNodes(UniqueArray& own_nodes_uid_around_nodes); + void _checkSync(); void _cellsInPatch(Real3 position, Real3 length, bool is_3d, Int32 level, UniqueArray& cells_in_patch); }; @@ -334,6 +335,7 @@ init() _writePostProcessing(); _testDirections(); _checkDirections(); + _checkSync(); } /*---------------------------------------------------------------------------*/ @@ -1172,6 +1174,31 @@ _nodesUidAroundNodes(UniqueArray& own_nodes_uid_around_nodes) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void AMRCartesianMeshTesterModule:: +_checkSync() +{ + IMesh* mesh = m_cartesian_mesh->mesh(); + Integer nb_error = 0; + + VariableCellInt32 test_var(VariableBuildInfo(mesh, "ArcaneTestAMRCheckSync")); + test_var.fill(0); + ENUMERATE_ (Cell, icell, mesh->ownCells()) { + test_var[icell] = 1; + } + test_var.synchronize(); + ENUMERATE_ (Cell, icell, mesh->allCells()) { + if (test_var[icell] != 1) { + nb_error++; + } + } + if (nb_error > 0) { + ARCANE_FATAL("Bad sync -- Nb error : {0}", nb_error); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void AMRCartesianMeshTesterModule:: _cellsInPatch(Real3 position, Real3 length, bool is_3d, Int32 level, UniqueArray& cells_in_patch) { diff --git a/arcane/ceapart/tests/CMakeLists.txt b/arcane/ceapart/tests/CMakeLists.txt index 646c6abb9a..d7372d42c5 100644 --- a/arcane/ceapart/tests/CMakeLists.txt +++ b/arcane/ceapart/tests/CMakeLists.txt @@ -104,6 +104,9 @@ if (ARCANE_HAS_ACCELERATOR_API) arcane_add_accelerator_test_parallel_thread(material_sync2_v7 testMaterial-sync-2.arc 4 -We,ARCANE_MATSYNCHRONIZE_VERSION,7) arcane_add_accelerator_test_parallel_thread(material_sync2_vacc testMaterial-sync-2.arc 4 -We,ARCANE_ACC_MAT_SYNCHRONIZER,1) + ARCANE_ADD_TEST(material_sync3 testMaterial-sync-3.arc) + ARCANE_ADD_TEST_PARALLEL_THREAD(material_sync3 testMaterial-sync-3.arc 4) + ARCANE_ADD_TEST(material3 testMaterial-3.arc "-m 20") # NOTE Ajoute test optmisation uniquement en sequentiel car pour l'instant cela # ne marche pas en parallele a cause de la suppression de mailles. diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc index 9a2e6375f9..969fdadb43 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc @@ -63,7 +63,7 @@ 2.0 2.0 48 192 12 8 64 72 - 72 288 12 8 160 168 + 120 480 12 8 192 216 133eed4a37931e6cd103f2fb12c354eb 0ba793345bd95bd20e83fc7cd6de9f02 7eec15be89bd293981c7b92df927cb78 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc index bf1e0e44e2..2150c8ce82 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc @@ -48,7 +48,7 @@ 1600 6400 484 - 336 1344 0 + 516 2064 0 be945c17467f6ba7bbf41ee1baf19c8c c92d0e52cea7b406b449d57521f42124 19dd0b9269462bd111611a5f0adac601 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc index 24463df511..f641a73309 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc @@ -65,7 +65,7 @@ 2.0 2.0 1600 6400 484 1144 1936 3600 1600 - 336 1344 0 0 352 480 640 + 516 2064 0 0 528 720 960 2ec1e04de3e4927fcb7578afedba1446 52335db38b14b6c2655b35770ea92dd2 66dae987c5a023af83c87cd6131d86f4 diff --git a/arcane/ceapart/tests/testMaterial-sync-3.arc b/arcane/ceapart/tests/testMaterial-sync-3.arc new file mode 100644 index 0000000000..414176060a --- /dev/null +++ b/arcane/ceapart/tests/testMaterial-sync-3.arc @@ -0,0 +1,25 @@ + + + + Test Material Synchronisation 3 + Test Material Synchronisation 3 + UnitTest + + + + + + 2 2 + 0.0 0.0 + 16.0 + 16.0 + + + + + + + 24 + + + diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc index ecfb0df8f7..4da85cc8b8 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshAMRPatchMng.cc (C) 2000-2024 */ +/* CartesianMeshAMRPatchMng.cc (C) 2000-2025 */ /* */ /* Gestionnaire de l'AMR par patch d'un maillage cartésien. */ /*---------------------------------------------------------------------------*/ @@ -1904,6 +1904,9 @@ refine() } } + // Recalcule les informations de synchronisation. + m_mesh->computeSynchronizeInfos(); + // ENUMERATE_(Cell, icell, m_mesh->allCells()){ // debug() << "\t" << *icell; // for(Node node : icell->nodes()){ @@ -1975,7 +1978,12 @@ coarse() if (version < 3) gm->setBuilderVersion(3); Int32 nb_ghost_layer = gm->nbGhostLayer(); - gm->setNbGhostLayer(nb_ghost_layer + (nb_ghost_layer % m_num_mng->pattern())); + // TODO AH : Cette ligne permettrait d'avoir moins de mailles fantômes et + // d'éviter leurs suppressions en cas d'inutilité. Mais le comportement + // serait différent de l'AMR historique. + //gm->setNbGhostLayer(nb_ghost_layer + (nb_ghost_layer % m_num_mng->pattern())); + // Comportement de l'AMR historique. + gm->setNbGhostLayer(nb_ghost_layer * 2); mesh_modifier->setDynamic(true); mesh_modifier->updateGhostLayers(); // Remet le nombre initial de couches de mailles fantômes diff --git a/arcane/src/arcane/materials/MeshMaterialSynchronizer.cc b/arcane/src/arcane/materials/MeshMaterialSynchronizer.cc index 6bc8cba213..90f795dc32 100644 --- a/arcane/src/arcane/materials/MeshMaterialSynchronizer.cc +++ b/arcane/src/arcane/materials/MeshMaterialSynchronizer.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* MeshMaterialSynchronizer.cc (C) 2000-2024 */ +/* MeshMaterialSynchronizer.cc (C) 2000-2025 */ /* */ /* Synchronisation des entités des matériaux. */ /*---------------------------------------------------------------------------*/ @@ -13,15 +13,16 @@ #include "arcane/materials/internal/MeshMaterialSynchronizer.h" -#include "arcane/VariableTypes.h" -#include "arcane/IParallelMng.h" -#include "arcane/ItemPrinter.h" -#include "arcane/IMesh.h" - #include "arcane/materials/CellToAllEnvCellConverter.h" #include "arcane/materials/MatItemEnumerator.h" #include "arcane/materials/MeshMaterialModifier.h" +#include "arcane/utils/HashSuite.h" + +#include "arcane/core/VariableTypes.h" +#include "arcane/core/IParallelMng.h" +#include "arcane/core/ItemPrinter.h" +#include "arcane/core/IMesh.h" #include "arcane/core/ItemGenericInfoListView.h" /*---------------------------------------------------------------------------*/ @@ -90,10 +91,15 @@ checkMaterialsInCells(Integer max_print) if (!mesh->parallelMng()->isParallel()) return; m_material_mng->checkValid(); + info(4) << "CheckMaterialsInCells"; + VariableCellInt32 indexes(VariableBuildInfo(mesh,"ArcaneMaterialPresenceIndexes")); - _checkComponents(indexes,m_material_mng->materialsAsComponents(),max_print); - _checkComponents(indexes,m_material_mng->environmentsAsComponents(),max_print); + _checkComponents(indexes, m_material_mng->materialsAsComponents(), max_print); + _checkComponents(indexes, m_material_mng->environmentsAsComponents(), max_print); + + VariableCellInt64 hashes(VariableBuildInfo(mesh, "ArcaneMaterialCheckHashes")); + _checkComponentsInGhostCells(hashes, max_print); } /*---------------------------------------------------------------------------*/ @@ -143,6 +149,71 @@ _checkComponents(VariableCellInt32& indexes, ARCANE_FATAL("Bad synchronisation"); } +void MeshMaterialSynchronizer:: +_checkComponentsInGhostCells(VariableCellInt64& hashes, Integer max_print) +{ + IMesh* mesh = m_material_mng->mesh(); + Integer nb_error = 0; + + ENUMERATE_ALLENVCELL (iallenvcell, m_material_mng, mesh->ownCells()) { + AllEnvCell all_env_cell = *iallenvcell; + Cell cell = all_env_cell.globalCell(); + + IntegerHashSuite hash_suite; + + Int32 nb_env = all_env_cell.nbEnvironment(); + hash_suite.add(nb_env); + + for (Integer i = 0; i < nb_env; ++i) { + EnvCell env_cell = all_env_cell.cell(i); + Int32 nb_matt = env_cell.nbMaterial(); + hash_suite.add(nb_matt); + + for (Integer j = 0; j < nb_matt; ++j) { + MatCell mat = env_cell.cell(j); + Int32 id = mat.materialId(); + hash_suite.add(id); + } + } + + hashes[cell] = hash_suite.hash(); + } + + hashes.synchronize(); + + ENUMERATE_ALLENVCELL (iallenvcell, m_material_mng, mesh->allCells()) { + AllEnvCell all_env_cell = *iallenvcell; + Cell cell = all_env_cell.globalCell(); + if (cell.isOwn()) + continue; + + IntegerHashSuite hash_suite; + + Int32 nb_env = all_env_cell.nbEnvironment(); + hash_suite.add(nb_env); + + for (Integer i = 0; i < nb_env; ++i) { + EnvCell env_cell = all_env_cell.cell(i); + Int32 nb_matt = env_cell.nbMaterial(); + hash_suite.add(nb_matt); + + for (Integer j = 0; j < nb_matt; ++j) { + MatCell mat = env_cell.cell(j); + Int32 id = mat.materialId(); + hash_suite.add(id); + } + } + if (hashes[cell] != hash_suite.hash()) { + nb_error++; + if (max_print < 0 || nb_error < max_print) { + error() << "Bad components synchronization -- Cell : " << cell << " -- Hash : " << hash_suite.hash(); + } + } + } + if (nb_error != 0) + ARCANE_FATAL("Bad components synchronization -- Nb error : {0}", nb_error); +} + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/materials/internal/MeshMaterialSynchronizer.h b/arcane/src/arcane/materials/internal/MeshMaterialSynchronizer.h index 8e37759b70..9bd89c0789 100644 --- a/arcane/src/arcane/materials/internal/MeshMaterialSynchronizer.h +++ b/arcane/src/arcane/materials/internal/MeshMaterialSynchronizer.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* MeshMaterialSynchronizer.h (C) 2000-2024 */ +/* MeshMaterialSynchronizer.h (C) 2000-2025 */ /* */ /* Synchronisation de la liste des matériaux/milieux des entités. */ /*---------------------------------------------------------------------------*/ @@ -17,7 +17,7 @@ #include "arcane/utils/TraceAccessor.h" #include "arcane/utils/ArrayView.h" -#include "arcane/VariableTypedef.h" +#include "arcane/core/VariableTypedef.h" #include "arcane/materials/MaterialsGlobal.h" #include "arcane/materials/MatItem.h" @@ -77,6 +77,8 @@ class MeshMaterialSynchronizer void _checkComponents(VariableCellInt32& indexes, ConstArrayView components, Integer max_print); + void _checkComponentsInGhostCells(VariableCellInt64& hashes, + Integer max_print); }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/utils/HashSuite.h b/arcane/src/arcane/utils/HashSuite.h new file mode 100644 index 0000000000..7f642791f8 --- /dev/null +++ b/arcane/src/arcane/utils/HashSuite.h @@ -0,0 +1,74 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* HashSuite.h (C) 2000-2025 */ +/* */ +/* Fonction de hachage d'une suite de valeur. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_UTILS_HASHSUITE_H +#define ARCANE_UTILS_HASHSUITE_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/utils/HashFunction.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/*! + * \internal + * \brief Classe permettant de calculer un hash de manière itératif. + * \warning L'ordre dans lequel les valeurs sont données via la méthode add() est important. + */ + +class IntegerHashSuite +{ + public: + + /*! + * \brief Méthode permettant d'ajouter une valeur dans le calcul du hash. + * \warning L'ordre dans lequel les valeurs sont données via la méthode + * add() est important. + * \param value La valeur à ajouter. + */ + template + void add(T value) + { + const UInt64 next_hash = static_cast(IntegerHashFunctionT::hashfunc(value)); + m_hash ^= next_hash + 0x9e3779b9 + (m_hash << 6) + (m_hash >> 2); + } + + /*! + * \brief Méthode permettant de récupérer le hash calculé à partir de + * toutes les valeurs passées à la méthode add(). + * \return Le hash. + */ + Int64 hash() const + { + return static_cast(m_hash); + } + + private: + + UInt64 m_hash{0}; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif diff --git a/arcane/src/arcane/utils/srcs.cmake b/arcane/src/arcane/utils/srcs.cmake index 063e13ffa5..4ade74bd08 100644 --- a/arcane/src/arcane/utils/srcs.cmake +++ b/arcane/src/arcane/utils/srcs.cmake @@ -55,6 +55,7 @@ set(ARCANE_SOURCES GenericRegisterer.cc GoBackwardException.cc GoBackwardException.h + HashSuite.h IDataCompressor.h Int128.h IOException.cc