From cfa5cc0aafa89857231f53666e2ffb9670c36b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Mon, 16 Mar 2020 20:02:56 +0100 Subject: [PATCH 1/5] Temporary workaround for pybind11 bug --- src/Python/pytnl/tnl/Array.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Python/pytnl/tnl/Array.h b/src/Python/pytnl/tnl/Array.h index b92f22f0d..b39fe6b0e 100644 --- a/src/Python/pytnl/tnl/Array.h +++ b/src/Python/pytnl/tnl/Array.h @@ -8,6 +8,21 @@ namespace py = pybind11; #include + +// pybind11 should actually take care of this inside py::format_descriptor, but apparently it does not work... +// see https://github.com/pybind/pybind11/issues/2135 +template< typename T, typename = void > +struct underlying_type +{ + using type = T; +}; +template< typename T > +struct underlying_type< T, std::enable_if_t< std::is_enum< T >::value > > +{ + using type = std::underlying_type_t< T >; +}; + + template< typename ArrayType > void export_Array(py::module & m, const char* name) { @@ -49,7 +64,9 @@ void export_Array(py::module & m, const char* name) // Size of one scalar sizeof( typename ArrayType::ValueType ), // Python struct-style format descriptor - py::format_descriptor< typename ArrayType::ValueType >::format(), + py::format_descriptor< + typename underlying_type< typename ArrayType::ValueType >::type + >::format(), // Number of dimensions 1, // Buffer dimensions -- GitLab From 520414ca936b7b97530d0e9ebccb735a53fb93af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Thu, 9 Apr 2020 09:21:46 +0200 Subject: [PATCH 2/5] Added methods startsWith and endsWith to String --- src/TNL/String.h | 10 +++++++ src/TNL/String.hpp | 16 ++++++++++ src/UnitTests/StringTest.cpp | 58 +++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/TNL/String.h b/src/TNL/String.h index 228cb5bcb..b0fb6644c 100644 --- a/src/TNL/String.h +++ b/src/TNL/String.h @@ -342,6 +342,16 @@ class String * \include StringExampleSplit.out */ std::vector< String > split( const char separator = ' ', SplitSkip skipEmpty = SplitSkip::NoSkip ) const; + + /** + * \brief Checks if the string starts with given prefix. + */ + bool startsWith( const String& prefix ) const; + + /** + * \brief Checks if the string ends with given suffix. + */ + bool endsWith( const String& suffix ) const; }; /** diff --git a/src/TNL/String.hpp b/src/TNL/String.hpp index 3c38fe6b0..64fae92cd 100644 --- a/src/TNL/String.hpp +++ b/src/TNL/String.hpp @@ -223,6 +223,22 @@ String::split( const char separator, SplitSkip skip ) const return parts; } +inline bool +String::startsWith( const String& prefix ) const +{ + if( prefix.getSize() > getSize()) + return false; + return std::equal( prefix.begin(), prefix.end(), begin() ); +} + +inline bool +String::endsWith( const String& suffix ) const +{ + if( suffix.getSize() > getSize()) + return false; + return std::equal( suffix.rbegin(), suffix.rend(), rbegin() ); +} + inline String operator+( char string1, const String& string2 ) { return convertToString( string1 ) + string2; diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp index aa2a64a19..7447c1e6c 100644 --- a/src/UnitTests/StringTest.cpp +++ b/src/UnitTests/StringTest.cpp @@ -317,7 +317,63 @@ TEST( StringTest, SaveLoad ) EXPECT_EQ( str1, str2 ); EXPECT_EQ( std::remove( TEST_FILE_NAME ), 0 ); -}; +} + +TEST( StringTest, startsWith ) +{ + String str( "abracadabra" ); + EXPECT_TRUE( str.startsWith( "a" ) ); + EXPECT_TRUE( str.startsWith( "ab" ) ); + EXPECT_TRUE( str.startsWith( "abr" ) ); + EXPECT_TRUE( str.startsWith( "abra" ) ); + EXPECT_TRUE( str.startsWith( "abrac" ) ); + EXPECT_TRUE( str.startsWith( "abraca" ) ); + EXPECT_TRUE( str.startsWith( "abracad" ) ); + EXPECT_TRUE( str.startsWith( "abracada" ) ); + EXPECT_TRUE( str.startsWith( "abracadab" ) ); + EXPECT_TRUE( str.startsWith( "abracadabr" ) ); + EXPECT_TRUE( str.startsWith( "abracadabra" ) ); + EXPECT_FALSE( str.startsWith( "b" ) ); + EXPECT_FALSE( str.startsWith( "aa" ) ); + EXPECT_FALSE( str.startsWith( "aba" ) ); + EXPECT_FALSE( str.startsWith( "abrb" ) ); + EXPECT_FALSE( str.startsWith( "abrad" ) ); + EXPECT_FALSE( str.startsWith( "abracb" ) ); + EXPECT_FALSE( str.startsWith( "abracaa" ) ); + EXPECT_FALSE( str.startsWith( "abracadb" ) ); + EXPECT_FALSE( str.startsWith( "abracadaa" ) ); + EXPECT_FALSE( str.startsWith( "abracadaba" ) ); + EXPECT_FALSE( str.startsWith( "abracadabrb" ) ); + EXPECT_FALSE( str.startsWith( "abracadabrab" ) ); +} + +TEST( StringTest, endsWith ) +{ + String str( "abracadabra" ); + EXPECT_TRUE( str.endsWith( "a" ) ); + EXPECT_TRUE( str.endsWith( "ra" ) ); + EXPECT_TRUE( str.endsWith( "bra" ) ); + EXPECT_TRUE( str.endsWith( "abra" ) ); + EXPECT_TRUE( str.endsWith( "dabra" ) ); + EXPECT_TRUE( str.endsWith( "adabra" ) ); + EXPECT_TRUE( str.endsWith( "cadabra" ) ); + EXPECT_TRUE( str.endsWith( "acadabra" ) ); + EXPECT_TRUE( str.endsWith( "racadabra" ) ); + EXPECT_TRUE( str.endsWith( "bracadabra" ) ); + EXPECT_TRUE( str.endsWith( "abracadabra" ) ); + EXPECT_FALSE( str.endsWith( "b" ) ); + EXPECT_FALSE( str.endsWith( "ba" ) ); + EXPECT_FALSE( str.endsWith( "ara" ) ); + EXPECT_FALSE( str.endsWith( "bbra" ) ); + EXPECT_FALSE( str.endsWith( "babra" ) ); + EXPECT_FALSE( str.endsWith( "bdabra" ) ); + EXPECT_FALSE( str.endsWith( "badabra" ) ); + EXPECT_FALSE( str.endsWith( "bcadabra" ) ); + EXPECT_FALSE( str.endsWith( "aacadabra" ) ); + EXPECT_FALSE( str.endsWith( "aracadabra" ) ); + EXPECT_FALSE( str.endsWith( "bbracadabra" ) ); + EXPECT_FALSE( str.endsWith( "babracadabra" ) ); +} #endif #include "main.h" -- GitLab From c39ce1ce24b05b2ec735be2eb9d427783cc55629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Tue, 14 Apr 2020 21:41:56 +0200 Subject: [PATCH 3/5] Various small fixes --- src/TNL/Communicators/MPIPrint.h | 14 +++++++------- src/TNL/Matrices/DistributedSpMV.h | 10 ++++------ .../DistributedGridSynchronizer.h | 1 + src/TNL/Solvers/PDE/ExplicitUpdater.h | 5 ----- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/TNL/Communicators/MPIPrint.h b/src/TNL/Communicators/MPIPrint.h index 825ae239f..6d78eafaf 100644 --- a/src/TNL/Communicators/MPIPrint.h +++ b/src/TNL/Communicators/MPIPrint.h @@ -24,8 +24,8 @@ else std::stringstream __tnl_mpi_print_stream_; \ __tnl_mpi_print_stream_ << "Node " << TNL::Communicators::MpiCommunicator::GetRank() << " of " \ << TNL::Communicators::MpiCommunicator::GetSize() << " : " << message << std::endl; \ - TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str().c_str() ); \ - mpiSend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() ); \ + TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str() ); \ + mpiSend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() ); \ } \ else \ { \ @@ -35,7 +35,7 @@ else __tnl_mpi_print_j++ ) \ { \ TNL::String __tnl_mpi_print_string_; \ - mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ + mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ std::cerr << __tnl_mpi_print_string_; \ } \ } \ @@ -77,8 +77,8 @@ else std::stringstream __tnl_mpi_print_stream_; \ __tnl_mpi_print_stream_ << "Node " << TNL::Communicators::MpiCommunicator::GetRank() << " of " \ << TNL::Communicators::MpiCommunicator::GetSize() << " : " << message << std::endl; \ - TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str().c_str() ); \ - mpiSsend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() ); \ + TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str() ); \ + mpiSend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() ); \ } \ } \ else \ @@ -94,7 +94,7 @@ else if( __tnl_mpi_print_cond ) \ { \ TNL::String __tnl_mpi_print_string_; \ - mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ + mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ std::cerr << __tnl_mpi_print_string_; \ } \ } \ @@ -103,4 +103,4 @@ else #else #define TNL_MPI_PRINT_COND( condition, message ) \ std::cerr << message << std::endl; -#endif \ No newline at end of file +#endif diff --git a/src/TNL/Matrices/DistributedSpMV.h b/src/TNL/Matrices/DistributedSpMV.h index a4711dce0..01e9c286f 100644 --- a/src/TNL/Matrices/DistributedSpMV.h +++ b/src/TNL/Matrices/DistributedSpMV.h @@ -153,12 +153,14 @@ public: updateCommunicationPattern( localMatrix, group ); // prepare buffers - commRequests.clear(); globalBuffer.init( Partitioner::getOffset( localMatrix.getColumns(), rank, nproc ), inVector.getConstLocalView(), localMatrix.getColumns() - Partitioner::getOffset( localMatrix.getColumns(), rank, nproc ) - inVector.getConstLocalView().getSize() ); const auto globalBufferView = globalBuffer.getConstView(); + // buffer for asynchronous communication requests + std::vector< typename CommunicatorType::Request > commRequests; + // send our data to all processes that need it for( int i = 0; i < commPatternStarts.getRows(); i++ ) { if( i == rank ) @@ -231,21 +233,17 @@ public: commPatternEnds.reset(); localOnlySpan.first = localOnlySpan.second = 0; globalBuffer.reset(); - commRequests.clear(); } protected: // communication pattern - Matrices::Dense< IndexType, Devices::Host, int, true, Allocators::Host< IndexType > > commPatternStarts, commPatternEnds; + Matrices::Dense< IndexType, Devices::Host, int > commPatternStarts, commPatternEnds; // span of rows with only block-diagonal entries std::pair< IndexType, IndexType > localOnlySpan; // global buffer for non-local elements of the vector __DistributedSpMV_impl::ThreePartVector< RealType, DeviceType, IndexType > globalBuffer; - - // buffer for asynchronous communication requests - std::vector< typename CommunicatorType::Request > commRequests; }; } // namespace Matrices diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridSynchronizer.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridSynchronizer.h index 1347683fd..dfe572dea 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedGridSynchronizer.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridSynchronizer.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace TNL { namespace Functions{ diff --git a/src/TNL/Solvers/PDE/ExplicitUpdater.h b/src/TNL/Solvers/PDE/ExplicitUpdater.h index 74c995229..16a661d22 100644 --- a/src/TNL/Solvers/PDE/ExplicitUpdater.h +++ b/src/TNL/Solvers/PDE/ExplicitUpdater.h @@ -18,11 +18,6 @@ #include #include -#ifdef USE_MPI - #include -#endif - - namespace TNL { namespace Solvers { namespace PDE { -- GitLab From a73752d35536f43cead44a3ff3d8b6e2f3f8ba2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Wed, 15 Apr 2020 23:09:56 +0200 Subject: [PATCH 4/5] Removed PrintStackBacktrace from the assert macros Printing backtrace directly from the program is not very useful, because it does not include line numbers, so we still had to use the debugger. Furthermore, the backtrace tends to be very long, especially when multiple MPI processes crash, which obfuscates the real error messages. --- src/TNL/Assert.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/TNL/Assert.h b/src/TNL/Assert.h index 630abd09f..99f833d24 100644 --- a/src/TNL/Assert.h +++ b/src/TNL/Assert.h @@ -121,7 +121,6 @@ #include #include -#include namespace TNL { /** @@ -164,8 +163,6 @@ printDiagnosticsHost( const char* assertion, << "Line: " << line << "\n" << "Diagnostics:\n" << diagnostics << std::endl; - PrintStackBacktrace; - throw AssertionError( str.str() ); } @@ -186,8 +183,6 @@ printDiagnosticsHost( const char* assertion, << "Function: " << function << "\n" << "Line: " << line << "\n" << "Diagnostics:\n" << diagnostics << std::endl; - - PrintStackBacktrace; } #endif // TNL_THROW_ASSERTION_ERROR -- GitLab From e594db0a9472d74edd033409dba8d383d51c717d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Wed, 15 Apr 2020 23:12:25 +0200 Subject: [PATCH 5/5] Fixed initialization of empty arrays in multimaps --- .../Containers/Multimaps/EllpackIndexMultimap.hpp | 12 ++++++++---- .../Multimaps/StaticEllpackIndexMultimap.hpp | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimap.hpp b/src/TNL/Containers/Multimaps/EllpackIndexMultimap.hpp index 6fb1f4b26..c75250029 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap.hpp +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap.hpp @@ -80,10 +80,12 @@ allocate( const LocalIndexType& maxValuesCount ) const IndexType ldSize = getAllocationKeysRange( this->getKeysRange() ); this->values.setSize( ldSize * this->maxValuesCount ); this->valuesCounts.setSize( this->getKeysRange() ); - this->valuesCounts.setValue( maxValuesCount ); + if( this->valuesCounts.getSize() > 0 ) + this->valuesCounts.setValue( maxValuesCount ); // extra cost at initialization, which allows to have much simpler operator== - values.setValue( 0 ); + if( this->values.getSize() > 0 ) + values.setValue( 0 ); } template< typename Index, @@ -108,7 +110,8 @@ allocate( const ValuesAllocationVectorType& valuesCounts ) this->valuesCounts = valuesCounts; // extra cost at initialization, which allows to have much simpler operator== - values.setValue( 0 ); + if( this->values.getSize() > 0 ) + values.setValue( 0 ); } template< typename Index, @@ -128,7 +131,8 @@ setLike( const EllpackIndexMultimap< Index, Device_, LocalIndex, SliceSize_ >& o maxValuesCount = other.maxValuesCount; // extra cost at initialization, which allows to have much simpler operator== - values.setValue( 0 ); + if( this->values.getSize() > 0 ) + values.setValue( 0 ); } template< typename Index, diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.hpp b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.hpp index 3e03f9e03..7af150615 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.hpp +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.hpp @@ -82,7 +82,8 @@ allocate() values.setSize( ldSize * ValuesCount ); // extra cost at initialization, which allows to have much simpler operator== - values.setValue( 0 ); + if( ldSize > 0 ) + values.setValue( 0 ); } template< int ValuesCount, @@ -99,7 +100,8 @@ setLike( const StaticEllpackIndexMultimap< ValuesCount, Index, Device_, LocalInd values.setSize( ldSize * ValuesCount ); // extra cost at initialization, which allows to have much simpler operator== - values.setValue( 0 ); + if( ldSize > 0 ) + values.setValue( 0 ); keysRange = other.keysRange; } -- GitLab