CP2K 2.4 (Revision 12889)

dbcsr_example_2.f90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------------!
00002 !   CP2K: A general program to perform molecular dynamics simulations         !
00003 !   Copyright (C) 2000 - 2013  CP2K developers group                          !
00004 !-----------------------------------------------------------------------------!
00005 
00006 ! *****************************************************************************
00016 PROGRAM dbcsr_example_2
00017   USE array_types,                     ONLY: array_data,&
00018                                              array_i1d_obj,&
00019                                              array_new,&
00020                                              array_nullify,&
00021                                              array_release
00022   USE dbcsr_block_access
00023   USE dbcsr_data_methods
00024   USE dbcsr_dist_operations,           ONLY: dbcsr_get_stored_coordinates
00025   USE dbcsr_error_handling,            ONLY: dbcsr_error_type
00026   USE dbcsr_io,                        ONLY: dbcsr_print
00027   USE dbcsr_kinds,                     ONLY: real_8
00028   USE dbcsr_message_passing,           ONLY: mp_cart_create,&
00029                                              mp_cart_rank,&
00030                                              mp_environ,&
00031                                              mp_world_finalize,&
00032                                              mp_world_init
00033   USE dbcsr_methods
00034   USE dbcsr_operations
00035   USE dbcsr_ptr_util
00036   USE dbcsr_transformations
00037   USE dbcsr_types
00038   USE dbcsr_util
00039   USE dbcsr_work_operations
00040 
00041   !$ USE OMP_LIB
00042 
00043   IMPLICIT NONE
00044 
00045   TYPE(dbcsr_obj)                          :: matrix_a
00046   TYPE(dbcsr_error_type)                   :: error
00047 
00048   TYPE(array_i1d_obj)                      :: col_blk_sizes, row_blk_sizes
00049   INTEGER, DIMENSION(:), POINTER           :: rbs, cbs
00050   INTEGER                                  :: mp_comm, group, numnodes, mynode, 
00051        prow, pcol, nblkrows_total, nblkcols_total, node_holds_blk, max_nze, nze, 
00052        row, col, row_s, col_s
00053   INTEGER, DIMENSION(2)                    :: npdims, myploc, coord
00054   INTEGER, DIMENSION(:,:), POINTER         :: pgrid
00055   TYPE(array_i1d_obj)                      :: col_dist, row_dist
00056   TYPE(dbcsr_distribution_obj)             :: dist
00057   TYPE(dbcsr_mp_obj)                       :: mp_env
00058   REAL(real_8), DIMENSION(:), ALLOCATABLE  :: values
00059   LOGICAL                                  :: tr
00060 
00061   !***************************************************************************************
00062 
00063   CALL mp_world_init(mp_comm)
00064   npdims(:) = 0
00065   CALL mp_cart_create (mp_comm, 2, npdims, myploc, group)
00066   CALL mp_environ (numnodes, mynode, group)
00067   ALLOCATE (pgrid(0:npdims(1)-1, 0:npdims(2)-1))
00068   DO prow = 0, npdims(1)-1
00069      DO pcol = 0, npdims(2)-1
00070         coord = (/ prow, pcol /)
00071         CALL mp_cart_rank (group, coord, pgrid(prow, pcol))
00072      ENDDO
00073   ENDDO
00074   CALL dbcsr_mp_new (mp_env, pgrid, group, mynode, numnodes,&
00075        myprow=myploc(1), mypcol=myploc(2))
00076   WRITE(*,*) 'mynode ',mynode,' numnodes',numnodes
00077   DEALLOCATE(pgrid)
00078 
00079   !***************************************************************************************
00080 
00081   !
00082   ! the matrix will contain nblkrows_total row blocks and nblkcols_total column blocks
00083   nblkrows_total = 4
00084   nblkcols_total = 4
00085 
00086   !
00087   ! set the block size for each row and column
00088   ALLOCATE (rbs(nblkrows_total), cbs(nblkcols_total))
00089   rbs(:) = 2
00090   cbs(:) = 2
00091 
00092   !
00093   ! set up the block size arrays
00094   CALL array_nullify (row_blk_sizes)
00095   CALL array_nullify (col_blk_sizes)
00096   CALL array_new (row_blk_sizes, rbs, gift=.TRUE.)
00097   CALL array_new (col_blk_sizes, cbs, gift=.TRUE.)
00098 
00099   !
00100   ! set the row and column distributions (here the distribution is set randomly)
00101   CALL random_dist (row_dist, nblkrows_total, npdims(1))
00102   CALL random_dist (col_dist, nblkcols_total, npdims(2))
00103 
00104   !
00105   ! set the dbcsr distribution object
00106   CALL dbcsr_distribution_new (dist, mp_env, row_dist, col_dist)
00107 
00108   !
00109   ! initialize the dbcsr matrix
00110   CALL dbcsr_init (matrix_a)
00111 
00112   !
00113   ! create the dbcsr matrix, i.e. a double precision non symmetric matrix
00114   ! with nblkrows_total x nblkcols_total blocks and
00115   ! sizes "sum(row_blk_sizes)" x "sum(col_blk_sizes)", distributed as
00116   ! specified by the dist object
00117   CALL dbcsr_create (matrix=matrix_a,&
00118        name="this is my matrix a",&
00119        dist=dist, &
00120        matrix_type=dbcsr_type_no_symmetry,&
00121        row_blk_size=row_blk_sizes,&
00122        col_blk_size=col_blk_sizes,&
00123        data_type=dbcsr_type_real_8,&
00124        error=error)
00125 
00126   !
00127   ! get the block sizes from the matrix
00128   rbs => array_data (dbcsr_row_block_sizes (matrix_a))
00129   cbs => array_data (dbcsr_col_block_sizes (matrix_a))
00130 
00131   !
00132   ! get the node id from the matrix
00133   mynode = dbcsr_mp_mynode (dbcsr_distribution_mp (dbcsr_distribution (matrix_a)))
00134 
00135   !
00136   ! get the maximum block size of the matrix
00137   max_nze = dbcsr_max_row_size (matrix_a) * dbcsr_max_col_size (matrix_a)
00138 
00139   !
00140   ! allocate a 1d buffer that is needed to put a block
00141   ! into the matrix (2d buffer can also be used)
00142   ALLOCATE (values (max_nze))
00143 
00144   !
00145   ! loop over the blocks, build a tridiagonal matrix
00146   DO row = 1, dbcsr_nblkrows_total (matrix_a)
00147      DO col = MAX(row-1,1),MIN(row+1,dbcsr_nblkcols_total (matrix_a))
00148         !
00149         ! get the node id that holds this (row, col) block
00150         tr = .FALSE.
00151         row_s=row ; col_s=col
00152         CALL dbcsr_get_stored_coordinates (matrix_a, row_s, col_s, tr, node_holds_blk)
00153         !
00154         ! put the block on the right node
00155         IF(node_holds_blk .EQ. mynode) THEN
00156            !
00157            ! get the size of the block
00158            nze = rbs(row_s) * cbs(col_s)
00159            !
00160            ! fill the matrix with the random block
00161            CALL RANDOM_NUMBER (values (1:nze))
00162            CALL dbcsr_put_block (matrix_a, row_s, col_s, values(1:nze))
00163         ENDIF
00164      ENDDO
00165   ENDDO
00166   DEALLOCATE (values)
00167 
00168   !
00169   ! finalize the dbcsr matrix
00170   CALL dbcsr_finalize(matrix_a, error=error)
00171 
00172   !
00173   ! print the matrix
00174   CALL dbcsr_print(matrix_a, error=error)
00175 
00176   !
00177   ! release the matrix
00178   CALL dbcsr_release (matrix_a)
00179 
00180   CALL dbcsr_distribution_release (dist)
00181   CALL dbcsr_mp_release (mp_env)
00182   CALL array_release (row_dist)
00183   CALL array_release (col_dist)
00184   CALL array_release (row_blk_sizes)
00185   CALL array_release (col_blk_sizes)
00186 
00187   !***************************************************************************************
00188 
00189   CALL mp_world_finalize()
00190 
00191   !***************************************************************************************
00192 
00193 CONTAINS
00194 
00195   SUBROUTINE random_dist (dist_array, dist_size, nbins)
00196     TYPE(array_i1d_obj), INTENT(out)         :: dist_array
00197     INTEGER, INTENT(in)                      :: dist_size, nbins
00198 
00199     INTEGER                                  :: i
00200     INTEGER, ALLOCATABLE, DIMENSION(:)       :: grid_dist
00201 
00202     ALLOCATE (grid_dist(dist_size))
00203     CALL array_nullify (dist_array)
00204 
00205     FORALL (i = 1 : dist_size)
00206        grid_dist(i) = MODULO (nbins-i, nbins)
00207     END FORALL
00208 
00209     CALL array_new (dist_array, grid_dist, lb=1)
00210     DEALLOCATE (grid_dist)
00211 
00212   END SUBROUTINE random_dist
00213 
00214 END PROGRAM dbcsr_example_2