Changeset 1933 for palm/trunk/SOURCE/pmc_child_mod.f90
- Timestamp:
- Jun 13, 2016 7:12:51 AM (8 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/pmc_child_mod.f90
r1932 r1933 1 MODULE pmc_c lient2 3 !------------------------------------------------------------------------------- -!1 MODULE pmc_child 2 3 !-------------------------------------------------------------------------------! 4 4 ! This file is part of PALM. 5 5 ! … … 16 16 ! 17 17 ! Copyright 1997-2016 Leibniz Universitaet Hannover 18 !------------------------------------------------------------------------------- -!18 !-------------------------------------------------------------------------------! 19 19 ! 20 20 ! Current revisions: 21 21 ! ------------------ 22 22 ! 23 ! 23 ! 24 24 ! Former revisions: 25 25 ! ----------------- 26 26 ! $Id$ 27 ! 28 ! 1897 2016-05-03 08:10:23Z raasch 29 ! Module renamed. Code clean up. The words server/client changed to parent/child. 27 30 ! 28 31 ! 1896 2016-05-03 08:06:41Z raasch … … 47 50 ! 48 51 ! 1786 2016-03-08 05:49:27Z raasch 49 ! change in c lient-server data transfer: server now gets data from client50 ! instead that client put's it to the server52 ! change in child-parent data transfer: parent now gets data from child 53 ! instead of that child puts it to the parent 51 54 ! 52 55 ! 1783 2016-03-06 18:36:17Z raasch … … 67 70 ! ------------ 68 71 ! 69 ! C lientpart of Palm Model Coupler70 !------------------------------------------------------------------------------ !72 ! Child part of Palm Model Coupler 73 !-------------------------------------------------------------------------------! 71 74 72 75 #if defined( __parallel ) … … 81 84 82 85 USE kinds 83 USE pmc_general, &84 ONLY: arraydef, c lientdef, da_desclen, da_namedef, da_namelen, pedef,&86 USE pmc_general, & 87 ONLY: arraydef, childdef, da_desclen, da_namedef, da_namelen, pedef, & 85 88 pmc_da_name_err, pmc_g_setname, pmc_max_array, pmc_status_ok 86 89 87 USE pmc_handle_communicator, & 88 ONLY: m_model_comm, m_model_npes, m_model_rank, m_to_server_comm 89 90 USE pmc_mpi_wrapper, & 91 ONLY: pmc_alloc_mem, pmc_bcast, pmc_inter_bcast, & 92 pmc_recv_from_server, pmc_send_to_server, pmc_time 90 USE pmc_handle_communicator, & 91 ONLY: m_model_comm, m_model_npes, m_model_rank, m_to_parent_comm 92 93 USE pmc_mpi_wrapper, & 94 ONLY: pmc_alloc_mem, pmc_bcast, pmc_inter_bcast, pmc_time 93 95 94 96 IMPLICIT NONE … … 97 99 SAVE 98 100 99 TYPE(c lientdef) :: me !<101 TYPE(childdef) :: me !< 100 102 101 103 INTEGER :: myindex = 0 !< counter and unique number for data arrays … … 103 105 104 106 105 INTERFACE pmc_c lientinit106 MODULE PROCEDURE pmc_c lientinit107 END INTERFACE PMC_ClientInit107 INTERFACE pmc_childinit 108 MODULE PROCEDURE pmc_childinit 109 END INTERFACE pmc_childinit 108 110 109 111 INTERFACE pmc_c_clear_next_array_list … … 142 144 143 145 144 PUBLIC pmc_c lientinit, pmc_c_clear_next_array_list, pmc_c_getbuffer,&145 pmc_c_getnextarray, pmc_c_putbuffer, pmc_c_setind_and_allocmem, &146 PUBLIC pmc_childinit, pmc_c_clear_next_array_list, pmc_c_getbuffer, & 147 pmc_c_getnextarray, pmc_c_putbuffer, pmc_c_setind_and_allocmem, & 146 148 pmc_c_set_dataarray, pmc_set_dataarray_name, pmc_c_get_2d_index_list 147 149 … … 150 152 151 153 152 SUBROUTINE pmc_c lientinit154 SUBROUTINE pmc_childinit 153 155 154 156 IMPLICIT NONE … … 160 162 !-- Get / define the MPI environment 161 163 me%model_comm = m_model_comm 162 me%inter_comm = m_to_ server_comm164 me%inter_comm = m_to_parent_comm 163 165 164 166 CALL MPI_COMM_RANK( me%model_comm, me%model_rank, istat ) 165 167 CALL MPI_COMM_SIZE( me%model_comm, me%model_npes, istat ) 166 168 CALL MPI_COMM_REMOTE_SIZE( me%inter_comm, me%inter_npes, istat ) 169 167 170 ! 168 171 !-- Intra-communicater is used for MPI_GET … … 173 176 174 177 ! 175 !-- Allocate an array of type arraydef for all serverPEs to store information178 !-- Allocate an array of type arraydef for all parent PEs to store information 176 179 !-- of then transfer array 177 180 DO i = 1, me%inter_npes … … 179 182 ENDDO 180 183 181 END SUBROUTINE pmc_c lientinit182 183 184 185 SUBROUTINE pmc_set_dataarray_name( serverarraydesc, serverarrayname,&186 c lientarraydesc, clientarrayname, istat )187 188 IMPLICIT NONE 189 190 CHARACTER(LEN=*), INTENT(IN) :: serverarrayname !<191 CHARACTER(LEN=*), INTENT(IN) :: serverarraydesc !<192 CHARACTER(LEN=*), INTENT(IN) :: c lientarrayname!<193 CHARACTER(LEN=*), INTENT(IN) :: c lientarraydesc!<184 END SUBROUTINE pmc_childinit 185 186 187 188 SUBROUTINE pmc_set_dataarray_name( parentarraydesc, parentarrayname, & 189 childarraydesc, childarrayname, istat ) 190 191 IMPLICIT NONE 192 193 CHARACTER(LEN=*), INTENT(IN) :: parentarrayname !< 194 CHARACTER(LEN=*), INTENT(IN) :: parentarraydesc !< 195 CHARACTER(LEN=*), INTENT(IN) :: childarrayname !< 196 CHARACTER(LEN=*), INTENT(IN) :: childarraydesc !< 194 197 195 198 INTEGER, INTENT(OUT) :: istat !< … … 204 207 205 208 istat = pmc_status_ok 209 206 210 ! 207 211 !-- Check length of array names 208 IF ( LEN( TRIM( serverarrayname) ) > da_namelen .OR.&209 LEN( TRIM( c lientarrayname) ) > da_namelen ) THEN212 IF ( LEN( TRIM( parentarrayname) ) > da_namelen .OR. & 213 LEN( TRIM( childarrayname) ) > da_namelen ) THEN 210 214 istat = pmc_da_name_err 211 215 ENDIF … … 214 218 myindex = myindex + 1 215 219 myname%couple_index = myIndex 216 myname% serverdesc = TRIM( serverarraydesc )217 myname%nameon server = TRIM( serverarrayname )218 myname%c lientdesc = TRIM( clientarraydesc )219 myname%nameonc lient = TRIM( clientarrayname )220 myname%parentdesc = TRIM( parentarraydesc ) 221 myname%nameonparent = TRIM( parentarrayname ) 222 myname%childdesc = TRIM( childarraydesc ) 223 myname%nameonchild = TRIM( childarrayname ) 220 224 ENDIF 221 225 222 226 ! 223 !-- Broadcat to all c lientPEs227 !-- Broadcat to all child PEs 224 228 !-- TODO: describe what is broadcast here and why it is done 225 229 CALL pmc_bcast( myname%couple_index, 0, comm=m_model_comm ) 226 CALL pmc_bcast( myname% serverdesc, 0, comm=m_model_comm )227 CALL pmc_bcast( myname%nameon server, 0, comm=m_model_comm )228 CALL pmc_bcast( myname%c lientdesc,0, comm=m_model_comm )229 CALL pmc_bcast( myname%nameonc lient,0, comm=m_model_comm )230 231 ! 232 !-- Broadcat to all serverPEs230 CALL pmc_bcast( myname%parentdesc, 0, comm=m_model_comm ) 231 CALL pmc_bcast( myname%nameonparent, 0, comm=m_model_comm ) 232 CALL pmc_bcast( myname%childdesc, 0, comm=m_model_comm ) 233 CALL pmc_bcast( myname%nameonchild, 0, comm=m_model_comm ) 234 235 ! 236 !-- Broadcat to all parent PEs 233 237 !-- TODO: describe what is broadcast here and why it is done 234 238 IF ( m_model_rank == 0 ) THEN … … 238 242 ENDIF 239 243 240 CALL pmc_bcast( myname%couple_index, mype, comm=m_to_ server_comm )241 CALL pmc_bcast( myname% serverdesc, mype, comm=m_to_server_comm )242 CALL pmc_bcast( myname%nameon server, mype, comm=m_to_server_comm )243 CALL pmc_bcast( myname%c lientdesc, mype, comm=m_to_server_comm )244 CALL pmc_bcast( myname%nameonc lient, mype, comm=m_to_server_comm )245 246 CALL pmc_g_setname( me, myname%couple_index, myname%nameonc lient)244 CALL pmc_bcast( myname%couple_index, mype, comm=m_to_parent_comm ) 245 CALL pmc_bcast( myname%parentdesc, mype, comm=m_to_parent_comm ) 246 CALL pmc_bcast( myname%nameonparent, mype, comm=m_to_parent_comm ) 247 CALL pmc_bcast( myname%childdesc, mype, comm=m_to_parent_comm ) 248 CALL pmc_bcast( myname%nameonchild, mype, comm=m_to_parent_comm ) 249 250 CALL pmc_g_setname( me, myname%couple_index, myname%nameonchild ) 247 251 248 252 END SUBROUTINE pmc_set_dataarray_name … … 269 273 ENDIF 270 274 271 CALL pmc_bcast( myname%couple_index, mype, comm=m_to_ server_comm )275 CALL pmc_bcast( myname%couple_index, mype, comm=m_to_parent_comm ) 272 276 273 277 END SUBROUTINE pmc_set_dataarray_name_lastentry … … 296 300 297 301 win_size = C_SIZEOF( dummy ) 298 CALL MPI_WIN_CREATE( dummy, win_size, iwp, MPI_INFO_NULL, me%intra_comm, &302 CALL MPI_WIN_CREATE( dummy, win_size, iwp, MPI_INFO_NULL, me%intra_comm, & 299 303 indwin, ierr ) 300 ! 301 !-- Open window on server side 304 305 ! 306 !-- Open window on parent side 302 307 !-- TODO: why is the next MPI routine called twice?? 303 308 CALL MPI_WIN_FENCE( 0, indwin, ierr ) 304 ! 305 !-- Close window on server side and open on client side 309 310 ! 311 !-- Close window on parent side and open on child side 306 312 CALL MPI_WIN_FENCE( 0, indwin, ierr ) 307 313 308 314 DO i = 1, me%inter_npes 309 315 disp = me%model_rank * 2 310 CALL MPI_GET( nrele((i-1)*2+1), 2, MPI_INTEGER, i-1, disp, 2, &316 CALL MPI_GET( nrele((i-1)*2+1), 2, MPI_INTEGER, i-1, disp, 2, & 311 317 MPI_INTEGER, indwin, ierr ) 312 318 ENDDO 319 313 320 ! 314 321 !-- MPI_GET is non-blocking -> data in nrele is not available until MPI_FENCE is … … 336 343 ! 337 344 !-- Local buffer used in MPI_GET can but must not be inside the MPI Window. 338 !-- Here, we use a dummy for the MPI window because the serverPEs do not access345 !-- Here, we use a dummy for the MPI window because the parent PEs do not access 339 346 !-- the RMA window via MPI_GET or MPI_PUT 340 CALL MPI_WIN_CREATE( dummy, winsize, iwp, MPI_INFO_NULL, me%intra_comm, &347 CALL MPI_WIN_CREATE( dummy, winsize, iwp, MPI_INFO_NULL, me%intra_comm, & 341 348 indwin2, ierr ) 349 342 350 ! 343 351 !-- MPI_GET is non-blocking -> data in nrele is not available until MPI_FENCE is … … 353 361 disp = nrele(2*(i-1)+1) 354 362 CALL MPI_WIN_LOCK( MPI_LOCK_SHARED , i-1, 0, indwin2, ierr ) 355 CALL MPI_GET( myind, 2*nr, MPI_INTEGER, i-1, disp, 2*nr, &363 CALL MPI_GET( myind, 2*nr, MPI_INTEGER, i-1, disp, 2*nr, & 356 364 MPI_INTEGER, indwin2, ierr ) 357 365 CALL MPI_WIN_UNLOCK( i-1, indwin2, ierr ) … … 389 397 390 398 LOGICAL FUNCTION pmc_c_getnextarray( myname ) 399 391 400 ! 392 401 !-- List handling is still required to get minimal interaction with … … 403 412 404 413 ! 405 !-- Array names are the same on all c lientPEs, so take first PE to get the name414 !-- Array names are the same on all child PEs, so take first PE to get the name 406 415 ape => me%pes(1) 416 407 417 ! 408 418 !-- Check if all arrays have been processed … … 497 507 498 508 IMPLICIT NONE 499 ! 500 !-- Naming convention for appendices: _sc -> server to client transfer 501 !-- _cs -> client to server transfer 502 !-- recv -> server to client transfer 503 !-- send -> client to server transfer 509 510 ! 511 !-- Naming convention for appendices: _pc -> parent to child transfer 512 !-- _cp -> child to parent transfer 513 !-- recv -> parent to child transfer 514 !-- send -> child to parent transfer 504 515 CHARACTER(LEN=da_namelen) :: myname !< 505 516 … … 520 531 INTEGER,DIMENSION(1024) :: req !< 521 532 522 REAL(wp), DIMENSION(:), POINTER, SAVE :: base_array_ sc !< base array523 REAL(wp), DIMENSION(:), POINTER, SAVE :: base_array_c s!< base array533 REAL(wp), DIMENSION(:), POINTER, SAVE :: base_array_pc !< base array 534 REAL(wp), DIMENSION(:), POINTER, SAVE :: base_array_cp !< base array 524 535 525 536 TYPE(pedef), POINTER :: ape !< … … 532 543 533 544 ! 534 !-- Server to clientdirection.545 !-- Parent to child direction. 535 546 !-- First stride: compute size and set index 536 547 DO i = 1, me%inter_npes … … 542 553 543 554 ar => ape%array_list(j) 544 ! 545 !-- Receive index from client 555 556 ! 557 !-- Receive index from child 546 558 tag = tag + 1 547 CALL MPI_RECV( myindex, 1, MPI_INTEGER, i-1, tag, me%inter_comm, &559 CALL MPI_RECV( myindex, 1, MPI_INTEGER, i-1, tag, me%inter_comm, & 548 560 MPI_STATUS_IGNORE, ierr ) 549 561 ar%recvindex = myindex 550 ! 551 !-- Determine max, because client buffer is allocated only once 562 563 ! 564 !-- Determine max, because child buffer is allocated only once 552 565 !-- TODO: give a more meaningful comment 553 566 IF( ar%nrdims == 3 ) THEN … … 565 578 !-- The buffer for MPI_GET can be PE local, i.e. it can but must not be part of 566 579 !-- the MPI RMA window 567 CALL pmc_alloc_mem( base_array_ sc, bufsize, base_ptr )580 CALL pmc_alloc_mem( base_array_pc, bufsize, base_ptr ) 568 581 me%totalbuffersize = bufsize*wp ! total buffer size in byte 569 582 … … 582 595 583 596 ! 584 !-- C lient to serverdirection597 !-- Child to parent direction 585 598 myindex = 1 586 599 rcount = 0 … … 604 617 rcount = rcount + 1 605 618 IF ( ape%nrele > 0 ) THEN 606 CALL MPI_ISEND( myindex, 1, MPI_INTEGER, i-1, tag, me%inter_comm, &619 CALL MPI_ISEND( myindex, 1, MPI_INTEGER, i-1, tag, me%inter_comm, & 607 620 req(rcount), ierr ) 608 621 ar%sendindex = myindex 609 622 ELSE 610 CALL MPI_ISEND( noindex, 1, MPI_INTEGER, i-1, tag, me%inter_comm, &623 CALL MPI_ISEND( noindex, 1, MPI_INTEGER, i-1, tag, me%inter_comm, & 611 624 req(rcount), ierr ) 612 625 ar%sendindex = noindex 613 626 ENDIF 627 614 628 ! 615 629 !-- Maximum of 1024 outstanding requests … … 635 649 636 650 ! 637 !-- Create RMA (one sided communication) window for data buffer c lient to server651 !-- Create RMA (one sided communication) window for data buffer child to parent 638 652 !-- transfer. 639 653 !-- The buffer of MPI_GET (counter part of transfer) can be PE-local, i.e. it 640 654 !-- can but must not be part of the MPI RMA window. Only one RMA window is 641 655 !-- required to prepare the data 642 !-- for server -> client transfer on the serverside656 !-- for parent -> child transfer on the parent side 643 657 !-- and 644 !-- for client -> server transfer on the client side 645 646 CALL pmc_alloc_mem( base_array_cs, bufsize ) 658 !-- for child -> parent transfer on the child side 659 CALL pmc_alloc_mem( base_array_cp, bufsize ) 647 660 me%totalbuffersize = bufsize * wp ! total buffer size in byte 648 661 649 662 winSize = me%totalbuffersize 650 663 651 CALL MPI_WIN_CREATE( base_array_c s, winsize, wp, MPI_INFO_NULL,&652 me%intra_comm, me%win_ server_client, ierr )653 CALL MPI_WIN_FENCE( 0, me%win_ server_client, ierr )664 CALL MPI_WIN_CREATE( base_array_cp, winsize, wp, MPI_INFO_NULL, & 665 me%intra_comm, me%win_parent_child, ierr ) 666 CALL MPI_WIN_FENCE( 0, me%win_parent_child, ierr ) 654 667 CALL MPI_BARRIER( me%intra_comm, ierr ) 655 668 … … 665 678 666 679 IF ( ape%nrele > 0 ) THEN 667 ar%sendbuf = C_LOC( base_array_cs(ar%sendindex) ) 680 ar%sendbuf = C_LOC( base_array_cp(ar%sendindex) ) 681 682 ! 668 683 !-- TODO: if this is an error to be really expected, replace the 669 684 !-- following message by a meaningful standard PALM message using 670 685 !-- the message-routine 671 686 IF ( ar%sendindex+ar%sendsize > bufsize ) THEN 672 WRITE( 0,'(a,i4,4i7,1x,a)') 'C lient Buffer too small ', i,&673 ar%sendindex, ar%sendsize, ar%sendindex+ar%sendsize, &687 WRITE( 0,'(a,i4,4i7,1x,a)') 'Child buffer too small ', i, & 688 ar%sendindex, ar%sendsize, ar%sendindex+ar%sendsize, & 674 689 bufsize, TRIM( ar%name ) 675 690 CALL MPI_ABORT( MPI_COMM_WORLD, istat, ierr ) … … 699 714 INTEGER :: myindex !< 700 715 INTEGER :: nr !< number of elements to get 701 !< from server716 !< from parent 702 717 INTEGER(KIND=MPI_ADDRESS_KIND) :: target_disp 703 718 INTEGER,DIMENSION(1) :: buf_shape … … 713 728 714 729 ! 715 !-- Synchronization of the model is done in pmci_ client_synchronize and716 !-- pmci_server_synchronize. Thereforthe RMA window can be filled without730 !-- Synchronization of the model is done in pmci_synchronize. 731 !-- Therefore the RMA window can be filled without 717 732 !-- sychronization at this point and a barrier is not necessary. 718 733 !-- Please note that waittime has to be set in pmc_s_fillbuffer AND … … 724 739 waittime = t2 - t1 725 740 ENDIF 726 ! 727 !-- Wait for buffer is filled 741 742 ! 743 !-- Wait for buffer is filled. 728 744 !-- TODO: explain in more detail what is happening here. The barrier seems to 729 !-- contradict what is said a few lines before r(i.e. that no barrier is necessary)745 !-- contradict what is said a few lines before (i.e. that no barrier is necessary) 730 746 !-- TODO: In case of PRESENT( waittime ) the barrrier would be calles twice. Why? 731 747 !-- Shouldn't it be done the same way as in pmc_putbuffer? … … 748 764 buf_shape(1) = nr 749 765 CALL C_F_POINTER( ar%recvbuf, buf, buf_shape ) 766 750 767 ! 751 768 !-- MPI passive target RMA … … 753 770 IF ( nr > 0 ) THEN 754 771 target_disp = ar%recvindex - 1 755 CALL MPI_WIN_LOCK( MPI_LOCK_SHARED , ip-1, 0, &756 me%win_ server_client, ierr )757 CALL MPI_GET( buf, nr, MPI_REAL, ip-1, target_disp, nr, MPI_REAL, &758 me%win_ server_client, ierr )759 CALL MPI_WIN_UNLOCK( ip-1, me%win_ server_client, ierr )772 CALL MPI_WIN_LOCK( MPI_LOCK_SHARED , ip-1, 0, & 773 me%win_parent_child, ierr ) 774 CALL MPI_GET( buf, nr, MPI_REAL, ip-1, target_disp, nr, MPI_REAL, & 775 me%win_parent_child, ierr ) 776 CALL MPI_WIN_UNLOCK( ip-1, me%win_parent_child, ierr ) 760 777 ENDIF 761 778 … … 775 792 776 793 DO ij = 1, ape%nrele 777 data_3d(:,ape%locind(ij)%j,ape%locind(ij)%i) = &794 data_3d(:,ape%locind(ij)%j,ape%locind(ij)%i) = & 778 795 buf(myindex:myindex+ar%a_dim(1)-1) 779 796 myindex = myindex+ar%a_dim(1) … … 804 821 INTEGER :: myindex !< 805 822 INTEGER :: nr !< number of elements to get 806 !< from server823 !< from parent 807 824 INTEGER(KIND=MPI_ADDRESS_KIND) :: target_disp !< 808 825 … … 854 871 855 872 DO ij = 1, ape%nrele 856 buf(myindex:myindex+ar%a_dim(1)-1) = &873 buf(myindex:myindex+ar%a_dim(1)-1) = & 857 874 data_3d(:,ape%locind(ij)%j,ape%locind(ij)%i) 858 875 myindex = myindex + ar%a_dim(1) … … 864 881 865 882 ENDDO 883 866 884 ! 867 885 !-- TODO: Fence might do it, test later 868 !-- Call MPI_WIN_FENCE( 0, me%win_ server_client, ierr) !886 !-- Call MPI_WIN_FENCE( 0, me%win_parent_child, ierr) ! 869 887 ! 870 888 !-- Buffer is filled … … 875 893 876 894 #endif 877 END MODULE pmc_c lient895 END MODULE pmc_child
Note: See TracChangeset
for help on using the changeset viewer.