Commit a1faf2bb authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Writting vectors tutorial.

parent 16d027ec
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
IF( BUILD_CUDA )
   #ADD_EXECUTABLE( Expressions Expressions.cpp )
   CUDA_ADD_EXECUTABLE( Expressions Expressions.cu )
   ADD_CUSTOM_COMMAND( COMMAND Expressions > Expressions.out OUTPUT Expressions.out )
   #ADD_EXECUTABLE( Reduction Reduction.cpp )
   CUDA_ADD_EXECUTABLE( Reduction Reduction.cu )
   ADD_CUSTOM_COMMAND( COMMAND Reduction > Reduction.out OUTPUT Reduction.out )
ENDIF()

IF( BUILD_CUDA )
ADD_CUSTOM_TARGET( TutorialsVectors-cuda ALL DEPENDS
   Expressions.out )
   Expressions.out
   Reduction.out )
ENDIF()

# set input and output files
+12 −10
Original line number Diff line number Diff line
@@ -8,24 +8,26 @@ using namespace TNL::Containers;
template< typename Device >
void expressions()
{
   using VectorType = Vector< float, Device >;
   using ViewType = VectorView< float, Device >;
   using RealType = float;
   using VectorType = Vector< RealType, Device >;
   using ViewType = VectorView< RealType, Device >;

   /****
    * Create vectors
    */
   const int size = 6;
   const int size = 11;
   VectorType a_v( size ), b_v( size ), c_v( size );
   ViewType a = a_v.getView();
   ViewType b = b_v.getView();
   ViewType c = c_v.getView();
   a.evaluate( [] __cuda_callable__ ( int i )->float { return i - 3;} );
   b = abs( a );
   c = sign( b );

   a.evaluate( [] __cuda_callable__ ( int i )->RealType { return 3.14 * ( i - 5.0 ) / 5.0; } );
   b = a * a;
   c = 3 * a + sign( a ) * sin( a );
   std::cout << "a = " << a << std::endl;
   std::cout << "sin( a ) = " << sin( a ) << std::endl;
   std::cout << "abs( sin( a ) ) = " << abs( sin ( a ) ) << std::endl;
   std::cout << "b = " <<  b << std::endl;
   std::cout << "c = " <<  c << std::endl;
   std::cout << "a + 3 * b + c * min( c, 0 ) = " <<  a + 3 * b + c * min( c, 0 ) << std::endl;
}

int main( int argc, char* argv[] )
+59 −0
Original line number Diff line number Diff line
#include <iostream>
#include <TNL/Containers/Vector.h>
#include <TNL/Containers/VectorView.h>

using namespace TNL;
using namespace TNL::Containers;

template< typename Device >
void expressions()
{
   using RealType = float;
   using VectorType = Vector< RealType, Device >;
   using ViewType = VectorView< RealType, Device >;
   
   /****
    * Create vectors
    */
   const int size = 11;
   VectorType a_v( size ), b_v( size ), c_v( size );
   ViewType a = a_v.getView();
   ViewType b = b_v.getView();
   ViewType c = c_v.getView();
   a.evaluate( [] __cuda_callable__ ( int i )->RealType { return i; } );
   b.evaluate( [] __cuda_callable__ ( int i )->RealType { return i - 5.0; } );
   c = -5;

   int arg;
   std::cout << "a = " << a << std::endl;
   std::cout << "b = " << b << std::endl;
   std::cout << "c = " << c << std::endl;
   std::cout << "min( a )  = " << argMin( a, arg ) << " at " << arg << std::endl;
   std::cout << "max( a )  = " << argMax( a, arg ) << " at " << arg << std::endl;
   std::cout << "min( b )  = " << argMin( b, arg ) << " at " << arg << std::endl;
   std::cout << "max( b )  = " << argMax( b, arg ) << " at " << arg << std::endl;
   std::cout << "min( abs( b ) ) = " << min( abs( b ) ) << std::endl;
   std::cout << "sum( b ) = " << sum( b ) << std::endl;
   std::cout << "sum( abs( b ) ) = " << sum( abs( b ) ) << std::endl;
   std::cout << "Scalar product: ( a, b ) =  " << ( a, b ) << std::endl;
   std::cout << "Scalar product: ( a + 3, abs( b ) / 2 ) =  " << ( a + 3, abs( b ) / 2 ) << std::endl;
   if( abs( a  + b ) <=  abs( a ) + abs( b ) )
      std::cout << "abs( a  + b ) <=  abs( a ) + abs( b ) holds" << std::endl;
}

