Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SWIFT
SWIFTsim
Commits
50c3c158
Commit
50c3c158
authored
Jan 27, 2016
by
Peter W. Draper
Browse files
Update non-MPI plotting scripts to same level as MPI ones
parent
739438e6
Changes
1
Hide whitespace changes
Inline
Side-by-side
examples/plot_tasks.py
100644 → 100755
View file @
50c3c158
###############################################################################
# This file is part of SWIFT.
# Copyright (c) 2015 Pedro Gonnet (pedro.gonnet@durham.ac.uk),
# Bert Vandenbroucke (bert.vandenbroucke@ugent.be)
# Matthieu Schaller (matthieu.schaller@durham.ac.uk)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
#!/usr/bin/env python
"""
Usage:
plot_tasks.py input.dat output.png [time-range-ms]
where input.dat is a thread info file for a step. Use the '-y interval'
flag of the swift MPI commands to create these. The output plot will be
called 'output.png'. Use the time-range-ms in millisecs to produce
plots with the same time span.
This file is part of SWIFT.
Copyright (c) 2015 Pedro Gonnet (pedro.gonnet@durham.ac.uk),
Bert Vandenbroucke (bert.vandenbroucke@ugent.be)
Matthieu Schaller (matthieu.schaller@durham.ac.uk)
(c) 2016 Peter W. Draper (p.w.draper@durham.ac.uk)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import
matplotlib
import
matplotlib.collections
as
collections
matplotlib
.
use
(
'Agg'
)
import
pylab
as
pl
import
numpy
as
np
import
sys
# CPU ticks per second.
CPU_CLOCK
=
2.7e9
params
=
{
'axes.labelsize'
:
10
,
'axes.titlesize'
:
10
,
'text.fontsize'
:
12
,
'legend.fontsize'
:
12
,
'xtick.labelsize'
:
10
,
'ytick.labelsize'
:
10
,
'text.usetex'
:
True
,
'figure.figsize'
:
(
12.
,
4.
),
'figure.subplot.left'
:
0.03
,
'figure.subplot.right'
:
0.995
,
'figure.subplot.bottom'
:
0.1
,
'figure.subplot.top'
:
0.99
,
'figure.subplot.wspace'
:
0.
,
'figure.subplot.hspace'
:
0.
,
'lines.markersize'
:
6
,
'lines.linewidth'
:
3.
,
'text.latex.unicode'
:
True
}
pl
.
rcParams
.
update
(
params
)
pl
.
rc
(
'font'
,
**
{
'family'
:
'sans-serif'
,
'sans-serif'
:[
'Times'
]})
types
=
{
"0"
:
"task_none"
,
"1"
:
"task_sort"
,
"2"
:
"task_self"
,
"3"
:
"task_pair"
,
"4"
:
"task_sub"
,
"5"
:
"task_ghost"
,
"6"
:
"task_kick1"
,
"7"
:
"task_kick2"
,
"8"
:
"task_send"
,
"9"
:
"task_recv"
,
"10"
:
"task_grav_pp"
,
"11"
:
"task_grav_mm"
,
"12"
:
"task_grav_up"
,
"13"
:
"task_grav_down"
,
"14"
:
"task_psort"
,
"15"
:
"task_split_cell"
,
"16"
:
"task_rewait"
,
"17"
:
"task_count"
}
subtypes
=
{
"0"
:
"subtask_none"
,
"1"
:
"subtask_density"
,
"2"
:
"subtask_force"
,
"3"
:
"subtask_grav"
,
"4"
:
"subtask_count"
}
# Assign colours for all types.
colors
=
[
"red"
,
"blue"
,
"green"
,
"yellow"
,
"cyan"
,
"magenta"
,
"black"
]
colors
=
colors
+
list
(
matplotlib
.
colors
.
cnames
)
index
=
0
subtypecolors
=
{}
for
key
in
subtypes
:
subtypecolors
[
subtypes
[
key
]]
=
colors
[
index
]
print
subtypes
[
key
],
" = "
,
colors
[
index
]
index
=
index
+
1
taskcolors
=
{}
for
key
in
types
:
taskcolors
[
types
[
key
]]
=
colors
[
index
]
print
types
[
key
],
" = "
,
colors
[
index
]
index
=
index
+
1
data
=
pl
.
loadtxt
(
"thread_info.dat"
)
# Basic plot configuration.
PLOT_PARAMS
=
{
"axes.labelsize"
:
10
,
"axes.titlesize"
:
10
,
"font.size"
:
12
,
"legend.fontsize"
:
12
,
"xtick.labelsize"
:
10
,
"ytick.labelsize"
:
10
,
"figure.figsize"
:
(
16.
,
4.
),
"figure.subplot.left"
:
0.03
,
"figure.subplot.right"
:
0.995
,
"figure.subplot.bottom"
:
0.1
,
"figure.subplot.top"
:
0.99
,
"figure.subplot.wspace"
:
0.
,
"figure.subplot.hspace"
:
0.
,
"lines.markersize"
:
6
,
"lines.linewidth"
:
3.
}
pl
.
rcParams
.
update
(
PLOT_PARAMS
)
# Tasks and subtypes. Indexed as in tasks.h.
TASKTYPES
=
[
"none"
,
"sort"
,
"self"
,
"pair"
,
"sub"
,
"ghost"
,
"kick1"
,
"kick2"
,
"send"
,
"recv"
,
"grav_pp"
,
"grav_mm"
,
"grav_up"
,
"grav_down"
,
"psort"
,
"split_cell"
,
"rewait"
,
"count"
]
TASKCOLOURS
=
{
"none"
:
"black"
,
"sort"
:
"lightblue"
,
"self"
:
"greenyellow"
,
"pair"
:
"navy"
,
"sub"
:
"hotpink"
,
"ghost"
:
"cyan"
,
"kick1"
:
"maroon"
,
"kick2"
:
"green"
,
"send"
:
"yellow"
,
"recv"
:
"magenta"
,
"grav_pp"
:
"mediumorchid"
,
"grav_mm"
:
"mediumturquoise"
,
"grav_up"
:
"mediumvioletred"
,
"grav_down"
:
"mediumnightblue"
,
"psort"
:
"steelblue"
,
"split_cell"
:
"seagreen"
,
"rewait"
:
"olive"
,
"count"
:
"powerblue"
}
SUBTYPES
=
[
"none"
,
"density"
,
"force"
,
"grav"
,
"count"
]
SUBCOLOURS
=
{
"none"
:
"black"
,
"density"
:
"red"
,
"force"
:
"blue"
,
"grav"
:
"indigo"
,
"count"
:
"purple"
}
# Show docs if help is requested.
if
len
(
sys
.
argv
)
==
2
and
(
sys
.
argv
[
1
][
0
:
2
]
==
"-h"
or
sys
.
argv
[
1
][
0
:
3
]
==
"--h"
):
from
pydoc
import
help
help
(
"__main__"
)
sys
.
exit
(
0
)
# Handle command-line.
if
len
(
sys
.
argv
)
!=
3
and
len
(
sys
.
argv
)
!=
4
:
print
"Usage: "
,
sys
.
argv
[
0
],
"input.dat output.png [time-range-ms]"
sys
.
exit
(
1
)
infile
=
sys
.
argv
[
1
]
outpng
=
sys
.
argv
[
2
]
delta_t
=
0
if
len
(
sys
.
argv
)
==
4
:
delta_t
=
int
(
sys
.
argv
[
3
])
*
CPU_CLOCK
/
1000
# Read input.
data
=
pl
.
loadtxt
(
infile
)
nthread
=
int
(
max
(
data
[:,
0
]))
+
1
print
"Number of threads:"
,
nthread
tasks
=
{}
tasks
[
-
1
]
=
[]
for
i
in
range
(
nthread
):
tasks
[
i
]
=
[]
# Avoid start and end times of zero.
data
=
data
[
data
[:,
4
]
!=
0
]
data
=
data
[
data
[:,
5
]
!=
0
]
# Calculate the time range, it not given.
if
delta_t
==
0
:
dt
=
max
(
data
[:,
5
])
-
min
(
data
[:,
4
])
if
dt
>
delta_t
:
delta_t
=
dt
# Once more doing the real gather and plots this time.
start_t
=
min
(
data
[:,
4
])
end_t
=
max
(
data
[:,
5
])
data
[:,
4
]
-=
start_t
data
[:,
5
]
-=
start_t
num_lines
=
pl
.
size
(
data
)
/
8
tasks
=
{}
tasks
[
-
1
]
=
[]
for
i
in
range
(
nthread
):
tasks
[
i
]
=
[]
num_lines
=
pl
.
size
(
data
)
/
10
for
line
in
range
(
num_lines
):
thread
=
int
(
data
[
line
,
0
])
tasks
[
thread
].
append
({})
tasks
[
thread
][
-
1
][
"type"
]
=
types
[
str
(
int
(
data
[
line
,
1
]))
]
tasks
[
thread
][
-
1
][
"subtype"
]
=
subtypes
[
str
(
int
(
data
[
line
,
2
]))]
tasks
[
thread
][
-
1
][
"tic"
]
=
int
(
data
[
line
,
4
])
/
CPU_CLOCK
*
1000
tasks
[
thread
][
-
1
][
"toc"
]
=
int
(
data
[
line
,
5
])
/
CPU_CLOCK
*
1000
tasks
[
thread
][
-
1
][
"t"
]
=
(
tasks
[
thread
][
-
1
][
"toc"
]
+
tasks
[
thread
][
-
1
][
"tic"
])
/
2
tasks
[
thread
][
-
1
][
"type"
]
=
TASKTYPES
[
int
(
data
[
line
,
1
])]
tasks
[
thread
][
-
1
][
"subtype"
]
=
SUBTYPES
[
int
(
data
[
line
,
2
])]
tic
=
int
(
data
[
line
,
4
])
/
CPU_CLOCK
*
1000
toc
=
int
(
data
[
line
,
5
])
/
CPU_CLOCK
*
1000
tasks
[
thread
][
-
1
][
"tic"
]
=
tic
tasks
[
thread
][
-
1
][
"toc"
]
=
toc
tasks
[
thread
][
-
1
][
"t"
]
=
(
toc
+
tic
)
/
2
combtasks
=
{}
combtasks
[
-
1
]
=
[]
...
...
@@ -136,22 +162,68 @@ for thread in range(nthread):
combtasks
[
thread
][
-
1
][
"subtype"
]
=
task
[
"subtype"
]
combtasks
[
thread
][
-
1
][
"tic"
]
=
task
[
"tic"
]
combtasks
[
thread
][
-
1
][
"toc"
]
=
task
[
"toc"
]
if
task
[
"type"
]
==
'task_
self
'
or
task
[
"type"
]
==
'task_
pair
'
or
task
[
"type"
]
==
'task_
sub
'
:
combtasks
[
thread
][
-
1
][
"color"
]
=
subtypecolors
[
task
[
"subtype"
]]
if
task
[
"type"
]
==
"
self
"
or
task
[
"type"
]
==
"
pair
"
or
task
[
"type"
]
==
"
sub
"
:
combtasks
[
thread
][
-
1
][
"colo
u
r"
]
=
SUBCOLOURS
[
task
[
"subtype"
]]
else
:
combtasks
[
thread
][
-
1
][
"color"
]
=
taskcolors
[
task
[
"type"
]]
combtasks
[
thread
][
-
1
][
"colo
u
r"
]
=
TASKCOLOURS
[
task
[
"type"
]]
lasttype
=
task
[
"type"
]
else
:
combtasks
[
thread
][
-
1
][
"toc"
]
=
task
[
"toc"
]
typesseen
=
[]
fig
=
pl
.
figure
()
ax
=
fig
.
add_subplot
(
1
,
1
,
1
)
ax
.
set_xlim
(
0
,
delta_t
*
1.03
*
1000
/
CPU_CLOCK
)
ax
.
set_ylim
(
0
,
nthread
)
tictoc
=
np
.
zeros
(
2
)
for
i
in
range
(
nthread
):
for
task
in
combtasks
[
i
]:
pl
.
fill_between
([
task
[
"tic"
],
task
[
"toc"
]],
i
+
0.05
,
i
+
0.95
,
facecolor
=
task
[
"color"
])
pl
.
xlabel
(
"Wall clock time [ms]"
)
pl
.
xlim
(
0
,
(
end_t
-
start_t
)
*
1.03
*
1000
/
CPU_CLOCK
)
pl
.
ylabel
(
"Thread ID"
)
pl
.
yticks
(
pl
.
array
(
range
(
nthread
))
+
0.5
,
pl
.
array
(
range
(
nthread
)))
pl
.
savefig
(
"task_graph.png"
)
# Collect ranges and colours into arrays.
tictocs
=
np
.
zeros
(
len
(
combtasks
[
i
])
*
2
)
colours
=
np
.
empty
(
len
(
combtasks
[
i
])
*
2
,
dtype
=
'object'
)
coloursseen
=
[]
j
=
0
for
task
in
combtasks
[
i
]:
tictocs
[
j
]
=
task
[
"tic"
]
tictocs
[
j
+
1
]
=
task
[
"toc"
]
colours
[
j
]
=
task
[
"colour"
]
colours
[
j
+
1
]
=
task
[
"colour"
]
j
=
j
+
2
if
task
[
"colour"
]
not
in
coloursseen
:
coloursseen
.
append
(
task
[
"colour"
])
# Legend support, collections don't add to this.
if
task
[
"subtype"
]
!=
"none"
:
qtask
=
task
[
"type"
]
+
"/"
+
task
[
"subtype"
]
else
:
qtask
=
task
[
"type"
]
if
qtask
not
in
typesseen
:
pl
.
plot
([],
[],
color
=
task
[
"colour"
],
label
=
qtask
)
typesseen
.
append
(
qtask
)
# Now plot each colour, faster to use a mask to select colour ranges.
for
colour
in
coloursseen
:
collection
=
collections
.
BrokenBarHCollection
.
span_where
(
tictocs
,
ymin
=
i
+
0.05
,
ymax
=
i
+
0.95
,
where
=
colours
==
colour
,
facecolor
=
colour
,
linewidths
=
0
)
ax
.
add_collection
(
collection
)
# Legend and room for it.
nrow
=
len
(
typesseen
)
/
5
if
len
(
typesseen
)
*
5
<
nrow
:
nrow
=
nrow
+
1
ax
.
fill_between
([
0
,
0
],
nthread
+
0.5
,
nthread
+
nrow
+
0.5
,
facecolor
=
"white"
)
ax
.
set_ylim
(
0
,
nthread
+
nrow
+
1
)
ax
.
legend
(
loc
=
1
,
shadow
=
True
,
mode
=
"expand"
,
ncol
=
5
)
ax
.
set_xlabel
(
"Wall clock time [ms]"
)
ax
.
set_ylabel
(
"Thread ID"
)
ax
.
set_yticks
(
pl
.
array
(
range
(
nthread
)),
True
)
pl
.
show
()
pl
.
savefig
(
outpng
)
print
"Graphics done, output written to"
,
outpng
sys
.
exit
(
0
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment