Commit 56573426 authored by GILLES Sebastien's avatar GILLES Sebastien

#1466 Make RAII initialization of Petsc and mpi an (internal) independant...

#1466 Make RAII initialization of Petsc and mpi an (internal) independant class - a singleton in fact. This way, more than one instance of MoReFEMData may be run in the same program.
parent eff0846c
This diff is collapsed.
......@@ -65,9 +65,9 @@ namespace MoReFEM
* \copydoc doxygen_hide_mpi_param
*/
explicit InputData(const std::string& filename,
const Wrappers::Mpi& mpi,
Utilities::InputDataNS::DoTrackUnusedFields do_track_unused_fields =
Utilities::InputDataNS::DoTrackUnusedFields::yes);
const Wrappers::Mpi& mpi,
Utilities::InputDataNS::DoTrackUnusedFields do_track_unused_fields =
Utilities::InputDataNS::DoTrackUnusedFields::yes);
//! Destructor
~InputData() = default;
......
......@@ -18,8 +18,8 @@
# include "ThirdParty/Wrappers/Mpi/Mpi.hpp"
# include "ThirdParty/Wrappers/Mpi/MpiScale.hpp"
# include "ThirdParty/Wrappers/Petsc/Petsc.hpp"
# include "ThirdParty/Wrappers/Petsc/Print.hpp"
# include "ThirdParty/Wrappers/Petsc/Internal/RAII.hpp"
# include "ThirdParty/Wrappers/Tclap/StringPair.hpp"
# include "ThirdParty/IncludeWithoutWarning/Tclap/Tclap.hpp"
......@@ -128,13 +128,9 @@ namespace MoReFEM
template<MpiScale MpiScaleT>
const std::string& GetResultDirectory() const noexcept;
private:
//! Holds Mpi object.
Wrappers::Mpi::const_unique_ptr mpi_ = nullptr;
//!
//! Holds RAII Petsc object, which ensures PetscFinalize() is called in due time.
Wrappers::Petsc::Petsc::const_unique_ptr petsc_ = nullptr;
private:
//! Holds InputData.
typename InputDataT::const_unique_ptr input_data_ = nullptr;
......
......@@ -29,10 +29,7 @@ namespace MoReFEM
MoReFEMData<InputDataT, DoTrackUnusedFieldsT, AdditionalCommandLineArgumentsPolicyT>
::MoReFEMData(int argc, char** argv)
{
Wrappers::Mpi::InitEnvironment(argc, argv);
mpi_ = std::make_unique<Wrappers::Mpi>(0, Wrappers::MpiNS::Comm::World);
petsc_ = std::make_unique<Wrappers::Petsc::Petsc>(__FILE__, __LINE__);
Internal::PetscNS::RAII::CreateOrGetInstance(__FILE__, __LINE__, argc, argv);
auto& environment = Utilities::Environment::CreateOrGetInstance(__FILE__, __LINE__);
......@@ -113,19 +110,13 @@ namespace MoReFEM
std::string start_time = "MOREFEM_START_TIME";
if (environment.DoExist(start_time))
if (!environment.DoExist(start_time))
{
throw Exception("There is an environment variable named 'MOREFEM_START_TIME'; please unset it before "
"running again your program (it might be set internally to determine the result "
"directory if ${MOREFEM_START_TIME} appears in the chosen path).",
__FILE__, __LINE__);
environment.SetEnvironmentVariable(std::make_pair(start_time, Utilities::Now(mpi)),
__FILE__, __LINE__);
mpi.Barrier();
}
environment.SetEnvironmentVariable(std::make_pair(start_time, Utilities::Now(mpi)),
__FILE__, __LINE__);
mpi.Barrier();
}
......@@ -161,7 +152,7 @@ namespace MoReFEM
{
Utilities::InputDataNS::CreateDefaultInputFile<typename InputDataT::Tuple>(input_data_file);
std::cout << '\n' << input_data_file << " wasn't existing and has just been created on processor 0; "
std::cout << '\n' << input_data_file << " wasn't existing and has just been created on root processor; "
"please edit it and then copy it onto all machines intended to run the code in parallel." << std::endl;
throw Exception("Input data file to edit and complete!", __FILE__, __LINE__);
......@@ -184,8 +175,8 @@ namespace MoReFEM
// We can be here only if the file exists...
input_data_ = std::make_unique<InputDataT>(input_data_file,
mpi,
DoTrackUnusedFieldsT);
mpi,
DoTrackUnusedFieldsT);
namespace ipl = Utilities::InputDataNS;
using Result = InputDataNS::Result;
......@@ -248,8 +239,8 @@ namespace MoReFEM
MoReFEMData<InputDataT, DoTrackUnusedFieldsT, AdditionalCommandLineArgumentsPolicyT>
::GetMpi() const noexcept
{
assert(!(!mpi_));
return *mpi_;
decltype(auto) raii = Internal::PetscNS::RAII::GetInstance(__FILE__, __LINE__);
return raii.GetMpi();
}
......
//! \file
//
//
// RAII.cpp
// MoReFEM
//
// Created by sebastien on 22/07/2019.
//Copyright © 2019 Inria. All rights reserved.
//
#include "Utilities/Exceptions/Exception.hpp"
#include "ThirdParty/Wrappers/Petsc/Internal/RAII.hpp"
#include "ThirdParty/Wrappers/Petsc/Exceptions/Petsc.hpp"
namespace MoReFEM::Internal::PetscNS
{
RAII::RAII(int argc, char** argv)
{
::MoReFEM::Wrappers::Mpi::InitEnvironment(argc, argv);
mpi_ = std::make_unique<::MoReFEM::Wrappers::Mpi>(0, ::MoReFEM::Wrappers::MpiNS::Comm::World);
int error_code = PetscInitialize(PETSC_NULL, PETSC_NULL, PETSC_NULL, "");
if (error_code)
throw ::MoReFEM::Wrappers::Petsc::ExceptionNS::Exception(error_code,
"PetscInitialize",
__FILE__, __LINE__);
}
RAII::~RAII()
{
int error_code = PetscFinalize();
assert(!error_code && "Error in PetscFinalize call!"); // No exception in destructors...
static_cast<void>(error_code); // avoid warning in release compilation.
}
const std::string& RAII::ClassName()
{
static std::string ret("Internal::PetscNS::RAII");
return ret;
}
} // namespace MoReFEM::Internal::PetscNS
//! \file
//
//
// RAII.hpp
// MoReFEM
//
// Created by sebastien on 22/07/2019.
//Copyright © 2019 Inria. All rights reserved.
//
#ifndef MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_INTERNAL_x_R_A_I_I_HPP_
# define MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_INTERNAL_x_R_A_I_I_HPP_
#include "Utilities/Singleton/Singleton.hpp"
#include "ThirdParty/Wrappers/Mpi/Mpi.hpp"
namespace MoReFEM::Internal::PetscNS
{
/*!
* \brief RAII class to initialize / close properly PETSc and mpi.
*/
class RAII final : public Utilities::Singleton<RAII>
{
private:
/// \name Special members.
///@{
//! Constructor.
explicit RAII(int argc, char** argv);
//! Destructor.
virtual ~RAII() override;
//! Friendship declaration to Singleton template class (to enable call to constructor).
friend class Utilities::Singleton<RAII>;
//! Name of the class.
static const std::string& ClassName();
///@}
public:
//! Accessor to mpi.
const ::MoReFEM::Wrappers::Mpi& GetMpi() const noexcept;
private:
//! Holds Mpi object.
::MoReFEM::Wrappers::Mpi::const_unique_ptr mpi_ = nullptr;
};
} // namespace MoReFEM::Internal::PetscNS
# include "ThirdParty/Wrappers/Petsc/Internal/RAII.hxx"
#endif // MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_INTERNAL_x_R_A_I_I_HPP_
//! \file
//
//
// RAII.hxx
// MoReFEM
//
// Created by sebastien on 22/07/2019.
//Copyright © 2019 Inria. All rights reserved.
//
#ifndef MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_INTERNAL_x_R_A_I_I_HXX_
# define MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_INTERNAL_x_R_A_I_I_HXX_
namespace MoReFEM::Internal::PetscNS
{
inline const ::MoReFEM::Wrappers::Mpi& RAII::GetMpi() const noexcept
{
assert(!(!mpi_));
return *mpi_;
}
} // namespace MoReFEM::Internal::PetscNS
#endif // MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_INTERNAL_x_R_A_I_I_HXX_
### ===================================================================================
### This file is generated automatically by Scripts/generate_cmake_source_list.py.
### Do not edit it manually!
### Convention is that:
### - When a CMake file is manually managed, it is named canonically CMakeLists.txt.
###. - When it is generated automatically, it is named SourceList.cmake.
### ===================================================================================
target_sources(${MOREFEM_UTILITIES}
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/RAII.cpp"
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/RAII.hpp"
"${CMAKE_CURRENT_LIST_DIR}/RAII.hxx"
)
/*!
//
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Fri, 20 Sep 2013 14:51:15 +0200
// Copyright (c) Inria. All rights reserved.
//
// \ingroup ThirdPartyGroup
// \addtogroup ThirdPartyGroup
// \{
*/
#include <cassert>
#include "ThirdParty/Wrappers/Petsc/Petsc.hpp"
#include "ThirdParty/Wrappers/Petsc/Exceptions/Petsc.hpp"
namespace MoReFEM
{
namespace Wrappers
{
namespace Petsc
{
Petsc::Petsc(const char* invoking_file, int invoking_line)
{
int error_code = PetscInitialize(PETSC_NULL, PETSC_NULL, PETSC_NULL, "");
if (error_code)
throw ExceptionNS::Exception(error_code, "PetscInitialize", invoking_file, invoking_line);
}
Petsc::~Petsc()
{
int error_code = PetscFinalize();
assert(!error_code && "Error in PetscFinalize call!"); // No exception in destructors...
static_cast<void>(error_code); // avoid warning in release compilation.
}
} // namespace Petsc
} // namespace Wrappers
} // namespace MoReFEM
/// @} // addtogroup ThirdPartyGroup
/*!
//
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Fri, 20 Sep 2013 14:51:15 +0200
// Copyright (c) Inria. All rights reserved.
//
// \ingroup ThirdPartyGroup
// \addtogroup ThirdPartyGroup
// \{
*/
#ifndef MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_PETSC_HPP_
# define MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_PETSC_HPP_
# include <memory>
namespace MoReFEM
{
namespace Wrappers
{
namespace Petsc
{
/*!
* \brief RAII class to initialize and close PETSc properly.
*/
struct Petsc final
{
//! Convenient alias against the relevant smart pointer to use with this RAII class.
using const_unique_ptr = std::unique_ptr<const Petsc>;
/// \name Special members.
///@{
//! Constructor (call to PetscInitialize)
//! \copydoc doxygen_hide_invoking_file_and_line
explicit Petsc(const char* invoking_file, int invoking_line);
//! Destructor (call to PetscFinalize).
~Petsc();
//! \copydoc doxygen_hide_copy_constructor
Petsc(const Petsc& rhs) = delete;
//! \copydoc doxygen_hide_move_constructor
Petsc(Petsc&& rhs) = delete;
//! \copydoc doxygen_hide_copy_affectation
Petsc& operator=(const Petsc& rhs) = delete;
//! \copydoc doxygen_hide_move_affectation
Petsc& operator=(Petsc&& rhs) = delete;
///@}
};
} // namespace Petsc
} // namespace Wrappers
} // namespace MoReFEM
/// @} // addtogroup ThirdPartyGroup
#endif // MOREFEM_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_PETSC_HPP_
......@@ -10,18 +10,17 @@
target_sources(${MOREFEM_UTILITIES}
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/Petsc.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Print.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Viewer.cpp"
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/Petsc.hpp"
"${CMAKE_CURRENT_LIST_DIR}/Print.hpp"
"${CMAKE_CURRENT_LIST_DIR}/Print.hxx"
"${CMAKE_CURRENT_LIST_DIR}/SnesMacro.hpp"
"${CMAKE_CURRENT_LIST_DIR}/Viewer.hpp"
)
include(${CMAKE_CURRENT_LIST_DIR}/Internal/SourceList.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/Solver/SourceList.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/Exceptions/SourceList.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/Vector/SourceList.cmake)
......
......@@ -186,8 +186,6 @@ namespace MoReFEM
* This follows item 16 of Scott Meyers's "Effective Modern C++", which advises to make const member
* functions thread safe.
*
* However, it is here enclosed in a unique_ptr as mutex doesn't seem to be movable (current implementations
* of both clang and gcc don't define the move constructor and the move assignation; the copy is deleted).
*/
static std::mutex singleton_mutex_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment