Changeset 4628 for palm/trunk/SOURCE/restart_data_mpi_io_mod.f90
- Timestamp:
- Jul 29, 2020 7:23:03 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/restart_data_mpi_io_mod.f90
r4622 r4628 25 25 ! ----------------- 26 26 ! $Id$ 27 ! extensions required for MPI-I/O of particle data to restart files 28 ! 29 ! 4622 2020-07-23 09:02:23Z raasch 27 30 ! unused variables removed 28 31 ! … … 65 68 ! 66 69 ! 4495 2020-04-13 20:11:20Z raasch 67 ! Initial version (K. Ketelsen), adjusted to PALM formatting standards (s. Raasch) 68 ! 70 ! Initial version (K. Ketelsen), adjusted to PALM formatting standards (S. Raasch) 69 71 ! 70 72 ! … … 127 129 USE kinds 128 130 131 USE particle_attributes, & 132 ONLY: grid_particles, & 133 particles, & 134 particle_type, & 135 prt_count, & 136 zero_particle 137 129 138 USE pegrid, & 130 139 ONLY: comm1dx, & … … 161 170 162 171 INTEGER(iwp) :: comm_io !< Communicator for MPI-IO 163 INTEGER(iwp) :: fh 172 INTEGER(iwp) :: fh = -1 !< MPI-IO file handle 164 173 #if defined( __parallel ) 165 174 INTEGER(iwp) :: fhs = -1 !< MPI-IO file handle to open file with comm2d always … … 170 179 INTEGER(iwp) :: ft_2d !< MPI filetype 2D array REAL with outer boundaries 171 180 INTEGER(iwp) :: ft_3d !< MPI filetype 3D array REAL with outer boundaries 181 INTEGER(iwp) :: ft_3di4 = -1 !< MPI filetype 3D array INTEGER*4 182 INTEGER(iwp) :: ft_3di8 = -1 !< MPI filetype 3D array INTEGER*8 172 183 INTEGER(iwp) :: ft_3dsoil !< MPI filetype for 3d-soil array 173 184 #endif … … 181 192 INTEGER(iwp) :: win_2di !< 182 193 INTEGER(iwp) :: win_2dr !< 194 INTEGER(iwp) :: win_3di4 = -1 !< 195 INTEGER(iwp) :: win_3di8 = -1 !< 183 196 INTEGER(iwp) :: win_3dr !< 184 197 INTEGER(iwp) :: win_3ds !< … … 190 203 INTEGER(KIND=rd_offset_kind) :: header_position !< 191 204 192 INTEGER(iwp), DIMENSION(:,:), POINTER, CONTIGUOUS :: array_2di!<205 INTEGER(iwp), DIMENSION(:,:), POINTER, CONTIGUOUS :: array_2di !< 193 206 194 207 INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE :: m_end_index !< … … 196 209 INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE :: m_start_index !< 197 210 211 INTEGER(isp), DIMENSION(:,:,:), POINTER, CONTIGUOUS :: array_3di4 !< 212 INTEGER(idp), DIMENSION(:,:,:), POINTER, CONTIGUOUS :: array_3di8 !< 198 213 199 214 LOGICAL :: all_pes_write !< all PEs have data to write … … 279 294 TYPE(domain_decomposition_grid_features) :: prerun_grid !< grid variables for the prerun 280 295 296 ! 297 !-- MPI_INTEGER8 is not standard MPI, but is supported on most MPI distibutions 298 !-- If not suppported, a workaround could be enabled with the following preprocessor directive 299 !#if defined( __NO_INTEGER8) 300 ! INTEGER :: MPI_INTEGER8 !< MPI data type INTEGER8 301 !#endif 281 302 282 303 SAVE … … 296 317 END INTERFACE rd_mpi_io_close 297 318 319 INTERFACE rd_mpi_io_check_open 320 MODULE PROCEDURE rd_mpi_io_check_open 321 END INTERFACE rd_mpi_io_check_open 322 298 323 INTERFACE rd_mpi_io_open 299 324 MODULE PROCEDURE rd_mpi_io_open … … 304 329 MODULE PROCEDURE rrd_mpi_io_int 305 330 MODULE PROCEDURE rrd_mpi_io_int_2d 331 MODULE PROCEDURE rrd_mpi_io_int4_3d 332 MODULE PROCEDURE rrd_mpi_io_int8_3d 306 333 MODULE PROCEDURE rrd_mpi_io_logical 307 334 MODULE PROCEDURE rrd_mpi_io_real … … 324 351 END INTERFACE rrd_mpi_io_surface 325 352 353 INTERFACE rrd_mpi_io_particles 354 MODULE PROCEDURE rrd_mpi_io_particles 355 END INTERFACE rrd_mpi_io_particles 356 357 INTERFACE rd_mpi_io_particle_filetypes 358 MODULE PROCEDURE rd_mpi_io_particle_filetypes 359 END INTERFACE rd_mpi_io_particle_filetypes 360 326 361 INTERFACE rd_mpi_io_surface_filetypes 327 362 MODULE PROCEDURE rd_mpi_io_surface_filetypes … … 332 367 MODULE PROCEDURE wrd_mpi_io_int 333 368 MODULE PROCEDURE wrd_mpi_io_int_2d 369 MODULE PROCEDURE wrd_mpi_io_int4_3d 370 MODULE PROCEDURE wrd_mpi_io_int8_3d 334 371 MODULE PROCEDURE wrd_mpi_io_logical 335 372 MODULE PROCEDURE wrd_mpi_io_real … … 347 384 END INTERFACE wrd_mpi_io_global_array 348 385 386 INTERFACE wrd_mpi_io_particles 387 MODULE PROCEDURE wrd_mpi_io_particles 388 END INTERFACE wrd_mpi_io_particles 389 349 390 INTERFACE wrd_mpi_io_surface 350 391 MODULE PROCEDURE wrd_mpi_io_surface … … 353 394 354 395 PUBLIC rd_mpi_io_check_array, & 396 rd_mpi_io_check_open, & 355 397 rd_mpi_io_close, & 356 398 rd_mpi_io_open, & 399 rd_mpi_io_particle_filetypes, & 400 rd_mpi_io_surface_filetypes, & 357 401 rrd_mpi_io, & 358 402 rrd_mpi_io_global_array, & 403 rrd_mpi_io_particles, & 359 404 rrd_mpi_io_surface, & 360 rd_mpi_io_surface_filetypes, &361 405 wrd_mpi_io, & 362 406 wrd_mpi_io_global_array, & 407 wrd_mpi_io_particles, & 363 408 wrd_mpi_io_surface 364 409 … … 394 439 TYPE(C_PTR) :: buf_ptr !< 395 440 #endif 396 397 ! write(9,*) 'Here is rd_mpi_io_open',nx,nx_on_file,ny,ny_on_file,TRIM(action) !kk may become Debug Output398 441 399 442 offset = 0 … … 1415 1458 ! Description: 1416 1459 ! ------------ 1460 !> Read 3d-INTEGER*4 array with MPI-IO 1461 !--------------------------------------------------------------------------------------------------! 1462 SUBROUTINE rrd_mpi_io_int4_3d( name, data ) 1463 1464 IMPLICIT NONE 1465 1466 CHARACTER(LEN=*), INTENT(IN) :: name !< 1467 1468 INTEGER(iwp) :: i !< 1469 1470 #if defined( __parallel ) 1471 INTEGER, DIMENSION(rd_status_size) :: status !< 1472 #endif 1473 1474 LOGICAL :: found !< 1475 1476 INTEGER(isp), INTENT(INOUT), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: data !< 1477 1478 1479 found = .FALSE. 1480 data = -1.0 1481 1482 DO i = 1, tgh%nr_arrays 1483 IF ( TRIM(array_names(i)) == TRIM( name ) ) THEN 1484 array_position = array_offset(i) 1485 found = .TRUE. 1486 EXIT 1487 ENDIF 1488 ENDDO 1489 1490 IF ( found ) THEN 1491 1492 #if defined( __parallel ) 1493 CALL sm_io%sm_node_barrier() ! Has no effect if I/O on limited # of cores is inactive 1494 IF( sm_io%iam_io_pe ) THEN 1495 CALL MPI_FILE_SET_VIEW( fh, array_position, MPI_INTEGER, ft_3di4, 'native', & 1496 MPI_INFO_NULL, ierr ) 1497 CALL MPI_FILE_READ_ALL( fh, array_3di4, SIZE( array_3di4 ), MPI_INTEGER, status, ierr ) 1498 ENDIF 1499 CALL sm_io%sm_node_barrier() 1500 #else 1501 CALL posix_lseek( fh, array_position ) 1502 CALL posix_read(fh, array_3di4, SIZE( array_3di4 ) ) 1503 #endif 1504 IF ( include_total_domain_boundaries ) THEN 1505 DO i = iog%nxl, iog%nxr 1506 data(:,iog%nys-nbgp:iog%nyn-nbgp,i-nbgp) = array_3di4(:,i,iog%nys:iog%nyn) 1507 ENDDO 1508 ELSE 1509 DO i = nxl, nxr 1510 data(:,nys:nyn,i) = array_3di4(:,i,nys:nyn) 1511 ENDDO 1512 ENDIF 1513 1514 ELSE 1515 1516 message_string = '3d-INTEGER*4 array "' // TRIM( name ) // '" not found in restart file' 1517 CALL message( 'rrd_mpi_io_int4_3d', 'PA0722', 3, 2, 0, 6, 0 ) 1518 1519 ENDIF 1520 1521 1522 END SUBROUTINE rrd_mpi_io_int4_3d 1523 1524 1525 1526 !--------------------------------------------------------------------------------------------------! 1527 ! Description: 1528 ! ------------ 1529 !> Read 3d-INTEGER*8 array with MPI-IO 1530 !--------------------------------------------------------------------------------------------------! 1531 SUBROUTINE rrd_mpi_io_int8_3d( name, data ) 1532 1533 IMPLICIT NONE 1534 1535 CHARACTER(LEN=*), INTENT(IN) :: name !< 1536 1537 INTEGER(iwp) :: i !< 1538 1539 #if defined( __parallel ) 1540 INTEGER, DIMENSION(rd_status_size) :: status !< 1541 #endif 1542 1543 LOGICAL :: found !< 1544 1545 INTEGER(idp), INTENT(INOUT), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: data !< 1546 1547 1548 found = .FALSE. 1549 data = -1.0 1550 1551 DO i = 1, tgh%nr_arrays 1552 IF ( TRIM(array_names(i)) == TRIM( name ) ) THEN 1553 array_position = array_offset(i) 1554 found = .TRUE. 1555 EXIT 1556 ENDIF 1557 ENDDO 1558 1559 IF ( found ) THEN 1560 1561 #if defined( __parallel ) 1562 CALL sm_io%sm_node_barrier() ! Has no effect if I/O on limited # of cores is inactive 1563 IF( sm_io%iam_io_pe ) THEN 1564 CALL MPI_FILE_SET_VIEW( fh, array_position, MPI_INTEGER8, ft_3di8, 'native', MPI_INFO_NULL, & 1565 ierr ) 1566 CALL MPI_FILE_READ_ALL( fh, array_3di8, SIZE( array_3di8 ), MPI_INTEGER8, status, ierr ) 1567 ENDIF 1568 CALL sm_io%sm_node_barrier() 1569 #else 1570 CALL posix_lseek( fh, array_position ) 1571 CALL posix_read(fh, array_3di8, SIZE( array_3di8 ) ) 1572 #endif 1573 IF ( include_total_domain_boundaries ) THEN 1574 DO i = iog%nxl, iog%nxr 1575 data(:,iog%nys-nbgp:iog%nyn-nbgp,i-nbgp) = array_3di8(:,i,iog%nys:iog%nyn) 1576 ENDDO 1577 ELSE 1578 DO i = nxl, nxr 1579 data(:,nys:nyn,i) = array_3di8(:,i,nys:nyn) 1580 ENDDO 1581 ENDIF 1582 1583 ELSE 1584 1585 message_string = '3d-INTEGER*8 array "' // TRIM( name ) // '" not found in restart file' 1586 CALL message( 'rrd_mpi_io_int8_3d', 'PA0722', 3, 2, 0, 6, 0 ) 1587 1588 ENDIF 1589 1590 1591 END SUBROUTINE rrd_mpi_io_int8_3d 1592 1593 1594 1595 !--------------------------------------------------------------------------------------------------! 1596 ! Description: 1597 ! ------------ 1417 1598 !> Read 2d-REAL array with MPI-IO 1418 1599 !--------------------------------------------------------------------------------------------------! … … 1949 2130 ! Description: 1950 2131 ! ------------ 2132 !> Write 3d-INTEGER*4 array with MPI-IO 2133 !--------------------------------------------------------------------------------------------------! 2134 SUBROUTINE wrd_mpi_io_int4_3d( name, data ) 2135 2136 IMPLICIT NONE 2137 2138 CHARACTER(LEN=*), INTENT(IN) :: name !< 2139 2140 INTEGER(iwp) :: i !< 2141 #if defined( __parallel ) 2142 INTEGER, DIMENSION(rd_status_size) :: status !< 2143 #endif 2144 INTEGER(isp), INTENT(IN), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: data !< 2145 2146 2147 IF ( header_array_index == max_nr_arrays ) THEN 2148 STOP '+++ maximum number of 2d/3d-array entries in restart file header exceeded' 2149 ENDIF 2150 2151 array_names(header_array_index) = name 2152 array_offset(header_array_index) = array_position 2153 header_array_index = header_array_index + 1 2154 2155 IF ( include_total_domain_boundaries ) THEN 2156 ! 2157 !-- Prepare output of 3d-REAL-array with ghost layers. In the virtual PE grid, the first 2158 !-- dimension is PEs along x, and the second along y. For MPI-IO it is recommended to have the 2159 !-- index order of the array in the same way, i.e. the first dimension should be along x and the 2160 !-- second along y. For this reason, the original PALM data need to be swaped. 2161 DO i = iog%nxl, iog%nxr 2162 array_3di4(:,i,iog%nys:iog%nyn) = data(:,iog%nys-nbgp:iog%nyn-nbgp,i-nbgp) 2163 ENDDO 2164 2165 ELSE 2166 ! 2167 !-- Prepare output of 3d-REAL-array without ghost layers 2168 DO i = nxl, nxr 2169 array_3di4(:,i,iog%nys:iog%nyn) = data(:,nys:nyn,i) 2170 ENDDO 2171 2172 ENDIF 2173 #if defined( __parallel ) 2174 CALL sm_io%sm_node_barrier() ! Has no effect if I/O on limited number of cores is inactive 2175 IF ( sm_io%iam_io_pe ) THEN 2176 CALL MPI_FILE_SET_VIEW( fh, array_position, MPI_INTEGER, ft_3di4, 'native', MPI_INFO_NULL, ierr ) 2177 CALL MPI_FILE_WRITE_ALL( fh, array_3di4, SIZE( array_3di4 ), MPI_INTEGER, status, ierr ) 2178 ENDIF 2179 CALL sm_io%sm_node_barrier() 2180 #else 2181 CALL posix_lseek( fh, array_position ) 2182 CALL posix_write( fh, array_3di4, SIZE( array_3di4 ) ) 2183 #endif 2184 ! 2185 !-- Type conversion required, otherwise right hand side brackets are calculated assuming 4 byte INT. 2186 !-- Maybe a compiler problem. 2187 array_position = array_position + INT( (nz+2), KIND = rd_offset_kind ) * & 2188 INT( (iog%ny+1), KIND = rd_offset_kind ) * & 2189 INT( (iog%nx+1), KIND = rd_offset_kind ) * isp 2190 2191 write(9,*) 'array_position int4_3d ',trim(name),' ',array_position 2192 2193 END SUBROUTINE wrd_mpi_io_int4_3d 2194 2195 2196 2197 !--------------------------------------------------------------------------------------------------! 2198 ! Description: 2199 ! ------------ 2200 !> Write 3d-INTEGER*8 array with MPI-IO 2201 !--------------------------------------------------------------------------------------------------! 2202 SUBROUTINE wrd_mpi_io_int8_3d( name, data ) 2203 2204 IMPLICIT NONE 2205 2206 CHARACTER(LEN=*), INTENT(IN) :: name !< 2207 2208 INTEGER(iwp) :: i !< 2209 #if defined( __parallel ) 2210 INTEGER, DIMENSION(rd_status_size) :: status !< 2211 #endif 2212 INTEGER(idp), INTENT(IN), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: data !< 2213 2214 2215 IF ( header_array_index == max_nr_arrays ) THEN 2216 STOP '+++ maximum number of 2d/3d-array entries in restart file header exceeded' 2217 ENDIF 2218 2219 array_names(header_array_index) = name 2220 array_offset(header_array_index) = array_position 2221 header_array_index = header_array_index + 1 2222 2223 IF ( include_total_domain_boundaries ) THEN 2224 ! 2225 !-- Prepare output of 3d-REAL-array with ghost layers. In the virtual PE grid, the first 2226 !-- dimension is PEs along x, and the second along y. For MPI-IO it is recommended to have the 2227 !-- index order of the array in the same way, i.e. the first dimension should be along x and the 2228 !-- second along y. For this reason, the original PALM data need to be swaped. 2229 DO i = iog%nxl, iog%nxr 2230 array_3di8(:,i,iog%nys:iog%nyn) = data(:,iog%nys-nbgp:iog%nyn-nbgp,i-nbgp) 2231 ENDDO 2232 2233 ELSE 2234 ! 2235 !-- Prepare output of 3d-REAL-array without ghost layers 2236 DO i = nxl, nxr 2237 array_3di8(:,i,iog%nys:iog%nyn) = data(:,nys:nyn,i) 2238 ENDDO 2239 2240 ENDIF 2241 #if defined( __parallel ) 2242 CALL sm_io%sm_node_barrier() ! Has no effect if I/O on limited number of cores is inactive 2243 IF ( sm_io%iam_io_pe ) THEN 2244 CALL MPI_FILE_SET_VIEW( fh, array_position, MPI_INTEGER8, ft_3di8, 'native', MPI_INFO_NULL, ierr ) 2245 CALL MPI_FILE_WRITE_ALL( fh, array_3di8, SIZE( array_3di8 ), MPI_INTEGER8, status, ierr ) 2246 ENDIF 2247 CALL sm_io%sm_node_barrier() 2248 #else 2249 CALL posix_lseek( fh, array_position ) 2250 CALL posix_write( fh, array_3di8, SIZE( array_3di8 ) ) 2251 #endif 2252 ! 2253 !-- Type conversion required, otherwise right hand side brackets are calculated assuming 4 byte INT. 2254 !-- Maybe a compiler problem. 2255 array_position = array_position + INT( (nz+2), KIND = rd_offset_kind ) * & 2256 INT( (iog%ny+1), KIND = rd_offset_kind ) * & 2257 INT( (iog%nx+1), KIND = rd_offset_kind ) * dp 2258 2259 write(9,*) 'array_position int8_3d ',trim(name),' ',array_position 2260 2261 END SUBROUTINE wrd_mpi_io_int8_3d 2262 2263 2264 2265 !--------------------------------------------------------------------------------------------------! 2266 ! Description: 2267 ! ------------ 1951 2268 !> Write 3d-REAL array with MPI-IO 1952 2269 !--------------------------------------------------------------------------------------------------! … … 2007 2324 INT( (iog%ny+1), KIND = rd_offset_kind ) * & 2008 2325 INT( (iog%nx+1), KIND = rd_offset_kind ) * wp 2326 2327 write(9,*) 'array_position real3d ',trim(name),' ',array_position 2009 2328 2010 2329 END SUBROUTINE wrd_mpi_io_real_3d … … 2576 2895 ! Description: 2577 2896 ! ------------ 2897 !> Read particle data array with MPI-IO. 2898 !--------------------------------------------------------------------------------------------------! 2899 SUBROUTINE rrd_mpi_io_particles( name, prt_global_index ) 2900 2901 IMPLICIT NONE 2902 2903 CHARACTER(LEN=*), INTENT(IN) :: name !< 2904 INTEGER(idp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: prt_global_index !< 2905 2906 INTEGER(iwp) :: array_size !< 2907 INTEGER(iwp) :: byte_column !< 2908 INTEGER(iwp) :: i !< 2909 INTEGER(iwp) :: ind !< 2910 INTEGER(iwp) :: j !< 2911 INTEGER(iwp) :: k !< 2912 INTEGER(iwp) :: n !< 2913 INTEGER(iwp) :: particle_size !< 2914 2915 INTEGER(KIND=rd_offset_kind) :: disp !< 2916 INTEGER(KIND=rd_offset_kind) :: offset !< 2917 INTEGER(KIND=rd_offset_kind) :: prt_nr_bytes !< 2918 2919 LOGICAL :: found !< 2920 2921 REAL(dp) :: rr !< there is no data type INTEGER*8 in MPI 2922 REAL(dp) :: rs !< use REAL*8 to compute max offset 2923 2924 TYPE(particle_type), DIMENSION(:), ALLOCATABLE, TARGET :: prt_data !< 2925 2926 #if defined( __parallel ) 2927 INTEGER, DIMENSION(rd_status_size) :: status !< 2928 #else 2929 TYPE(C_PTR) :: buf 2930 #endif 2931 2932 found = .FALSE. 2933 2934 DO i = 1, tgh%nr_arrays 2935 IF ( TRIM(array_names(i)) == TRIM( name ) ) THEN 2936 array_position = array_offset(i) 2937 found = .TRUE. 2938 EXIT 2939 ENDIF 2940 ENDDO 2941 2942 IF ( found ) THEN 2943 2944 offset = 0 2945 2946 particle_size = STORAGE_SIZE(zero_particle) / 8 ! 8 here means number of bits/byte, NOT wp 2947 2948 array_size = 0 2949 DO i = nxl, nxr 2950 DO j = nys, nyn 2951 array_size = MAX( array_size, SUM(prt_count(:,j,i)) ) 2952 ENDDO 2953 ENDDO 2954 2955 write(9,*) 'particle_size_read ',particle_size,array_size,array_position,sum(prt_global_index) 2956 2957 ALLOCATE( prt_data(MAX(array_size,1)) ) 2958 2959 ! 2960 !-- Write columns of particle 2961 #if defined( __parallel ) 2962 CALL MPI_FILE_SET_VIEW( fh, offset, MPI_BYTE, MPI_BYTE, 'native', MPI_INFO_NULL, ierr ) 2963 #endif 2964 prt_nr_bytes = 0 2965 DO i = nxl, nxr 2966 DO j = nys, nyn 2967 disp = array_position + prt_global_index(nzb,j,i) * particle_size 2968 byte_column = SUM( prt_count(:,j,i) ) * particle_size 2969 prt_nr_bytes = MAX( disp+byte_column, prt_nr_bytes ) 2970 2971 #if defined( __parallel ) 2972 CALL sm_io%sm_node_barrier() ! Has no effect if I/O on limited number of cores is inactive 2973 IF ( byte_column > 0 ) THEN 2974 CALL MPI_FILE_SEEK( fh, disp, MPI_SEEK_SET, ierr ) 2975 CALL MPI_FILE_READ( fh, prt_data, byte_column, MPI_BYTE, status, ierr ) 2976 ENDIF 2977 CALL sm_io%sm_node_barrier() 2978 #else 2979 buf = C_LOC(prt_data) ! use C_PTR to avaid another overlay in posix interface 2980 CALL posix_lseek( fh, disp ) 2981 CALL posix_read( fh, buf, byte_column ) 2982 #endif 2983 ind = 1 2984 DO k = nzb, nzt+1 2985 DO n = 1, prt_count(k,j,i) 2986 grid_particles(k,j,i)%particles(n) = prt_data(ind) 2987 ind = ind+1 2988 ENDDO 2989 ENDDO 2990 2991 ENDDO 2992 ENDDO 2993 2994 #if defined( __parallel ) 2995 rs = prt_nr_bytes 2996 CALL MPI_ALLREDUCE( rs, rr, 1, MPI_DOUBLE_PRECISION, MPI_MAX, comm2d, ierr ) 2997 prt_nr_bytes = rr 2998 #else 2999 rr = rs 3000 #endif 3001 array_position = prt_nr_bytes 3002 3003 write(9,*) 'array_position after particle read ',array_position,prt_nr_bytes,rs 3004 3005 DEALLOCATE( prt_data ) 3006 3007 ENDIF 3008 3009 END SUBROUTINE rrd_mpi_io_particles 3010 3011 3012 3013 !--------------------------------------------------------------------------------------------------! 3014 ! Description: 3015 ! ------------ 2578 3016 !> Read 1d-REAL surface data array with MPI-IO. 2579 3017 !--------------------------------------------------------------------------------------------------! … … 2599 3037 #if defined( __parallel ) 2600 3038 INTEGER, DIMENSION(rd_status_size) :: status !< 3039 #else 3040 TYPE(C_PTR) :: buf !< 2601 3041 #endif 2602 3042 2603 3043 LOGICAL :: found !< 2604 3044 2605 REAL(wp), INTENT(OUT), DIMENSION(:) :: data!<3045 REAL(wp), INTENT(OUT), DIMENSION(:), TARGET :: data !< 2606 3046 2607 3047 … … 2677 3117 ierr ) 2678 3118 #else 3119 ! 3120 !-- Use C_PTR here, because posix read does not work with indexed array 3121 buf = C_LOC( data(m_start_index(j_f,i_f)) ) 2679 3122 CALL posix_lseek( fh, disp_f ) 2680 CALL posix_read( fh, data(m_start_index(j_f,i_f):), nr_bytes_f )3123 CALL posix_read( fh, buf, nr_bytes_f ) 2681 3124 #endif 2682 3125 disp_f = disp … … 2697 3140 2698 3141 ENDIF 2699 2700 ! IF ( lo_first_index == 1 ) THEN2701 ! IF ( debug_level >= 2 .AND. nr_val > 0 ) WRITE(9,*) 'r_surf_1 ', TRIM( name ), ' ', nr_val, SUM( data(1:nr_val) )2702 ! ELSE2703 ! IF ( debug_level >= 2 .AND. nr_val > 0 ) WRITE(9,*) 'r_surf_next ', TRIM( name ), ' ', &2704 ! lo_first_index,nr_val, SUM( data(1:nr_val) )2705 ! ENDIF2706 2707 3142 2708 3143 CONTAINS … … 2928 3363 ! Description: 2929 3364 ! ------------ 3365 !> Write particle data with MPI-IO. 3366 !--------------------------------------------------------------------------------------------------! 3367 SUBROUTINE wrd_mpi_io_particles( name, prt_global_index ) 3368 3369 IMPLICIT NONE 3370 3371 CHARACTER(LEN=*), INTENT(IN) :: name !< 3372 INTEGER(idp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: prt_global_index !< 3373 3374 INTEGER(iwp) :: array_size !< 3375 INTEGER(iwp) :: byte_column !< 3376 INTEGER(iwp) :: i !< 3377 INTEGER(iwp) :: ind !< 3378 INTEGER(iwp) :: j !< 3379 INTEGER(iwp) :: k !< 3380 INTEGER(iwp) :: n !< 3381 INTEGER(iwp) :: particle_size !< 3382 3383 INTEGER(KIND=rd_offset_kind) :: disp !< 3384 INTEGER(KIND=rd_offset_kind) :: offset !< 3385 INTEGER(KIND=rd_offset_kind) :: prt_nr_bytes !< 3386 3387 REAL(dp) :: rs !< use REAL*8 to compute max offset 3388 REAL(dp) :: rr !< there is no data type INTEGER*8 in MPI 3389 3390 3391 TYPE(particle_type), DIMENSION(:), ALLOCATABLE, TARGET :: prt_data !< 3392 3393 #if defined( __parallel ) 3394 INTEGER, DIMENSION(rd_status_size) :: status !< 3395 #else 3396 TYPE(C_PTR) :: buf 3397 #endif 3398 3399 3400 offset = 0 3401 3402 array_names(header_array_index) = TRIM(name) 3403 array_offset(header_array_index) = array_position 3404 header_array_index = header_array_index + 1 3405 3406 particle_size = STORAGE_SIZE( zero_particle ) / 8 3407 3408 array_size = 0 3409 DO i = nxl, nxr 3410 DO j = nys, nyn 3411 array_size = MAX( array_size, SUM(prt_count(:,j,i)) ) 3412 ENDDO 3413 ENDDO 3414 3415 ALLOCATE( prt_data(MAX(array_size,1)) ) 3416 3417 ! 3418 !-- Write columns of particles. 3419 !-- The particles of a column are stored sequentially in the first dimension of the particles array. 3420 !-- Store only the particles of one cell would be possible with this setup, but the I/O portions 3421 !-- for a maximum of 100 particles are not big enough. 3422 #if defined( __parallel ) 3423 CALL MPI_FILE_SET_VIEW( fh, offset, MPI_BYTE, MPI_BYTE, 'native', MPI_INFO_NULL, ierr ) 3424 #endif 3425 prt_nr_bytes = 0 3426 DO i = nxl, nxr 3427 DO j = nys, nyn 3428 disp = array_position + prt_global_index(nzb,j,i) * particle_size 3429 byte_column = SUM( prt_count(:,j,i) ) * particle_size 3430 prt_nr_bytes = MAX( disp+byte_column, prt_nr_bytes ) 3431 3432 ind = 1 3433 DO k = nzb, nzt+1 3434 DO n = 1, prt_count(k,j,i) 3435 prt_data(ind) = grid_particles(k,j,i)%particles(n) 3436 ind = ind+1 3437 ENDDO 3438 ENDDO 3439 3440 #if defined( __parallel ) 3441 CALL sm_io%sm_node_barrier() ! Has no effect if I/O on limited number of cores is inactive 3442 IF ( byte_column > 0 ) THEN 3443 CALL MPI_FILE_SEEK( fh, disp, MPI_SEEK_SET, ierr ) 3444 CALL MPI_FILE_WRITE( fh, prt_data, byte_column, MPI_BYTE, status, ierr ) 3445 ENDIF 3446 CALL sm_io%sm_node_barrier() 3447 #else 3448 buf = C_LOC(prt_data) ! use C_PTR to avoid another overlay in posix interface 3449 CALL posix_lseek( fh, disp ) 3450 CALL posix_write( fh, buf, byte_column ) 3451 #endif 3452 ENDDO 3453 ENDDO 3454 3455 #if defined( __parallel ) 3456 rs = prt_nr_bytes 3457 CALL MPI_ALLREDUCE( rs, rr, 1, MPI_DOUBLE_PRECISION, MPI_MAX, comm2d, ierr ) 3458 prt_nr_bytes = rr 3459 #else 3460 rr = rs 3461 #endif 3462 array_position = prt_nr_bytes 3463 3464 write(9,*) 'array_position after particle ',array_position,prt_nr_bytes,rs 3465 3466 DEALLOCATE( prt_data ) 3467 3468 END SUBROUTINE wrd_mpi_io_particles 3469 3470 3471 3472 !--------------------------------------------------------------------------------------------------! 3473 ! Description: 3474 ! ------------ 2930 3475 !> Write 1d-REAL surface data array with MPI-IO. 2931 3476 !--------------------------------------------------------------------------------------------------! … … 3043 3588 3044 3589 3590 3045 3591 !--------------------------------------------------------------------------------------------------! 3046 3592 ! Description: … … 3207 3753 ENDIF 3208 3754 3755 fh = -1 3756 3209 3757 restart_file_size = array_position / ( 1024.0_dp * 1024.0_dp ) 3210 3758 3211 3759 END SUBROUTINE rd_mpi_io_close 3760 3761 3762 3763 FUNCTION rd_mpi_io_check_open() RESULT ( isopen ) 3764 3765 LOGICAL :: isopen 3766 3767 isopen = ( fh /= -1 ) 3768 3769 END FUNCTION rd_mpi_io_check_open 3212 3770 3213 3771 … … 3567 4125 ! Description: 3568 4126 ! ------------ 4127 !> This subroutine creates file types to access 3d-INTEGER*4 arrays and 3d-INTEGER*8 arrays 4128 !> distributed in blocks among processes to a single file that contains the global arrays. 4129 !> These types are only used for particle data. 4130 !--------------------------------------------------------------------------------------------------! 4131 SUBROUTINE rd_mpi_io_particle_filetypes 4132 4133 IMPLICIT NONE 4134 4135 INTEGER, DIMENSION(3) :: dims3 !< 4136 INTEGER, DIMENSION(3) :: lize3 !< 4137 INTEGER, DIMENSION(3) :: start3 !< 4138 4139 TYPE(domain_decomposition_grid_features) :: save_io_grid !< temporary variable to store grid settings 4140 4141 ! 4142 !-- MPI_INTEGER8 is not standard MPI, but is supported on most MPI distibutions 4143 !-- If not suppported, a workaround could be enabled with the following preprocessor directive 4144 !#if defined( __NO_INTEGER8) 4145 ! CALL MPI_TYPE_CONTIGUOUS( 2, MPI_INTEGER, MPI_INTEGER8, ierr ) 4146 ! CALL MPI_TYPE_COMMIT( MPI_INTEGER8, ierr ) 4147 !#endif 4148 4149 IF ( sm_io%is_sm_active() ) THEN 4150 save_io_grid = sm_io%io_grid 4151 ENDIF 4152 4153 IF( .NOT. pe_active_for_read ) RETURN 4154 4155 ! 4156 !-- Decision, if storage with or without ghost layers. 4157 !-- Please note that the indexing of the global array always starts at 0, even in Fortran. 4158 !-- Therefore the PE local indices have to be shifted by nbgp in the case with ghost layers. 4159 IF ( include_total_domain_boundaries ) THEN 4160 4161 iog%nxl = nxl + nbgp 4162 iog%nxr = nxr + nbgp 4163 iog%nys = nys + nbgp 4164 iog%nyn = nyn + nbgp 4165 iog%nnx = nnx 4166 iog%nny = nny 4167 iog%nx = nx + 2 * nbgp 4168 iog%ny = ny + 2 * nbgp 4169 IF ( myidx == 0 ) THEN 4170 iog%nxl = iog%nxl - nbgp 4171 iog%nnx = iog%nnx + nbgp 4172 ENDIF 4173 IF ( myidx == npex-1 .OR. npex == -1 ) THEN ! npex == 1 if -D__parallel not set 4174 iog%nxr = iog%nxr + nbgp 4175 iog%nnx = iog%nnx + nbgp 4176 ENDIF 4177 IF ( myidy == 0 ) THEN 4178 iog%nys = iog%nys - nbgp 4179 iog%nny = iog%nny + nbgp 4180 ENDIF 4181 IF ( myidy == npey-1 .OR. npey == -1 ) THEN ! npey == 1 if -D__parallel not set 4182 iog%nyn = iog%nyn + nbgp 4183 iog%nny = iog%nny + nbgp 4184 ENDIF 4185 4186 CALL sm_io%sm_adjust_outer_boundary() 4187 4188 ELSE 4189 4190 iog%nxl = nxl 4191 iog%nxr = nxr 4192 iog%nys = nys 4193 iog%nyn = nyn 4194 iog%nnx = nnx 4195 iog%nny = nny 4196 iog%nx = nx 4197 iog%ny = ny 4198 4199 ENDIF 4200 4201 IF ( sm_io%is_sm_active() ) THEN 4202 #if defined( __parallel ) 4203 CALL sm_io%sm_allocate_shared( array_3di4, nzb, nzt+1, sm_io%io_grid%nxl, sm_io%io_grid%nxr,& 4204 sm_io%io_grid%nys, sm_io%io_grid%nyn, win_3di4 ) 4205 CALL sm_io%sm_allocate_shared( array_3di8, nzb, nzt+1, sm_io%io_grid%nxl, sm_io%io_grid%nxr,& 4206 sm_io%io_grid%nys, sm_io%io_grid%nyn, win_3di8 ) 4207 #endif 4208 ELSE 4209 ALLOCATE( array_3di4(nzb:nzt+1,iog%nxl:iog%nxr,iog%nys:iog%nyn) ) 4210 ALLOCATE( array_3di8(nzb:nzt+1,iog%nxl:iog%nxr,iog%nys:iog%nyn) ) 4211 4212 sm_io%io_grid = iog 4213 ENDIF 4214 4215 ! 4216 !-- Create filetype for 3d INTEGER array 4217 dims3(1) = nz + 2 4218 dims3(2) = iog%nx + 1 4219 dims3(3) = iog%ny + 1 4220 4221 lize3(1) = dims3(1) 4222 lize3(2) = sm_io%io_grid%nnx 4223 lize3(3) = sm_io%io_grid%nny 4224 4225 start3(1) = nzb 4226 start3(2) = sm_io%io_grid%nxl 4227 start3(3) = sm_io%io_grid%nys 4228 4229 #if defined( __parallel ) 4230 IF ( sm_io%iam_io_pe ) THEN 4231 CALL MPI_TYPE_CREATE_SUBARRAY( 3, dims3, lize3, start3, MPI_ORDER_FORTRAN, MPI_INTEGER, & 4232 ft_3di4, ierr ) 4233 CALL MPI_TYPE_COMMIT( ft_3di4, ierr ) 4234 4235 CALL MPI_TYPE_CREATE_SUBARRAY( 3, dims3, lize3, start3, MPI_ORDER_FORTRAN, MPI_INTEGER8, & 4236 ft_3di8, ierr ) 4237 CALL MPI_TYPE_COMMIT( ft_3di8, ierr ) 4238 ENDIF 4239 #endif 4240 4241 END SUBROUTINE rd_mpi_io_particle_filetypes 4242 4243 4244 4245 !--------------------------------------------------------------------------------------------------! 4246 ! Description: 4247 ! ------------ 3569 4248 !> This subroutine creates file types to access 3d-soil arrays distributed in blocks among processes 3570 4249 !> to a single file that contains the global arrays. It is not required for the serial mode. … … 3655 4334 ENDIF 3656 4335 4336 ! 4337 !-- Free last particle filetypes 4338 IF ( sm_io%iam_io_pe .AND. ft_3di4 /= -1 ) THEN 4339 CALL MPI_TYPE_FREE( ft_3di4, ierr ) 4340 CALL MPI_TYPE_FREE( ft_3di8, ierr ) 4341 ENDIF 4342 4343 IF ( sm_io%is_sm_active() .AND. win_3di4 /= -1 ) THEN 4344 CALL sm_io%sm_free_shared( win_3di4 ) 4345 CALL sm_io%sm_free_shared( win_3di8 ) 4346 ENDIF 4347 3657 4348 ft_surf = -1 3658 4349 win_surf = -1 3659 4350 #else 3660 DEALLOCATE( array_2d, array_2di, array_3d ) 4351 IF ( ASSOCIATED(array_2d) ) DEALLOCATE( array_2d ) 4352 IF ( ASSOCIATED(array_2di) ) DEALLOCATE( array_2di ) 4353 IF ( ASSOCIATED(array_3d) ) DEALLOCATE( array_3d ) 4354 IF ( ASSOCIATED(array_3di4) ) DEALLOCATE( array_3di4 ) 4355 IF ( ASSOCIATED(array_3di8) ) DEALLOCATE( array_3di8 ) 3661 4356 #endif 3662 4357
Note: See TracChangeset
for help on using the changeset viewer.