starpu_paje_summary.Rmd 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. # StarPU --- Runtime system for heterogeneous multicore architectures.
  2. #
  3. # Copyright (C) 2017 CNRS
  4. # Copyright (C) 2014 Université de Bordeaux
  5. # Copyright (C) 2016 Inria
  6. #
  7. # StarPU is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU Lesser General Public License as published by
  9. # the Free Software Foundation; either version 2.1 of the License, or (at
  10. # your option) any later version.
  11. #
  12. # StarPU is distributed in the hope that it will be useful, but
  13. # WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. #
  16. # See the GNU Lesser General Public License in COPYING.LGPL for more details.
  17. #
  18. <div id="table-of-contents">
  19. <h2>Table of Contents</h2>
  20. <div id="text-table-of-contents">
  21. <ul>
  22. <li><a href="#sec-1">1. Introduction</a>
  23. <ul>
  24. <li>
  25. <ul>
  26. <li><a href="#sec-1-0-1">1.0.1. How to compile</a></li>
  27. <li><a href="#sec-1-0-2">1.0.2. Software dependencies</a></li>
  28. </ul>
  29. </li>
  30. </ul>
  31. </li>
  32. <li><a href="#sec-2">2. Gantt Charts of the whole Trace</a></li>
  33. <li><a href="#sec-3">3. Table Summary</a></li>
  34. <li><a href="#sec-4">4. State Duration during the Execution Time</a></li>
  35. <li><a href="#sec-5">5. Distribution Histograms</a></li>
  36. </ul>
  37. </div>
  38. </div>
  39. ```{r Setup, echo=FALSE}
  40. opts_chunk$set(echo=FALSE)
  41. ```
  42. ```{r Install_R_libraries}
  43. InstalledPackage <- function(package)
  44. {
  45. available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE)))
  46. missing <- package[!available]
  47. if (length(missing) > 0) return(FALSE)
  48. return(TRUE)
  49. }
  50. CRANChoosen <- function()
  51. {
  52. return(getOption("repos")["CRAN"] != "@CRAN@")
  53. }
  54. UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org")
  55. {
  56. if(!InstalledPackage(package))
  57. {
  58. if(!CRANChoosen())
  59. {
  60. chooseCRANmirror()
  61. if(!CRANChoosen())
  62. {
  63. options(repos = c(CRAN = defaultCRANmirror))
  64. }
  65. }
  66. suppressMessages(suppressWarnings(install.packages(package)))
  67. if(!InstalledPackage(package)) return(FALSE)
  68. }
  69. return(TRUE)
  70. }
  71. # Now install desired libraries
  72. libraries <- c("ggplot2", "plyr", "data.table", "RColorBrewer")
  73. for(libr in libraries)
  74. {
  75. if(!UsePackage(libr))
  76. {
  77. stop("Error!", libr)
  78. }
  79. }
  80. ```
  81. ```{r Load_R_files}
  82. # Load ggplot and plyr just for the following cases
  83. library(ggplot2)
  84. library(plyr)
  85. library(data.table)
  86. library(RColorBrewer)
  87. # Defining non-computation states:
  88. def_states<-c("Initializing","Deinitializing","Overhead","Nothing","Sleeping","Freeing","Allocating","WritingBack","FetchingInput","PushingOutput","Callback","Progressing","Unpartitioning","AllocatingReuse","Reclaiming","DriverCopy","DriverCopyAsync","Scheduling","Executing")
  89. # Function for reading .csv file
  90. read_df <- function(file,range1,range2) {
  91. df<-read.csv(file, header=FALSE, strip.white=TRUE)
  92. names(df) <- c("Nature","ResourceId","Type","Start","End","Duration", "Depth", "Value")
  93. df = df[!(names(df) %in% c("Nature","Type", "Depth"))]
  94. df$Origin<-as.factor(as.character(file))
  95. # Changing names if needed:
  96. df$Value <- as.character(df$Value)
  97. df$Value <- ifelse(df$Value == "F", "Freeing", as.character(df$Value))
  98. df$Value <- ifelse(df$Value == "A", "Allocating", as.character(df$Value))
  99. df$Value <- ifelse(df$Value == "W", "WritingBack", as.character(df$Value))
  100. df$Value <- ifelse(df$Value == "No", "Nothing", as.character(df$Value))
  101. df$Value <- ifelse(df$Value == "I", "Initializing", as.character(df$Value))
  102. df$Value <- ifelse(df$Value == "D", "Deinitializing", as.character(df$Value))
  103. df$Value <- ifelse(df$Value == "Fi", "FetchingInput", as.character(df$Value))
  104. df$Value <- ifelse(df$Value == "Po", "PushingOutput", as.character(df$Value))
  105. df$Value <- ifelse(df$Value == "C", "Callback", as.character(df$Value))
  106. df$Value <- ifelse(df$Value == "B", "Overhead", as.character(df$Value))
  107. df$Value <- ifelse(df$Value == "Sc", "Scheduling", as.character(df$Value))
  108. df$Value <- ifelse(df$Value == "E", "Executing", as.character(df$Value))
  109. df$Value <- ifelse(df$Value == "Sl", "Sleeping", as.character(df$Value))
  110. df$Value <- ifelse(df$Value == "P", "Progressing", as.character(df$Value))
  111. df$Value <- ifelse(df$Value == "U", "Unpartitioning", as.character(df$Value))
  112. df$Value <- ifelse(df$Value == "Ar", "AllocatingReuse", as.character(df$Value))
  113. df$Value <- ifelse(df$Value == "R", "Reclaiming", as.character(df$Value))
  114. df$Value <- ifelse(df$Value == "Co", "DriverCopy", as.character(df$Value))
  115. df$Value <- ifelse(df$Value == "CoA", "DriverCopyAsync", as.character(df$Value))
  116. # Small cleanup
  117. df$Start<-round(df$Start,digit=1)
  118. df$End<-round(df$End,digit=1)
  119. df$ResourceId<-as.factor(df$ResourceId)
  120. df$Value<-as.factor(df$Value)
  121. # Start from zero
  122. m <- min(df$Start)
  123. df$Start <- df$Start - m
  124. df$End <- df$Start+df$Duration
  125. # Return data frame
  126. df
  127. }
  128. ```
  129. ```{r Load_traces}
  130. df<-data.frame()
  131. if( !exists("input_traces") )
  132. input_traces<-c("example.native.trace.csv", "example.simgrid.trace.csv")
  133. for (i in 1:length(input_traces)){
  134. dfs<-read_df(input_traces[i])
  135. df<-rbindlist(list(df,dfs))
  136. }
  137. # Color palettes
  138. colourCount = length(unique(df$Value))
  139. getPalette = colorRampPalette(brewer.pal(9, "Set1"))
  140. # Order of Value so we can have good colors
  141. ker_states<-as.character(unique(df[!(df$Value %in% def_states),Value]))
  142. ordered_states<-append(sort(ker_states), def_states)
  143. df$Value <- factor(df$Value, levels=ordered_states)
  144. # Order of ResourceId so we can have y-axis
  145. df$ResourceId <- factor(df$ResourceId, levels=sort(as.character(unique(df$ResourceId))))
  146. ```
  147. # Introduction
  148. This document presents a basic analysis of multiple StarPU
  149. traces. First, paje *traces* will be transferred into *.csv* files and
  150. then we analyze them with **R**. This summary is a first step that
  151. should help researchers verify their hypothesis or find problematic
  152. areas that require more exhaustive investigation.
  153. Be cautious, as the following results are only a brief analysis of
  154. the traces and many important phenomena could still be hidden. Also,
  155. be very careful when comparing different states or traces. Even
  156. though some large discrepancies can be irrelevant, in other cases
  157. even the smallest differences can be essential in understanding what
  158. exactly happened during the StarPU execution.
  159. ### How to compile
  160. ./starpu_summary.sh example.native.trace example.simgrid.trace
  161. ### Software dependencies
  162. In order to run this analysis you need to have R installed:
  163. sudo apt-get install r-base
  164. Easiest way to transform *paje* traces generated by StarPU to *.csv* is to use *pjdump* program (<https://github.com/schnorr/pajeng>), so we encourage users to install it.
  165. When R is installed, one will need to start R (e.g., from terminal) and install *knitr* package:
  166. R> install.packages("knitr")
  167. Additional R packages used in this analysis (*ggplot2, plyr, data.table, RColorBrewer*) will be installed automatically when the document is compiled for the first time. If there is any trouble, install them by hand directly from R (the same way as *knitr*)
  168. # Gantt Charts of the whole Trace
  169. First, we show a simple gantt chart of every trace. X-axis is a
  170. simple timeline of the execution, *Resources* on y-axis correspond
  171. to different CPUs/GPUs that were used and finally different colors
  172. represent different *States* of the application.
  173. This kind of figures can often point to the idle time or
  174. synchronization problems. Small disadvantage is that in most cases
  175. there are too many states, thus it is impossible to display them all
  176. on a single plot without aggregation. Therefore for any strange
  177. behavior at a certain part of the trace, we strongly suggest to zoom
  178. on the interval it occurred.
  179. ```{r Gantt1}
  180. ggplot(df,aes(x=Start,xend=End, y=factor(ResourceId), yend=factor(ResourceId),color=Value)) +
  181. theme_bw() + scale_color_manual(name="State",values=getPalette(colourCount)) +
  182. geom_segment(size=8) + ylab("Resource") + xlab("Time [ms]") +
  183. facet_wrap(~Origin,ncol=1,scale="free_y")
  184. ```
  185. Second, we will concentrate only on computation kernel states, to
  186. get rid of visualization artifacts that can be introduced by other
  187. (sometimes irrelevant) states. Normally, this plot should not be too
  188. different from the previous one.
  189. ```{r Gantt2}
  190. # Select only computation kernels
  191. df1 <- df[!(df$Value %in% c("Initializing","Deinitializing","Overhead","Nothing","Sleeping","Freeing","Allocating","WritingBack","FetchingInput","PushingOutput","Callback","Progressing","Unpartitioning","AllocatingReuse","Reclaiming","DriverCopy","DriverCopyAsync","Scheduling","Executing")),]
  192. # Start from zero
  193. m <- min(df1$Start)
  194. df1$Start <- df1$Start - m
  195. df1$End <- df1$Start+df1$Duration
  196. # Plot
  197. ggplot(df1,aes(x=Start,xend=End, y=factor(ResourceId), yend=factor(ResourceId),color=Value)) +
  198. theme_bw() + scale_color_manual(name="State",values=getPalette(colourCount)) +
  199. geom_segment(size=8) + ylab("Resource") + xlab("Time [ms]") +
  200. facet_wrap(~Origin,ncol=1,scale="free_y")
  201. ```
  202. # Table Summary
  203. Here we present how much time application spent in each state
  204. (OverallDuration), how many times it was in that state (Count),
  205. mean and median values of duration (Mean and Median), and finally
  206. what is a standard deviation (StandDev).
  207. General information provided by this table can sometimes give an
  208. idea to application experts which parts of code are not working as
  209. desired. Be aware that this kind of tables hide many important
  210. things, such as outliers, multiple modes, etc.
  211. ```{r Table}
  212. options(width=120)
  213. ddply(df,.(Value,Origin), summarize, OverallDuration=sum(Duration), Count=length(Duration), Mean=mean(Duration), Median=median(Duration), StandDev=sd(Duration))
  214. ```
  215. # State Duration during the Execution Time
  216. Now, we show how duration of each state was changing during the
  217. execution. This can display a general behavior of a state; show if
  218. there are outliers or multiple modes; are some events occurring in
  219. groups, etc. . It can also suggest a strange behavior of a state
  220. during a certain time interval, which should be later investigated
  221. more carefully.
  222. However, since each event is represented by a single point (and
  223. there is no "alpha" factor), those events that happen almost
  224. simultaneously are overplotted. Therefore density of events along
  225. execution time may not be easy to read.
  226. ```{r Dur}
  227. ggplot(df,aes(x=Start,y=Duration)) + geom_point(aes(color=Value)) + theme_bw() + scale_color_manual(name="State",values=getPalette(colourCount)) + ggtitle("State Duration during the Execution Time") + theme(legend.position="none") + ylab("Duration [ms]") + xlab("Time [ms]") + facet_grid(Value~Origin, scale="free_y")
  228. ```
  229. # Distribution Histograms
  230. Finally, we show a distribution of *Duration* for each state in form
  231. of histograms. X-axis is partitioned into bins with equidistant time
  232. intervals in milliseconds, while y-axis represents the number of
  233. occurrences inside such intervals for a certain state. Note that for
  234. the first plot y-axis is not fixed, meaning that the scale changes
  235. from one row to another. This plot allows to not only to see what
  236. was the most frequent duration of a state, but also to compare
  237. duration between different states.
  238. ```{r Hist1}
  239. ggplot(df, aes(x=Duration)) + geom_histogram(aes(y=..count..,fill=factor(Value)),binwidth = diff(range(df$Duration))/30) + theme_bw() + scale_fill_manual(name="State",values=getPalette(colourCount)) + ggtitle("Histograms for State Distribution") + ylab("Count") + xlab("Duration [ms]") + theme(legend.position="none") + facet_grid(Value~Origin,scales = "free_y")
  240. ```
  241. Similar to the previous figure, only now traces are showed vertically
  242. instead of horizontally. Note that for this plot x-axis is not fixed,
  243. meaning that the scale changes from one column to another. This plot
  244. allows to compare frequency of different states and in case of
  245. multiple traces to easily compare duration distribution for each
  246. state.
  247. ```{r Hist2}
  248. ggplot(df, aes(x=Duration)) + geom_histogram(aes(y=..count..,fill=factor(Value)),binwidth = diff(range(df$Duration))/30) + theme_bw() + scale_fill_manual(name="State",values=getPalette(colourCount)) + ggtitle("Histograms for State Distribution") + ylab("Count") + xlab("Duration [ms]") + theme(legend.position="none") + facet_grid(Origin~Value,scales = "free_x")
  249. ```