Merge lp:~albertog/siesta/4.0-json-time into lp:siesta/4.0

Proposed by Alberto Garcia
Status: Merged
Merged at revision: 558
Proposed branch: lp:~albertog/siesta/4.0-json-time
Merge into: lp:siesta/4.0
Diff against target: 173 lines (+79/-12) (has conflicts)
4 files modified
Docs/siesta.tex (+6/-1)
Src/siesta_analysis.F (+4/-0)
Src/timer_tree.f90 (+63/-11)
version.info (+6/-0)
Text conflict in version.info
To merge this branch: bzr merge lp:~albertog/siesta/4.0-json-time
Reviewer Review Type Date Requested Status
Nick Papior Approve
Review via email: mp+337797@code.launchpad.net

Description of the change

When using the tree-timer, a 'time.json' file in JSON format is written.
This file can be used by third-party scripts to process timing data.

Also, add a new intermediate timing section for 'siesta_analysis'.

To post a comment you must log in.
Revision history for this message
Alberto Garcia (albertog) wrote :

I forgot to add that this has been prompted by the need to set up a benchmarking workflow in AiiDA. The Siesta plugin now processes the timing information in the time.json file.

Revision history for this message
Nick Papior (nickpapior) wrote :

I have made a merge request that tries to solve some of the things I have remarked below.

Note they are comments/remarks. I however think the logic is easier by not having two optional arguments.

Revision history for this message
Alberto Garcia (albertog) wrote :
Download full text (4.8 KiB)

Dear Nick,

Thank you for reviewing this.
My comments:

— I did not want to introduce another dependency for m_io. This write operation is very localized in time, so there is no need to reserve
a unit in the way of m_io.
- My json schema is not perfect: the “info nodes: time, calls, and %, are logically also children of the section objects, but conceptually different (they are “leaf info” instead of tree branches. So with a view to a future scripting capability of the json file, I put the “_” in front to clearly mark them as different. This is obviously not fool-proof.
- I agree that we do not need two different optional arguments.

Let me know if you agree, and I will just merge the interface simplification from your changes.

  Best regards,

  Alberto

> On 19 Feb 2018, at 09:21, Nick Papior <email address hidden> wrote:
>
> I have made a merge request that tries to solve some of the things I have remarked below.
>
> Note they are comments/remarks. I however think the logic is easier by not having two optional arguments.
>
> Diff comments:
>
>>
>> === modified file 'Src/timer_tree.f90'
>> --- Src/timer_tree.f90 2016-01-25 16:00:16 +0000
>> +++ Src/timer_tree.f90 2018-02-15 15:48:27 +0000
>> @@ -266,31 +269,71 @@
>> enddo
>> p%data%totTime = globaltime + 1.0e-6_dp
>>
>> + json_output = .true.
>> + call get_unit_number(js_lun)
>> + open(unit=js_lun,file="time.json",form="formatted", &
>> + action="write",position="rewind")
>> +
>> write(*,"(/,a20,T30,a6,a12,a8)") "Section","Calls","Walltime","%"
>> - call walk_tree(p,0)
>>
>> + write(js_lun,*) '{'
>> + call walk_tree(p,0,json=json_output,js_lun=js_lun)
>> + write(js_lun,*) '}'
>> + if (json_output) close(js_lun)
>> +
>> end subroutine timer_report_global
>>
>> !------------------------------------------------
>> - recursive subroutine walk_tree(p,level,maxlevel)
>> + recursive subroutine walk_tree(p,level,maxlevel,json,js_lun)
>> type(section_t), intent(in),target :: p
>> integer, intent(in) :: level
>> integer, intent(in), optional:: maxlevel
>> + logical, intent(in), optional:: json
>> + integer, intent(in), optional:: js_lun
>>
>> integer :: i
>> - character(len=40) fmtstr
>> + character(len=40) fmtstr, fmt_json, fmt_json_head
>> + logical :: json_output
>>
>> + json_output = .false.
>> + if (present(json)) then
>> + json_output = json
>> + if (.not. present(js_lun)) then
>> + call die("Need a js_lun for json timer output")
>> + endif
>> + endif
>> if (present(maxlevel)) then
>> if (level > maxlevel) RETURN
>> endif
>> pd => p%data
>> write(fmtstr,"(a,i0,a1,a)") "(", level+1, "x", ",a20,T30,i6,f12.3,f8.2)"
>> +
>> write(*,fmtstr) pd%name, pd%nCalls, &
>> pd%totTime, 100*pd%totTime/globaltime
>> + if (json_output) then
>> + write(fmt_json,"(a,i0,a1,a)") "(",2*level+1,"x",",a,i0,a,f12.3,a,f8.2)"
>> + write(fmt_json_head,"(a,i0,a)") "(", 2*level+1, "x,a)"
>> + write(js_lun,fmt=fmt_json,advance="no") &
>> + '"' // trim(pd%name) // '": { "_calls": ', pd%nCalls, &
>> ...

Read more...

Revision history for this message
Nick Papior (nickpapior) wrote :

Dear Alberto,

m_io: no worries. I wouldn't mind having that dependency, but your call.
tree vs branch: I see, perhaps we could mark them with "leaf_calls" which clarifies this?

Agreed! ;)

