diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 78585003da472bde1185a3c3380fcc860ce800c2..5d45bbbceb86b1468da9efeccdec15e3a4b37de8 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -40,7 +40,7 @@ public: template< typename Array, typename T, bool hasGetArrayData = detail::HasGetArrayData< T >::value > -struct ArrayAssignment{}; +struct ArrayAssignment; /** * \brief Specialization for array-array assignment with containers implementing diff --git a/src/TNL/Containers/Algorithms/ArrayOperations.h b/src/TNL/Containers/Algorithms/ArrayOperations.h index 219465e18c9aa3d65931e36d29e689a62915571c..7977b6b728f1b9827b569d2520ef322d2f49b432 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperations.h +++ b/src/TNL/Containers/Algorithms/ArrayOperations.h @@ -10,7 +10,6 @@ #pragma once -#include <list> #include <TNL/Devices/Host.h> #include <TNL/Devices/Cuda.h> #include <TNL/Devices/MIC.h> @@ -46,9 +45,12 @@ struct ArrayOperations< Devices::Host > const Index size ); template< typename DestinationElement, - typename SourceElement > - static void copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ); + typename Index, + typename SourceIterator > + static void copyFromIterator( DestinationElement* destination, + Index destinationSize, + SourceIterator first, + SourceIterator last ); template< typename Element1, typename Element2, @@ -93,9 +95,12 @@ struct ArrayOperations< Devices::Cuda > const Index size ); template< typename DestinationElement, - typename SourceElement > - static void copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ); + typename Index, + typename SourceIterator > + static void copyFromIterator( DestinationElement* destination, + Index destinationSize, + SourceIterator first, + SourceIterator last ); template< typename Element1, typename Element2, @@ -177,9 +182,12 @@ struct ArrayOperations< Devices::MIC > const Index size ); template< typename DestinationElement, - typename SourceElement > - static void copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ); + typename Index, + typename SourceIterator > + static void copyFromIterator( DestinationElement* destination, + Index destinationSize, + SourceIterator first, + SourceIterator last ); template< typename Element1, typename Element2, diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp index 68615a386c84a761e358a22a7076f1eafbf5ad0f..e916be6aa8cc6959414b9011f2314c0ed2921595 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp +++ b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp @@ -12,6 +12,7 @@ #include <iostream> #include <memory> +#include <stdexcept> #include <TNL/Math.h> #include <TNL/ParallelFor.h> @@ -94,27 +95,29 @@ copy( DestinationElement* destination, } template< typename DestinationElement, - typename SourceElement > + typename Index, + typename SourceIterator > void ArrayOperations< Devices::Cuda >:: -copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ) +copyFromIterator( DestinationElement* destination, + Index destinationSize, + SourceIterator first, + SourceIterator last ) { - const auto size = source.size(); - const std::size_t copy_buffer_size = std::min( Devices::Cuda::TransferBufferSize / (std::size_t) sizeof( DestinationElement ), ( std::size_t ) size ); using BaseType = typename std::remove_cv< DestinationElement >::type; - std::unique_ptr< BaseType[] > copy_buffer{ new BaseType[ copy_buffer_size ] }; - std::size_t copiedElements = 0; - auto it = source.begin(); - while( copiedElements < size ) - { - const auto copySize = std::min( size - copiedElements, copy_buffer_size ); - for( std::size_t i = 0; i < copySize; i++ ) - copy_buffer[ i ] = static_cast< DestinationElement >( * it ++ ); - ArrayOperations< Devices::Cuda, Devices::Host >::copy( &destination[ copiedElements ], ©_buffer[ 0 ], copySize ); - copiedElements += copySize; + std::unique_ptr< BaseType[] > buffer{ new BaseType[ Devices::Cuda::getGPUTransferBufferSize() ] }; + Index copiedElements = 0; + while( copiedElements < destinationSize && first != last ) { + Index i = 0; + while( i < Devices::Cuda::getGPUTransferBufferSize() && first != last ) + buffer[ i++ ] = *first++; + ArrayOperations< Devices::Cuda, Devices::Host >::copy( &destination[ copiedElements ], buffer.get(), i ); + copiedElements += i; } + if( first != last ) + throw std::length_error( "Source iterator is larger than the destination array." ); } + template< typename Element1, typename Element2, typename Index > diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp index a50a10aaf0724368f8e45dc7aa655bec5c737844..4cfe789ecad8307875b25a7e0e61b49dc44a3ca0 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp +++ b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp @@ -11,6 +11,7 @@ #pragma once #include <type_traits> +#include <stdexcept> #include <string.h> #include <TNL/ParallelFor.h> @@ -91,15 +92,20 @@ copy( DestinationElement* destination, } template< typename DestinationElement, - typename SourceElement > + typename Index, + typename SourceIterator > void ArrayOperations< Devices::Host >:: -copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ) +copyFromIterator( DestinationElement* destination, + Index destinationSize, + SourceIterator first, + SourceIterator last ) { - std::size_t i = 0; - for( const SourceElement& e : source ) - destination[ i++ ] = e; + Index i = 0; + while( i < destinationSize && first != last ) + destination[ i++ ] = *first++; + if( first != last ) + throw std::length_error( "Source iterator is larger than the destination array." ); } diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp index 601ce06668dbb71eefd1810dc72f0772740166dc..5bf04dbaf5374cf564932f93b64aabdc5dba4a6a 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp +++ b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp @@ -112,11 +112,14 @@ copy( DestinationElement* destination, } template< typename DestinationElement, - typename SourceElement > + typename Index, + typename SourceIterator > void ArrayOperations< Devices::MIC >:: -copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ) +copyFromIterator( DestinationElement* destination, + Index destinationSize, + SourceIterator first, + SourceIterator last ) { throw Exceptions::NotImplementedError(); } diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 9807128036998f4a72acd148e871dd1a66669e87..76ce6384439c7ecb4f7dcc62a76d183ad4fd7e91 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -132,7 +132,7 @@ Array( const std::list< InValue >& list, : allocator( allocator ) { this->setSize( list.size() ); - Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list ); + Algorithms::ArrayOperations< Device >::copyFromIterator( this->getData(), this->getSize(), list.cbegin(), list.cend() ); } template< typename Value, @@ -604,7 +604,7 @@ Array< Value, Device, Index, Allocator >:: operator=( const std::list< InValue >& list ) { this->setSize( list.size() ); - Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list ); + Algorithms::ArrayOperations< Device >::copyFromIterator( this->getData(), this->getSize(), list.cbegin(), list.cend() ); return *this; }