diff --git a/packages/core.cmake b/packages/core.cmake index df848bc..5dfe857 100644 --- a/packages/core.cmake +++ b/packages/core.cmake @@ -1,224 +1,226 @@ #=============================================================================== # @file core.cmake # # @author Guillaume Anciaux # @author Nicolas Richart # # @date Mon Oct 13 10:50:54 2014 # # @brief Core package # # @section LICENSE # # Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # LibMultiScale is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # LibMultiScale is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with LibMultiScale. If not, see . # #=============================================================================== package_declare(core NOT_OPTIONAL DESCRIPTION "core package for LibMultiScale") set(LIBMULTISCALE_CONTINUUM_HDRS_LIST_CORE common/container_mesh.hh ) set(LIBMULTISCALE_GEOMETRY_HDRS_LIST_CORE geometry/geom_inter.hh geometry/cylinder.hh geometry/geometry.hh geometry/geom_sub.hh geometry/geom_composed.hh geometry/chaudron.hh geometry/ellipsoid.hh geometry/cube.hh geometry/geom_union.hh geometry/ball.hh geometry/cube_surface.hh ) set(LIBMULTISCALE_CORE_FILES common/lm_file.hh common/lm_file.cc common/lm_fwd.hh common/lm_libc.cc common/action_interface.cc common/action_interface.hh common/visitor_libmultiscale.hh common/model_list.hh common/id_manager.hh common/lm_log.hh common/lm_log.cc common/lm_ostream_types.hh common/lm_macros.hh common/lm_types.hh common/lm_globals.hh common/lm_globals.cc common/lm_common.hh common/domain_interface.hh common/domain_interface.cc common/ref_subset.cc common/ref_subset.hh common/ref_set.cc common/ref_set.hh common/reference_manager.cc common/reference_manager.hh common/reference_manager_interface.hh common/attached_object.hh common/ref_point.hh common/ref_point_data.hh common/component_libmultiscale.hh common/lm_functions.cc common/lm_functions.hh common/lm_timer.cc common/lm_timer.hh common/lm_object.hh parser/lm_parser.cc parser/lm_parser_inline_impl.hh parser/parse_result.hh parser/xml_parser_restart.cc parser/algebraic_parser.cc parser/lm_parsable.cc parser/xml_parser_restart.hh parser/lm_parsable.hh parser/lm_parsable_inline_impl.hh parser/algebraic_parser.hh parser/xml_parser.hh parser/lm_parser.hh parser/lm_parameter.hh parser/lm_defaults.hh # ${LIBMULTISCALE_MD_HDRS_LIST_CORE} md/domain_md_interface.hh md/spatial_filter_atomic.cc md/domain_md.cc md/trace_atom.cc md/domain_md_interface.cc md/container_neighbor_atoms.hh md/trace_atom.hh md/domain_md.hh md/spatial_filter_atomic.hh md/ref_atom.hh md/container_neighbor_atoms_interface.hh md/domain_md_interface.hh ${LIBMULTISCALE_GEOMETRY_HDRS_LIST_CORE} geometry/geometry_manager.cc geometry/spatial_grid_libmultiscale.hh geometry/geometry_manager.hh geometry/spatial_grid.hh geometry/spatial_grid.cc geometry/geometry.cc geometry/cube.cc geometry/ball.cc geometry/cylinder.cc geometry/geom_inter.cc geometry/geom_sub.cc geometry/geom_union.cc geometry/geom_composed.cc geometry/surface.hh geometry/surface.cc geometry/cube_surface.cc ${LIBMULTISCALE_CONTINUUM_HDRS_LIST_CORE} continuum/domain_continuum.cc continuum/domain_continuum_interface.cc continuum/ref_node_continuum.hh continuum/domain_continuum.hh continuum/ref_element.hh continuum/domain_continuum_interface.hh # ${LIBMULTISCALE_DD_HDRS_LIST_CORE} dd/domain_dd_interface.hh dd/domain_dd.hh dd/domain_dd.cc dd/domain_dd_interface.cc dd/container_dd.hh dd/ref_node_dd.hh factory/domain_multiscale.cc factory/factory_multiscale.cc factory/factory_multiscale.hh factory/domain_multiscale.hh units/units.hh units/units.cc units/units_converter.hh units/units_converter.cc units/quantity.hh communicator/comm_buffer.hh communicator/communicator_distributed.hh communicator/communicator_unity.hh communicator/communicator.hh communicator/communicator.cc communicator/pack_buffer.hh communicator/communicator_mpi_linear.hh communicator/communicator_mpi_linear.cc communicator/communicator_world.hh + communicator/comm_group.cc + communicator/comm_group.hh container/container_array.hh container/iterator_array_base_type.hh container/container.hh container/iterator_array.hh container/field.hh fmm/fmm_multigrid.hh fmm/fmm_interface.hh fmm/moments.hh fmm/fmm.hh fmm/radial_function.hh math/low_pass_filter.hh math/cubic_spline.hh math/full_matrix.hh math/full_matrix_inline_impl.hh math/function_interface.hh math/band_matrix.hh math/hanning_window.hh math/constant_function.hh math/gaussian_function.hh math/array.hh math/array.cc math/product_function.hh math/dispersion_relation.hh math/spline_function.hh math/diag_matrix.hh math/tensor.hh math/hamming_window.hh math/math_tools.hh math/math_tools.cc math/matrix.c math/matrix.hh math/matrix_blaswrapper.h boost/for_each2.hpp ) set(LIBMULTISCALE_GEOMETRY_LIST_CORE "((Cylinder,CYLINDER))" "((Cube,CUBE))" "((Ball,BALL))" "((GeomSub,SUB))" "((GeomInter,INTER))" "((GeomUnion,UNION))" "((CubeSurface,CUBE_SURFACE))" ) package_declare_sources(core ${LIBMULTISCALE_CORE_FILES}) set_module_headers_from_package(geometry core ${LIBMULTISCALE_GEOMETRY_HDRS_LIST_CORE}) set_module_headers_from_package(continuum core ${LIBMULTISCALE_CONTINUUM_HDRS_LIST_CORE}) declare_boost_list_from_package(geometry core ${LIBMULTISCALE_GEOMETRY_LIST_CORE}) diff --git a/src/common/action_interface.hh b/src/common/action_interface.hh index bc994bc..3e55ae8 100644 --- a/src/common/action_interface.hh +++ b/src/common/action_interface.hh @@ -1,114 +1,115 @@ /** * @file action_interface.hh * * @author Guillaume Anciaux * * @date Mon Sep 08 23:40:22 2014 * * @brief This is the interface to all action objects * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #ifndef __LIBMULTISCALE_ACTION_INTERFACE_HH__ #define __LIBMULTISCALE_ACTION_INTERFACE_HH__ /* -------------------------------------------------------------------------- */ #include "component_libmultiscale.hh" #include "lm_parsable.hh" +#include "comm_group.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ class ActionInterface : public Parsable, public Component { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: ActionInterface(); virtual ~ActionInterface(){}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: //! this function holds to possible restriction to action calls virtual bool shouldMakeAction(); //! do the action effectively virtual void action(); //! initialisation of the action internal data virtual void init(){}; //! set parameters virtual void declareParams(); protected: //! this function check for the stage mask bool doesStageMaskMatch(); //! set start and end step when onestep is declared void setOneStep(); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: //! set default values void setDefaults(); ///! set the mask // void setStageMask(UInt mask){stage_mask = mask;}; ///! get the mask // IntegrationSchemeMask & getStageMask(){return stage_mask;}; //! function to print the contain of the class virtual void printself(std::ostream &stream, int indent = 0) const; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: //! actual dump step UInt action_step; //! start step UInt start_step; //! end step UInt end_step; //! one shot UInt one_shot; //! frequency of the dump UInt frequency; private: //! stage mask to explicitly specify at what place in the scheme to do the //! action IntegrationSchemeMask stage_mask; }; /* -------------------------------------------------------------------------- */ inline std::ostream &operator<<(std::ostream &os, ActionInterface &obj) { obj.printself(os); return os; } /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_ACTION_INTERFACE_HH__ */ diff --git a/src/common/domain_interface.cc b/src/common/domain_interface.cc index 3b82466..b6a013e 100644 --- a/src/common/domain_interface.cc +++ b/src/common/domain_interface.cc @@ -1,129 +1,115 @@ /** * @file domain_interface.cc * * @author Guillaume Anciaux * * @date Mon Sep 08 23:45:56 2014 * * @brief This is the interface to all domain (model/plugins) * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #include "domain_interface.hh" #include "cube.hh" #include "lm_common.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ -DomainInterface::DomainInterface(CommGroup gid) { - group_id = gid; - restartfile = ""; -} -/* -------------------------------------------------------------------------- */ -DomainInterface::DomainInterface(UInt Dim) { - group_id = group_all; - restartfile = ""; -} +DomainInterface::DomainInterface(CommGroup & group) : group_id(group) { restartfile = ""; } /* -------------------------------------------------------------------------- */ -DomainInterface::DomainInterface() { - group_id = group_all; - restartfile = ""; -} -/* -------------------------------------------------------------------------- */ - DomainInterface::~DomainInterface() {} /* -------------------------------------------------------------------------- */ Real DomainInterface::getEpot() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ void DomainInterface::performStep1() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ void DomainInterface::performStep2() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ void DomainInterface::performStep3() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ void DomainInterface::performStep4() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ void DomainInterface::performStep5() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ UInt DomainInterface::getType() { return type; } /* -------------------------------------------------------------------------- */ -CommGroup DomainInterface::getGroupID() { return group_id; } +CommGroup & DomainInterface::getCommGroup() { return group_id; } /* -------------------------------------------------------------------------- */ void DomainInterface::getDomainDimensions(Cube &bbox) { Real xmin[3]; Real xmax[3]; getDomainDimensions(xmin, xmax); bbox.setDimensions(xmin, xmax); } /* -------------------------------------------------------------------------- */ void DomainInterface::getSubDomainDimensions(Cube &bbox) { Real xmin[3]; Real xmax[3]; getSubDomainDimensions(xmin, xmax); bbox.setDimensions(xmin, xmax); } /* -------------------------------------------------------------------------- */ bool DomainInterface::shouldRestart() { return restartfile.size(); } /* -------------------------------------------------------------------------- */ const std::string &DomainInterface::getRestartFile() { return restartfile; } /* -------------------------------------------------------------------------- */ void DomainInterface::printself(std::ostream &stream, int indent) const {} /* -------------------------------------------------------------------------- */ /* LMDESC DomainInterface This section describe the section that is associated with every model. */ void DomainInterface::declareParams() { /* LMKEYWORD RESTART_FILE Specifies a filename to perform a restart just after initialization. */ this->parseKeyword("RESTART_FILE", restartfile, ""); /* LMKEYWORD RESTART_CONTINUE_IF_NOTFOUND Set a flag that allow RESTART routine to ignore the absence of a file while restarting. If the restart file is not existing no restart procedure is launched at and a warning message is outputed. */ this->parseTag("RESTART_CONTINUE_IF_NOTFOUND", restart_continue_if_notfound, false); } /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ diff --git a/src/common/domain_interface.hh b/src/common/domain_interface.hh index bec9892..e64d266 100644 --- a/src/common/domain_interface.hh +++ b/src/common/domain_interface.hh @@ -1,214 +1,211 @@ /** * @file domain_interface.hh * * @author Guillaume Anciaux * * @date Mon Sep 08 23:40:22 2014 * * @brief This is the interface to all domain (model/plugins) * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ /* -------------------------------------------------------------------------- */ #ifndef DOMAIN_INTERFACE_H #define DOMAIN_INTERFACE_H /* -------------------------------------------------------------------------- */ +#include "comm_group.hh" #include "component_libmultiscale.hh" #include "lm_parsable.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ template class FactoryMultiScale; class FilterInterface; class ActionInterface; class Cube; /* -------------------------------------------------------------------------- */ /** * Class DomainInterface * is the most generic interface to domains */ class DomainInterface : public Parsable, public Component { public: /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ - DomainInterface(CommGroup gid); - DomainInterface(UInt Dim); - DomainInterface(); - + DomainInterface(CommGroup &group_id); virtual ~DomainInterface(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ //! initialization method virtual void init() = 0; //! generic access to potential energy virtual Real getEpot(); //! virtual first step of a domain virtual void performStep1(); //! virtual second step of a domain virtual void performStep2(); //! virtual third step of a domain virtual void performStep3(); //! virtual fourth step of a domain virtual void performStep4(); //! virtual fifth step of a domain virtual void performStep5(); //! set internal timestep to a given value virtual void setTimeStep(Real ts) = 0; //! set current timestep to a given value virtual void setCurrentStep(UInt ts) = 0; //! get internal timestep to a given value virtual Real getTimeStep() = 0; //! get current timestep to a given value virtual UInt getCurrentStep() = 0; //! restart from xml file function virtual void readXMLFile(const std::string &filename) = 0; /** the type of code used. Currently could be only of two kinds Atomic or Continu, for MD and continuum simulations */ //! type of simulation UInt getType(); /** return a group id referencing a subset of processor where a domain is ran on */ //! group of processor ID - CommGroup getGroupID(); + CommGroup &getCommGroup(); //! return the size of the domain ususefull to deal with pbc virtual void getDomainDimensions(Real *xmin, Real *xmax) = 0; //! return the size of the box associated to current processor virtual void getSubDomainDimensions(Real *xmin, Real *xmax) = 0; //! return the size of the domain ususefull to deal with pbc void getDomainDimensions(Cube &bbox); //! return the size of the box associated to current processor void getSubDomainDimensions(Cube &bbox); //! set the parameters common to all domains virtual void declareParams(); //! add points for vector of reals virtual void addPoints(const std::vector &allPositions) { LM_TOIMPLEMENT; }; /* -------------------------------------------------------------------------- */ // old material part /* ------------------------------------------------------------------------ */ bool shouldRestart(); //! function that return the restart file name const std::string &getRestartFile(); /* -------------------------------------------------------------------------- */ // functions for AMELCG /* ------------------------------------------------------------------------ */ //! return product of force by descent direction (for AMELCG) */ virtual Real getFdotDir() = 0; //! return max of forces (for AMELCG) virtual Real getFMax() = 0; //! return max of direction vector (for AMELCG) virtual Real getDirMax() = 0; //! return norm 2 of forces (for AMELCG) virtual Real getFNorm2() = 0; //! return stuff for AMELCG virtual Real getFdotOldF() = 0; //! update direction AMELCG virtual void updateDirection(Real beta) = 0; //! return stuff for AMELCG virtual void saveForceVector() = 0; //! displace in descent direction with given magnitude virtual void displaceTowardsDirection(Real alpha) = 0; //! get amount of work done by external forces /* virtual double getExternalWork()=0; */ /* //! set amount of work done by external forces */ /* virtual void setExternalWork(double work)=0; */ //! function to print the contain of the class virtual void printself(std::ostream &stream, int indent = 0) const; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: //! type identifier UInt type; // type fe, md meshless, xfem /* -------------------------------------------------------------------------- */ // old material part /* ------------------------------------------------------------------------ */ //! restartfile name std::string restartfile; //! restart if exists flag bool restart_continue_if_notfound; private: - //! number for private group of communication - CommGroup group_id; + CommGroup &group_id; }; /* -------------------------------------------------------------------------- */ inline std::ostream &operator<<(std::ostream &os, DomainInterface &obj) { obj.printself(os); return os; } /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ #endif // DOMAIN_INTERFACE_H diff --git a/src/common/lm_globals.cc b/src/common/lm_globals.cc index 302c205..2026015 100644 --- a/src/common/lm_globals.cc +++ b/src/common/lm_globals.cc @@ -1,124 +1,117 @@ /** * @file lm_globals.cc * * @author Guillaume Anciaux * @author Jaehyun Cho * @author Till Junge * * @date Mon Sep 08 23:40:22 2014 * * @brief This file contains all the global variables of LM * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #include "lm_common.hh" #include #include /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ // global variables UInt current_step; IntegrationSchemeStage current_stage; Real current_time; UInt nb_step; UInt nb_step_next_event; UInt global_level; UInt global_mod; UInt global_proc; UInt global_proc1; UInt global_proc2; UInt start_dump; UInt end_dump; std::string my_hostname; UInt print_crap_to_file; std::ostream *global_out; std::ofstream file_out; UInt wait_on_fatal; UInt wait_at_startup; UInt create_seg_fault; UInt lm_my_proc_id; UInt lm_world_size; UInt lm_job_id; UInt spatial_dimension; UInt lm_uint_max = std::numeric_limits::max(); Real lm_real_max = std::numeric_limits::max(); /// used to avoid infinite FATAL recursion in stage PRE_FATAL bool fatal_loop = false; #if defined(LIBMULTISCALE_USE_TIMER) std::map mesT; std::map nmes; std::map tstart; std::map tstop; #endif /* -------------------------------------------------------------------------- */ UInt getGlobalCurrentRelease() { UInt k = 0; switch (current_stage) { case PRE_DUMP: k = 0; break; case PRE_STEP1: k = 1; break; case PRE_STEP2: k = 2; break; case PRE_STEP3: k = 3; break; case PRE_STEP4: k = 4; break; case PRE_STEP5: k = 5; break; case PRE_STEP6: k = 6; break; case PRE_STEP7: k = 7; break; case PRE_FATAL: k = 8; break; default: LM_FATAL("error: unknown stage " << current_stage); } return (8 * current_step + k); } -/* -------------------------------------------------------------------------- */ -const int CommGroup::id_all = std::numeric_limits::max(); -const int CommGroup::id_none = id_all - 1; -const int CommGroup::id_invalid = id_all - 2; -CommGroup group_all(CommGroup::id_all); -CommGroup group_none(CommGroup::id_none); -CommGroup group_invalid(CommGroup::id_invalid); /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ diff --git a/src/common/lm_globals.hh b/src/common/lm_globals.hh index 4d0dcad..c78d47f 100644 --- a/src/common/lm_globals.hh +++ b/src/common/lm_globals.hh @@ -1,90 +1,86 @@ /** * @file lm_globals.hh * * @author Guillaume Anciaux * @author Jaehyun Cho * @author Till Junge * * @date Mon Sep 08 23:40:22 2014 * * @brief This file contains all the global variables of LM * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #ifndef __LIBMULTISCALE_LM_GLOBALS_HH__ #define __LIBMULTISCALE_LM_GLOBALS_HH__ /* -------------------------------------------------------------------------- */ #include "lm_macros.hh" #include "lm_types.hh" #include /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ static const std::string invalidFilter = "invalid filter"; static const std::string invalidGeom = "invalid geometry"; static const std::string invalidDomain = "invalid domain"; static const std::string invalidDumper = "invalid dumper"; static const std::string invalidStimulator = "invalid stimulator"; using LMID = std::string; /* -------------------------------------------------------------------------- */ // global variables EXTERN UInt current_step; EXTERN IntegrationSchemeStage current_stage; EXTERN Real current_time; EXTERN UInt nb_step; EXTERN UInt nb_step_next_event; EXTERN UInt global_level; EXTERN UInt global_mod; EXTERN UInt global_proc; EXTERN UInt global_proc1; EXTERN UInt global_proc2; EXTERN UInt start_dump; EXTERN UInt end_dump; EXTERN std::string my_hostname; EXTERN UInt print_crap_to_file; EXTERN std::ostream *global_out; EXTERN std::ofstream file_out; EXTERN UInt wait_on_fatal; EXTERN UInt wait_at_startup; EXTERN UInt create_seg_fault; EXTERN UInt lm_my_proc_id; EXTERN UInt lm_world_size; EXTERN UInt lm_job_id; EXTERN UInt spatial_dimension; EXTERN UInt lm_uint_max; EXTERN Real lm_real_max; /// used to avoid infinite FATAL recursion in stage PRE_FATAL EXTERN bool fatal_loop; /* -------------------------------------------------------------------------- */ EXTERN UInt getGlobalCurrentRelease(); /* -------------------------------------------------------------------------- */ -EXTERN CommGroup group_all; -EXTERN CommGroup group_none; -EXTERN CommGroup group_invalid; -/* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_LM_GLOBALS_HH__ */ diff --git a/src/common/lm_ostream_types.hh b/src/common/lm_ostream_types.hh index ba0588d..d94de34 100644 --- a/src/common/lm_ostream_types.hh +++ b/src/common/lm_ostream_types.hh @@ -1,127 +1,120 @@ /** * @file lm_ostream_types.hh * * @author Guillaume Anciaux * @author Till Junge * @author Jaehyun Cho * @author Moseley Philip Arthur * * @date Mon Sep 08 23:40:22 2014 * * @brief Definition of the printing features of the principal enums of * LibMultiScale * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #ifndef __LIBMULTISCALE_LM_OSTREAM_TYPES_HH__ #define __LIBMULTISCALE_LM_OSTREAM_TYPES_HH__ /* -------------------------------------------------------------------------- */ #include "lm_common.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ inline std::ostream &operator<<(std::ostream &os, FieldType q) { switch (q) { case _position0: os << "position0"; break; case _position: os << "position"; break; case _displacement: os << "displacement"; break; case _velocity: os << "velocity"; break; case _force: os << "force"; break; case _temperature: os << "temperature"; break; case _grouprank: os << "grouprank"; break; case _stress: os << "stress"; break; case _strain: os << "strain"; break; case _epot: os << "pe/atom"; break; case _mass: os << "mass"; break; default: LM_FATAL("unknown field type"); } return os; } /* -------------------------------------------------------------------------- */ inline std::ostream &operator<<(std::ostream &os, Operator op) { switch (op) { case OP_NONE: os << "NONE"; break; case OP_AVERAGE: os << "AVERAGE"; break; case OP_DENSITY: os << "DENSITY"; break; case OP_DEVIATION: os << "DEVIATION"; break; case OP_MAX: os << "MAX"; break; case OP_MIN: os << "MIN"; break; case OP_SUM: os << "SUM"; break; default: LM_FATAL("unknown operator"); } return os; } /* -------------------------------------------------------------------------- */ -inline std::ostream &operator<<(std::ostream &os, CommGroup group) { - os << "Communication Group #" << group.getID(); - return os; -} - -/* -------------------------------------------------------------------------- */ - __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_LM_OSTREAM_TYPES_HH__ */ diff --git a/src/common/lm_types.hh b/src/common/lm_types.hh index 6343b01..b017a4f 100644 --- a/src/common/lm_types.hh +++ b/src/common/lm_types.hh @@ -1,450 +1,432 @@ /** * @file lm_types.hh * * @author Guillaume Anciaux * @author Jaehyun Cho * @author Till Junge * @author Moseley Philip Arthur * * @date Mon Sep 08 23:40:22 2014 * * @brief This where the global types and enums of LibMultiScale are defined * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #ifndef __LIBMULTISCALE_LM_TYPES_HH__ #define __LIBMULTISCALE_LM_TYPES_HH__ /* -------------------------------------------------------------------------- */ #include "lm_macros.hh" #include #include #include #include /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ // error management /* -------------------------------------------------------------------------- */ #define LM_EXIT_FAILURE 1 #define LM_EXIT_SUCCESS 0 /* -------------------------------------------------------------------------- */ // TYPEDEFS /* -------------------------------------------------------------------------- */ typedef unsigned int UInt; typedef double Real; typedef Real REAL; /* -------------------------------------------------------------------------- */ // ENUMS /* -------------------------------------------------------------------------- */ enum DOFType { dt_local_master = 1, dt_local_slave = 2, dt_local = 4, dt_ghost = 8, dt_all = 255 }; /* -------------------------------------------------------------------------- */ enum GeomType { BALL = 1, CUBE = 2, INTER = 3, SUB = 4, ELLIPSOID = 5, UNION = 6, CYLINDER = 7, CHAUDRON = 8, CUBE_SURFACE = 9 }; /* -------------------------------------------------------------------------- */ enum COutputType { OUTPUT_REF = 1, OUTPUT_REAL = 2, OUTPUT_NULL = 32767 }; /* -------------------------------------------------------------------------- */ enum CouplingStage { COUPLING_STEP1 = 1, COUPLING_STEP2 = 2, COUPLING_STEP3 = 4, COUPLING_STEP4 = 8, COUPLING_STEP5 = 16, COUPLING_STEP6 = 32, COUPLING_STEP7 = 64 }; /* -------------------------------------------------------------------------- */ enum Operator { OP_NONE = 0, OP_AVERAGE = 1, OP_DENSITY = 2, OP_DEVIATION = 4, OP_MAX = 8, OP_MIN = 16, OP_SUM = 64 }; /* -------------------------------------------------------------------------- */ enum ActionType { at_stimulator = 0, at_dumper = 1, at_filter = 2, at_compute = 4, at_uninitialised = 32767 }; /* -------------------------------------------------------------------------- */ enum LatticeType { _not_defined, mono_atom_1d, hex_2d, hex_2d_radial, fcc_3d }; template struct LatticeDim { static const UInt value; }; template <> struct LatticeDim { static const UInt value = 1; }; template <> struct LatticeDim { static const UInt value = 2; }; template <> struct LatticeDim { static const UInt value = 2; }; template <> struct LatticeDim { static const UInt value = 3; }; /* -------------------------------------------------------------------------- */ enum IntegrationSchemeStage { NONE_STEP = 0, PRE_DUMP = 1, PRE_STEP1 = 2, PRE_STEP2 = 4, PRE_STEP3 = 8, PRE_STEP4 = 16, PRE_STEP5 = 32, PRE_STEP6 = 64, PRE_STEP7 = 128, PRE_FATAL = 256, // This stage only exists if a FATAL is triggered ALL_STEP = 65536 }; /* -------------------------------------------------------------------------- */ class IntegrationSchemeMask { public: IntegrationSchemeMask(UInt mask) { stage = mask; } IntegrationSchemeMask(const IntegrationSchemeStage &s) { stage = s; } IntegrationSchemeMask() { stage = NONE_STEP; }; virtual ~IntegrationSchemeMask(){}; bool operator&(const IntegrationSchemeStage &s) const { return (stage & s); }; IntegrationSchemeMask &operator=(const IntegrationSchemeStage &s) { stage = s; return (*this); }; IntegrationSchemeMask operator|=(const IntegrationSchemeStage &s) { stage |= s; return (*this); }; IntegrationSchemeMask operator|=(const IntegrationSchemeMask &m) { stage |= m.stage; return (*this); }; bool isNone() { return (stage == NONE_STEP); } virtual void printself(std::ostream &stream, int indent = 0) const { stream << "NONE_STEP"; if ((*this) & PRE_DUMP) stream << "|PREDUMP"; if ((*this) & PRE_STEP1) stream << "|PRE_STEP1"; if ((*this) & PRE_STEP2) stream << "|PRE_STEP2"; if ((*this) & PRE_STEP3) stream << "|PRE_STEP3"; if ((*this) & PRE_STEP4) stream << "|PRE_STEP4"; if ((*this) & PRE_STEP5) stream << "|PRE_STEP5"; if ((*this) & PRE_STEP6) stream << "|PRE_STEP6"; if ((*this) & PRE_STEP7) stream << "|PRE_STEP7"; if ((*this) & PRE_FATAL) stream << "|PRE_FATAL"; if ((*this) & ALL_STEP) stream << "|ALL_STEP"; }; private: UInt stage; }; inline std::ostream &operator<<(std::ostream &stream, const IntegrationSchemeMask &_this) { _this.printself(stream); return stream; } inline std::ostream &operator<<(std::ostream &stream, const IntegrationSchemeStage &_this) { switch (_this) { case NONE_STEP: stream << "NONESTEP"; break; case PRE_DUMP: stream << "PREDUMP"; break; case PRE_STEP1: stream << "PRE_STEP1"; break; case PRE_STEP2: stream << "PRE_STEP2"; break; case PRE_STEP3: stream << "PRE_STEP3"; break; case PRE_STEP4: stream << "PRE_STEP4"; break; case PRE_STEP5: stream << "PRE_STEP5"; break; case PRE_STEP6: stream << "PRE_STEP6"; break; case PRE_STEP7: stream << "PRE_STEP7"; break; case PRE_FATAL: stream << "PRE_FATAL"; break; case ALL_STEP: stream << "ALL_STEP"; break; } return stream; } /* -------------------------------------------------------------------------- */ -class CommGroup { - -public: - static const int id_all; - static const int id_none; - static const int id_invalid; - - CommGroup() { group_id = id_invalid; } - - CommGroup(int id) { this->setID(id); } - - bool operator==(CommGroup &grp) { return (grp.group_id == group_id); } - - bool operator!=(CommGroup &grp) { return (grp.group_id != group_id); } - - void setID(int id) { group_id = id; }; - int getID() { return group_id; }; - -private: - int group_id; -}; -/* -------------------------------------------------------------------------- */ - enum PhysicalQuantity { // physical quantities Length, Mass, Energy, Time, MassDensity, Force, Pressure, Temperature }; /* -------------------------------------------------------------------------- */ // enum DDModelType { // _DD2D, // _PARADIS, // }; /* -------------------------------------------------------------------------- */ /* describes the orientation of the edge dislo by indication which * quadrant is shifted towards x=0*/ enum dislo_orientation { TOP_RIGHT = 0, TOP_LEFT = 1, BOTTOM_RIGHT = 2, BOTTOM_LEFT = 3 }; /* -------------------------------------------------------------------------- */ // template using Vector = Eigen::Matrix; template struct Vector : public Eigen::Matrix { using Eigen::Matrix::Matrix; // Vector(const std::vector & vec){ // if (vec.size() != Dim) // throw std::runtime_error("not matching vector size"); // for (UInt i = 0 ; i < Dim ; ++i ){ // (*this)[i] = vec[i]; // } // } }; template struct Vector<1, T> : public Eigen::Matrix { using Eigen::Matrix::Matrix; Vector<1, T>(const T &val) { (*this)[0] = val; } //operator T() const { return (*this)[0]; } }; // template using Array1D = Eigen::Array; template struct Array1D : public Eigen::Array { using Eigen::Array::Array; using Eigen::Array::operator=; }; // template using ArrayView1D = Eigen::Map>; template struct ArrayView1D : public Eigen::Map> { using Eigen::Map>::Map; }; // template using Matrix = Eigen::Matrix; template struct Matrix : public Eigen::Matrix { using Eigen::Matrix::Matrix; }; // template using VectorView = Eigen::Map>; template struct VectorView : public Eigen::Map> { using Eigen::Map>::Map; using Eigen::Map>::Map::operator=; }; // template using MatrixView = Eigen::Map>; template struct MatrixView : public Eigen::Map> { using Eigen::Map>::Map; }; template bool isNaN(T t) { Eigen::ArrayXd a(t); return a.isNaN().any(); } template bool isInf(T t) { Eigen::ArrayXd a(t); return a.isInf().any(); } enum FieldType { _position0 = 0, _position = 1, _displacement = 2, _velocity = 3, _force = 4, _stress = 5, _temperature = 6, _grouprank = 7, _strain = 8, _epot = 9, _applied_force = 10, _mass = 11, _tag = 12, _id = 13, _proc = 14, _charge = 15, ft_uninitialised = 32767 }; template struct FieldTraits { using TensorType = Vector; using TensorViewType = VectorView; }; +template struct FieldTraits { + using TensorType = Vector<1>; + using TensorViewType = VectorView<1>; +}; + /* -------------------------------------------------------------------------- */ // VectorProxy set of classes // helpful to wrap n variables (of the same type) // and manipulate them/convert them as an eigen vector template struct vector_proxy_getter { static Real &item_getter(T &v, UInt i) { if (dim == i) return std::get(v); return vector_proxy_getter::item_getter(v, i); } }; template struct vector_proxy_getter { static Real &item_getter(T &v, UInt i) { return *new Real(std::nan("1")); } }; template struct vector_proxy { vector_proxy(T tup) : tup(tup){}; auto &operator[](UInt i) { return vector_proxy_getter::value - 1>::item_getter( this->tup, i); } T tup; }; template struct real_tuple { using type = typename real_tuple::type; }; template struct real_tuple<0, Args...> { using type = std::tuple; }; template struct VectorProxy : public vector_proxy::type> { using tuple_type = typename real_tuple::type; template VectorProxy(Args &... args) : vector_proxy(tuple_type(args...)){}; operator Eigen::Matrix() { Eigen::Matrix res; for (UInt i = 0; i < Dim; ++i) res[i] = (*this)[i]; return res; } operator Vector() { Vector res; for (UInt i = 0; i < Dim; ++i) res[i] = (*this)[i]; return res; } }; /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ #endif /* __LIBMULTISCALE_LM_TYPES_HH__ */ diff --git a/src/common/reference_manager.hh b/src/common/reference_manager.hh index 4b30c4b..4fc3e03 100644 --- a/src/common/reference_manager.hh +++ b/src/common/reference_manager.hh @@ -1,185 +1,185 @@ /** * @file reference_manager.hh * * @author Guillaume Anciaux * * @date Mon Sep 08 23:40:22 2014 * * @brief This is the manager of reference and coherency with migrations * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ #ifndef __LIBMULTISCALE_REFERENCE_MANAGER_HH__ #define __LIBMULTISCALE_REFERENCE_MANAGER_HH__ /* -------------------------------------------------------------------------- */ #include "ref_point_data.hh" #include "ref_set.hh" #include "ref_subset.hh" #include "reference_manager_interface.hh" #include #include /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ template class ReferenceManager : public ReferenceManagerInterface { public: /* ------------------------------------------------------------------------ */ /* Typedefs */ /* ------------------------------------------------------------------------ */ typedef typename Ref::Domain::ContainerPoints GlobalContainer; typedef std::map BufferMap; typedef std::map MapRefToUInt; typedef std::map MapRefToRef; typedef std::map> MapUIntToRefList; /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ virtual ~ReferenceManager(){}; ReferenceManager(typename Ref::Domain::ContainerPoints &global_container) : global_set(global_container, "global-container"), have_changed(false){}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ //! function that start the updating process of all attached structures void updateRefSubSets(); //! set the mpi communicator - void setMPIComm(MPI_Comm comm) { - worldCom = comm; + void setCommGroup(CommGroup & comm) { + worldCom = comm.getMPICommGroup(); if (worldCom != MPI_COMM_NULL) MPI_Comm_rank(worldCom, &rank); } //! request to manage a subset void addSubSet(const std::string &name, ContainerArray &sub); //! request to remove a subset void removeSubSet(const LMID &name); //! request attaching a given vector v with a given container c void attachVector(std::vector &v, ContainerArray &c, UInt nb_components = 1); //! request attaching a given vector v with the global container void attachVector(std::vector &v, GlobalContainer &cont, UInt nb_components = 1); //! request detaching a given vector v with a given container c void detachVector(std::vector &v, ContainerArray &c); //! request detaching a given vector v with the global container void detachVector(std::vector &v, GlobalContainer &cont); //! request attaching a generic AttachedObject with a given container c void attachObject(AttachedObject &obj, ContainerArray &c); //! request detaching a generic AttachedObject with a given container c void detachObject(AttachedObject &obj, ContainerArray &c); //! print bilan for concerned container : used only to debug void printBilan(); protected: //! generic communication routine to send/recv a bunch of buffers void exchangeBuffers(BufferMap &toSend, BufferMap &toRecv); //! translate the references for moved atoms void translateMovingReferences(); //! pack masks to a BufferMap void packMasks(MapRefToUInt &masks); //! unpack masks to a BufferMap void unpackMasks(MapRefToUInt &masks); //! clear the buffers and/or create one entry per proc I should com with void clearPackBuffers(); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ public: protected: //! global set RefSet global_set; //! subset array std::map>>> subsets; //! mapping between sent atom ref and new proc owner MapRefToUInt sent; //! inverse mapping : sent atoms sorted by receiving processors MapUIntToRefList sent_byproc; //! new atoms generated by migration (received) MapUIntToRefList newatoms; //! communication buffers to be sent BufferMap buffers_tosend; //! communication buffers to be received BufferMap buffers_torecv; //! mapping between moved atoms old ref and new ref MapRefToRef moved; //! flag to notify if updating of attached references needed bool have_changed; //! for debug purpose void printPackBuffersStatus(); private: MPI_Comm worldCom; int rank; }; /* -------------------------------------------------------------------------- */ template struct ReferenceManager> : public ReferenceManagerInterface { }; /* -------------------------------------------------------------------------- */ template <> struct ReferenceManager : public ReferenceManagerInterface { void removeSubSet(const LMID &name){}; }; /* -------------------------------------------------------------------------- */ template <> struct ReferenceManager : public ReferenceManagerInterface { void removeSubSet(const LMID &name){}; }; /* -------------------------------------------------------------------------- */ class RefElemMeca1D; template <> struct ReferenceManager : public ReferenceManagerInterface { void removeSubSet(const LMID &name){}; }; /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_REFERENCE_MANAGER_HH__ */ diff --git a/src/communicator/communicator.cc b/src/communicator/communicator.cc index 06d5090..093f64b 100644 --- a/src/communicator/communicator.cc +++ b/src/communicator/communicator.cc @@ -1,41 +1,51 @@ /** * @file communicator.cc * * @author Guillaume Anciaux * * @date Fri Mar 08 09:36:00 2013 * * @brief Mother class of LM communicators * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #include "communicator.hh" #include "lm_common.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ -Communicator *Communicator::communicator = NULL; +template <> +std::unique_ptr> IDManager::static_pointer; /* -------------------------------------------------------------------------- */ + +Communicator &Communicator::getCommunicator() { + if (!static_pointer) + LM_FATAL("singleton not implemented"); + + Communicator &ref = dynamic_cast(*static_pointer); + return ref; +}; + __END_LIBMULTISCALE__ diff --git a/src/communicator/communicator.hh b/src/communicator/communicator.hh index da209d4..62258c2 100644 --- a/src/communicator/communicator.hh +++ b/src/communicator/communicator.hh @@ -1,586 +1,630 @@ /** * @file communicator.hh * * @author Guillaume Anciaux * * @date Fri Nov 08 12:44:53 2013 * * @brief Mother class of LM communicators * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ #ifndef __LIBMULTISCALE_COMMUNICATOR_HH__ #define __LIBMULTISCALE_COMMUNICATOR_HH__ /* -------------------------------------------------------------------------- */ #include "comm_buffer.hh" +#include "comm_group.hh" +#include "id_manager.hh" #include "tensor.hh" +#include #include /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ class Geometry; /* -------------------------------------------------------------------------- */ -class Communicator { +class Communicator : public IDManager { public: - /* -------------------------------------------------------------------------- - */ - // Constructor/desctructor - /* -------------------------------------------------------------------------- - */ - virtual ~Communicator(){}; - /* ------------------------------------------------------------------------ */ - /* Class Members */ - /* ------------------------------------------------------------------------ */ - //! return the communicator used - static Communicator &getCommunicator() { - if (!communicator) - LM_THROW("communicator not already created"); - return *communicator; - }; + static Communicator &getCommunicator(); //! set the communicator template static void createCommunicator() { - if (communicator) - LM_THROW("communicator was already created"); - communicator = new T(); + Communicator::getManager(); }; - /* -------------------------------------------------------------------------- - */ - // Virtual functions - /* -------------------------------------------------------------------------- - */ - - //! test if am i in the group specified by ID - virtual bool amIinGroup(CommGroup group_index) = 0; //! add a group of nb_proc processors - virtual UInt addGroup(UInt nb_procs) = 0; + virtual void addGroup(const LMID &id, UInt nb_procs) = 0; //! return the equivalent MPI group from one group ID - virtual MPI_Comm getMpiGroup(CommGroup group_index) = 0; + // virtual MPI_Comm getMpiGroup(CommGroup &group_index) = 0; + + UInt getNbGroups(){return objects.size();}; + auto &getGroups() { return objects; }; + static auto &getGroup(const LMID &id) { + return Communicator::getCommunicator().getObject(id); + }; + + //! wait for unsynchronisated comunications + virtual void waitForPendingComs() = 0; + + // //! test if am i in the group specified by ID + // virtual bool amIinGroup(const LMID &id) { + // return this->amIinGroup(this->getObject(id)); + // }; + //! test if am i in the group specified by ID + // virtual bool amIinGroup(CommGroup &group_index) = 0; //! barrier for a given group (no param is a barrier on all processors) - virtual void synchronize(CommGroup group_index = group_all) = 0; + // virtual void synchronize(const LMID & group_index = "group_all") = 0; //! return number of processors present in group specified - virtual UInt getNBprocsOnGroup(CommGroup i) = 0; + // virtual UInt getNBprocsOnGroup(CommGroup &i) = 0; //! return my real rank from a group rank and group ID - virtual UInt realRank(UInt i, CommGroup group) = 0; + // virtual UInt absoluteRank(UInt i, CommGroup &group) = 0; //! return my group rank from a real rank and group ID - virtual UInt groupRank(UInt i, CommGroup group) = 0; - virtual bool isInGroup(UInt i, CommGroup group) = 0; - virtual UInt getNBGroups() = 0; - //! wait for unsynchronisated comunications - virtual void waitForPendingComs() = 0; + // virtual UInt groupRank(UInt i, CommGroup &group) = 0; + // virtual bool isInGroup(UInt i, CommGroup &group) = 0; + //! global comunication over a group to send geometries structures - virtual void sendLocalGeometriesToGroup(Geometry &geom, CommGroup group) = 0; + // virtual void sendLocalGeometriesToGroup(Geometry &geom, CommGroup &group) = + // 0; //! global comunication over a group to receive geometries structures - virtual void receiveLocalGeometriesFromGroup(Geometry **geom, - CommGroup group) = 0; + // virtual void receiveLocalGeometriesFromGroup(Geometry **geom, + // CommGroup &group) = 0; //! global comunication Over a group to send boolean tables - virtual void sendCommunicationTable(std::vector &com_with, - CommGroup destgroup) = 0; + // virtual void sendCommunicationTable(std::vector &com_with, + // CommGroup &destgroup) = 0; //! global comunication over a group to receive boolean tables - virtual void receiveCommunicationTable(std::vector &com_with, - CommGroup fromgroup) = 0; + // virtual void receiveCommunicationTable(std::vector &com_with, + // CommGroup &fromgroup) = 0; //! receive array from a processor on by its ID in a given group - virtual void receiveUInts(CommBuffer &d, UInt nb, UInt from, - CommGroup group, const std::string &comment) = 0; + // virtual void receiveUInts(CommBuffer &d, UInt nb, UInt from, + // CommGroup &group, const std::string &comment) = + // 0; //! send array to a processor on by its ID in a given group - virtual void sendUInts(CommBuffer &i, UInt nb, UInt dest, - CommGroup group, const std::string &comment) = 0; + // virtual void sendUInts(CommBuffer &i, UInt nb, UInt dest, + // CommGroup &group, const std::string &comment) = 0; //! receive array from a processor on by its ID in a given group - virtual void receiveReals(CommBuffer &d, UInt nb, UInt from, - CommGroup group, const std::string &comment) = 0; + // virtual void receiveReals(CommBuffer &d, UInt nb, UInt from, + // CommGroup &group, const std::string &comment) = + // 0; //! send array to a processor on by its ID in a given group - virtual void sendReals(CommBuffer &i, UInt nb, UInt dest, - CommGroup group, const std::string &comment) = 0; + // virtual void sendReals(CommBuffer &i, UInt nb, UInt dest, + // CommGroup &group, const std::string &comment) = 0; //! reduction operation over a given group - virtual void reduceUInt(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op) = 0; + // virtual void reduceUInt(CommBuffer &contrib, UInt nb, CommGroup + // &group, + // const std::string &comment, Operator op) = 0; //! reduction operation over a given group - virtual void reduceReal(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op) = 0; + // virtual void reduceReal(CommBuffer &contrib, UInt nb, CommGroup + // &group, + // const std::string &comment, Operator op) = 0; //! reduction operation over a given group - virtual void allReduceUInt(CommBuffer &contrib, UInt nb, - CommGroup group, const std::string &comment, - Operator op) = 0; + // virtual void allReduceUInt(CommBuffer &contrib, UInt nb, + // CommGroup &group, const std::string &comment, + // Operator op) = 0; //! reduction operation over a given group - virtual void allReduceReal(CommBuffer &contrib, UInt nb, - CommGroup group, const std::string &comment, - Operator op) = 0; + // virtual void allReduceReal(CommBuffer &contrib, UInt nb, + // CommGroup &group, const std::string &comment, + // Operator op) = 0; // //! broadcast over a given group // virtual void broadcastUInt(CommBuffer & contrib,UInt nb,CommGroup // group, // const std::string & comment)=0; // //! broadcast over a given group // virtual void broadcastReal(CommBuffer & contrib,UInt nb,CommGroup // group, // const std::string & comment)=0; // //! gathering operation over a given group // virtual void gatherUInt(CommBuffer & contrib,UInt nb,CommBuffer // & receive, // UInt to,CommGroup group, const std::string & // comment)=0; // //! gathering operation over a given group // virtual void gatherReal(CommBuffer & contrib,UInt nb,CommBuffer // & receive, // UInt to,CommGroup group, const std::string & // comment)=0; //! printself function - virtual void printself(std::ostream &stream){}; + // virtual void printself(std::ostream &stream){}; /* -------------------------------------------------------------------------- */ // Generic functions /* -------------------------------------------------------------------------- */ // receive functions //! receive an nb-data array from a processor specified by its ID in a given //! group - template - inline void receive(std::vector &d, UInt nb, UInt from, CommGroup group, - const std::string &comment); - //! receive array from a processor specified by its ID in a given group - template - inline void receive(std::vector &d, UInt from, CommGroup group, - const std::string &comment); - //! receive an nb-data array from a processor specified by its ID in a given - //! group - template - inline void receive(CommBuffer &d, UInt nb, UInt from, CommGroup group, - const std::string &comment); - //! receive array from a processor specified by its ID in a given group - template - inline void receive(CommBuffer &d, UInt from, CommGroup group, - const std::string &comment); - //! receive a C-style array from a processor specified by its ID in a given - //! group - template - inline void receive(T *d, UInt nb, UInt from, CommGroup group, - const std::string &comment); - - // sending functions - - //! send an nb-data array to a processor specified by its ID in a given group - template - inline void send(std::vector &d, UInt nb, UInt to, CommGroup group, - const std::string &comment); - //! send array to a processor specified by its ID in a given group - template - inline void send(std::vector &d, UInt to, CommGroup group, - const std::string &comment); - //! send an nb-data array to a processor specified by its ID in a given group - template - inline void send(CommBuffer &d, UInt nb, UInt to, CommGroup group, - const std::string &comment); - //! send array to a processor specified by its ID in a given group - template - inline void send(CommBuffer &d, UInt to, CommGroup group, - const std::string &comment); - //! send a C-style array to a processor specified by its ID in a given group - template - inline void send(T *d, UInt nb, UInt to, CommGroup group, - const std::string &comment); - - // reducing functions - - //! reduce by sum from a commbuffer - template - inline void reduce(CommBuffer &d, UInt nb, CommGroup group, - const std::string &comment, Operator op); - //! reduce from a vector - template - inline void reduce(std::vector &d, UInt nb, CommGroup group, - const std::string &comment, Operator op); - //! reduce a C-style array (for compatibility : involve additional copy) - template - inline void reduce(T *d, UInt nb, CommGroup group, const std::string &comment, - Operator op); - - //! reduce by sum from a commbuffer - template - inline void allReduce(CommBuffer &d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - LM_TOIMPLEMENT; - }; + // template + // inline void receive(std::vector &d, UInt nb, UInt from, CommGroup + // &group, + // const std::string &comment); + // //! receive array from a processor specified by its ID in a given group + // template + // inline void receive(std::vector &d, UInt from, CommGroup &group, + // const std::string &comment); + // //! receive an nb-data array from a processor specified by its ID in a + // given + // //! group + // template + // inline void receive(CommBuffer &d, UInt nb, UInt from, CommGroup &group, + // const std::string &comment); + // //! receive array from a processor specified by its ID in a given group + // template + // inline void receive(CommBuffer &d, UInt from, CommGroup &group, + // const std::string &comment); + // //! receive a C-style array from a processor specified by its ID in a given + // //! group + // template + // inline void receive(T *d, UInt nb, UInt from, CommGroup &group, + // const std::string &comment); + + // // sending functions + + // //! send an nb-data array to a processor specified by its ID in a given + // group + // template + // inline void send(std::vector &d, UInt nb, UInt to, CommGroup &group, + // const std::string &comment); + // //! send array to a processor specified by its ID in a given group + // template + // inline void send(std::vector &d, UInt to, CommGroup &group, + // const std::string &comment); + // //! send an nb-data array to a processor specified by its ID in a given + // group + // template + // inline void send(CommBuffer &d, UInt nb, UInt to, CommGroup &group, + // const std::string &comment); + // //! send array to a processor specified by its ID in a given group + // template + // inline void send(CommBuffer &d, UInt to, CommGroup &group, + // const std::string &comment); + // //! send a C-style array to a processor specified by its ID in a given + // group + // template + // inline void send(T *d, UInt nb, UInt to, CommGroup &group, + // const std::string &comment); + + // // reducing functions + + // //! reduce by sum from a commbuffer + // template + // inline void reduce(CommBuffer &d, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); + // //! reduce from a vector + // template + // inline void reduce(std::vector &d, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); + // //! reduce a C-style array (for compatibility : involve additional copy) + // template + // inline void reduce(T *d, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); + + // //! reduce by sum from a commbuffer + // template + // inline void allReduce(CommBuffer &d, UInt nb, CommGroup &group, + // const std::string &comment, Operator op) { + // LM_TOIMPLEMENT; + // }; - inline void allReduce(Tensor &d, UInt nb, CommGroup group, - const std::string &comment, Operator op); + // inline void allReduce(Tensor &d, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); - //! reduce from a vector - template - inline void allReduce(std::vector &d, UInt nb, CommGroup group, - const std::string &comment, Operator op); - //! reduce a C-style array (for compatibility : involve additional copy) - template - inline void allReduce(T *d, UInt nb, CommGroup group, - const std::string &comment, Operator op); + // //! reduce from a vector + // template + // inline void allReduce(std::vector &d, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); + // //! reduce a C-style array (for compatibility : involve additional copy) + // template + // inline void allReduce(T *d, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); // broadcasting functions // //! broadcast commbuffer // template // inline void broadcast(CommBuffer & d,UInt nb,CommGroup group,const // std::string & comment); // //! broadcast vector // template // inline void broadcast(std::vector & d,UInt nb,CommGroup group,const // std::string & comment); // //! broadcast C-style array // template // inline void broadcast(T *d,UInt nb,CommGroup group,const std::string & // comment); // gather functions // //! gather commbuffer // template // inline void gather(CommBuffer & d,UInt nb, CommBuffer & e, // UInt to, CommGroup group, const std::string & comment); //! gather vector // template // inline void gather(std::vector & d, UInt nb, std::vector & e, // UInt to, CommGroup group, const std::string & comment); // //! reduce a C-style array // template // inline void gather(T *d,UInt nb, T *e, // UInt to, CommGroup group, const std::string & comment); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ - - static Communicator *communicator; }; /* -------------------------------------------------------------------------- */ -template -inline void Communicator::receive(std::vector &d, UInt from, CommGroup group, - const std::string &comment) { - CommBuffer buf(d); - receive(buf, from, group, comment); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::receive(std::vector &d, UInt nb, UInt from, - CommGroup group, const std::string &comment) { - CommBuffer buf(d); - receive(buf, nb, from, group, comment); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::send(std::vector &d, UInt nb, UInt from, - CommGroup group, const std::string &comment) { - CommBuffer buf(d); - send(buf, nb, from, group, comment); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::send(std::vector &d, UInt from, CommGroup group, - const std::string &comment) { - send(d, d.size(), from, group, comment); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::receive(CommBuffer &d, UInt from, CommGroup group, - const std::string &comment) { - receive(d, UINT_MAX, from, group, comment); -} -/* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::receive(CommBuffer &d, UInt nb, UInt from, - CommGroup group, const std::string &comment) { - receiveReals(d, nb, from, group, comment); -} -/* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::send(CommBuffer &d, UInt nb, UInt to, - CommGroup group, const std::string &comment) { - sendReals(d, nb, to, group, comment); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::send(CommBuffer &d, UInt nb, UInt to, - CommGroup group, const std::string &comment) { - - UInt nb_uint = nb * sizeof(T) / sizeof(UInt); - if (sizeof(T) % sizeof(UInt) != 0) - LM_FATAL("have to reimplement this shit"); - - std::vector buf(nb_uint); - memcpy(&buf[0], d.buffer(), sizeof(UInt) * nb_uint); - auto c_buf = CommBuffer(buf); - sendUInts(c_buf, nb_uint, to, group, comment); -} -/* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::send(CommBuffer &d, UInt nb, UInt to, - CommGroup group, const std::string &comment) { - sendUInts(d, nb, to, group, comment); -} -/* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::receive(CommBuffer &d, UInt nb, UInt from, - CommGroup group, const std::string &comment) { - receiveUInts(d, nb, from, group, comment); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::receive(CommBuffer &d, UInt nb, UInt from, - CommGroup group, const std::string &comment) { - - UInt nb_uint = nb * sizeof(T) / sizeof(UInt); - if (sizeof(T) % sizeof(UInt) != 0) - LM_FATAL("have to reimplement this shit"); - - std::vector buf(nb_uint); - auto c_buf = CommBuffer(buf); - receiveUInts(c_buf, nb_uint, from, group, comment); - memcpy(d.buffer(), &buf[0], sizeof(UInt) * nb_uint); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::send(CommBuffer &d, UInt from, CommGroup group, - const std::string &comment) { - send(d, d.size(), from, group, comment); -} +// template +// inline void Communicator::receive(std::vector &d, UInt from, +// CommGroup &group, +// const std::string &comment) { +// CommBuffer buf(d); +// receive(buf, from, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::receive(std::vector &d, UInt nb, UInt from, +// CommGroup &group, +// const std::string &comment) { +// CommBuffer buf(d); +// receive(buf, nb, from, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::send(std::vector &d, UInt nb, UInt from, +// CommGroup &group, const std::string &comment) +// { +// CommBuffer buf(d); +// send(buf, nb, from, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::send(std::vector &d, UInt from, CommGroup +// &group, +// const std::string &comment) { +// send(d, d.size(), from, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::receive(CommBuffer &d, UInt from, CommGroup +// &group, +// const std::string &comment) { +// receive(d, UINT_MAX, from, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template <> +// inline void Communicator::receive(CommBuffer &d, UInt nb, UInt from, +// CommGroup &group, +// const std::string &comment) { +// receiveReals(d, nb, from, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template <> +// inline void Communicator::send(CommBuffer &d, UInt nb, UInt to, +// CommGroup &group, const std::string &comment) +// { +// sendReals(d, nb, to, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::send(CommBuffer &d, UInt nb, UInt to, +// CommGroup &group, const std::string &comment) +// { + +// UInt nb_uint = nb * sizeof(T) / sizeof(UInt); +// if (sizeof(T) % sizeof(UInt) != 0) +// LM_FATAL("have to reimplement this shit"); + +// std::vector buf(nb_uint); +// memcpy(&buf[0], d.buffer(), sizeof(UInt) * nb_uint); +// auto c_buf = CommBuffer(buf); +// sendUInts(c_buf, nb_uint, to, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template <> +// inline void Communicator::send(CommBuffer &d, UInt nb, UInt to, +// CommGroup &group, const std::string &comment) +// { +// sendUInts(d, nb, to, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template <> +// inline void Communicator::receive(CommBuffer &d, UInt nb, UInt from, +// CommGroup &group, +// const std::string &comment) { +// receiveUInts(d, nb, from, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::receive(CommBuffer &d, UInt nb, UInt from, +// CommGroup &group, +// const std::string &comment) { + +// UInt nb_uint = nb * sizeof(T) / sizeof(UInt); +// if (sizeof(T) % sizeof(UInt) != 0) +// LM_FATAL("have to reimplement this shit"); + +// std::vector buf(nb_uint); +// auto c_buf = CommBuffer(buf); +// receiveUInts(c_buf, nb_uint, from, group, comment); +// memcpy(d.buffer(), &buf[0], sizeof(UInt) * nb_uint); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::send(CommBuffer &d, UInt from, CommGroup &group, +// const std::string &comment) { +// send(d, d.size(), from, group, comment); +// } -/* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::reduce(CommBuffer &d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - reduceReal(d, nb, group, comment, op); -} -/* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::reduce(CommBuffer &d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - reduceUInt(d, nb, group, comment, op); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::reduce(std::vector &d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - CommBuffer buf(d); - reduce(buf, nb, group, comment, op); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::reduce(T *d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - CommBuffer buf; - buf.resize(nb); - std::copy(d, d + nb, buf.buffer()); - reduce(buf, nb, group, comment, op); - std::copy(buf.buffer(), buf.buffer() + nb, d); -} +// /* -------------------------------------------------------------------------- +// */ +// template <> +// inline void Communicator::reduce(CommBuffer &d, UInt nb, CommGroup +// &group, +// const std::string &comment, Operator op) { +// reduceReal(d, nb, group, comment, op); +// } +// /* -------------------------------------------------------------------------- +// */ +// template <> +// inline void Communicator::reduce(CommBuffer &d, UInt nb, CommGroup +// &group, +// const std::string &comment, Operator op) { +// reduceUInt(d, nb, group, comment, op); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::reduce(std::vector &d, UInt nb, CommGroup +// &group, +// const std::string &comment, Operator op) { +// CommBuffer buf(d); +// reduce(buf, nb, group, comment, op); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::reduce(T *d, UInt nb, CommGroup &group, +// const std::string &comment, Operator op) { +// CommBuffer buf; +// buf.resize(nb); +// std::copy(d, d + nb, buf.buffer()); +// reduce(buf, nb, group, comment, op); +// std::copy(buf.buffer(), buf.buffer() + nb, d); +// } // /* -------------------------------------------------------------------------- // */ // template <> // inline void Communicator::broadcast(CommBuffer & d,UInt nb,CommGroup // group, // const std::string & comment){ // broadcastReal(d,nb,group,comment); // } // /* -------------------------------------------------------------------------- // */ // template <> // inline void Communicator::broadcast(CommBuffer & d,UInt nb,CommGroup // group, // const std::string & comment){ // broadcastUInt(d,nb,group,comment); // } // /* -------------------------------------------------------------------------- // */ // template // inline void Communicator::broadcast(std::vector & d,UInt nb,CommGroup // group, // const std::string & comment){ // CommBuffer buf(d); // broadcast(buf,nb,group,comment); // } // /* -------------------------------------------------------------------------- // */ // template // inline void Communicator::broadcast(T *d,UInt nb,CommGroup group, // const std::string & comment){ // CommBuffer buf; // buf.resize(nb); // std::copy(d,d+nb,buf.buffer()); // broadcast(buf,nb,group,comment); // std::copy(buf.buffer(),buf.buffer()+nb,d); // } // /* -------------------------------------------------------------------------- // */ // template <> // inline void Communicator::gather(CommBuffer & d,UInt nb, // CommBuffer & e, // UInt to, CommGroup group, const std::string & // comment){ // gatherReal(d,nb,e,to,group,comment); // } // /* -------------------------------------------------------------------------- // */ // template <> // inline void Communicator::gather(CommBuffer & d,UInt nb, // CommBuffer & e, // UInt to, CommGroup group,const std::string & // comment){ // gatherUInt(d,nb,e,to,group,comment); // } // /* -------------------------------------------------------------------------- // */ // template // inline void Communicator::gather(std::vector & d,UInt nb, std::vector & // e, // UInt to, CommGroup group, const std::string & // comment){ // CommBuffer buf1(d); // CommBuffer buf2(e); // gather(buf1,nb,buf2,to,group,comment); // } // /* -------------------------------------------------------------------------- // */ // template // inline void Communicator::gather(T *d,UInt nb,T *e,UInt to,CommGroup group, // const std::string & comment){ // // CommBuffer buf1; // // buf1.resize(nb); // // std::copy(d,d+nb,buf1.buffer()); // // CommBuffer buf2; // // buf2.resize(nb); // // std::copy(e,e+nb,buf2.buffer()); // gather(d,nb,e,to,group,comment); // // // std::copy(buf1.buffer(),buf1.buffer()+nb,d); // // // std::copy(buf2.buffer(),buf2.buffer()+nb,d); // } /* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::allReduce(CommBuffer &d, UInt nb, - CommGroup group, const std::string &comment, - Operator op) { - allReduceReal(d, nb, group, comment, op); -} -/* -------------------------------------------------------------------------- */ -template <> -inline void Communicator::allReduce(CommBuffer &d, UInt nb, - CommGroup group, const std::string &comment, - Operator op) { - allReduceUInt(d, nb, group, comment, op); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::allReduce(std::vector &d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - CommBuffer buf(d); - allReduce(buf, nb, group, comment, op); -} -/* -------------------------------------------------------------------------- */ +// template <> +// inline void Communicator::allReduce(CommBuffer &d, UInt nb, +// CommGroup &group, +// const std::string &comment, Operator op) +// { +// allReduceReal(d, nb, group, comment, op); +// } +// /* -------------------------------------------------------------------------- +// */ +// template <> +// inline void Communicator::allReduce(CommBuffer &d, UInt nb, +// CommGroup &group, +// const std::string &comment, Operator op) +// { +// allReduceUInt(d, nb, group, comment, op); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::allReduce(std::vector &d, UInt nb, +// CommGroup &group, +// const std::string &comment, Operator op) +// { +// CommBuffer buf(d); +// allReduce(buf, nb, group, comment, op); +// } +// /* -------------------------------------------------------------------------- +// */ -template -inline void Communicator::allReduce(T *d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - CommBuffer buf; - buf.resize(nb); - std::copy(d, d + nb, buf.buffer()); - allReduce(buf, nb, group, comment, op); - std::copy(buf.buffer(), buf.buffer() + nb, d); -} +// template +// inline void Communicator::allReduce(T *d, UInt nb, CommGroup &group, +// const std::string &comment, Operator op) +// { +// CommBuffer buf; +// buf.resize(nb); +// std::copy(d, d + nb, buf.buffer()); +// allReduce(buf, nb, group, comment, op); +// std::copy(buf.buffer(), buf.buffer() + nb, d); +// } -/* -------------------------------------------------------------------------- */ +// /* -------------------------------------------------------------------------- +// */ -inline void Communicator::allReduce(Tensor &d, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - allReduce(d.getVec(), d.size(), group, comment, op); -} +// inline void Communicator::allReduce(Tensor &d, UInt nb, CommGroup &group, +// const std::string &comment, Operator op) +// { +// allReduce(d.getVec(), d.size(), group, comment, op); +// } -/* -------------------------------------------------------------------------- */ +// /* -------------------------------------------------------------------------- +// */ -template -inline void Communicator::send(T *d, UInt nb, UInt to, CommGroup group, - const std::string &comment) { - CommBuffer buf; - buf.resize(nb); - std::copy(d, d + nb, buf.buffer()); - send(buf, nb, to, group, comment); -} -/* -------------------------------------------------------------------------- */ -template -inline void Communicator::receive(T *d, UInt nb, UInt from, CommGroup group, - const std::string &comment) { - CommBuffer buf; - buf.resize(nb); - receive(buf, nb, from, group, comment); - std::copy(buf.buffer(), buf.buffer() + nb, d); -} -/* -------------------------------------------------------------------------- */ -inline std::ostream &operator<<(std::ostream &os, Communicator &c) { - c.printself(os); - return os; -} -/* -------------------------------------------------------------------------- */ +// template +// inline void Communicator::send(T *d, UInt nb, UInt to, CommGroup &group, +// const std::string &comment) { +// CommBuffer buf; +// buf.resize(nb); +// std::copy(d, d + nb, buf.buffer()); +// send(buf, nb, to, group, comment); +// } +// /* -------------------------------------------------------------------------- +// */ +// template +// inline void Communicator::receive(T *d, UInt nb, UInt from, CommGroup &group, +// const std::string &comment) { +// CommBuffer buf; +// buf.resize(nb); +// receive(buf, nb, from, group, comment); +// std::copy(buf.buffer(), buf.buffer() + nb, d); +// } +// /* -------------------------------------------------------------------------- +// */ +// inline std::ostream &operator<<(std::ostream &os, Communicator &c) { +// c.printself(os); +// return os; +// } +// /* -------------------------------------------------------------------------- +// */ __END_LIBMULTISCALE__ //#include "communicator_world.hh" //__BEGIN_LIBMULTISCALE__ // static WorldCommunicator WORLD_COMMUNICATOR; ///* -------------------------------------------------------------------------- ///*/ //__END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_COMMUNICATOR_HH__ */ diff --git a/src/communicator/communicator_mpi_linear.cc b/src/communicator/communicator_mpi_linear.cc index 26fa88f..2abdcfb 100644 --- a/src/communicator/communicator_mpi_linear.cc +++ b/src/communicator/communicator_mpi_linear.cc @@ -1,681 +1,662 @@ /** * @file communicator_mpi_linear.cc * * @author Guillaume Anciaux * * @date Mon Jul 28 15:36:04 2014 * * @brief This is the implementation of the LM communicator using MPI where * models are distributed over processors * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #define TIMER #include "communicator_mpi_linear.hh" #include "ball.hh" #include "cube.hh" #include "geometry.hh" #include "lm_common.hh" #include /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ LinearMPI::~LinearMPI() { // MPI_Type_free(&geom_type); } /* -------------------------------------------------------------------------- */ LinearMPI::LinearMPI() { DUMP("creating linear mpi communicateur", DBG_INFO); - MPI_Comm_size(MPI_COMM_WORLD, &n_procs); - free_procs = (UInt)n_procs; - nb_groups = 0; - goffsets[0] = 0; + int n_proc; + MPI_Comm_size(MPI_COMM_WORLD, &n_proc); + nb_procs = n_proc; + // free_procs = (UInt)n_procs; // creation des types specifiques au transport de mes objets int blocks[3]; MPI_Aint disp[3]; MPI_Datatype types[3]; blocks[0] = 2; types[0] = MPI_UNSIGNED; blocks[1] = 11; types[1] = MPI_DOUBLE; blocks[2] = 1; types[2] = MPI_UB; - mpi_geom MpiGeom; + MPIGeom mpi_geom; - void *add = &MpiGeom.type; + void *add = &mpi_geom.type; MPI_Get_address(add, disp); - add = MpiGeom.center; + add = mpi_geom.center; MPI_Get_address(add, disp + 1); - add = &MpiGeom + 1; + add = &mpi_geom + 1; MPI_Get_address(add, disp + 2); MPI_Aint base = disp[0]; for (UInt i = 0; i < 3; ++i) disp[i] -= base; // for (UInt i=0;i < 3;++i){ // DUMP("deplacement calcule pour voir : " //<< disp[i] << " et base = " << base); //} MPI_Type_struct(3, blocks, disp, types, &geom_type); MPI_Type_commit(&geom_type); - sequence_number.resize(lm_world_size); + // sequence_number.resize(lm_world_size); - for (UInt i = 0; i < lm_world_size; ++i) - sequence_number[0] = 0; + // for (UInt i = 0; i < lm_world_size; ++i) + // sequence_number[0] = 0; } /* -------------------------------------------------------------------------- */ -UInt LinearMPI::addGroup(UInt nb_procs) { +void LinearMPI::addGroup(const LMID &id, UInt nb_procs) { /* TODO : faire le parser pour le domaine global */ /* en attendant je creer deux sous group de avec un group de 1 pour */ /* l'elasticite lineaire */ int color; + auto free_procs = this->getFreeProcs(); + if (free_procs < nb_procs) { LM_FATAL( "While trying to add " << nb_procs << " procs: There are not enough processors for the required topology!" << "(only " << free_procs << " are available)"); } + MPIGroup new_group(id, nb_procs); + auto nb_groups = objects.size(); + this->addObject(new_group); DUMP("Building processor group number " << nb_groups, DBG_INFO); if (lm_my_proc_id < free_procs && lm_my_proc_id >= free_procs - nb_procs) color = 0; else color = MPI_UNDEFINED; DUMP("free_procs " << free_procs << " nb_procs " << nb_procs << " diff " << free_procs - nb_procs << " color " << color, DBG_ALL); - MPI_Comm_split(MPI_COMM_WORLD, color, lm_my_proc_id, &groups[nb_groups]); - DUMP("group pointer (" << nb_groups << ")=" << groups[nb_groups], DBG_DETAIL); + MPI_Comm_split(MPI_COMM_WORLD, color, lm_my_proc_id, &(new_group.mpi_ID)); + DUMP("group pointer (" << nb_groups << ")=" << new_group, DBG_DETAIL); MPI_Barrier(MPI_COMM_WORLD); - - DUMP("processor " << lm_my_proc_id << " group " << nb_groups << " built", + DUMP("for proc " << lm_my_proc_id << ", group " << nb_groups << " built", DBG_INFO); - taille_groups[nb_groups] = nb_procs; - free_procs -= nb_procs; - goffsets[nb_groups] = free_procs; - ++nb_groups; - - return (nb_groups - 1); + UInt proc_id = 0; + for (auto &p : new_group) { + p.mpi_rank = proc_id + free_procs; + p.id = proc_id; + ++proc_id; + } }; /* -------------------------------------------------------------------------- */ -void LinearMPI::sendLocalGeometriesToGroup(Geometry &geom, CommGroup group) { - mpi_geom s; +void LinearMPI::sendLocalGeometriesToGroup(Geometry &geom, CommGroup &group) { + MPIGeom s; s.type = geom.getType(); DUMP("sending geometry of type " << s.type << " " << geom, DBG_INFO); s.Dim = geom.getDim(); s.center[0] = geom.getCenter(0); s.center[1] = geom.getCenter(1); s.center[2] = geom.getCenter(2); switch (s.type) { case Geometry::BALL: { Ball &b = static_cast(geom); s.rmin = b.rMin(); s.rmax = b.rMax(); } break; case Geometry::CUBE: { Cube &c = dynamic_cast(geom); s.xmax = c.getXmax()[0]; s.xmin = c.getXmin()[0]; s.ymax = c.getXmax()[1]; s.ymin = c.getXmin()[1]; s.zmax = c.getXmax()[2]; s.zmin = c.getXmin()[2]; } break; default: LM_FATAL( "geometry " << s.type << " cannot be sent through network (to be implemented?)"); break; } - for (UInt i = 0; i < taille_groups[group.getID()]; ++i) { - DUMP("sending geometry to " << i + goffsets[group.getID()] - << " - seq number " - << sequence_number[i + goffsets[group.getID()]], + auto &mpi_group = dynamic_cast(group); + for (auto &proc : mpi_group) { + DUMP("sending geometry to " << proc.mpi_rank << " - seq number " + << proc.sequence_number, DBG_INFO); - MPI_Send(&s, 1, geom_type, i + goffsets[group.getID()], - sequence_number[i + goffsets[group.getID()]], MPI_COMM_WORLD); - DUMP("geometry Sent to " << i + goffsets[group.getID()] << " - seq number " - << sequence_number[i + goffsets[group.getID()]], - DBG_INFO); - ++sequence_number[i + goffsets[group.getID()]]; + LM_TOIMPLEMENT; + // MPI_Send(&s, 1, geom_type, i + group_offsets[group.getID()], + // sequence_number[i + group_offsets[group.getID()]], + // MPI_COMM_WORLD); + // DUMP("geometry Sent to " + // << i + group_offsets[group.getID()] << " - seq number " + // << sequence_number[i + group_offsets[group.getID()]], + // DBG_INFO); + // ++sequence_number[i + group_offsets[group.getID()]]; } } /* -------------------------------------------------------------------------- */ void LinearMPI::receiveLocalGeometriesFromGroup(Geometry **geom_tab, - CommGroup group) { + CommGroup &group) { if (!geom_tab) { LM_FATAL("pointeur de geometrie non valide"); } - if (group == group_all || group == group_none) + if (group.getID() == "group_all" || group.getID() == "group_none") LM_FATAL("invalid communicator"); - if (group.getID() >= (int)nb_groups) { - LM_FATAL("le group specifie existe pas : " << group); - } - - mpi_geom *s = new mpi_geom[taille_groups[group.getID()]]; - memset(s, 0, sizeof(mpi_geom) * taille_groups[group.getID()]); - DUMP("normalement je m'aprete a recevoir " << taille_groups[group.getID()] - << " structure mpi_geom", - DBG_DETAIL); - // MPI_Barrier(MPI_COMM_WORLD); - - // reception des messages de l'autre group - MPI_Status status; - - for (UInt i = 0; i < taille_groups[group.getID()]; ++i) { - DUMP("receiving geometry from " - << i + goffsets[group.getID()] << " - seq number " - << sequence_number[i + goffsets[group.getID()]], - DBG_INFO); - MPI_Recv(&s[i], 1, geom_type, goffsets[group.getID()] + i, - sequence_number[i + goffsets[group.getID()]], MPI_COMM_WORLD, - &status); - DUMP("geometry Received from " - << i + goffsets[group.getID()] << " - seq number " - << sequence_number[i + goffsets[group.getID()]], - DBG_INFO); - ++sequence_number[i + goffsets[group.getID()]]; - } - - // conversion des structure MPI en objets concrets - for (UInt i = 0; i < taille_groups[group.getID()]; ++i) { - DUMP("recv geometry of type " << s[i].type, DBG_INFO); - switch (s[i].type) { - case Geometry::BALL: - geom_tab[i] = new Ball(s[i].Dim); - geom_tab[i]->setCenter(s[i].center[0], s[i].center[1], s[i].center[2]); - ((Ball *)geom_tab[i])->setRayons(s[i].rmin, s[i].rmax); - break; - case Geometry::CUBE: - geom_tab[i] = new Cube(s[i].Dim); - // geom_tab[i]->SetCenter(s[i].center[0],s[i].center[1],s[i].center[2]); - dynamic_cast(geom_tab[i]) - ->setDimensions(s[i].xmin, s[i].xmax, s[i].ymin, s[i].ymax, s[i].zmin, - s[i].zmax); - break; - - default: - LM_FATAL("structure MPI indecodable -> type = " - << s[i].type << " received from " - << i + goffsets[group.getID()]); - } - } - delete[] s; + // test if group exists + getObject(group.getID()); + LM_TOIMPLEMENT; + // std::vector s(group_sizes[group.getID()]); + // memset(&s[0], 0, sizeof(MPIGeom) * group_sizes[group.getID()]); + // DUMP("normalement je m'aprete a recevoir " << group_sizes[group.getID()] + // << " structure mpi_geom", + // DBG_DETAIL); + // // reception des messages de l'autre group + // MPI_Status status; + + // for (UInt i = 0; i < group_sizes[group.getID()]; ++i) { + // DUMP("receiving geometry from " + // << i + group_offsets[group.getID()] << " - seq number " + // << sequence_number[i + group_offsets[group.getID()]], + // DBG_INFO); + // MPI_Recv(&s[i], 1, geom_type, group_offsets[group.getID()] + i, + // sequence_number[i + group_offsets[group.getID()]], + // MPI_COMM_WORLD, + // &status); + // DUMP("geometry Received from " + // << i + group_offsets[group.getID()] << " - seq number " + // << sequence_number[i + group_offsets[group.getID()]], + // DBG_INFO); + // ++sequence_number[i + group_offsets[group.getID()]]; + // } + + // // conversion des structure MPI en objets concrets + // for (UInt i = 0; i < group_sizes[group.getID()]; ++i) { + // DUMP("recv geometry of type " << s[i].type, DBG_INFO); + // switch (s[i].type) { + // case Geometry::BALL: + // geom_tab[i] = new Ball(s[i].Dim); + // geom_tab[i]->setCenter(s[i].center[0], s[i].center[1], s[i].center[2]); + // ((Ball *)geom_tab[i])->setRayons(s[i].rmin, s[i].rmax); + // break; + // case Geometry::CUBE: + // geom_tab[i] = new Cube(s[i].Dim); + // dynamic_cast(geom_tab[i]) + // ->setDimensions(s[i].xmin, s[i].xmax, s[i].ymin, s[i].ymax, + // s[i].zmin, + // s[i].zmax); + // break; + + // default: + // LM_FATAL("structure MPI indecodable -> type = " + // << s[i].type << " received from " + // << i + group_offsets[group.getID()]); + // } + // } } /* -------------------------------------------------------------------------- */ void LinearMPI::sendCommunicationTable(std::vector &com_with, - CommGroup destgroup) { + CommGroup &destgroup) { // ici les tableaux a envoyer ont la dimension de la taille de destgroup - UInt desttaille = taille_groups[destgroup.getID()]; + auto &destination_group = dynamic_cast(destgroup); + + UInt i = 0; + for (auto &proc : destination_group) { - for (UInt i = 0; i < desttaille; ++i) { - // UInt size = requests.size(); - // requests.resize(size+1); - // MPI_Isend(&com_with[i],1,MPI_INT,i+goffsets[destgroup], - // sequence_number[i+goffsets[destgroup]],MPI_COMM_WORLD,&requests[size]); - DUMP("Sending " << com_with[i] << " to " << i + goffsets[destgroup.getID()] - << " - seq number " - << sequence_number[i + goffsets[destgroup.getID()]], + DUMP("Sending " << com_with[i] << " to " << proc.mpi_rank + << " - seq number " << proc.sequence_number, DBG_INFO); - MPI_Send(&com_with[i], 1, MPI_INT, i + goffsets[destgroup.getID()], - sequence_number[i + goffsets[destgroup.getID()]], MPI_COMM_WORLD); + MPI_Send(&com_with[i], 1, MPI_INT, proc.mpi_rank, proc.sequence_number, + MPI_COMM_WORLD); - DUMP("Sent " << com_with[i] << " to " << i + goffsets[destgroup.getID()] - << " - seq number " - << sequence_number[i + goffsets[destgroup.getID()]], + DUMP("Sent " << com_with[i] << " to " << proc.mpi_rank << " - seq number " + << proc.sequence_number, DBG_INFO); - ++sequence_number[i + goffsets[destgroup.getID()]]; + ++proc.sequence_number; + ++i; } } /* -------------------------------------------------------------------------- */ void LinearMPI::receiveCommunicationTable(std::vector &com_with, - CommGroup fromgroup) { + CommGroup &fromgroup) { // ici les tableaux a remplir ont la taille de fromgroup - UInt fromtaille = taille_groups[fromgroup.getID()]; + auto &from_group = dynamic_cast(fromgroup); MPI_Status status; - for (UInt i = 0; i < fromtaille; ++i) { - DUMP("Receiving from " << i + goffsets[fromgroup.getID()] - << " - seq number " - << sequence_number[i + goffsets[fromgroup.getID()]], + UInt i = 0; + for (auto &proc : from_group) { + DUMP("Receiving from " << proc.mpi_rank << " - seq number " + << proc.sequence_number, DBG_INFO); - MPI_Recv(&com_with[i], 1, MPI_INT, i + goffsets[fromgroup.getID()], - sequence_number[i + goffsets[fromgroup.getID()]], MPI_COMM_WORLD, - &status); + MPI_Recv(&com_with[i], 1, MPI_INT, proc.mpi_rank, proc.sequence_number, + MPI_COMM_WORLD, &status); - DUMP("Received " << com_with[i] << " from " - << i + goffsets[fromgroup.getID()] << " - seq number " - << sequence_number[i + goffsets[fromgroup.getID()]], + DUMP("Received " << com_with[i] << " from " << proc.mpi_rank + << " - seq number " << proc.sequence_number, DBG_INFO); - ++sequence_number[i + goffsets[fromgroup.getID()]]; + ++proc.sequence_number; + ++i; } } /* -------------------------------------------------------------------------- */ -void LinearMPI::sendReals(CommBuffer &d, UInt nb, UInt dest, - CommGroup group, const std::string &buf) { +// void LinearMPI::sendReals(CommBuffer &d, UInt nb, UInt dest, +// CommGroup &group, const std::string &buf) { - DUMP("sending " << nb << " Reals to " << dest + goffsets[group.getID()] - << " - seq number " - << sequence_number[dest + goffsets[group.getID()]] << " for " - << buf, - DBG_INFO); - - MPI_Send(d.buffer(), nb, MPI_DOUBLE, dest + goffsets[group.getID()], - sequence_number[dest + goffsets[group.getID()]], MPI_COMM_WORLD); - - DUMP("sent " << nb << " Reals to " << dest + goffsets[group.getID()] - << " - seq number " - << sequence_number[dest + goffsets[group.getID()]] << " for " - << buf, - DBG_INFO); +// auto &mpi_group = dynamic_cast(group); +// auto &proc = mpi_group[dest]; - ++sequence_number[dest + goffsets[group.getID()]]; -} -/* -------------------------------------------------------------------------- */ +// DUMP("sending " << nb << " Reals to " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " << buf, +// DBG_INFO); -void LinearMPI::receiveReals(CommBuffer &d, UInt nb, UInt from, - CommGroup group, const std::string &buf) { - MPI_Status status; +// MPI_Send(d.buffer(), nb, MPI_DOUBLE, proc.mpi_rank, proc.sequence_number, +// MPI_COMM_WORLD); - DUMP("probe reception of reals from " - << from + goffsets[group.getID()] << " - seq number " - << sequence_number[from + goffsets[group.getID()]] << " for " << buf, - DBG_INFO); +// DUMP("sent " << nb << " Reals to " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " << buf, +// DBG_INFO); - if (nb == UINT_MAX) { - MPI_Probe(from + goffsets[group.getID()], - sequence_number[from + goffsets[group.getID()]], MPI_COMM_WORLD, - &status); - int nb_tmp; - MPI_Get_count(&status, MPI_DOUBLE, &nb_tmp); - nb = nb_tmp; - } +// ++proc.sequence_number; +// } +// /* -------------------------------------------------------------------------- */ + +// void LinearMPI::receiveReals(CommBuffer &d, UInt nb, UInt from, +// CommGroup &group, const std::string &buf) { +// MPI_Status status; +// auto &mpi_group = dynamic_cast(group); +// auto &proc = mpi_group[from]; + +// DUMP("probe reception of reals from " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " +// << buf, +// DBG_INFO); + +// if (nb == UINT_MAX) { +// MPI_Probe(proc.mpi_rank, proc.sequence_number, MPI_COMM_WORLD, &status); +// int nb_tmp; +// MPI_Get_count(&status, MPI_DOUBLE, &nb_tmp); +// nb = nb_tmp; +// } - DUMP("receiving " << nb << " Reals from " << from + goffsets[group.getID()] - << " - seq number " - << sequence_number[from + goffsets[group.getID()]] - << " for " << buf, - DBG_INFO); +// DUMP("receiving " << nb << " Reals from " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " << buf, +// DBG_INFO); - d.append(nb); - MPI_Recv(*d, nb, MPI_DOUBLE, from + goffsets[group.getID()], - sequence_number[from + goffsets[group.getID()]], MPI_COMM_WORLD, - &status); +// d.append(nb); +// MPI_Recv(*d, nb, MPI_DOUBLE, proc.mpi_rank, proc.sequence_number, +// MPI_COMM_WORLD, &status); - DUMP("received " << nb << " Reals from " << from + goffsets[group.getID()] - << " - seq number " - << sequence_number[from + goffsets[group.getID()]] << " for " - << buf, - DBG_INFO); - ++sequence_number[from + goffsets[group.getID()]]; -} -/* -------------------------------------------------------------------------- */ +// DUMP("received " << nb << " Reals from " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " << buf, +// DBG_INFO); +// ++proc.sequence_number; +// } +// /* -------------------------------------------------------------------------- */ -void LinearMPI::sendUInts(CommBuffer &i, UInt nb, UInt dest, - CommGroup group, const std::string &buf) { - DUMP("sending " << nb << " integers to " << dest + goffsets[group.getID()] - << " - seq number " - << sequence_number[dest + goffsets[group.getID()]] << " for " - << buf, - DBG_INFO); +// void LinearMPI::sendUInts(CommBuffer &i, UInt nb, UInt dest, +// CommGroup &group, const std::string &buf) { - MPI_Send(i.buffer(), nb, MPI_INT, dest + goffsets[group.getID()], - sequence_number[dest + goffsets[group.getID()]], MPI_COMM_WORLD); - DUMP("sent " << nb << " integers to " << dest + goffsets[group.getID()] - << " - seq number " - << sequence_number[dest + goffsets[group.getID()]] << " for " - << buf, - DBG_INFO); +// auto &mpi_group = dynamic_cast(group); +// auto &proc = mpi_group[dest]; - ++sequence_number[dest + goffsets[group.getID()]]; -} -/* -------------------------------------------------------------------------- */ -void LinearMPI::receiveUInts(CommBuffer &i, UInt nb, UInt from, - CommGroup group, const std::string &buf) { - MPI_Status status; +// DUMP("sending " << nb << " integers to " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " << buf, +// DBG_INFO); - STARTTIMER("MPI_probe"); - DUMP("probe reception of integers from " - << from + goffsets[group.getID()] << " - seq number " - << sequence_number[from + goffsets[group.getID()]] << " for " << buf, - DBG_INFO); +// MPI_Send(i.buffer(), nb, MPI_INT, proc.mpi_rank, proc.sequence_number, +// MPI_COMM_WORLD); - if (nb == UINT_MAX) { - MPI_Probe(from + goffsets[group.getID()], - sequence_number[from + goffsets[group.getID()]], MPI_COMM_WORLD, - &status); - int nb_tmp = 0; - MPI_Get_count(&status, MPI_INT, &nb_tmp); - nb = nb_tmp; - } +// DUMP("sent " << nb << " integers to " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " << buf, +// DBG_INFO); - STOPTIMER("MPI_probe"); +// ++proc.sequence_number; +// } +// /* -------------------------------------------------------------------------- */ +// void LinearMPI::receiveUInts(CommBuffer &i, UInt nb, UInt from, +// CommGroup &group, const std::string &buf) { +// MPI_Status status; +// auto &mpi_group = dynamic_cast(group); +// auto &proc = mpi_group[from]; + +// STARTTIMER("MPI_probe"); +// DUMP("probe reception of integers from " << proc.mpi_rank << " - seq number " +// << proc.sequence_number << " for " +// << buf, +// DBG_INFO); + +// if (nb == UINT_MAX) { +// MPI_Probe(proc.mpi_rank, proc.sequence_number, MPI_COMM_WORLD, &status); +// int nb_tmp = 0; +// MPI_Get_count(&status, MPI_INT, &nb_tmp); +// nb = nb_tmp; +// } - DUMP("receiving " << nb << " integers from " << from + goffsets[group.getID()] - << " - seq number " - << sequence_number[from + goffsets[group.getID()]] - << " for " << buf, - DBG_INFO); - STARTTIMER("MPI_append"); - i.append(nb); - STOPTIMER("MPI_append"); - STARTTIMER("MPI_receive"); - MPI_Recv(*i, nb, MPI_INT, from + goffsets[group.getID()], - sequence_number[from + goffsets[group.getID()]], MPI_COMM_WORLD, - &status); - STOPTIMER("MPI_receive"); - DUMP("received " << nb << " integers from " << from + goffsets[group.getID()] - << " - seq number " - << sequence_number[from + goffsets[group.getID()]] << " for " - << buf, - DBG_INFO); - ++sequence_number[from + goffsets[group.getID()]]; -} +// STOPTIMER("MPI_probe"); + +// DUMP("receiving " << nb << " integers from " << proc.mpi_rank +// << " - seq number " << proc.sequence_number << " for " +// << buf, +// DBG_INFO); +// STARTTIMER("MPI_append"); +// i.append(nb); +// STOPTIMER("MPI_append"); +// STARTTIMER("MPI_receive"); +// MPI_Recv(*i, nb, MPI_INT, proc.mpi_rank, proc.sequence_number, MPI_COMM_WORLD, +// &status); +// STOPTIMER("MPI_receive"); +// DUMP("received " << nb << " integers from " << proc.mpi_rank +// << " - seq number " << proc.sequence_number << " for " +// << buf, +// DBG_INFO); +// ++proc.sequence_number; +// } -/* -------------------------------------------------------------------------- */ +// /* -------------------------------------------------------------------------- */ void LinearMPI::waitForPendingComs() { MPI_Status status; for (UInt i = 0; i < requests.size(); ++i) MPI_Wait(&requests[i], &status); requests.clear(); } /* -------------------------------------------------------------------------- */ -void LinearMPI::reduceUInt(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - MPI_Op mpi_op; - switch (op) { - case OP_SUM: - mpi_op = MPI_SUM; - break; - case OP_MAX: - mpi_op = MPI_MAX; - break; - case OP_MIN: - mpi_op = MPI_MIN; - break; - default: - LM_FATAL("unknown operator " << op); - } - - if (!amIinGroup(group)) { - LM_FATAL( - "reduction can't be made if not a member of the group: " << comment); - } - CommBuffer result; - result.resize(nb); - MPI_Reduce(contrib.buffer(), result.buffer(), nb, MPI_INT, mpi_op, 0, - groups[group.getID()]); - contrib = result; -} - -/* -------------------------------------------------------------------------- */ - -void LinearMPI::reduceReal(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op) { - - MPI_Op mpi_op; - switch (op) { - case OP_SUM: - mpi_op = MPI_SUM; - break; - case OP_MAX: - mpi_op = MPI_MAX; - break; - case OP_MIN: - mpi_op = MPI_MIN; - break; - default: - LM_FATAL("unknown operator " << op); - } +// void LinearMPI::reduceUInt(CommBuffer &contrib, UInt nb, CommGroup &group, +// const std::string &comment, Operator op) { +// MPI_Op mpi_op; +// switch (op) { +// case OP_SUM: +// mpi_op = MPI_SUM; +// break; +// case OP_MAX: +// mpi_op = MPI_MAX; +// break; +// case OP_MIN: +// mpi_op = MPI_MIN; +// break; +// default: +// LM_FATAL("unknown operator " << op); +// } - if (!amIinGroup(group)) { - LM_FATAL( - "reduction can't be made if not a member of the group: " << comment); - } - CommBuffer result; - result.resize(nb); - MPI_Reduce(contrib.buffer(), result.buffer(), nb, MPI_DOUBLE, mpi_op, 0, - groups[group.getID()]); - contrib = result; -} +// if (!amIinGroup(group)) { +// LM_FATAL( +// "reduction can't be made if not a member of the group: " << comment); +// } +// CommBuffer result; +// result.resize(nb); +// MPI_Reduce(contrib.buffer(), result.buffer(), nb, MPI_INT, mpi_op, 0, +// dynamic_cast(group).mpi_ID); +// contrib = result; +// } -/* -------------------------------------------------------------------------- */ -void LinearMPI::allReduceUInt(CommBuffer &contrib, UInt nb, - CommGroup group, const std::string &comment, - Operator op) { - MPI_Op mpi_op; - switch (op) { - case OP_SUM: - mpi_op = MPI_SUM; - break; - case OP_MAX: - mpi_op = MPI_MAX; - break; - case OP_MIN: - mpi_op = MPI_MIN; - break; - default: - LM_FATAL("unknown operator " << op); - } +// /* -------------------------------------------------------------------------- */ + +// void LinearMPI::reduceReal(CommBuffer &contrib, UInt nb, CommGroup &group, +// const std::string &comment, Operator op) { + +// MPI_Op mpi_op; +// switch (op) { +// case OP_SUM: +// mpi_op = MPI_SUM; +// break; +// case OP_MAX: +// mpi_op = MPI_MAX; +// break; +// case OP_MIN: +// mpi_op = MPI_MIN; +// break; +// default: +// LM_FATAL("unknown operator " << op); +// } - if (!amIinGroup(group)) { - LM_FATAL( - "reduction can't be made if not a member of the group: " << comment); - } - CommBuffer result; - result.resize(nb); - MPI_Allreduce(contrib.buffer(), result.buffer(), nb, MPI_INT, mpi_op, - groups[group.getID()]); - contrib = result; -} +// if (!amIinGroup(group)) { +// LM_FATAL( +// "reduction can't be made if not a member of the group: " << comment); +// } +// CommBuffer result; +// result.resize(nb); +// MPI_Reduce(contrib.buffer(), result.buffer(), nb, MPI_DOUBLE, mpi_op, 0, +// dynamic_cast(group).mpi_ID); +// contrib = result; +// } -/* -------------------------------------------------------------------------- */ +// /* -------------------------------------------------------------------------- */ +// void LinearMPI::allReduceUInt(CommBuffer &contrib, UInt nb, +// CommGroup &group, const std::string &comment, +// Operator op) { +// MPI_Op mpi_op; +// switch (op) { +// case OP_SUM: +// mpi_op = MPI_SUM; +// break; +// case OP_MAX: +// mpi_op = MPI_MAX; +// break; +// case OP_MIN: +// mpi_op = MPI_MIN; +// break; +// default: +// LM_FATAL("unknown operator " << op); +// } -void LinearMPI::allReduceReal(CommBuffer &contrib, UInt nb, - CommGroup group, const std::string &comment, - Operator op) { +// if (!amIinGroup(group)) { +// LM_FATAL( +// "reduction can't be made if not a member of the group: " << comment); +// } +// CommBuffer result; +// result.resize(nb); +// MPI_Allreduce(contrib.buffer(), result.buffer(), nb, MPI_INT, mpi_op, +// dynamic_cast(group).mpi_ID); +// contrib = result; +// } - MPI_Op mpi_op; - switch (op) { - case OP_SUM: - mpi_op = MPI_SUM; - break; - case OP_MAX: - mpi_op = MPI_MAX; - break; - case OP_MIN: - mpi_op = MPI_MIN; - break; - default: - LM_FATAL("unknown operator " << op); - } +// /* -------------------------------------------------------------------------- */ + +// void LinearMPI::allReduceReal(CommBuffer &contrib, UInt nb, +// CommGroup &group, const std::string &comment, +// Operator op) { + +// MPI_Op mpi_op; +// switch (op) { +// case OP_SUM: +// mpi_op = MPI_SUM; +// break; +// case OP_MAX: +// mpi_op = MPI_MAX; +// break; +// case OP_MIN: +// mpi_op = MPI_MIN; +// break; +// default: +// LM_FATAL("unknown operator " << op); +// } - if (!amIinGroup(group)) { - LM_FATAL( - "reduction can't be made if not a member of the group: " << comment); - } - CommBuffer result; - result.resize(nb); - MPI_Allreduce(contrib.buffer(), result.buffer(), nb, MPI_DOUBLE, mpi_op, - groups[group.getID()]); - contrib = result; -} +// if (!amIinGroup(group)) { +// LM_FATAL( +// "reduction can't be made if not a member of the group: " << comment); +// } +// CommBuffer result; +// result.resize(nb); +// MPI_Allreduce(contrib.buffer(), result.buffer(), nb, MPI_DOUBLE, mpi_op, +// dynamic_cast(group).mpi_ID); +// contrib = result; +// } /* -------------------------------------------------------------------------- */ // void LinearMPI::gatherUInt(CommBuffer & contrib,UInt nb, // CommBuffer & receive, -// UInt to, CommGroup group, const std::string & +// UInt to, CommGroup& group, const std::string & // comment){ // if (!amIinGroup(group)){ // LM_FATAL("gathering can't be made if not a member of the group: " << // comment); // } // // CommBuffer result; // // result.resize(nb); // MPI_Gather(contrib.buffer(),nb,MPI_INT,receive.buffer(),nb,MPI_INT,to,groups[group.getID()]); // // contrib = result; // } // /* -------------------------------------------------------------------------- // */ // void LinearMPI::gatherReal(CommBuffer & contrib, UInt nb, // CommBuffer & receive, -// UInt to, CommGroup group,const std::string & +// UInt to, CommGroup& group,const std::string & // comment){ // if (!amIinGroup(group)){ // LM_FATAL("gatherng can't be made if not a member of the group: " << // comment); // } // // CommBuffer result; // // result.resize(nb); // MPI_Gather(contrib.buffer(),nb,MPI_DOUBLE,receive.buffer(),nb,MPI_DOUBLE,to,groups[group.getID()]); // // contrib = result; // } /* -------------------------------------------------------------------------- */ -UInt LinearMPI::getNBGroups() { return nb_groups; } -/* -------------------------------------------------------------------------- */ - -bool LinearMPI::amIinGroup(CommGroup group) { - if (group == group_all) - return true; - if (group == group_none) - return false; - - DUMP("testing if i am in " << group << " : " - << (group.getID() < (int)nb_groups && - groups[group.getID()] != MPI_COMM_NULL), - DBG_DETAIL); - - if (group.getID() >= (int)nb_groups) - return false; - return (groups[group.getID()] != MPI_COMM_NULL); -} -/* -------------------------------------------------------------------------- */ -bool LinearMPI::isInGroup(UInt i, CommGroup group) { - if (group == group_all) - return true; - if (group == group_none) - return false; - return (i >= goffsets[group.getID()] && - i < goffsets[group.getID()] + taille_groups[group.getID()]); -} -/* -------------------------------------------------------------------------- */ -MPI_Comm LinearMPI::getMpiGroup(CommGroup group) { - return groups[group.getID()]; -} -/* -------------------------------------------------------------------------- */ -UInt LinearMPI::getNBprocsOnGroup(CommGroup group) { - LM_ASSERT(group != group_invalid, "invalid group"); - if (group == group_all) - return n_procs; - if (group == group_none) - return 0; - return taille_groups[group.getID()]; -} -/* -------------------------------------------------------------------------- */ +// UInt LinearMPI::getNbGroups() { return objects.size(); } +// /* -------------------------------------------------------------------------- */ -void LinearMPI::synchronize(CommGroup group_index) { - STARTTIMER("waiting"); - DUMP("group_index " << group_index, DBG_INFO); - if (group_index == group_all) - MPI_Barrier(MPI_COMM_WORLD); - else - MPI_Barrier(groups[group_index.getID()]); - STOPTIMER("waiting"); -} -/* -------------------------------------------------------------------------- */ +// bool LinearMPI::amIinGroup(CommGroup &group) { -UInt LinearMPI::realRank(UInt i, CommGroup group) { - return i + goffsets[group.getID()]; -} +// return group.isInGroup(lm_my_proc_id); +// } +// /* -------------------------------------------------------------------------- */ +// bool LinearMPI::isInGroup(UInt i, CommGroup &group) { +// if (group == group_all) +// return true; +// if (group == group_none) +// return false; +// return (i >= groups[group.getID()].offset && +// i < groups[group.getID()].offset + groups[group.getID()].size); +// } +// /* -------------------------------------------------------------------------- */ +// MPI_Comm LinearMPI::getMpiGroup(CommGroup &group) { +// return groups[group.getID()].mpi_ID; +// } +// /* -------------------------------------------------------------------------- */ +// UInt LinearMPI::getNBprocsOnGroup(CommGroup &group) { +// LM_ASSERT(group != group_invalid, "invalid group"); +// if (group == group_all) +// return nb_procs; +// if (group == group_none) +// return 0; +// return groups[group.getID()].size; +// } +// /* -------------------------------------------------------------------------- */ + +// void LinearMPI::synchronize(CommGroup &group_index) { +// STARTTIMER("waiting"); +// DUMP("group_index " << group_index, DBG_INFO); +// if (group_index == group_all) +// MPI_Barrier(MPI_COMM_WORLD); +// else +// MPI_Barrier(groups[group_index.getID()].mpi_ID); +// STOPTIMER("waiting"); +// } /* -------------------------------------------------------------------------- */ -UInt LinearMPI::groupRank(UInt i, CommGroup group) { - if (group == group_all) - return i; - if (group == group_none) - LM_FATAL("cannot request rank from group_none"); - if (isInGroup(i, group)) - return i - goffsets[group.getID()]; - else { - LM_FATAL("requested global rank " << i << " not in logical subgroup " - << group); - } -} +// UInt LinearMPI::absoluteRank(UInt i, CommGroup &group) { +// return groups[group.getID()].processors()[i].mpi_rank; +// } +// /* -------------------------------------------------------------------------- */ + +// UInt LinearMPI::groupRank(UInt i, CommGroup &group) { +// if (group == group_all) +// return i; +// if (group == group_none) +// LM_FATAL("cannot request rank from group_none"); +// if (isInGroup(i, group)) +// return i - groups[group.getID()].offset; +// else { +// LM_FATAL("requested global rank " << i << " not in logical subgroup " +// << group); +// } +// } /* -------------------------------------------------------------------------- */ -void LinearMPI::printself(std::ostream &stream) { - stream << "LinearMPI object " << std::endl; - stream << "free procs " << free_procs << std::endl; - stream << "nb_groups " << nb_groups << std::endl; - for (UInt i = 0; i < nb_groups; ++i) { - stream << "size_group[" << i << "] = " << taille_groups[i] << std::endl; - stream << "goffsets[" << i << "] = " << goffsets[i] << std::endl; - stream << "groups[" << i << "] = " << groups[i] << std::endl; - CommGroup tmp(i); - stream << "am I in group " << i << " ? " << amIinGroup(tmp) << std::endl; - } -} +// void LinearMPI::printself(std::ostream &stream) { +// stream << "LinearMPI object " << std::endl; +// stream << "free procs " << getFreeProcs() << std::endl; +// stream << "nb_groups " << groups.size() << std::endl; +// for (UInt i = 0; i < groups.size(); ++i) { +// stream << "size_group[" << i << "] = " << groups[i].size << std::endl; +// stream << "group_offsets[" << i << "] = " << groups[i].offset << std::endl; +// stream << "groups[" << i << "] = " << groups[i] << std::endl; +// CommGroup tmp(i); +// stream << "am I in group " << i << " ? " << amIinGroup(tmp) << std::endl; +// } +// } /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ diff --git a/src/communicator/communicator_mpi_linear.hh b/src/communicator/communicator_mpi_linear.hh index 8e46bba..46b282d 100644 --- a/src/communicator/communicator_mpi_linear.hh +++ b/src/communicator/communicator_mpi_linear.hh @@ -1,177 +1,181 @@ /** * @file communicator_mpi_linear.hh * * @author Guillaume Anciaux * * @date Wed Nov 06 20:35:11 2013 * * @brief This is the implementation of the LM communicator using MPI where * models are distributed over processors * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ #ifndef __LIBMULTISCALE_COMMUNICATOR_MPI_LINEAR_HH__ #define __LIBMULTISCALE_COMMUNICATOR_MPI_LINEAR_HH__ /* -------------------------------------------------------------------------- */ -#define TAILLE_GROUPS 50 -/* -------------------------------------------------------------------------- */ #include "communicator.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ -typedef struct mpi_geom_ { +struct MPIGeom { UInt type; UInt Dim; Real center[3]; // l'information est le rayon min et max et c'est tout (boule) Real rmin; Real rmax; // l'information sont les dimensions et c'est c'est tout (cube) Real xmin; Real xmax; Real ymin; Real ymax; Real zmin; Real zmax; -} mpi_geom; +}; /* -------------------------------------------------------------------------- */ class LinearMPI : public Communicator { public: /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ LinearMPI(); ~LinearMPI(); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ - inline UInt getNBprocsOnGroup(CommGroup group); - inline UInt getNBGroups(); - inline bool amIinGroup(CommGroup i); - inline bool isInGroup(UInt i, CommGroup group); - inline MPI_Comm getMpiGroup(CommGroup i); - inline UInt realRank(UInt i, CommGroup group); - inline UInt groupRank(UInt i, CommGroup group); + // inline UInt getNBprocsOnGroup(CommGroup &group); + // inline UInt getNBGroups(); + // inline bool amIinGroup(CommGroup &i); + // inline bool isInGroup(UInt i, CommGroup &group); + // inline MPI_Comm getMpiGroup(CommGroup &i); + // inline UInt absoluteRank(UInt i, CommGroup &group); + // inline UInt groupRank(UInt i, CommGroup &group); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ - void printself(std::ostream &stream); + // void printself(std::ostream &stream); /* ------------------------------------------------------------------------ */ /* Communication Methods */ /* ------------------------------------------------------------------------ */ - inline void sendLocalGeometriesToGroup(Geometry &geom, CommGroup group); - inline void receiveLocalGeometriesFromGroup(Geometry **geom, CommGroup group); + inline void sendLocalGeometriesToGroup(Geometry &geom, CommGroup &group); + inline void receiveLocalGeometriesFromGroup(Geometry **geom, + CommGroup &group); inline void sendCommunicationTable(std::vector &com_with, - CommGroup destgroup); + CommGroup &destgroup); inline void receiveCommunicationTable(std::vector &com_with, - CommGroup fromgroup); - inline void sendReals(CommBuffer &d, UInt nb, UInt dest, - CommGroup group, const std::string &buf); - inline void receiveReals(CommBuffer &d, UInt nb, UInt from, - CommGroup group, const std::string &buf); - inline void sendUInts(CommBuffer &i, UInt nb, UInt dest, - CommGroup group, const std::string &buf); - inline void receiveUInts(CommBuffer &i, UInt nb, UInt from, - CommGroup group, const std::string &buf); - inline void reduceUInt(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op); - inline void reduceReal(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op); - inline void allReduceUInt(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op); - inline void allReduceReal(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op); - // inline void broadcastUInt(CommBuffer & contrib,UInt nb,CommGroup + CommGroup &fromgroup); + // inline void sendReals(CommBuffer &d, UInt nb, UInt dest, + // CommGroup &group, const std::string &buf); + // inline void receiveReals(CommBuffer &d, UInt nb, UInt from, + // CommGroup &group, const std::string &buf); + // inline void sendUInts(CommBuffer &i, UInt nb, UInt dest, + // CommGroup &group, const std::string &buf); + // inline void receiveUInts(CommBuffer &i, UInt nb, UInt from, + // CommGroup &group, const std::string &buf); + // inline void reduceUInt(CommBuffer &contrib, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); + // inline void reduceReal(CommBuffer &contrib, UInt nb, CommGroup &group, + // const std::string &comment, Operator op); + // inline void allReduceUInt(CommBuffer &contrib, UInt nb, + // CommGroup &group, const std::string &comment, + // Operator op); + // inline void allReduceReal(CommBuffer &contrib, UInt nb, + // CommGroup &group, const std::string &comment, + // Operator op); + // inline void broadcastUInt(CommBuffer & contrib,UInt nb,CommGroup& // group, // const std::string & comment); - // inline void broadcastReal(CommBuffer & contrib,UInt nb,CommGroup + // inline void broadcastReal(CommBuffer & contrib,UInt nb,CommGroup& // group, // const std::string & comment); // inline void gatherUInt(CommBuffer & contrib,UInt nb, CommBuffer // & recevie, - // UInt to, CommGroup group, const std::string & + // UInt to, CommGroup& group, const std::string & // comment); // inline void gatherReal(CommBuffer & contrib, UInt nb, // CommBuffer & receive, - // UInt to, CommGroup group, const std::string & comment); + // UInt to, CommGroup& group, const std::string & + // comment); - inline void waitForPendingComs(); - inline UInt addGroup(UInt nb_procs); - inline void synchronize(CommGroup group_index); + inline void waitForPendingComs() override; + inline void addGroup(const LMID &id, UInt nb_procs) override; + //inline void synchronize(LMID group_index) override; + + UInt getFreeProcs() { + UInt used_procs = 0; + ; + for (auto &group : objects) { + used_procs += group.second->size(); + } + return nb_procs - used_procs; + }; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /* variables to treat MPI comms */ - MPI_Comm groups[TAILLE_GROUPS]; - - UInt free_procs; - int n_procs; - UInt nb_groups; - UInt taille_groups[TAILLE_GROUPS]; - UInt goffsets[TAILLE_GROUPS]; - - /* types for transport of objects */ + // std::vector groups; + UInt nb_procs; MPI_Datatype geom_type; std::vector requests; - std::vector sequence_number; + // std::vector sequence_number; }; __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_COMMUNICATOR_MPI_LINEAR_HH__ */ diff --git a/src/communicator/communicator_unity.hh b/src/communicator/communicator_unity.hh index 0a6baba..3c873af 100644 --- a/src/communicator/communicator_unity.hh +++ b/src/communicator/communicator_unity.hh @@ -1,150 +1,153 @@ /** * @file communicator_unity.hh * * @author Guillaume Anciaux * * @date Mon Oct 28 19:23:14 2013 * * @brief Simple LM communicator used in the sequential case * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ #ifndef __LIBMULTISCALE_COMMUNICATOR_UNITY_HH__ #define __LIBMULTISCALE_COMMUNICATOR_UNITY_HH__ /* -------------------------------------------------------------------------- */ #include "communicator.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ class UnityMPI : public Communicator { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: UnityMPI() { DUMP("creating unity communicateur", DBG_INFO); free_procs = 1; }; ~UnityMPI() {} /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ - UInt addGroup(UInt nb_procs) { + void addGroup(const LMID &id, UInt nb_procs) override { if (free_procs == 0 && nb_procs > 1) LM_FATAL("not enough free processors to make group"); --free_procs; - return 0; }; - bool amIinGroup(CommGroup i) { return (lm_my_proc_id == 0); } - MPI_Comm getMpiGroup(CommGroup i) { return MPI_COMM_WORLD; }; + // bool amIinGroup(CommGroup &i) override { return (lm_my_proc_id == 0); } + // MPI_Comm getMpiGroup(CommGroup &i) override { return MPI_COMM_WORLD; }; - UInt getNBprocsOnGroup(CommGroup i) { return 1; }; + // UInt getNBprocsOnGroup(CommGroup &i) override { return 1; }; - void synchronize(CommGroup group_index){}; - UInt realRank(UInt i, CommGroup group) { return 0; }; - UInt groupRank(UInt i, CommGroup group) { return 0; }; + // void synchronize(CommGroup &group_index) override{}; + // UInt absoluteRank(UInt i, CommGroup &group) override { return 0; }; + // UInt groupRank(UInt i, CommGroup &group) override { return 0; }; - bool isInGroup(UInt i, CommGroup group) { return true; }; - UInt getNBGroups() { return 1; }; + // bool isInGroup(UInt i, CommGroup &group) override { return true; }; + // UInt getNBGroups() override { return 1; }; // operation de communications // si un seul proc pas de comm - void sendLocalGeometriesToGroup(Geometry &geom, CommGroup group){}; - void receiveLocalGeometriesFromGroup(Geometry **geom, CommGroup group){}; - void sendCommunicationTable(std::vector &com_with, - CommGroup destgroup){}; - void receiveCommunicationTable(std::vector &com_with, - CommGroup fromgroup){}; - - void sendUInts(CommBuffer &d, UInt nb, UInt dest, CommGroup group, - const std::string &buf){}; - void receiveUInts(CommBuffer &d, UInt nb, UInt from, CommGroup group, - const std::string &buf){}; - void sendReals(CommBuffer &d, UInt nb, UInt dest, CommGroup group, - const std::string &buf){}; - - void receiveReals(CommBuffer &d, UInt nb, UInt from, CommGroup group, - const std::string &buf){}; - - void reduceUInt(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op){}; - void reduceReal(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op){}; - // void broadcastUInt(CommBuffer & contrib,UInt nb,CommGroup group, + // void sendLocalGeometriesToGroup(Geometry &geom, CommGroup &group) + // override{}; + // void receiveLocalGeometriesFromGroup(Geometry **geom, + // CommGroup &group) override{}; + // void sendCommunicationTable(std::vector &com_with, + // CommGroup &destgroup) override{}; + // void receiveCommunicationTable(std::vector &com_with, + // CommGroup &fromgroup) override{}; + + // void sendUInts(CommBuffer &d, UInt nb, UInt dest, CommGroup &group, + // const std::string &buf) override{}; + // void receiveUInts(CommBuffer &d, UInt nb, UInt from, CommGroup + // &group, + // const std::string &buf) override{}; + // void sendReals(CommBuffer &d, UInt nb, UInt dest, CommGroup &group, + // const std::string &buf) override{}; + + // void receiveReals(CommBuffer &d, UInt nb, UInt from, CommGroup + // &group, + // const std::string &buf) override{}; + + // void reduceUInt(CommBuffer &contrib, UInt nb, CommGroup &group, + // const std::string &comment, Operator op) override{}; + // void reduceReal(CommBuffer &contrib, UInt nb, CommGroup &group, + // const std::string &comment, Operator op) override{}; + // void broadcastUInt(CommBuffer & contrib,UInt nb,CommGroup& group, // const std::string & comment){}; - // void broadcastReal(CommBuffer & contrib,UInt nb,CommGroup group, + // void broadcastReal(CommBuffer & contrib,UInt nb,CommGroup& group, // const std::string & comment){}; - void allReduceUInt(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op){}; - void allReduceReal(CommBuffer &contrib, UInt nb, CommGroup group, - const std::string &comment, Operator op){}; + // void allReduceUInt(CommBuffer &contrib, UInt nb, CommGroup &group, + // const std::string &comment, Operator op) override{}; + // void allReduceReal(CommBuffer &contrib, UInt nb, CommGroup &group, + // const std::string &comment, Operator op) override{}; // void gatherUInt(CommBuffer & contrib,UInt nb,CommBuffer & // receive, - // UInt to,CommGroup group,const std::string & comment){}; + // UInt to,CommGroup& group,const std::string & comment){}; // void gatherReal(CommBuffer & contrib,UInt nb,CommBuffer & // receive, - // UInt to,CommGroup group,const std::string & comment){}; - void waitForPendingComs(){}; + // UInt to,CommGroup& group,const std::string & comment){}; + void waitForPendingComs() override{}; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: UInt free_procs; }; /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_COMMUNICATOR_UNITY_HH__ */ diff --git a/src/communicator/pack_buffer.hh b/src/communicator/pack_buffer.hh index 1ca9ac2..859c015 100644 --- a/src/communicator/pack_buffer.hh +++ b/src/communicator/pack_buffer.hh @@ -1,115 +1,116 @@ /** * @file pack_buffer.hh * * @author Guillaume Anciaux * * @date Mon Oct 28 13:15:05 2013 * * @brief The is a buffer useful in the inter/intra models * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see . * */ #ifndef __LIBMULTISCALE_PACK_BUFFER_H__ #define __LIBMULTISCALE_PACK_BUFFER_H__ /* -------------------------------------------------------------------------- */ +#include "lm_common.hh" #include /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ class PackBuffer { public: PackBuffer() : read_position(0){}; //! add an object to the packed buffer template inline void operator<<(T &data); //! add a vector of objects to the packed buffer template inline void operator<<(std::vector &data); //! pop out a packed object template inline void operator>>(T &data); //! clear the pack buffer inline void clear(); //! return actual size of the pack buffer inline UInt size(); //! return what remains to read inline UInt remainingSize(); //! resize the pack buffer (argument in bytes) inline void resize(UInt size); //! return the raw buffer inline char *buffer(); private: std::vector buf; UInt read_position; }; /* -------------------------------------------------------------------------- */ template void PackBuffer::operator<<(T &data) { UInt size = buf.size(); buf.resize(size + sizeof(T)); T *ptr = (T *)&buf[size]; *ptr = data; }; /* -------------------------------------------------------------------------- */ template void PackBuffer::operator<<(std::vector &data) { UInt size = buf.size(); UInt add_size = data.size() * sizeof(T); buf.resize(size + add_size); memcpy(&buf[size], &data[0], add_size); }; /* -------------------------------------------------------------------------- */ template void PackBuffer::operator>>(T &data) { #ifndef LM_OPTIMIZED UInt size = buf.size(); #endif // LM_OPTIMIZED LM_ASSERT(read_position < size, "no more data to read"); T *ptr = (T *)&buf[read_position]; data = *ptr; read_position += sizeof(T); }; /* -------------------------------------------------------------------------- */ void PackBuffer::clear() { buf.clear(); read_position = 0; }; /* -------------------------------------------------------------------------- */ UInt PackBuffer::size() { return buf.size() - read_position; }; /* -------------------------------------------------------------------------- */ UInt PackBuffer::remainingSize() { return buf.size(); }; /* -------------------------------------------------------------------------- */ void PackBuffer::resize(UInt size) { buf.resize(size); }; /* -------------------------------------------------------------------------- */ char *PackBuffer::buffer() { return &buf[0]; } /* -------------------------------------------------------------------------- */ __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_PACK_BUFFER_H__ */ diff --git a/src/container/container.hh b/src/container/container.hh index 422fa79..f65d566 100644 --- a/src/container/container.hh +++ b/src/container/container.hh @@ -1,196 +1,197 @@ /** * @file container.hh * * @author Guillaume Anciaux * * @date Tue Jul 22 14:47:56 2014 * * @brief This is the generic container class * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ #ifndef __LIBMULTISCALE_CONTAINER_HH__ #define __LIBMULTISCALE_CONTAINER_HH__ /* -------------------------------------------------------------------------- */ +#include "comm_group.hh" #include "cube.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ class Communicator; class ReferenceManagerInterface; struct ComponentNull; /* -------------------------------------------------------------------------- */ class ContainerInterface { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - ContainerInterface() { - refmanager = NULL; - comm_group = group_invalid; - }; + ContainerInterface() : comm_group(nullptr), refmanager(nullptr){}; virtual ~ContainerInterface(){}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ //! return bounding box Cube &getBoundingBox() { return bounding_box; }; //! ste bounding box void setBoundingBox(Cube &c) { bounding_box = c; }; //! return the communication group - CommGroup getCommGroup() { return comm_group; }; + CommGroup &getCommGroup() { + if (comm_group == nullptr) + LM_FATAL("invalid group"); + return *comm_group; + }; //! return the ReferenceManager ReferenceManagerInterface &getRefManager() { if (!refmanager) LM_THROW("cannot access undefined Reference Manager"); return *refmanager; }; bool hasRefManager() { return refmanager; }; //! set the ReferenceManager void setRefManager(ReferenceManagerInterface *refMgr) { refmanager = refMgr; }; //! return the communication group - void setCommGroup(CommGroup group) { comm_group = group; }; + void setCommGroup(CommGroup &group) { comm_group = &group; }; //! copy the container info void copyContainerInfo(ContainerInterface &cont) { bounding_box = cont.getBoundingBox(); - comm_group = cont.getCommGroup(); + comm_group = &cont.getCommGroup(); refmanager = cont.refmanager; } /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: Cube bounding_box; - CommGroup comm_group; - + CommGroup *comm_group; ReferenceManagerInterface *refmanager; }; /* -------------------------------------------------------------------------- */ template class ContainerArray; /* -------------------------------------------------------------------------- */ /** * Interface Container. * Generic container */ template class Container_base : public ContainerInterface { /* ------------------------------------------------------------------------ */ /* Typedefs */ /* ------------------------------------------------------------------------ */ public: typedef ContainerArray ContainerSubset; typedef T Ref; class iterator_base; /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ Container_base(){}; virtual ~Container_base(){}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ //! sort conained items virtual void sort() { LM_TOIMPLEMENT; }; //! search for a given item index virtual UInt search(T &el) { LM_TOIMPLEMENT; }; //! add a given item virtual void add(const T &el) { LM_TOIMPLEMENT; }; //! get an item from its index virtual T &get(UInt index) { LM_TOIMPLEMENT; }; //! get an item from its index virtual T &operator[](UInt index) { LM_TOIMPLEMENT; }; //! remove an item from its index virtual void remove(UInt index) { LM_TOIMPLEMENT; }; //! return the number of items virtual UInt size(DOFType dt = dt_local) = 0; }; /* -------------------------------------------------------------------------- */ template class Container_base::iterator_base { public: iterator_base(Container_base &cont) : iterator_base() { this->cont = &cont; } iterator_base() : cont(nullptr){}; virtual ~iterator_base(){}; virtual void operator++() = 0; virtual T &operator*() = 0; virtual bool operator!=(const iterator_base &) const = 0; virtual bool operator==(const iterator_base &) const = 0; protected: Container_base *cont; }; /* -------------------------------------------------------------------------- */ #define DECLARE_CONTAINER_ACCEPT_FUNCTIONS \ template void accept(D &dumper) { dumper.dump(*this); } __END_LIBMULTISCALE__ #endif /* __LIBMULTISCALE_CONTAINER_HH__ */ diff --git a/src/continuum/domain_continuum.cc b/src/continuum/domain_continuum.cc index f8519c0..c4fe01b 100644 --- a/src/continuum/domain_continuum.cc +++ b/src/continuum/domain_continuum.cc @@ -1,264 +1,264 @@ /** * @file domain_continuum.cc * * @author Guillaume Anciaux * * @date Wed Nov 06 20:35:11 2013 * * @brief Mother of all continuum domains * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ /* -------------------------------------------------------------------------- */ #include "domain_continuum.hh" #include "communicator.hh" #include "geometry_manager.hh" #include "lib_continuum.hh" #include "lm_common.hh" #include "xml_parser_restart.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ template -DomainContinuum::DomainContinuum(CommGroup GID) +DomainContinuum::DomainContinuum(LMID GID) : DomainContinuumInterface(GID), arlequin_flag(false), slave_displacements_computed(false), prestressed_periodicity_flag(false) { geometries.resize(10); createOutput("output"); getOutput("output") = make_argument(mesh_container); } /* -------------------------------------------------------------------------- */ template DomainContinuum::~DomainContinuum() {} /* -------------------------------------------------------------------------- */ template typename DomainContinuum::ContainerPoints & DomainContinuum::getContainer() { Cube c; c.setDim(Dim); - Communicator &myComm = Communicator::getCommunicator(); - if (myComm.amIinGroup(getGroupID())) { + auto &comm_group = getCommGroup(); + if (comm_group.amIinGroup()) { getDomainDimensions(c); mesh_container.getBoundingBox() = c; } - mesh_container.setCommGroup(getGroupID()); + mesh_container.setCommGroup(getCommGroup()); return mesh_container; } /* -------------------------------------------------------------------------- */ template std::vector> & DomainContinuum::getPBCpairs() { return pbc_pairs; } /* -------------------------------------------------------------------------- */ template inline void DomainContinuum::readXMLFile( const std::string &filename) { XMLRestartParser parser; DUMP("Setting Dummy simulation from libMultiScale XML Data format " << filename, DBG_INFO); if (parser.parseFile(filename, this->restart_continue_if_notfound)) { DUMP("restart was not performed because file was not found", DBG_WARNING); return; } this->setCurrentStep(current_step); DUMP("read done " << filename, DBG_INFO); UnitsConverter unit; unit.setInUnits(atomic_unit_system); UInt cpt = 0; UInt cpt2 = 0; #ifndef LM_OPTIMIZED UInt total = getContainerNodes().size(); #endif // LM_OPTIMIZED DUMP("total = " << total, DBG_DETAIL); for (auto &&n : getContainerNodes()) { // for (n = it.getFirst(); !it.end() ; n = it.getNext()){ auto X = n.position0(); if (cpt2 % 100 == 0) DUMP("passing node number " << cpt2 << "/" << total << " reloaded", DBG_INFO); ++cpt2; if (!parser.isDofRegistered(X)) continue; Vector U; parser.assignDispField(X, U); n.displacement() = U; Vector V; parser.assignVelField(X, V); n.velocity() = V; if (cpt % 100 == 0) DUMP("node number " << cpt << "/" << total << " reloaded", DBG_INFO); ++cpt; } DUMP("associated " << cpt << " over " << total, DBG_INFO); performStep2(); } /* -------------------------------------------------------------------------- */ template ContElems &DomainContinuum::getContainerElems() { Cube c; c.setDim(Dim); - Communicator &myComm = Communicator::getCommunicator(); - auto & elems = mesh_container.getContainerElems(); - if (myComm.amIinGroup(getGroupID())) { + auto &comm_group = getCommGroup(); + auto &elems = mesh_container.getContainerElems(); + if (comm_group.amIinGroup()) { getDomainDimensions(c); elems.getBoundingBox() = c; } - elems.setCommGroup(getGroupID()); + elems.setCommGroup(getCommGroup()); return elems; } /* -------------------------------------------------------------------------- */ template ContNodes &DomainContinuum::getContainerNodes() { Cube c; c.setDim(Dim); - Communicator &myComm = Communicator::getCommunicator(); - auto & nodes = mesh_container.getContainerNodes(); - if (myComm.amIinGroup(getGroupID())) { + auto &comm_group = getCommGroup(); + auto &nodes = mesh_container.getContainerNodes(); + if (comm_group.amIinGroup()) { getDomainDimensions(c); nodes.getBoundingBox() = c; } - nodes.setCommGroup(getGroupID()); + nodes.setCommGroup(getCommGroup()); return nodes; } /* -------------------------------------------------------------------------- */ template Geometry &DomainContinuum::getGeom() { return *GeometryManager::getManager().getGeometry(geometries[0]); } /* -------------------------------------------------------------------------- */ /* LMDESC DomainContinuum This section describe the section that is associated with continuum mechanics model. It is the starting point of every Continuum Mechanics plugins. */ template inline void DomainContinuum::declareParams() { DomainInterface::declareParams(); /* LMKEYWORD DOMAIN_GEOMETRY Specify the geometry/region describing the domain */ this->parseKeyword("DOMAIN_GEOMETRY", geometries[0]); /* LMKEYWORD CONSTRAINED_GEOMETRY For minimization purpose (obsolete). This provided a region not included in the computation of the objective function and the gradient. */ this->parseKeyword("CONSTRAINED_GEOMETRY", geom_constrained, invalidGeom); /* LMKEYWORD TIMESTEP Specify the explicit integration timestep */ this->parseKeyword("TIMESTEP", timeStep); /* LMKEYWORD PRESTRESSED_PERIODICITY set whether the corrective displacement of slaves should be considered */ this->parseKeyword("PRESTRESSED_PERIODICITY", prestressed_periodicity_flag, false); } /* -------------------------------------------------------------------------- */ #ifdef LIBMULTISCALE_LIBMESH template class DomainContinuum, ContainerNodesLibMesh<1>, 1>; template class DomainContinuum, ContainerNodesLibMesh<2>, 2>; template class DomainContinuum, ContainerNodesLibMesh<3>, 3>; #endif #ifdef LIBMULTISCALE_SIMULPACK template class DomainContinuum, ContainerNodesSimulPack<2>, 2>; template class DomainContinuum, ContainerNodesSimulPack<3>, 3>; #endif #ifdef LIBMULTISCALE_MECA1D template class DomainContinuum; #endif #ifdef LIBMULTISCALE_AKANTU_PLUGIN template class DomainContinuum, ContainerNodesAkantu<1>, 1>; template class DomainContinuum, ContainerNodesAkantu<2>, 2>; template class DomainContinuum, ContainerNodesAkantu<3>, 3>; #endif __END_LIBMULTISCALE__ diff --git a/src/continuum/domain_continuum.hh b/src/continuum/domain_continuum.hh index a3385e5..6c1c15d 100644 --- a/src/continuum/domain_continuum.hh +++ b/src/continuum/domain_continuum.hh @@ -1,189 +1,189 @@ /** * @file domain_continuum.hh * * @author Guillaume Anciaux * @author Till Junge * * @date Tue Oct 29 22:09:05 2013 * * @brief Mother of all continuum domains * * @section LICENSE * * Copyright INRIA and CEA * * The LibMultiScale is a C++ parallel framework for the multiscale * coupling methods dedicated to material simulations. This framework * provides an API which makes it possible to program coupled simulations * and integration of already existing codes. * * This Project was initiated in a collaboration between INRIA Futurs Bordeaux * within ScAlApplix team and CEA/DPTA Ile de France. * The project is now continued at the Ecole Polytechnique Fédérale de Lausanne * within the LSMS/ENAC laboratory. * * This software is governed by the CeCILL-C license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. * */ #ifndef __LIBMULTISCALE_DOMAIN_CONTINUUM_HH__ #define __LIBMULTISCALE_DOMAIN_CONTINUUM_HH__ /* -------------------------------------------------------------------------- */ #include "container_mesh.hh" #include "domain_continuum_interface.hh" /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ /* -------------------------------------------------------------------------- */ /** Class DomainContinuum Template class from DomainContinuumInterface that helps developper to implement with optimisation processes by template a Continuous domain object */ template class DomainContinuum : public DomainContinuumInterface { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - DomainContinuum(CommGroup GID); + DomainContinuum(LMID GID); virtual ~DomainContinuum(); void compute_make_call(){}; /* ------------------------------------------------------------------------ */ /* Typedefs */ /* ------------------------------------------------------------------------ */ //! generic container type to course over nodes typedef ContNodes ContainerNodes; //! generic iterator type to course over nodes typedef typename ContainerNodes::iterator IteratorNodes; //! generic reference to nodes typedef typename ContainerNodes::Ref RefNode; //! generic reference to nodes typedef typename ContainerNodes::Ref RefPoint; //! generic reference to container of points (contains also the mesh) typedef ContainerMesh ContainerPoints; //! generic container type to course over elems typedef ContElems ContainerElems; //! generic iterator type to course over elems typedef typename ContainerElems::iterator IteratorElems; //! generic reference to nodes typedef typename ContainerElems::Ref RefElem; //! generic reference to container of points typedef typename ContainerPoints::ContainerSubset ContainerSubset; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ //! return the geometric definition of the domain Geometry &getGeom(); //! get internal timestep to a given value virtual Real getTimeStep() { return timeStep; }; //! return the container of elements ContainerElems &getContainerElems(); //! return the container of nodes ContainerNodes &getContainerNodes(); //! return the container of points ContainerPoints &getContainer(); //ContainerPoints &getOutput(); //! return PBC pairs in a vector std::vector> &getPBCpairs(); //! return value of arlequin flag bool arlequin() { return arlequin_flag; } //! returns whether an md domain is perdiodic in direction dir virtual bool isPeriodic(UInt dir) { LM_TOIMPLEMENT; } /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ void build(){}; //! implementation of the parsing method virtual void declareParams(); //! reload xml file of a saved situation void readXMLFile(const std::string &filename); // //! connect and build the adapted object // void connect(FactoryMultiScale &f); // //! connect and build the adapted object // void connect(FactoryMultiScale &f); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: //! flag to active arlequin energy weigthing bool arlequin_flag; //! PBC pairs std::vector> pbc_pairs; //! slave node initial displacements; std::vector slave_displacements; //! container of mesh ContainerPoints mesh_container; //! whether the initial displacements have been computed bool slave_displacements_computed; //! mapping from zone id to geometries std::vector geometries; //! mapping between zone id and BC types // std::vector boundaries; //! contrained geom LMID geom_constrained; //! timestep value Quantity