parse_logs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #!/usr/bin/perl
  2. # Parse the log output files of run-experiment
  3. # Send concatenated log files to stdin, or list them on the command
  4. # line.
  5. use strict;
  6. my $mode = '';
  7. my $depth = 0;
  8. my $numops = 0;
  9. my $phase = '';
  10. my $numparties = '';
  11. my $what = '';
  12. my $setupsize = 0;
  13. my $opsize = 0;
  14. my @seconds = (0, 0);
  15. my $netsetup = '';
  16. my %preproc_s_data = ();
  17. my %preproc_kib_data = ();
  18. my %online_s_data = ();
  19. my %online_kib_data = ();
  20. while(<>) {
  21. chomp;
  22. if (/Network setup: (.*)/) {
  23. $netsetup = "$1 ";
  24. next;
  25. }
  26. if (/===== Running duoram (\S+) (\d+) (\d+) (\S+) ([23]P)/) {
  27. $mode = $1;
  28. $depth = $2;
  29. $numops = $3;
  30. $phase = $4;
  31. $numparties = $5;
  32. my $label = "${numparties}Duoram $mode $depth $netsetup$numops";
  33. if ($mode eq "read" && $numparties eq "2P") {
  34. &parse_2P_read($label);
  35. } elsif ($mode eq "write" && $numparties eq "2P" && $phase eq "preproc") {
  36. &parse_2P_write_preproc($label);
  37. } elsif ($mode eq "write" && $numparties eq "2P" && $phase eq "online") {
  38. &parse_2P_write_online($label);
  39. } elsif ($numparties eq "3P" && $phase eq "preproc") {
  40. &parse_3P_preproc("$depth $netsetup$numops");
  41. } elsif ($numparties eq "3P" && $phase eq "online") {
  42. &parse_3P_online("$depth $netsetup$numops");
  43. }
  44. @seconds = (0,0);
  45. $what = '';
  46. $setupsize = 0;
  47. $opsize = 0;
  48. next;
  49. }
  50. }
  51. # Convert the data (in the form [n, sum, sum_squares]) to statistics (in
  52. # the form [mean, variance])
  53. my %preproc_s_stats = ();
  54. my %preproc_kib_stats = ();
  55. my %online_s_stats = ();
  56. my %online_kib_stats = ();
  57. &statsify(\%preproc_s_stats, \%preproc_s_data);
  58. &statsify(\%preproc_kib_stats, \%preproc_kib_data);
  59. &statsify(\%online_s_stats, \%online_s_data);
  60. &statsify(\%online_kib_stats, \%online_kib_data);
  61. # The 2P readwrite values are just the sums of the read and the write values
  62. &sum_readwrite_2P(\%preproc_s_stats);
  63. &sum_readwrite_2P(\%preproc_kib_stats);
  64. &sum_readwrite_2P(\%online_s_stats);
  65. &sum_readwrite_2P(\%online_kib_stats);
  66. # The total values are the sums of the preproc and online values
  67. my %total_s_stats = ();
  68. my %total_kib_stats = ();
  69. &sum_preproc_online(\%total_s_stats, \%preproc_s_stats, \%online_s_stats);
  70. &sum_preproc_online(\%total_kib_stats, \%preproc_kib_stats, \%online_kib_stats);
  71. # Output the data
  72. &output_stats(\%preproc_s_stats, "Preprc", "s");
  73. &output_stats(\%preproc_kib_stats, "Preprc", "KiB");
  74. &output_stats(\%online_s_stats, "Onln", "s");
  75. &output_stats(\%online_kib_stats, "Onln", "KiB");
  76. &output_stats(\%total_s_stats, "Totl", "s");
  77. &output_stats(\%total_kib_stats, "Totl", "KiB");
  78. # Subroutines
  79. sub parse_2P_read {
  80. my $label = $_[0];
  81. my $who = 0;
  82. my @preproc_s = ();
  83. my @preproc_kib = ();
  84. my @online_s = ();
  85. my @online_kib = ();
  86. while(<>) {
  87. last if /===== End/;
  88. if (/===== P([012]) output/) {
  89. $who = $1;
  90. next;
  91. }
  92. if (/Total preprocessing time: (\d+) µs/) {
  93. $preproc_s[$who] = $1 / 1000000;
  94. }
  95. if (/Total preprocessing bytes: (\d+)/) {
  96. $preproc_kib[$who] = $1 / 1024;
  97. }
  98. if (/Total query time: (\d+) µs/) {
  99. $online_s[$who] = $1 / 1000000;
  100. }
  101. if (/Total query bytes: (\d+)/) {
  102. $online_kib[$who] = $1 / 1024;
  103. }
  104. }
  105. &accum_data(\%preproc_s_data, $label, &maxarray(@preproc_s));
  106. &accum_data(\%preproc_kib_data, $label, &avgarray(@preproc_kib));
  107. &accum_data(\%online_s_data, $label, &maxarray(@online_s));
  108. &accum_data(\%online_kib_data, $label, &avgarray(@online_kib));
  109. }
  110. sub parse_2P_write_preproc {
  111. my $label = $_[0];
  112. my $who = 0;
  113. my @preproc_s = ();
  114. my @preproc_kib = ();
  115. while(<>) {
  116. last if /===== End/;
  117. if (/===== P([012]) output/) {
  118. $who = $1;
  119. next;
  120. }
  121. if (/time to generate and evaluate \d+ OTs is: (\d+\.?\d*+)s/) {
  122. $preproc_s[$who] = $1;
  123. }
  124. if (/bytes transmitted for OT = (\d+) bytes/) {
  125. $preproc_kib[$who] = $1 / 1024;
  126. }
  127. if (/WallClockTime: (\d+\.?\d*) s/) {
  128. $preproc_s[$who] += $1;
  129. }
  130. if (/CommunicationCost: (\d+) bytes/) {
  131. $preproc_kib[$who] += $1 / 1024;
  132. }
  133. }
  134. &accum_data(\%preproc_s_data, $label, &maxarray(@preproc_s));
  135. &accum_data(\%preproc_kib_data, $label, &avgarray(@preproc_kib));
  136. }
  137. sub parse_2P_write_online {
  138. my $label = $_[0];
  139. my $who = 0;
  140. my @online_s = ();
  141. my @online_kib = ();
  142. while(<>) {
  143. last if /===== End/;
  144. if (/===== P([012]) output/) {
  145. $who = $1;
  146. next;
  147. }
  148. if (/write_time = (\d+\.?\d*)/) {
  149. $online_s[$who] = $1;
  150. }
  151. if (/communication_cost_writes = (\d+) bytes/) {
  152. $online_kib[$who] = $1 / 1024;
  153. }
  154. }
  155. &accum_data(\%online_s_data, $label, &maxarray(@online_s));
  156. &accum_data(\%online_kib_data, $label, &avgarray(@online_kib));
  157. }
  158. sub parse_3P_preproc {
  159. my $labelsuffix = $_[0];
  160. my $who = 0;
  161. my @preproc_s = ();
  162. my @preproc_kib = ();
  163. while(<>) {
  164. last if /===== End/;
  165. if (/WallClockTime: (\d+\.?\d*)/) {
  166. $preproc_s[$who] = $1;
  167. }
  168. if (/CommunicationCost: (\d+) bytes/) {
  169. $preproc_kib[$who] = $1 / 1024;
  170. }
  171. }
  172. &accum_data(\%preproc_s_data, "3PDuoram read $labelsuffix", &maxarray(@preproc_s));
  173. &accum_data(\%preproc_kib_data, "3PDuoram read $labelsuffix", &avgarray(@preproc_kib));
  174. &accum_data(\%preproc_s_data, "3PDuoram write $labelsuffix", &maxarray(@preproc_s));
  175. &accum_data(\%preproc_kib_data, "3PDuoram write $labelsuffix", &avgarray(@preproc_kib));
  176. &accum_data(\%preproc_s_data, "3PDuoram readwrite $labelsuffix", 2*&maxarray(@preproc_s));
  177. &accum_data(\%preproc_kib_data, "3PDuoram readwrite $labelsuffix", 2*&avgarray(@preproc_kib));
  178. }
  179. sub parse_3P_online {
  180. my $labelsuffix = $_[0];
  181. my $who = 0;
  182. my @read_s = ();
  183. my @read_kib = ();
  184. my @write_s = ();
  185. my @write_kib = ();
  186. my @readwrite_s = ();
  187. my @readwrite_kib = ();
  188. while(<>) {
  189. last if /===== End/;
  190. if (/===== P([012]) output/) {
  191. $who = $1;
  192. next;
  193. }
  194. if (/write_time =\s+(\d+\.?\d*)/) {
  195. $write_s[$who] = $1;
  196. }
  197. if (/communication_cost_writes = (\d+) bytes/) {
  198. $write_kib[$who] = $1 / 1024;
  199. }
  200. if (/dependent_read_time =\s+(\d+\.?\d*)/) {
  201. $read_s[$who] = $1;
  202. }
  203. if (/communication_cost_dep_read = (\d+) bytes/) {
  204. $read_kib[$who] = $1 / 1024;
  205. }
  206. if (/interleaved_time =\s+(\d+\.?\d*)/) {
  207. $readwrite_s[$who] = $1;
  208. }
  209. if (/communication_cost_interleaved = (\d+) bytes/) {
  210. $readwrite_kib[$who] = $1 / 1024;
  211. }
  212. }
  213. &accum_data(\%online_s_data, "3PDuoram read $labelsuffix", &maxarray(@read_s));
  214. &accum_data(\%online_kib_data, "3PDuoram read $labelsuffix", &avgarray(@read_kib));
  215. &accum_data(\%online_s_data, "3PDuoram write $labelsuffix", &maxarray(@write_s));
  216. &accum_data(\%online_kib_data, "3PDuoram write $labelsuffix", &avgarray(@write_kib));
  217. &accum_data(\%online_s_data, "3PDuoram readwrite $labelsuffix", &maxarray(@readwrite_s));
  218. &accum_data(\%online_kib_data, "3PDuoram readwrite $labelsuffix", &avgarray(@readwrite_kib));
  219. }
  220. sub maxarray {
  221. my $max = $_[0];
  222. foreach (@_) {
  223. $max = $_ if $_ > $max;
  224. }
  225. $max;
  226. }
  227. sub avgarray {
  228. my $sum = 0;
  229. my $n = 0;
  230. foreach (@_) {
  231. $sum += $_;
  232. $n += 1;
  233. }
  234. $sum / $n;
  235. }
  236. # Pass:
  237. # - a reference to a dictionary
  238. # - the key into that dictionary
  239. # - the new data point
  240. # Data is stored in the dictionary as a triple (n, sum, sum_squares)
  241. sub accum_data {
  242. my ($dict, $key, $data) = @_;
  243. $dict->{$key} = [0, 0, 0] unless defined $dict->{$key};
  244. $dict->{$key}->[0] += 1;
  245. $dict->{$key}->[1] += $data;
  246. $dict->{$key}->[2] += ($data * $data);
  247. }
  248. # Convert data (in the form [n, sum, sum_squares]) to statistics (in
  249. # the form [mean, variance])
  250. sub statsify {
  251. my ($sdict, $ddict) = @_;
  252. my $key;
  253. foreach $key (keys %$ddict) {
  254. my $data = $ddict->{$key};
  255. my $n = $data->[0];
  256. my $sum = $data->[1];
  257. my $sumsq = $data->[2];
  258. if ($n == 0) {
  259. $sdict->{$key} = [undef, undef];
  260. } elsif ($n == 1) {
  261. $sdict->{$key} = [$sum, undef];
  262. } else {
  263. $sdict->{$key} = [$sum/$n, ($sumsq - ($sum*$sum/$n))/($n-1)];
  264. }
  265. }
  266. }
  267. # Turn a stat array [mean, variance] into a string to display
  268. sub statstr {
  269. my $data = $_[0];
  270. if (defined $data->[1]) {
  271. my $mean = $data->[0];
  272. my $stddev = sqrt($data->[1]);
  273. return "$mean ± $stddev";
  274. } elsif (defined $data->[0]) {
  275. return $data->[0];
  276. } else {
  277. return "none"
  278. }
  279. }
  280. # Sum two stat arrays
  281. sub statsum {
  282. my ($data0, $data1) = @_;
  283. if (defined $data0->[1] && defined $data1->[1]) {
  284. return [$data0->[0] + $data1->[0], $data0->[1] + $data1->[1]];
  285. } else {
  286. return [$data0->[0] + $data1->[0], undef];
  287. }
  288. }
  289. # The 2P readwrite values are just the sums of the read and the write values
  290. sub sum_readwrite_2P {
  291. my $dict = $_[0];
  292. my $key;
  293. foreach $key (keys %$dict) {
  294. if ($key =~ /^2PDuoram read /) {
  295. my $writekey = $key;
  296. my $readwritekey = $key;
  297. $writekey =~ s/^2PDuoram read /2PDuoram write /;
  298. $readwritekey =~ s/^2PDuoram read /2PDuoram readwrite /;
  299. if (defined $dict->{$writekey}) {
  300. $dict->{$readwritekey} = &statsum($dict->{$key}, $dict->{$writekey});
  301. } else {
  302. # It's OK if we're missing the data point, since we
  303. # don't necessary parse all the data at once.
  304. # print "Missing data point for $writekey\n";
  305. }
  306. }
  307. }
  308. }
  309. # Add the preproc and online stats to get the total stats
  310. sub sum_preproc_online {
  311. my ($tdict, $pdict, $odict) = @_;
  312. my $key;
  313. foreach $key (keys %$pdict) {
  314. if (defined $odict->{$key}) {
  315. $tdict->{$key} = &statsum($pdict->{$key}, $odict->{$key});
  316. }
  317. }
  318. }
  319. # Output the stats in the given dictionary. Append $phase to the
  320. # protocol name, and add $units to the end.
  321. sub output_stats {
  322. my ($dict, $phase, $units) = @_;
  323. my $label;
  324. foreach $label (sort keys %$dict) {
  325. my $printlabel = $label;
  326. $printlabel =~ s/PDuoram/PDuoram$phase/;
  327. print $printlabel, " ", &statstr($dict->{$label}), " $units\n";
  328. }
  329. }