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 3248 2011-06-23 13:03:19Z coquart $'
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)%mg_infos )
00429 Nullify ( Grids(i)%reduced_gauss_data%remote_index )
00430 Nullify ( Grids(i)%reduced_gauss_data%nbr_points_per_lat )
00431 Nullify ( Grids(i)%halo )
00432 enddo
00433
00434
00435
00436 Number_of_Masks_allocated = 8
00437
00438 Allocate (Masks(Number_of_Masks_allocated), STAT = ierror)
00439
00440 if ( ierror > 0 ) then
00441 ierrp (1) = ierror
00442 ierrp (2) = Number_of_Masks_allocated
00443
00444 ierror = PRISM_Error_Alloc
00445 call psmile_error ( ierror, 'Masks', &
00446 ierrp, 2, __FILE__, __LINE__ )
00447 return
00448 endif
00449
00450 Masks(:)%status = PSMILe_status_free
00451
00452 do i = 1, Number_of_Masks_allocated
00453 Nullify ( Masks(i)%mask_array )
00454 enddo
00455
00456
00457
00458 Number_of_Fields_allocated = 8
00459
00460 Allocate (Fields(Number_of_Fields_allocated), STAT = ierror)
00461
00462 if ( ierror > 0 ) then
00463 ierrp (1) = ierror
00464 ierrp (2) = Number_of_Fields_allocated
00465
00466 ierror = PRISM_Error_Alloc
00467 call psmile_error ( ierror, 'Fields', &
00468 ierrp, 2, __FILE__, __LINE__ )
00469 return
00470 endif
00471
00472 Fields(:)%status = PSMILe_status_free
00473 Fields(:)%smioc_loc = PRISM_Undefined
00474
00475
00476
00477 Fields(:)%used_for_coupling = .false.
00478
00479
00480
00481 Fields(:)%Taskin%n_recv_direct = 0
00482 Fields(:)%Taskin%n_recv_coupler = 0
00483
00484 Fields(:)%Taskin%n_alloc_recv_direct = 0
00485 Fields(:)%Taskin%n_alloc_recv_coupler = 0
00486
00487 do i = 1, Number_of_Fields_allocated
00488 Nullify ( Fields(i)%io_infos )
00489 Nullify ( Fields(i)%io_chan_infos )
00490 Nullify ( Fields(i)%io_task_lookup )
00491
00492 Nullify ( Fields(i)%Taskout )
00493 Nullify ( Fields(i)%Taskin%recv_direct )
00494 Nullify ( Fields(i)%Taskin%recv_coupler )
00495 Nullify ( Fields(i)%Taskin%buffer_int )
00496 Nullify ( Fields(i)%Taskin%buffer_real )
00497 Nullify ( Fields(i)%Taskin%buffer_dble )
00498 #if defined ( PRISM_QUAD_TYPE )
00499 Nullify ( Fields(i)%Taskin%buffer_quad )
00500 #endif
00501 Nullify ( Fields(i)%Taskin%In_channel )
00502 enddo
00503
00504
00505
00506 Number_of_Cpls_allocated = 0
00507 Nullify (cpl_list)
00508
00509
00510
00511 Number_of_Userdefs_allocated = 8
00512
00513 Allocate (Userdefs(Number_of_Userdefs_allocated), STAT = ierror)
00514
00515 if ( ierror > 0 ) then
00516 ierrp (1) = ierror
00517 ierrp (2) = Number_of_Userdefs_allocated
00518
00519 ierror = PRISM_Error_Alloc
00520 call PSMILe_Error ( ierror, 'Userdefs', &
00521 ierrp, 2, __FILE__, __LINE__ )
00522 return
00523 endif
00524
00525 Userdefs(:)%ig_transi_side = PRISM_Undefined
00526 Userdefs(:)%ig_nb_links = 0
00527 Userdefs(:)%status = PSMILe_status_free
00528
00529
00530 do i = 1, Number_of_Userdefs_allocated
00531 Nullify ( Userdefs(i)%dga_wght )
00532 Nullify ( Userdefs(i)%iga_igl )
00533 Nullify ( Userdefs(i)%real_gridless )
00534 Nullify ( Userdefs(i)%dble_gridless )
00535 enddo
00536
00537
00538
00539
00540
00541 call psmile_def_mpi_compcomm (ierror)
00542 if ( ierror /= 0 ) return
00543
00544
00545
00546
00547
00548
00549
00550
00551 call MPI_Comm_size ( comm_psmile, psmile_size, ierror )
00552
00553 if ( ierror /= MPI_SUCCESS ) then
00554 ierrp (1) = ierror
00555 ierror = PRISM_Error_MPI
00556
00557 call psmile_error ( ierror, 'MPI_Comm_size', &
00558 ierrp, 1, __FILE__, __LINE__ )
00559 return
00560 endif
00561
00562 call MPI_Comm_rank ( comm_psmile, psmile_rank, 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_rank', &
00569 ierrp, 1, __FILE__, __LINE__ )
00570 return
00571 endif
00572
00573 if ( Appl%stand_alone ) then
00574
00575 coupler_rank = PRISM_UNDEFINED
00576
00577 else
00578
00579 call MPI_Comm_rank ( comm_coupler, coupler_rank, ierror )
00580
00581 if ( ierror /= MPI_SUCCESS ) then
00582 ierrp (1) = ierror
00583 ierror = PRISM_Error_MPI
00584
00585 call psmile_error ( ierror, 'MPI_Comm_rank', &
00586 ierrp, 1, __FILE__, __LINE__ )
00587 return
00588 endif
00589
00590 endif
00591
00592 #ifdef DEBUGX
00593
00594
00595
00596 call psmile_attach (psmile_rank)
00597 #endif
00598
00599
00600
00601
00602
00603
00604 call psmile_def_datatypes (ierror)
00605 if ( ierror /= 0 ) return
00606
00607
00608
00609
00610
00611 if ( PRISM_outputLevel > 0 ) then
00612
00613 write( * , 9990 )
00614
00615 if ( MPI_was_initialized ) then
00616 write( * , 9980 ) 'prism_init'
00617 else
00618 write( * , 9980 ) 'application'
00619 endif
00620
00621 write( * , 9990 )
00622
00623 write( * , * ) &
00624 'Sequ.No.: ',Appl%sequence_number,' rank ', Appl%rank,', ',Appl%size,' proc(s).'
00625
00626 endif
00627
00628
00629
00630
00631
00632 if ( .not. Appl%Stand_alone ) then
00633 call MPI_Send (Appl%name, max_name, MPI_CHARACTER, &
00634 PRISMdrv_root, 1, comm_global, ierror)
00635
00636 if (ierror /= MPI_SUCCESS) THEN
00637 ierrp (1) = ierror
00638 ierrp (2) = PRISMdrv_root
00639 ierrp (3) = 1
00640 ierror = PRISM_Error_Send
00641
00642 call psmile_error (ierror, 'MPI_Send', &
00643 ierrp, 3, __FILE__, __LINE__ )
00644 return
00645 endif
00646 endif
00647
00648
00649
00650
00651
00652 index = 0
00653 ipos = 0
00654 if ( Appl%sequence_number > 1 ) then
00655 do k = 1, Appl%sequence_number-1
00656 do j = 1, PRISM_noCompsPerAppl(k)
00657 index = index + PRISM_compRankSets(ipos+j)
00658 enddo
00659 ipos = index
00660 enddo
00661 endif
00662
00663 index = 1
00664 PRISM_noCompsPerProc = 0
00665
00666 do i = 1, PRISM_noCompsPerAppl(Appl%sequence_number)
00667 do j = 1, PRISM_compRankSets(ipos+i)
00668 do k = PRISM_rankSets(ipos+index,1),PRISM_rankSets(ipos+index,2),PRISM_rankSets(ipos+index,3)
00669 if ( Appl%rank == k ) PRISM_noCompsPerProc = PRISM_noCompsPerProc + 1
00670 enddo
00671 index = index + 1
00672 enddo
00673 enddo
00674
00675 if ( .not. Appl%Stand_alone ) then
00676 call MPI_Send (PRISM_noCompsPerProc, 1, MPI_INTEGER, &
00677 PRISMdrv_root, 1, comm_global, ierror)
00678
00679 if (ierror /= MPI_SUCCESS) THEN
00680 ierrp (1) = ierror
00681 ierrp (2) = PRISMdrv_root
00682 ierrp (3) = 1
00683 ierror = PRISM_Error_Send
00684
00685 call psmile_error (ierror, 'MPI_Send', &
00686 ierrp, 3, __FILE__, __LINE__ )
00687 return
00688 endif
00689 endif
00690
00691 #ifdef DEBUG
00692 print *, trim(ch_id), ': prism_init: PRISM_noCompsPerProc ', PRISM_noCompsPerProc
00693 call psmile_flushstd()
00694 #endif
00695
00696
00697
00698
00699
00700 #ifdef __PSMILE_WITH_IO
00701 call psmile_io_init(ierror)
00702 if ( ierror /= 0 ) then
00703 ierrp (1) = ierror
00704 call psmile_error ( ierror, 'PSMILe_IO_Init', &
00705 ierrp, 1, __FILE__, __LINE__ )
00706 endif
00707
00708 #endif
00709
00710 call psmile_flushstd()
00711
00712
00713
00714
00715
00716 call psmile_user_data_init()
00717
00718
00719
00720
00721
00722 PRISM_is_initialized = .true.
00723
00724 #ifdef DEBUG
00725
00726
00727
00728 #if ! defined ( PRISM_with_MPI1 )
00729 call MPI_Comm_set_errhandler (comm_psmile, MPI_ERRORS_RETURN, ierror)
00730 call MPI_Comm_set_errhandler (MPI_COMM_WORLD, MPI_ERRORS_RETURN, ierror)
00731 #else
00732 call MPI_errhandler_set (comm_psmile, MPI_ERRORS_RETURN, ierror)
00733 call MPI_errhandler_set (MPI_COMM_WORLD, MPI_ERRORS_RETURN, ierror)
00734 #endif
00735 #endif
00736
00737 #ifdef VERBOSE
00738 print *, trim(ch_id), ': prism_init: eof ierror =', &
00739 ierror
00740 #endif /* VERBOSE */
00741
00742
00743
00744
00745 8000 format ('] ', a)
00746 9990 format (1x, 44('-'))
00747 9980 format (1x, '--- MPI_Init was called from ', a11, ' ---')
00748
00749 end subroutine prism_init