From dc9d756951c6f63e149b722077e668e207b08d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 10 Aug 2021 17:11:59 +0200 Subject: [PATCH 1/9] Failing test --- test/CoreTest.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/test/CoreTest.cpp b/test/CoreTest.cpp index 8e5b2c9937..1c10a42173 100644 --- a/test/CoreTest.cpp +++ b/test/CoreTest.cpp @@ -950,3 +950,73 @@ TEST_CASE( "load_chunk_wrong_datatype", "[core]" ) "Type conversion during chunk loading not yet implemented" ) ); } } + +TEST_CASE( "DoConvert_single_value_to_vector", "[core]" ) +{ +#if openPMD_HAVE_ADIOS2 + { + Series write( "../samples/writeSingleMesh.bp", Access::CREATE ); + auto E_x = write.iterations[ 0 ].meshes[ "E" ][ "x" ]; + E_x.resetDataset( { Datatype::INT, { 10 } } ); + E_x.makeConstant( 10 ); + } + { + Series read( "../samples/writeSingleMesh.bp", Access::READ_ONLY ); + auto E = read.iterations[ 0 ].meshes[ "E" ]; + REQUIRE( E.axisLabels() == std::vector< std::string >{ "x" } ); + } +#endif + { + char val = 'x'; + Attribute attr{ val }; + + // the following conversions should be possible + REQUIRE( attr.get< char >() == 'x' ); // no conversion + REQUIRE( attr.get< unsigned char >() == 'x' ); + REQUIRE( attr.get< signed char >() == 'x' ); + // all the previous ones, but make them single-element vectors now + REQUIRE( + attr.get< std::vector< char > >() == std::vector< char >{ 'x' } ); + REQUIRE( + attr.get< std::vector< unsigned char > >() == + std::vector< unsigned char >{ 'x' } ); + REQUIRE( + attr.get< std::vector< signed char > >() == + std::vector< signed char >{ 'x' } ); + } + { + std::array< double, 7 > array{ 0, 1, 2, 3, 4, 5, 6 }; + Attribute attr{ array }; + + // the following conversions should be possible + REQUIRE( attr.get< std::array< double, 7 > >() == array ); + // we don't need array-to-array conversions, + // so array< int, 7 > cannot be loaded here + REQUIRE( + attr.get< std::vector< double > >() == + std::vector< double >{ 0, 1, 2, 3, 4, 5, 6 } ); + REQUIRE( + attr.get< std::vector< int > >() == + std::vector< int >{ 0, 1, 2, 3, 4, 5, 6 } ); + } + { + std::vector< double > vector{ 0, 1, 2, 3, 4, 5, 6 }; + std::array< double, 7 > arraydouble{ 0, 1, 2, 3, 4, 5, 6 }; + std::array< int, 7 > arrayint{ 0, 1, 2, 3, 4, 5, 6 }; + Attribute attr{ vector }; + + // the following conversions should be possible + REQUIRE( attr.get< std::array< double, 7 > >() == arraydouble ); + REQUIRE( attr.get< std::array< int, 7 > >() == arrayint ); + REQUIRE_THROWS_WITH( + ( attr.get< std::array< int, 8 > >() ), + Catch::Equals( "getCast: no vector to array conversion possible " + "(wrong requested array size)." ) ); + REQUIRE( + attr.get< std::vector< double > >() == + std::vector< double >{ 0, 1, 2, 3, 4, 5, 6 } ); + REQUIRE( + attr.get< std::vector< int > >() == + std::vector< int >{ 0, 1, 2, 3, 4, 5, 6 } ); + } +} \ No newline at end of file From 49cd364be2e4690f6cf06acec794cc60d535251b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 10 Aug 2021 17:12:29 +0200 Subject: [PATCH 2/9] Conversions in Attribute.hpp 1) single values to 1-value vectors 2) vectors to arrays 3) arrays to vectors --- include/openPMD/backend/Attribute.hpp | 87 +++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/include/openPMD/backend/Attribute.hpp b/include/openPMD/backend/Attribute.hpp index 900d807be0..8974f12d92 100644 --- a/include/openPMD/backend/Attribute.hpp +++ b/include/openPMD/backend/Attribute.hpp @@ -138,6 +138,93 @@ struct DoConvert, std::vector< U >, false> } }; +// conversion cast: turn a single value into a 1-element vector +template< typename T, typename U > +struct DoConvert, false> +{ + static constexpr bool convertible = std::is_convertible::value; + + template< typename PV, typename UU = U > + auto operator()( PV pv ) + -> typename std::enable_if< convertible, std::vector< UU > >::type + { + std::vector< U > u; + u.reserve( 1 ); + u.push_back( *pv ); + return u; + } + + template< typename PV, typename UU = U > + auto operator()( PV ) + -> typename std::enable_if< !convertible, std::vector< UU > >::type + { + throw std::runtime_error( + "getCast: no scalar to vector conversion possible."); + } +}; + +// conversion cast: array to vector +// if a backend reports a std::array<> for something where the frontend expects +// a vector +template< typename T, typename U, size_t n > +struct DoConvert , std::vector< U >, false> +{ + static constexpr bool convertible = std::is_convertible::value; + + template< typename PV, typename UU = U > + auto operator()( PV pv ) + -> typename std::enable_if< convertible, std::vector< UU > >::type + { + std::vector< U > u; + u.reserve( n ); + std::copy( pv->begin(), pv->end(), std::back_inserter(u) ); + return u; + } + + template< typename PV, typename UU = U > + auto operator()( PV ) + -> typename std::enable_if< !convertible, std::vector< UU > >::type + { + throw std::runtime_error( + "getCast: no array to vector conversion possible."); + } +}; + +// conversion cast: vector to array +// if a backend reports a std::vector<> for something where the frontend expects +// an array +template< typename T, typename U, size_t n > +struct DoConvert , std::array< U, n >, false> +{ + static constexpr bool convertible = std::is_convertible::value; + + template< typename PV, typename UU = U > + auto operator()( PV pv ) + -> typename std::enable_if< convertible, std::array< UU, n > >::type + { + std::array< U, n > u; + if( n != pv->size() ) + { + throw std::runtime_error( + "getCast: no vector to array conversion possible " + "(wrong requested array size)."); + } + for( size_t i = 0; i < n; ++i ) + { + u[ i ] = ( *pv )[ i ]; + } + return u; + } + + template< typename PV, typename UU = U > + auto operator()( PV ) + -> typename std::enable_if< !convertible, std::array< UU, n > >::type + { + throw std::runtime_error( + "getCast: no vector to array conversion possible."); + } +}; + /** Retrieve a stored specific Attribute and cast if convertible. * * @throw std::runtime_error if stored object is not static castable to U. From f5773c913b49a31e064ca448cdbcb1cd4bc6e4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 10 Aug 2021 16:58:25 +0200 Subject: [PATCH 3/9] Some cleanup in Attribute.hpp 1) Simplify types in DoConvert, remove unnecessary template parameter 2) Replace a long if-then-else chain by variantSrc::visit --- include/openPMD/backend/Attribute.hpp | 125 ++++++-------------------- 1 file changed, 26 insertions(+), 99 deletions(-) diff --git a/include/openPMD/backend/Attribute.hpp b/include/openPMD/backend/Attribute.hpp index 8974f12d92..cf0dc3309d 100644 --- a/include/openPMD/backend/Attribute.hpp +++ b/include/openPMD/backend/Attribute.hpp @@ -98,8 +98,7 @@ struct DoConvert; template< typename T, typename U > struct DoConvert { - template< typename PV > - U operator()( PV ) + U operator()( T * ) { throw std::runtime_error("getCast: no cast possible."); } @@ -108,8 +107,7 @@ struct DoConvert template< typename T, typename U > struct DoConvert { - template< typename PV > - U operator()( PV pv ) + U operator()( T * pv ) { return static_cast< U >( *pv ); } @@ -120,8 +118,8 @@ struct DoConvert, std::vector< U >, false> { static constexpr bool convertible = std::is_convertible::value; - template< typename PV, typename UU = U > - auto operator()( PV pv ) + template< typename UU = U > + auto operator()( std::vector< T > const * pv ) -> typename std::enable_if< convertible, std::vector< UU > >::type { std::vector< U > u; @@ -130,8 +128,8 @@ struct DoConvert, std::vector< U >, false> return u; } - template< typename PV, typename UU = U > - auto operator()( PV ) + template< typename UU = U > + auto operator()( std::vector< T > const * ) -> typename std::enable_if< !convertible, std::vector< UU > >::type { throw std::runtime_error("getCast: no vector cast possible."); @@ -144,8 +142,8 @@ struct DoConvert, false> { static constexpr bool convertible = std::is_convertible::value; - template< typename PV, typename UU = U > - auto operator()( PV pv ) + template< typename UU = U > + auto operator()( T const * pv ) -> typename std::enable_if< convertible, std::vector< UU > >::type { std::vector< U > u; @@ -154,8 +152,8 @@ struct DoConvert, false> return u; } - template< typename PV, typename UU = U > - auto operator()( PV ) + template< typename UU = U > + auto operator()( T const * ) -> typename std::enable_if< !convertible, std::vector< UU > >::type { throw std::runtime_error( @@ -167,12 +165,12 @@ struct DoConvert, false> // if a backend reports a std::array<> for something where the frontend expects // a vector template< typename T, typename U, size_t n > -struct DoConvert , std::vector< U >, false> +struct DoConvert, std::vector< U >, false> { static constexpr bool convertible = std::is_convertible::value; - template< typename PV, typename UU = U > - auto operator()( PV pv ) + template< typename UU = U > + auto operator()( std::array< T, n > const * pv ) -> typename std::enable_if< convertible, std::vector< UU > >::type { std::vector< U > u; @@ -181,8 +179,8 @@ struct DoConvert , std::vector< U >, false> return u; } - template< typename PV, typename UU = U > - auto operator()( PV ) + template< typename UU = U > + auto operator()( std::array< T, n > const * ) -> typename std::enable_if< !convertible, std::vector< UU > >::type { throw std::runtime_error( @@ -194,12 +192,12 @@ struct DoConvert , std::vector< U >, false> // if a backend reports a std::vector<> for something where the frontend expects // an array template< typename T, typename U, size_t n > -struct DoConvert , std::array< U, n >, false> +struct DoConvert, std::array< U, n >, false> { static constexpr bool convertible = std::is_convertible::value; - template< typename PV, typename UU = U > - auto operator()( PV pv ) + template< typename UU = U > + auto operator()( std::vector< T > const * pv ) -> typename std::enable_if< convertible, std::array< UU, n > >::type { std::array< U, n > u; @@ -216,8 +214,8 @@ struct DoConvert , std::array< U, n >, false> return u; } - template< typename PV, typename UU = U > - auto operator()( PV ) + template< typename UU = U > + auto operator()( std::vector< T > const * ) -> typename std::enable_if< !convertible, std::array< UU, n > >::type { throw std::runtime_error( @@ -236,83 +234,12 @@ inline U getCast( Attribute const & a ) { auto v = a.getResource(); - - if(auto pvalue_c = variantSrc::get_if< char >( &v ) ) - return DoConvert{}(pvalue_c); - else if(auto pvalue_uc = variantSrc::get_if< unsigned char >( &v ) ) - return DoConvert{}(pvalue_uc); - else if(auto pvalue_s = variantSrc::get_if< short >( &v ) ) - return DoConvert{}(pvalue_s); - else if(auto pvalue_i = variantSrc::get_if< int >( &v ) ) - return DoConvert{}(pvalue_i); - else if(auto pvalue_l = variantSrc::get_if< long >( &v ) ) - return DoConvert{}(pvalue_l); - else if(auto pvalue_ll = variantSrc::get_if< long long >( &v ) ) - return DoConvert{}(pvalue_ll); - else if(auto pvalue_us = variantSrc::get_if< unsigned short >( &v ) ) - return DoConvert{}(pvalue_us); - else if(auto pvalue_ui = variantSrc::get_if< unsigned int >( &v ) ) - return DoConvert{}(pvalue_ui); - else if(auto pvalue_ul = variantSrc::get_if< unsigned long >( &v ) ) - return DoConvert{}(pvalue_ul); - else if(auto pvalue_ull = variantSrc::get_if< unsigned long long >( &v ) ) - return DoConvert{}(pvalue_ull); - else if(auto pvalue_f = variantSrc::get_if< float >( &v ) ) - return DoConvert{}(pvalue_f); - else if(auto pvalue_d = variantSrc::get_if< double >( &v ) ) - return DoConvert{}(pvalue_d); - else if(auto pvalue_ld = variantSrc::get_if< long double >( &v ) ) - return DoConvert{}(pvalue_ld); - else if(auto pvalue_cf = variantSrc::get_if< std::complex< float > >( &v ) ) - return DoConvert, U>{}(pvalue_cf); - else if(auto pvalue_cd = variantSrc::get_if< std::complex< double > >( &v ) ) - return DoConvert, U>{}(pvalue_cd); - else if(auto pvalue_cld = variantSrc::get_if< std::complex< long double > >( &v ) ) - return DoConvert, U>{}(pvalue_cld); - else if(auto pvalue_str = variantSrc::get_if< std::string >( &v ) ) - return DoConvert{}(pvalue_str); - // vector - else if(auto pvalue_vc = variantSrc::get_if< std::vector< char > >( &v ) ) - return DoConvert, U>{}(pvalue_vc); - else if(auto pvalue_vuc = variantSrc::get_if< std::vector< unsigned char > >( &v ) ) - return DoConvert, U>{}(pvalue_vuc); - else if(auto pvalue_vs = variantSrc::get_if< std::vector< short > >( &v ) ) - return DoConvert, U>{}(pvalue_vs); - else if(auto pvalue_vi = variantSrc::get_if< std::vector< int > >( &v ) ) - return DoConvert, U>{}(pvalue_vi); - else if(auto pvalue_vl = variantSrc::get_if< std::vector< long > >( &v ) ) - return DoConvert, U>{}(pvalue_vl); - else if(auto pvalue_vll = variantSrc::get_if< std::vector< long long > >( &v ) ) - return DoConvert, U>{}(pvalue_vll); - else if(auto pvalue_vus = variantSrc::get_if< std::vector< unsigned short > >( &v ) ) - return DoConvert, U>{}(pvalue_vus); - else if(auto pvalue_vui = variantSrc::get_if< std::vector< unsigned int > >( &v ) ) - return DoConvert, U>{}(pvalue_vui); - else if(auto pvalue_vul = variantSrc::get_if< std::vector< unsigned long > >( &v ) ) - return DoConvert, U>{}(pvalue_vul); - else if(auto pvalue_vull = variantSrc::get_if< std::vector< unsigned long long > >( &v ) ) - return DoConvert, U>{}(pvalue_vull); - else if(auto pvalue_vf = variantSrc::get_if< std::vector< float > >( &v ) ) - return DoConvert, U>{}(pvalue_vf); - else if(auto pvalue_vd = variantSrc::get_if< std::vector< double > >( &v ) ) - return DoConvert, U>{}(pvalue_vd); - else if(auto pvalue_vld = variantSrc::get_if< std::vector< long double > >( &v ) ) - return DoConvert, U>{}(pvalue_vld); - else if(auto pvalue_vcf = variantSrc::get_if< std::vector< std::complex< float > > >( &v ) ) - return DoConvert >, U>{}(pvalue_vcf); - else if(auto pvalue_vcd = variantSrc::get_if< std::vector< std::complex< double > > >( &v ) ) - return DoConvert >, U>{}(pvalue_vcd); - else if(auto pvalue_vcld = variantSrc::get_if< std::vector< std::complex< long double > > >( &v ) ) - return DoConvert >, U>{}(pvalue_vcld); - else if(auto pvalue_vstr = variantSrc::get_if< std::vector< std::string > >( &v ) ) - return DoConvert, U>{}(pvalue_vstr); - // extra - else if(auto pvalue_vad = variantSrc::get_if< std::array< double, 7 > >( &v ) ) - return DoConvert, U>{}(pvalue_vad); - else if(auto pvalue_b = variantSrc::get_if< bool >( &v ) ) - return DoConvert{}(pvalue_b); - else - throw std::runtime_error("getCast: unknown Datatype."); + return variantSrc::visit( + []( auto && containedValue ) -> U { + using containedType = std::decay_t< decltype( containedValue ) >; + return DoConvert< containedType, U >{}( &containedValue ); + }, + v ); } template< typename U > From 4271d70d8f453d1ae071ef20ee6b1edab4a307af Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 10 Aug 2021 22:45:30 -0700 Subject: [PATCH 4/9] CoreTest: Fix std::array constructors Make more widely compile-able. --- test/CoreTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/CoreTest.cpp b/test/CoreTest.cpp index 1c10a42173..72830b0df2 100644 --- a/test/CoreTest.cpp +++ b/test/CoreTest.cpp @@ -985,7 +985,7 @@ TEST_CASE( "DoConvert_single_value_to_vector", "[core]" ) std::vector< signed char >{ 'x' } ); } { - std::array< double, 7 > array{ 0, 1, 2, 3, 4, 5, 6 }; + std::array< double, 7 > array{{ 0, 1, 2, 3, 4, 5, 6 }}; Attribute attr{ array }; // the following conversions should be possible @@ -1001,8 +1001,8 @@ TEST_CASE( "DoConvert_single_value_to_vector", "[core]" ) } { std::vector< double > vector{ 0, 1, 2, 3, 4, 5, 6 }; - std::array< double, 7 > arraydouble{ 0, 1, 2, 3, 4, 5, 6 }; - std::array< int, 7 > arrayint{ 0, 1, 2, 3, 4, 5, 6 }; + std::array< double, 7 > arraydouble{{ 0, 1, 2, 3, 4, 5, 6 }}; + std::array< int, 7 > arrayint{{ 0, 1, 2, 3, 4, 5, 6 }}; Attribute attr{ vector }; // the following conversions should be possible @@ -1019,4 +1019,4 @@ TEST_CASE( "DoConvert_single_value_to_vector", "[core]" ) attr.get< std::vector< int > >() == std::vector< int >{ 0, 1, 2, 3, 4, 5, 6 } ); } -} \ No newline at end of file +} From dca2d95479be637d6acc885bd5724ff24835fbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 11 Aug 2021 11:14:04 +0200 Subject: [PATCH 5/9] Explicit casting in some places This avoids some warnings --- include/openPMD/backend/Attribute.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/openPMD/backend/Attribute.hpp b/include/openPMD/backend/Attribute.hpp index cf0dc3309d..73a3c98d05 100644 --- a/include/openPMD/backend/Attribute.hpp +++ b/include/openPMD/backend/Attribute.hpp @@ -148,7 +148,7 @@ struct DoConvert, false> { std::vector< U > u; u.reserve( 1 ); - u.push_back( *pv ); + u.push_back( static_cast< U >( *pv ) ); return u; } @@ -209,7 +209,7 @@ struct DoConvert, std::array< U, n >, false> } for( size_t i = 0; i < n; ++i ) { - u[ i ] = ( *pv )[ i ]; + u[ i ] = static_cast< U >( ( *pv )[ i ] ); } return u; } From 9f2bc40614c19f95cda8519dfa66128401fc0f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 11 Aug 2021 11:14:22 +0200 Subject: [PATCH 6/9] Intel compilers: Don't use variantSrc::visit They don't like it --- include/openPMD/backend/Attribute.hpp | 86 +++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/include/openPMD/backend/Attribute.hpp b/include/openPMD/backend/Attribute.hpp index 73a3c98d05..961ec9f1c2 100644 --- a/include/openPMD/backend/Attribute.hpp +++ b/include/openPMD/backend/Attribute.hpp @@ -234,12 +234,98 @@ inline U getCast( Attribute const & a ) { auto v = a.getResource(); + + // icpc does not like variantSrc::visit + // we use variantSrc::visit for the other compilers to avoid having an + // endless list of if-then-else + // also, once we switch to C++17, we might throw this out in + // favor of a hopefully working std::visit +#ifdef __INTEL_COMPILER + if(auto pvalue_c = variantSrc::get_if< char >( &v ) ) + return DoConvert{}(pvalue_c); + else if(auto pvalue_uc = variantSrc::get_if< unsigned char >( &v ) ) + return DoConvert{}(pvalue_uc); + else if(auto pvalue_s = variantSrc::get_if< short >( &v ) ) + return DoConvert{}(pvalue_s); + else if(auto pvalue_i = variantSrc::get_if< int >( &v ) ) + return DoConvert{}(pvalue_i); + else if(auto pvalue_l = variantSrc::get_if< long >( &v ) ) + return DoConvert{}(pvalue_l); + else if(auto pvalue_ll = variantSrc::get_if< long long >( &v ) ) + return DoConvert{}(pvalue_ll); + else if(auto pvalue_us = variantSrc::get_if< unsigned short >( &v ) ) + return DoConvert{}(pvalue_us); + else if(auto pvalue_ui = variantSrc::get_if< unsigned int >( &v ) ) + return DoConvert{}(pvalue_ui); + else if(auto pvalue_ul = variantSrc::get_if< unsigned long >( &v ) ) + return DoConvert{}(pvalue_ul); + else if(auto pvalue_ull = variantSrc::get_if< unsigned long long >( &v ) ) + return DoConvert{}(pvalue_ull); + else if(auto pvalue_f = variantSrc::get_if< float >( &v ) ) + return DoConvert{}(pvalue_f); + else if(auto pvalue_d = variantSrc::get_if< double >( &v ) ) + return DoConvert{}(pvalue_d); + else if(auto pvalue_ld = variantSrc::get_if< long double >( &v ) ) + return DoConvert{}(pvalue_ld); + else if(auto pvalue_cf = variantSrc::get_if< std::complex< float > >( &v ) ) + return DoConvert, U>{}(pvalue_cf); + else if(auto pvalue_cd = variantSrc::get_if< std::complex< double > >( &v ) ) + return DoConvert, U>{}(pvalue_cd); + else if(auto pvalue_cld = variantSrc::get_if< std::complex< long double > >( &v ) ) + return DoConvert, U>{}(pvalue_cld); + else if(auto pvalue_str = variantSrc::get_if< std::string >( &v ) ) + return DoConvert{}(pvalue_str); + // vector + else if(auto pvalue_vc = variantSrc::get_if< std::vector< char > >( &v ) ) + return DoConvert, U>{}(pvalue_vc); + else if(auto pvalue_vuc = variantSrc::get_if< std::vector< unsigned char > >( &v ) ) + return DoConvert, U>{}(pvalue_vuc); + else if(auto pvalue_vs = variantSrc::get_if< std::vector< short > >( &v ) ) + return DoConvert, U>{}(pvalue_vs); + else if(auto pvalue_vi = variantSrc::get_if< std::vector< int > >( &v ) ) + return DoConvert, U>{}(pvalue_vi); + else if(auto pvalue_vl = variantSrc::get_if< std::vector< long > >( &v ) ) + return DoConvert, U>{}(pvalue_vl); + else if(auto pvalue_vll = variantSrc::get_if< std::vector< long long > >( &v ) ) + return DoConvert, U>{}(pvalue_vll); + else if(auto pvalue_vus = variantSrc::get_if< std::vector< unsigned short > >( &v ) ) + return DoConvert, U>{}(pvalue_vus); + else if(auto pvalue_vui = variantSrc::get_if< std::vector< unsigned int > >( &v ) ) + return DoConvert, U>{}(pvalue_vui); + else if(auto pvalue_vul = variantSrc::get_if< std::vector< unsigned long > >( &v ) ) + return DoConvert, U>{}(pvalue_vul); + else if(auto pvalue_vull = variantSrc::get_if< std::vector< unsigned long long > >( &v ) ) + return DoConvert, U>{}(pvalue_vull); + else if(auto pvalue_vf = variantSrc::get_if< std::vector< float > >( &v ) ) + return DoConvert, U>{}(pvalue_vf); + else if(auto pvalue_vd = variantSrc::get_if< std::vector< double > >( &v ) ) + return DoConvert, U>{}(pvalue_vd); + else if(auto pvalue_vld = variantSrc::get_if< std::vector< long double > >( &v ) ) + return DoConvert, U>{}(pvalue_vld); + else if(auto pvalue_vcf = variantSrc::get_if< std::vector< std::complex< float > > >( &v ) ) + return DoConvert >, U>{}(pvalue_vcf); + else if(auto pvalue_vcd = variantSrc::get_if< std::vector< std::complex< double > > >( &v ) ) + return DoConvert >, U>{}(pvalue_vcd); + else if(auto pvalue_vcld = variantSrc::get_if< std::vector< std::complex< long double > > >( &v ) ) + return DoConvert >, U>{}(pvalue_vcld); + else if(auto pvalue_vstr = variantSrc::get_if< std::vector< std::string > >( &v ) ) + return DoConvert, U>{}(pvalue_vstr); + // extra + else if(auto pvalue_vad = variantSrc::get_if< std::array< double, 7 > >( &v ) ) + return DoConvert, U>{}(pvalue_vad); + else if(auto pvalue_b = variantSrc::get_if< bool >( &v ) ) + return DoConvert{}(pvalue_b); + else + throw std::runtime_error("getCast: unknown Datatype."); + +#else return variantSrc::visit( []( auto && containedValue ) -> U { using containedType = std::decay_t< decltype( containedValue ) >; return DoConvert< containedType, U >{}( &containedValue ); }, v ); +#endif } template< typename U > From 101723a95db6050d137d011b3c3ed652b2182c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 11 Aug 2021 11:52:41 +0200 Subject: [PATCH 7/9] Remove scattered checks for vector attributes --- src/Mesh.cpp | 16 ++++------------ src/RecordComponent.cpp | 5 ++--- src/backend/MeshRecordComponent.cpp | 12 +++--------- src/backend/PatchRecord.cpp | 15 +-------------- 4 files changed, 10 insertions(+), 38 deletions(-) diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 5d8ebe439d..e9551c42e6 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -318,10 +318,8 @@ Mesh::read() aRead.name = "axisLabels"; IOHandler()->enqueue(IOTask(this, aRead)); IOHandler()->flush(); - if( *aRead.dtype == DT::VEC_STRING ) + if( *aRead.dtype == DT::VEC_STRING || *aRead.dtype == DT::STRING) setAxisLabels(Attribute(*aRead.resource).get< std::vector< std::string > >()); - else if( *aRead.dtype == DT::STRING ) - setAxisLabels({Attribute(*aRead.resource).get< std::string >()}); else throw std::runtime_error("Unexpected Attribute datatype for 'axisLabels'"); @@ -329,24 +327,18 @@ Mesh::read() IOHandler()->enqueue(IOTask(this, aRead)); IOHandler()->flush(); Attribute a = Attribute(*aRead.resource); - if( *aRead.dtype == DT::VEC_FLOAT ) + if( *aRead.dtype == DT::VEC_FLOAT || *aRead.dtype == DT::FLOAT ) setGridSpacing(a.get< std::vector< float > >()); - else if( *aRead.dtype == DT::FLOAT ) - setGridSpacing(std::vector< float >({a.get< float >()})); - else if( *aRead.dtype == DT::VEC_DOUBLE ) + else if( *aRead.dtype == DT::VEC_DOUBLE || *aRead.dtype == DT::DOUBLE ) setGridSpacing(a.get< std::vector< double > >()); - else if( *aRead.dtype == DT::DOUBLE ) - setGridSpacing(std::vector< double >({a.get< double >()})); else throw std::runtime_error("Unexpected Attribute datatype for 'gridSpacing'"); aRead.name = "gridGlobalOffset"; IOHandler()->enqueue(IOTask(this, aRead)); IOHandler()->flush(); - if( *aRead.dtype == DT::VEC_DOUBLE ) + if( *aRead.dtype == DT::VEC_DOUBLE || *aRead.dtype == DT::DOUBLE ) setGridGlobalOffset(Attribute(*aRead.resource).get< std::vector< double > >()); - else if( *aRead.dtype == DT::DOUBLE ) - setGridGlobalOffset({Attribute(*aRead.resource).get< double >()}); else throw std::runtime_error("Unexpected Attribute datatype for 'gridGlobalOffset'"); diff --git a/src/RecordComponent.cpp b/src/RecordComponent.cpp index bff6286e0e..d40061c198 100644 --- a/src/RecordComponent.cpp +++ b/src/RecordComponent.cpp @@ -343,9 +343,8 @@ RecordComponent::readBase() // uint64_t check Datatype const attrDtype = *aRead.dtype; - if( isSame( attrDtype, determineDatatype< uint64_t >() ) ) - e.push_back( a.get< uint64_t >() ); - else if( isSame( attrDtype, determineDatatype< std::vector< uint64_t > >() ) ) + if( isSame( attrDtype, determineDatatype< std::vector< uint64_t > >() ) + || isSame( attrDtype, determineDatatype< uint64_t >() ) ) for( auto const& val : a.get< std::vector< uint64_t > >() ) e.push_back( val ); else diff --git a/src/backend/MeshRecordComponent.cpp b/src/backend/MeshRecordComponent.cpp index 0a3a72d597..8c9634a32c 100644 --- a/src/backend/MeshRecordComponent.cpp +++ b/src/backend/MeshRecordComponent.cpp @@ -39,18 +39,12 @@ MeshRecordComponent::read() IOHandler()->enqueue(IOTask(this, aRead)); IOHandler()->flush(); Attribute a = Attribute(*aRead.resource); - if( *aRead.dtype == DT::VEC_FLOAT ) + if( *aRead.dtype == DT::VEC_FLOAT || *aRead.dtype == DT::FLOAT ) setPosition(a.get< std::vector< float > >()); - else if( *aRead.dtype == DT::FLOAT ) - setPosition(std::vector< float >({a.get< float >()})); - else if( *aRead.dtype == DT::VEC_DOUBLE ) + else if( *aRead.dtype == DT::VEC_DOUBLE || *aRead.dtype == DT::DOUBLE ) setPosition(a.get< std::vector< double > >()); - else if( *aRead.dtype == DT::DOUBLE ) - setPosition(std::vector< double >({a.get< double >()})); - else if( *aRead.dtype == DT::VEC_LONG_DOUBLE ) + else if( *aRead.dtype == DT::VEC_LONG_DOUBLE || *aRead.dtype == DT::LONG_DOUBLE ) setPosition(a.get< std::vector< long double > >()); - else if( *aRead.dtype == DT::LONG_DOUBLE ) - setPosition(std::vector< long double >({a.get< long double >()})); else throw std::runtime_error( "Unexpected Attribute datatype for 'position'"); diff --git a/src/backend/PatchRecord.cpp b/src/backend/PatchRecord.cpp index 9179c03c78..3926677a30 100644 --- a/src/backend/PatchRecord.cpp +++ b/src/backend/PatchRecord.cpp @@ -62,21 +62,8 @@ PatchRecord::read() IOHandler()->enqueue(IOTask(this, aRead)); IOHandler()->flush(); - if( *aRead.dtype == Datatype::ARR_DBL_7 ) + if( *aRead.dtype == Datatype::ARR_DBL_7 || *aRead.dtype == Datatype::VEC_DOUBLE ) this->setAttribute("unitDimension", Attribute(*aRead.resource).template get< std::array< double, 7 > >()); - else if( *aRead.dtype == Datatype::VEC_DOUBLE ) - { - auto vec = Attribute(*aRead.resource).template get< std::vector< double > >(); - if( vec.size() == 7 ) - { - std::array< double, 7 > arr; - std::copy(vec.begin(), - vec.end(), - arr.begin()); - this->setAttribute("unitDimension", arr); - } else - throw std::runtime_error("Unexpected Attribute datatype for 'unitDimension'"); - } else throw std::runtime_error("Unexpected Attribute datatype for 'unitDimension'"); From 8219f3c8dac558e10181e72be3eed6636eedbd9c Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Wed, 11 Aug 2021 13:01:07 -0700 Subject: [PATCH 8/9] Generalize icpc guard As defined in CMake for compiler identification. --- include/openPMD/backend/Attribute.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openPMD/backend/Attribute.hpp b/include/openPMD/backend/Attribute.hpp index 961ec9f1c2..4555796e2c 100644 --- a/include/openPMD/backend/Attribute.hpp +++ b/include/openPMD/backend/Attribute.hpp @@ -240,7 +240,7 @@ getCast( Attribute const & a ) // endless list of if-then-else // also, once we switch to C++17, we might throw this out in // favor of a hopefully working std::visit -#ifdef __INTEL_COMPILER +#if defined(__ICC) || defined(__INTEL_COMPILER) if(auto pvalue_c = variantSrc::get_if< char >( &v ) ) return DoConvert{}(pvalue_c); else if(auto pvalue_uc = variantSrc::get_if< unsigned char >( &v ) ) From 1cb0a9ec71dad32d711e298d94936bb89586ee54 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Wed, 11 Aug 2021 13:03:56 -0700 Subject: [PATCH 9/9] Doc ICC version (2021.3.0) --- include/openPMD/backend/Attribute.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openPMD/backend/Attribute.hpp b/include/openPMD/backend/Attribute.hpp index 4555796e2c..5471283662 100644 --- a/include/openPMD/backend/Attribute.hpp +++ b/include/openPMD/backend/Attribute.hpp @@ -235,7 +235,7 @@ getCast( Attribute const & a ) { auto v = a.getResource(); - // icpc does not like variantSrc::visit + // icpc 2021.3.0 does not like variantSrc::visit (with mpark-variant) // we use variantSrc::visit for the other compilers to avoid having an // endless list of if-then-else // also, once we switch to C++17, we might throw this out in