make_graphs.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. import json
  5. from math import sqrt
  6. import numpy as np
  7. import matplotlib.pyplot as plt
  8. from contextlib import contextmanager
  9. Z_STAR = 1.96
  10. ##
  11. # This functionality allows us to temporarily change our working directory
  12. #
  13. # @input newdir - the new directory (relative to our current position) we want to be in
  14. @contextmanager
  15. def cd(newdir, makenew):
  16. prevdir = os.getcwd()
  17. directory = os.path.expanduser(newdir)
  18. if not os.path.exists(directory) and makenew:
  19. os.makedirs(directory)
  20. os.chdir(directory)
  21. try:
  22. yield
  23. finally:
  24. os.chdir(prevdir)
  25. def readData(dataDirectory):
  26. serverData = {}
  27. clientData = {}
  28. realDirectory = os.path.expanduser(dataDirectory)
  29. for test in os.listdir(realDirectory):
  30. if not test.startswith('.') and not test.endswith('.tar.gz') and test.find("default") == -1:
  31. testParts = test.split("-")
  32. if not testParts[0] in serverData:
  33. serverData[testParts[0]] = {}
  34. if not testParts[0] in clientData:
  35. clientData[testParts[0]] = {}
  36. if not testParts[1] in serverData[testParts[0]]:
  37. serverData[testParts[0]][testParts[1]] = {}
  38. if not testParts[1] in clientData[testParts[0]]:
  39. clientData[testParts[0]][testParts[1]] = {}
  40. if not testParts[2] in serverData[testParts[0]][testParts[1]]:
  41. serverData[testParts[0]][testParts[1]][testParts[2]] = {}
  42. if not testParts[2] in clientData[testParts[0]][testParts[1]]:
  43. clientData[testParts[0]][testParts[1]][testParts[2]] = {}
  44. if not testParts[3] in serverData[testParts[0]][testParts[1]][testParts[2]]:
  45. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]] = {}
  46. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_wall'] = []
  47. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_cpu'] = []
  48. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_recv'] = []
  49. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_sent'] = []
  50. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_wall'] = []
  51. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_cpu'] = []
  52. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_recv'] = []
  53. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_sent'] = []
  54. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_wall'] = []
  55. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_cpu'] = []
  56. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_recv'] = []
  57. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_sent'] = []
  58. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_wall'] = []
  59. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_cpu'] = []
  60. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_recv'] = []
  61. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_sent'] = []
  62. if not testParts[3] in clientData[testParts[0]][testParts[1]][testParts[2]]:
  63. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]] = {}
  64. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_wall'] = []
  65. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_cpu'] = []
  66. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_recv'] = []
  67. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_sent'] = []
  68. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_wall'] = []
  69. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_cpu'] = []
  70. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_recv'] = []
  71. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_sent'] = []
  72. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_wall'] = []
  73. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_cpu'] = []
  74. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_recv'] = []
  75. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_sent'] = []
  76. for test in os.listdir(realDirectory):
  77. if not test.startswith('.') and not test.endswith('.tar.gz') and test.find("default") == -1:
  78. testParts = test.split("-")
  79. for whichEntity in os.listdir(os.path.join(realDirectory, test)):
  80. if whichEntity.startswith('s') or whichEntity.startswith('d'):
  81. try:
  82. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'overallEpoch.out')), 'r') as overallEpochFile:
  83. for line in overallEpochFile:
  84. lineParts = line.rstrip().split(',')
  85. wallTime = float(lineParts[0])
  86. cpuTime = float(lineParts[1])
  87. dataRecv = float(lineParts[2])
  88. dataSent = float(lineParts[3])
  89. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_wall'].append(wallTime)
  90. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_cpu'].append(cpuTime)
  91. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_recv'].append(dataRecv)
  92. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_sent'].append(dataSent)
  93. except FileNotFoundError as e:
  94. pass
  95. try:
  96. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'epochUp.out')), 'r') as epochUpFile:
  97. for line in epochUpFile:
  98. lineParts = line.rstrip().split(',')
  99. wallTime = float(lineParts[0])
  100. cpuTime = float(lineParts[1])
  101. dataRecv = float(lineParts[2])
  102. dataSent = float(lineParts[3])
  103. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_wall'].append(wallTime)
  104. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_cpu'].append(cpuTime)
  105. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_recv'].append(dataRecv)
  106. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_sent'].append(dataSent)
  107. except FileNotFoundError as e:
  108. pass
  109. try:
  110. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'epochDown.out')), 'r') as epochDownFile:
  111. for line in epochDownFile:
  112. lineParts = line.rstrip().split(',')
  113. wallTime = float(lineParts[0])
  114. cpuTime = float(lineParts[1])
  115. dataRecv = float(lineParts[2])
  116. dataSent = float(lineParts[3])
  117. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_wall'].append(wallTime)
  118. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_cpu'].append(cpuTime)
  119. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_recv'].append(dataRecv)
  120. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_sent'].append(dataSent)
  121. except FileNotFoundError as e:
  122. pass
  123. try:
  124. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'voteUpdate.out')), 'r') as voteUpdateFile:
  125. for line in voteUpdateFile:
  126. lineParts = line.rstrip().split(',')
  127. wallTime = float(lineParts[0])
  128. cpuTime = float(lineParts[1])
  129. dataRecv = float(lineParts[2])
  130. dataSent = float(lineParts[3])
  131. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_wall'].append(wallTime)
  132. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_cpu'].append(cpuTime)
  133. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_recv'].append(dataRecv)
  134. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_sent'].append(dataSent)
  135. except FileNotFoundError as e:
  136. pass
  137. elif whichEntity.startswith('c'):
  138. try:
  139. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'vote.out')), 'r') as repVerifierFile:
  140. for line in repVerifierFile:
  141. lineParts = line.rstrip().split(',')
  142. wallTime = float(lineParts[0])
  143. cpuTime = float(lineParts[1])
  144. dataRecv = float(lineParts[2])
  145. dataSent = float(lineParts[3])
  146. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_wall'].append(wallTime)
  147. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_cpu'].append(cpuTime)
  148. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_recv'].append(dataRecv)
  149. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_sent'].append(dataSent)
  150. except FileNotFoundError as e:
  151. pass
  152. try:
  153. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'repProver.out')), 'r') as repProverFile:
  154. for line in repProverFile:
  155. lineParts = line.rstrip().split(',')
  156. wallTime = float(lineParts[0])
  157. cpuTime = float(lineParts[1])
  158. dataRecv = float(lineParts[2])
  159. dataSent = float(lineParts[3])
  160. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_wall'].append(wallTime)
  161. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_cpu'].append(cpuTime)
  162. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_recv'].append(dataRecv)
  163. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_sent'].append(dataSent)
  164. except FileNotFoundError as e:
  165. pass
  166. try:
  167. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'repVerifier.out')), 'r') as repVerifierFile:
  168. for line in repVerifierFile:
  169. lineParts = line.rstrip().split(',')
  170. wallTime = float(lineParts[0])
  171. cpuTime = float(lineParts[1])
  172. dataRecv = float(lineParts[2])
  173. dataSent = float(lineParts[3])
  174. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_wall'].append(wallTime)
  175. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_cpu'].append(cpuTime)
  176. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_recv'].append(dataRecv)
  177. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_sent'].append(dataSent)
  178. except FileNotFoundError as e:
  179. pass
  180. return serverData, clientData
  181. def plotComparison(data, dataParts, xVariable, lineVariable, whichGraph, **kwargs):
  182. title = kwargs['title'] if 'title' in kwargs else ''
  183. xLabel = kwargs['xLabel'] if 'xLabel' in kwargs else ''
  184. yLabel = kwargs['yLabel'] if 'yLabel' in kwargs else ''
  185. fileNameStr = kwargs['fileNameStr'] if 'fileNameStr' in kwargs else f"basic-{xVariable}-{lineVariable}-{whichGraph}"
  186. legendLoc = kwargs['legendLoc'] if 'legendLoc' in kwargs else "best"
  187. legendBBoxAnchor = kwargs['legendBBoxAnchor'] if 'legendBBoxAnchor' in kwargs else (0, 1)
  188. loglog = kwargs['loglog'] if 'loglog' in kwargs else True
  189. yLim = kwargs['yLim'] if 'yLim' in kwargs else False
  190. aspect = kwargs['aspect'] if 'aspect' in kwargs else None
  191. fig = plt.figure()
  192. ax = fig.gca()
  193. whichLines = 0
  194. lineSelection = []
  195. legendStart = ""
  196. legendEnd = ""
  197. if lineVariable == 'workload':
  198. whichLines = 0
  199. lineSelection = data.keys()
  200. legendStart = "Workload: "
  201. elif lineVariable == 'numServers':
  202. whichLines = 1
  203. lineSelection = data['all'].keys()
  204. legendEnd = " servers"
  205. elif lineVariable == 'numClients':
  206. whichLines = 2
  207. lineSelection = data['all']['2'].keys()
  208. legendEnd = " clients"
  209. elif lineVariable == 'lambda':
  210. whichLines = 3
  211. lineSelection = data['all']['2']['5'].keys()
  212. legendStart = "Lambda: "
  213. whichX = 0
  214. xSelection = []
  215. if xVariable == 'workload':
  216. whichX = 0
  217. xSelection = data.keys()
  218. elif xVariable == 'numServers':
  219. whichX = 1
  220. xSelection = [int(x) for x in data['all'].keys()]
  221. xSelection.sort()
  222. elif xVariable == 'numClients':
  223. whichX = 2
  224. xSelection = [int(x) for x in data['all']['2'].keys()]
  225. xSelection.sort()
  226. elif xVariable == 'lambda':
  227. whichX = 3
  228. xSelection = [int(x) for x in data['all']['2']['5'].keys()]
  229. xSelection.sort()
  230. for selection in lineSelection:
  231. xs = []
  232. ys = []
  233. yErrs = []
  234. legend = legendStart + selection + legendEnd
  235. dataParts[whichLines] = selection
  236. for x in xSelection:
  237. dataParts[whichX] = str(x)
  238. curr_data = data[dataParts[0]][dataParts[1]][dataParts[2]][dataParts[3]][whichGraph]
  239. mean = np.mean(curr_data)
  240. std = np.std(curr_data)
  241. sqrt_len = sqrt(len(curr_data))
  242. xs.append(x)
  243. ys.append(mean)
  244. yErrs.append(Z_STAR * std / sqrt_len)
  245. line, _, _ = ax.errorbar(xs, ys, yerr=yErrs, capsize=7.0, label=legend)
  246. ax.set_title(title, fontsize='x-large')
  247. ax.set_xlabel(xLabel, fontsize='large')
  248. ax.set_ylabel(yLabel, fontsize='large')
  249. bottom, top = ax.get_ylim()
  250. bottom = (0 if bottom > 0 else bottom)
  251. ax.set_ylim(bottom=bottom)
  252. if yLim:
  253. ax.set_ylim(bottom=yLim[0], top=yLim[1])
  254. if aspect:
  255. ax.set_aspect(aspect, adjustable='box')
  256. legend = ax.legend(loc=legendLoc, bbox_to_anchor=legendBBoxAnchor, fontsize='large')
  257. with cd('../plt/', True):
  258. fig.savefig(f"{fileNameStr}.pdf", bbox_inches='tight')
  259. plt.close(fig)
  260. def main(dataDirectory, plotOptionsFile):
  261. serverData, clientData = readData(dataDirectory)
  262. plotOptions = []
  263. with open(plotOptionsFile, 'r') as options:
  264. plotOptions = json.load(options)
  265. for option in plotOptions:
  266. try:
  267. data = serverData if (option['data'].lower() == "server" or option['data'].lower() == "s") else clientData
  268. dataParts = option['dataParts']
  269. xVariable = option['xVariable']
  270. lineVariable = option['lineVariable']
  271. whichGraph = option['whichGraph']
  272. except KeyError as e:
  273. continue
  274. kwargs = {}
  275. if "title" in option:
  276. kwargs["title"] = option["title"]
  277. if "xLabel" in option:
  278. kwargs["xLabel"] = option["xLabel"]
  279. if "yLabel" in option:
  280. kwargs["yLabel"] = option["yLabel"]
  281. if "fileNameStr" in option:
  282. kwargs["fileNameStr"] = option["fileNameStr"]
  283. if "legendLoc" in option:
  284. kwargs["legendLoc"] = option["legendLoc"]
  285. if "legendBBoxAnchor" in option:
  286. anchor = (option["legendBBoxAnchor"][0], option["legendBBoxAnchor"][1])
  287. kwargs["legendBBoxAnchor"] = anchor
  288. if "loglog" in option:
  289. kwargs["loglog"] = option["loglog"]
  290. if "yLim" in option:
  291. kwargs["yLim"] = option["yLim"]
  292. if "aspect" in option:
  293. kwargs["aspect"] = option["aspect"]
  294. plotComparison(data, dataParts, xVariable, lineVariable, whichGraph, **kwargs)
  295. if __name__ == "__main__":
  296. main("../out", "../plt/plots.json")