diff --git a/Documentation/Examples/Algorithms/Segments/.SegmentsExample_General.cpp.swp b/Documentation/Examples/Algorithms/Segments/.SegmentsExample_General.cpp.swp deleted file mode 100644 index f50e0038f2a01cc4ed7c7742797ac5bb2531788d..0000000000000000000000000000000000000000 Binary files a/Documentation/Examples/Algorithms/Segments/.SegmentsExample_General.cpp.swp and /dev/null differ diff --git a/Documentation/Examples/Algorithms/Segments/CMakeLists.txt b/Documentation/Examples/Algorithms/Segments/CMakeLists.txt index c7f05c37f3f6f46e3bdc7d8223e1a512cb1a86a8..7479762c320bf98ac16064ef79b29e814b1f0bfa 100644 --- a/Documentation/Examples/Algorithms/Segments/CMakeLists.txt +++ b/Documentation/Examples/Algorithms/Segments/CMakeLists.txt @@ -1,5 +1,10 @@ set( COMMON_EXAMPLES SegmentsExample_General + SegmentsExample_CSR_constructor_1 + SegmentsExample_CSR_constructor_2 + SegmentsExample_CSR_getSerializationType + SegmentsExample_CSR_getSegmentsType + SegmentsExample_CSR_setSegmentsSizes ) if( BUILD_CUDA ) diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c6e28575220b792d1fdeb6e18a879d0dc705b3a --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cpp @@ -0,0 +1,51 @@ +#include <iostream> +#include <functional> +#include <TNL/Containers/Vector.h> +#include <TNL/Algorithms/Segments/CSR.h> +#include <TNL/Devices/Host.h> +#include <TNL/Devices/Cuda.h> + +template< typename Device > +void SegmentsExample() +{ + using SegmentsType = typename TNL::Algorithms::Segments::CSR< Device, int >; + + /*** + * Create segments with given segments sizes. + */ + TNL::Containers::Vector< int, Device > segmentsSizes{ 1, 2, 3, 4, 5 }; + SegmentsType segments( segmentsSizes ); + std::cout << "Segments sizes are: " << segments << std::endl; + + /*** + * Allocate array for the segments; + */ + TNL::Containers::Array< double, Device > data( segments.getStorageSize(), 0.0 ); + + /*** + * Insert data into particular segments. + */ + auto data_view = data.getView(); + segments.forAllElements( [=] __cuda_callable__ ( int segmentIdx, int localIdx, int globalIdx, bool& compute ) mutable { + if( localIdx <= segmentIdx ) + data_view[ globalIdx ] = segmentIdx; + } ); + + /*** + * Print the data managed by the segments. + */ + auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; }; + printSegments( segments, fetch, std::cout ); +} + +int main( int argc, char* argv[] ) +{ + std::cout << "Example of CSR segments on host: " << std::endl; + SegmentsExample< TNL::Devices::Host >(); + +#ifdef HAVE_CUDA + std::cout << "Example of CSR segments on CUDA GPU: " << std::endl; + SegmentsExample< TNL::Devices::Cuda >(); +#endif + return EXIT_SUCCESS; +} diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cu b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cu new file mode 120000 index 0000000000000000000000000000000000000000..9daf42acefa262936fd0d476cbd4912a93fe63b1 --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cu @@ -0,0 +1 @@ +SegmentsExample_CSR_constructor_1.cpp \ No newline at end of file diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c15f5791ee4aebe74d7a3087d07fc6e265f6afc9 --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp @@ -0,0 +1,50 @@ +#include <iostream> +#include <functional> +#include <TNL/Containers/Vector.h> +#include <TNL/Algorithms/Segments/CSR.h> +#include <TNL/Devices/Host.h> +#include <TNL/Devices/Cuda.h> + +template< typename Device > +void SegmentsExample() +{ + using SegmentsType = typename TNL::Algorithms::Segments::CSR< Device, int >; + + /*** + * Create segments with given segments sizes. + */ + SegmentsType segments{ 1, 2, 3, 4, 5 }; + std::cout << "Segments sizes are: " << segments << std::endl; + + /*** + * Allocate array for the segments; + */ + TNL::Containers::Array< double, Device > data( segments.getStorageSize(), 0.0 ); + + /*** + * Insert data into particular segments. + */ + auto data_view = data.getView(); + segments.forAllElements( [=] __cuda_callable__ ( int segmentIdx, int localIdx, int globalIdx, bool& compute ) mutable { + if( localIdx <= segmentIdx ) + data_view[ globalIdx ] = segmentIdx; + } ); + + /*** + * Print the data managed by the segments. + */ + auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; }; + printSegments( segments, fetch, std::cout ); +} + +int main( int argc, char* argv[] ) +{ + std::cout << "Example of CSR segments on host: " << std::endl; + SegmentsExample< TNL::Devices::Host >(); + +#ifdef HAVE_CUDA + std::cout << "Example of CSR segments on CUDA GPU: " << std::endl; + SegmentsExample< TNL::Devices::Cuda >(); +#endif + return EXIT_SUCCESS; +} diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cu b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cu new file mode 120000 index 0000000000000000000000000000000000000000..9286174a1ee2b0797c99f97a699acb186281caef --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cu @@ -0,0 +1 @@ +SegmentsExample_CSR_constructor_2.cpp \ No newline at end of file diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSegmentsType.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSegmentsType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fea90117304d1465c2da781a8d0ce0202edf427a --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSegmentsType.cpp @@ -0,0 +1,29 @@ +#include <iostream> +#include <functional> +#include <TNL/Algorithms/Segments/CSR.h> +#include <TNL/Devices/Host.h> +#include <TNL/Devices/Cuda.h> + +template< typename Device > +void SegmentsExample() +{ + using SegmentsType = typename TNL::Algorithms::Segments::CSR< Device, int >; + + /*** + * Create segments and print the segments type. + */ + SegmentsType segments; + std::cout << "The segments type is: " << segments.getSegmentsType() << std::endl; +} + +int main( int argc, char* argv[] ) +{ + std::cout << "Example of CSR segments on host: " << std::endl; + SegmentsExample< TNL::Devices::Host >(); + +#ifdef HAVE_CUDA + std::cout << "Example of CSR segments on CUDA GPU: " << std::endl; + SegmentsExample< TNL::Devices::Cuda >(); +#endif + return EXIT_SUCCESS; +} diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSerializationType.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSerializationType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a52a18e5069f0c9d75ea841bcd687520760fc7cc --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSerializationType.cpp @@ -0,0 +1,29 @@ +#include <iostream> +#include <functional> +#include <TNL/Algorithms/Segments/CSR.h> +#include <TNL/Devices/Host.h> +#include <TNL/Devices/Cuda.h> + +template< typename Device > +void SegmentsExample() +{ + using SegmentsType = typename TNL::Algorithms::Segments::CSR< Device, int >; + + /*** + * Create segments and print the serialization type. + */ + SegmentsType segments; + std::cout << "The serialization type is: " << segments.getSerializationType() << std::endl; +} + +int main( int argc, char* argv[] ) +{ + std::cout << "Example of CSR segments on host: " << std::endl; + SegmentsExample< TNL::Devices::Host >(); + +#ifdef HAVE_CUDA + std::cout << "Example of CSR segments on CUDA GPU: " << std::endl; + SegmentsExample< TNL::Devices::Cuda >(); +#endif + return EXIT_SUCCESS; +} diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSerializationType.cu b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSerializationType.cu new file mode 120000 index 0000000000000000000000000000000000000000..31c65453cf012b2a16e40c5010f7c2d899d15a18 --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_getSerializationType.cu @@ -0,0 +1 @@ +SegmentsExample_CSR_getSerializationType.cpp \ No newline at end of file diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_setSegmentsSizes.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_setSegmentsSizes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59a9e1bfad95a33706cd082e7a153c7c1de8284a --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_setSegmentsSizes.cpp @@ -0,0 +1,32 @@ +#include <iostream> +#include <functional> +#include <TNL/Containers/Vector.h> +#include <TNL/Algorithms/Segments/CSR.h> +#include <TNL/Devices/Host.h> +#include <TNL/Devices/Cuda.h> + +template< typename Device > +void SegmentsExample() +{ + using SegmentsType = typename TNL::Algorithms::Segments::CSR< Device, int >; + + /*** + * Create segments with given segments sizes. + */ + TNL::Containers::Vector< int, Device > segmentsSizes{ 1, 2, 3, 4, 5 }; + SegmentsType segments; + segments.setSegmentsSizes( segmentsSizes ); + std::cout << "Segments sizes are: " << segments << std::endl; +} + +int main( int argc, char* argv[] ) +{ + std::cout << "Example of CSR segments on host: " << std::endl; + SegmentsExample< TNL::Devices::Host >(); + +#ifdef HAVE_CUDA + std::cout << "Example of CSR segments on CUDA GPU: " << std::endl; + SegmentsExample< TNL::Devices::Cuda >(); +#endif + return EXIT_SUCCESS; +} diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_setSegmentsSizes.cu b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_setSegmentsSizes.cu new file mode 120000 index 0000000000000000000000000000000000000000..f56df02ad1b0444f3a952d1287de91bbc096b51e --- /dev/null +++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_setSegmentsSizes.cu @@ -0,0 +1 @@ +SegmentsExample_CSR_setSegmentsSizes.cpp \ No newline at end of file diff --git a/src/TNL/Algorithms/Segments/CSR.h b/src/TNL/Algorithms/Segments/CSR.h index 221c02b8a462f1341ce1dc2522802836d5bd7286..5290ac9f4908968c9b2f212bd65262845a8c14d4 100644 --- a/src/TNL/Algorithms/Segments/CSR.h +++ b/src/TNL/Algorithms/Segments/CSR.h @@ -110,7 +110,8 @@ class CSR * The number of segments is given by the size of \e segmentsSizes. Particular elements * of this container define sizes of particular segments. * - * \tparam SizesContainer is a type of container for segments sizes. + * \tparam SizesContainer is a type of container for segments sizes. It can be \ref TNL::Containers::Array or + * \ref TNL::Containers::Vector for example. * \param sizes is an instance of the container with the segments sizes. * * See the following example: @@ -135,11 +136,11 @@ class CSR * * See the following example: * - * \includelineno Algorithms/Segments/SegmentsExample_constructor_2.cpp + * \includelineno Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp * * The result looks as follows: * - * \include SegmentsExample_constructor_1.out + * \include SegmentsExample_CSR_constructor_2.out */ template< typename ListIndex > CSR( const std::initializer_list< ListIndex >& segmentsSizes ); @@ -158,49 +159,118 @@ class CSR */ CSR( const CSR&& segments ); + /** + * \brief Returns string with serialization type. + * + * The string has a form `Algorithms::Segments::CSR< IndexType, [any_device], [any_kernel], [any_allocator] >`. + * + * \return \ref String with the serialization type. + * + * \par Example + * \include Algorithms/Segments/SegmentsExample_CSR_getSerializationType.cpp + * \par Output + * \include SegmentsExample_CSR_getSerializationType.out + */ static String getSerializationType(); + /** + * \brief Returns string with segments type. + * + * The string has a form `CSR< KernelType >`. + * + * \return \ref String with the segments type. + * + * \par Example + * \include Algorithms/Segments/SegmentsExample_CSR_getSegmentsType.cpp + * \par Output + * \include SegmentsExample_CSR_getSegmentsType.out + */ static String getSegmentsType(); /** * \brief Set sizes of particular segments. + * + * \tparam SizesContainer is a container with segments sizes. It can be \ref TNL::Containers::Array or + * \ref TNL::Containers::Vector for example. + * + * \param segmentsSizes is an instance of the container with segments sizes. */ - template< typename SizesHolder > - void setSegmentsSizes( const SizesHolder& sizes ); + template< typename SizesContainer > + void setSegmentsSizes( const SizesContainer& segmentsSizes ); + /** + * \brief Reset the segments to empty states. + * + * It means that there is no segment in the CSR segments. + */ void reset(); + /** + * \brief Getter of a view object. + * + * \return View for this instance of CSR segments which can by used for example in + * lambda functions running in GPU kernels. + */ ViewType getView(); + /** + * \brief Getter of a view object for constants instances. + * + * \return View for this instance of CSR segments which can by used for example in + * lambda functions running in GPU kernels. + */ const ConstViewType getConstView() const; /** - * \brief Number of segments. + * \brief Getter of number of segments. + * + * \return number of segments within this object. */ __cuda_callable__ IndexType getSegmentsCount() const; - /*** - * \brief Returns size of the segment number \r segmentIdx + /** + * \brief Returns size of particular segment. + * + * \return size of the segment number \e segmentIdx. */ __cuda_callable__ IndexType getSegmentSize( const IndexType segmentIdx ) const; /*** * \brief Returns number of elements managed by all segments. + * + * \return number of elements managed by all segments. */ __cuda_callable__ IndexType getSize() const; - /*** - * \brief Returns number of elements that needs to be allocated. + /** + * \brief Returns number of elements that needs to be allocated by a container connected to this segments. + * + * \return size of container connected to this segments. */ __cuda_callable__ IndexType getStorageSize() const; + /** + * \brief Computes the global index of an element managed by the segments. + * + * The global index serves as a refernce on the element in its container. + * + * \param segmentIdx is index of a segment with the element. + * \param localIdx is tha local index of the element within the segment. + * \return global index of the element. + */ __cuda_callable__ IndexType getGlobalIndex( const Index segmentIdx, const Index localIdx ) const; + /** + * \brief Returns segment view (i.e. segment accessor) of segment with given index. + * + * \param segmentIdx is index of the request segment. + * \return segment view of given segment. + */ __cuda_callable__ SegmentViewType getSegmentView( const IndexType segmentIdx ) const; diff --git a/src/TNL/Algorithms/Segments/CSR.hpp b/src/TNL/Algorithms/Segments/CSR.hpp index 10bbc5847e5296e86b02619d8e0295e443a7b864..ce91e7dc5d01e4336a1f2138173c7d16d354b103 100644 --- a/src/TNL/Algorithms/Segments/CSR.hpp +++ b/src/TNL/Algorithms/Segments/CSR.hpp @@ -79,7 +79,7 @@ CSR< Device, Index, Kernel, IndexAllocator >:: getSerializationType() { return "CSR< [any_device], " + - TNL::getSerializationType< IndexType >() + + TNL::getSerializationType< IndexType >() + ", " + TNL::getSerializationType< KernelType >() + " >"; }