|
CP2K 2.4 (Revision 12889)
|
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
1.7.3