cf4ocl (C Framework for OpenCL)  v2.1.0
Object-oriented framework for developing and benchmarking OpenCL projects in C/C++
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ccl_plot_events.py (a8a16e7)
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # This file is part of cf4ocl (C Framework for OpenCL).
4 #
5 # cf4ocl is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # cf4ocl is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with cf4ocl. If not, see <http://www.gnu.org/licenses/>.
17 #
18 
19 ## @file
20 # Plots a Gantt-like chart of OpenCL events using the profiling info
21 # exported using the @ref CCL_PROFILER "profiler module".
22 #
23 # @author Nuno Fachada
24 # @date 2016
25 # @copyright [GNU General Public License version 3 (GPLv3)](http://www.gnu.org/licenses/gpl.html)
26 
27 ##
28 # @page ccl_plot_events
29 #
30 # @brief Plots a Gantt-like chart of OpenCL events using the profiling info
31 # exported using the @ref CCL_PROFILER "profiler module".
32 #
33 # SYNOPSIS
34 # ========
35 #
36 # **ccl_plot_events.py** *FILE.TSV*
37 #
38 # DESCRIPTION
39 # ===========
40 #
41 # The `ccl_plot_events` script accepts a single parameter indicating
42 # a file containing profiling info exported using the
43 # @ref CCL_PROFILER "profiler module".
44 #
45 # This script requires a [Python](https://www.python.org/) installation,
46 # and depends on the [Matplotlib](http://matplotlib.org/) and
47 # [NumPy](http://www.numpy.org/) libraries.
48 #
49 # AUTHOR
50 # ======
51 #
52 # Written by Nuno Fachada.
53 #
54 # REPORTING BUGS
55 # ==============
56 #
57 # * Report ccl_plot_events.py bugs at https://github.com/fakenmc/cf4ocl/issues
58 # * cf4ocl home page: http://fakenmc.github.io/cf4ocl/
59 # * cf4ocl wiki: https://github.com/fakenmc/cf4ocl/wiki
60 #
61 # COPYRIGHT
62 # =========
63 #
64 # Copyright (C) 2016 Nuno Fachada<br/>
65 # License GPLv3+: GNU GPL version 3 or later
66 # <http://gnu.org/licenses/gpl.html>.<br/>
67 # This is free software: you are free to change and redistribute it.<br/>
68 # There is NO WARRANTY, to the extent permitted by law.
69 #
70 
71 import sys
72 import os.path
73 import numpy
74 import pylab
75 import matplotlib.pyplot as plt
76 import matplotlib.patches as patches
77 import matplotlib.ticker as ticker
78 
79 # Check command-line arguments
80 if len(sys.argv) < 2:
81  print 'Usage: ' + sys.argv[0] + ' <file.tsv>\n'
82  exit(-1)
83 elif sys.argv[1] == '--version':
84  print 'ccl_plot_events.py v2.0.0\n'
85  exit(0)
86 elif not os.path.isfile(sys.argv[1]):
87  print "File not found: '" + sys.argv[1] + "'\n"
88  exit(-2)
89 
90 
91 # Load profiling info in file given as first cli argument
92 pdat = numpy.genfromtxt(sys.argv[1], delimiter='\t', dtype=None, names=('queue','t_start','t_end','event'))
93 
94 # Get queues
95 queues = numpy.unique(pdat['queue']).tolist()
96 # Determine number of queues
97 num_queues = len(queues)
98 
99 # Create matplotlib figure
100 plt.figure()
101 # Set relative dimensions of plotting area
102 ax = plt.axes([0.1, 0.1, 0.71, 0.8])
103 # Set a vertical grid
104 plt.grid(True, axis='x')
105 # Set axis absolute dimensions of plotting area (depends on profiling info)
106 plt.axis([min(pdat['t_start']), max(pdat['t_end']), -0.5, num_queues - 0.5])
107 # Set ticks to queue names
108 plt.yticks(range(num_queues), queues, size='small')
109 
110 # Determine event names
111 uniq_evts = numpy.unique(pdat['event']).tolist()
112 # Determine number of event names
113 num_uniq_evts = len(uniq_evts)
114 # Associate a different color with each event name
115 cmap = pylab.cm.get_cmap('spectral')
116 uniq_colors = [x*cmap.N/num_uniq_evts for x in range(num_uniq_evts)]
117 
118 # Create legend handles (one for each event name)
119 handles = []
120 for uniq_evt in uniq_evts:
121  # Determine index of current event name
122  uei = uniq_evts.index(uniq_evt)
123  # Get color associated with current event name
124  color = cmap(uniq_colors[uei])
125  # Create a color patch for the legend of the current event name
126  ptch = patches.Patch(edgecolor='black', facecolor=color, linestyle='solid', fill=True)
127  # Add patch to legend handles
128  handles.append(ptch)
129 
130 # Plot events
131 for event in pdat:
132  # Determine plotting locations for current event
133  x = event['t_start']
134  y = queues.index(event['queue']) - 0.4
135  width = event['t_end'] - event['t_start']
136  # Determine index of event name of which current event is an instance of
137  uei = uniq_evts.index(event['event'])
138  # Determine the color for current event (which is the same for the
139  # associated event name)
140  color = cmap(uniq_colors[uei])
141  # Plot event
142  rect = patches.Rectangle((x, y), width, 0.8, edgecolor='none', facecolor=color, fill=True)
143  plt.gca().add_patch(rect)
144 
145 # Add legend
146 plt.legend(handles, uniq_evts, borderaxespad=0, bbox_to_anchor=(1.02, 1), loc=2, prop={'size':'x-small'})
147 
148 # Label axes
149 plt.ylabel('Queues')
150 plt.xlabel('Time')
151 
152 # Show figure
153 plt.show()
154 
155 
156 
157 
158