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

Added two examples of approximation of the Laplace operator with the lambda matrices.

parent cfd0bb88
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -13,8 +13,18 @@ ADD_CUSTOM_COMMAND( COMMAND LambdaMatrixExample_getNonzeroElementsCount >
                     ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/LambdaMatrixExample_getNonzeroElementsCount.out
                    OUTPUT LambdaMatrixExample_getNonzeroElementsCount.out )


IF( BUILD_CUDA )
   CUDA_ADD_EXECUTABLE( LambdaMatrixExample_Laplace_cuda LambdaMatrixExample_Laplace.cu )
   ADD_CUSTOM_COMMAND( COMMAND LambdaMatrixExample_Laplace_cuda >
                        ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/LambdaMatrixExample_Laplace.out
                     OUTPUT LambdaMatrixExample_Laplace.out )

   CUDA_ADD_EXECUTABLE( LambdaMatrixExample_Laplace_2_cuda LambdaMatrixExample_Laplace_2.cu )
   ADD_CUSTOM_COMMAND( COMMAND LambdaMatrixExample_Laplace_2_cuda >
                       ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/LambdaMatrixExample_Laplace_2.out
                       OUTPUT LambdaMatrixExample_Laplace_2.out )
                  

                     CUDA_ADD_EXECUTABLE( LambdaMatrixExample_rowsReduction_cuda LambdaMatrixExample_rowsReduction.cu )
   ADD_CUSTOM_COMMAND( COMMAND LambdaMatrixExample_rowsReduction_cuda >
                        ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/LambdaMatrixExample_rowsReduction.out
@@ -36,6 +46,16 @@ IF( BUILD_CUDA )
                       OUTPUT LambdaMatrixExample_forAllRows.out )

