00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_init_mpi1 (ierror)
00012
00013
00014
00015
00016 use PRISM_constants
00017 use PSMILe, dummy_interface => PSMILe_Init_MPI1
00018 use PSMILe_SCC, only : get_execution_mode, get_dates, &
00019 get_appli_details, get_applicomp_details, get_applicomprk_detls, &
00020 close_scc_file, open_scc_file
00021
00022 implicit none
00023
00024
00025
00026 integer, Intent (Out) :: ierror
00027
00028
00029
00030
00031
00032
00033
00034 integer :: index, il_myint
00035 integer :: global_size
00036 integer, parameter :: ndibuf = 3
00037 integer :: ibuf (ndibuf)
00038
00039 integer, parameter :: nerrp = 2
00040 integer :: ierrp (nerrp)
00041
00042 integer, dimension(15) :: idate
00043 double precision, dimension(3) :: ddate
00044
00045 Type(PRISM_Time_Struct) :: tdate
00046 INTEGER :: noHosts(0:1), noArgs(0:1)
00047
00048 integer, parameter :: rank_dummy = huge(il_myint)
00049
00050 integer, allocatable :: appl_redirect(:)
00051 character (len=max_name) :: cpatch(0:1)
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 character(len=len_cvs_string), save :: mycvs =
00075 '$Id: psmile_init_mpi1.F90 2687 2010-10-28 15:15:52Z coquart $'
00076
00077
00078
00079 #ifdef VERBOSE
00080 print *, trim(ch_id), ': PSMILe_Init_MPI1: start'
00081 #endif /* VERBOSE */
00082
00083
00084
00085
00086
00087 call MPI_Allreduce ( rank_dummy, PRISMdrv_root, 1, MPI_Integer, MPI_MIN, MPI_COMM_WORLD, ierror )
00088
00089 if ( ierror /= MPI_SUCCESS ) then
00090 ierrp (1) = ierror
00091 ierror = PRISM_Error_MPI
00092
00093 call psmile_error ( ierror, 'MPI_Allreduce', &
00094 ierrp, 1, __FILE__, __LINE__ )
00095 return
00096 endif
00097
00098
00099 if ( PRISMdrv_root == rank_dummy ) then
00100
00101 PRISMdrv_root = 0
00102 endif
00103
00104
00105
00106
00107 call MPI_Comm_dup ( MPI_COMM_WORLD, comm_global, ierror )
00108
00109 if ( ierror /= MPI_SUCCESS ) then
00110 ierrp (1) = ierror
00111 ierror = PRISM_Error_MPI
00112
00113 call psmile_error ( ierror, 'MPI_Comm_dup', &
00114 ierrp, 1, __FILE__, __LINE__ )
00115 return
00116 endif
00117
00118 call MPI_Comm_rank ( comm_global, global_rank, ierror )
00119
00120 if ( ierror /= MPI_SUCCESS ) then
00121 ierrp (1) = ierror
00122 ierror = PRISM_Error_MPI
00123
00124 call psmile_error ( ierror, 'MPI_Comm_rank', &
00125 ierrp, 1, __FILE__, __LINE__ )
00126 return
00127 endif
00128
00129 call MPI_Comm_size ( comm_global, global_size, ierror )
00130
00131 if ( ierror /= MPI_SUCCESS ) then
00132 ierrp (1) = ierror
00133 ierror = PRISM_Error_MPI
00134
00135 call psmile_error ( ierror, 'MPI_Comm_size', &
00136 ierrp, 1, __FILE__, __LINE__ )
00137 return
00138 endif
00139
00140
00141
00142 call MPI_Comm_dup (comm_global, comm_trans, ierror)
00143
00144 if ( ierror /= MPI_SUCCESS ) then
00145 ierrp (1) = ierror
00146 ierror = PRISM_Error_MPI
00147
00148 call psmile_error ( ierror, 'MPI_Comm_dup', &
00149 ierrp, 1, __FILE__, __LINE__ )
00150 return
00151 endif
00152
00153
00154
00155
00156
00157
00158 call MPI_Allreduce (PSMILe_latest_protocol_version, protocol_version, &
00159 1, MPI_Integer, MPI_MIN, comm_global, &
00160 ierror)
00161
00162 if ( ierror /= MPI_SUCCESS ) then
00163 ierrp (1) = ierror
00164 ierror = PRISM_Error_MPI
00165
00166 call psmile_error ( ierror, 'MPI_Allreduce', &
00167 ierrp, 1, __FILE__, __LINE__ )
00168 return
00169 endif
00170
00171 if ( protocol_version < PSMILe_latest_protocol_version) then
00172
00173 write (*, 9990) protocol_version, PSMILe_latest_protocol_version
00174 call psmile_assert ( __FILE__, __LINE__, &
00175 'impossible protocol versions computed')
00176
00177 9990 format (/1x, 'PSMILe_Init_MPI1: protocol_version =', i7, &
00178 '; latest =', i7)
00179 endif
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 if (global_rank == PRISMdrv_root) then
00191
00192
00193
00194 noApplication = 1
00195
00196
00197
00198
00199 noComponents = 1
00200
00201 ibuf (1) = noApplication
00202 ibuf (2) = noComponents
00203 ibuf (3) = 1
00204 endif
00205
00206 call MPI_Bcast( ibuf, ndibuf, MPI_Integer, &
00207 PRISMdrv_root, comm_global, ierror )
00208
00209 if ( ierror /= MPI_SUCCESS ) then
00210 ierrp (1) = ierror
00211 ierror = PRISM_Error_MPI
00212
00213 call psmile_error ( ierror, 'MPI_Bcast', &
00214 ierrp, 1, __FILE__, __LINE__ )
00215 return
00216 endif
00217
00218 noApplication = ibuf (1)
00219 noComponents = ibuf (2)
00220 Appl%stand_alone = ibuf (3) .eq. 1
00221
00222 #ifdef PRISM_ASSERTION
00223 if ( noApplication < 1 ) then
00224 call psmile_assert ( __FILE__, __LINE__, &
00225 'Number of Application should be > 0!')
00226 endif
00227
00228 if ( noComponents < noApplication ) then
00229 call psmile_assert ( __FILE__, __LINE__, &
00230 'Number of Components should be >= Number of Applications!')
00231 endif
00232
00233 if ( ibuf(3) < 0 .or. ibuf (3) > 1 ) then
00234 call psmile_assert ( __FILE__, __LINE__, &
00235 'Stand alone flag should be 0 or 1!')
00236 endif
00237 #endif
00238
00239 if ( Appl%stand_alone ) then
00240 print *, trim(ch_id), ': PSMILe_Init_MPI1: Assuming stand alone run!'
00241 endif
00242
00243
00244
00245 Allocate (PRISM_applProc (0:noApplication), STAT = ierror)
00246
00247 if ( ierror > 0 ) then
00248 ierrp (1) = ierror
00249 ierrp (2) = noApplication + 1
00250
00251 ierror = PRISM_Error_Alloc
00252 call psmile_error ( ierror, 'PRISM_applProc', &
00253 ierrp, 2, __FILE__, __LINE__ )
00254 return
00255 endif
00256
00257 Allocate (PRISM_applName (0:noApplication), STAT = ierror)
00258
00259 if ( ierror > 0 ) then
00260 ierrp (1) = ierror
00261 ierrp (2) = noApplication + 1
00262
00263 ierror = PRISM_Error_Alloc
00264 call psmile_error ( ierror, 'PRISM_applName', &
00265 ierrp, 2, __FILE__, __LINE__ )
00266 return
00267 endif
00268
00269 PRISM_applName(:) = ' '
00270
00271
00272
00273 if ( Appl%stand_alone ) then
00274
00275 PRISM_applProc(0) = 0
00276 PRISM_applProc(1) = global_size
00277
00278 PRISM_applName(0) = 'Stand alone'
00279 PRISM_applName(1) = trim(Appl%name)
00280
00281
00282
00283
00284 call open_scc_file (ierror)
00285
00286
00287
00288 call get_execution_mode (ierror, ierror)
00289
00290
00291
00292
00293 call get_dates (PRISM_initial_date, tdate, &
00294 PRISM_Jobstart_date, PRISM_Jobend_date, ierror)
00295
00296
00297
00298
00299 Allocate (PRISM_noCompsPerAppl (0:1), STAT = ierror)
00300
00301 if ( ierror > 0 ) then
00302 ierrp (1) = ierror
00303 ierrp (2) = 1
00304
00305 ierror = PRISM_Error_Alloc
00306 call psmile_error ( ierror, 'PRISM_noCompsPerAppl', &
00307 ierrp, 2, __FILE__, __LINE__ )
00308 return
00309 endif
00310
00311 call get_appli_details ( 1, PRISM_applName, cpatch, &
00312 noHosts, PRISM_Redirect, &
00313 PRISM_noCompsPerAppl, &
00314 noArgs, ierror )
00315
00316
00317
00318 Allocate (PRISM_compName (1:PRISM_noCompsPerAppl(1)), STAT = ierror)
00319
00320 if ( ierror > 0 ) then
00321 ierrp (1) = ierror
00322 ierrp (2) = PRISM_noCompsPerAppl(1)
00323
00324 ierror = PRISM_Error_Alloc
00325 call psmile_error ( ierror, 'PRISM_compName', &
00326 ierrp, 2, __FILE__, __LINE__ )
00327 return
00328 endif
00329
00330 Allocate(PRISM_compRankSets(1:PRISM_noCompsPerAppl(1)), STAT = ierror)
00331
00332 if ( ierror > 0 ) then
00333 ierrp (1) = ierror
00334 ierrp (2) = PRISM_noCompsPerAppl(1)
00335
00336 ierror = PRISM_Error_Alloc
00337 call psmile_error ( ierror, 'PRISM_compRankSets', &
00338 ierrp, 2, __FILE__, __LINE__ )
00339 return
00340 endif
00341
00342 call get_applicomp_details ( 1, PRISM_noCompsPerAppl(1), &
00343 PRISM_compName, PRISM_compRankSets, ierror)
00344
00345
00346
00347
00348 noRanksets = sum(PRISM_compRankSets(:))
00349 Allocate (PRISM_rankSets (noRanksets,3), STAT = ierror)
00350
00351 if ( ierror > 0 ) then
00352 ierrp (1) = ierror
00353 ierrp (2) = noRanksets
00354
00355 ierror = PRISM_Error_Alloc
00356 call psmile_error ( ierror, 'PRISM_rankSets', &
00357 ierrp, 2, __FILE__, __LINE__ )
00358 return
00359 endif
00360
00361 call get_applicomprk_detls ( 1, noRanksets, &
00362 PRISM_rankSets, ierror)
00363
00364 do index = 1, noRanksets
00365 PRISM_rankSets(index,3) = max(1,PRISM_rankSets(index,3))
00366 PRISM_rankSets(index,2) = max(PRISM_rankSets(index,1),PRISM_rankSets(index,2))
00367 enddo
00368
00369 index = 1
00370
00371
00372 call close_scc_file ()
00373
00374 else
00375
00376
00377
00378
00379
00380
00381 Allocate (PRISM_noCompsPerAppl (0:noApplication), STAT = ierror)
00382
00383 if ( ierror > 0 ) then
00384 ierrp (1) = ierror
00385 ierrp (2) = noApplication
00386
00387 ierror = PRISM_Error_Alloc
00388 call psmile_error ( ierror, 'PRISM_noCompsPerAppl', &
00389 ierrp, 2, __FILE__, __LINE__ )
00390 return
00391 endif
00392
00393 Allocate (PRISM_compName (1:noComponents), STAT = ierror)
00394
00395 if ( ierror > 0 ) then
00396 ierrp (1) = ierror
00397 ierrp (2) = noComponents
00398
00399 ierror = PRISM_Error_Alloc
00400 call psmile_error ( ierror, 'PRISM_compName', &
00401 ierrp, 2, __FILE__, __LINE__ )
00402 return
00403 endif
00404
00405
00406
00407
00408
00409
00410
00411
00412 call MPI_Bcast( PRISM_applProc(0), noApplication+1, MPI_Integer, &
00413 PRISMdrv_root, comm_global, ierror )
00414
00415 if ( ierror /= MPI_SUCCESS ) then
00416 ierrp (1) = ierror
00417 ierror = PRISM_Error_MPI
00418 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00419 __FILE__, __LINE__ )
00420 return
00421 endif
00422
00423 #ifdef PRISM_ASSERTION
00424 if ( PRISM_applProc(0) < 1 ) then
00425 call psmile_assert ( __FILE__, __LINE__, &
00426 'Coupler should be assigned to at least 1 processor!')
00427 endif
00428
00429 if ( noApplication < 1 ) then
00430 call psmile_assert ( __FILE__, __LINE__, &
00431 'Number of Application should be > 0!')
00432 endif
00433 #endif
00434
00435
00436
00437
00438
00439
00440
00441
00442 call MPI_Bcast( PRISM_applName(0), (noApplication+1)*max_name, &
00443 MPI_Character, &
00444 PRISMdrv_root, comm_global, ierror )
00445
00446 if ( ierror /= MPI_SUCCESS ) then
00447 ierrp (1) = ierror
00448 ierror = PRISM_Error_MPI
00449 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00450 __FILE__, __LINE__ )
00451 return
00452 endif
00453
00454
00455
00456
00457
00458
00459
00460 #ifdef VERBOSE
00461 do index = 1, noApplication
00462 print *, trim(ch_id), ': ', index, &
00463 'name of the application: ', trim(Appl%name)
00464 print *, trim(ch_id), ': ', index, &
00465 'compared to name given in PMIOD: ', trim(PRISM_applName(index))
00466 enddo
00467 #endif
00468 index = 1
00469
00470 do while ((trim(Appl%name) /= trim(PRISM_applName(index))) &
00471 .and. index <= noApplication)
00472 index = index + 1
00473 enddo
00474
00475 if ( index > noApplication ) then
00476 ierrp (1) = noApplication
00477 ierrp (2) = index
00478
00479 call PSMILe_Error ( ierror, Appl%name, ierrp, 2, &
00480 __FILE__, __LINE__ )
00481 return
00482 endif
00483
00484 Appl%sequence_number = index
00485
00486
00487
00488 call MPI_Bcast( PRISM_compName(1), noComponents*max_name, &
00489 MPI_Character, &
00490 PRISMdrv_root, comm_global, ierror )
00491
00492 if ( ierror /= MPI_SUCCESS ) then
00493 ierrp (1) = ierror
00494 ierror = PRISM_Error_MPI
00495 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00496 __FILE__, __LINE__ )
00497 return
00498 endif
00499
00500
00501
00502 call MPI_Bcast( PRISM_noCompsPerAppl(1), noApplication, &
00503 MPI_Integer, &
00504 PRISMdrv_root, comm_global, ierror )
00505
00506 if ( ierror /= MPI_SUCCESS ) then
00507 ierrp (1) = ierror
00508 ierror = PRISM_Error_MPI
00509 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00510 __FILE__, __LINE__ )
00511 return
00512 endif
00513
00514
00515
00516
00517
00518 Allocate (PRISM_compRankSets (1:noComponents), STAT = ierror)
00519
00520 if ( ierror > 0 ) then
00521 ierrp (1) = ierror
00522 ierrp (2) = noComponents
00523
00524 ierror = PRISM_Error_Alloc
00525 call psmile_error ( ierror, 'PRISM_compRankSets', &
00526 ierrp, 2, __FILE__, __LINE__ )
00527 return
00528 endif
00529
00530 call MPI_Bcast( PRISM_compRankSets(1), noComponents, &
00531 MPI_Integer, &
00532 PRISMdrv_root, comm_global, ierror )
00533
00534 if ( ierror /= MPI_SUCCESS ) then
00535 ierrp (1) = ierror
00536 ierror = PRISM_Error_MPI
00537 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00538 __FILE__, __LINE__ )
00539 return
00540 endif
00541
00542 noRanksets = sum(PRISM_compRankSets(:))
00543 Allocate (PRISM_rankSets (noRanksets,3), STAT = ierror)
00544
00545 if ( ierror > 0 ) then
00546 ierrp (1) = ierror
00547 ierrp (2) = noRanksets
00548
00549 ierror = PRISM_Error_Alloc
00550 call psmile_error ( ierror, 'PRISM_rankSets', &
00551 ierrp, 2, __FILE__, __LINE__ )
00552 return
00553 endif
00554
00555 call MPI_Bcast( PRISM_rankSets(1,1), noRanksets*3, &
00556 MPI_Integer, &
00557 PRISMdrv_root, comm_global, ierror )
00558
00559 if ( ierror /= MPI_SUCCESS ) then
00560 ierrp (1) = ierror
00561 ierror = PRISM_Error_MPI
00562 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00563 __FILE__, __LINE__ )
00564 return
00565 endif
00566
00567
00568
00569 Allocate ( appl_redirect(noApplication), STAT = ierror)
00570 if ( ierror > 0 ) then
00571 ierrp (1) = ierror
00572 ierrp (2) = noApplication
00573 ierror = PRISM_Error_Alloc
00574 call psmile_error ( ierror, 'appl_redirect', &
00575 ierrp, 2, __FILE__, __LINE__ )
00576 return
00577 endif
00578
00579 call MPI_Bcast( appl_redirect, noApplication, &
00580 MPI_Integer, PRISMdrv_root, comm_global, ierror )
00581
00582 if ( ierror /= MPI_SUCCESS ) then
00583 ierrp (1) = ierror
00584 ierror = PRISM_Error_MPI
00585 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00586 __FILE__, __LINE__ )
00587 return
00588 endif
00589
00590 PRISM_Redirect(1) = appl_redirect(Appl%sequence_number)
00591
00592 Deallocate ( appl_redirect, STAT = ierror)
00593 if ( ierror > 0 ) then
00594 ierrp (1) = ierror
00595 ierrp (2) = noApplication
00596 ierror = PRISM_Error_Dealloc
00597 call psmile_error ( ierror, 'appl_redirect', &
00598 ierrp, 2, __FILE__, __LINE__ )
00599 return
00600 endif
00601
00602 endif
00603
00604
00605
00606
00607
00608
00609
00610 if ( PRISM_noCompsPerAppl(index) > 1 .and. PRISM_comp_init ) then
00611 ierror = PRISM_Error_InitApp
00612 ierrp (1) = PRISM_noCompsPerAppl(index)
00613 call psmile_error ( ierror, 'Explicit call to PRISM_Init required', &
00614 ierrp, 1, __FILE__, __LINE__ )
00615 return
00616 endif
00617
00618
00619
00620 call psmile_def_mpi_comm (ierror)
00621 if (ierror /= 0) return
00622
00623 if ( PRISM_ApplProc(index) /= Appl%size ) then
00624
00625 ierror = PRISM_Error_InitApp
00626 ierrp (1) = PRISM_ApplProc(index)
00627 ierrp (2) = Appl%size
00628
00629 call psmile_error ( ierror, &
00630 'Inconsistent mpirun command and scc.xml', ierrp, 2, &
00631 __FILE__, __LINE__ )
00632 return
00633 endif
00634
00635 if ( .not. Appl%stand_alone ) then
00636
00637
00638
00639
00640
00641
00642 call MPI_Bcast( idate(1), 15, &
00643 MPI_Integer, PRISMdrv_root, comm_global, ierror )
00644
00645 if ( ierror /= MPI_SUCCESS ) then
00646 ierrp (1) = ierror
00647 ierror = PRISM_Error_MPI
00648 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00649 __FILE__, __LINE__ )
00650 return
00651 endif
00652
00653 call MPI_Bcast( ddate(1), 3, &
00654 MPI_Double_Precision, PRISMdrv_root, comm_global, ierror )
00655
00656 if ( ierror /= MPI_SUCCESS ) then
00657 ierrp (1) = ierror
00658 ierror = PRISM_Error_MPI
00659 call psmile_error ( ierror, 'MPI_Bcast', ierrp, 1, &
00660 __FILE__, __LINE__ )
00661 return
00662 endif
00663
00664 PRISM_Jobstart_date%year = idate(1)
00665 PRISM_Jobstart_date%month = idate(2)
00666 PRISM_Jobstart_date%day = idate(3)
00667 PRISM_Jobstart_date%hour = idate(4)
00668 PRISM_Jobstart_date%minute = idate(5)
00669 PRISM_Jobstart_date%second = ddate(1)
00670
00671 PRISM_Jobend_date%year = idate(6)
00672 PRISM_Jobend_date%month = idate(7)
00673 PRISM_Jobend_date%day = idate(8)
00674 PRISM_Jobend_date%hour = idate(9)
00675 PRISM_Jobend_date%minute = idate(10)
00676 PRISM_Jobend_date%second = ddate(2)
00677
00678 PRISM_initial_date%year = idate(11)
00679 PRISM_initial_date%month = idate(12)
00680 PRISM_initial_date%day = idate(13)
00681 PRISM_initial_date%hour = idate(14)
00682 PRISM_initial_date%minute = idate(15)
00683 PRISM_initial_date%second = ddate(3)
00684
00685 endif
00686
00687
00688
00689 ierror = 0
00690
00691 #ifdef VERBOSE
00692 print *, trim(ch_id), ': PSMILe_Init_MPI1: eof ierror =', ierror
00693 #endif /* VERBOSE */
00694
00695 end subroutine PSMILe_Init_MPI1