00001
00002
00003
00004
00005
00006
00007
00008 #ifdef DONT_HAVE_STDMPI2
00009 #define PRISM_with_MPI1
00010 #endif
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 subroutine prism_init ( appl_name, ierror )
00042
00043
00044
00045 use PRISM, dummy_interface => prism_init
00046
00047 use PSMILe
00048
00049 use psmile_user_data, only : psmile_user_data_init
00050
00051 use psmile_timer, only : psmile_timer_init, psmile_timer_start
00052
00053 implicit none
00054
00055
00056
00057 character(len=*), Intent (In) :: appl_name
00058
00059
00060
00061 integer, Intent (Out) :: ierror
00062
00063
00064
00065
00066
00067
00068
00069
00070 integer :: i, j, k, ipos, index
00071 integer :: intercomm
00072 integer :: comp_index
00073
00074 logical :: flag
00075 integer, parameter :: nerrp = 3
00076 integer :: ierrp (nerrp)
00077
00078 integer :: parallel_io
00079 logical :: output_into_file
00080 logical, save :: called
00081
00082 integer :: lenstr
00083
00084 integer :: ndibuf
00085 integer, dimension (:), allocatable :: ibuf
00086
00087 #ifdef PROFILE
00088 character (len=max_name) :: timer_label(2)
00089 #endif
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 Character(len=len_cvs_string), save :: mycvs =
00119 '$Id: prism_init.F90 2846 2011-01-04 12:02:30Z hanke $'
00120
00121
00122
00123 #ifdef VERBOSE
00124 print *, trim(appl_name), ': prism_init: start'
00125 #endif /* VERBOSE */
00126
00127
00128
00129
00130
00131 ierror = 0
00132 intercomm = MPI_COMM_NULL
00133
00134 called = .false.
00135
00136 parallel_io = 1
00137
00138
00139
00140
00141
00142
00143 write (ch_id(1:), '(a4,a)') '[?] ', trim(appl_name)
00144
00145
00146
00147 if (PRISM_is_initialized) then
00148 ierror = PRISM_Warn_Init
00149 ierrp (1) = Appl%sequence_number
00150 call psmile_warning ( ierror, 'PRISM_Init', ierrp, 1, &
00151 __FILE__, __LINE__ )
00152 return
00153 endif
00154
00155
00156
00157 Appl%name=trim(appl_name)
00158 Appl%args=""
00159 Appl%sequence_number=1
00160 Appl%stand_alone = .false.
00161 Appl%comm = MPI_COMM_NULL
00162 Appl%comm_user = MPI_COMM_NULL
00163 Appl%rank = -1
00164
00165
00166
00167 PRISM_calendar_type = PRISM_UNDEFINED
00168
00169
00170
00171 real_pi = atan (1.0) * 4.0
00172 real_pi2 = 2.0 * real_pi
00173 real_pih = real_pi * 0.5
00174 real_deg2rad = real_pi / 180.0
00175
00176 dble_pi = atan (1.0d0) * 4.0d0
00177 dble_pi2 = 2.0d0 * dble_pi
00178 dble_pih = dble_pi * 0.5d0
00179 dble_deg2rad = dble_pi / 180.0d0
00180
00181
00182
00183
00184
00185
00186
00187 call MPI_Initialized ( flag, ierror )
00188
00189 MPI_was_initialized = .not. flag
00190
00191 if (.not. flag) then
00192
00193 call MPI_Init (ierror)
00194
00195 if ( ierror /= MPI_SUCCESS ) then
00196 ierrp (1) = ierror
00197 call psmile_error ( PRISM_Error_MPI, 'MPI_Init', &
00198 ierrp, 1, __FILE__, __LINE__ )
00199 return
00200 endif
00201
00202 endif
00203
00204
00205
00206 call psmile_init_datatypes (ierror)
00207 if (ierror /= 0) return
00208
00209 #if ! defined ( PRISM_with_MPI1 )
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 call MPI_Comm_get_parent ( intercomm, ierror )
00222
00223 if ( ierror /= MPI_SUCCESS ) then
00224 ierrp (1) = ierror
00225 ierror = PRISM_Error_MPI
00226
00227 call psmile_error ( ierror, 'MPI_Comm_get_parent', &
00228 ierrp, 1, __FILE__, __LINE__ )
00229 return
00230 endif
00231
00232 #endif /* not PRISM_with_MPI1 */
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 if ( intercomm == MPI_COMM_NULL ) then
00244
00245 call psmile_init_mpi1 (ierror)
00246
00247 else
00248
00249 Appl%stand_alone = .false.
00250 call psmile_init_mpi2 (intercomm, ierror)
00251
00252 endif
00253
00254 if ( ierror /= 0 ) return
00255
00256
00257
00258
00259 call MPI_OP_CREATE(psmile_ddadd_mpi_callback, .TRUE., PSMILE_MPI_SUMDD, ierror)
00260
00261
00262
00263
00264
00265 output_into_file = PRISM_Redirect(1) == 1
00266
00267 if ( output_into_file .and. .not. called ) then
00268 lenstr = len_trim(Appl%name)
00269 #ifdef NAG_COMPILER
00270 call psmile_redirstdout ( Appl%name(1:lenstr), lenstr, &
00271 parallel_io, Appl%rank, Appl%size, ierror)
00272
00273 #else
00274 ndibuf = lenstr / length_of_integer + 1
00275
00276 Allocate (ibuf(1:ndibuf), STAT = ierror)
00277 if ( ierror > 0 ) then
00278 ierrp (1) = ierror
00279 ierrp (2) = ndibuf
00280 call psmile_error ( PRISM_Error_Alloc, 'ibuf', &
00281 ierrp, 2, __FILE__, __LINE__ )
00282 return
00283 endif
00284
00285 ipos = 0
00286
00287 call psmile_char2buf (ibuf, ndibuf, ipos, Appl%name(1:lenstr))
00288
00289 call psmile_redirstdout ( ibuf, lenstr, &
00290 parallel_io, Appl%rank, Appl%size, ierror)
00291
00292 #endif
00293 called = .true.
00294 else if ( output_into_file .and. called ) then
00295 print *, trim(Appl%name), ' Skipped redirect of stdout for ', trim(Appl%name)
00296 print *, trim(Appl%name), ' Only one redirect per application process is possible.'
00297 else
00298 print *, trim(Appl%name), ' Skipped redirect of stdout for ', trim(Appl%name)
00299 endif
00300
00301
00302
00303
00304
00305 #ifdef PROFILE
00306 timer_label(1) = 'Init to Finalize'
00307 timer_label(2) = 'Init to Enddef'
00308
00309 call psmile_timer_init (2, timer_label, 'Application : ' // TRIM(Appl%name), &
00310 TRIM(Appl%name) // '_timer_stats', Appl%comm)
00311
00312 call psmile_timer_start(1)
00313 call psmile_timer_start(2)
00314 #endif
00315
00316
00317
00318
00319
00320
00321 ch_id = '['
00322 ipos = 1
00323 call psmile_int2char (global_rank, ch_id, ipos)
00324
00325 write (ch_id(ipos+1:), 8000) trim(appl_name)
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 Number_of_Comps_allocated = PRISM_noCompsPerAppl(Appl%sequence_number)
00336
00337 Allocate (Comps(Number_of_Comps_allocated), STAT = ierror)
00338
00339 if ( ierror > 0 ) then
00340 ierrp (1) = ierror
00341 ierrp (2) = Number_of_Comps_allocated
00342 ierror = PRISM_Error_Alloc
00343
00344 call psmile_error ( ierror, 'Components', &
00345 ierrp, 2, __FILE__, __LINE__ )
00346 return
00347 endif
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 Comps(1:Number_of_Comps_allocated)%status = PSMILe_status_free
00359
00360 comp_index = 1
00361 do i = 2, Appl%sequence_number
00362 comp_index = comp_index + PRISM_noCompsPerAppl(i-1)
00363 enddo
00364
00365
00366
00367 Number_of_Methods_allocated = 8
00368
00369 Allocate (Methods(Number_of_Methods_allocated), STAT = ierror)
00370
00371 if ( ierror > 0 ) then
00372 ierrp (1) = ierror
00373 ierrp (2) = Number_of_Methods_allocated
00374
00375 ierror = PRISM_Error_Alloc
00376 call psmile_error ( ierror, 'Methods', &
00377 ierrp, 2, __FILE__, __LINE__ )
00378 return
00379 endif
00380
00381 Methods(:)%status = PSMILe_status_free
00382
00383 do i = 1, Number_of_Methods_allocated
00384 Nullify ( Methods(i)%send_infos_direct )
00385 Nullify ( Methods(i)%send_infos_coupler )
00386 Nullify ( Methods(i)%recv_infos_direct )
00387 Nullify ( Methods(i)%recv_infos_coupler )
00388 Nullify ( Methods(i)%coords_pointer )
00389 Nullify ( Methods(i)%subgrid_pointer )
00390 Nullify ( Methods(i)%vector_pointer )
00391 Nullify ( Methods(i)%halo_pointer )
00392 Nullify ( Methods(i)%gauss2_real(1)%vector)
00393 Nullify ( Methods(i)%gauss2_real(2)%vector)
00394 Nullify ( Methods(i)%gauss2_dble(1)%vector)
00395 Nullify ( Methods(i)%gauss2_dble(2)%vector)
00396 #if defined ( PRISM_QUAD_TYPE )
00397 Nullify ( Methods(i)%gauss2_quad(1)%vector)
00398 Nullify ( Methods(i)%gauss2_quad(2)%vector)
00399 #endif
00400 enddo
00401
00402
00403
00404 Number_of_Grids_allocated = 8
00405
00406 Allocate (Grids(Number_of_Grids_allocated), STAT = ierror)
00407
00408 if ( ierror > 0 ) then
00409 ierrp (1) = ierror
00410 ierrp (2) = Number_of_Grids_allocated
00411
00412 ierror = PRISM_Error_Alloc
00413 call psmile_error ( ierror, 'Grids', &
00414 ierrp, 2, __FILE__, __LINE__ )
00415 return
00416 endif
00417
00418 Grids(:)%status = PSMILe_status_free
00419 Grids(:)%nlev = 0
00420 Grids(:)%nbr_halo_segments = 0
00421 Grids(:)%comp_id = PSMILe_undef
00422
00423 do i = 1, Number_of_Grids_allocated
00424 Nullify ( Grids(i)%corner_pointer )
00425 Nullify ( Grids(i)%partition )
00426 Nullify ( Grids(i)%extent )
00427 Nullify ( Grids(i)%mg_infos )
00428 Nullify ( Grids(i)%nbr_points_per_lat )
00429 Nullify ( Grids(i)%mg_infos )
00430 Nullify ( Grids(i)%send_list )
00431 Nullify ( Grids(i)%recv_list )
00432 Nullify ( Grids(i)%get_list )
00433 Nullify ( Grids(i)%put_list )
00434 Nullify ( Grids(i)%remote_index )
00435 Nullify ( Grids(i)%star )
00436 Nullify ( Grids(i)%face )
00437 Nullify ( Grids(i)%global_beg )
00438 Nullify ( Grids(i)%global_end )
00439 Nullify ( Grids(i)%l2g )
00440 Nullify ( Grids(i)%g2l )
00441 Nullify ( Grids(i)%halo )
00442 enddo
00443
00444
00445
00446 Number_of_Masks_allocated = 8
00447
00448 Allocate (Masks(Number_of_Masks_allocated), STAT = ierror)
00449
00450 if ( ierror > 0 ) then
00451 ierrp (1) = ierror
00452 ierrp (2) = Number_of_Masks_allocated
00453
00454 ierror = PRISM_Error_Alloc
00455 call psmile_error ( ierror, 'Masks', &
00456 ierrp, 2, __FILE__, __LINE__ )
00457 return
00458 endif
00459
00460 Masks(:)%status = PSMILe_status_free
00461
00462 do i = 1, Number_of_Masks_allocated
00463 Nullify ( Masks(i)%mask_array )
00464 enddo
00465
00466
00467
00468 Number_of_Fields_allocated = 8
00469
00470 Allocate (Fields(Number_of_Fields_allocated), STAT = ierror)
00471
00472 if ( ierror > 0 ) then
00473 ierrp (1) = ierror
00474 ierrp (2) = Number_of_Fields_allocated
00475
00476 ierror = PRISM_Error_Alloc
00477 call psmile_error ( ierror, 'Fields', &
00478 ierrp, 2, __FILE__, __LINE__ )
00479 return
00480 endif
00481
00482 Fields(:)%status = PSMILe_status_free
00483 Fields(:)%smioc_loc = PRISM_Undefined
00484
00485
00486
00487 Fields(:)%used_for_coupling = .false.
00488
00489
00490
00491 Fields(:)%Taskin%n_recv_direct = 0
00492 Fields(:)%Taskin%n_recv_coupler = 0
00493
00494 Fields(:)%Taskin%n_alloc_recv_direct = 0
00495 Fields(:)%Taskin%n_alloc_recv_coupler = 0
00496
00497 do i = 1, Number_of_Fields_allocated
00498 Nullify ( Fields(i)%io_infos )
00499 Nullify ( Fields(i)%io_chan_infos )
00500 Nullify ( Fields(i)%io_task_lookup )
00501
00502 Nullify ( Fields(i)%Taskout )
00503 Nullify ( Fields(i)%Taskin%recv_direct )
00504 Nullify ( Fields(i)%Taskin%recv_coupler )
00505 Nullify ( Fields(i)%Taskin%buffer_int )
00506 Nullify ( Fields(i)%Taskin%buffer_real )
00507 Nullify ( Fields(i)%Taskin%buffer_dble )
00508 #if defined ( PRISM_QUAD_TYPE )
00509 Nullify ( Fields(i)%Taskin%buffer_quad )
00510 #endif
00511 Nullify ( Fields(i)%Taskin%Judate_Axis )
00512 Nullify ( Fields(i)%Taskin%In_channel )
00513 enddo
00514
00515
00516
00517 Number_of_Cpls_allocated = 0
00518 Nullify (cpl_list)
00519
00520
00521
00522 Number_of_Userdefs_allocated = 8
00523
00524 Allocate (Userdefs(Number_of_Userdefs_allocated), STAT = ierror)
00525
00526 if ( ierror > 0 ) then
00527 ierrp (1) = ierror
00528 ierrp (2) = Number_of_Userdefs_allocated
00529
00530 ierror = PRISM_Error_Alloc
00531 call PSMILe_Error ( ierror, 'Userdefs', &
00532 ierrp, 2, __FILE__, __LINE__ )
00533 return
00534 endif
00535
00536 Userdefs(:)%ig_transi_side = PRISM_Undefined
00537 Userdefs(:)%ig_nb_links = 0
00538 Userdefs(:)%status = PSMILe_status_free
00539
00540
00541 do i = 1, Number_of_Userdefs_allocated
00542 Nullify ( Userdefs(i)%dga_wght )
00543 Nullify ( Userdefs(i)%iga_igl )
00544 Nullify ( Userdefs(i)%real_gridless )
00545 Nullify ( Userdefs(i)%dble_gridless )
00546 enddo
00547
00548
00549
00550
00551
00552 call psmile_def_mpi_compcomm (ierror)
00553 if ( ierror /= 0 ) return
00554
00555
00556
00557
00558
00559
00560
00561
00562 call MPI_Comm_size ( comm_psmile, psmile_size, ierror )
00563
00564 if ( ierror /= MPI_SUCCESS ) then
00565 ierrp (1) = ierror
00566 ierror = PRISM_Error_MPI
00567
00568 call psmile_error ( ierror, 'MPI_Comm_size', &
00569 ierrp, 1, __FILE__, __LINE__ )
00570 return
00571 endif
00572
00573 call MPI_Comm_rank ( comm_psmile, psmile_rank, ierror )
00574
00575 if ( ierror /= MPI_SUCCESS ) then
00576 ierrp (1) = ierror
00577 ierror = PRISM_Error_MPI
00578
00579 call psmile_error ( ierror, 'MPI_Comm_rank', &
00580 ierrp, 1, __FILE__, __LINE__ )
00581 return
00582 endif
00583
00584 if ( Appl%stand_alone ) then
00585
00586 coupler_rank = PRISM_UNDEFINED
00587
00588 else
00589
00590 call MPI_Comm_rank ( comm_coupler, coupler_rank, ierror )
00591
00592 if ( ierror /= MPI_SUCCESS ) then
00593 ierrp (1) = ierror
00594 ierror = PRISM_Error_MPI
00595
00596 call psmile_error ( ierror, 'MPI_Comm_rank', &
00597 ierrp, 1, __FILE__, __LINE__ )
00598 return
00599 endif
00600
00601 endif
00602
00603 #ifdef DEBUGX
00604
00605
00606
00607 call psmile_attach (psmile_rank)
00608 #endif
00609
00610
00611
00612
00613
00614
00615 call psmile_def_datatypes (ierror)
00616 if ( ierror /= 0 ) return
00617
00618
00619
00620
00621
00622 if ( PRISM_outputLevel > 0 ) then
00623
00624 write( * , 9990 )
00625
00626 if ( MPI_was_initialized ) then
00627 write( * , 9980 ) 'prism_init'
00628 else
00629 write( * , 9980 ) 'application'
00630 endif
00631
00632 write( * , 9990 )
00633
00634 write( * , * ) &
00635 'Sequ.No.: ',Appl%sequence_number,' rank ', Appl%rank,', ',Appl%size,' proc(s).'
00636
00637 endif
00638
00639
00640
00641
00642
00643 if ( .not. Appl%Stand_alone ) then
00644 call MPI_Send (Appl%name, max_name, MPI_CHARACTER, &
00645 PRISMdrv_root, 1, comm_global, ierror)
00646
00647 if (ierror /= MPI_SUCCESS) THEN
00648 ierrp (1) = ierror
00649 ierrp (2) = PRISMdrv_root
00650 ierrp (3) = 1
00651 ierror = PRISM_Error_Send
00652
00653 call psmile_error (ierror, 'MPI_Send', &
00654 ierrp, 3, __FILE__, __LINE__ )
00655 return
00656 endif
00657 endif
00658
00659
00660
00661
00662
00663 index = 0
00664 ipos = 0
00665 if ( Appl%sequence_number > 1 ) then
00666 do k = 1, Appl%sequence_number-1
00667 do j = 1, PRISM_noCompsPerAppl(k)
00668 index = index + PRISM_compRankSets(ipos+j)
00669 enddo
00670 ipos = index
00671 enddo
00672 endif
00673
00674 index = 1
00675 PRISM_noCompsPerProc = 0
00676
00677 do i = 1, PRISM_noCompsPerAppl(Appl%sequence_number)
00678 do j = 1, PRISM_compRankSets(ipos+i)
00679 do k = PRISM_rankSets(ipos+index,1),PRISM_rankSets(ipos+index,2),PRISM_rankSets(ipos+index,3)
00680 if ( Appl%rank == k ) PRISM_noCompsPerProc = PRISM_noCompsPerProc + 1
00681 enddo
00682 index = index + 1
00683 enddo
00684 enddo
00685
00686 if ( .not. Appl%Stand_alone ) then
00687 call MPI_Send (PRISM_noCompsPerProc, 1, MPI_INTEGER, &
00688 PRISMdrv_root, 1, comm_global, ierror)
00689
00690 if (ierror /= MPI_SUCCESS) THEN
00691 ierrp (1) = ierror
00692 ierrp (2) = PRISMdrv_root
00693 ierrp (3) = 1
00694 ierror = PRISM_Error_Send
00695
00696 call psmile_error (ierror, 'MPI_Send', &
00697 ierrp, 3, __FILE__, __LINE__ )
00698 return
00699 endif
00700 endif
00701
00702 #ifdef DEBUG
00703 print *, trim(ch_id), ': prism_init: PRISM_noCompsPerProc ', PRISM_noCompsPerProc
00704 call psmile_flushstd()
00705 #endif
00706
00707
00708
00709
00710
00711 #ifdef __PSMILE_WITH_IO
00712 call psmile_io_init(ierror)
00713 if ( ierror /= 0 ) then
00714 ierrp (1) = ierror
00715 call psmile_error ( ierror, 'PSMILe_IO_Init', &
00716 ierrp, 1, __FILE__, __LINE__ )
00717 endif
00718
00719 #endif
00720
00721 call psmile_flushstd()
00722
00723
00724
00725
00726
00727 call psmile_user_data_init()
00728
00729
00730
00731
00732
00733 PRISM_is_initialized = .true.
00734
00735 #ifdef DEBUG
00736
00737
00738
00739 #if ! defined ( PRISM_with_MPI1 )
00740 call MPI_Comm_set_errhandler (comm_psmile, MPI_ERRORS_RETURN, ierror)
00741 call MPI_Comm_set_errhandler (MPI_COMM_WORLD, MPI_ERRORS_RETURN, ierror)
00742 #else
00743 call MPI_errhandler_set (comm_psmile, MPI_ERRORS_RETURN, ierror)
00744 call MPI_errhandler_set (MPI_COMM_WORLD, MPI_ERRORS_RETURN, ierror)
00745 #endif
00746 #endif
00747
00748 #ifdef VERBOSE
00749 print *, trim(ch_id), ': prism_init: eof ierror =', &
00750 ierror
00751 #endif /* VERBOSE */
00752
00753
00754
00755
00756 8000 format ('] ', a)
00757 9990 format (1x, 44('-'))
00758 9980 format (1x, '--- MPI_Init was called from ', a11, ' ---')
00759
00760 end subroutine prism_init