ELSE()
   ADD_EXECUTABLE( LambdaMatrixExample_Laplace LambdaMatrixExample_Laplace.cpp )
   ADD_CUSTOM_COMMAND( COMMAND LambdaMatrixExample_Laplace >
                       ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/LambdaMatrixExample_Laplace.out
                       OUTPUT LambdaMatrixExample_Laplace.out )

   ADD_EXECUTABLE( LambdaMatrixExample_Laplace_2 LambdaMatrixExample_Laplace_2.cpp )
   ADD_CUSTOM_COMMAND( COMMAND LambdaMatrixExample_Laplace_2 >
                        ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/LambdaMatrixExample_Laplace_2.out
                        OUTPUT LambdaMatrixExample_Laplace_2.out )

   ADD_EXECUTABLE( LambdaMatrixExample_rowsReduction LambdaMatrixExample_rowsReduction.cpp )
   ADD_CUSTOM_COMMAND( COMMAND LambdaMatrixExample_rowsReduction >
                        ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/LambdaMatrixExample_rowsReduction.out
@@ -59,6 +79,8 @@ ENDIF()

ADD_CUSTOM_TARGET( RunLambdaMatricesExamples ALL DEPENDS
   LambdaMatrixExample_Constructor.out
   LambdaMatrixExample_Laplace.out
   LambdaMatrixExample_Laplace_2.out
   LambdaMatrixExample_getCompressedRowLengths.out
   LambdaMatrixExample_getNonzeroElementsCount.out
   LambdaMatrixExample_rowsReduction.out
+75 −0
Original line number Diff line number Diff line
#include <iostream>
#include <TNL/Matrices/LambdaMatrix.h>
#include <TNL/Devices/Host.h>
#include <TNL/Devices/Cuda.h>


template< typename Device >
void laplaceOperatorMatrix()
{
   /***
    * Set  matrix representing approximation of the Laplace operator on regular
    * grid using the finite difference method.
    */
   const int gridSize( 4 );
   const int matrixSize = gridSize * gridSize;
   auto rowLengths = [=] __cuda_callable__ ( const int rows, const int columns, const int rowIdx ) -> int
   {
      const int gridRow = rowIdx / gridSize;                  // coordinates in the numerical grid
      const int gridColumn = rowIdx % gridSize;
      if( gridRow == 0 || gridRow == gridSize - 1 ||          // boundary grid node
          gridColumn == 0 || gridColumn == gridSize - 1 )
          return 1;
      return 5;
   };
   auto matrixElements = [=] __cuda_callable__ ( const int rows, const int columns, const int rowIdx, const int localIdx, int& columnIdx, double& value) {
      const int gridRow = rowIdx / gridSize;                  // coordinates in the numerical grid
      const int gridColumn = rowIdx % gridSize;
      if( gridRow == 0 || gridRow == gridSize - 1 ||          // boundary grid node
          gridColumn == 0 || gridColumn == gridSize - 1 )
         {
            columnIdx = rowIdx;                               // diagonal element ....
            value = 1.0;                                      // ... is set to 1
         }
         else                                                 // interior grid node
         {
            switch( localIdx )                                // set diagonal element to 4
            {                                                 // and the others to -1
               case 0:
                  columnIdx = rowIdx - gridSize;
                  value = -1;
                  break;
               case 1:
                  columnIdx = rowIdx - 1;
                  value = -1;
                  break;
               case 2:
                  columnIdx = rowIdx;
                  value = 4;
                  break;
               case 3:
                  columnIdx = rowIdx + 1;
                  value = -1;
                  break;
               case 4:
                  columnIdx = rowIdx + gridSize;
                  value = -1;
                  break;
            }
         }
   };
   auto matrix = TNL::Matrices::LambdaMatrixFactory< double, Device, int >::create(
      matrixSize, matrixSize, matrixElements, rowLengths );
   std::cout << "Laplace operator matrix: " << std::endl << matrix << std::endl;
}

int main( int argc, char* argv[] )
{
   std::cout << "Creating Laplace operator matrix on CPU ... " << std::endl;
   laplaceOperatorMatrix< TNL::Devices::Host >();

#ifdef HAVE_CUDA
   std::cout << "Creating Laplace operator matrix on CUDA GPU ... " << std::endl;
   laplaceOperatorMatrix< TNL::Devices::Cuda >();
#endif
}
+1 −0
Original line number Diff line number Diff line
LambdaMatrixExample_Laplace.cpp
 No newline at end of file
+63 −0
Original line number Diff line number Diff line
#include <iostream>
#include <TNL/Matrices/LambdaMatrix.h>
#include <TNL/Devices/Host.h>
#include <TNL/Devices/Cuda.h>


template< typename Device >
void laplaceOperatorMatrix()
{
   /***
    * Set  matrix representing approximation of the Laplace operator on regular
    * grid using the finite difference method.
    */
   const int gridSize( 4 );
   const int matrixSize = gridSize * gridSize;
   TNL::Containers::Vector< int, Device > columnOffsets{ 0, -1, 0, 1, 0 };  // helper vector for getting matrix elements column indexes
   columnOffsets.setElement( 0, -gridSize );
   columnOffsets.setElement( 4, gridSize );
   auto columnOffsetsView = columnOffsets.getView();
   TNL::Containers::Vector< double, Device > values{ 1, 1, -4, 1, 1 };      // helper vector for getting matrix elements values
   auto valuesView = values.getView();

   auto rowLengths = [=] __cuda_callable__ ( const int rows, const int columns, const int rowIdx ) -> int
   {
      const int gridRow = rowIdx / gridSize;                  // coordinates in the numerical grid
      const int gridColumn = rowIdx % gridSize;

      if( gridRow == 0 || gridRow == gridSize - 1 ||          // boundary grid node
          gridColumn == 0 || gridColumn == gridSize - 1 )
          return 1;
      return 5;
   };

   auto matrixElements = [=] __cuda_callable__ ( const int rows, const int columns, const int rowIdx, const int localIdx, int& columnIdx, double& value) {
      const int gridRow = rowIdx / gridSize;                  // coordinates in the numerical grid
      const int gridColumn = rowIdx % gridSize;
      if( gridRow == 0 || gridRow == gridSize - 1 ||          // boundary grid node
          gridColumn == 0 || gridColumn == gridSize - 1 )
         {
            columnIdx = rowIdx;                               // diagonal element ....
            value = 1.0;                                      // ... is set to 1
         }
         else                                                 // interior grid node
         {
            columnIdx = rowIdx + columnOffsetsView[ localIdx ];
            value = valuesView[ localIdx ];
         }
   };
   auto matrix = TNL::Matrices::LambdaMatrixFactory< double, Device, int >::create(
      matrixSize, matrixSize, matrixElements, rowLengths );
   std::cout << "Laplace operator matrix: " << std::endl << matrix << std::endl;
}

int main( int argc, char* argv[] )
{
   std::cout << "Creating Laplace operator matrix on CPU ... " << std::endl;
   laplaceOperatorMatrix< TNL::Devices::Host >();

#ifdef HAVE_CUDA
   std::cout << "Creating Laplace operator matrix on CUDA GPU ... " << std::endl;
   laplaceOperatorMatrix< TNL::Devices::Cuda >();
#endif
}
+1 −0
Original line number Diff line number Diff line
LambdaMatrixExample_Laplace_2.cpp
 No newline at end of file
Loading