west_environment.f90 13.5 KB
Newer Older
Marco Govoni's avatar
Marco Govoni committed
1
!
Marco Govoni's avatar
Marco Govoni committed
2
! Copyright (C) 2015-2021 M. Govoni 
Marco Govoni's avatar
Marco Govoni committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
! This file is distributed under the terms of the
! GNU General Public License. See the file `License'
! in the root directory of the present distribution,
! or http://www.gnu.org/copyleft/gpl.txt .
!
! This file is part of WEST.
!
! Contributors to this file: 
! Marco Govoni
!
!-----------------------------------------------------------------------
MODULE west_environment
  !-----------------------------------------------------------------------
  !
  USE io_global,       ONLY: stdout, meta_ionode
  !
  IMPLICIT NONE
  !
  SAVE
  !
  PRIVATE
  !
  PUBLIC :: west_environment_start
  PUBLIC :: west_environment_end
  !
  !-----------------------------------------------------------------------
CONTAINS
  !-----------------------------------------------------------------------
  !
  SUBROUTINE west_environment_start( code )
    !
Marco Govoni's avatar
Marco Govoni committed
34
35
36
37
    USE kinds,           ONLY : DP
    USE io_files,        ONLY : crash_file, nd_nmbr
    USE mp_images,       ONLY : me_image, my_image_id, root_image, nimage
    USE westcom,         ONLY : savedir, logfile, outdir, west_prefix 
Govoni's avatar
Govoni committed
38
    USE base64_module,   ONLY : base64_init 
Marco Govoni's avatar
Marco Govoni committed
39
    USE json_string_utilities, ONLY : lowercase_string
40
    USE west_version,    ONLY : start_forpy
Marco Govoni's avatar
Marco Govoni committed
41
    !USE logfile_mod,     ONLY : clear_log
Marco Govoni's avatar
Marco Govoni committed
42
    !
Victor Yu's avatar
Victor Yu committed
43
44
    IMPLICIT NONE
    !
Marco Govoni's avatar
Marco Govoni committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    CHARACTER(LEN=*), INTENT(IN) :: code
    !
    LOGICAL           :: exst, debug = .false.
    CHARACTER(LEN=80) :: uname
    CHARACTER(LEN=6), EXTERNAL :: int_to_char
    INTEGER :: ios, crashunit
    INTEGER, EXTERNAL :: find_free_unit
    !
    ! ... Intel compilers v .ge.8 allocate a lot of stack space
    ! ... Stack limit is often small, thus causing SIGSEGV and crash
    !
#if defined(__INTEL_COMPILER)
    CALL remove_stack_limit ( )
#endif
Marco Govoni's avatar
Marco Govoni committed
59
    CALL start_forpy() 
60
61
62
63
    !
    ! Input from (-i), output from (-o)
    !
    CALL parse_command_arguments()
Marco Govoni's avatar
Marco Govoni committed
64
    CALL fetch_input_yml(1,(/1/),.FALSE.,.FALSE.)
Marco Govoni's avatar
Marco Govoni committed
65
    !
Marco Govoni's avatar
Marco Govoni committed
66
67
68
    savedir = TRIM(ADJUSTL(outdir)) // TRIM(ADJUSTL(west_prefix)) // "." // TRIM(lowercase_string(code)) // ".save/"
    logfile = TRIM(ADJUSTL(savedir)) // TRIM(lowercase_string(code))//".json"
    CALL my_mkdir( TRIM(ADJUSTL(savedir)) ) 
Marco Govoni's avatar
Marco Govoni committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    !
    ! ... use ".FALSE." to disable all clocks except the total cpu time clock
    ! ... use ".TRUE."  to enable clocks
    !
    CALL init_clocks( .TRUE. )
    CALL start_clock( TRIM(code) )
    !
    ! ... for compatibility with PWSCF
    !
#if defined(__MPI)
    nd_nmbr = TRIM ( int_to_char( me_image+1 ))
#else
    nd_nmbr = ' '
#endif
    !
    IF( meta_ionode ) THEN
       !
       ! ...  search for file CRASH and delete it
       !
       INQUIRE( FILE=TRIM(crash_file), EXIST=exst )
       IF( exst ) THEN
          crashunit = find_free_unit()
          OPEN( UNIT=crashunit, FILE=TRIM(crash_file), STATUS='OLD',IOSTAT=ios )
          IF (ios==0) THEN
             CLOSE( UNIT=crashunit, STATUS='DELETE', IOSTAT=ios )
          ELSE
             WRITE(stdout,'(5x,"Remark: CRASH file could not be deleted")')
          END IF
       END IF
       !
    ELSE
       ! ... one processor per image (other than meta_ionode)
       ! ... or, for debugging purposes, all processors,
       ! ... open their own standard output file
#if defined(DEBUG)
       debug = .true.
#endif
       IF (debug ) THEN
          uname = 'out.' // trim(int_to_char( my_image_id )) // '_' // &
               trim(int_to_char( me_image))
          OPEN ( unit = stdout, file = TRIM(uname),status='unknown')
       ELSE
#if defined(_WIN32)
          OPEN ( unit = stdout, file='NUL:', status='unknown' )
#else
          OPEN ( unit = stdout, file='/dev/null', status='unknown' )
#endif
       END IF
       !
    END IF
    !
Govoni's avatar
Govoni committed
120
    ! Initialize base64 tables  
121
    CALL base64_init()
Govoni's avatar
Govoni committed
122
    !
Marco Govoni's avatar
Marco Govoni committed
123
    !CALL clear_log()
Marco Govoni's avatar
Marco Govoni committed
124
125
126
127
128
129
    CALL west_opening_message( code )
#if defined(__MPI)
    CALL report_parallel_status ( )
#else
    CALL errore(TRIM(code), 'West need MPI to run', 1 ) 
#endif
Govoni's avatar
Govoni committed
130
    !
Marco Govoni's avatar
Marco Govoni committed
131
132
133
134
  END SUBROUTINE
  !
  !
  SUBROUTINE west_environment_end( code )
Marco Govoni's avatar
Marco Govoni committed
135
136
    !
    USE json_module,     ONLY : json_file
Marco Govoni's avatar
Marco Govoni committed
137
138
    USE mp_world,        ONLY : mpime,root,world_comm
    USE mp,              ONLY : mp_barrier
Marco Govoni's avatar
Marco Govoni committed
139
    USE westcom,         ONLY : logfile 
140
    USE west_version,    ONLY : end_forpy
Marco Govoni's avatar
Marco Govoni committed
141
142
    !
    IMPLICIT NONE 
Marco Govoni's avatar
Marco Govoni committed
143
144
    !
    CHARACTER(LEN=*), INTENT(IN) :: code
Marco Govoni's avatar
Marco Govoni committed
145
146
147
148
    INTEGER :: iunit
    TYPE(json_file) :: json 
    CHARACTER(LEN=9)  :: cdate, ctime
    CHARACTER(LEN=80) :: time_str
Marco Govoni's avatar
Marco Govoni committed
149
    LOGICAL :: found
Marco Govoni's avatar
Marco Govoni committed
150
151
152
153
154
155
    !
    IF ( meta_ionode ) WRITE( stdout, * )
    !
    CALL stop_clock(  TRIM(code) )
    CALL print_clock( TRIM(code) )
    !
Marco Govoni's avatar
Marco Govoni committed
156
157
158
159
160
161
162
163
164
    CALL date_and_tim( cdate, ctime )
    !
    time_str = 'This run was terminated on:  ' // ctime // ' ' // cdate
    !
    IF( meta_ionode ) THEN
       WRITE( stdout,*)
       WRITE( stdout,3334) time_str
       WRITE( stdout,3335)
    END IF
Marco Govoni's avatar
Marco Govoni committed
165
166
167
168
169
    !
    IF( meta_ionode ) THEN
       WRITE( stdout,'(A)')      '   JOB DONE.'
       WRITE( stdout,3335)
    END IF
Marco Govoni's avatar
Marco Govoni committed
170
3334 FORMAT(3X,A60,/)
Marco Govoni's avatar
Marco Govoni committed
171
172
173
3335 FORMAT('=',78('-'),'=')
    FLUSH(stdout)
    !
Marco Govoni's avatar
Marco Govoni committed
174
175
176
    IF( mpime == root ) THEN
      !
      CALL json%initialize()
Victor Yu's avatar
Victor Yu committed
177
      CALL json%load(filename=TRIM(logfile))
Marco Govoni's avatar
Marco Govoni committed
178
      !
Govoni's avatar
Govoni committed
179
180
181
      CALL json%update('runjob.completed', .TRUE., found)
      CALL json%add('runjob.endtime', TRIM(ctime) )
      CALL json%add('runjob.enddate', TRIM(cdate) )
Marco Govoni's avatar
Marco Govoni committed
182
183
      !
      OPEN( NEWUNIT=iunit,FILE=TRIM(logfile) )
Victor Yu's avatar
Victor Yu committed
184
      CALL json%print( iunit )
Marco Govoni's avatar
Marco Govoni committed
185
186
187
188
      CLOSE( iunit )
      !
      CALL json%destroy()
      !
Marco Govoni's avatar
Marco Govoni committed
189
190
    ENDIF
    !
191
192
    CALL end_forpy()
    !
Marco Govoni's avatar
Marco Govoni committed
193
    CALL mp_barrier(world_comm) 
Marco Govoni's avatar
Marco Govoni committed
194
    !
Marco Govoni's avatar
Marco Govoni committed
195
196
197
198
199
200
  END SUBROUTINE
  !
  !
  !
  SUBROUTINE west_opening_message( code )
    !
Marco Govoni's avatar
Marco Govoni committed
201
    USE json_module,     ONLY : json_file
Marco Govoni's avatar
Marco Govoni committed
202
203
    USE io_global,       ONLY : stdout
    USE global_version,  ONLY : version_number, svn_revision
204
    USE west_version,    ONLY : west_version_number, west_git_revision
205
    USE mp_world,        ONLY : mpime,root 
Marco Govoni's avatar
Marco Govoni committed
206
    USE westcom,         ONLY : logfile
Govoni's avatar
Govoni committed
207
    USE base64_module,   ONLY : islittleendian  
Marco Govoni's avatar
Marco Govoni committed
208
    USE forpy_mod,        ONLY : dict, dict_create 
Marco Govoni's avatar
Marco Govoni committed
209
    !USE logfile_mod,      ONLY : append_log, itoa, ltoa, dtoa
Marco Govoni's avatar
Marco Govoni committed
210
    !
Victor Yu's avatar
Victor Yu committed
211
212
    IMPLICIT NONE
    !
Marco Govoni's avatar
Marco Govoni committed
213
214
215
216
217
218
    ! I/O
    !
    CHARACTER(LEN=*), INTENT(IN) :: code
    !
    ! Workspace
    !
Marco Govoni's avatar
Marco Govoni committed
219
220
    TYPE(json_file) :: json
    INTEGER :: iunit
Marco Govoni's avatar
Marco Govoni committed
221
222
    CHARACTER(LEN=9)  :: cdate, ctime
    !
Marco Govoni's avatar
Marco Govoni committed
223
224
225
226
    INTEGER :: IERR
    CHARACTER(LEN=:),ALLOCATABLE :: s
    TYPE(dict) :: attr
    !
Marco Govoni's avatar
Marco Govoni committed
227
228
    CALL date_and_tim( cdate, ctime )
    !
229
230
231
    IF ( TRIM (west_git_revision) /= "unknown" ) THEN
       WRITE( stdout, '(/5X,"Program ",A," v. ",A," git rev. ",A," starts on ",A9," at ",A9)' ) &
       & TRIM(code), TRIM(west_version_number), TRIM (west_git_revision), cdate, ctime
Marco Govoni's avatar
Marco Govoni committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    ELSE
       WRITE( stdout, '(/5X,"Program ",A," v. ",A," starts on ",A9," at ",A9)' ) &
       & TRIM(code), TRIM(west_version_number), cdate, ctime
    ENDIF
    !
    WRITE( stdout, '(/5X,"This program is part of the open-source West suite",&
    &/5X,"for massively parallel calculations of excited states in materials; please cite", &
    &/9X,"""M. Govoni et al., J. Chem. Theory Comput. 11, 2680 (2015);",&
    &/9X," URL http://www.west-code.org"", ", &
    &/5X,"in publications or presentations arising from this work.")' ) 
    !
    IF ( TRIM (svn_revision) /= "unknown" ) THEN 
       WRITE( stdout, '(/5X,"Based on the Quantum ESPRESSO v. ",A," svn rev. ",A)') TRIM (version_number), TRIM (svn_revision)
    ELSE
       WRITE( stdout, '(/5X,"Based on the Quantum ESPRESSO v. ",A)') TRIM (version_number)
    ENDIF
    !
Govoni's avatar
Govoni committed
249
250
    IF( islittleendian() ) THEN 
       WRITE( stdout, '(/5X,"I/O is Little Endian",A)') "" 
Govoni's avatar
Govoni committed
251
    ELSE
Govoni's avatar
Govoni committed
252
       WRITE( stdout, '(/5X,"I/O is Big Endian",A)') ""
Govoni's avatar
Govoni committed
253
254
    ENDIF 
    !
255
    IF( mpime == root ) THEN 
Marco Govoni's avatar
Marco Govoni committed
256
257
      ! 
      CALL json%initialize()
Marco Govoni's avatar
Marco Govoni committed
258
      !
Marco Govoni's avatar
Marco Govoni committed
259
260
261
262
263
264
265
266
267
268
269
270
      CALL json%add('runjob.startdate', TRIM(cdate) )
      CALL json%add('runjob.starttime', TRIM(ctime) )
      CALL json%add('runjob.completed', .FALSE. )
      CALL json%add('software.package', "WEST" )
      CALL json%add('software.program', TRIM(code) )
      CALL json%add('software.version', TRIM(west_version_number) )
      IF( TRIM (west_git_revision) /= "unknown" ) CALL json%add('software.westgit', TRIM(west_git_revision) )
      CALL json%add('software.website',"http://www.west-code.org")
      CALL json%add('software.citation',"M. Govoni et al., J. Chem. Theory Comput. 11, 2680 (2015).")
      CALL json%add('software.qeversion', TRIM(version_number) )
      IF( TRIM (svn_revision) /= "unknown" ) CALL json%add('software.qesvn', TRIM(svn_revision) )
      CALL json%add('config.io.islittleendian', islittleendian() )
Marco Govoni's avatar
Marco Govoni committed
271
      !
Marco Govoni's avatar
Marco Govoni committed
272
      OPEN( NEWUNIT=iunit, FILE=TRIM(logfile) )
Victor Yu's avatar
Victor Yu committed
273
      CALL json%print( iunit )
Marco Govoni's avatar
Marco Govoni committed
274
      CLOSE( iunit )
Marco Govoni's avatar
Marco Govoni committed
275
      !
Marco Govoni's avatar
Marco Govoni committed
276
      CALL json%destroy()
Marco Govoni's avatar
Marco Govoni committed
277
      !
Marco Govoni's avatar
Marco Govoni committed
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
      !s = '{ '
      !s = s // '"startdate" : '   //'"'//TRIM(cdate) //'" , '
      !s = s // '"startime" : '    //'"'//TRIM(ctime)     //'" , '
      !s = s // '"package" : '     //'"WEST"'          //' , '
      !s = s // '"program" : '     //'"'//TRIM(code)      //'" , '
      !s = s // '"version" : '     //'"'//TRIM(west_version_number) //'" , '
      !IF( TRIM (west_git_revision) /= "unknown" ) THEN
      !   s = s // '"git_version" : ' //'"'//TRIM(west_git_revision) //'" , '
      !ENDIF
      !s = s // '"website" : '     //'"http://www.west-code.org"' //' , '
      !s = s // '"citation" : '    //'"M. Govoni et al., J. Chem. Theory Comput. 11, 2680 (2015)."' //' , '
      !s = s // '"website" : '     //'"http://www.west-code.org"' //' , '
      !s = s // '"qeversion" : '     //'"'//TRIM(version_number) //'" , '
      !s = s // '"islittleendian" : ' //ltoa(islittleendian()) //'   '
      !s = s // '}'
      !!
      !IERR = dict_create(attr)
      !IERR = attr%setitem("type", "intro" )
      !!
      !CALL append_log( s, attr )
      !!
      !CALL attr%destroy
Marco Govoni's avatar
Marco Govoni committed
300
      !
301
302
    ENDIF 
    !
Marco Govoni's avatar
Marco Govoni committed
303
304
305
306
307
308
309
310
311
  END SUBROUTINE 
  !
  !
  !
  SUBROUTINE report_parallel_status()
     !-----------------------------------------------------------------------
     !
     ! ... Report the mpi/openmp status
     !
Marco Govoni's avatar
Marco Govoni committed
312
     USE json_module,      ONLY : json_file
Marco Govoni's avatar
Marco Govoni committed
313
314
     USE io_global,        ONLY : stdout
     USE mp_global,        ONLY : nimage,npool,nbgrp,nproc_image,nproc_pool,nproc_bgrp 
315
     USE mp_world,         ONLY : nproc,mpime,root 
Marco Govoni's avatar
Marco Govoni committed
316
     USE io_push,          ONLY : io_push_title,io_push_bar
Marco Govoni's avatar
Marco Govoni committed
317
     USE forpy_mod,        ONLY : dict, dict_create 
Marco Govoni's avatar
Marco Govoni committed
318
319
     USE westcom,          ONLY : logfile
     !USE logfile_mod,      ONLY : append_log, itoa
Marco Govoni's avatar
Marco Govoni committed
320
321
322
323
324
325
326
327
     !
     IMPLICIT NONE
     !
#if defined(__OPENMP)
     INTEGER, EXTERNAL :: omp_get_max_threads
#endif
     !
     INTEGER :: nth, ncores 
Marco Govoni's avatar
Marco Govoni committed
328
329
     TYPE(json_file) :: json
     INTEGER :: iunit
Marco Govoni's avatar
Marco Govoni committed
330
331
332
333
     !
     INTEGER :: IERR
     CHARACTER(LEN=:),ALLOCATABLE :: s
     TYPE(dict) :: attr
Marco Govoni's avatar
Marco Govoni committed
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
     !
#if defined(__OPENMP)
     nth = omp_get_max_threads()
#else
     nth = 1
#endif
     ncores = nproc * nth
     !
     CALL io_push_title('**MPI** Parallelization Status')
     WRITE(stdout, "(5x, '   ',i14,'      ',4i14)") nproc, nimage, npool, nbgrp, nproc_bgrp
     CALL io_push_bar()
     WRITE(stdout, "(5x, '                N         =         I      X      P      X      B      X      Z')") 
     WRITE(stdout, "(5x, '                ^                   ^             ^             ^             ^')") 
     WRITE(stdout, "(5x, '                |                   |             |             |             |')") 
     WRITE(stdout, "(5x, '              #rnk                  |             |             |             |')") 
     WRITE(stdout, "(5x, '                                 #image           |             |             |')") 
     WRITE(stdout, "(5x, '                                                #pool           |             |')") 
     WRITE(stdout, "(5x, '                                                              #bgrp           |')") 
     WRITE(stdout, "(5x, '                                                                            #R&G')") 
     CALL io_push_bar()
     !
#if defined(__OPENMP)
     WRITE(stdout, "(5x, '**OPENMP** Parallelization Status')")
     WRITE(stdout, "(5x, '#thr/rnk               = ',i12)") nth
     CALL io_push_bar()
     WRITE(stdout, "(5x, '#prc = (rnk) * (thr) = ',i12)") ncores
     CALL io_push_bar()
#else
     WRITE(stdout, "(5x, '#prc = ',i12)") ncores
     CALL io_push_bar()
#endif
365
    !
Marco Govoni's avatar
Marco Govoni committed
366
367
368
    IF( mpime == root ) THEN
       !
       CALL json%initialize()
369
       !
Victor Yu's avatar
Victor Yu committed
370
       CALL json%load(filename=TRIM(logfile))
Marco Govoni's avatar
Marco Govoni committed
371
372
373
374
375
376
377
       !
       CALL json%add('parallel.nranks', nproc )
       CALL json%add('parallel.nimage', nimage )
       CALL json%add('parallel.npool', npool )
       CALL json%add('parallel.nbgrp', nbgrp )
       CALL json%add('parallel.nrg', nproc_bgrp )
       CALL json%add('parallel.nproc', ncores )
378
#if defined(__OPENMP)
Marco Govoni's avatar
Marco Govoni committed
379
       CALL json%add('parallel.nthreads', nth )
380
381
#endif
       !
Marco Govoni's avatar
Marco Govoni committed
382
       OPEN( NEWUNIT=iunit,FILE=TRIM(logfile) )
Victor Yu's avatar
Victor Yu committed
383
       CALL json%print( iunit )
Marco Govoni's avatar
Marco Govoni committed
384
       CLOSE( iunit )
385
       !
Marco Govoni's avatar
Marco Govoni committed
386
       CALL json%destroy()
387
       !
Marco Govoni's avatar
Marco Govoni committed
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
!       !
!       s = '{ '
!       s = s // '"nranks" : '   //ITOA(nproc)      //' , '
!       s = s // '"nimage" : '   //ITOA(nimage)     //' , '
!       s = s // '"nimage" : '   //ITOA(nimage)     //' , '
!       s = s // '"npool" : '    //ITOA(npool)      //' , '
!       s = s // '"nbgrp" : '    //ITOA(nbgrp)      //' , '
!       s = s // '"nrg" : '      //ITOA(nproc_bgrp) //' , '
!#if defined(__OPENMP)
!       s = s // '"nthreads" : ' //ITOA(nth)        //' , '
!#endif
!       s = s // '"nproc" : '    //ITOA(ncores)     //'   '
!       s = s // '}'
!       !
!       IERR = dict_create(attr)
!       IERR = attr%setitem("type", "parallel" )
!       !
!       CALL append_log( s, attr )
!       !
!       CALL attr%destroy
!       !
409
    ENDIF 
Marco Govoni's avatar
Marco Govoni committed
410
411
412
413
     !
  END SUBROUTINE
  !
END MODULE