review: Approve
lp:~albertog/siesta/4.0-json-time updated
559. By Alberto Garcia

Use only the presence of json unit as signal to dump JSON

(Thanks to Nick Papior)

We keep the get_unit_number internal routine for now, to avoid
an extra dependency on m_io.

Revision history for this message
Nick Papior (nickpapior) wrote :

@Alberto, should I merge in this branch, or will you?

Revision history for this message
Alberto Garcia (albertog) wrote :

I will merge it shortly.

----- El 20 de Feb 2018, a las 21:15, Nick Rubner Papior <email address hidden> escribió:

| @Alberto, should I merge in this branch, or will you?
| --
| https://code.launchpad.net/~albertog/siesta/4.0-json-time/+merge/337797
| You are the owner of lp:~albertog/siesta/4.0-json-time.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Docs/siesta.tex'
--- Docs/siesta.tex 2017-12-28 13:00:52 +0000
+++ Docs/siesta.tex 2018-02-19 13:31:01 +0000
@@ -6595,7 +6595,12 @@
6595\index{UseTreeTimer@{\bf UseTreeTimer}}6595\index{UseTreeTimer@{\bf UseTreeTimer}}
65966596
6597Enable an experimental timer which is based on wall time on the master6597Enable an experimental timer which is based on wall time on the master
6598node and is aware of the tree-structure of the timed sections.6598node and is aware of the tree-structure of the timed sections. At the
6599end of the program, a report is generated in the output file, and a
6600{\tt time.json} file in JSON format is also
6601written. \index{JSON timing report@{\bf JSON timing report}}
6602This file can be
6603used by third-party scripts to process timing data.
65996604
6600{\it Default value:} {\tt .false.}6605{\it Default value:} {\tt .false.}
66016606
66026607
=== modified file 'Src/siesta_analysis.F'
--- Src/siesta_analysis.F 2017-10-04 09:48:27 +0000
+++ Src/siesta_analysis.F 2018-02-19 13:31:01 +0000
@@ -94,6 +94,8 @@
94 endif94 endif
95 endif95 endif
9696
97 call timer( 'siesta_analysis', 1 )
98
97! All the comments below assume that this compatibility option99! All the comments below assume that this compatibility option
98! is not used.100! is not used.
99! Note also that full compatibility cannot be guaranteed101! Note also that full compatibility cannot be guaranteed
@@ -456,6 +458,8 @@
456! -- Set xa to xa_last at the top of this file. Write any "next iter" coordinate file458! -- Set xa to xa_last at the top of this file. Write any "next iter" coordinate file
457! in 'siesta_move'459! in 'siesta_move'
458460
461 call timer( 'siesta_analysis', 2 )
462
459!--------------------------------------------------------------------------- END463!--------------------------------------------------------------------------- END
460 END subroutine siesta_analysis464 END subroutine siesta_analysis
461 END module m_siesta_analysis465 END module m_siesta_analysis
462466
=== modified file 'Src/timer_tree.f90'
--- Src/timer_tree.f90 2016-01-25 16:00:16 +0000
+++ Src/timer_tree.f90 2018-02-19 13:31:01 +0000
@@ -218,9 +218,10 @@
218 end subroutine timer_all_off218 end subroutine timer_all_off
219219
220 !------------------------------------------------220 !------------------------------------------------
221 subroutine timer_report(secname)221 subroutine timer_report(secname,file_unit)
222 character(len=*), optional :: secname222 character(len=*), optional :: secname
223223 integer, intent(in), optional :: file_unit
224
224 integer :: i, loc225 integer :: i, loc
225 logical :: full226 logical :: full
226227
@@ -253,7 +254,7 @@
253 !------------------------------------------------254 !------------------------------------------------
254 subroutine timer_report_global()255 subroutine timer_report_global()
255256
256 integer :: i257 integer :: i, js_lun
257 type(times_t), pointer :: qd258 type(times_t), pointer :: qd
258259
259 p => global_section260 p => global_section
@@ -266,31 +267,68 @@
266 enddo267 enddo
267 p%data%totTime = globaltime + 1.0e-6_dp268 p%data%totTime = globaltime + 1.0e-6_dp
268269
270 ! Open JSON
271 call get_unit_number(js_lun)
272 open(unit=js_lun, file="time.json", form="formatted", &
273 action="write",position="rewind")
274
269 write(*,"(/,a20,T30,a6,a12,a8)") "Section","Calls","Walltime","%"275 write(*,"(/,a20,T30,a6,a12,a8)") "Section","Calls","Walltime","%"
270 call walk_tree(p,0)276 ! Due to border logic we need this top-level wrapping
271277 write(js_lun,"(a)") "{"
278 call walk_tree(p,0, js_lun=js_lun)
279 write(js_lun,"(a)") "}"
280
281 close(js_lun)
282
272 end subroutine timer_report_global283 end subroutine timer_report_global
273284
274 !------------------------------------------------285 !------------------------------------------------
275 recursive subroutine walk_tree(p,level,maxlevel)286 recursive subroutine walk_tree(p,level,maxlevel,js_lun)
276 type(section_t), intent(in),target :: p287 type(section_t), intent(in),target :: p
277 integer, intent(in) :: level288 integer, intent(in) :: level
278 integer, intent(in), optional:: maxlevel289 integer, intent(in), optional:: maxlevel
290 integer, intent(in), optional:: js_lun
279291
280 integer :: i292 integer :: i
281 character(len=40) fmtstr293 character(len=64) fmtstr, fmt_json, fmt_json_head
294 logical :: json_output
282295
296 ! Determine whether we should output JSON
297 ! If the unit is there, we output to JSON as well
298 json_output = present(js_lun)
299
283 if (present(maxlevel)) then300 if (present(maxlevel)) then
284 if (level > maxlevel) RETURN301 if (level > maxlevel) RETURN
285 endif302 end if
303
286 pd => p%data304 pd => p%data
287 write(fmtstr,"(a,i0,a1,a)") "(", level+1, "x", ",a20,T30,i6,f12.3,f8.2)"305 write(fmtstr,"(a,i0,a1,a)") "(", level+1, "x", ",a20,T30,i6,f12.3,f8.2)"
288 write(*,fmtstr) pd%name, pd%nCalls, &306
289 pd%totTime, 100*pd%totTime/globaltime307 write(*,fmtstr) pd%name, pd%nCalls, pd%totTime, 100*pd%totTime/globaltime
308 if (json_output) then
309 write(fmt_json,"(a,i0,a1,a)") "(",2*level+1,"x",",a,i0,a,f12.3,a,f8.2)"
310 write(fmt_json_head,"(a,i0,a)") "(", 2*level+1, "x,a)"
311 write(js_lun,fmt=fmt_json,advance="no") &
312 '"' // trim(pd%name) // '": { "_calls": ', pd%nCalls, &
313 ', "_time": ', pd%totTime, &
314 ', "_%": ', 100*pd%totTime/globaltime
315 end if
290 if (p%nchildren /= 0) then316 if (p%nchildren /= 0) then
317 if (json_output) write(js_lun,"(a)") ","
291 do i=1,p%nchildren318 do i=1,p%nchildren
292 call walk_tree(p%child(i),level+1,maxlevel)319 call walk_tree(p%child(i),level+1,maxlevel, js_lun)
320 if (json_output) then
321 if (i < p%nchildren) then
322 write(js_lun,fmt="(a)") ','
323 else
324 write(js_lun,*) ! just new line
325 endif
326 endif
293 enddo327 enddo
328 ! End the parent section with an indented '}'
329 if (json_output) write(js_lun,fmt=fmt_json_head,advance="no") "}"
330 else
331 if (json_output) write(js_lun,fmt="(a)",advance="no") "}"
294 endif332 endif
295333
296 end subroutine walk_tree334 end subroutine walk_tree
@@ -353,4 +391,18 @@
353 endif391 endif
354 end subroutine current_time392 end subroutine current_time
355393
394subroutine get_unit_number(lun)
395integer, intent(out) :: lun
396
397logical :: used
398integer :: iostat
399
400do lun= 10, 99
401 inquire(unit=lun, opened=used, iostat=iostat)
402 if (iostat .ne. 0) used = .true.
403 if (.not. used) return
404enddo
405call die("Cannot get unit for timer output")
406end subroutine get_unit_number
407
356end module m_timer_tree408end module m_timer_tree
357409
=== modified file 'version.info'
--- version.info 2018-02-19 08:15:36 +0000
+++ version.info 2018-02-19 13:31:01 +0000
@@ -1,1 +1,7 @@
1<<<<<<< TREE
1siesta-4.0--5572siesta-4.0--557
3=======
4siesta-4.0--555--json-time-4
5
6
7>>>>>>> MERGE-SOURCE

Subscribers

People subscribed via source and target branches