mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-24 21:10:33 +05:00
logging in ngcore
This commit is contained in:
parent
782aa072bc
commit
fd3474f5cb
@ -101,6 +101,13 @@ test_guidelines:
|
|||||||
- docker run -e CCACHE_DIR=/ccache -v /mnt/ccache:/ccache netgen_${CI_BUILD_REF_NAME}:${UBUNTU_VERSION} bash /root/src/netgen/tests/build_guidelines.sh
|
- docker run -e CCACHE_DIR=/ccache -v /mnt/ccache:/ccache netgen_${CI_BUILD_REF_NAME}:${UBUNTU_VERSION} bash /root/src/netgen/tests/build_guidelines.sh
|
||||||
when: always
|
when: always
|
||||||
|
|
||||||
|
# check if it compiles without spdlog
|
||||||
|
test_noSpdlog:
|
||||||
|
<<: *ubuntu
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- docker run -e CCACHE_DIR=/ccache -v /mnt/ccache:/ccache netgen_${CI_BUILD_REF_NAME}:${UBUNTU_VERSION} bash /root/src/netgen/tests/build_nospdlog.sh
|
||||||
|
|
||||||
cleanup_ubuntu:
|
cleanup_ubuntu:
|
||||||
stage: cleanup
|
stage: cleanup
|
||||||
tags:
|
tags:
|
||||||
|
@ -19,6 +19,8 @@ option( USE_CCACHE "use ccache")
|
|||||||
option( USE_INTERNAL_TCL "Compile tcl files into the code and don't install them" ON)
|
option( USE_INTERNAL_TCL "Compile tcl files into the code and don't install them" ON)
|
||||||
option( ENABLE_UNIT_TESTS "Enable Catch unit tests")
|
option( ENABLE_UNIT_TESTS "Enable Catch unit tests")
|
||||||
option( ENABLE_CPP_CORE_GUIDELINES_CHECK "Enable cpp core guideline checks on ngcore" OFF)
|
option( ENABLE_CPP_CORE_GUIDELINES_CHECK "Enable cpp core guideline checks on ngcore" OFF)
|
||||||
|
option( USE_SPDLOG "Enable spd log logging" ON)
|
||||||
|
option( DEBUG_LOG "Enable more debug output (may increase computation time) - only works with USE_SPDLOG=ON" OFF)
|
||||||
|
|
||||||
option( USE_SUPERBUILD "use ccache" ON)
|
option( USE_SUPERBUILD "use ccache" ON)
|
||||||
|
|
||||||
@ -258,6 +260,7 @@ endif (USE_GUI)
|
|||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
if (USE_PYTHON)
|
if (USE_PYTHON)
|
||||||
|
add_subdirectory(external_dependencies/pybind11)
|
||||||
add_definitions(-DNG_PYTHON)
|
add_definitions(-DNG_PYTHON)
|
||||||
find_path(PYBIND_INCLUDE_DIR pybind11/pybind11.h HINTS ${PYTHON_INCLUDE_DIR})
|
find_path(PYBIND_INCLUDE_DIR pybind11/pybind11.h HINTS ${PYTHON_INCLUDE_DIR})
|
||||||
if( PYBIND_INCLUDE_DIR )
|
if( PYBIND_INCLUDE_DIR )
|
||||||
@ -350,6 +353,11 @@ endif(ENABLE_UNIT_TESTS)
|
|||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
|
if(USE_SPDLOG)
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/external_projects/spdlog.cmake)
|
||||||
|
include_directories(${SPDLOG_INCLUDE_DIR})
|
||||||
|
endif(USE_SPDLOG)
|
||||||
|
|
||||||
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
||||||
find_program(
|
find_program(
|
||||||
CLANG_TIDY_EXE
|
CLANG_TIDY_EXE
|
||||||
|
@ -142,6 +142,8 @@ set_vars( NETGEN_CMAKE_ARGS
|
|||||||
CMAKE_INSTALL_PREFIX
|
CMAKE_INSTALL_PREFIX
|
||||||
ENABLE_UNIT_TESTS
|
ENABLE_UNIT_TESTS
|
||||||
ENABLE_CPP_CORE_GUIDELINES_CHECK
|
ENABLE_CPP_CORE_GUIDELINES_CHECK
|
||||||
|
USE_SPDLOG
|
||||||
|
DEBUG_LOG
|
||||||
)
|
)
|
||||||
|
|
||||||
# propagate all variables set on the command line using cmake -DFOO=BAR
|
# propagate all variables set on the command line using cmake -DFOO=BAR
|
||||||
|
18
cmake/external_projects/spdlog.cmake
Normal file
18
cmake/external_projects/spdlog.cmake
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
include(ExternalProject)
|
||||||
|
find_program(GIT_EXECUTABLE git)
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
project_spdlog
|
||||||
|
PREFIX ${CMAKE_BINARY_DIR}/spdlog
|
||||||
|
GIT_REPOSITORY https://github.com/gabime/spdlog.git
|
||||||
|
GIT_TAG v1.2.1
|
||||||
|
TIMEOUT 01
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(project_spdlog source_dir)
|
||||||
|
set(SPDLOG_INCLUDE_DIR ${source_dir}/include)
|
@ -1,16 +1,41 @@
|
|||||||
add_library(ngcore SHARED archive.cpp)
|
|
||||||
|
|
||||||
target_compile_definitions(ngcore PRIVATE -DNGCORE_EXPORTS)
|
add_library(ngcore SHARED archive.cpp logging.cpp)
|
||||||
|
|
||||||
|
target_compile_definitions(ngcore PRIVATE NGCORE_EXPORTS)
|
||||||
|
if(NOT WIN32)
|
||||||
|
target_compile_options(ngcore PRIVATE -fvisibility=hidden)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
if(USE_SPDLOG)
|
||||||
|
include_directories(${SPDLOG_INCLUDE_DIR})
|
||||||
|
install(DIRECTORY ${SPDLOG_INCLUDE_DIR}
|
||||||
|
DESTINATION ${NG_INSTALL_DIR_INCLUDE}
|
||||||
|
)
|
||||||
|
add_dependencies(ngcore project_spdlog)
|
||||||
|
target_compile_definitions(ngcore PUBLIC NETGEN_USE_SPDLOG)
|
||||||
|
if(DEBUG_LOG)
|
||||||
|
target_compile_definitions(ngcore PUBLIC NETGEN_LOG_DEBUG)
|
||||||
|
endif(DEBUG_LOG)
|
||||||
|
endif(USE_SPDLOG)
|
||||||
|
|
||||||
install(TARGETS ngcore DESTINATION ${NG_INSTALL_DIR} COMPONENT netgen)
|
install(TARGETS ngcore DESTINATION ${NG_INSTALL_DIR} COMPONENT netgen)
|
||||||
|
|
||||||
if(USE_PYTHON)
|
if(USE_PYTHON)
|
||||||
|
target_compile_definitions(ngcore PUBLIC NETGEN_PYTHON)
|
||||||
target_include_directories(ngcore PUBLIC ${PYTHON_INCLUDE_DIRS})
|
target_include_directories(ngcore PUBLIC ${PYTHON_INCLUDE_DIRS})
|
||||||
endif(USE_PYTHON)
|
endif(USE_PYTHON)
|
||||||
|
|
||||||
install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp
|
install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp
|
||||||
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
||||||
|
|
||||||
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
||||||
set_target_properties(ngcore PROPERTIES CXX_CLANG_TIDY "${DO_CLANG_TIDY}")
|
set_target_properties(ngcore PROPERTIES CXX_CLANG_TIDY "${DO_CLANG_TIDY}")
|
||||||
endif(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
endif(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
||||||
|
|
||||||
|
if(USE_PYTHON)
|
||||||
|
pybind11_add_module(pyngcore SHARED python_ngcore.cpp)
|
||||||
|
target_link_libraries(pyngcore PUBLIC ngcore)
|
||||||
|
set_target_properties(pyngcore PROPERTIES INSTALL_RPATH "${NG_RPATH_TOKEN}/${NETGEN_PYTHON_RPATH}")
|
||||||
|
install(TARGETS pyngcore DESTINATION ${NG_INSTALL_DIR_PYTHON} COMPONENT netgen)
|
||||||
|
endif(USE_PYTHON)
|
||||||
|
|
||||||
|
@ -3,24 +3,25 @@
|
|||||||
|
|
||||||
#include <complex> // for complex
|
#include <complex> // for complex
|
||||||
#include <cstring> // for size_t, strlen
|
#include <cstring> // for size_t, strlen
|
||||||
#include <fstream> // for operator<<, ifstream, ofstream, basic...
|
#include <fstream> // for ifstream, ofstream
|
||||||
#include <functional> // for function
|
#include <functional> // for function
|
||||||
#include <map> // for map, _Rb_tree_iterator
|
#include <map> // for map
|
||||||
#include <memory> // for __shared_ptr_access, __shared_ptr_acc...
|
#include <memory> // for shared_ptr
|
||||||
#include <stdexcept> // for runtime_error
|
#include <stdexcept> // for runtime_error
|
||||||
#include <string> // for string, operator+
|
#include <string> // for string
|
||||||
#include <type_traits> // for declval, enable_if, false_type, is_co...
|
#include <type_traits> // for declval, enable_if, false_type, is_co...
|
||||||
#include <typeinfo> // for type_info
|
#include <typeinfo> // for type_info
|
||||||
#include <utility> // for move, swap, pair
|
#include <utility> // for move, swap, pair
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
|
|
||||||
|
#include "logging.hpp" // for logger
|
||||||
#include "ngcore_api.hpp" // for NGCORE_API, unlikely
|
#include "ngcore_api.hpp" // for NGCORE_API, unlikely
|
||||||
#include "type_traits.hpp" // for all_of_tmpl
|
#include "type_traits.hpp" // for all_of_tmpl
|
||||||
#include "version.hpp" // for VersionInfo
|
#include "version.hpp" // for VersionInfo
|
||||||
|
|
||||||
#ifdef NG_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
#endif // NG_PYTHON
|
#endif // NETGEN_PYTHON
|
||||||
|
|
||||||
namespace ngcore
|
namespace ngcore
|
||||||
{
|
{
|
||||||
@ -104,20 +105,28 @@ namespace ngcore
|
|||||||
std::vector<void*> nr2ptr;
|
std::vector<void*> nr2ptr;
|
||||||
protected:
|
protected:
|
||||||
bool shallow_to_python = false;
|
bool shallow_to_python = false;
|
||||||
|
// version map is only used in InArchives
|
||||||
|
std::map<std::string, VersionInfo> version_map;
|
||||||
|
std::shared_ptr<spdlog::logger> logger;
|
||||||
public:
|
public:
|
||||||
Archive() = delete;
|
Archive() = delete;
|
||||||
Archive(const Archive&) = delete;
|
Archive(const Archive&) = delete;
|
||||||
Archive(Archive&&) = delete;
|
Archive(Archive&&) = delete;
|
||||||
Archive (bool ais_output) :
|
Archive (bool ais_output) : is_output(ais_output), shared_ptr_count(0),
|
||||||
is_output(ais_output), shared_ptr_count(0), ptr_count(0) { ; }
|
ptr_count(0), logger(GetLogger("Archive")) { ; }
|
||||||
|
|
||||||
virtual ~Archive() { ; }
|
virtual ~Archive() { ; }
|
||||||
|
|
||||||
|
// If the object is pickled, all shallow archived objects will be pickled as a list,
|
||||||
|
// instead of written as a binary archive. This allows pickle to serialize every object only
|
||||||
|
// once and put them together correctly afterwards. Therefore all objects that may live in
|
||||||
|
// Python should be archived using this Shallow function. If Shallow is called from C++ code
|
||||||
|
// it archives the object normally.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Archive& Shallow(T& val)
|
Archive& Shallow(T& val)
|
||||||
{
|
{
|
||||||
static_assert(detail::is_any_pointer<T>, "ShallowArchive must be given pointer type!");
|
static_assert(detail::is_any_pointer<T>, "ShallowArchive must be given pointer type!");
|
||||||
#ifdef NG_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
if(shallow_to_python)
|
if(shallow_to_python)
|
||||||
{
|
{
|
||||||
if(is_output)
|
if(is_output)
|
||||||
@ -126,17 +135,17 @@ namespace ngcore
|
|||||||
val = pybind11::cast<T>(ShallowInPython());
|
val = pybind11::cast<T>(ShallowInPython());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // NG_PYTHON
|
#endif // NETGEN_PYTHON
|
||||||
*this & val;
|
*this & val;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NG_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
virtual void ShallowOutPython(pybind11::object /*unused*/) // NOLINT (copy by val is ok for this virt func)
|
virtual void ShallowOutPython(const pybind11::object& /*unused*/)
|
||||||
{ throw std::runtime_error("Should not get in ShallowToPython base class implementation!"); }
|
{ throw std::runtime_error("Should not get in ShallowToPython base class implementation!"); }
|
||||||
virtual pybind11::object ShallowInPython()
|
virtual pybind11::object ShallowInPython()
|
||||||
{ throw std::runtime_error("Should not get in ShallowFromPython base class implementation!"); }
|
{ throw std::runtime_error("Should not get in ShallowFromPython base class implementation!"); }
|
||||||
#endif // NG_PYTHON
|
#endif // NETGEN_PYTHON
|
||||||
|
|
||||||
Archive& operator=(const Archive&) = delete;
|
Archive& operator=(const Archive&) = delete;
|
||||||
Archive& operator=(Archive&&) = delete;
|
Archive& operator=(Archive&&) = delete;
|
||||||
@ -261,28 +270,39 @@ namespace ngcore
|
|||||||
{
|
{
|
||||||
if(Output())
|
if(Output())
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Store shared ptr of type " + Demangle(typeid(T).name()));
|
||||||
// save -2 for nullptr
|
// save -2 for nullptr
|
||||||
if(!ptr)
|
if(!ptr)
|
||||||
return (*this) << -2;
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Storing nullptr");
|
||||||
|
return (*this) << -2;
|
||||||
|
}
|
||||||
|
|
||||||
void* reg_ptr = ptr.get();
|
void* reg_ptr = ptr.get();
|
||||||
bool neededDowncast = false;
|
bool neededDowncast = false;
|
||||||
// Downcasting is only possible for our registered classes
|
// Downcasting is only possible for our registered classes
|
||||||
if(typeid(T) != typeid(*ptr))
|
if(typeid(T) != typeid(*ptr))
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Typids are different: " + Demangle(typeid(T).name()) + " vs. " +
|
||||||
|
Demangle(typeid(*ptr).name()));
|
||||||
if(!IsRegistered(Demangle(typeid(*ptr).name())))
|
if(!IsRegistered(Demangle(typeid(*ptr).name())))
|
||||||
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
||||||
+ Demangle(typeid(*ptr).name())
|
+ Demangle(typeid(*ptr).name())
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
reg_ptr = GetArchiveRegister(Demangle(typeid(*ptr).name())).downcaster(typeid(T), ptr.get());
|
reg_ptr = GetArchiveRegister(Demangle(typeid(*ptr).name())).downcaster(typeid(T), ptr.get());
|
||||||
// if there was a true downcast we have to store more information
|
// if there was a true downcast we have to store more information
|
||||||
if(reg_ptr != static_cast<void*>(ptr.get()) )
|
if(reg_ptr != static_cast<void*>(ptr.get()))
|
||||||
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Multiple/Virtual inheritance involved, need to cast pointer");
|
||||||
neededDowncast = true;
|
neededDowncast = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto pos = shared_ptr2nr.find(reg_ptr);
|
auto pos = shared_ptr2nr.find(reg_ptr);
|
||||||
// if not found store -1 and the pointer
|
// if not found store -1 and the pointer
|
||||||
if(pos == shared_ptr2nr.end())
|
if(pos == shared_ptr2nr.end())
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Didn't find the shared_ptr, create new registry entry at " +
|
||||||
|
std::to_string(shared_ptr_count));
|
||||||
auto p = ptr.get();
|
auto p = ptr.get();
|
||||||
(*this) << -1;
|
(*this) << -1;
|
||||||
(*this) & neededDowncast & p;
|
(*this) & neededDowncast & p;
|
||||||
@ -293,23 +313,27 @@ namespace ngcore
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
// if found store the position and if it has to be downcasted and how
|
// if found store the position and if it has to be downcasted and how
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Found shared_ptr at position " + std::to_string(pos->second));
|
||||||
(*this) << pos->second << neededDowncast;
|
(*this) << pos->second << neededDowncast;
|
||||||
if(neededDowncast)
|
if(neededDowncast)
|
||||||
(*this) << Demangle(typeid(*ptr).name());
|
(*this) << Demangle(typeid(*ptr).name());
|
||||||
}
|
}
|
||||||
else // Input
|
else // Input
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Reading shared_ptr of type " + Demangle(typeid(T).name()));
|
||||||
int nr;
|
int nr;
|
||||||
(*this) & nr;
|
(*this) & nr;
|
||||||
// -2 restores a nullptr
|
// -2 restores a nullptr
|
||||||
if(nr == -2)
|
if(nr == -2)
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Reading a nullptr");
|
||||||
ptr = nullptr;
|
ptr = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
// -1 restores a new shared ptr by restoring the inner pointer and creating a shared_ptr to it
|
// -1 restores a new shared ptr by restoring the inner pointer and creating a shared_ptr to it
|
||||||
if (nr == -1)
|
if (nr == -1)
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Createing new shared_ptr");
|
||||||
T* p = nullptr;
|
T* p = nullptr;
|
||||||
bool neededDowncast;
|
bool neededDowncast;
|
||||||
(*this) & neededDowncast & p;
|
(*this) & neededDowncast & p;
|
||||||
@ -317,6 +341,7 @@ namespace ngcore
|
|||||||
// if we did downcast we need to store a shared_ptr<void> to the true object
|
// if we did downcast we need to store a shared_ptr<void> to the true object
|
||||||
if(neededDowncast)
|
if(neededDowncast)
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Shared pointer needed downcasting");
|
||||||
std::string name;
|
std::string name;
|
||||||
(*this) & name;
|
(*this) & name;
|
||||||
auto info = GetArchiveRegister(name);
|
auto info = GetArchiveRegister(name);
|
||||||
@ -327,15 +352,20 @@ namespace ngcore
|
|||||||
ptr.get())));
|
ptr.get())));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nr2shared_ptr.push_back(ptr);
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Shared pointer didn't need downcasting");
|
||||||
|
nr2shared_ptr.push_back(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Reading already existing pointer at entry " + std::to_string(nr));
|
||||||
auto other = nr2shared_ptr[nr];
|
auto other = nr2shared_ptr[nr];
|
||||||
bool neededDowncast;
|
bool neededDowncast;
|
||||||
(*this) & neededDowncast;
|
(*this) & neededDowncast;
|
||||||
if(neededDowncast)
|
if(neededDowncast)
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Shared pointer needed pointer downcast");
|
||||||
// if there was a downcast we can expect the class to be registered (since archiving
|
// if there was a downcast we can expect the class to be registered (since archiving
|
||||||
// wouldn't have worked else)
|
// wouldn't have worked else)
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -348,7 +378,10 @@ namespace ngcore
|
|||||||
other.get())));
|
other.get())));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ptr = std::static_pointer_cast<T>(other);
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Shared pointer didn't need pointer casts");
|
||||||
|
ptr = std::static_pointer_cast<T>(other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
@ -360,26 +393,39 @@ namespace ngcore
|
|||||||
{
|
{
|
||||||
if (Output())
|
if (Output())
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Store pointer of type " + Demangle(typeid(T).name()));
|
||||||
// if the pointer is null store -2
|
// if the pointer is null store -2
|
||||||
if (!p)
|
if (!p)
|
||||||
return (*this) << -2;
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Storing nullptr");
|
||||||
|
return (*this) << -2;
|
||||||
|
}
|
||||||
auto reg_ptr = static_cast<void*>(p);
|
auto reg_ptr = static_cast<void*>(p);
|
||||||
if(typeid(T) != typeid(*p))
|
if(typeid(T) != typeid(*p))
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Typeids are different: " + Demangle(typeid(T).name()) + " vs. " +
|
||||||
|
Demangle(typeid(*p).name()));
|
||||||
if(!IsRegistered(Demangle(typeid(*p).name())))
|
if(!IsRegistered(Demangle(typeid(*p).name())))
|
||||||
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
||||||
+ Demangle(typeid(*p).name())
|
+ Demangle(typeid(*p).name())
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
reg_ptr = GetArchiveRegister(Demangle(typeid(*p).name())).downcaster(typeid(T), static_cast<void*>(p));
|
reg_ptr = GetArchiveRegister(Demangle(typeid(*p).name())).downcaster(typeid(T), static_cast<void*>(p));
|
||||||
|
if(reg_ptr != static_cast<void*>(p))
|
||||||
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Multiple/Virtual inheritance involved, need to cast pointer");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto pos = ptr2nr.find(reg_ptr);
|
auto pos = ptr2nr.find(reg_ptr);
|
||||||
// if the pointer is not found in the map create a new entry
|
// if the pointer is not found in the map create a new entry
|
||||||
if (pos == ptr2nr.end())
|
if (pos == ptr2nr.end())
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Didn't find pointer, create new registry entry at " +
|
||||||
|
std::to_string(ptr_count));
|
||||||
ptr2nr[reg_ptr] = ptr_count++;
|
ptr2nr[reg_ptr] = ptr_count++;
|
||||||
if(typeid(*p) == typeid(T))
|
if(typeid(*p) == typeid(T))
|
||||||
if (std::is_constructible<T>::value)
|
if (std::is_constructible<T>::value)
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Store standard class pointer (no virt. inh,...)");
|
||||||
return (*this) << -1 & (*p);
|
return (*this) << -1 & (*p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -395,6 +441,7 @@ namespace ngcore
|
|||||||
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
||||||
+ Demangle(typeid(*p).name())
|
+ Demangle(typeid(*p).name())
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Store a possibly more complicated pointer");
|
||||||
return (*this) << -3 << Demangle(typeid(*p).name()) & (*p);
|
return (*this) << -3 << Demangle(typeid(*p).name()) & (*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,27 +449,39 @@ namespace ngcore
|
|||||||
{
|
{
|
||||||
(*this) & pos->second;
|
(*this) & pos->second;
|
||||||
bool downcasted = !(reg_ptr == static_cast<void*>(p) );
|
bool downcasted = !(reg_ptr == static_cast<void*>(p) );
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Store a the existing position in registry at " +
|
||||||
|
std::to_string(pos->second));
|
||||||
|
NETGEN_DEBUG_LOG(logger, std::string("Pointer ") + (downcasted ? "needs " : "doesn't need ") +
|
||||||
|
"downcasting");
|
||||||
// store if the class has been downcasted and the name
|
// store if the class has been downcasted and the name
|
||||||
(*this) << downcasted << Demangle(typeid(*p).name());
|
(*this) << downcasted << Demangle(typeid(*p).name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Reading pointer of type " + Demangle(typeid(T).name()));
|
||||||
int nr;
|
int nr;
|
||||||
(*this) & nr;
|
(*this) & nr;
|
||||||
if (nr == -2) // restore a nullptr
|
if (nr == -2) // restore a nullptr
|
||||||
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Loading a nullptr");
|
||||||
p = nullptr;
|
p = nullptr;
|
||||||
|
}
|
||||||
else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...)
|
else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...)
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Load a new pointer to a simple class");
|
||||||
p = detail::constructIfPossible<T>();
|
p = detail::constructIfPossible<T>();
|
||||||
nr2ptr.push_back(p);
|
nr2ptr.push_back(p);
|
||||||
(*this) & *p;
|
(*this) & *p;
|
||||||
}
|
}
|
||||||
else if(nr == -3) // restore one of our registered classes that can have multiple inheritance,...
|
else if(nr == -3) // restore one of our registered classes that can have multiple inheritance,...
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Load a new pointer to a potentially more complicated class "
|
||||||
|
"(allows for multiple/virtual inheritance,...)");
|
||||||
// As stated above, we want this special behaviour only for our classes that implement DoArchive
|
// As stated above, we want this special behaviour only for our classes that implement DoArchive
|
||||||
std::string name;
|
std::string name;
|
||||||
(*this) & name;
|
(*this) & name;
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Name = " + name);
|
||||||
auto info = GetArchiveRegister(name);
|
auto info = GetArchiveRegister(name);
|
||||||
// the creator creates a new object of type name, and returns a void* pointing
|
// the creator creates a new object of type name, and returns a void* pointing
|
||||||
// to T (which may have an offset)
|
// to T (which may have an offset)
|
||||||
@ -434,9 +493,13 @@ namespace ngcore
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
NETGEN_DEBUG_LOG(logger, "Restoring pointer to already existing object at registry position " +
|
||||||
|
std::to_string(nr));
|
||||||
bool downcasted;
|
bool downcasted;
|
||||||
std::string name;
|
std::string name;
|
||||||
(*this) & downcasted & name;
|
(*this) & downcasted & name;
|
||||||
|
NETGEN_DEBUG_LOG(logger, std::string(downcasted ? "Downcasted" : "Not downcasted") +
|
||||||
|
" object of type " + name);
|
||||||
if(downcasted)
|
if(downcasted)
|
||||||
{
|
{
|
||||||
// if the class has been downcasted we can assume it is in the register
|
// if the class has been downcasted we can assume it is in the register
|
||||||
@ -536,7 +599,7 @@ namespace ngcore
|
|||||||
{
|
{
|
||||||
static_assert(detail::all_of_tmpl<std::is_base_of<Bases,T>::value...>,
|
static_assert(detail::all_of_tmpl<std::is_base_of<Bases,T>::value...>,
|
||||||
"Variadic template arguments must be base classes of T");
|
"Variadic template arguments must be base classes of T");
|
||||||
detail::ClassArchiveInfo info;
|
detail::ClassArchiveInfo info {};
|
||||||
info.creator = [this,&info](const std::type_info& ti) -> void*
|
info.creator = [this,&info](const std::type_info& ti) -> void*
|
||||||
{ return typeid(T) == ti ? detail::constructIfPossible<T>()
|
{ return typeid(T) == ti ? detail::constructIfPossible<T>()
|
||||||
: Archive::Caster<T, Bases...>::tryUpcast(ti, detail::constructIfPossible<T>()); };
|
: Archive::Caster<T, Bases...>::tryUpcast(ti, detail::constructIfPossible<T>()); };
|
||||||
@ -643,6 +706,9 @@ namespace ngcore
|
|||||||
BinaryInArchive (const std::string& filename)
|
BinaryInArchive (const std::string& filename)
|
||||||
: BinaryInArchive(std::make_shared<std::ifstream>(filename)) { ; }
|
: BinaryInArchive(std::make_shared<std::ifstream>(filename)) { ; }
|
||||||
|
|
||||||
|
const VersionInfo& GetVersion(const std::string& library) override
|
||||||
|
{ return version_map[library]; }
|
||||||
|
|
||||||
using Archive::operator&;
|
using Archive::operator&;
|
||||||
Archive & operator & (double & d) override
|
Archive & operator & (double & d) override
|
||||||
{ Read(d); return *this; }
|
{ Read(d); return *this; }
|
||||||
@ -758,6 +824,9 @@ namespace ngcore
|
|||||||
TextInArchive (const std::string& filename)
|
TextInArchive (const std::string& filename)
|
||||||
: TextInArchive(std::make_shared<std::ifstream>(filename)) {}
|
: TextInArchive(std::make_shared<std::ifstream>(filename)) {}
|
||||||
|
|
||||||
|
const VersionInfo& GetVersion(const std::string& library) override
|
||||||
|
{ return version_map[library]; }
|
||||||
|
|
||||||
using Archive::operator&;
|
using Archive::operator&;
|
||||||
Archive & operator & (double & d) override
|
Archive & operator & (double & d) override
|
||||||
{ *stream >> d; return *this; }
|
{ *stream >> d; return *this; }
|
||||||
@ -805,7 +874,7 @@ namespace ngcore
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef NG_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
|
|
||||||
template<typename ARCHIVE>
|
template<typename ARCHIVE>
|
||||||
class PyArchive : public ARCHIVE
|
class PyArchive : public ARCHIVE
|
||||||
@ -813,7 +882,11 @@ namespace ngcore
|
|||||||
private:
|
private:
|
||||||
pybind11::list lst;
|
pybind11::list lst;
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
protected:
|
||||||
using ARCHIVE::stream;
|
using ARCHIVE::stream;
|
||||||
|
using ARCHIVE::version_map;
|
||||||
|
using ARCHIVE::logger;
|
||||||
|
using ARCHIVE::GetLibraryVersions;
|
||||||
public:
|
public:
|
||||||
PyArchive(const pybind11::object& alst = pybind11::none()) :
|
PyArchive(const pybind11::object& alst = pybind11::none()) :
|
||||||
ARCHIVE(std::make_shared<std::stringstream>()),
|
ARCHIVE(std::make_shared<std::stringstream>()),
|
||||||
@ -821,8 +894,13 @@ namespace ngcore
|
|||||||
{
|
{
|
||||||
ARCHIVE::shallow_to_python = true;
|
ARCHIVE::shallow_to_python = true;
|
||||||
if(Input())
|
if(Input())
|
||||||
stream = std::make_shared<std::stringstream>
|
{
|
||||||
(pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-1]));
|
stream = std::make_shared<std::stringstream>
|
||||||
|
(pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-1]));
|
||||||
|
*this & version_map;
|
||||||
|
stream = std::make_shared<std::stringstream>
|
||||||
|
(pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-2]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using ARCHIVE::Output;
|
using ARCHIVE::Output;
|
||||||
@ -831,39 +909,45 @@ namespace ngcore
|
|||||||
using ARCHIVE::operator&;
|
using ARCHIVE::operator&;
|
||||||
using ARCHIVE::operator<<;
|
using ARCHIVE::operator<<;
|
||||||
using ARCHIVE::GetVersion;
|
using ARCHIVE::GetVersion;
|
||||||
void ShallowOutPython(pybind11::object val) override { lst.append(val); }
|
void ShallowOutPython(const pybind11::object& val) override { lst.append(val); }
|
||||||
pybind11::object ShallowInPython() override { return lst[index++]; }
|
pybind11::object ShallowInPython() override { return lst[index++]; }
|
||||||
|
|
||||||
pybind11::list WriteOut()
|
pybind11::list WriteOut()
|
||||||
{
|
{
|
||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
lst.append(pybind11::bytes(std::static_pointer_cast<std::stringstream>(stream)->str()));
|
lst.append(pybind11::bytes(std::static_pointer_cast<std::stringstream>(stream)->str()));
|
||||||
|
stream = std::make_shared<std::stringstream>();
|
||||||
|
*this & GetLibraryVersions();
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename T_ARCHIVE_OUT=BinaryOutArchive, typename T_ARCHIVE_IN=BinaryInArchive>
|
template<typename T, typename T_ARCHIVE_OUT=BinaryOutArchive, typename T_ARCHIVE_IN=BinaryInArchive>
|
||||||
auto NGSPickle(bool printoutput=false)
|
auto NGSPickle()
|
||||||
{
|
{
|
||||||
return pybind11::pickle([printoutput](T* self)
|
return pybind11::pickle([](T* self)
|
||||||
{
|
{
|
||||||
PyArchive<T_ARCHIVE_OUT> ar;
|
PyArchive<T_ARCHIVE_OUT> ar;
|
||||||
ar & self;
|
ar & self;
|
||||||
auto output = pybind11::make_tuple(ar.WriteOut());
|
auto output = pybind11::make_tuple(ar.WriteOut());
|
||||||
if(printoutput)
|
NETGEN_DEBUG_LOG(GetLogger("Archive"), "pickling output for object of type " +
|
||||||
pybind11::print("pickle output of", Demangle(typeid(T).name()),"=", output);
|
Demangle(typeid(T).name()) + " = " +
|
||||||
|
std::string(pybind11::str(output)));
|
||||||
return output;
|
return output;
|
||||||
},
|
},
|
||||||
[](pybind11::tuple state)
|
[](pybind11::tuple state)
|
||||||
{
|
{
|
||||||
T* val = nullptr;
|
T* val = nullptr;
|
||||||
|
NETGEN_DEBUG_LOG(GetLogger("Archive"), "State for unpickling of object of type " +
|
||||||
|
Demangle(typeid(T).name()) + " = " +
|
||||||
|
std::string(pybind11::str(state[0])));
|
||||||
PyArchive<T_ARCHIVE_IN> ar(state[0]);
|
PyArchive<T_ARCHIVE_IN> ar(state[0]);
|
||||||
ar & val;
|
ar & val;
|
||||||
return val;
|
return val;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NG_PYTHON
|
#endif // NETGEN_PYTHON
|
||||||
} // namespace ngcore
|
} // namespace ngcore
|
||||||
|
|
||||||
#endif // NETGEN_CORE_ARCHIVE_HPP
|
#endif // NETGEN_CORE_ARCHIVE_HPP
|
||||||
|
109
libsrc/core/logging.cpp
Normal file
109
libsrc/core/logging.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
|
||||||
|
#include "logging.hpp"
|
||||||
|
|
||||||
|
#ifdef NETGEN_USE_SPDLOG
|
||||||
|
|
||||||
|
#include <spdlog/sinks/ansicolor_sink.h>
|
||||||
|
#include <spdlog/sinks/basic_file_sink.h>
|
||||||
|
|
||||||
|
#endif // NETGEN_USE_SPDLOG
|
||||||
|
|
||||||
|
namespace ngcore
|
||||||
|
{
|
||||||
|
#ifdef NETGEN_USE_SPDLOG
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<spdlog::sinks::sink>>& GetDefaultSinks()
|
||||||
|
{
|
||||||
|
static std::vector<std::shared_ptr<spdlog::sinks::sink>> sinks =
|
||||||
|
{ std::make_shared<spdlog::sinks::ansicolor_stdout_sink_mt>() };
|
||||||
|
return sinks;
|
||||||
|
}
|
||||||
|
std::shared_ptr<spdlog::logger> CreateDefaultLogger(const std::string& name)
|
||||||
|
{
|
||||||
|
auto& default_sinks = GetDefaultSinks();
|
||||||
|
auto logger = std::make_shared<spdlog::logger>(name, default_sinks.begin(), default_sinks.end());
|
||||||
|
spdlog::details::registry::instance().register_and_init(logger);
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
std::shared_ptr<spdlog::logger> GetLogger(const std::string& name)
|
||||||
|
{
|
||||||
|
auto logger = spdlog::get(name);
|
||||||
|
if(!logger)
|
||||||
|
logger = detail::CreateDefaultLogger(name);
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLoggingLevel(spdlog::level::level_enum level, const std::string& name)
|
||||||
|
{
|
||||||
|
if(!name.empty())
|
||||||
|
spdlog::get(name)->set_level(level);
|
||||||
|
else
|
||||||
|
spdlog::set_level(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddFileSink(const std::string& filename, spdlog::level::level_enum level, const std::string& logger)
|
||||||
|
{
|
||||||
|
auto sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename);
|
||||||
|
sink->set_level(level);
|
||||||
|
if(!logger.empty())
|
||||||
|
GetLogger(logger)->sinks().push_back(sink);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
detail::GetDefaultSinks().push_back(sink);
|
||||||
|
spdlog::details::registry::instance().apply_all([sink](auto logger) { logger->sinks().push_back(sink); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddConsoleSink(spdlog::level::level_enum level, const std::string& logger)
|
||||||
|
{
|
||||||
|
auto sink = std::make_shared<spdlog::sinks::ansicolor_stdout_sink_mt>();
|
||||||
|
sink->set_level(level);
|
||||||
|
if(!logger.empty())
|
||||||
|
GetLogger(logger)->sinks().push_back(sink);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
detail::GetDefaultSinks().push_back(sink);
|
||||||
|
spdlog::details::registry::instance().apply_all([sink](auto logger) { logger->sinks().push_back(sink); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearLoggingSinks(const std::string& logger)
|
||||||
|
{
|
||||||
|
if(!logger.empty())
|
||||||
|
GetLogger(logger)->sinks().clear();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
detail::GetDefaultSinks().clear();
|
||||||
|
spdlog::details::registry::instance().apply_all([](auto logger) { logger->sinks().clear(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlushOnLoggingLevel(spdlog::level::level_enum level, const std::string& logger)
|
||||||
|
{
|
||||||
|
if(!logger.empty())
|
||||||
|
GetLogger(logger)->flush_on(level);
|
||||||
|
else
|
||||||
|
spdlog::flush_on(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // NETGEN_USE_SPDLOG
|
||||||
|
|
||||||
|
// Dummy functions if no spdlog is available
|
||||||
|
|
||||||
|
std::shared_ptr<spdlog::logger> GetLogger(const std::string& /*unused*/)
|
||||||
|
{
|
||||||
|
return std::make_shared<spdlog::logger>();
|
||||||
|
}
|
||||||
|
void SetLoggingLevel(spdlog::level::level_enum /*unused*/, const std::string& /*unused*/) {}
|
||||||
|
void AddFileSink(const std::string& /*unused*/, spdlog::level::level_enum /*unused*/,
|
||||||
|
const std::string& /*unused*/)
|
||||||
|
{}
|
||||||
|
void AddConsoleSink(spdlog::level::level_enum /*unused*/, const std::string& /*unused*/) {}
|
||||||
|
void ClearLoggingSinks(const std::string& /*unused*/) {}
|
||||||
|
void FlushOnLoggingLevel(spdlog::level::level_enum /*unused*/, const std::string& /*unused*/) {}
|
||||||
|
|
||||||
|
#endif // NETGEN_USE_SPDLOG
|
||||||
|
} //namespace ngcore
|
87
libsrc/core/logging.hpp
Normal file
87
libsrc/core/logging.hpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef NETGEN_CORE_LOGGING_HPP
|
||||||
|
#define NETGEN_CORE_LOGGING_HPP
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ngcore_api.hpp"
|
||||||
|
|
||||||
|
#ifdef NETGEN_USE_SPDLOG
|
||||||
|
|
||||||
|
#ifdef NETGEN_LOG_DEBUG
|
||||||
|
#define SPDLOG_DEBUG_ON
|
||||||
|
#endif // NETGEN_LOG_DEBUG
|
||||||
|
|
||||||
|
#include <spdlog/logger.h>
|
||||||
|
#include <spdlog/sinks/sink.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#define NETGEN_DEBUG_LOG(logger, ...) SPDLOG_DEBUG(logger, __VA_ARGS__)
|
||||||
|
|
||||||
|
#else // NETGEN_USE_SPDLOG
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace spdlog
|
||||||
|
{
|
||||||
|
// Dummys if Netgen is compiled with USE_SPDLOG=OFF.
|
||||||
|
class logger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
void trace(const T& /*unused*/) {}
|
||||||
|
template<typename T>
|
||||||
|
void debug(const T& /*unused*/) {}
|
||||||
|
template<typename T>
|
||||||
|
void info(const T& text) { std::cout << text << std::endl; }
|
||||||
|
template<typename T>
|
||||||
|
void warn(const T& text) { std::cout << text << std::endl; }
|
||||||
|
template<typename T>
|
||||||
|
void error(const T& text) { std::cout << text << std::endl; }
|
||||||
|
template<typename T>
|
||||||
|
void critical(const T& text) { std::cout << text << std::endl; }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace level
|
||||||
|
{
|
||||||
|
enum level_enum
|
||||||
|
{
|
||||||
|
trace = 0,
|
||||||
|
debug = 1,
|
||||||
|
info = 2,
|
||||||
|
warn = 3,
|
||||||
|
err = 4,
|
||||||
|
critical = 5,
|
||||||
|
off = 6
|
||||||
|
};
|
||||||
|
} // namespace level
|
||||||
|
|
||||||
|
namespace sinks
|
||||||
|
{
|
||||||
|
class sink {};
|
||||||
|
} // namespace sinks
|
||||||
|
|
||||||
|
} //namespace spdlog
|
||||||
|
|
||||||
|
#define NETGEN_DEBUG_LOG(logger, ...)
|
||||||
|
|
||||||
|
#endif // NETGEN_USE_SPDLOG
|
||||||
|
|
||||||
|
namespace ngcore
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<spdlog::sinks::sink>>& GetDefaultSinks();
|
||||||
|
inline std::shared_ptr<spdlog::logger> CreateDefaultLogger(const std::string& name);
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
NGCORE_API std::shared_ptr<spdlog::logger> GetLogger(const std::string& name);
|
||||||
|
NGCORE_API void SetLoggingLevel(spdlog::level::level_enum level, const std::string& name);
|
||||||
|
NGCORE_API void AddFileSink(const std::string& filename, spdlog::level::level_enum level, const std::string& logger);
|
||||||
|
NGCORE_API void AddConsoleSink(spdlog::level::level_enum level, const std::string& logger);
|
||||||
|
NGCORE_API void ClearLoggingSinks(const std::string& logger);
|
||||||
|
NGCORE_API void FlushOnLoggingLevel(spdlog::level::level_enum level, const std::string& logger);
|
||||||
|
} // namespace ngcore
|
||||||
|
|
||||||
|
#endif // NETGEN_CORE_LOGGING_HPP
|
@ -2,6 +2,7 @@
|
|||||||
#define NETGEN_CORE_NGCORE_HPP
|
#define NETGEN_CORE_NGCORE_HPP
|
||||||
|
|
||||||
#include "archive.hpp"
|
#include "archive.hpp"
|
||||||
|
#include "logging.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
#endif // NETGEN_CORE_NGCORE_HPP
|
#endif // NETGEN_CORE_NGCORE_HPP
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#define NGCORE_API_EXPORT __declspec(dllexport)
|
#define NGCORE_API_EXPORT __declspec(dllexport)
|
||||||
#define NGCORE_API_IMPORT __declspec(dllimport)
|
#define NGCORE_API_IMPORT __declspec(dllimport)
|
||||||
#else
|
#else
|
||||||
#define NGCORE_API_EXPORT
|
#define NGCORE_API_EXPORT __attribute__((visibility("default")))
|
||||||
#define NGCORE_API_IMPORT
|
#define NGCORE_API_IMPORT __attribute__((visibility("default")))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NGCORE_EXPORTS
|
#ifdef NGCORE_EXPORTS
|
||||||
|
30
libsrc/core/python_ngcore.cpp
Normal file
30
libsrc/core/python_ngcore.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
#include "logging.hpp"
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
using namespace ngcore;
|
||||||
|
|
||||||
|
PYBIND11_MODULE(pyngcore, m) // NOLINT
|
||||||
|
{
|
||||||
|
py::enum_<spdlog::level::level_enum>(m, "LOG_LEVEL", "Logging level")
|
||||||
|
.value("Trace", spdlog::level::trace)
|
||||||
|
.value("Debug", spdlog::level::debug)
|
||||||
|
.value("Info", spdlog::level::info)
|
||||||
|
.value("Warn", spdlog::level::warn)
|
||||||
|
.value("Error", spdlog::level::err)
|
||||||
|
.value("Critical", spdlog::level::critical)
|
||||||
|
.value("Off", spdlog::level::off);
|
||||||
|
|
||||||
|
m.def("SetLoggingLevel", &SetLoggingLevel, py::arg("level"), py::arg("logger")="",
|
||||||
|
"Set logging level, if name is given only to the specific logger, else set the global logging level");
|
||||||
|
m.def("AddFileSink", &AddFileSink, py::arg("filename"), py::arg("level"), py::arg("logger")="",
|
||||||
|
"Add File sink, either only to logger specified or globally to all loggers");
|
||||||
|
m.def("AddConsoleSink", &AddConsoleSink, py::arg("level"), py::arg("logger")="",
|
||||||
|
"Add console output for specific logger or all if none given");
|
||||||
|
m.def("ClearLoggingSinks", &ClearLoggingSinks, py::arg("logger")="",
|
||||||
|
"Clear sinks of specific logger, or all if none given");
|
||||||
|
m.def("FlushOnLoggingLevel", &FlushOnLoggingLevel, py::arg("level"), py::arg("logger")="",
|
||||||
|
"Flush every message with level at least `level` for specific logger or all loggers if none given.");
|
||||||
|
}
|
@ -6,6 +6,10 @@ add_library(gen OBJECT
|
|||||||
mpi_interface.cpp gzstream.cpp
|
mpi_interface.cpp gzstream.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
target_link_libraries(gen ngcore)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
set_target_properties( gen PROPERTIES POSITION_INDEPENDENT_CODE ON )
|
set_target_properties( gen PROPERTIES POSITION_INDEPENDENT_CODE ON )
|
||||||
|
|
||||||
install( FILES ngexception.hpp DESTINATION ${NG_INSTALL_DIR_INCLUDE} COMPONENT netgen_devel )
|
install( FILES ngexception.hpp DESTINATION ${NG_INSTALL_DIR_INCLUDE} COMPONENT netgen_devel )
|
||||||
|
@ -3,6 +3,9 @@ add_library(gprim OBJECT
|
|||||||
adtree.cpp geom2d.cpp geom3d.cpp geomfuncs.cpp
|
adtree.cpp geom2d.cpp geom3d.cpp geomfuncs.cpp
|
||||||
geomtest3d.cpp transform3d.cpp spline.cpp splinegeometry.cpp
|
geomtest3d.cpp transform3d.cpp spline.cpp splinegeometry.cpp
|
||||||
)
|
)
|
||||||
|
if(NOT WIN32)
|
||||||
|
target_link_libraries(gprim ngcore)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
set_target_properties( gprim PROPERTIES POSITION_INDEPENDENT_CODE ON )
|
set_target_properties( gprim PROPERTIES POSITION_INDEPENDENT_CODE ON )
|
||||||
|
|
||||||
|
@ -4,6 +4,10 @@ add_library( la OBJECT
|
|||||||
|
|
||||||
set_target_properties(la PROPERTIES POSITION_INDEPENDENT_CODE ON )
|
set_target_properties(la PROPERTIES POSITION_INDEPENDENT_CODE ON )
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
target_link_libraries(la ngcore)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
densemat.hpp linalg.hpp opti.hpp
|
densemat.hpp linalg.hpp opti.hpp
|
||||||
polynomial.hpp vector.hpp
|
polynomial.hpp vector.hpp
|
||||||
|
@ -506,7 +506,6 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m)
|
|||||||
)
|
)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.def("__str__", &ToString<Mesh>)
|
|
||||||
.def_property_readonly("_timestamp", &Mesh::GetTimeStamp)
|
.def_property_readonly("_timestamp", &Mesh::GetTimeStamp)
|
||||||
.def("Load", FunctionPointer
|
.def("Load", FunctionPointer
|
||||||
([](Mesh & self, const string & filename)
|
([](Mesh & self, const string & filename)
|
||||||
|
@ -9,7 +9,7 @@ if(USE_GUI)
|
|||||||
endif(USE_GUI)
|
endif(USE_GUI)
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
target_link_libraries( occ ${OCC_LIBRARIES} ${PYTHON_LIBRARIES})
|
target_link_libraries( occ ngcore ${OCC_LIBRARIES} ${PYTHON_LIBRARIES})
|
||||||
install( TARGETS occ ${NG_INSTALL_DIR})
|
install( TARGETS occ ${NG_INSTALL_DIR})
|
||||||
if (USE_GUI)
|
if (USE_GUI)
|
||||||
target_link_libraries( occvis occ )
|
target_link_libraries( occvis occ )
|
||||||
|
@ -4,8 +4,7 @@ add_library(stl ${NG_LIB_TYPE}
|
|||||||
)
|
)
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
target_link_libraries( stl mesh ${PYTHON_LIBRARIES})
|
target_link_libraries( stl ngcore mesh ${PYTHON_LIBRARIES})
|
||||||
target_link_libraries( stl ${PYTHON_LIBRARIES})
|
|
||||||
install( TARGETS stl ${NG_INSTALL_DIR})
|
install( TARGETS stl ${NG_INSTALL_DIR})
|
||||||
endif(NOT WIN32)
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ endif(USE_GUI)
|
|||||||
add_library(visual ${NG_LIB_TYPE} ${LIB_VISUAL_SOURCES})
|
add_library(visual ${NG_LIB_TYPE} ${LIB_VISUAL_SOURCES})
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
target_link_libraries( visual ${PYTHON_LIBRARIES} ${MPI_CXX_LIBRARIES} ${OPENGL_LIBRARIES} )
|
target_link_libraries( visual ngcore ${PYTHON_LIBRARIES} ${MPI_CXX_LIBRARIES} ${OPENGL_LIBRARIES} )
|
||||||
install( TARGETS visual ${NG_INSTALL_DIR})
|
install( TARGETS visual ${NG_INSTALL_DIR})
|
||||||
endif(NOT WIN32)
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
8
tests/build_nospdlog.sh
Normal file
8
tests/build_nospdlog.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
cd
|
||||||
|
mkdir -p build/netgen
|
||||||
|
cd build/netgen
|
||||||
|
cmake ../../src/netgen -DUSE_CCACHE=ON -DUSE_SPDLOG=OFF -DCMAKE_CXX_COMPILER=clang++ \
|
||||||
|
-DCMAKE_C_COMPILER=clang
|
||||||
|
make -j12
|
||||||
|
make install
|
||||||
|
|
@ -3,8 +3,7 @@ if(ENABLE_UNIT_TESTS)
|
|||||||
add_custom_target(unit_tests)
|
add_custom_target(unit_tests)
|
||||||
|
|
||||||
# Build catch_main test object
|
# Build catch_main test object
|
||||||
message("netgen include dir = ${NETGEN_INCLUDE_DIR_ABSOLUTE} --------------------------------------")
|
include_directories(${CATCH_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../libsrc/include ${SPDLOG_INCLUDE_DIR})
|
||||||
include_directories(${CATCH_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../libsrc/include})
|
|
||||||
add_library(catch_main STATIC main.cpp)
|
add_library(catch_main STATIC main.cpp)
|
||||||
set_target_properties(catch_main PROPERTIES CXX_STANDARD 17)
|
set_target_properties(catch_main PROPERTIES CXX_STANDARD 17)
|
||||||
add_dependencies(unit_tests catch_main)
|
add_dependencies(unit_tests catch_main)
|
||||||
@ -15,11 +14,7 @@ add_test(NAME unit_tests_built COMMAND ${CMAKE_COMMAND} --build . --target unit_
|
|||||||
|
|
||||||
macro(add_unit_test name sources)
|
macro(add_unit_test name sources)
|
||||||
add_executable(test_${name} ${sources} )
|
add_executable(test_${name} ${sources} )
|
||||||
if (WIN32)
|
target_link_libraries(test_${name} ngcore catch_main)
|
||||||
target_link_libraries(test_${name} ngcore catch_main)
|
|
||||||
else(WIN32)
|
|
||||||
target_link_libraries(test_${name} ngcore catch_main)
|
|
||||||
endif(WIN32)
|
|
||||||
|
|
||||||
add_dependencies(unit_tests test_${name})
|
add_dependencies(unit_tests test_${name})
|
||||||
add_test(NAME unit_${name} COMMAND test_${name})
|
add_test(NAME unit_${name} COMMAND test_${name})
|
||||||
|
Loading…
Reference in New Issue
Block a user