Changeset 1933 for palm/trunk/SOURCE/pmc_parent_mod.f90
- Timestamp:
- Jun 13, 2016 7:12:51 AM (8 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/pmc_parent_mod.f90
r1927 r1933 1 MODULE pmc_ server2 3 !------------------------------------------------------------------------------- -!1 MODULE pmc_parent 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 ! 1901 2016-05-04 15:39:38Z raasch 29 ! Module renamed. Code clean up. The words server/client changed to parent/child. 27 30 ! 28 31 ! 1900 2016-05-04 15:27:53Z 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 c lient put's it to the server52 ! change in child-parent data transfer: parent now gets data from child 53 ! instead that child put's it to the parent 51 54 ! 52 55 ! 1779 2016-03-03 08:01:28Z raasch … … 68 71 ! ------------ 69 72 ! 70 ! Serverpart of Palm Model Coupler71 !------------------------------------------------------------------------------ !73 ! Parent part of Palm Model Coupler 74 !-------------------------------------------------------------------------------! 72 75 73 76 #if defined( __parallel ) … … 80 83 #endif 81 84 USE kinds 82 USE pmc_general, &83 ONLY: arraydef, c lientdef, da_namedef, da_namelen, pedef,&85 USE pmc_general, & 86 ONLY: arraydef, childdef, da_namedef, da_namelen, pedef, & 84 87 pmc_g_setname, pmc_max_array, pmc_max_models, pmc_sort 85 88 86 USE pmc_handle_communicator, &87 ONLY: m_model_comm,m_model_rank,m_model_npes, m_to_c lient_comm,&88 m_world_rank, pmc_ server_for_client89 90 USE pmc_mpi_wrapper, &89 USE pmc_handle_communicator, & 90 ONLY: m_model_comm,m_model_rank,m_model_npes, m_to_child_comm, & 91 m_world_rank, pmc_parent_for_child 92 93 USE pmc_mpi_wrapper, & 91 94 ONLY: pmc_alloc_mem, pmc_bcast, pmc_time 92 95 … … 96 99 SAVE 97 100 98 TYPE c lientindexdef101 TYPE childindexdef 99 102 INTEGER :: nrpoints !< 100 103 INTEGER, DIMENSION(:,:), ALLOCATABLE :: index_list_2d !< 101 END TYPE c lientindexdef102 103 TYPE(c lientdef), DIMENSION(pmc_max_models) :: clients!<104 TYPE(c lientindexdef), DIMENSION(pmc_max_models) :: indclients!<104 END TYPE childindexdef 105 106 TYPE(childdef), DIMENSION(pmc_max_models) :: children !< 107 TYPE(childindexdef), DIMENSION(pmc_max_models) :: indchildren !< 105 108 106 109 INTEGER :: next_array_in_list = 0 !< 107 110 108 111 109 PUBLIC pmc_ server_for_client110 111 112 INTERFACE pmc_ serverinit113 MODULE PROCEDURE pmc_ serverinit114 END INTERFACE pmc_ serverinit112 PUBLIC pmc_parent_for_child 113 114 115 INTERFACE pmc_parentinit 116 MODULE PROCEDURE pmc_parentinit 117 END INTERFACE pmc_parentinit 115 118 116 119 INTERFACE pmc_s_set_2d_index_list … … 147 150 END INTERFACE pmc_s_set_active_data_array 148 151 149 PUBLIC pmc_ serverinit, pmc_s_clear_next_array_list, pmc_s_fillbuffer,&150 pmc_s_getdata_from_buffer, pmc_s_getnextarray, &151 pmc_s_setind_and_allocmem, pmc_s_set_active_data_array, &152 PUBLIC pmc_parentinit, pmc_s_clear_next_array_list, pmc_s_fillbuffer, & 153 pmc_s_getdata_from_buffer, pmc_s_getnextarray, & 154 pmc_s_setind_and_allocmem, pmc_s_set_active_data_array, & 152 155 pmc_s_set_dataarray, pmc_s_set_2d_index_list 153 156 … … 155 158 156 159 157 SUBROUTINE pmc_ serverinit160 SUBROUTINE pmc_parentinit 158 161 159 162 IMPLICIT NONE 160 163 161 INTEGER :: c lientid!<164 INTEGER :: childid !< 162 165 INTEGER :: i !< 163 166 INTEGER :: j !< … … 165 168 166 169 167 DO i = 1, SIZE( pmc_server_for_client )-1 168 169 clientid = pmc_server_for_client( i ) 170 171 clients(clientid)%model_comm = m_model_comm 172 clients(clientid)%inter_comm = m_to_client_comm(clientid) 170 DO i = 1, SIZE( pmc_parent_for_child )-1 171 172 childid = pmc_parent_for_child( i ) 173 174 children(childid)%model_comm = m_model_comm 175 children(childid)%inter_comm = m_to_child_comm(childid) 176 173 177 ! 174 178 !-- Get rank and size 175 CALL MPI_COMM_RANK( clients(clientid)%model_comm, & 176 clients(clientid)%model_rank, istat ) 177 CALL MPI_COMM_SIZE( clients(clientid)%model_comm, & 178 clients(clientid)%model_npes, istat ) 179 CALL MPI_COMM_REMOTE_SIZE( clients(clientid)%inter_comm, & 180 clients(clientid)%inter_npes, istat ) 179 CALL MPI_COMM_RANK( children(childid)%model_comm, & 180 children(childid)%model_rank, istat ) 181 CALL MPI_COMM_SIZE( children(childid)%model_comm, & 182 children(childid)%model_npes, istat ) 183 CALL MPI_COMM_REMOTE_SIZE( children(childid)%inter_comm, & 184 children(childid)%inter_npes, istat ) 185 181 186 ! 182 187 !-- Intra communicater is used for MPI_GET 183 CALL MPI_INTERCOMM_MERGE( clients(clientid)%inter_comm, .FALSE., & 184 clients(clientid)%intra_comm, istat ) 185 CALL MPI_COMM_RANK( clients(clientid)%intra_comm, & 186 clients(clientid)%intra_rank, istat ) 187 188 ALLOCATE( clients(clientid)%pes(clients(clientid)%inter_npes)) 189 ! 190 !-- Allocate array of TYPE arraydef for all client PEs to store information 188 CALL MPI_INTERCOMM_MERGE( children(childid)%inter_comm, .FALSE., & 189 children(childid)%intra_comm, istat ) 190 CALL MPI_COMM_RANK( children(childid)%intra_comm, & 191 children(childid)%intra_rank, istat ) 192 193 ALLOCATE( children(childid)%pes(children(childid)%inter_npes)) 194 195 ! 196 !-- Allocate array of TYPE arraydef for all child PEs to store information 191 197 !-- of the transfer array 192 DO j = 1, c lients(clientid)%inter_npes193 ALLOCATE( c lients(clientid)%pes(j)%array_list(pmc_max_array) )198 DO j = 1, children(childid)%inter_npes 199 ALLOCATE( children(childid)%pes(j)%array_list(pmc_max_array) ) 194 200 ENDDO 195 201 196 CALL get_da_names_from_c lient (clientid)197 198 ENDDO 199 200 END SUBROUTINE pmc_ serverinit201 202 203 204 SUBROUTINE pmc_s_set_2d_index_list( c lientid, index_list )202 CALL get_da_names_from_child (childid) 203 204 ENDDO 205 206 END SUBROUTINE pmc_parentinit 207 208 209 210 SUBROUTINE pmc_s_set_2d_index_list( childid, index_list ) 205 211 206 212 IMPLICIT NONE 207 213 208 INTEGER, INTENT(IN) :: c lientid!<214 INTEGER, INTENT(IN) :: childid !< 209 215 INTEGER, DIMENSION(:,:), INTENT(INOUT) :: index_list !< 210 216 … … 219 225 220 226 IF ( m_model_rank == 0 ) THEN 221 ! 222 !-- Sort to ascending server PE 227 228 ! 229 !-- Sort to ascending parent PE order 223 230 CALL pmc_sort( index_list, 6 ) 224 231 225 232 is = 1 226 233 DO ip = 0, m_model_npes-1 227 ! 228 !-- Split into server PEs 234 235 ! 236 !-- Split into parent PEs 229 237 ie = is - 1 238 230 239 ! 231 240 !-- There may be no entry for this PE … … 244 253 ian = 0 245 254 ENDIF 246 ! 247 !-- Send data to other server PEs 255 256 ! 257 !-- Send data to other parent PEs 248 258 IF ( ip == 0 ) THEN 249 indc lients(clientid)%nrpoints = ian259 indchildren(childid)%nrpoints = ian 250 260 IF ( ian > 0) THEN 251 ALLOCATE( indc lients(clientid)%index_list_2d(6,ian) )252 indc lients(clientid)%index_list_2d(:,1:ian) =&261 ALLOCATE( indchildren(childid)%index_list_2d(6,ian) ) 262 indchildren(childid)%index_list_2d(:,1:ian) = & 253 263 index_list(:,is:ie) 254 264 ENDIF 255 265 ELSE 256 CALL MPI_SEND( ian, 1, MPI_INTEGER, ip, 1000, m_model_comm, &266 CALL MPI_SEND( ian, 1, MPI_INTEGER, ip, 1000, m_model_comm, & 257 267 istat ) 258 268 IF ( ian > 0) THEN 259 CALL MPI_SEND( index_list(1,is), 6*ian, MPI_INTEGER, ip, &269 CALL MPI_SEND( index_list(1,is), 6*ian, MPI_INTEGER, ip, & 260 270 1001, m_model_comm, istat ) 261 271 ENDIF … … 267 277 ELSE 268 278 269 CALL MPI_RECV( indc lients(clientid)%nrpoints, 1, MPI_INTEGER, 0, 1000,&279 CALL MPI_RECV( indchildren(childid)%nrpoints, 1, MPI_INTEGER, 0, 1000, & 270 280 m_model_comm, MPI_STATUS_IGNORE, istat ) 271 ian = indc lients(clientid)%nrpoints281 ian = indchildren(childid)%nrpoints 272 282 273 283 IF ( ian > 0 ) THEN 274 ALLOCATE( indc lients(clientid)%index_list_2d(6,ian) )275 CALL MPI_RECV( indc lients(clientid)%index_list_2d, 6*ian,&276 MPI_INTEGER, 0, 1001, m_model_comm, &284 ALLOCATE( indchildren(childid)%index_list_2d(6,ian) ) 285 CALL MPI_RECV( indchildren(childid)%index_list_2d, 6*ian, & 286 MPI_INTEGER, 0, 1001, m_model_comm, & 277 287 MPI_STATUS_IGNORE, istat) 278 288 ENDIF … … 280 290 ENDIF 281 291 282 CALL set_pe_index_list( c lientid, clients(clientid),&283 indc lients(clientid)%index_list_2d,&284 indc lients(clientid)%nrpoints )292 CALL set_pe_index_list( childid, children(childid), & 293 indchildren(childid)%index_list_2d, & 294 indchildren(childid)%nrpoints ) 285 295 286 296 END SUBROUTINE pmc_s_set_2d_index_list … … 298 308 299 309 300 LOGICAL FUNCTION pmc_s_getnextarray( clientid, myname ) 310 LOGICAL FUNCTION pmc_s_getnextarray( childid, myname ) 311 301 312 ! 302 313 !-- List handling is still required to get minimal interaction with … … 304 315 !-- TODO: what does "still" mean? Is there a chance to change this! 305 316 CHARACTER(LEN=*), INTENT(OUT) :: myname !< 306 INTEGER(iwp), INTENT(IN) :: c lientid!<317 INTEGER(iwp), INTENT(IN) :: childid !< 307 318 308 319 TYPE(arraydef), POINTER :: ar … … 310 321 311 322 next_array_in_list = next_array_in_list + 1 312 ! 313 !-- Array names are the same on all client PEs, so take first PE to get the name 314 ape => clients(clientid)%pes(1) 323 324 ! 325 !-- Array names are the same on all children PEs, so take first PE to get the name 326 ape => children(childid)%pes(1) 315 327 316 328 IF ( next_array_in_list > ape%nr_arrays ) THEN 329 317 330 ! 318 331 !-- All arrays are done … … 323 336 ar => ape%array_list(next_array_in_list) 324 337 myname = ar%name 338 325 339 ! 326 340 !-- Return true if legal array … … 332 346 333 347 334 SUBROUTINE pmc_s_set_dataarray_2d( c lientid, array, array_2 )348 SUBROUTINE pmc_s_set_dataarray_2d( childid, array, array_2 ) 335 349 336 350 IMPLICIT NONE 337 351 338 INTEGER,INTENT(IN) :: c lientid!<352 INTEGER,INTENT(IN) :: childid !< 339 353 340 354 REAL(wp), INTENT(IN), DIMENSION(:,:), POINTER :: array !< … … 355 369 IF ( PRESENT( array_2 ) ) THEN 356 370 second_adr = C_LOC(array_2) 357 CALL pmc_s_setarray( c lientid, nrdims, dims, array_adr,&371 CALL pmc_s_setarray( childid, nrdims, dims, array_adr, & 358 372 second_adr = second_adr) 359 373 ELSE 360 CALL pmc_s_setarray( c lientid, nrdims, dims, array_adr )374 CALL pmc_s_setarray( childid, nrdims, dims, array_adr ) 361 375 ENDIF 362 376 … … 365 379 366 380 367 SUBROUTINE pmc_s_set_dataarray_3d( c lientid, array, nz_cl, nz, array_2 )381 SUBROUTINE pmc_s_set_dataarray_3d( childid, array, nz_cl, nz, array_2 ) 368 382 369 383 IMPLICIT NONE 370 384 371 INTEGER, INTENT(IN) :: c lientid!<385 INTEGER, INTENT(IN) :: childid !< 372 386 INTEGER, INTENT(IN) :: nz !< 373 387 INTEGER, INTENT(IN) :: nz_cl !< … … 381 395 TYPE(C_PTR) :: second_adr !< 382 396 397 ! 383 398 !-- TODO: the next assignment seems to be obsolete. Please check! 384 399 dims = 1 … … 397 412 IF ( PRESENT( array_2 ) ) THEN 398 413 second_adr = C_LOC( array_2 ) 399 CALL pmc_s_setarray( c lientid, nrdims, dims, array_adr,&414 CALL pmc_s_setarray( childid, nrdims, dims, array_adr, & 400 415 second_adr = second_adr) 401 416 ELSE 402 CALL pmc_s_setarray( c lientid, nrdims, dims, array_adr )417 CALL pmc_s_setarray( childid, nrdims, dims, array_adr ) 403 418 ENDIF 404 419 … … 407 422 408 423 409 SUBROUTINE pmc_s_setind_and_allocmem( c lientid )410 411 USE control_parameters, &424 SUBROUTINE pmc_s_setind_and_allocmem( childid ) 425 426 USE control_parameters, & 412 427 ONLY: message_string 413 428 … … 415 430 416 431 ! 417 !-- Naming convention for appendices: _ sc -> server to clienttransfer418 !-- _c s -> client to servertransfer419 !-- send -> server to clienttransfer420 !-- recv -> c lient to servertransfer421 INTEGER, INTENT(IN) :: c lientid!<432 !-- Naming convention for appendices: _pc -> parent to child transfer 433 !-- _cp -> child to parent transfer 434 !-- send -> parent to child transfer 435 !-- recv -> child to parent transfer 436 INTEGER, INTENT(IN) :: childid !< 422 437 423 438 INTEGER :: arlen !< … … 439 454 TYPE(arraydef), POINTER :: ar !< 440 455 441 REAL(wp),DIMENSION(:), POINTER, SAVE :: base_array_ sc !< base array for server to clienttransfer442 REAL(wp),DIMENSION(:), POINTER, SAVE :: base_array_c s !< base array for client to servertransfer443 444 ! 445 !-- Server to clientdirection456 REAL(wp),DIMENSION(:), POINTER, SAVE :: base_array_pc !< base array for parent to child transfer 457 REAL(wp),DIMENSION(:), POINTER, SAVE :: base_array_cp !< base array for child to parent transfer 458 459 ! 460 !-- Parent to child direction 446 461 myindex = 1 447 462 rcount = 0 … … 450 465 ! 451 466 !-- First stride: compute size and set index 452 DO i = 1, c lients(clientid)%inter_npes453 454 ape => c lients(clientid)%pes(i)467 DO i = 1, children(childid)%inter_npes 468 469 ape => children(childid)%pes(i) 455 470 tag = 200 456 471 … … 469 484 tag = tag + 1 470 485 rcount = rcount + 1 471 CALL MPI_ISEND( myindex, 1, MPI_INTEGER, i-1, tag, & 472 clients(clientid)%inter_comm, req(rcount), ierr ) 486 CALL MPI_ISEND( myindex, 1, MPI_INTEGER, i-1, tag, & 487 children(childid)%inter_comm, req(rcount), ierr ) 488 473 489 ! 474 490 !-- Maximum of 1024 outstanding requests 475 !-- TODO: what does this limit mean s?491 !-- TODO: what does this limit mean? 476 492 IF ( rcount == 1024 ) THEN 477 493 CALL MPI_WAITALL( rcount, req, MPI_STATUSES_IGNORE, ierr ) … … 492 508 493 509 ! 494 !-- Create RMA (One Sided Communication) window for data buffer serverto495 !-- c lienttransfer.510 !-- Create RMA (One Sided Communication) window for data buffer parent to 511 !-- child transfer. 496 512 !-- The buffer of MPI_GET (counterpart of transfer) can be PE-local, i.e. 497 513 !-- it can but must not be part of the MPI RMA window. Only one RMA window is 498 514 !-- required to prepare the data for 499 !-- server -> client transfer on the serverside515 !-- parent -> child transfer on the parent side 500 516 !-- and for 501 !-- c lient -> server transfer on the clientside502 CALL pmc_alloc_mem( base_array_ sc, bufsize )503 c lients(clientid)%totalbuffersize = bufsize * wp517 !-- child -> parent transfer on the child side 518 CALL pmc_alloc_mem( base_array_pc, bufsize ) 519 children(childid)%totalbuffersize = bufsize * wp 504 520 505 521 winsize = bufsize * wp 506 CALL MPI_WIN_CREATE( base_array_sc, winsize, wp, MPI_INFO_NULL, & 507 clients(clientid)%intra_comm, & 508 clients(clientid)%win_server_client, ierr ) 522 CALL MPI_WIN_CREATE( base_array_pc, winsize, wp, MPI_INFO_NULL, & 523 children(childid)%intra_comm, & 524 children(childid)%win_parent_child, ierr ) 525 509 526 ! 510 527 !-- Open window to set data 511 CALL MPI_WIN_FENCE( 0, clients(clientid)%win_server_client, ierr ) 528 CALL MPI_WIN_FENCE( 0, children(childid)%win_parent_child, ierr ) 529 512 530 ! 513 531 !-- Second stride: set buffer pointer 514 DO i = 1, c lients(clientid)%inter_npes515 516 ape => c lients(clientid)%pes(i)532 DO i = 1, children(childid)%inter_npes 533 534 ape => children(childid)%pes(i) 517 535 518 536 DO j = 1, ape%nr_arrays 519 537 520 538 ar => ape%array_list(j) 521 ar%sendbuf = C_LOC( base_array_sc(ar%sendindex) ) 522 523 !-- TODO: replace this by standard PALM error message using the message routine 524 IF ( ar%sendindex + ar%sendsize > bufsize ) THEN 525 write(0,'(a,i4,4i7,1x,a)') 'Server Buffer too small ',i, & 526 ar%sendindex,ar%sendsize,ar%sendindex+ar%sendsize,bufsize,trim(ar%name) 527 CALL MPI_Abort (MPI_COMM_WORLD, istat, ierr) 539 ar%sendbuf = C_LOC( base_array_pc(ar%sendindex) ) 540 541 IF ( ar%sendindex + ar%sendsize > bufsize ) THEN 542 WRITE( message_string, '(a,i4,4i7,1x,a)' ) & 543 'Parent buffer too small ',i, & 544 ar%sendindex,ar%sendsize,ar%sendindex+ar%sendsize, & 545 bufsize,trim(ar%name) 546 CALL message( 'pmc_s_setind_and_allocmem', 'PA0429', 3, 2, 0, 6, 0 ) 528 547 ENDIF 529 548 ENDDO … … 531 550 532 551 ! 533 !-- C lient to serverdirection552 !-- Child to parent direction 534 553 bufsize = 8 554 535 555 ! 536 556 !-- First stride: compute size and set index 537 DO i = 1, c lients(clientid)%inter_npes538 539 ape => c lients(clientid)%pes(i)557 DO i = 1, children(childid)%inter_npes 558 559 ape => children(childid)%pes(i) 540 560 tag = 300 541 561 … … 543 563 544 564 ar => ape%array_list(j) 545 ! 546 !-- Receive index from client 565 566 ! 567 !-- Receive index from child 547 568 tag = tag + 1 548 CALL MPI_RECV( myindex, 1, MPI_INTEGER, i-1, tag, &549 c lients(clientid)%inter_comm, MPI_STATUS_IGNORE, ierr )569 CALL MPI_RECV( myindex, 1, MPI_INTEGER, i-1, tag, & 570 children(childid)%inter_comm, MPI_STATUS_IGNORE, ierr ) 550 571 551 572 IF ( ar%nrdims == 3 ) THEN … … 564 585 !-- The buffer for MPI_GET can be PE local, i.e. it can but must not be part of 565 586 !-- the MPI RMA window 566 CALL pmc_alloc_mem( base_array_cs, bufsize, base_ptr ) 567 clients(clientid)%totalbuffersize = bufsize * wp 568 569 CALL MPI_BARRIER( clients(clientid)%intra_comm, ierr ) 587 CALL pmc_alloc_mem( base_array_cp, bufsize, base_ptr ) 588 children(childid)%totalbuffersize = bufsize * wp 589 590 CALL MPI_BARRIER( children(childid)%intra_comm, ierr ) 591 570 592 ! 571 593 !-- Second stride: set buffer pointer 572 DO i = 1, c lients(clientid)%inter_npes573 574 ape => c lients(clientid)%pes(i)594 DO i = 1, children(childid)%inter_npes 595 596 ape => children(childid)%pes(i) 575 597 576 598 DO j = 1, ape%nr_arrays … … 585 607 586 608 587 SUBROUTINE pmc_s_fillbuffer( c lientid, waittime )609 SUBROUTINE pmc_s_fillbuffer( childid, waittime ) 588 610 589 611 IMPLICIT NONE 590 612 591 INTEGER, INTENT(IN) :: c lientid!<613 INTEGER, INTENT(IN) :: childid !< 592 614 593 615 REAL(wp), INTENT(OUT), OPTIONAL :: waittime !< … … 612 634 613 635 ! 614 !-- Synchronization of the model is done in pmci_ client_synchronize and615 !-- pmci_server_synchronize.Therefor the RMA window can be filled without636 !-- Synchronization of the model is done in pmci_synchronize. 637 !-- Therefor the RMA window can be filled without 616 638 !-- sychronization at this point and a barrier is not necessary. 617 639 !-- Please note that waittime has to be set in pmc_s_fillbuffer AND … … 619 641 IF ( PRESENT( waittime) ) THEN 620 642 t1 = pmc_time() 621 CALL MPI_BARRIER( c lients(clientid)%intra_comm, ierr )643 CALL MPI_BARRIER( children(childid)%intra_comm, ierr ) 622 644 t2 = pmc_time() 623 645 waittime = t2- t1 624 646 ENDIF 625 647 626 DO ip = 1, c lients(clientid)%inter_npes627 628 ape => c lients(clientid)%pes(ip)648 DO ip = 1, children(childid)%inter_npes 649 650 ape => children(childid)%pes(ip) 629 651 630 652 DO j = 1, ape%nr_arrays … … 649 671 CALL C_F_POINTER( ar%data, data_3d, ar%a_dim(1:3) ) 650 672 DO ij = 1, ape%nrele 651 buf(myindex:myindex+ar%a_dim(4)-1) = &673 buf(myindex:myindex+ar%a_dim(4)-1) = & 652 674 data_3d(1:ar%a_dim(4),ape%locind(ij)%j,ape%locind(ij)%i) 653 675 myindex = myindex + ar%a_dim(4) … … 659 681 660 682 ENDDO 683 661 684 ! 662 685 !-- Buffer is filled 663 CALL MPI_BARRIER( c lients(clientid)%intra_comm, ierr )686 CALL MPI_BARRIER( children(childid)%intra_comm, ierr ) 664 687 665 688 END SUBROUTINE pmc_s_fillbuffer … … 667 690 668 691 669 SUBROUTINE pmc_s_getdata_from_buffer( c lientid, waittime )692 SUBROUTINE pmc_s_getdata_from_buffer( childid, waittime ) 670 693 671 694 IMPLICIT NONE 672 695 673 INTEGER, INTENT(IN) :: c lientid!<674 REAL(wp), INTENT(OUT), OPTIONAL :: waittime !<675 676 INTEGER :: ierr !<677 INTEGER :: ij !<678 INTEGER :: ip !<679 INTEGER :: istat !<680 INTEGER :: j !<681 INTEGER :: myindex !<682 INTEGER :: nr !<683 INTEGER :: target_pe !<684 INTEGER(kind=MPI_ADDRESS_KIND) :: target_disp !<685 686 INTEGER, DIMENSION(1) :: buf_shape !<696 INTEGER, INTENT(IN) :: childid !< 697 REAL(wp), INTENT(OUT), OPTIONAL :: waittime !< 698 699 INTEGER :: ierr !< 700 INTEGER :: ij !< 701 INTEGER :: ip !< 702 INTEGER :: istat !< 703 INTEGER :: j !< 704 INTEGER :: myindex !< 705 INTEGER :: nr !< 706 INTEGER :: target_pe !< 707 INTEGER(kind=MPI_ADDRESS_KIND) :: target_disp !< 708 709 INTEGER, DIMENSION(1) :: buf_shape !< 687 710 688 711 REAL(wp) :: t1 !< … … 697 720 698 721 t1 = pmc_time() 699 ! 700 !-- Wait for client to fill buffer 701 CALL MPI_BARRIER( clients(clientid)%intra_comm, ierr ) 722 723 ! 724 !-- Wait for child to fill buffer 725 CALL MPI_BARRIER( children(childid)%intra_comm, ierr ) 702 726 t2 = pmc_time() - t1 703 727 IF ( PRESENT( waittime ) ) waittime = t2 728 704 729 ! 705 730 !-- TODO: check next statement 706 731 !-- Fence might do it, test later 707 !-- CALL MPI_WIN_FENCE( 0, c lients(clientid)%win_server_client, ierr)708 CALL MPI_BARRIER( c lients(clientid)%intra_comm, ierr )709 710 DO ip = 1, c lients(clientid)%inter_npes711 712 ape => c lients(clientid)%pes(ip)732 !-- CALL MPI_WIN_FENCE( 0, children(childid)%win_parent_child, ierr) 733 CALL MPI_BARRIER( children(childid)%intra_comm, ierr ) 734 735 DO ip = 1, children(childid)%inter_npes 736 737 ape => children(childid)%pes(ip) 713 738 714 739 DO j = 1, ape%nr_arrays … … 731 756 IF ( nr > 0 ) THEN 732 757 target_disp = ar%recvindex - 1 733 ! 734 !-- Client PEs are located behind server PEs 758 759 ! 760 !-- Child PEs are located behind parent PEs 735 761 target_pe = ip - 1 + m_model_npes 736 CALL MPI_WIN_LOCK( MPI_LOCK_SHARED, target_pe, 0, &737 c lients(clientid)%win_server_client, ierr )738 CALL MPI_GET( buf, nr, MPI_REAL, target_pe, target_disp, nr, &739 MPI_REAL, c lients(clientid)%win_server_client, ierr )740 CALL MPI_WIN_UNLOCK( target_pe, &741 c lients(clientid)%win_server_client, ierr )762 CALL MPI_WIN_LOCK( MPI_LOCK_SHARED, target_pe, 0, & 763 children(childid)%win_parent_child, ierr ) 764 CALL MPI_GET( buf, nr, MPI_REAL, target_pe, target_disp, nr, & 765 MPI_REAL, children(childid)%win_parent_child, ierr ) 766 CALL MPI_WIN_UNLOCK( target_pe, & 767 children(childid)%win_parent_child, ierr ) 742 768 ENDIF 743 769 … … 755 781 CALL C_F_POINTER( ar%data, data_3d, ar%a_dim(1:3)) 756 782 DO ij = 1, ape%nrele 757 data_3d(1:ar%a_dim(4),ape%locind(ij)%j,ape%locind(ij)%i) = &783 data_3d(1:ar%a_dim(4),ape%locind(ij)%j,ape%locind(ij)%i) = & 758 784 buf(myindex:myindex+ar%a_dim(4)-1) 759 785 myindex = myindex + ar%a_dim(4) … … 770 796 771 797 772 SUBROUTINE get_da_names_from_client( clientid ) 773 ! 774 !-- Get data array description and name from client 798 SUBROUTINE get_da_names_from_child( childid ) 799 800 ! 801 !-- Get data array description and name from child 775 802 IMPLICIT NONE 776 803 777 INTEGER, INTENT(IN) :: c lientid !<804 INTEGER, INTENT(IN) :: childid !< 778 805 779 806 TYPE(da_namedef) :: myname !< 780 807 781 808 DO 782 CALL pmc_bcast( myname%couple_index, 0, comm=m_to_c lient_comm(clientid) )809 CALL pmc_bcast( myname%couple_index, 0, comm=m_to_child_comm(childid) ) 783 810 IF ( myname%couple_index == -1 ) EXIT 784 CALL pmc_bcast( myname% serverdesc, 0, comm=m_to_client_comm(clientid) )785 CALL pmc_bcast( myname%nameon server, 0, comm=m_to_client_comm(clientid) )786 CALL pmc_bcast( myname%c lientdesc, 0, comm=m_to_client_comm(clientid) )787 CALL pmc_bcast( myname%nameonc lient, 0, comm=m_to_client_comm(clientid) )788 789 CALL pmc_g_setname( c lients(clientid), myname%couple_index,&790 myname%nameon server)811 CALL pmc_bcast( myname%parentdesc, 0, comm=m_to_child_comm(childid) ) 812 CALL pmc_bcast( myname%nameonparent, 0, comm=m_to_child_comm(childid) ) 813 CALL pmc_bcast( myname%childdesc, 0, comm=m_to_child_comm(childid) ) 814 CALL pmc_bcast( myname%nameonchild, 0, comm=m_to_child_comm(childid) ) 815 816 CALL pmc_g_setname( children(childid), myname%couple_index, & 817 myname%nameonparent ) 791 818 ENDDO 792 819 793 END SUBROUTINE get_da_names_from_client 794 795 796 797 SUBROUTINE pmc_s_setarray(clientid, nrdims, dims, array_adr, second_adr ) 798 ! 799 !-- Set array for client interPE 0 820 END SUBROUTINE get_da_names_from_child 821 822 823 824 SUBROUTINE pmc_s_setarray(childid, nrdims, dims, array_adr, second_adr ) 825 826 ! 827 !-- Set array for child inter PE 0 800 828 IMPLICIT NONE 801 829 802 INTEGER, INTENT(IN) :: c lientid!<803 INTEGER, INTENT(IN) :: nrdims !<804 INTEGER, INTENT(IN), DIMENSION(:) :: dims !<830 INTEGER, INTENT(IN) :: childid !< 831 INTEGER, INTENT(IN) :: nrdims !< 832 INTEGER, INTENT(IN), DIMENSION(:) :: dims !< 805 833 806 834 TYPE(C_PTR), INTENT(IN) :: array_adr !< … … 813 841 814 842 815 DO i = 1, c lients(clientid)%inter_npes816 817 ape => c lients(clientid)%pes(i)843 DO i = 1, children(childid)%inter_npes 844 845 ape => children(childid)%pes(i) 818 846 ar => ape%array_list(next_array_in_list) 819 847 ar%nrdims = nrdims … … 835 863 836 864 837 SUBROUTINE pmc_s_set_active_data_array( c lientid, iactive )865 SUBROUTINE pmc_s_set_active_data_array( childid, iactive ) 838 866 839 867 IMPLICIT NONE 840 868 841 INTEGER, INTENT(IN) :: c lientid!<869 INTEGER, INTENT(IN) :: childid !< 842 870 INTEGER, INTENT(IN) :: iactive !< 843 871 … … 849 877 TYPE(arraydef), POINTER :: ar !< 850 878 851 DO ip = 1, c lients(clientid)%inter_npes852 853 ape => c lients(clientid)%pes(ip)879 DO ip = 1, children(childid)%inter_npes 880 881 ape => children(childid)%pes(ip) 854 882 855 883 DO j = 1, ape%nr_arrays … … 868 896 869 897 870 SUBROUTINE set_pe_index_list( c lientid, myclient, index_list, nrp )898 SUBROUTINE set_pe_index_list( childid, mychild, index_list, nrp ) 871 899 872 900 IMPLICIT NONE 873 901 874 INTEGER, INTENT(IN) :: c lientid!<902 INTEGER, INTENT(IN) :: childid !< 875 903 INTEGER, INTENT(IN), DIMENSION(:,:) :: index_list !< 876 904 INTEGER, INTENT(IN) :: nrp !< 877 905 878 TYPE(c lientdef), INTENT(INOUT) :: myclient!<906 TYPE(childdef), INTENT(INOUT) :: mychild !< 879 907 880 908 INTEGER :: i !< … … 888 916 INTEGER(KIND=MPI_ADDRESS_KIND) :: winsize !< 889 917 890 INTEGER, DIMENSION(myc lient%inter_npes):: remind !<918 INTEGER, DIMENSION(mychild%inter_npes) :: remind !< 891 919 892 920 INTEGER, DIMENSION(:), POINTER :: remindw !< … … 896 924 897 925 ! 898 !-- First, count entries for every remote c lientPE899 DO i = 1, myc lient%inter_npes900 ape => myc lient%pes(i)926 !-- First, count entries for every remote child PE 927 DO i = 1, mychild%inter_npes 928 ape => mychild%pes(i) 901 929 ape%nrele = 0 902 930 ENDDO 931 903 932 ! 904 933 !-- Loop over number of coarse grid cells 905 934 DO j = 1, nrp 906 935 rempe = index_list(5,j) + 1 ! PE number on remote PE 907 ape => myc lient%pes(rempe)908 ape%nrele = ape%nrele + 1 ! Increment number of elements for this clientPE909 ENDDO 910 911 DO i = 1, myc lient%inter_npes912 ape => myc lient%pes(i)936 ape => mychild%pes(rempe) 937 ape%nrele = ape%nrele + 1 ! Increment number of elements for this child PE 938 ENDDO 939 940 DO i = 1, mychild%inter_npes 941 ape => mychild%pes(i) 913 942 ALLOCATE( ape%locind(ape%nrele) ) 914 943 ENDDO … … 921 950 DO j = 1, nrp 922 951 rempe = index_list(5,j) + 1 923 ape => myc lient%pes(rempe)952 ape => mychild%pes(rempe) 924 953 remind(rempe) = remind(rempe)+1 925 954 ind = remind(rempe) … … 927 956 ape%locind(ind)%j = index_list(2,j) 928 957 ENDDO 929 ! 930 !-- Prepare number of elements for client PEs 931 CALL pmc_alloc_mem( rldef, myclient%inter_npes*2 ) 932 ! 933 !-- Number of client PEs * size of INTEGER (i just arbitrary INTEGER) 934 winsize = myclient%inter_npes*c_sizeof(i)*2 935 936 CALL MPI_WIN_CREATE( rldef, winsize, iwp, MPI_INFO_NULL, & 937 myclient%intra_comm, indwin, ierr ) 958 959 ! 960 !-- Prepare number of elements for children PEs 961 CALL pmc_alloc_mem( rldef, mychild%inter_npes*2 ) 962 963 ! 964 !-- Number of child PEs * size of INTEGER (i just arbitrary INTEGER) 965 winsize = mychild%inter_npes*c_sizeof(i)*2 966 967 CALL MPI_WIN_CREATE( rldef, winsize, iwp, MPI_INFO_NULL, & 968 mychild%intra_comm, indwin, ierr ) 969 938 970 ! 939 971 !-- Open window to set data … … 942 974 rldef(1) = 0 ! index on remote PE 0 943 975 rldef(2) = remind(1) ! number of elements on remote PE 0 976 944 977 ! 945 978 !-- Reserve buffer for index array 946 DO i = 2, myc lient%inter_npes979 DO i = 2, mychild%inter_npes 947 980 i2 = (i-1) * 2 + 1 948 981 rldef(i2) = rldef(i2-2) + rldef(i2-1) * 2 ! index on remote PE 949 rldef(i2+1) = remind(i) ! number of elements on remote PE 950 ENDDO 951 ! 952 !-- Close window to allow client to access data 982 rldef(i2+1) = remind(i) ! number of elements on remote PE 983 ENDDO 984 985 ! 986 !-- Close window to allow child to access data 953 987 CALL MPI_WIN_FENCE( 0, indwin, ierr ) 954 ! 955 !-- Client has retrieved data 988 989 ! 990 !-- Child has retrieved data 956 991 CALL MPI_WIN_FENCE( 0, indwin, ierr ) 957 992 958 i2 = 2 * myc lient%inter_npes - 1993 i2 = 2 * mychild%inter_npes - 1 959 994 winsize = ( rldef(i2) + rldef(i2+1) ) * 2 995 960 996 ! 961 997 !-- Make sure, MPI_ALLOC_MEM works … … 965 1001 966 1002 CALL MPI_BARRIER( m_model_comm, ierr ) 967 CALL MPI_WIN_CREATE( remindw, winsize*c_sizeof(i), iwp, MPI_INFO_NULL, &968 myc lient%intra_comm, indwin2, ierr )1003 CALL MPI_WIN_CREATE( remindw, winsize*c_sizeof(i), iwp, MPI_INFO_NULL, & 1004 mychild%intra_comm, indwin2, ierr ) 969 1005 ! 970 1006 !-- Open window to set data 971 1007 CALL MPI_WIN_FENCE( 0, indwin2, ierr ) 1008 972 1009 ! 973 1010 !-- Create the 2D index list 974 1011 DO j = 1, nrp 975 1012 rempe = index_list(5,j) + 1 ! PE number on remote PE 976 ape => myc lient%pes(rempe)1013 ape => mychild%pes(rempe) 977 1014 i2 = rempe * 2 - 1 978 1015 ind = rldef(i2) + 1 … … 981 1018 rldef(i2) = rldef(i2)+2 982 1019 ENDDO 983 ! 984 !-- All data areset 1020 1021 ! 1022 !-- All data are set 985 1023 CALL MPI_WIN_FENCE( 0, indwin2, ierr ) 1024 986 1025 ! 987 1026 !-- Don't know why, but this barrier is necessary before windows can be freed 988 1027 !-- TODO: find out why this is required 989 CALL MPI_BARRIER( myc lient%intra_comm, ierr )1028 CALL MPI_BARRIER( mychild%intra_comm, ierr ) 990 1029 991 1030 CALL MPI_WIN_FREE( indwin, ierr ) 992 1031 CALL MPI_WIN_FREE( indwin2, ierr ) 993 1032 1033 ! 994 1034 !-- TODO: check if the following idea needs to be done 995 1035 !-- Sollte funktionieren, Problem mit MPI implementation … … 1000 1040 1001 1041 #endif 1002 END MODULE pmc_ server1042 END MODULE pmc_parent
Note: See TracChangeset
for help on using the changeset viewer.