int main( int argc, char* argv[] )
{
   /****
    * Perform test on CPU
    */
   std::cout << "Expressions on CPU ..." << std::endl;
   expressions< Devices::Host >();

   /****
    * Perform test on GPU
    */
   std::cout << "Expressions on GPU ..." << std::endl;
   expressions< Devices::Cuda >();
}

+1 −0
Original line number Diff line number Diff line
Reduction.cpp
 No newline at end of file
+15 −3
Original line number Diff line number Diff line
@@ -2,10 +2,12 @@

## Introduction

This tutorial introduces vectors in TNL. `Vector`, in addition to `Array`, offers also basic operations from linear algebra. Methods implemented in arrays and vectors are particularly usefull for GPU programming. From this point of view, the reader will learn how to easily allocate memory on GPU, transfer data between GPU and CPU but also, how to initialise data allocated on GPU and perform parallel reduction and vector operations without writting low-level CUDA kernels. In addition, the resulting code is hardware platform independent, so it can be ran on CPU without any changes.
This tutorial introduces vectors in TNL. `Vector`, in addition to `Array`, offers also basic operations from linear algebra. The reader will mainly learn how to do Blas level 1 operations in TNL. Thanks to the design of TNL, it is easier to implement, hardware architecture transparent and in some cases even faster then [Blas](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) or [cuBlas](https://developer.nvidia.com/cublas) implementation.

# Table of Contents
1. [Vectors](#vectors)
   1. [Horizontal operations] (#horizontal_operations)
   2. [Vertical operations] (#vertical_operations)
2. [Static vectors](#static_vectors)

## Vectors <a name="vectors"></a>
@@ -18,9 +20,9 @@ This tutorial introduces vectors in TNL. `Vector`, in addition to `Array`, offer

`Vector`, unlike `Array`, requires that the `Real` type is numeric or a type for which basic algebraic operations are defined. What kind of algebraic operations is required depends on what vector operations the user will call. `Vector` is derived from `Array` so it inherits all its methods. In the same way the `Array` has its counterpart `ArraView`, `Vector` has `VectorView` which is derived from `ArrayView`. We refer to to [Arrays tutorial](../../Arrays/html/index.html) for more details.

### Vector expressions
### Horizontal operations <a name="horizontal_operations"></a>

Vector expressions in TNL are processed by the [Expression Templates](https://en.wikipedia.org/wiki/Expression_templates). It makes algebraic operations with vectors easy to do and very efficient at the same time. In some cases, one get even more efficient code compared to [Blas](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) and [cuBlas](https://developer.nvidia.com/cublas). See the following example to learn how simple it is.
By *horizontal* operations we mean vector expressions where we have one or more vectors as an input and a vector as an output. In TNL, this kind of operations is performed by the [Expression Templates](https://en.wikipedia.org/wiki/Expression_templates). It makes algebraic operations with vectors easy to do and very efficient at the same time. In some cases, one get even more efficient code compared to [Blas](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) and [cuBlas](https://developer.nvidia.com/cublas). See the following example.

\include Expressions.cpp

@@ -28,5 +30,15 @@ Output is:

\include Expressions.out

Vector expressions work only with `VectorView` not with `Vector`. The expression is evaluated on the same device where the vectors are allocated, this is done automatically. One cannot, however, mix vectors from different devices in one expression. Vector expression may contain any common function like `min`, `max`, `abs`, `sin`, `cos`, `exp`, `log`, `sqrt`, `pow` etc. 

### Vertical operations <a name="vertical_operations"></a>
By *vertical operations* we mean (parallel) reduction based operations where we have one or more vectors (or vector expressions) as an input and one value as an output. For example computing scalar product, vector norm or finding minimum or maximum of vector elements is based on reduction. See the following example.

\include Reduction.cpp

Output is:

\include Reduction.out

## Static vectors <a name="static_vectors"></a>