aboutsummaryrefslogtreecommitdiff
path: root/notebook/ldc_benchmark.ipynb
blob: 0248e63a154f73758b7406acabddec419e282f03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from result.ldc_2d_benchmark_P100  import ldc_2d_p100\n",
    "from result.ldc_2d_benchmark_K2200 import ldc_2d_k2200\n",
    "from result.ldc_3d_benchmark_P100  import ldc_3d_p100\n",
    "from result.ldc_3d_benchmark_K2200 import ldc_3d_k2200"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((32, (16, 1), 'single', True), [15, 16, 16, 16, 16, 16, 16, 16, 16, 16])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ldc_2d_k2200[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((16, (16, 1, 1), 'symbolic.D3Q19', 'single', True),\n",
       " [58, 60, 60, 60, 60, 60, 60, 60, 59, 60])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ldc_3d_k2200[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def descriptor_subset(data, descriptor):\n",
    "    return list(\n",
    "        map(lambda m: (m[0][0:2] + m[0][3:], m[1]),\n",
    "            filter(lambda m: m[0][2] == descriptor, ldc_3d_p100)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "ldc_3d_D3Q19_p100  = descriptor_subset(ldc_3d_p100,  'symbolic.D3Q19')\n",
    "ldc_3d_D3Q27_p100  = descriptor_subset(ldc_3d_p100,  'symbolic.D3Q27')\n",
    "ldc_3d_D3Q19_k2200 = descriptor_subset(ldc_3d_k2200, 'symbolic.D3Q19')\n",
    "ldc_3d_D3Q27_k2200 = descriptor_subset(ldc_3d_k2200, 'symbolic.D3Q27')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def values(data, index):\n",
    "    return set(map(lambda m: m[0][index], data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{16, 32, 48, 64, 96, 128}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "values(ldc_3d_D3Q19_k2200, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def has(value, options):\n",
    "    if options == None:\n",
    "        return True\n",
    "    else:\n",
    "        return value in options\n",
    "\n",
    "def subset(data, size=None, layout=None, precision=None, optimization=None):\n",
    "    return list(\n",
    "        filter(lambda m: has(m[0][0], size) and has(m[0][1][0], layout) and has(m[0][2], precision) and has(m[0][3], optimization),\n",
    "               data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mlups_for_size(measurement):\n",
    "    dim = len(list(measurement[0][1]))\n",
    "    return (measurement[0][0]**dim, numpy.average(measurement[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def scatter(data, **kwargs):\n",
    "    plt.scatter(*zip(*list(data)), **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mlups_per_size_overview_plot(data, title, **kwargs):\n",
    "    plt.figure(figsize=(10,8))\n",
    "    plt.grid()\n",
    "    plt.title(title)\n",
    "    plt.xscale('log')\n",
    "    plt.xlabel('Cells')\n",
    "    plt.ylabel('MLUPS')\n",
    "    scatter(map(mlups_for_size, subset(data, precision=['single'], optimization=[True], **kwargs)), label='single, CSE')\n",
    "    scatter(map(mlups_for_size, subset(data, precision=['double'], optimization=[True], **kwargs)), label='double, CSE')\n",
    "    scatter(map(mlups_for_size, subset(data, precision=['single'], optimization=[False], **kwargs)), label='single, not-CSE')\n",
    "    scatter(map(mlups_for_size, subset(data, precision=['double'], optimization=[False], **kwargs)), label='double, not-CSE')\n",
    "    plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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ZX19ROHikIuzx/svFJ7XTcfwT4EpFJ7b1yhcGfzT+tQpFZtwul6Stk9E3EghUJywrZPj8yS72OJBCv9zfhNQQWE09BwKX7cyMAtxkpqJ4UySdkA2/TYvpfRkc9dSX9m06aUURqcOBT4C/gB8L6X0WjOWJgnDmSRJUq54zpkkSVKOGM4kSZJypKi/hLZr166pR48eTbKv1atX06FDfb9KSGoaHpfKK49N5VFzH5fTp09fllLaq671ijqc9ejRg7/85S9Nsq/y8nLKysqaZF9SfXlcKq88NpVHzX1cRsR/172W05qSJEm5YjiTJEnKEcOZJElSjhT1OWe1WbduHQsXLmTt2rU7td/OnTsze/bsndqntq1t27bsv//+tG7durlLkSSpyexy4WzhwoV06tSJHj16EBE7rd9Vq1bRqVOnndafti2lxPLly1m4cCE9e/Zs7nIkSWoyu9y05tq1a+nSpctODWZqehFBly5ddvoIqCRJebfLhTPAYLaL8HWUJJWiXTKc5dHll1/OG2+8sV3bzp8/n759+273visrK7nyyivp1asXffr04YQTTuCll14C4Oabb6ZPnz7079+fAQMGVLWXlZXRu3dvBgwYwIABAzj77LO3e/+SJKn+drlzzvLqZz/7WbPt+/LLL6dnz57MnTuXFi1a8M477zB79mxefPFFHn/8cWbMmEGbNm1YtmwZH330UdV2EydOZNCgQc1WtyRJpajkR84mv7KI437we3p+8wmO+8HvmfzKoh3qb/Xq1QwfPpzDDz+cvn378utf/xoojERt+jWDjh078u1vf5vDDz+cwYMH8/777wPw9ttvM3jwYI466iiuv/56OnbsuEX/GzZsYMyYMRx11FH079+fn/70p9us5+233+all17ipptuokWLwst90EEHMXz4cJYsWULXrl1p06YNAF27dqV79+479PglSdKOKelwNvmVRVz78KssWrGGBCxasYZrH351hwLak08+Sffu3Zk5cyavvfYaJ5988hbrrF69msGDBzNz5kxOOOEE7rnnHgBGjx7N6NGjmTZt2lZD0r333kvnzp2ZNm0a06ZN45577uHdd9/daj2vv/46AwYMoGXLllssO+mkk1iwYAGHHHIIX/7yl3nuuedqLL/wwgurpjXHjBnTkKdBkiRtp5IOZ+OemsOadRtqtK1Zt4FxT83Z7j779evHM888wze+8Q2ef/55OnfuvMU6u+22G6eeeioARx55JPPnzwfgxRdf5JxzzgHgggsuqLX/qVOn8otf/IIBAwZwzDHHsHz5cubOnbtdtXbs2JHp06dz9913s9dee3Heeedx3333VS2fOHEiFRUVVFRUMG7cuO3ahyRJapiSPuds8Yo1DWqvj0MOOYTp06fz29/+lmuvvZaTTjqJ66+/vsY6rVu3rroSsWXLlqxfv77e/aeUuPPOOxk2bFi91u/Tpw8zZ85k48aNVdOa1bVs2ZKysjLKysro168fEyZM4NJLL613PZIkaecq6ZGz7nu0a1B7fSxevJj27dvzxS9+kWuuuYYZM2bUe9vBgwfzm9/8BoBJkybVus6wYcP4yU9+wrp16wB46623WL16NQCf+tSntli/V69eDBo0iBtuuIGUEgBz587l0UcfZc6cOTVG3SoqKjjwwAPrXa8kSdr5SnrkbMyw3lz78Ks1pjbbtW7JmGG9t7vPV199lTFjxtCiRQtat27NT37yk3pve9ttt/HFL36RH//4xwwfPrzWKdHLL7+c+fPnM3DgQFJK7LXXXkyePJlly5ZVha/N/exnP+PrX/86Bx98MO3bt6dLly6MGzeOyspKvvKVr7BixQpatWrFwQcfzN1331213YUXXki7doWg2rVrV5555pkGPhuSJKmhYmsf6MVg0KBBadMVkJvMnj2bQw89tN59TH5lEeOemsPiFWvovkc7xgzrzRlH7LfFek3x800ffvgh7dq1IyKYNGkSv/rVr3j00Ufrte3jjz/OO++8w6hRoxq1xqbW0Nez1JSXl1NWVtbcZUhb8NhUHm06Luv72b+zRcT0lFKd31FV0iNnAGccsV+TvCD1MX36dEaOHElKiT322IPx48fXe9tNFxhIkqSt2/RNDZtmzTZ9UwOQmzxQ8uEsT44//nhmzpzZ3GVIkrTL2tY3NRjOJEmSmtjiFWtotfsrtNnrKaL1CtK6PfifD4axeMURzV1aFcOZJEkqGV33eZ01nR8mWhS+9SB2W0HbfR+mXfvdgOHNW1ympL9KQ5IklZY2ez9VFcw2iRbraLP3U81U0ZYcOZMkqRE115WBqt0/1n3QoPbm4MhZIxs7diw/+tGPtmvb++67j5EjR9a6rLYfRa+vdevW8c1vfpNPfvKT9O3bl6OPPprf/e53AIwfP55+/frRv39/+vbtW/VVHpdeeik9e/as+q3NY489drv3L0mlojF+w1k7Zp8O+zSovTk4claCrrvuOpYsWcJrr71GmzZteP/993nuuedYuHAhN998MzNmzKBz585UVlbywQcf/5/EuHHjOPvss5uxckkqLuOemsO6dn+hwz/VPPl83FO7OXrWTEYPHM3YP49l7Ya1VW1tW7Zl9MDRzVhVTY6czXoAbu0LY/co/DvrgR3u8uabb6Z37958/vOfZ86cj39EvaKigsGDB9O/f3/OPPNM/v73vwNQVlbGpi/TXbZsGT169KjaZsGCBZx88sn07t2b7373u7Xub9y4cRx11FH079+fG264YZu1ffjhh9xzzz3ceeedtGnTBoBu3bpx7rnnsnTpUjp16lQ1KtexY0d69uy53c+DJJW6pRv/TNt9H6bFbiuIgBbZyedLN/65uUsrWcMPGs7YY8eyb4d9CYJ9O+zL2GPHMvygfFwMAKUezmY9AFNGwcoFQCr8O2XUDgW06dOnM2nSJF555RUefvhhpk2bVrXs4osv5oc//CGzZs2iX79+Ww1b1b388stMnDiRiooKHnzwQTb/RYSpU6cyd+5cXn75ZSoqKpg+fTp//OMft9rfvHnz+Kd/+id23333LZYdfvjhdOvWjZ49e3LZZZcxZcqUGsvHjBlTNa154YUX1lm7JJW6dt2m1nryebtuU5upIkEhoE09eyqzLpnF1LOn5iqYQamHs2dvhHVraratW1No307PP/88Z555Ju3bt2f33XfntNNOA2DlypWsWLGCz372swBccskl2wxRm5x44ol06dKFdu3acdZZZ/HCCy/UWD516lSmTp3KEUccwcCBA3nzzTdr/Jh5Q7Rs2ZInn3yShx56iEMOOYSrr76asWPHVi0fN24cFRUVVFRUMHHixO3ahySVktRqRYPaJSj1c85WLmxYez1FRIPWb9WqFRs3bgRg7dq1NZZt3tfm91NKXHvttVx55ZX12tfBBx/MX//6163+VmhEcPTRR3P00Udz4oknctlll9UIaJKk+tu3wz4sWb2k1nZpa0p75Kzz/g1rr4cTTjiBRx55hDVr1rBq1aqqqcHOnTuz55578vzzzwNw//33V42i9ejRg+nTpwPw0EMP1ejv6aef5m9/+xtr1qxh8uTJHHfccTWWDxs2jPHjx1NZWQnAokWLWLp0KQBDhw5l0aKa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c6raKyoqGDx4MP379+fMM8/k73//O1AYRdr0ZbrLli2jR48eVdssWLCAk08+md69e/Pd73631v2NGzeOo446iv79+3PDDZv/lOmWevTowQ033MDAgQPp168fb775JgB/+9vfOOOMM+jfvz+DBw9m1qxZzJ8/n7vuuotbb72VAQMG8Pzzz9fo6+233+all17ipptuokWLwuF00EEHMXz4cJYsWULXrl1p06YNAF27dqV79+71fBYlbY/G+M1gSU2rpMPZyilTWHLd9axfvBhSYv3ixSy57vodCmjTp09n0qRJvPLKKzz88MNMmzatatksNS+nAAAeJklEQVTFF1/MD3/4Q2bNmkW/fv22Graqe/nll5k4cSIVFRU8+OCDbP6LCFOnTmXu3Lm8/PLLVFRUMH36dP74xz/W2W/Xrl2ZMWMG//qv/1o17XrDDTdwxBFHMGvWLL73ve9x8cUX06NHD6666iquvvpqKioqOP7442v08/rrrzNgwABatmy5xT5OOukkFixYwCGHHMKXv/xlnnvuuRrLL7zwwqppzTFjxtRZs6S6NcZvBktqWiUdzpbeehtpbc3h/7R2LUtvvW27+3z++ec588wzad++PbvvvjunnXYaACtXrmTFihV89rOfBeCSSy6pV4g68cQT6dKlC+3ateOss87ihRdeqLF86tSpTJ06lSOOOIKBAwfy5ptvMnfu3Dr7PeusswA48sgjmT9/PgAvvPACF110EQBDhgxh+fLlrFy5st6PfXMdO3Zk+vTp3H333ey1116cd9553HfffVXLN4XOiooKxo0bt937kfSxxvjNYElNq6TPOVu/ZEmD2usrIhq0fqtWrdi4cSMAazcLi5v3tfn9lBLXXnstV155ZYP2uWmqsWXLlqxfv76qr81tvr8NGzZw5JFHAnDaaadxySWXMHPmTDZu3Fg1rVldy5YtKSsro6ysjH79+jFhwgQuvfTSBtUqqf42nVdWn98MlpRPJT1y1mrffRvUXh8nnHACjzzyCGvWrGHVqlVMyaZIO3fuzJ577ll1ztb9999fNYrWo0cPpk+fDsBDDz1Uo7+nn36av/3tb6xZs4bJkydz3HHH1Vg+bNgwxo8fT2VlJQCLFi1i6dKlAAwdOpRFixY1qPaJEycChYsAunbtyu67706nTp1YtWoVUAhbm0a7brzxRnr16sWgQYO44YYb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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "mlups_per_size_overview_plot(ldc_2d_k2200, 'Performance of D2Q9 LDC @ K2200', layout=[32])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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