XM_40017/notebooks/jacobi_method.ipynb
2024-09-23 16:17:55 +02:00

1949 lines
388 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "2e15ced8",
"metadata": {},
"source": [
"<img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/VU_logo.png/800px-VU_logo.png?20161029201021\" width=\"350\">\n",
"\n",
"### Programming large-scale parallel systems"
]
},
{
"cell_type": "markdown",
"id": "e8549215",
"metadata": {},
"source": [
"# Jacobi method"
]
},
{
"cell_type": "markdown",
"id": "6e0ef563",
"metadata": {},
"source": [
"## Contents\n",
"\n",
"In this notebook, we will learn\n",
"\n",
"- How to paralleize the Jacobi method\n",
"- How the data partition can impact the performance of a distributed algorithm\n",
"- How to use latency hiding to improve parallel performance\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "48fd29d9",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Do not forget to run the next cell before you start studying this notebook. \n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1dc78750",
"metadata": {},
"outputs": [],
"source": [
"using Printf\n",
"\n",
"function answer_checker(answer,solution)\n",
" if answer == solution\n",
" \"🥳 Well done! \"\n",
" else\n",
" \"It's not correct. Keep trying! 💪\"\n",
" end |> println\n",
"end\n",
"gauss_seidel_1_check(answer) = answer_checker(answer,\"c\")\n",
"jacobi_1_check(answer) = answer_checker(answer, \"d\")\n",
"jacobi_2_check(answer) = answer_checker(answer, \"b\")\n",
"jacobi_3_check(answer) = answer_checker(answer, \"c\")\n",
"lh_check(answer) = answer_checker(answer, \"c\")\n",
"sndrcv_check(answer) = answer_checker(answer,\"b\")\n",
"function partition_1d_answer(bool)\n",
" bool || return\n",
" msg = \"\"\"\n",
"- We update N^2/P items per iteration\n",
"- We need data from 2 neighbors (2 messages per iteration)\n",
"- We communicate N items per message\n",
"- Communication/computation ratio is 2N/(N^2/P) = 2P/N =O(P/N)\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function partition_2d_answer(bool)\n",
" bool || return\n",
" msg = \"\"\"\n",
"- We update N^2/P items per iteration\n",
"- We need data from 4 neighbors (4 messages per iteration)\n",
"- We communicate N/sqrt(P) items per message\n",
"- Communication/computation ratio is (4N/sqrt(P)/(N^2/P)= 4sqrt(P)/N =O(sqrt(P)/N)\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function partition_cyclic_answer(bool)\n",
" bool || return\n",
" msg = \"\"\"\n",
"- We update N^2/P items\n",
"- We need data from 4 neighbors (4 messages per iteration)\n",
"- We communicate N^2/P items per message (the full data owned by the neighbor)\n",
"- Communication/computation ratio is O(1)\n",
" \"\"\"\n",
"println(msg)\n",
"end\n",
"function sndrcv_fix_answer(bool)\n",
" bool || return\n",
" msg = \"\"\"\n",
" One needs to carefully order the sends and the receives to avoid cyclic dependencies\n",
" that might result in deadlocks. The actual implementation is left as an exercise. \n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"jacobitest_check(answer) = answer_checker(answer,\"a\")\n",
"function jacobitest_why(bool)\n",
" bool || return\n",
" msg = \"\"\"\n",
" The test will pass. The parallel implementation does exactly the same operations\n",
" in exactly the same order than the sequential one. Thus, the result should be\n",
" exactly the same. Note however this is often not true in other parallel algorithms.\n",
" Specially, when one does parallel reductions.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"gauss_seidel_2_check(answer) = answer_checker(answer,\"d\")\n",
"function gauss_seidel_2_why(bool)\n",
" bool || return\n",
" msg = \"\"\"\n",
" All \"red\" cells can be updated in parallel as they only depend on the values of \"black\" cells.\n",
" In order workds, we can update the \"red\" cells in any order whithout changing the result. They only\n",
" depend on values in the \"black\" cells, which will not change during the loop over \"red\" cells.\n",
" Similarly, all \"black\" cells can be updated in parallel as they only depend on \"red\" cells.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"println(\"🥳 Well done! \")"
]
},
{
"cell_type": "markdown",
"id": "d4cb59d5",
"metadata": {},
"source": [
"## The Jacobi method for the Laplace equation\n",
"\n",
"\n",
"The [Jacobi method](https://en.wikipedia.org/wiki/Jacobi_method) is a numerical tool to solve systems of linear algebraic equations. One of the main applications of the Jacobi method is to solve the equations resulting from boundary value problems (BVPs). I.e., given the values at the boundary (of a grid), we are interested in finding the interior values that fulfill a certain equation.\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "6a2bdbc6",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkQAAAEVCAYAAAAB2vqVAAAACXBIWXMAAB7CAAAewgFu0HU+AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAIABJREFUeJzt3XecXHW5+PHPbnpIIxgChhJAQhWViIKIgCIqSLGBV0QvihQBCyrCVRFRQP151WsBsfdCEWFd1HtBrKA0BQxIUDqBEDpJKMnu/v54ZpizszO7OzNn5pzd83m/XvPac2bOnHl2yjnP+daunp6eASRJkgqsO+sAJEmSsmZCJEmSCm9icqW7u/s1/f39t2cUiyRJUkd0d3cv7O/v/1V5fWLV47fut99+SzsckyRJUkf19vb2J9etMpMkSYVnQiRJkgrPhEiSJBWeCZEkSSo8EyJJklR4JkSSJKnwTIgkSVLhmRBJkqTCMyGSJEmFZ0IkSZIKz4RIkiQVngmRJEkqPBMiSZJUeCZEkiSp8EyIJElS4ZkQSZKkwjMhkiRJhWdCJEmSCs+ESFInTQXWBbqyDkSSkkyIJLXT+sAxwMXAA8ATwENAH3Aj8CVg68yi64xTgZuI90FSTk3MOgBJ49aXgHcRpUKPAucC/yQSoi2BtwHHAUcBHwH+XzZhttVmwMdKy/8DfJtICttpHvC80vI/gPva/HrSuGBCJKldDiWSoRuBVwLLqh4/A+gBdgc+C6wCzuxkgB2wAlgOzAf+BTzZgdfcFbigtHwo8MMOvKY05lllJqme9wHnAO9tcT/vYGgyBPA48BbgqdL6GcDsFl8rb1YCOwL/QSQqA9mGI6keEyJJ9ewMvAl4cQv7WA5cOczjy4DLSsuzgL1beK28Wgb8FHgw60Ak1WeVmaR2+QTRfmWkUpGlwKtLy89pa0SSVIcJkTQ2HAdMr7rvXOBW4CXAscBzgUlEgvF94HyyraL54ii3m5xYXt3ka32IoSXePwLuBvYlGnBvDUwB7iLa2HyLSnXdcBYA/wm8AtiAGDJgOVGy9T3g9jrP+3CN+74P3JtY3434/JJuAX4OPAt4T+J17wMuJd7Xh2rse39gG2C7xH2vLcWf9EtgSdV9i4G3Ay8k2jv1Ee/d1cR79Res7tN419PTM1C+9fb2Lso6Hkk1LSdOSMnbPsD7gf4ajw0QvZpa8dPSfn7c4n5G0ksl5t2b3MfTDP3/X0b06hogkpZriESi/PgSYJMR9vseorH3ANE4/OvA14DrS/c9CZxY57m1Ppedqrb5ZI1tLgC2Au6s8dgAkQRvWOP1flJn++rbWxPP6QJOJxKgPuCS0v/3LSIZKj/nTmD7Ov+nNCb19vYuSuZAtiGSxoatgLnA0Yn7XgZ8FHg3cWLfgGjzUy6BeA+wSwdjbMZUKiUkNwN/bHI/84n354TEfccDexKNmRcSpSDzifelD9iWSABm1NnnR4ikcjpwElHycgQxTMAOpf1MIRqDn1Hj+euVYjp5mLhPL20zl0pp1SSi9O+3pZjnlv5eWHp8M+C0Gvs6vLRtMuE5KrH/8u2cxOOHlP63J4jvyl6l57yTKC06iHivNiZKrKRxy4RIGhseAR5mcJXS+4DXEVf0dxGlSOcBRya2OaRTATbpAGBOafk0olSlGQ+XbskxfvYB9gMuT9y3BvgylQRmS6KtU7WXJO4/D/g0Q6uMvgx8t7T8YSKZGCmmak8ktit7JfB3opru2tJj1xLJ7p2lbQ4iEqekVaVtV9W4L3l7OvH44aW/l1C78fu5RKmYNO6ZEElj1++AP9S4/zdUTnrP71g0jZsOfKq0fCHwg5T3fxExMGEtn6NSInM4Q0uJPgJMKC1/fpjXKD/WxfAlQY2YRGUwx6Q1xGcLsA6QRhOHhaW/U4fZ5nwiYXp4mG2kMc9G1dLYVa966WliQMAFxKjF9RwNbDrM4+XRjp9PlJDUcztRStWo04heZXcQI1qn7c/DPPYocAWwB9Hdf3eiLRMM7v7/OPDXYfZzA9HYeQOigfSGDG403Yy7iPeklnsSy8N9tqN1N/Ed2Jv4DL7J0JKwS0s3aVwzIZLGrnuGeexBIiGaNsw2hxDta0ayTelWzx9pPCE6nKjyewB4FZHApW249wdifrE9Sss7UkmIdqJybLyFkavx/kkkRBBjN10wzLajMVzcyd5lw322o/V14jvQVVp+H9Fz7lzgthT2L40ZJkTS2DVcEjGa+bJuZviqks2JmekfYviT482jeK2k1wJnAY+Vlht9/mgtH+Hx5ECJ69dZfmQUr5OsSpo/iu1H0urn2ogfEP/v6URV3bbAZ0q364lpP75DJK7SuGZCJI1drY4L884RHv8pcDDRbuUtLb5W2auI0ofVxGCMw1VHtapvhMfXJJan1FleO4rXqbefZjXbsLwZA0R7qp8QPejeRqVd0Q7EHHOfIMZ5+moH45I6zkbVkjrlVcAviDZOryba8LTTrBEen5lYfrjOcvVgmLUkG2TXGjBxLLgH+DhRKrgz8BUq/8u00no72nlJuWFCJKkTRpMMbQxslOJrVo/QXG1hYnlpYvnGxPJwjc5rbXNj3a3GhgGi1O44YmyrryQeOymTiKQOMSGS1G7JZOg11C8Z+h1wcYqvO9y8aF1ESUhZssfeLVSm49iI2qNCl82m0v39AWL8oKw1UpV6CvDmOo+tIgafvKG0vpB0GnJLuWRCJKmdXs3gZOjy4TdP1ZsYPE9a0l5USqP+xOASIohBFyESp+HaTyUHSDyTkdstdUKy2q66yu9rxEjVs0vr7wU+MMy+ytN2QIzbNJq536QxyUbVktrl1UQX9KnAr4lxenYbZvs5DB5luVUziN5SxzO41GQelaqgfgZP91H2VSIRWkxUFZ3P0ElcNyTa3UB0vf9sGkGn4K7E8gaJ5VlEQ/pHS7eyHYlpO2qV3M2jUpJ2EZ1t8C11lAmRNDacAGxBTDVRdiwx9cUfie7RM4keQxDzXUF0mz+7tPx52tfFvdq6VJIhgANLt5GMNHZQIz5AzEX2IqJU5H5iTrgjqFSDHU/tROApIt6LgeeWtvk48HsiKdiV6H21APgXMXxAdTL3NaKEaYfEfScR3epvLMW2CzFFB1SOx8+n8pmVp2E5unT/1ol9HVeK8SpiQMWyO4gSr0XAoUQy+hjwX6XX+EVVnN2lbT5b+v/uJpLJnYAPEnOy3VlalsYtEyJpbNgTeHFpudwLaufSbTWREE0hqomo2q583w9pLCGqNTfWaE0ixsxpdNycx5p4rXpuI96zbwJfrHrsViJhqk4Oku4m5jQ7gUhIzq56/GEiAT2N2uMVvYlIiMrbQmUgyN8SCdGmVD6f8v8+O3FfOSHalZibLbmv8uffzeCEqDyj/TlEO6rk0Aa/YnBisx/wjtK+P8VQK4kBG09m5HGdpDGtq6en55mi5O7u7q323Xff6rp0SRorjqXS/mc3on0QRIPgLYk2NbcTgw420vi4myjp2YhIcpYB1zG6cYqyMoEoJdoceJJoLH5nnW27iORsM2JW+yeJ//Ef2G5I41Rvb++i/v7+Zy4SLSGSVAS3M7QNUCP6iR5keehFNlp9xPQkN41i2wFaf4+kMc1eZpIkqfBMiCRJUuFZZSZpPPgQcYG3S+K+Q4jGyHcSc3VJUl0mRJLGg9OoDJBYdlTp7+8wIZI0AhMiSePB/GEey3NPMEk5YUIkaTx4eORNJKk+G1VLkqTCMyGSJEmFZ0IkSZIKz4RIkiQVngmRJEkqPBMiSZJUeCZEkiSp8EyIJElS4ZkQSZKkwjMhkiRJhWdCJEmSCs+ESJIkFZ4JkSRJKjwTIkmSVHgmRJIkqfBMiCRJUuGZEEmSpMIzIZIkSYU3MesAxpH5wNTE+uPAQxnFIkmSGmAJUXrOBW5P3D6bYSySJKVhHnBf1W33TCNqE0uIJElSPROIGpCkKVkE0m6WEEmSpMIzIZIkSYVnQiRJkgrPhEiSJBWeCZEkSSo8EyJJklR4JkSSJKnwTIgkSVLhmRBJkqTCMyGSJEmFZ0IkSZIKz7nM0jEVWLfqvg2IOWD6Oh/OENOAlwELgTnAcuBfwBXkI77pxGSBmwKziPhuAf4C9GcYV9k6VOKbScR3M3Al+YhvBpX41iHi+ydwFTCQYVxls4jv36bEZ70cuBG4hnzEN5tKfFOB+4F/ANdmGVTCusBuwCZEfMuB64HrsgwqYS7x/m0MTCbev78DN2QZVMKziPdvIyK+5cDfgCVZBpUwj3j/FhDn5PuBq4nfcB7Mq3HfRh2PohN6enoGyrfe3t5FWcczxmwMfAN4nDiwV99WAJ8mkpAsbAp8B1hZJ777gU8RJ4QsbAZ8H1hVJ777gFOIE34WtgR+DKyuE98y4GNEEpKFrYCfAU/Uie9u4EQiIc7CtsD5wJN14rsT+BBxks/CDsAvgKfqxHc78H6ym8jyBUAP8HSd+G4FjgUmZRTfTsDFwJo68f0LODrD+HYGfgOsrRPfzcDhxIVrFnYFLhkmvpuAwzKMbw/gMuKiuVZ8S4BDGcM1Tb29vYuSOZAJUfMOof6JslbisUeH4zuM+ifKWonHSzsc3xHUPxHVOrG/uMPxHUf9E1GtE/viDsf3AeqfiGqdOHfocHwnUf9AX327Bdiug7F1AR+n/oG+1olpqw7G1w2c1kB8NwBbdDC+CcD/I0pHRxPf34nS6U6ZCPxPA/FdRWdLPCYBZ44ytgGiJH/DDsY3GfhWA/H9EZjfwfhSY0KUjvcx+h9b+fY0sH+H4vtwg7ENEFfxr+lQfCc3Ed8TwMs7FN/pTcS3iiiW74T/biK+x+lcUvmVJuJ7FNixQ/F9o4n4HqYzSWUXUWraaHwPANt0IL5uolSy0fiWEyWunYjvgibiW0ZnkraJQG8T8d1JZ5K2ScD/NRHfbXQ2aUtFdUI0Zou6MvQq4HPEgasRk4AfEdUI7bQfcUJv1BTgJ0C7k+I3EtVgjZoKnEtUs7XTIUTpRqOmE9VDG6cbzhDvAI5v4nkziBNFuw9aRwPHNPG8WcCF1G6vkKb3E9UkjZpDxDc33XCG+DBRDdGo9YCLaH/198nAQU08b33i/Wt39fdpwIFNPG9DIr52Vy9/FtiniedtTMTX7urbLwJ7NfG8hcTxJavq0VSYEDVmEvBlmq/TnQF8Ib1whphMfKGb/VxnE8leu0wDPk/jyWTZXOAz6YUzxAyi9KVZ82guGR2tOcQBtVkbAqemFEstzwLOaOH5GxFVWe2yPvCJFp6/EPhIOqHUtIBok9as5wAnpBRLLQuJNmnN2oao6m2XRS3ufwfgPSnFUsv2Le5/R+KCo12eBxzVwvNfTHMXG7lhQtSYg2m92Hdv4EUpxFLLocDmLe5jP+KH0Q6H0XoJyhuBrVOIpZYjaL0u/C20/hnUczRREtCKw2hf0fuxtF5CkcZnUM/xRC/BVhzD0B6lafkgUdLYivfR+v9Yz4dpvYTieNpXCnMirZdQnEBcWLbDSbTeQPrEFPZRz8m0nhP8Vwr7yMyYDTwjr8vZftq13zzH15XSfmpJY7/dwAEp7KeWNOKbQL7jm0Qk5e2QRnxTgH1T2E8tacQ3HXh1Cvupltb3ehbNVcmMZALptNGcS3s6wEwmne/NfNrTAWYa6XxvNiJ6H45JXT09PQPlle7u7q323XffpVkGlHPLSKcNxmrgjhT2U20R6Vw9rCIa8aVtK9JJwlcCd6Wwn2pb03x1XtJjwD0p7Cepi/RKxh4lvstp6ia9nliPAPemtK+yCaTXPu5homdmmiaSXqPjh4hGzGmaRFTJpeFBoudtmqaQXsnsCqKRepqmkl77x/uJ9zBN00ivUfn7iaYbudfb27uov7//5vK6AzOO3kSiDUIaptOZHiHNWod8xzeDfMc3q3TLq9lkN/bUaMwhu7G7RmNd2ldtloa5tL/xdyvWo/Wq33aaR/sb97difdI7F7XDs7MOoFlWmUmSpLSkUcqeCROi0VtLFKVKkqTa0m4u0DFWmTXmCtJp+PhX4A8p7KfaG0inHv1y4M8p7KfaQcR0Iq36IzHPWdreQnR9btVlxFxEaTuUmCOvVZcQczml7T9Jp6rh17RnHqzDSaeqq5eYiy1tR5JOVetFxLQUaeoiejmmMU3Nz4F/p7CfpG7g3aTTg+1cYtqWNE0gemGm0YPtJ8To/WmaRPSgTGMcoXYcmzvChKgxF5BOQvReIilK21JiFN5WHUMMt5+2O4hRjFsxQJw4bmo9nCGW0/o4TP3Au0j/gA/R2Pi0FvfRR3S9T/uACjGa+Mkt7mMNkVil3SgY4rvT6jg9TwFvIxoup20ycWxoxWrgrcTI5GmbQWvj1EDE9Vbiu5K2ucR3uxUPEfE93Xo4Q2xAXHS14n7iwqgdk3JvAry+xX3cQ0x6PSZZZdaYnxITFrbif2lPMgQx5P+tLe6jh/YkQwDfpvUT8Xm0JxkCOJvWT8Q/pj3JEMT8R632LvkO7UmGIAYtfbTFfXyd9iRDEINutpoofJX2JEMQ84OtbnEfX6Q9yRDEoKhPtbiPz9GeZAhiIu21Le7jM7QnGYIYtLTVROb0FPZRz6nEBV0rPpXCPjJjQtSYNcSkn81+4CtpbtqF0Xqa6PI4MNKGdTxGDA7XLk/QWnwPE4PDtctKWvv/HyAGJmuXR2ithOM+Wi/BGc4DNDftSdk9tDaS9Ejup7WRsO+g9RK64dwDfLKF5/+L1kYyH8ntRNLRrH8SI9W3y1JaK+G9gUjq2+UfwJdaeP7fgK+lFEst1xEXhc26kpgUdswyIWrcr4EPNfG8tURR55J0wxniIpqbXuBp4D+Ig0o7nUdz00c8RbRBui3dcIb4Ic1ND/IE0YarHeMjJX2b5sb4WEUUh6c9vk+1s0q3Rj1OzEHV7o4LXyDew0Y9SgxM2K7SobLPEHMeNuohIr5WS+hGcirxG27UCmLgxJXphjPER4ljYKPuI96/dpVelZ1AnEMadQ8RX6sldCN5L/DbJp53B9GcZE264XSWCVFzPg+8ndH/eB4gJoX9RdsiGuwMogHpaH889wOvBC5uW0SDnUI0gBxt0fS9wJ5EY+BOOJEoyRrtj/tuYHfa01C+lvcTB9bRVg/cToxue0W7AqpyDHFiGm3R/r+Bl9Cehui1HE6UxIy2pHcpsAtxBd1uA0QbpU8z+pLUG4GdaU9D72r9wJuJxHK08V1PzHN1S7uCSugjLkwaaat4LRFfuy+2IH6z+9NYScyVRHztvtiCOObtA3y3gedcTnz/0h7stfPK09739PQM9Pb2tnum8/FmE6KIcCVxcKi+PUgUYWc1iNtC4HtE6UCt+FYQyVNWg/RtQZTIrK4T3/3EFWm75mYaySKi3dgTdeK7j6iCafcM3vVsQ/SIebJOfMuIKrxW58dq1vZER4Sn6sR3N1EF2u4Zxut5HlGa8HSd+O4kJgtt9wzj9SwmerStqRPf7cQVfbvm3hrJi4jSjrV14ruV9HouNeMlxEVUvfhuIebOy6pz0W5Ej9S+OvHdDLyT9s1dNpI9gd8PE99NRMHAmC1Y6e3tXZTMgZy6Ix3TiCx++8R9vUQVQKuN/NIwHXgZ0SV/DtFo9Raia327Gug1Yh2ihGVzotvxfcTB4C/kI74ZRHybEfHdSyW+PDQgnEXEt5BIHpcRB6uryEd8s4n4NiXey2R8zbYnS9McKvGtQ8S3BLiGfMQ3l4hvY+K3vIxoj3JtlkElrEclvmlEfNfTvs4ZjZpHxLeAmEJjGRFbO4Z2aMZ84vi8gEi+lxGfbbubV4zWDgwtHT2cMd5eCJy6o12eIBr8Jt1HPpIhiBKYZuqtO2UVnauua8ZKIsHNq8eI3oF59SjNtevolEeAC7MOYhgPESVtefUgMbZQXq2guXZPnbKcKOnNq1rzznWi+q7jxmxRlyRJUlpMiCRJUuGZEEmSpMIzIZIkSYVnQiRJkgrPhEiSJBWeCZEkSSo8EyJJklR4JkSSJKnwTIgkSVLhmRBJkqTCcy6z9PQxeCLNPEyqKUmSRsGEKD17Zh2AJEkpewDYqeq+pVkE0m4mRJIkqZ61wNVZB9EJtiGSJEmFZ0IkSZIKz4RIkiQVngmRJEkqPBMiSZJUeCZEkiSp8Ox2n56pwIHALsDGwDTgXmK8hp8Bt2UXmiRJGo4JUeu6gOOAU4B162xzOvBL4EgiSZIkKc+OAGaMcttrgN+3MZaOMCFqzRTgXGC/0vpq4GzgEuAxYHsiWdq2tM3OwAHAFR2PVJKk0TsF2HCU234RE6LC+zKVZGgF8ArghsTjfwK+AXwfeAswD+gBXgz8u3NhSpLUkAuBuaXlWcCrE489Cvwmsf63TgXVTiZEzTsMeFdi/e0MTobK+krbvhBYBKwH/JgoLRpoc4ySJDXj6MTytgxOiO4CDu5sOO1nL7PmTANOTaxfAvxqmO2fBk5KrL8IeGMb4pIkSU0wIWrOO4GNEuvfHcVzeoAHE+sfTzMgSZLUPBOi5iSLCtcSda0jWUP0NCvbjmh0LUmSMmZC1Lj5xFhDZUuAlaN87l+r1t+QSkSSJKklJkSN2x2YkFi/toHnXlO1vkfL0UiSpJaZEDVuu6r1Rkagvr1qfdvWQpEkSWkwIWpcdUK0rIHnriB6nJWtDzyr5YgkSVJLTIgat3HV+v0NPHeASIqSNmktHEmS1CoTosbNrFp/osHnP1m1Ptq5YiRJUpuYEDWuOoF5qsHnVydE1QmWJEnqMBOixk2rWl/T4POfrlqf3kIskiQpBSZEjauuIpvU4PMnV62vbiEWSZKUAhOixlUPwjilwedPrVp/vIVYJElSCkyIGledwFRXoY2kevvRjnItSZLaxISocXdWrc9v4LndwLwR9idJkjrMhKhxS6rWFzTw3PUZ3OZoOfBAyxFJkqSWmBA1rjohWtjAczetWr+xtVAkSVIaTIgadxmwNrG+uIHnvrBq/dLWw5EkSa0yIWrcA8CfE+vbMvrBFV9UtX5BKhFJkpR/+wNHAHtmHUgtJkTN+WlieQJw4CieMxl4bWL9OqwykyQVx4nA2cDhWQdSiwlRc74D3JFYP2wUzzkAmJtY/0SqEUmSpKaZEDXnKeBjifU9gf2G2X4qcEZi/QrgF22IS5IkNcGEqHk/AL6RWP8u8IIa200mqti2KK3fCxwMDLQzOEmSNHoTsw5gjDsGmA0cRFSHXQF8E/gt8BiwHXAs8JzS9suIqrO7Oh6pJEmjt5BKjrBJ1WPzgP9qYp+NjNvXcSZErVlDlPZcCnySGHjxmNItqQ84n0iOVnQyQEmSmnA5sGGdx+YDp3Uwlo4wIUrH14mG1vsALyWy4JlESdBS4ByidEiSpLHgcWBGm/a9uk37bYkJUXrWABeWbpIkjWVbZR1Ap9moWpIkFZ4JkSRJKjwTIkmSVHgmRJIkqfBMiCRJUuGZEEmSpMIzIZIkSYVnQiRJkgrPhEiSJBWeCZEkSSo8EyJJklR4JkSSJKnwTIgkSVLhmRBJkqTCMyGSJEmFZ0IkSZIKz4RIkiQVngmRJEkqPBMiSZJUeCZEkiSp8EyIJElS4ZkQSZKkwjMhkiRJhWdCJEmSCs+ESJIkFZ4JkSRJKjwTIkmSVHgmRJIkqfBMiCRJUuGZEEmSpMIzIZIkSYU3MesA8uCss87atbu7e5us46hnyZIl86666qqtAfr6+tZceeWVf8k6piqTgJ0T69cAqzOKpZ4dgXVKy/8GlmUYSy1bAM8uLT8A3JRhLLU8Cyj/RtYAef8OXgusyiiWevwOtmY9YNvS8lrgigxjqWUisEti/W/AyoxiqWnx4sU7Tp48eR2A7bbb7taddtrpnqxjqmdgYOCOo4466v86+ZomREB3d/ehwJFZx1HP6tWrueKKQb/9d2YVyyi9LesA1HZ+B5W1d2QdwAhy9x285pprnlneaKONMoxkZF1dXRcBHU2IrDKTJEmFZwnRUKuBFVkHkdTX1zcXmAnQ1dXFwMDAHRmHVG0SlaJ2iPcvb1VmmwBdpeXcfcbE+zeptNwH3J1hLLWsC8xKrOftOzgRWJBY9zvYOL+Dran+Dj5Azqptu7u7N+nv7+8C6O/vfwK4P+OQqj1zrsuCCdFQvzryyCPfmHUQSbvtttuXgOMApk+fPrBq1aqF2UY0xPbADYn1o4CfZxRLPU8Bk0vLFwNvyjCWWv4BbFdaXg4szC6Umr4AvK+0PED+4tuawW1ejgHOzSiWep4EppSWfwO8PsNYarkeeG5peQX5+4w/B3ygtJzH7+CWwNLE+nuAn2QUS03z5s17Yvny5VMB7r777v898sgjD8w6pqSzzz77y8CxWb2+VWaSJKnwTIgkSVLhmRBJkqTCMyGSJEmFZ0IkSZIKz4RIkiQVngmRJEkqPMch6pxJwAuAnYAZpfu+ADydWUSSJDVuDjF34PbABOA24JxMI0qBCVH7HQB8iJjYcVrVY2diQiRJGhs+A+xHDITalbj/N5gQaRReCOxaWl5LDOe+QXbhMAnYG9gd2IgY8fVfwAXA3zOMK2kK8GpgN2Io/D7gFuA8YEmGcZWtRyS6i4F5xPD81wI/Ix9D4c8E9gdeRHzXniRGwv4ZcGeGcZUtIN6/5xHTMTwKXEkcUB/NMK6yzYj377nEVBEPETOrn0c+pmJ4IfH72BKYCtwDXAr8CujPMK6JwF7AHsDGpftuBS4Ers4opmrTgNcSs9I/G1hDjHB+LnGMyYNJwKuAl5G/Y/T+RDIE8Fjp76w624457U6IPkIc9AB+yvDTOUwGfphY/xD5m6umGdcT78PlwFXAfwDfyCiWQ4kMf8Maj51MlFgdS/wAs3IE8Cki0aj2ceC/ie9GFiYCXyJmep9c9dh/AqeX/p7f0agG+yTwfmCdGo99iph+46yORlQxm/iOHUwUsycdDpwGvBH4Q4fjKlsfOJtI1rqqHjuSeP8OIJLfLCwGvkYkRNXeD/yVONk/0MmgSg4ifpu1plD/KPBt4rfd18mgqnygFMucGo+dShwDT+9oREO9jThG17poPhn4CjElSFbH6POIOe4uJy5Oe4nkfFxod0K0G5HpAlw3wrYTGDy/1GmMj4QoT/MpvZ1Ihq4grtruIg5gRwBbAO8mvuRnZhUgkWzMI06KPcAyYFPihLQp8EFi3rTvZxCU5HF3AAAL/0lEQVTbNOBooprzHOAyYCVRHfouom3Yj4C/EVfGWTiOiLMHuIQ4OW5LzC+3HvBV4irzigxiWwC8hXjPzgP+TFyh7wIcRnzuPweeAzySQXxbAQeWXvsc4C9EYvQy4K3Eb+WC0nZPZhDfK4lk6HbiAnMJcXX+euAVwIuBbxL/Q6eV35+riPfoDqIE5nDi/XoHURLzuQxiKzuKSMr/jyhNW058144ijounERewv8wqQOKCagMi4biQSD42Jo4vWxAXrEuIxDgLH8vodTvCKrNi+QdxJVR9BX4WcRLfgvjhZZkQXUtcAf216v6ziYPVAiLGLBIigB8DH2bwTOA/JE7wfyKq+94GnNLxyMKviSvJpVX3f59IhKYRSWcWCVE/cYV7CvBg4v7vEcnlT4mk7Q3AtzodHJGcfRo4g0p1AETpxpVEMrkJcZF3Yceji6q7dwHfJarfy84kvoOHEFUa84mTfSf9E/gfouou6UyiumwbIvYsE6I/Ed+t66vu/1bpvrlEjFkmRDcQJeF/rLr/TOL3uzlxAZtVQjSu2e2+WN5H7eqIx4GLSsubdy6cmo5maDIEcTK4uLScVYyPEyedu2s8djnR0wKyfQ/fzNBkiNJ9V5WWs4rvn0QJ1oM1HjsfeKK0nFV8fwFOYnAyVPajxHJW8X2dKAFaW+OxcnODLqINVKedwNBkCGA1lSrkzRlaFdlJhzE0GYJog3VZaTnr4997GZoMQb6O0eOWCZHK5pf+Lss0iuHlOcbJRANhyGd8XeT7/VuXSrusPMY3P7Gcx/iSbU7yFl/5vbuXbNsnDifPv42ysRDjmGZCJIA9iUaRkF2D75HsSzQYhXzGeDpxUn+a7KrzhvNeoi3HAFHKkCddRFXaBOBh8tXuDqJpwZdLy8uolFTmxXwqVbS/IR89CcteQrRdhCjhyqNDgZeWlvMa48vJ/zF6zDMh0kuAXxAH/YuJdgB583KikWs30VYnbweEjxA9WCCqJW/MMJZaDiN6AEG0j/lddqEM0UW0jziI6IF0GPkYuqBsIlEdtTfwFNEo/PFMIxpsHvC/RIeDu4j2YXmxmGiPMxn4LdF7Km8OpNJe7etk20O0nl2JY/QEolfXl7INZ/yyUfXIJhFdmUfSR5wYx5LFRCPcmcRJ8k1k2y22lpcSB9VpRM+Qt5KvYvcPEd2xIT7/rLq013MIUSLUTSQeH802nCG+RPTy6Sd6JGXRWLmeLqIB88FEyd/BwO+zDKjKbKIn4Q5EddTeRHuYPHgu0ZtrXaIB/+uIRut5sg9xoTWJGKPr3dmGU9NOxHFvJtHOqXzhoDYwIRrZJKJX0UjWMLYSotlEI72ZRGPSfYkGkHkyj+jCO424wnwdcZWeF6+kctV7KtmPYVJtB6KHVDdxFZz1GFPV3kHEBDGswnezC6WmDxIJZT9RMpSnZA3i/dqBqGZ8OdFoPQ/WIY4t6xK9V19FvkrVABYSSdAkovTlEPKXaMwhvnMziU4bryV/x+hxxYRoZGuAE0exXZYjxDbjXcQ4IQ8R45jk8Yd2DPAs4ur3IPKVDEF0b+8iqhpPyTaUmk4iqiuuIa5+85QMdRHvH1R6T+XJZOL9A/gs+atKeR6V8YbeRn6SIYg2QwuJJOhA8pcMQVRxzyBGgD6U/CVDEN3rNyR6Zb6BfB6jxxUTopGtIZ91363asfT390TCkUeLS38voXZX7ayV4zuHfCUbZeXP+ALyN2feekS7F4jxh/JmMyq9Bn+SZSB1lL97j5O/Rt7l793l5KuBd1I5xl8SA4XmUfIYfV+WgRRFnhpV5ymWIihPNFtrzJW8yHuM5fjyeAUM+Y4vOdGx8TWuHN9K8lc6nfffLRijamh3CVHyqrl67qJqs9sZiIb4INEYOI8lL2XvJurPV2QdSB3lOaX+nWkU9e1LVP3clXUgNSyn8v7dlGUgdSylEl8ex30pTy2St4bKEA33P0+0bcqrQ4Dp5Ld0HOB4om1ino/R40q7E6LkzNDz624VntPOQDI0m+gpULZNYnkPKqPzrqKz0ynk9SSeVGvE5Ty5JusARnBD1gEM42ny/f6tJt/xrSC/Fwq3URm1Pa/ymIRXy+MxeksqVd0QVd/lv3sl7r+NfMY/rHYnRMnMttYsyEmvaGcgGdqW6H5ay0WJ5RuB7dofzjOmAIuAW8hmosrRmEr8AJeSvwbVEAeB9cnvwXUmcfC6kfxVq0A0GJ1Ofg+cGxNV+XmdZHprIinKWwnCJCK2f5PfhsDrEFNg3ETtqVDyII/H6COpjLmW9EIGn+dOJeZkG1PanRAlB6h7GfElXFVju1lEi/rxaCWju9Ls5BXVNGKyyu2JA8JO1P5csjSLeN+eQ3Td3YV8JUUvJoYCmE6MpfPebMMZYgviM55LNKp+fbbhDHEAMSL1JGIspywn/azl7cSQBRDHpiwmmx3O14iT00qipDkvpVmTiZLuHYmEaDHwaKYRDTWfmET62USD5ZeTvwuG6cTcg9sS59GdyEdyeTej+67luSqyrnYnRJcklucQo+W+m8FfvtnEeBDJuXjGkxuotEXIix2JZAiiCm8xtSd9zdIuVKpRX0CUnl2bXThDvIE4aEF0281bQrQPkQxBjN9U72IkK28mkiGI9y9vCdEhVDp6HEL+EqJDS39nEJ9vXhKi7aj0jtqC+B3/OrtwanoFkQwB7E6UBOatFHAxkQxR+rsj8KfswnnGF0u3candPbuWEF0vy44krlpPIYrdzgJuJgbu+ir5KgEYz5ZS6bmwkvgM8uZGKu2rHgZuzTCWWq5OLOflZJR0LZVODf8kX8kQDH7Prq67VXbyHt/VdZazdhsxthnE7zdv09gAXEelmuwe8tmlfSmV3o2Pk//2lONCJ8YhOoYofZhZWl9MZQyNsj8BJwCvIep11V4riCu3vYl5kJZnG05NdxEx7knM3/NItuEMcQ6RZGxKzHWVN38mqlKeT5TA5s1/E5/xTOAHGcdSy8eotA37cZaB1HEAMY3NLcSErnnxCPG73YeoUs7jOERLiPnBXgL8nHxeiC8HdqZyjM7T/H7jVicSor8TdbRfY2gi9BAxSu3HGdrrJG8DyY03N5LPq7ek60q3vOrNOoAR/IH8VYWWDZDPRK1sLfD9rIMYxiPAV7IOoo6l5L9E48rSLc/GwjF6XOnUSNVXE+1otirdJhGNs65jcOv5gzoUjyRJ0jM6PXXHzeSzvYokSSowp8uQJEmFZ0IkSZIKz4RIkiQVXqfbEI0Fk775zW/OHXmzzvnRj340pbw8MDAAlQH38mJW1foM8hdj0mTyF19y8uNu8hfflKr1vMVXPTl0Hr+DXYnlSeQvvuR3sIv8xTe1aj1v8VUfB9chZzH29/c/8x2cMGFC7s51a9eundLV1TXyhm1iQjTU/n19fbmaG2iLLbbgsssuA2D16tVd5G/uomrfyzqAEexPvt/DDch3fGPhO/jtkTfJ1GvJ93s4n3zHNxa+g98o3XJjxYrKfMALFizYJ2/nuiyTIbDKTJIkyYRIkiTJKjNg7dq1p02cOPHrWcdRz4wZM2bttddezwYYGBjou/TSS2/JOqYqE4AtE+u3kr+Rxjej0g5mOTE/Wp7MB9YtLT9OzLGUJzOBBaXlPmLKiDyp/g7eRv6mZPA72Jq8fwe7gUWJ9dx9B3fbbbfNpkyZMgVgzpw591OZdy53+vr6Oj5dU1dPT095Aki6u7u32nffffM+5LokSVJLent7F/X39z8zWLRVZpIkqfBMiCRJUuGZEEmSpMIzIZIkSYVnQiRJkgrPhEiSJBWeCZEkSSo8EyJJklR4JkSSJKnwTIgkSVLhmRBJkqTCMyGSJEmFZ0IkSZIKz4RIkiQVngmRJEkqPBMiSZJUeCZEkiSp8EyIJElS4ZkQSZKkwjMhkiRJhWdCJEmSCs+ESJIkFZ4JkSRJKjwTIkmSVHgmRJIkqfBMiCRJUuGZEEmSpMIzIZIkSYVnQiRJkgrPhEiSJBWeCZEkSSo8EyJJklR4JkSSJKnwTIgkSVLhmRBJkqTCMyGSJEmFZ0IkSZIKb2LV+uY9PT0mSZIkabxbmFwZlBD19/f/qqOhSJIkZaC/v3/QuqVBkiSp8EyIJElS4f1/csf0sRRtfuMAAAAASUVORK5CYII=\" align=\"left\" width=\"300\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "93e84ff8",
"metadata": {},
"source": [
"When solving a [Laplace equation](https://en.wikipedia.org/wiki/Laplace%27s_equation) in 1D, the Jacobi method leads to the following iterative scheme: The entry $i$ of vector $u$ at iteration $t+1$ is computed as:\n",
"\n",
"$u^{t+1}_i = \\dfrac{u^t_{i-1}+u^t_{i+1}}{2}$\n",
"\n",
"\n",
"This algorithm is yet simple but shares fundamental challenges with many other algorithms used in scientific computing. This is why we are studying it here.\n"
]
},
{
"cell_type": "markdown",
"id": "e63a5792",
"metadata": {},
"source": [
"### Serial implementation\n",
"\n",
"The following code implements the iterative scheme above for boundary conditions -1 and 1 on a grid with $n$ interior points.\n",
"\n",
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> `u, u_new = u_new, u` is equivalent to `tmp = u; u = u_new; u_new = tmp`. I.e. we swap the arrays `u` and `u_new` are referring to. \n",
"</div>\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "14a58308",
"metadata": {},
"outputs": [],
"source": [
"function jacobi(n,niters)\n",
" u = zeros(n+2)\n",
" u[1] = -1\n",
" u[end] = 1\n",
" u_new = copy(u)\n",
" for t in 1:niters\n",
" for i in 2:(n+1)\n",
" u_new[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" u, u_new = u_new, u\n",
" end\n",
" u\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "432bd862",
"metadata": {},
"source": [
"If you run it for zero iterations, we will see the initial condition."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "76e1eba1",
"metadata": {},
"outputs": [],
"source": [
"jacobi(5,0)"
]
},
{
"cell_type": "markdown",
"id": "c75cb9a6",
"metadata": {},
"source": [
"If you run it for enough iterations, you will see the expected solution of the Laplace equation: values that vary linearly form -1 to 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b52be374",
"metadata": {},
"outputs": [],
"source": [
"jacobi(5,100)"
]
},
{
"cell_type": "markdown",
"id": "22fda724",
"metadata": {},
"source": [
"In our version of the Jacobi method, we return after a given number of iterations. Other stopping criteria are possible. For instance, iterate until the maximum difference between u and u_new (in absolute value) is below a tolerance."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "15de7bf5",
"metadata": {},
"outputs": [],
"source": [
"function jacobi_with_tol(n,tol)\n",
" u = zeros(n+2)\n",
" u[1] = -1\n",
" u[end] = 1\n",
" u_new = copy(u)\n",
" while true\n",
" diff = 0.0\n",
" for i in 2:(n+1)\n",
" ui_new = 0.5*(u[i-1]+u[i+1])\n",
" u_new[i] = ui_new\n",
" diff_i = abs(ui_new-u[i])\n",
" diff = max(diff_i,diff) \n",
" end\n",
" if diff < tol\n",
" return u_new\n",
" end\n",
" u, u_new = u_new, u\n",
" end\n",
" u\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "697ad307",
"metadata": {},
"outputs": [],
"source": [
"n = 5\n",
"tol = 1e-10\n",
"jacobi_with_tol(n,tol)"
]
},
{
"cell_type": "markdown",
"id": "6e085701",
"metadata": {},
"source": [
"However, we are not going to parallelize this more complex in this notebook (left as an exercise). The simpler one is already challenging enough to start with."
]
},
{
"cell_type": "markdown",
"id": "9df06442",
"metadata": {},
"source": [
"## Parallelization of the Jacobi method\n",
"\n",
"Now, let us parallelize the Jacobi method."
]
},
{
"cell_type": "markdown",
"id": "d6918c31",
"metadata": {},
"source": [
"\n",
"### Where can we exploit parallelism?\n",
"\n",
"Look at the two nested loops in the sequential implementation:\n",
"\n",
"```julia\n",
"for t in 1:nsteps\n",
" for i in 2:(n+1)\n",
" u_new[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" u, u_new = u_new, u\n",
"end\n",
"```\n",
"\n",
"- The outer loop over `t` cannot be parallelized. The value of `u` at step `t+1` depends on the value at the previous step `t`.\n",
"- The inner loop is trivially parallel. The loop iterations are independent (any order is possible).\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "97a2d7d5",
"metadata": {},
"source": [
"### Parallelization strategy\n",
"\n",
"Remember that a sufficiently large grain size is needed to achieve performance in a distributed algorithm. For Jacobi, one could update each entry of vector `u_new` in a different process, but this would not be efficient. Instead, we use a parallelization strategy with a larger grain size that is analogous to the algorithm 3 we studied for the matrix-matrix multiplication:\n",
"\n",
"- Data partition: each worker updates a consecutive section of the array `u_new` \n",
"\n",
"The following figure displays the data distribution over 3 processes."
]
},
{
"attachments": {
"fig09.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "a9667c42",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig09.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "22dc6e54",
"metadata": {},
"source": [
"### Data dependencies\n",
"\n",
"Recall the Jacobi update:\n",
"\n",
"`u_new[i] = 0.5*(u[i-1]+u[i+1])`"
]
},
{
"cell_type": "markdown",
"id": "ba4113af",
"metadata": {},
"source": [
"Note that an entry in the interior of the locally stored vector can be updated using local data only. For updating this one, communication is not needed."
]
},
{
"attachments": {
"f1.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA6gAAADyCAYAAABAvOgkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABgzSURBVHic7d19mF11YSfw750kBBIigWJiADUEBOXdRYvgCwtCX/VhH0TbLRVrdUlod/Gpq0+7a1uoL1316RarqzSpZXe77q61Pmu73bZYEFOtFUSs4BsCQhCEEEyUd4aQ3P3jnGHOTO6duTOZmfObyefzPPfJ79x7zr1fZm5O7pfzO+d2Nm7c2A0AAAC0bKjtAAAAAJAoqAAAABRi8bjln+50OlvaCAIAAMC+pdvtrk3y2ZHlMQW10+lsufjii2+b61AAAADsezZt2pRud/SySKb4AgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAowuK2AwAAPb05yZIkVyf5fstZAGBOKKgAUKY/SrIiyWsz/YK6JMmJSU5N8pIkB9f3/26SW/c2YGH+KMnLk/z3JB9p4fUXp/p9JcnjSYZbyAAw7ymoALAw/U6SdyVZ2uOxD89xlrlwdKoifu0cvd6aJOemKv6nJjklybL6sfVJNs1RDoAFRUEFgDK9LdUR0Fumuf2aVOW0m+T2JPcmOXtmopHkgizMog/QKgUVAMr0X/dy+08m+VSSryV5OMlLk3xlb0MV7Oenud2FqaZBfzrJV6e47ZYkN9W3byf5y2lmAKCmoAJAmdamutr+1lTnNE7VF2Y0zcL1r1IdDf1uplZQP5qx57oun8lQAPsqXzMDAGW6Jcn3YlruoN6c5P1JfnaOXm/3HL0OwD7FEVQAYCG4IMnP1eO/azMIANPnCCoAAABFUFABAAAogoIKAABAEZyDCgDzx7IkZ/R57LYk35/DLPPJLyZ5S5/HTqr/fEeSX+qzzvokd850KAD2pKACwPxxWJJr+jz29iRXzGGW+eTIJOdMss5x9a2XA2c2DgD9KKgAMH88nuTaPo85etrfZ5Lc0eextyd5WZKPJdncZ527ZyETAD0oqAAwf9yX5Ny2Q8xDt9a3Xt5Q//nVJH8xN3EA6MdFkgAAACiCggoAAEARTPEFgIVpbZINjeU1jfGGJK9pLH88/c/RBIA5o6ACwML03CS/2eexC8ctXxMFdaoOTvK9xnKnMb4iyfsby7+VZNNchAKY7xRUACjTFUmWZvrF8Z4kHxhwXVepnbpOqpLay7L6NmL/2Y8DsDAoqABQpsv2cvstqY7c7SvekqoU/niK2/3bVEeaH5zidj9OctSA626f4nMD7LMUVABgIdg6ze0emOZ2u5PcOc1tAejDVXwBAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAirC47QDQy5VXXnn40NDQG9rOMZGrrrrqVUk6SXLXXXfdsm3bth+1HGm8E5McUo/vSXJni1l6OSLJUfX40SQ3tZhlEFcmebLtEAzkDUkObzvEBJ6fZG09fijJ19uL0tOzkry4sfzFJLtbytLPKzP6P9m/kWRHi1km87Uk/9B2CAby/CTntx1iAp0kr2osfz3VPqQkJydZWY/vTrKlvSh7Wrt27fNXr169NklWrlz50Pnnn1/a/neM+++//yOXX375023nmGsKKkVatGjR0d1u9w/bzjGRG2+8Mbt3P/OZ7bw2sywQF7YdYBJ/FgV1vrg0ycvbDjEFF7UdYBKl799Kz/ehKKjzxYuSFP3ZY5zS3/vF2bJlS7Zs2ZIkWbduXVL4/nfNmjUbk+xzBdUUXwAAAIrgCCrzxS1tB+jhpJHB0qVLtw4PD29rM0wPx2X07/gTSW5vMUsva1NNJUySbqppeiXZP8kxbYdgrz1Q30pyVJLl1XBod7KssOn3wwclO5/duOObKW+K70mjw/13JIsLm+L7xGHJrmVtp2CvlfbZo5Pq9J0R9yX5YUtZ+jk+yaJ6/FiS77WYZQ9Lly5dNzw8fGCSdLvd3an2byVZluTotkO0TUFlvnjJ+vXrd7YdomloaKg7Mj799NM/unnz5ve2maeHB5McWo+/leSlLWbp5a+TvKYeP5nqvJWSvDjVuWPMb3+c5PK2Q4yzOcmZ1XD5E8nDhU1vP+P1yZff0bjj5UkebitNH93R4Wn/J9n8J+1F6WXVFcmDZ7Sdgr2yK+X9u7QsVekb8YEkH24pSz8/TnJQPf7nVOeLF+OEE0647qabbjorSXbu3PnY+vXri/odb9q06Yxut/ultnO0zRRfAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAvHjUm+Wt+OG3CbzzS2+alZygUAADCQxW0HYMacmqRTj5cPuM0JSY6ux4fMeCIAAIApcAQVAACAIiioAAAAFEFBBQAAoAgKKgAAAEVQUAEAACiCggoAAEARFFQAAACKoKACAABQBAUVAACAIiio+7YlbQcAAAAYoaAuHMON8dIB1u8kOXSWsgAAAEyZgrpwPNwYP2eA9Y9PsnyWsgAAAEyZgrpw3N4Ynz7A+r86W0EAAACmQ0FdOG5ojC9M8qwJ1v3JJL8+u3EAAACmZnHbAZgxn0jy9nq8OsmfJ/nlJNsb63SS/OskH0t1gaThDHa+aus6nc5LN27cuKvtHE2XXHLJM+OtW7cekeS09tL01Pz7vTzl5Tu4MR5KefmOaTsAM+LwlPfeWjE63DWUvO349qL0sn38aSKnJnm8jSSD+eGzy/sZPnVg2wmYEaXtO8Z/Znt+ysu4qDE+MIXle+SRR57Z/3Y6nUUbN24sKl+32z2u7QwlUFAXjn9OVUp/oV7+mSR3Jdmc5P5UZeCMVB/WkuSyJG9McvScppymbrf7pbYzTOTWW29dn2R92zkm8KIk17cdYgJLU3Y+5q+31rdCPX5A8uGr2k4xievaDjCxb51X3WBGLUr5/y69PaMHJ0p0Sgr7Gd52223PjJcsWbIsheWjoqAuLBtS/d+0l9XLK5K8dtw63SQfTPKeVAUVAACgCArqwvLjJGcluTTVEYMXNB7bleTqJB9Kcm193z8l2VKPt85NRAAAgN4U1IXnyVRHSD+Y5Nmpzkd9PMm9SZ4at+6b5jba4O67774vrlu3ruhzeF73utcte/rppztJ8o1vfOPJO+64o6hzZFNNmx35O74ze/7+27Y4o+fT7Er13i3ZY20HYGDnZOx5UKVZkmS/elzie38oyQGN5RLf+8tSXVchqX5+pe1/m3a2HYCBXZPqvMmSNb8i8Ikku9sK0sf+Gd3/PpXC3v+nnHLKkiOPPHK/JFmxYsWuAw44oLT97xgXXXRRwef/z57Oxo0bu88sdDrHXnzxxbdNtAEAAADMhE2bNh3T7Xa/O7Lsa2YAAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgCz7VNJrktydttBACibggoAzLZXJDkryeq2gwBQNgUVAACAIixuOwAAsOCdkmRRkh+1HQSAsimoAMBs29Z2AADmBwUVAJhtb05yYJKrk9zechYACqagAgCz7X1J1iT5pSioAEzARZIAAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAiqCgAgAAUITFbQcAABa885IsTXJr20EAKJuCCgDMthvbDgDA/GCKLwAAAEVQUAEAACiCggoAAEARFFQAAACKoKACAABQBAUVAACAIiioAAAAFEFBBQAAoAiL2w4AvWzatOmUbrf7sbZzTOR973vf8bt37+4kyfbt27c88cQTj7adaZy1SQ6sxz9MsrW9KD0dmuQ59fjJJHe0mGUQP5Pk4bZDMJArk5zcdogJrKpvSfJ4kjtbzNLL8iRHNpa/laTbUpZ+jk/Sqcd3J3mkxSyT+WSSD7cdgoGcluSKtkNMoJPqvT/iriSPtZSlnyNT7UOS5MEkD7SYZQ8HHXTQqhUrVqxKkjVr1jz+1re+tbT97xjDw8NnXXrppcNt55hrCiqlOijJ6W2HmMi9996b3bt3jyye2GaWAazI2A+cpVmR5Nlth5jEkrYDMLATU/j+o2FFktVth5jEy9oOMIkT2g4wiRvaDsDADs782XckyUltB5jEiiTr2g7R9NBDD+Whhx5Kkuy3337F73+XLl26qO0MbTDFFwAAgCI4gsq80Ol0LtvdOFxZiPeMDFatWvW5bdu2bW4xSy//IcmyevyDJH/cYpZefjnJsfX46SS/12KWXtYk+bW2Q7DXPp/kurZDjPOWVFPwk2Q4yXvbi9LTaUleM7p4wlXJop2tpenp5vWNhetS/Z5L8sYkx7Qdgr2yO8llbYcYZ0mS320s/02S61vK0s+7kuxfj+9O8vEWs+xh9erVb37ggQfWJcmuXbue6na775lsm7nU6XSem+TitnO0TUFlXuh2u/9pw4YNRX1AGhoaemandtxxx23etm1baR8y35bRgnp/yvwQPFJQd6a8fC+OgroQfCHlvbfOSdkF9dczpqB+4hPJyYWd59ZpFtQvpryf4elRUOe7bsp7Xy3L2IL69ynv/OZ3ZLSg3pPCfoZHHHHE2Y2COrxhw4ai8m3atOmMbre7zxdUU3wBAAAogoIKAABAERRUAAAAiqCgAgAAUAQFFQAAgCIoqAAAABRBQQUAAKAICioAAABFUFABAAAogoIKAABAERRUAAAAirC47QDjvCPJonr8iSQ/GGCbtyQ5tB7/TZJvzkKuES9Icn49fjzJR+rxs5L8Yv3Y85KsTLItyQ1J/luSL0/jtY6un+/sJEck+YkkD6X6mVyT5H8l+f4E2/+LJOfW4/uS/I8J1n1hkvMay19N8rkJ1n91kpfU428n+esJ1gUAABhIaQX1vUmW1uN/zGAF9e1JjqvHWzO7BfW4JO+vx9tSFdRXJPnfqUpk05okJyf5N0muTPLvkuwe4DUOSvLBJL+aPX8/z0lybKrSelmSP6j/7PW8BzSyPprkz5M81ec135TktxrLX8jEBfV3kpxZj98ZBRUAAJgBpvjunVemKnIj5fSRJHemOro6opPk11KV78kckaqYX5yx5fSeJF+rn7tb37d/kt9OdSS11+/xK3WeJDkwyWkTvO6rxy2/LMnyPusuqx8fcd0EzwsAADAwBXX6lif5dJL9UpXEU1JN9T2q/vNnk2xprP/OJOsmeL79k/zfJCfUy8NJfi/J4ammDZ9aP/dzk2xsbPcL9XOPtzPVkdAR40voiINTTQdu2i9V+e7lFRk9yr09ydf7rAcAADAlCur0LU+yKsl/THJhkpsbj+1KcnWSczJ6NHVxkl+Z4PkuT/LievxYkrPq++4bt94PkmxIdfS0ue2qHs/ZnKbbr6CemdHzfr80wPrN+z+fwaYtAwAATEpB3TvXZfQ8z16+l+R/NpZf1We9lammAY94Zya/sNLvp7qYUVIdfb24T74Rp6Wa6jtes3C+O8mTPe7vt/5E56kCAABMiYK6dz6U0XNC+2mWxOP7rHNBkhX1eHuSjw/w2t0kf9JYPrfHOrekuphTkixJ74I8UjgfTbI5o0dRT87o1ZFHHJLRo7yJ808BAIAZpKDunS9MvsqY81BXprpo0nhnNsbXpjp/dBA3NMYv7fF4N9U03BHnjHv88CQvqsdfTHWV35GjokOpphk3nZXR98w9SW4bMCcAAMCkSvuamfnkkVTfSzqZxxrjxakuMPTkuHVOboxXJ/nNATMc1BgfkOoo7CPj1vlcqgspJXtO2z27Mb62sf6Ic5L8RWPZ9F4AAGDWKKjT98SA642fAtzrCOpPNMb/sr5Nx8r0LqgjTkx1MaWRab+9CudNSX5cP9f4QqugAgAAs8YU3zL0unjRdPT6fd6Z0WnGnYw9ajpSOLelOl81qa5AvLkeH5VkbT1+bpJjGts6/xQAAJhRC6GgLoT/huZU4XeluhjRdG739Hn+8dN2k+TYJEfU489n7JHeXl9P0zx6+p3s+fU3AAAAe6W0crerMV7Ud62xVs5GkDm2rTFek+RH07z1+07SyQrntRlrsvVN7wUAAGZcaQX14cb44AHWPyTVRYXmu+sb4/FX2p0J12X0COnaVFN3Jyqc30nyg3p8dqr3ydkTrA8AALDXSiuo9zfGJw6w/nnpfdGh+eazjfELM/2LJPXzQJJvNZbPbbzG95Lc1WObkXNMVyd5fZLD6uXmOaoAAAAzprSC+rXG+PWZuHyuSPLbsxtnzvxtklsbyx/JzF04aUTzqOdvpDr6PP7+fuu/uzEeucovAADAjCqtoP5lY3xSknf0We+QJH+VZN2sJ5obu5K8M6PTcE9I8vdJnjfAtsck+WiqQj+RZuE8ps/9g6zv6r0AAMCsKO17UK9ONRX1+Hr5g0lemeTTqa4auzLJGUl+JdU5qv+Y5DlJjp7roLPg/6U6UnlZvXx6ktuSfCrJNamm4T6R6sjq4UlenGqq7sn1+l+Z5Pn/IcnTGfs7353+hfPeJN9NdbXfJuefAgAAs6K0gvp0kotSlaaD6vteW9/G+06SC7KwjuhdnuSHSf4wyZIkS5O8sb7trYeT3Jiq+I64uX69fj6XsQX1ySRfmoEsAAAAeyhtim9SnYd6ZpIb+jz+VJI/TfKTqS7+s9D8l1QXiPqzVIVwIo+lOn/1olRHmSczvsxPdjR0/OP/lOooLgAAwIwr7QjqiJtTHek7KcnLU03jfTzJ3anOzdzeWPf0jH5n6mOznOtvM3pxoe5EKzZ8p7FNMnnpTKqptW9Ksj7VlOYXJjk0yQGpLlB0X73O11MV9kG9O8l/biw/Psn6f5Wx2Yen8FoAAABTUmpBTaoCeHN9m8jDkzw+k3Ym+dEUt9k1jW1GPJnqqOdMTWN+KlMrtHuTHQAAYEpKnOILAADAPkhBBQAAoAglT/GFpg9s3Lhxd9shmi655JJnxrfccstPp/oapJIsb4yfm+QP2grSx3GN8ZKUl29V2wGYET+V6uu5SnJUY7x/ynvvnzJ28YINSWdnO1EGcm7K+x2/qO0A7LWhlPd3c/zn9vOSPK+NIBPYvzE+MoX9DLds2fLMV1MuXrx46caNG4vKl+SwtgOUYCEX1BWZmf++XZnb81zp7TfaDjCRHTt2vCLJK9rOMYHVSf592yEmsDhl52P+Oj1jv16rNPul+Pf+HW9oO8EkzqhvMJM6Kf7vZs6ub6U6PIX9DLdvH73O6tDQUHH732530GuwLmwLuaB+JsmrZ+B5bkrykhl4HgAAACawkAsq89iuXbu2Dw0N/V3bOSZy5JFHntrtdjtJsm3bttsfffTRh9rONM4LkhxUj7cmubfFLL2sTjX1OKm+8ujbLWYZxFSugE27vpyyZ74cltFpXI8mubXFLL0cmOrrzUbclMG/Wm2unJrqCFeS3J6ktP1vU+n7NkY9mKTkzx6dVO/9Ed9N8khLWfo5NtUsxiS5P8kPWsyyh0MOOWTNypUrD0+SVatWlbj/HWN4eHhX2xnasJAL6seTXDMDz7N1Bp6DKbrkkku+meTn2s4BzEvvbDsAMC/dFJ89FrQdO3Zkx44dSZI777wz119/fcuJ6GUhF9RPth0AAACAwfmaGQAAAIqgoAIAAFAEBRUAAIAiKKgAAAAUQUEFAACgCAoqAAAARVBQAQAAKIKCCgAAQBEUVAAAAIqgoAIAAFAEBRUAAIAiKKgAAAAUQUEFAACgCAoqAAAARVBQAQAAKIKCCgAAQBEUVAAAAIqgoAIAAFAEBRUAAIAiKKgAAAAUQUEFAACgCAoqAAAARVBQAQAAKIKCCgAAQBEUVAAAAIqgoAIAAFAEBRUAAIAiKKgAAAAUQUEFAACgCAoqAAAARVjcXOh2u2s3bdrUVhYAAAD2Id1ud21zefG4xz/b7XbnLg0AAADUTPEFAACgCAoqAAAARfj/lUqiwpreHXAAAAAASUVORK5CYII="
}
},
"cell_type": "markdown",
"id": "97a5079d",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:f1.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "343e60c3",
"metadata": {},
"source": [
"However, to update the entries on the boundary of the locally stored vector we need entries stored on other processors."
]
},
{
"attachments": {
"f2.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "fce954fe",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:f2.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "3f90d701",
"metadata": {},
"source": [
"Thus, in order to update the local entries in `u_new`, we also need some remote entries of vector `u` located in neighboring processes. Figure below shows the entries of `u` needed to update the local entries of `u_new` in a particular process (CPU 2)."
]
},
{
"attachments": {
"fig22.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "8e156e29",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig22.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "513f1f7e",
"metadata": {},
"source": [
"### Communication overhead\n",
"\n",
"Now that we understand which are the data dependencies, we can do the theoretical performance analysis.\n",
"\n",
"\n",
"- We update $N/P$ entries in each process at each iteration, where $N$ is the total length of the vector and $P$ the number of processes\n",
"- Thus, computation complexity is $O(N/P)$\n",
"- We need to get remote entries from 2 neighbors (2 messages per iteration)\n",
"- We need to communicate 1 entry per message\n",
"- Thus, communication complexity is $O(1)$\n",
"- Communication/computation ration is $O(P/N)$, making the algorithm potentially scalable if $P<<N$.\n"
]
},
{
"cell_type": "markdown",
"id": "1b3c8c05",
"metadata": {},
"source": [
"### Ghost (aka halo) cells\n",
"\n",
"This parallel strategy is efficient according to the theoretical analysis. But how to implement it? A usual way of implementing the Jacobi method and related algorithms is using so-called ghost cells. Ghost cells represent the missing data dependencies in the data owned by each process. After importing the appropriate values from the neighbor processes one can perform the usual sequential Jacobi update locally in the processes. Cells with gray edges are ghost (or boundary) cells in the following figure. Note that we added one ghost cell at the front and end of the local array."
]
},
{
"attachments": {
"fig13.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "98e0eb71",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig13.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "0148f9b3",
"metadata": {},
"source": [
"Thus, the algorithm is usually implemented following two main phases at each iteration Jacobi:\n",
"\n",
"1. Fill the ghost entries with communications\n",
"2. Do the Jacobi update sequentially at each process"
]
},
{
"attachments": {
"fig15.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA6gAAAFACAYAAACxyVHuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N15fFT19f/x12cmIQFkE1wANxBFrTu4b1itimQC2mKrtfrtRtXazbbWrmJba+1m7S5fv9Wqrbb5VWBugFatpe4buGvdFVcU2cISSOZ+fn+cO2QyTCAsmXszeT8fj/vIvXPv3Dm5M3PnnvvZ3DXXXOMRERERERERiVkq7gBEREREREREQAmqiIiIiIiIJERV0fLJzrlX4whEREREREREehbv/W7AP/PL7RJU59yrU6ZMeb7cQYmIiIiIiEjPM23aNLxv6xZJVXxFREREREQkEZSgioiIiIiISCIoQRUREREREZFEUIIqIiIiIiIiiaAEVURERERERBJBCaqIiIiIiIgkghJUERERERERSQQlqCIiIiIiIpIISlBFREREREQkEZSgioiIiIiISCIoQRUREREREZFEUIIqIiIiIiIiiaAEVURERERERBKhKu4ARDbGe+8aGxsvizuODbnuuusOWLhw4SCAhQsXvvbiiy++EndMRXYBRkbzy4H5McZSSn/g4ILlu4FcTLGUdPjhhx+dTqerAE455ZSnDjzwwEVxx9QR59yDdXV1s8rxWtls9nPOueHleK3NMXv27BFPPPHErgArV65c8thjjz0ed0xFBgEHFCzPjSmODRlXMP84sCSmODpyAHYcARYAL8cYy3pGjBixy7Bhw0YCbLvttsunTJmStPNvO+l0+vJTTz11TVe/ThAEewFndfXrbK7m5ub0L3/5y2Pyy88+++z8xYsXL48zphIOxn4/wT73C2KMpZQRwK7R/FLgsRhjWc/gwYMH7rXXXgfmly+55JK5MYazUWEY3jBx4sQX446jHJSgSuJddtllbsyYMd+NO44NeeGFF3jyySfzi8dsaNuEmBB3ABuRuGP4wAMPrJsfN25c4uIr5L3/LVCWBBX4DDC2TK+1yd577z3uvffewofq44qlkxL92SL58SXOK6+8wiuv2D3LUaNGQcLPv9XV1T8HujxB9d6Pds4l+re96NyR9M9+0uMDyMQdQKH333+/3XschuExqVRyK5em0+l7gR6RoCb3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"
}
},
"cell_type": "markdown",
"id": "baccd833",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig15.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "0a40846c",
"metadata": {},
"source": [
"We are going to implement this algorithm with MPI later in this notebook."
]
},
{
"cell_type": "markdown",
"id": "75f735a2",
"metadata": {},
"source": [
"## Extension to 2D\n",
"\n",
"\n",
"The Jacobi method studied so far was for a one dimensional Laplace equation. In real-world applications however, one solve equations in multiple dimensions. Typically 2D and 3D. The 2D and 3D cases are conceptually equivalent, but we will discuss the 2D case here for simplicity.\n",
"\n",
"Now, the goal is to find the interior points of a 2D grid given the values at the boundary.\n",
"\n"
]
},
{
"attachments": {
"fig17.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "18659ed7",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig17.png\" align=\"left\" width=\"400\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "ca411d89",
"metadata": {},
"source": [
"For the Laplace equation in 2D, the interior values in the computational grid (represented by a matrix $u$) are computed with this iterative scheme. The entry $(i,j)$ of matrix $u$ at iteration $t+1$ is computed as:\n",
"\n",
"\n",
"$u^{t+1}_{(i,j)} = \\dfrac{u^t_{(i-1,j)}+u^t_{(i+1,j)}+u^t_{(i,j-1)}+u^t_{(i,j+1)}}{4}$\n",
"\n",
"Note that each entry is updated as the average of the four neighbors (top,bottom,left,right) of that entry in the previous iteration. "
]
},
{
"cell_type": "markdown",
"id": "8c916627",
"metadata": {},
"source": [
"### Serial implementation\n",
"\n",
"The next code implements a simple example, where the boundary values are equal to 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1e843565",
"metadata": {},
"outputs": [],
"source": [
"function jacobi_2d(n,niters)\n",
" u = zeros(n+2,n+2)\n",
" u[1,:] = u[end,:] = u[:,1] = u[:,end] .= 1\n",
" u_new = copy(u)\n",
" for t in 1:niters\n",
" for j in 2:(n+1)\n",
" for i in 2:(n+1)\n",
" north = u[i,j+1]\n",
" south = u[i,j-1]\n",
" east = u[i+1,j]\n",
" west = u[i-1,j]\n",
" u_new[i,j] = 0.25*(north+south+east+west)\n",
" end\n",
" end\n",
" u, u_new = u_new, u\n",
" end\n",
" u\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "f4dc50b1",
"metadata": {},
"source": [
"If you run the function for zero iterations you will see the initial condition."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4acf219e",
"metadata": {},
"outputs": [],
"source": [
"n = 10\n",
"niters = 0\n",
"u = jacobi_2d(n,niters)"
]
},
{
"cell_type": "markdown",
"id": "efd4df6a",
"metadata": {},
"source": [
"If you run the problem for enough iterations, you should converge to the exact solution. In this case, the exact solution is a matrix with all values equal to one."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5c120b8b",
"metadata": {},
"outputs": [],
"source": [
"n = 10\n",
"niters = 300\n",
"u = jacobi_2d(n,niters)"
]
},
{
"cell_type": "markdown",
"id": "85895681",
"metadata": {},
"source": [
"### Where can we exploit parallelism?\n",
"\n",
"```julia\n",
"for t in 1:niters\n",
" for j in 2:(n+1)\n",
" for i in 2:(n+1)\n",
" north = u[i,j+1]\n",
" south = u[i,j-1]\n",
" east = u[i+1,j]\n",
" west = u[i-1,j]\n",
" u_new[i,j] = 0.25*(north+south+east+west)\n",
" end\n",
" end\n",
" u, u_new = u_new, u\n",
"end\n",
"```\n",
"\n",
"- The outer loop cannot be parallelized (like in the 1d case). \n",
"- The two inner loops are trivially parallel\n"
]
},
{
"cell_type": "markdown",
"id": "65e4f745",
"metadata": {},
"source": [
"### Parallelization strategies\n",
"\n",
"In 2d one has more flexibility in order to distribute the data over the processes. We consider these three alternatives:\n",
"\n",
"- 1D block row partition (each worker handles a subset of consecutive rows and all columns)\n",
"- 2D block partition (each worker handles a subset of consecutive rows and columns)\n",
"- 2D cyclic partition (each workers handles a subset of alternating rows ans columns)\n",
"\n",
"\n",
"\n",
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Other options are 1D block column partition and 1D cyclic (row or column) partition. They are not analyzed in this notebook since they are closely related to the other strategies. In Julia, in fact, it is often preferable to work with 1D block column partitions than with 1D block row partitions since matrices are stored in column major order.\n",
"</div>\n",
"\n",
"\n",
"The three partition types are depicted in the following figure for 4 processes."
]
},
{
"attachments": {
"fig-jacobi-partitions.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "11e834b5",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig-jacobi-partitions.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "7384ddfe",
"metadata": {},
"source": [
"Which of the thee alternatives is more efficient? To answer this question we need to quantify how much data is processed and communicated in each case. The following analysis assumes that the grid is of $N$ by $N$ cells and that the number of processes is $P$."
]
},
{
"cell_type": "markdown",
"id": "f733d88f",
"metadata": {},
"source": [
"### 1D block partition\n",
"\n",
"The following figure shows the portion of vector `u_new` that is updated at each iteration by a particular process (CPU 3) left picture, and which entries of `u` are needed to update this data, right picture. We use analogous figures for the other partitions below.\n"
]
},
{
"attachments": {
"g26521.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "6b983ffd",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g26521.png\" align=\"left\" width=\"400\">\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "1bc21623",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Compute the complexity of the communication over computation ratio for this data partition.\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d01f8ce8",
"metadata": {},
"outputs": [],
"source": [
"uncover = false # Change to true to see the answer\n",
"partition_1d_answer(uncover)"
]
},
{
"cell_type": "markdown",
"id": "a9bed431",
"metadata": {},
"source": [
"### 2D block partition"
]
},
{
"attachments": {
"g26305.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxIAAAGaCAYAAACbuHVXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7d15uBxVnfj/dyc3ZA8JSyBhC6uGHREICjpuaFxxA3EBNwRnRh3BBRRHHVQQBRG38JuvOjoqgugII4srOMriwiKIaNgCsm8BQkhISPr3x+m2q+tW1e2T2/eeSvJ+PU89t7vu6erPrb5dpz51lgJJI20noNlafps4ljp7lLCPlqcORJJUW49gXVEbA6kDWEtdCMwv+d0yYAnwGHA7cA1wFXAR4UQple1aP1cDixLGodExFdi09fhR4KGEsUhad/0e2Kfkd08Q6sIlwG3A1cAfgYuBpaMS3WBjgW1aj1cCf08Uh6T12IV0rjD3uiwFvgXMTRAvmTgeTvT+67MULRJvzbznqaP0nsNli4S09vk98fXho8CZwJzRD5eNM3HclOD9NXy2SNSILRLD9wdCq0PbJGAaMB3YA9gws/5w4BDgo8AXCF8ESZLWBb8F/pJ5PplQB84g1IdTWuunAe8CDgPeD3x9FGOUpOSyLRInVJQbA+wGnE5o2s1ekfnkCMeYZ4tEOrZI9MYWCWntk22ReHdFubHA3sACQpenbH343hGOMcsWibWfLRI1MiZ1AOu41cD1wL8BewHXZn73MeC1KYKSJGmUrSKMFzwa2A/4W+Z3pwHPTxGUpOGxa9PouRk4iDDQbGugAXwG+DHhAFtmDLAnsDuwGaGpeDFhwPRlwP1DvHbD3LoGoZk5r0nI8otMIxz4n07ostVu2fgToWvXiooYYo2j0/z9JOHKVZUNCPsEwtWJZQVlJgITWo+faG0XYCPgxcCWrfddRBgEGNtqM4Hw2e7QiuUOQsvDLZHbaRvO/m7/rZNy8RV95kPt3wFgf0Kr2iaE/XsXcAlwdw9/R9YY4EA63f3uozPwUtL65XrCsfePhGPLWOAkwnGvSrtVYzfCZBITCfXhLYT6sOrYPUCYhGJ6bntFx8bVlE+OshGwL+H4vCHwFPAg4ULhVa3n/TKezrG8rH4rK7+M6iv2Ywn7e0/CPhhL+DseILTUXEfYD72wrpAi9dq1qcir6G7SfV1JuX8C/ovwJSobsLYKOIfyAWs7VLw2v+STiDGEvqu/IJy4lr3uAeA4wkGoHw7ObPv/66H8mzPly7rwfC5T5h2EE+szCAe7/N+zorWdiT28dwM4ilB55bezGrgAmEVvXZv6tb9PrHhtfvlCyTYmEcbxFP1d7b/tx4T/r14cRKjoi7Z1DaEiA7s2SWujXrs2FXk73ceDslaJ+cD3CLPPlR3PVhAmNNm8ZBv7Vbw2v+QvAk0APgz8HyFRKHvdXcB7CHVDP7wjs+2Teij/vkz5j5aUaRBahe6meh/cD3x+iPdr1xVln8tq4Dx6ryteRLjoWrStawk9O8CuTVoHDCeRGEPI9tuv/38l5c5i8BfpKcJV5KIv/O4F2xhOIjGhpNyykvUX0J8WrpFOJI4Cfp15voowPWH+7/kVQycT7QHz2WUp3YnA3YSkcKhEol/7e7iJxCzC1Z982aL/u4cIV6GqvIWwj/PbyvaRXgYcgImEtDYaTiIxnu6LZZ8tKfczBh9/VraW/Pq/05nuPGs4icSWJeXKjs/foT/JxEgkEkX11mrChaP8cf7qiveaRWiB6aWueBh41hCxv5ne6ooDMZHQOmA4iQTAVzOvX1hS5ixCwnEi8By6m2M3Icx2cUNmOzcSuvlkjSc0A++dKfdoZl122TP32gmEL/XFwJHAroTuPxCSobnAf9D9JV+TfZE30olE+2rHTYTWofbftDHhilP27zmz4n3fmim3mvCZtiuvBuEE+5Lcew6VSJTt7wahGb2X/T2b8Hl+IlPuOxR/5lvlXjuR0Jyd3VdvI3Spg9AKsj8hiWmXuY/yK4B70V3RXwQ8M/P7pwHfbP3uTjqVspWDtPYYTiIBcHbm9VeUlPkZob77GOGEdGrmd5sTjsfZVs/fMfhEfjLhuPf8TLk7KD427pp77ZaEC3nntd7r6XQu5IwlXMj7HN0XkdZkX+T1O5HYj1BfNQkXvT4GbE93C/cWwKsJPSIuL3mffF1xC6F1KVtXzAN+QnddMatke3tSXVfsBHwD6wqtQ4abSLwt8/rVFF9Z3oWhB8NPIvQLbW/rjRVls1cGejEW2LmHcvPofKkfpjNeYU2NdCLRPkHetKTsQXSarlfTfTBrm0p3U+5xJdsaoPtAWpVI9Lq/96O3/f1Wht4veafl4pxWUq5BaElrl/3PknKXZ8qcTfn/86fp3kdWDtLaY7iJxAcYun7alaGv8E+n++T2xSXl1mTWpsmEE+6hZOuPOxh+K32/E4l86/xQJpWsz9YVl1FdV/xnpmxZD4zsecw5lNcVn8K6QuuI4SYS8+n+MpSd1PbiGZntnFtRLjaRiPGlzPZfNsxtjUYiUVbBtJ2ZKfuNgt8fmfn9H6lO+GYBj2fK92P6117291sZer9kbUy4QtW+UrXFEOUnAve2yi+ju8UMQmtE+/0XEwYolhkgzD1v5SCtfYabSGSP4asY3ni7gzLbKmtRHunpX7+X2f68YW6r34nE9zO/z7e69GpN6op7KK8r9qS7rti4YlsDdPfEsK6oAad/TSM/HqFo1oheXU1ndomiq+ej4ZLM430SxdCrWwjN5FW+knn8SgZfCXtl5vECqme2uAf4Uc/R9WYk9vfBdK4+/YAwaLDKMsKVIwjdsp6d+312H51NdQL7FNXdyCStu7L14RiGVx9eSjjBhHrUh6liKLM08/g5a7iNbF1xLr3VFT9oPZ5AGA+Xla8rHqrYlnVFDTn9axr5sQxDTZ+6PaHf5hxCNl+WAJb1VR+uAcJ0d+0p96bkfr/NKMTQL5fQqWjKXEeYBm8TwtWR7QndodqyJ+/ZSqPqPd8SEWOK/X1g5vGve3zNdZnHuxHGTrTF7qNf9fiektYt+frwycJSHU8ntHhuTXHS8RRhfNlI1UXjCcfnXQl1RL576dMyj+tWH/6GMJYBQkv1NoTuRjEtM/2oK36Seb5v5rF1xVrIRCKN/MGvLAN/OWGA7V4lv88bT8j4+9XcNxk4ntCXcpMeX5O/b0Xd9HrAXEjnb96STiIxjs6AsqeAW3vcVi9S7u9s/9+PAP/Sw2uy/8f55ugtM497+ft73UeS1i3Z48gKYElJuTcQBgf3MpYM+l8XTQf+nTDGMd89Z7RiGK6zCN2f9iScK3yotdxGSAp+Rei6XdUqkK0rjgf+uYf3ta5Yh5lIpJH9Ii6n+MD5ccLMO1kPErqILM695gA6N1zrV3e1jYCfE8ZgtK0kzLywuLW0W1JmEFpM+vn+I6XsJkN52eb2bKWRHVS2hKFbN/LbKpN6f2fHMPQ653dWflBetgLtZZ8/SWgC7+X+HZLWHdn68IGSMmcQ7s+QlT02ZrvsPI8wzqKfddFswkl2trVhRS6Gla31M+lMx163+vBJ4AXAlwmJWbvb7rat5a2EcSq/AU4GflqwjdR1xQrC7IVlA8E1ykwk0sjOvf+Hgt8/h5BIQPjif4owTWZZX8Q7GDyV53B9ns5J7V8JU6P+nOI7a76w9bu1wbihiwDdze3ZrmcrM4/XZFtlUu/v7DiPLxOm2ItxTe55dp/18vc36H1/Slp3DFUfvppOEtGesvS7hPsnFXmC/l+Q+BqdJOJqQqvtpRR3wzqUMKi5rh4mzPD4QeAVhJ4PB9A5oR9LuPfRPxHOPT6We33quiKmnEaBicTom0H3rEFFfQzfTedKwTGEexSUaVA9I86amAa8qfX4McIVnnsryvfz/bNX+HuZvSO2wpjZY7nNMo8XZx4vIXRpGiB0RZpEqLiG854p93fbg5nHPwfOH+b2sq0wmxKSoyob4fFIWt9sRfdEDUX1YbbrzDsIA3LLTKT/ScSWhBNuCMfl51N95XxtqQ/vIkwWsqC17X0I5yZH0bnfwwnALwlJU5t1hbrUrdltffB+OoNnV1N8UMwOPvrOENvbgeHfuyFvLzoZ/8+pPqkF2KOP751tou5loNqcyO33EusEOlefVhOmJm1rEm7+ByGJ62V7Q5XJ7u9f0J/9na2AernD6vWZx0PdgbQX2X3WS7z5GyJKWvcdR6clcgXFM9y168NlwA+H2F7scaSXY+O+mXLnM3T3m7WpPmxbBVwJfJLQ1ew3md/l70+VrSvys/WtiRsyj60r1kImEqPrhYTBSW0/Av5cUK49MGkVxV1bsg7p8b3b25lKbzf2aVtaWioYA7y+xxh6ke0ju3UP5edHbv+FdN8VtcjL6ZzY38DgiiN7t8+De3jP1wzx+5HY39kB92U3C8r6RebxYYSB+8NxWebxq3soP9Q+krRueR3d9534JqGbbtZYOsev5YTW4Cq9HBuzdepQdQHEHZ/H01ud0KuY+nAsQ98jqRfLCPcqapuT+711hdQHsTekG0doiXgy87r7CIObitycKbd3SRkIN4LJ3mG5SfkApDsyZWYPEe9zMmX/NETZd+fev6rZuRcbECqMJqE1oOpuoq/LvXevN6T7ZMU2B4BrM2U/UFDm2ZnfP0J3N6i8l+Teu+iGdNn9fR3ViV6v+/sFmTIXV2yvbYAwo1X7NZ/q4TVVZhC6fLU/x/zc4VlbZ8p6kyFp7RJ7Q7oJhNmP2neAbgKLKD+OPpIpV1ZnAuxE50ZpTcq7nDYy5Z5i6EG7r85sc6jpSU+g+/j8leriQ9qIcPxsHxeruskelXvvohvS9eq1me3kW4HydcWnh/E+EBK1bF1xYEXZren+jK0rtNYaKpGYQviHfwVh5oO76f6CL6F7gFnetzJlL6O469IcQmtGM7eUHRR/nCnzJaoHK00mXJVol39fSbk30Z0c9SORgHDgyh64i/6mVxDGE6zOlO01kVhJmLEibwPCVbF2uXson+bvkky5KyiernUvwhWloRKJkdjfm9CpqFdSfXBueyWd/bmacCfVqj63U4DDgYtKfv/5TJx3AXMLysyiO3GzcpDWLkMlEtMICcCrgdMYfEx8CNilYvsXZMpeQPEV8LmEqbiz260au/abTLkTqe5zvzmhd0C7/JsLyjQIU2Znk6N+JBLQuclek1CPF9XdbyLUIdn6sCiROIeQcFRNS7sh3Z/pewvK5OuKk6muKyYT7qVUdlErW0ffRfEUv7MIA7WtK7ROyCYSscuvge2G2P5edB+Q7iJk/YcD7wK+QSeD/zFwe6ZsWSJxcC6OxwiJyB9by6W58l/Ilf8FYZaHN7V+/h+dg8gZmXL9SCSeSTj5bW/zDsJJ6bGEK+WX06koTs+U6yWR+BadfXsRYTaQNxISwr9lyq2iuol6R8Ig7Hb5+1sxHg4c2Xqf9kn/1zPlihIJGJn9fV5um3cRZhxpf+bHFrzmo7nX3NeK/32EGxn9KyHBuJjO/+DdJe8/mdA1rL2tZYSbH70DOAL4ImEGkSahgnsUKwdpbZM96YxdLmDoFvIX0H2CfCuhVfnNhMTlu3Qfa9vTclclEu/MxbGY0Pe/fWw8L1f+27ny/0uYCOVNhO7K7X2wkpA89DOReCHdf//NhBP3YwnH4qta6x8hzC5VlUi0T8SXE6Z2/RShvjqUUBd+lc4xuUloeSgbg5mvK+4nnJtU1RX3lGxrEoPriq8T6orDCfV8u/fFD7Cu0DogNpFYRjjhexG9j0s5msFXN/LLxYSrPbdl1lU1055E95WV7JK/18EEwsls1fs/SbgK87zMun4kEhBm6sgePPPLo4RWiTdn1vWSSLyDcODMX9nPLssJNx0ayn6EE+2qfbSAMHB7qERiJPb3bEKlWLa9L5S87k10VyZDLVXd32YTKuiq1/+K8H9s5SCtfWITiccJF1p6aSVtO57q+qB9gjmB3hKJBt0n3fnlllz5aT38nUsJ9VG2y20/EgkY3GUqv9wPPJdwEt9eV5VI9HpcnzNEXG9icPfqquW64s0AocXhuiFefwmhxaTd3c26ogacQmvN/JZwMCyyhHC1/zFCS8HVhEx7ZUn5MgsIXT6OI1yRac/0tIzQlebbdK6SXEiYNg1ColDm+NZ2X0poOpxGpzkyf9BdTujf/y7CiffudJKgewlXkr7cinEXwkEcwswP/fBVwkHleMKJczvOB4FzCVf/byFURu33Hmo8R9t/Eg6o/0YYWN1u5n2UMCvHyXTPOlTmd4T9+BHCoPf2HTqXE1oQvkZoMZqVifFvJdsaif19N2HGkecQxnVsTfhb29st21/fJVxxexdhMPs8uhPUJYQp+n5D+N+7ZIgYnkloHj8c2LW1fiXh8/0m4X9yFWFfTST+uyIpnV8SxjgUeSyz3Eo47t7I0IOm804iHOs+RDietY9HSwnH2v8itGoC/A8hoVhBuSahNeMLhAHKTyMcG9vdpu4r+DsOJFy1fyvhuN8ey3Ynod74EuG4OI/O8Tl/z4Q19SlCIvPBVhztOO8h/N2fI7Q4T868940M9mI694h4NqHOyk5Xu7j1PmcR6oGhPqd2XXEk4bxiOHXFPYS64n30VldMwrpC6lmD0Oe9rL/+aBhPGOg13Bka1tSmrPk0t/kWibypdGbKGo5JFI+VWBOp93feZEJf4V5mgKoynvBZOmOcpDUxhnAM6WXGpZEygXB8TnFjtEbrvft1v4zxhIHuwz22t1lXSFrnDJVISJIkKZKZniRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpmtO/an3wQ8KNdaD8Pg6SJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJGn4Gp2HzbcAs5NFIkkaygXQ+HPqIEZWcy7wktRRSJJK3Q2NswEGMivfDeyfJh5JUg/uAdbxRIJ9gdNSByFJKnUlcDbAGGjOg+8dArfvnDgoSVKls44Ox+zmtqkj6b/mtuFv+/7RqSORJFVZtHPIHZrzGtBspg5HkhTlTGisYyfczQXAUamjkCT1bkzqACRJkiStlZrN3HJM6ohKrEodwBAWAwelDmKw5vyCz3hu6qgKHA/cnDqIChsBK1IHUax5Ru7zXZQ6ohJXAWekDqLCycD1qYMo1lyY+4wXpI6o/5oLcn/jQmg26rc0roMxp6SPo2wZczo0rk4fR+GyKPcZn1GDmIo+4xUwdeP0cZTGdzOM+Uj6OAYtOzP4fOOlNYgrtwy8GBqL08dR+RmvSh9D4XJs/jMeGPLYLklSEo2adr1tUt/Y2uoYX1FIdYwTYEmzvrFBOImrW3yFXeVrGGf7H7F2ceXUMb7Bn7FdmyRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElStIHBq055O/DcUY9kaGOA81IHUWEq8CngX1IH0u2ImfCt3Lp5XwGWpIimws7AFtT3M96A8H2pYXxn7waHZp7fN5NaxslOwExgm9SBlNgD2JRa7ru7Zoevx/rkrtnU8rNge+AQ4GmpAymxF7ARtdx3982EzTLPz3459TweDADfBVakDqTEFsDbgXmpA+k2bypcmVt3xL8DR6eIpsIswjlbDb8j/1DTc95TtocPda0pSCSaDerZUtGknnFljaF2MTaL4qnjZ9xo/axbXG1jcj9rpNkoWFnDOGv/Gdc9vvVRXT+LOh5D29ai/+Panm9ALevzf2hQz//BgrqoWcf9WOP6/B9qes5beL7RbOaWY0Y9rt6sSh3AEBYDB6UOYrDm/ILPeG7qqAocD9ycOogKG1Hbq1PNM3Kf76LUEZW4CjgjdRAVTgauTx1EsebC3Ge8IHVE/ddckPsbF6aOqMR1wCmpg6hwOnB16iCKNRflPuO6Hg9WEI75dXUzoc6smebcgvON+amjKnAQ4Zytzmp6zts8Jv8Z1zDbkSRJklR3JhKSJEmSoplISJIkSYpmIiFJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoA4NXnTsPOHLUI+lNXeMCmAC8AtgmdSDdPrkrfDy37nWvB+5JEU2FZwHTqe9nPBkYSy3ju3yXsPvalkyhlnGyObAn9YwN4JnAptQyvkc2DF+P9ckjG1LLz4JNgWdQz9gA9gI2o5bxLZkCUzPPL9+FWsbJWOBwYGnqQEpMJxz0a7bvXjcLzs2t++RLgC1TRFNhd8I5W8323yA1jO/cefC6rjUNaDa7C33kMTjp8VGMqlezgbtTB1FhFvAIsCx1IN1eNR5+vHH3ut3vh+ufShNPqWnAJODe1IGUGEM4Ea7h/+CZG8K7Jnee37kKtrovXTylZgIrgcWpAykxHRgP1HDf3TITtste+DkTGkcnC2dENBcAR3We3/oUbH9/snDKbQasoL7/xzOADajl//HfN4Mtx3aef3MZvH9JunjKLJkJUx6ExurUkRRbuglssBzG1excbecBuHyj7nUHPwTnPZkmnlITCN+Tul1QzarpOe/xU+Az07JrChIJjoXGaaMYVa9WEa4S1NVi4FDgZ6kD6dacD1yYW7kzNG5MEU2F44F3ADukDqTERoQkZ4PUgQzWPAN4T2bF7dCYkySUalcBlwHvTR1IiZOBlwG7pQ5ksOZCYMfMivUgkeAmaOyUKpoK1wEXAx9KHUiJ04HnEFpNaqa5iO5W+3OAU9PEUmXgMrh0PhzwWOpIik35Icw7H37xrdSR5MwBzs6teyk0LkoQS5WDCHHOSB1IhZqe8zaPIfeddYyEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpWgOazdy6O4H7UgRT7aq9Ye+rUkdR7po9YdtbYfpjqSPJ2RDYIbfuBmB5glgq3LU5PLwJ7Pbn1JEUWzkA1+8Oz7g6dSQFtgJmZp6vAK5PFEuFG+bC5Mdhzt9TR1Lsji3gsQ1h17+kjqTArsD4zPMzoXF0qmBGRnMBcFRmxXLgmkTBVLhmD5j2CGx/e+pIit0yB5ZMgz2vSx1JgWfQ/X/8EHB3olgq/G5X2PtGGFiVOpJiVz8NNn8YZj+QOpKc8cBOuXU3Ao8kiKXCQ9Phlh1h3z+kjqTcFfvD/lekjqLALGBOdkVRIiFJqrf1IZGQJNWcXZskSZIkRTORkCRJkhRtoGDdn4CFox3I0M59Hbzu3NRRlPvRwfDMK2Druo0v2Rw4MLfuSmBpglgqXDsH7pkN8y9PHUmx5ePgwgPhNb9KHUmBnQjjJNqeAC5IFEuFi14I0x+C/WvY7x3gD7vBA7PgpT9LHUmB+cCU1EGMsseBn6YOYrCLXwgb3wf71HAcEsDv9oClm8Hz/5g6kgL7AxMyz+8EbkoUS4X/+Sd46W9h/FOpIyl24TzY9m6Ye0fqSHImAfvl1v0JeDhBLBXumgF/2AUOPj91JOV+9Bp4zY9SR1FgR2D37IqiMRLHQuO00YupZ6uAsamDqLAYOBSo2UlIcz5wYW7locCi0Y+lyl5HwJ2vhAdemzqSYr+cBvMvghXPTh1JgWOBQzLPb4fGnCSRVLsKuAx4b+pASpwMvAzYLXUggzUXEg7gbevDGImboJEfuFkH1wEXAx9KHUiJ02HWi+HuI1IHUuA8wsWttnOAUxPFUmHgMrh0PhxQt8lTWqb8EOadD7/4VupIcuYAZ+fWvR+o2QXCN+8H3zsRmtNTR1Khpue8zWPIfWft2iRJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYpmIiFJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJCmaiYQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSoplISJIkSYrWgGaze9WHnoTPrUwTTqUpwOOpg6gwBVgOPJU6kG4vHwv/O7F73R7L4cZmcflUmuOAsdBYnjqScqsnwphlqaMY7Ivj4N0Dned3NGGbpeniKTUZWEX4ntTRBGAsUMN9d/Mk2D574edMaBydLJwR0VwAHNV5fstq2OGJZOGUWwv+jwdqeiy9XNs0SAAAGIpJREFUZQJs1eg8/9pT8L4anm/U9Vjf1pwAjVVAzfbd3Ab8aUL3uoNXwIWr0sRTpjkWntqA+p9T1jC+D46DU8Zn1wwMLvTaM+FzZ41WSBEuA16UOogKvwA+BlyROpBuh+0PnNa97vhPww33JAmn1NkvgwcPhH85LnUkxR6YBF//Anz4PakjGewVhwEv6DyfeR/w6lTRVPhv4Drgc6kDKfFeYH/gsNSBDDb7HGCr1FGMrtl3AYekjqLA94DfAV9MHUiJD8CMfeGoT6YOZLDNPgts3Hn+il/D3TU83zjpTHjXcTCjhhcVAE47Geb+Fub/JHUk3XaZBZzYve69X4Pdrk8STqlLd4PL3gnNOp9T1vSc97WHEerKfyhIJPa7HbhydAKKVte4IFwZuIHaxfjGGYPXvWEhsGi0I6n2k2fA4uVwYs0OOG2/nAbfaNY0voO6n054ktr9HwLwGHAX9YwN4GBgN2oZ38QaXl0eaROXU8vPgseBv1PP2ADuhIFdanqsyl1B3/KhesZ5UhPe8Bc44LHUkRT7wnKYfncN992SwauevwieX7M43zwJLnuK+n6H22oY337Pyq9xjIQkSZKkaCYSkiRJkqKZSEiSJEmKZiIhSZIkKZqJhCRJkqRoJhKSJEmSohVM/yqNmKmE6TU3AjYkTKN4L/CXitcMAJsVrG8Sppp7vPW4zDhgZuvxYxROTzfIzNbrngLu66F83kTC39iLewk3t5IkSVqrmEhoNOwNvBPYk+JWsNXwg7vgMxMLfrc58MOKba8A/gb8FDiv9TxrW8KN0ADOBL7RQ7ynATsS5op/XQ/l8+YBJ/dY9pWsWbIiSZKUlImERtIA8CHgVZl1K4A7gEcIt4DfApgKO2zVOsf/CPCZiPfYgNDKsVvrfd4DLB525JIkSapkIqGR0gA+DfxT6/mdhBaB/wOyd+kdA+wK134Y9tgBGltVbPO7wDczz2cSWg6OALZrPf4kudu3J/Yu4MGK31f9TpI0csYD04HVhG6v6+Ed5KXhMZHQSHkjnSTiWuBYwniGvNXAdfC2n8EOG8IPHqrY5pN0j3FYAtwC/Ab4NrAlsB8hobhpWNH3z73YdUmS6uIZwMsJdcUmmfWrgduB38MejZLXfgjYpWD9U4T67TbgyrANVheU+xiwA/Aw8P4eYn0+4UIZwGepHk9Y5kvAtB7K/S9w7hpsX+s5EwmNhCnAO1qPFwPHUZxE5Fz6JPAfa/B+S4HzgX9uPd+L+iQSkqT0ZgCfIIxhKzKGMKZuW/gjsOKEVvknMmW2Ap5e8R7zgMOAG4ETCC3xWXNar78/Iub2+03u8TV5O7a2M5Qr13D7Ws+ZSGgkvIzOQe8s4sYs5AdL9+q2zOON13AbkqR1z+bAVwlj8iCM0/shIWNot4JvRLgI9WJo7A7jn0voPruoYHvLgNMzz8cTWsSf03qvuYSWgDcTLnTVwVVUJwvXj1YgWreYSGgk7Jt5/NNRes9s0+2To/SevdiK0JQ+lVChLAL+ilO+StJo2AA4iU4ScRbwZUJ3pKzFhK6y58KrLof/ebTiVlsrgB8XrP8qcAqhDpwNvB74r+EE30fXEboAS31lIqGRsGvr54OEMQKjYc/M40Wj9J69+ErBuoeB7xAqtKJ+tJKk/ng9sHPr8QV0tySUuKAJf3037Bw7A+Ay4PPAOa3nB1CfREIaEd7ZWv02lnCzORi9JOLFhO5UEMZi/GGU3rcXywiJzS2txxCa0N8LnEq48Z0kqf8GgDe0Hi8DvtD7Sx9+GHh0Dd7zDjpjAmevweultYotEuq3KYSpX6H/fUOfSff/7KbATsD2mXVfobe7V4+kh4AFwM/pHmw3FngWcAyhgnkW8G7gjNEOUJLWA08njHMA+CWjUzc06XSbqtvF2gHCwOtVwGMM7t4lRTORUL9lB0v3+2r77q2lyGOEwW3n9/k918R1rSVvFWGq2r8A3yIkQq8n3Hnbm+hJUn9lu7xePUrvuQnh3hTQ++xMo+GVhBmlJrSerwD+DJwH/Ay72WoNmUio35YRDlAb0Oni1C+LCF2E2pYQTsD/ClxBvQZZV3mIkEh8gLCf9gMuThqRJK17ZmUe31Zaqn8adKYhh3A/ibrIz2a4AWEikPZ9NY4nfWu+1kImEhoJiwhdjrYhTIvXrxP8XxHujh1jZebxBj2+ZnzBa/ste3Ws6m7ekqQ1k72Y1c+T5LF0309iGrA1cBCwR2vd48D3+/iea2oxoe78HWHc4uOELsj7AIcSun7tQ5jZ6j2ErllSz0wkNBKuJSQSA4RxDZcljCVbeUwvLdWtffOex/ocS1b2JkfjS0tJkvqhnyfIUwitymUeAj5CmLkwtTdR3G3pb4RuTV8i3PdiH+B5hKRD6lndBgJp3ZDtpnNosiiCh+nMoLFDD+U3J9zzAeD2EYko2Drz2PERktR/2YtBU/q43SbhIlV2uZvQxfZ0Qr13bR/fbziqxj4sIdy9u13mxSMejdY5tkhoJNxAmIJ1H0L//1cRrnwMYRzAiwizHfXLauAa4EBgF8JNie6qKJ89kI7k4LxXZx7/aQTfR5LWV/dlHm9DGE/XD48RujHFap+w93rulS03UjcxXUQYe7gj3d21pJ7YIqGR8mk63YqOA95C5cHzeTPhgpnAa0YglnNbP8cAJwATS8rtBBzeevwQa9bEO4MwrWuj5PdjgCMJTcgANxFmcZIk9Vf2Is2epaVGT7t1fDLldURWthXl8dJSw/dA6+e0EXwPraNskdBIuYcwK9EphAFv/0pIEi4FFgKPEA5aWwD7w6m793ZcXSNXAhcB8wkzVHyfME3sQsJA8OnA3sBLCQOym8Bn6J7KtlfTCDc9urf1vrcQui6NJQyqfgGwbavscsIAN6fdk6T++wvh+DuD0Np9Bp0bg6bQng52PLAZQ9+0NTsRxwOlpYZvo9bPkUxWtI4ykdBIuhZ4O3As4Sr9bOCNxUUbwOXL4VmnjlAsnybcIO81hHEQ7yopt6RV9rfDfL/NgYMrfn83oW/qDcN8H0lSsRXADwjH+6nA0fR8d+spUwgXefp5cn09nXphHvDjirJjCV2DIdzYdKTG0m1OaI0HuHmE3kPrMBMJjbQ7gfcT+l4+h9C8vBHhoL6UcEXmz3DkJPjxgfBA/kC2BPh26/FwBq+tBD5H6OY0H9iNcEO4ia33uJMwruMnDO+O3HcSKq09gV0Jc3dvTMiUHiUcqK8ALmFkp5eVJMH3COMZ5hAGQT9MqFMqZnGa14Ddv0Kou/qZSPya0FI/EXgr1XfbfiOdloIL1vD9ZlCdgGwAfIxON/dfruH7aD1mIqHR8lcqB7r98YiSXzwKfKWPcdwGfLWP28tbReiX6wBqSUpvGWGc3lcJJ+b/DDwXOJswocaDhAs9GwF7AQfBb8ZCY/YIxLIE+Dqhq+8s4P8BCwjdYNtdruYQWs4PaT2/m9CqsiY+RbhgdQnhLtb3t95nY0I33yPodLX9K6ELsBTFREKSJK3LbiN0sz2JcM+EXYD/aP2uPUYtM/lMA1j5exg3EveB+A5hfMTrCUnDya31SwljJ7LnZe2xhmt6M70GsH9rqfI3QhfkkZoZSuswZ22SJEnrunuAtwHHE26S2m4BGEPnXOhh4CJ43ir43UcZ3K3pIcL04UMNkq7SBD5PuIv0FYQJPyDM5NROIu4ktFa8hTBhx5o6H/g/wuQmeasJrRCnEJKsOtw8T2shWyQkSdL6oEmY1vtXhPOfjQmz9jUJYwlaMyP95kUlr/9EH2P5fWsZRxjwPJnQDelh+jew+mI6N4idRui+NYEwY+B9pJ3BSusIEwlJkrS+eYpwMn3fUAVH2Erg76PwPo/RfadvqS/s2iRJkiQpmomEJEmSpGgmEpIkSZKimUhIkiRJimYiIUmSJClaA5q528R/8i74xP1pwqm0F3BN6iAq7AHcTvF8zQm9fhqcs333ugNug+tXpImnzPJNYfU0mDScObNHUHMAlm4PU/6WOpLBvjwT3jKj8/zuFbDFDeniKbUz8ASwKHEcZbYGpgI13HeLdoZtxmdWnAmNo5OFMyKaC4CjOs9vfxLm/CVZOOV2Idwg7I7UgZTYBsZNhYm3pg5ksL9uB7PGdZ7/92L41xqebyzdCSbfQm1v0PbE9jDuMRj3QOpIuu22Afx22+51b7kTzl+aJp4yK6fCss2BP6WOpEJNz3k/MRM+vkV2TcH0rzNvJdw2vm72JNxYpa52JZyA1OxEeNM5QC6RePpf4amaTQO3aDdYOgHmXps6kmIrN4A/bVfP+GY/A8gkEuOfpJ7flW0IN3KqY2wAzyPEWMP4Jm5LuOvtemTiMmr5WbAt4aZkdYwN4IUwaQCeXsNj1YQtCfdNaJn9YD2PqX/cCXa8HgZqdsGt7U9bwcx7YfPrU0fS7enTCN+PjKfdCnPvSRJOqfu3gNs2pb7fYajtOe/MZwBdiURBiwTHQuO00QuqZ6uAsamDqLAYOBT4WepAujXnAxfmVh5K7a4K73UE3PlKeOC1qSMp9stpMP8iWPHs1JEUOBY4JPP8dmjMSRJJtasId5R9b+pASpwMvAzYLXUggzUXAjtmVqwHLRLcBI2dUkVT4TrCTb4+lDqQEqfDrBfD3UekDqTAeYSbr7WdA5yaKJYKA5fBpfPhgJpdcGub8kOYdz784lupI8mZA5ydW/d+4PLRD6XKm/eD750IzempI6lQ03Pe5jHkvrOOkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0QYK1m0Mze1GPZIhbQ/cUsO42nYcA/vNgu/ULcbNC9ZtBqwc7UCq7TINxg8AW6SOpNhmU2DbBvWMb3Lu+UA9v8M7j4epG8LvahgbwLOmw+IN4MY6xjcudQAJDEBzy9RBDLbdOJg2Fa6tYWwAe0yBiQPAzNSRFBibez6RWsa5JTBjU2BC6kiKbT0Wtp1C/fbdxgXrplO7OHeaDluPgUU1/Q4DbAX8vY7xbZhf0YBmM0UkkqQ1diY0jk4dRH81FwBHpY5CktQ7uzZJkiRJimYiIUmSJCmaiYQkSZKkaEWDrb8N/GS0AxnaIefAOYekjqLcIWfD7t+HE/4ndSQ5ewHH59a9H7grQSwV3v1ReHhXOPuw1JEU+/1m8Pkv1fR/8G3A/MzzB4B/SRRLhTf8N0y6F77xwdSRFHvnp+HxOfD9N6WOpMAXgVmpgxhl9wD/ljqIwQ77Dky5Hf7zo6kjKfaOz8ITs+Csw1NHUuDLwKaZ51dQy/ONN/4HfPEk2HRZ6kiKHXkM7HsVHPnr1JHkbMrg7+xJwLUJYqnw6YPhujfA2W9IHUm5Q8+Gsw9NHUWBlwNvya4oGmx9LDROG72YetYEGqmDqLAa+CjhS1MjzfnAhbmVO0PjxhTRVPgp8Dxgg9SBlNgOuIVa/g82zwDek1lxOzTmJAml2lLgJmDP1IGUuJIQWw1namkuBHbMrFgfBlvfBI2dUkVTYRlwHbBf6kBKXAPsxODZ3GqguQjYJrPiHODUNLFUGbgMLp0PBzyWOpJiU34I886HX3wrdSQ5c4Czc+teCo2LEsRS5Xjg09S7V05Nz3mbx5D7ztZ5J0qSJEmqKRMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRRsYvOpH+wJvH/VIelPXuNr2oXYxnrgbfCy37pDXAPekiKbClkCD2u2/f5jZ+lnD+K7YGfbPPF8yhVrGyQCwCfWMDWAzYCy1jO/RabBh6iBG2aPTqOVnwQDhf6WOsUH4jo2jlvEtmQJTM89vmA2fODBZOOUa8JlnweSlqQMptnIy3L4DvL5m+27vzeC43LoTDwJmpYimwj6tnzX8jnSpYXw/2hdek1/ZbHYvxzQBl3VmmZ/7fJtNmFuDuFz6t5yR+3wX1SAml/4uC3OfcXMB65zmgu6/cWEN9rtLf5dFuf/jL60GVtVwadYghqHiq2GMc1cx6Hxjfg3+71z6txyT+3ybTQavaB5DPTVTBzCE1cDxqYMYrDm/4DOemzqqAj8FVqQOosJ21PZ/sHlG7vNdlDqiEkuBa1MHUeFKYHnqIIo1F7LeJRLNhakjKrEM+F3qICpcQ/iu1VBzUe4zPiN1RCWahGN+Xa0g1Jk105xbcL4xP3VUBY4nnLPVWV3PN47Jf8aOkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJ0ppoNruXY5qAyzqzzM99vs0mzK1BXC79W87Ifb6LahCTS3+XhbnPuLmAdU5zQfffuLAG+92lv8ui3P/xGTWIyaV/y9zc59tshnOQ1HG59G85ZtBn3AgPsp76IIz7AvWzAtggdRAVHgQOA36eOpBuy18C43/SvW7xbrDRjWniKfVh4O3A01IHUmIGcDcwMXUgg606Hcb8a2bF7dDYPlk45X4PXA78W+pASnwGeCmwZ+pABmveCOyYWXEmNI5OFc3IaC4AjsqsuAkac1NFU+Fa4CLg+NSBlDgNOBDYJ3UggzVvAbbpPF/9ZRhbx+PBMmA2sDh1ICX+BnwD+GzqQLo9PBdmXN+97smXw4SL08RT6kXAWcAmqQOpUNNz3pXvh4HPZdcMDC40sBpYNUoRxaprXG013HfjVw9eN2MVtYuTdkJbt7ja2vuxhvGNaRasrGGcQPic6xwb1De+9VEdP4u6/5/UPb6MMXU+HtSwPu9Sw303oyCe8XXcjzWuz7vUML6BQeeUjpGQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdFMJCRJkiRFM5GQJEmSFM1EQpIkSVI0EwlJkiRJ0UwkJEmSJEUzkZAkSZIUzURCkiRJUjQTCUmSJEnRTCQkSZIkRTORkCRJkhTNREKSJElSNBMJSZIkSdEGCtY9H5rjRj2SIR3XgJM/nDqKcieMh5ccAgfslTqSnKcVrHsnNO8f9Ugqfe+5cPN0+PeafsYPToJTx8BJdYxv79zzadCsYZyf2Qw23RuOrGFsAN+cB3dtCifUMb4ZqQNIYAY0j0kdxGAf3wS2eCa8q4axAXztGXD/TPh4HeOblnu+Vz0/4w+MgQ//M2z6ROpIip0wHXY6AA6v277brGDdq6E5d9QjqXTJ0+Di8fDZuu2/jGMbcGod43tufkUDms0UkUiS1tiZ0Dg6dRD91VwAHJU6CklS78YAV8IjN8DjJhSSVGt3rACuBG5NHckIuBW4svU3SpJqa2kz5A5cOQYa+8OM/eGpG1KHJUmqsujEcMxunJI6kv5rnBL+tjtOTB2JJKnKyr+E3KGxf3uw9RKYviRpTJKkITznjtQRjLwD/p46AklSlelLgCUA/z8urGuPwKqEnAAAAABJRU5ErkJggg=="
}
},
"cell_type": "markdown",
"id": "6f7b5b36",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g26305.png\" align=\"left\" width=\"400\">\n",
"</div>\n"
]
},
{
"cell_type": "markdown",
"id": "09bd28ca",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Compute the complexity of the communication over computation ratio for this data partition.\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e94a1ea6",
"metadata": {},
"outputs": [],
"source": [
"uncover = false\n",
"partition_2d_answer(uncover)"
]
},
{
"cell_type": "markdown",
"id": "9aaf1ca6",
"metadata": {},
"source": [
"### 2D cyclic partition"
]
},
{
"attachments": {
"g26911.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "77701278",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g26911.png\" align=\"left\" width=\"400\">\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "b373e9ce",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Compute the complexity of the communication over computation ratio for this data partition.\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "10fab825",
"metadata": {},
"outputs": [],
"source": [
"uncover = false\n",
"partition_cyclic_answer(uncover)"
]
},
{
"cell_type": "markdown",
"id": "191fa03b",
"metadata": {},
"source": [
"### Summary\n",
"\n",
"|Partition | Messages <br> per iteration | Communication <br>per worker | Computation <br>per worker | Ratio communication/<br>computation |\n",
"|---|---|---|---|---|\n",
"| 1d block | 2 | O(N) | N²/P | O(P/N) |\n",
"| 2d block | 4 | O(N/√P) | N²/P | O(√P/N) |\n",
"| 2d cyclic | 4 |O(N²/P) | N²/P | O(1) |"
]
},
{
"cell_type": "markdown",
"id": "c0c6d216",
"metadata": {},
"source": [
"### Which partition is the best one?\n",
"\n",
"\n",
"\n",
"- Both 1d and 2d block partitions are potentially scalable if $P<<N$\n",
"- The 2d block partition has the lowest communication complexity\n",
"- The 1d block partition requires to send less messages (It can be useful if the fixed cost of sending a message is high)\n",
"- The best strategy for a given problem size will thus depend on the machine.\n",
"- Cyclic partitions are impractical for this application (but they are useful in others) \n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "8caf9b30",
"metadata": {},
"source": [
"## The Gauss-Seidel method \n",
"\n",
"Now let us study a slightly more challenging method. The implementation of Jacobi used an auxiliary array `u_new`. The usage of `u_new` seems a bit unnecessary at first sight, right? If we remove it, we get another method called Gauss-Seidel.\n",
"\n",
"\n",
"The following cell contains the sequential implementation of Gauss-Seidel. It is obtained taking the sequential implementation of Jacobi, removing `u_new`, and only using `u`. This method is more efficient in terms of memory consumed (only one vector required instead of two). However it is harder to parallelize."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "efd792c3",
"metadata": {},
"outputs": [],
"source": [
"function gauss_seidel(n,niters)\n",
" u = zeros(n+2)\n",
" u[1] = -1\n",
" u[end] = 1\n",
" for t in 1:niters\n",
" for i in 2:(n+1)\n",
" u[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" end\n",
" u\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "5a38cef6",
"metadata": {},
"source": [
"Note that the final solution is nearly the same as for Jacobi for a large enough number of iterations."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c7efa254",
"metadata": {},
"outputs": [],
"source": [
"n = 5\n",
"niters = 1000\n",
"gauss_seidel(n,niters)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "37b7c288",
"metadata": {},
"outputs": [],
"source": [
"jacobi(n,niters)"
]
},
{
"cell_type": "markdown",
"id": "97d9ad59",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Which of the two loops in the Gauss-Seidel method are trivially parallelizable?\n",
"</div>\n",
"\n",
"```julia\n",
"for t in 1:niters\n",
" for i in 2:(n+1)\n",
" u[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
"end\n",
"```\n",
"\n",
" a) Both of them\n",
" b) The outer, but not the inner\n",
" c) None of them\n",
" d) The inner, but not the outer\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0b383598",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c or d\n",
"gauss_seidel_1_check(answer)"
]
},
{
"cell_type": "markdown",
"id": "6b06f709",
"metadata": {},
"source": [
"If you look into the algorithm closely, you will realize that the steps in loop over `i` are not independent. To update `u[i]` we first need to update `u[i-1]`, which requires to update `u[i-2]` etc. This happens for Gauss-Seidel but not for Jacobi. For Jacobi the updates are written into the temporary array `u_new` instead of updating `u` directly. In other words, in Jacobi, updating `u_new[i]` does not require any entry updated entry of `u_new`. It only requires entries in vector `u`, which is not modified in the loop over `i`."
]
},
{
"cell_type": "markdown",
"id": "099634d9",
"metadata": {},
"source": [
"### Backwards Gauss-Seidel\n",
"\n",
"In addition, the the result of the Gauss-Seidel method depends on the order of the steps in the loop over `i`. This is another symptom that tells you that this loop is hard (or impossible) to parallelize. For instance, if you do the iterations over `i` by reversing the loop order, you get another method called *backward* Gauss-Seidel."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ff03c246",
"metadata": {},
"outputs": [],
"source": [
"function backward_gauss_seidel(n,niters)\n",
" u = zeros(n+2)\n",
" u[1] = -1\n",
" u[end] = 1\n",
" for t in 1:niters\n",
" for i in (n+1):-1:2\n",
" u[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" end\n",
" u\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "63c4ce1f",
"metadata": {},
"source": [
"Both Jacobi and *forward* and *backward* Gauss-Seidel converge to the same result, but they lead to slightly different values during the iterations. Check it with the following cells. First, run the methods with `niters=1` and then with `niters=100`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "abe31423",
"metadata": {},
"outputs": [],
"source": [
"n = 5\n",
"niters = 1\n",
"u_forward = gauss_seidel(n,niters)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "23430f70",
"metadata": {},
"outputs": [],
"source": [
"u_backward = backward_gauss_seidel(n,niters)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0b2b2437",
"metadata": {},
"outputs": [],
"source": [
"u_jacobi = jacobi(n,niters)"
]
},
{
"cell_type": "markdown",
"id": "0deb5549",
"metadata": {},
"source": [
"### Red-black Gauss-Seidel\n",
"\n",
"There is yet another version called *red-black* Gauss-Seidel. This uses a very clever order for the steps in the loop over `i`. It does this loop in two phases. First, one updates the entries with even index, and then the entries with odd index."
]
},
{
"attachments": {
"g28304.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "dda0a371",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g28304.png\" align=\"left\" width=\"300\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "9707f13b",
"metadata": {},
"source": [
"The implementation is given in the following cell. Note that we introduced an extra loop that represent\n",
"each one of the two phases."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c0cbe2d8",
"metadata": {},
"outputs": [],
"source": [
"function red_black_gauss_seidel(n,niters)\n",
" u = zeros(n+2)\n",
" u[1] = -1\n",
" u[end] = 1\n",
" for t in 1:niters\n",
" for color in (0,1)\n",
" for i in (n+1):-1:2\n",
" if color == mod(i,2)\n",
" u[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" end\n",
" end\n",
" end\n",
" u\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "13ce270f",
"metadata": {},
"source": [
"Run the method for several values of `niters`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "59c1e7f8",
"metadata": {},
"outputs": [],
"source": [
"n = 5\n",
"niters = 1000\n",
"red_black_gauss_seidel(n,niters)"
]
},
{
"cell_type": "markdown",
"id": "d1bacc26",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Which of the loops in the red-black Gauss-Seidel method are trivially parallelizable?\n",
"</div>\n",
"\n",
"```julia\n",
"for t in 1:niters\n",
" for color in (0,1)\n",
" for i in (n+1):-1:2\n",
" if color == mod(i,2)\n",
" u[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" end\n",
" end\n",
"end\n",
"```\n",
"\n",
" a) All loops\n",
" b) Loop over t only\n",
" c) Loop over color only\n",
" d) Loop over i only\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d511cc02",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c or d\n",
"gauss_seidel_2_check(answer)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8946b83f",
"metadata": {},
"outputs": [],
"source": [
"uncover = false\n",
"gauss_seidel_2_why(uncover)"
]
},
{
"cell_type": "markdown",
"id": "41e90d60",
"metadata": {},
"source": [
"### Changing an algorithm to make it parallel\n",
"\n",
"Note that the original method (the forward Gauss-Seidel) cannot be parallelized, we needed to modify the method slightly with the red-black ordering in order to create a method that can be parallelized. However the method we parallelized is not equivalent to the original one. This happens in practice in many other applications. An algorithm might be impossible to parallelize and one needs to modify it to exploit parallelism. However, one needs to be careful when modifying the algorithm to not destroy the algorithmic properties of the original one. In this case, we succeeded. The red-black Gauss-Seidel converges as fast (if not faster) than the original forward Gauss-Seidel. However, this is not true in general. There is often a trade-off between the algorithmic properties and how parallelizable is the algorithm."
]
},
{
"cell_type": "markdown",
"id": "8ed4129c",
"metadata": {},
"source": [
"## MPI implementation\n",
"\n",
"In the last part of this notebook, we consider the implementation of the Jacobi method using MPI. We will consider the 1D version for simplicity.\n",
"\n",
"\n",
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> The programming model of MPI is generally better suited for data-parallel algorithms like this one than the task-based model provided by Distributed.jl. In any case, one can also implement it using Distributed.jl, but it requires some extra effort to setup the remote channels right for the communication between neighbor processes. \n",
"</div>\n",
"\n",
"\n",
"We are going to implement the method in a function with the following signature\n",
"\n",
"```julia\n",
" u = jacobi_mpi(n,niters,comm)\n",
"```\n",
"\n",
"The signature will be very similar to the sequential function `jacobi`, but there are some important differences:\n",
"\n",
"1. The parallel one takes an MPI communicator object. This allows the user to decide which communicator to use. For instance, `MPI.COMM_WORLD` directly or a duplicate of this one (which is the recommended approach).\n",
"2. Function `jacobi_mpi` will be called on multiple MPI ranks. Thus, the values of `n` and `niters` should be the same in all ranks. The caller of this function has to make sure that this is true. Otherwise, the parallel code will not work.\n",
"3. The result `u` is NOT the same as the result of the sequential function `jacobi`. It will contained only the local portion of `u` stored at each rank. To recover the same vector as in the sequential case, one needs to gather these pieces in a single rank. We will do this later.\n",
"\n",
"The implementation of the parallel function is given in the following code snipped:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d31c1e41",
"metadata": {},
"outputs": [],
"source": [
"code1 = quote\n",
" function jacobi_mpi(n,niters,comm)\n",
" # Initialization\n",
" u, u_new = init(n,comm)\n",
" for t in 1:niters\n",
" # Communication\n",
" ghost_exchange!(u,comm)\n",
" # Local computation\n",
" local_update!(u,u_new)\n",
" u, u_new = u_new, u\n",
" end\n",
" return u\n",
" end\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "04a38c37",
"metadata": {},
"source": [
"In the following cells, we discuss the implementation of the helper functions `init`, `ghost_exchange`, and `local_update`."
]
},
{
"cell_type": "markdown",
"id": "96b8d40e",
"metadata": {},
"source": [
"### Initialization\n",
"\n",
"Let us start with function `init`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b98a9348",
"metadata": {},
"outputs": [],
"source": [
"code2 = quote\n",
" function init(n,comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" if mod(n,nranks) != 0\n",
" println(\"n must be a multiple of nranks\")\n",
" MPI.Abort(comm,1)\n",
" end\n",
" load = div(n,nranks)\n",
" u = zeros(load+2)\n",
" if rank == 0\n",
" u[1] = -1\n",
" end\n",
" if rank == nranks-1\n",
" u[end] = 1\n",
" end\n",
" u_new = copy(u)\n",
" u, u_new\n",
" end\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "1b9e75d8",
"metadata": {},
"source": [
"This function crates and initializes the vector `u` and the auxiliary vector `u_new` and fills in the boundary values. Note that we are not creating the full arrays like in the sequential case. We are only creating the parts to be managed by the current rank. To this end, we start by computing the number of entries to be updated in this rank, i.e., variable `load`. We have assumed that `n` is a multiple of the number of ranks for simplicity. If this is not the case, we stop the computation with `MPI.Abort`. Note that we are allocating two extra elements in `u` (and `u_new`) for the ghost cells and boundary conditions. The following figure displays the arrays created for `n==9` and `nranks==3` (thus `load == 3`). Note that the first and last elements of the arrays are displayed with gray edges denoting that they are the extra elements allocated for ghost cells or boundary conditions."
]
},
{
"attachments": {
"fig.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "756b8d01",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "3f0e49e4",
"metadata": {},
"source": [
"### Communication\n",
"\n",
"Once the working arrays have been created, we can start with the iterations of the Jacobi method. Remember that this is implemented in parallel by updating the ghost cells with data from neighboring processes and then performing the sequential Jacobi update. See figure:"
]
},
{
"attachments": {
"fig15.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA6gAAAFACAYAAACxyVHuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N15fFT19f/x12cmIQFkE1wANxBFrTu4b1itimQC2mKrtfrtRtXazbbWrmJba+1m7S5fv9Wqrbb5VWBugFatpe4buGvdFVcU2cISSOZ+fn+cO2QyTCAsmXszeT8fj/vIvXPv3Dm5M3PnnvvZ3DXXXOMRERERERERiVkq7gBEREREREREQAmqiIiIiIiIJERV0fLJzrlX4whEREREREREehbv/W7AP/PL7RJU59yrU6ZMeb7cQYmIiIiIiEjPM23aNLxv6xZJVXxFREREREQkEZSgioiIiIiISCIoQRUREREREZFEUIIqIiIiIiIiiaAEVURERERERBJBCaqIiIiIiIgkghJUERERERERSQQlqCIiIiIiIpIISlBFREREREQkEZSgioiIiIiISCIoQRUREREREZFEUIIqIiIiIiIiiaAEVURERERERBKhKu4ARDbGe+8aGxsvizuODbnuuusOWLhw4SCAhQsXvvbiiy++EndMRXYBRkbzy4H5McZSSn/g4ILlu4FcTLGUdPjhhx+dTqerAE455ZSnDjzwwEVxx9QR59yDdXV1s8rxWtls9nPOueHleK3NMXv27BFPPPHErgArV65c8thjjz0ed0xFBgEHFCzPjSmODRlXMP84sCSmODpyAHYcARYAL8cYy3pGjBixy7Bhw0YCbLvttsunTJmStPNvO+l0+vJTTz11TVe/ThAEewFndfXrbK7m5ub0L3/5y2Pyy88+++z8xYsXL48zphIOxn4/wT73C2KMpZQRwK7R/FLgsRhjWc/gwYMH7rXXXgfmly+55JK5MYazUWEY3jBx4sQX446jHJSgSuJddtllbsyYMd+NO44NeeGFF3jyySfzi8dsaNuEmBB3ABuRuGP4wAMPrJsfN25c4uIr5L3/LVCWBBX4DDC2TK+1yd577z3uvffewofq44qlkxL92SL58SXOK6+8wiuv2D3LUaNGQcLPv9XV1T8HujxB9d6Pds4l+re96NyR9M9+0uMDyMQdQKH333+/3XschuExqVRyK5em0+l7gR6RoCb3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"
}
},
"cell_type": "markdown",
"id": "6b214777",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig15.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "c1bd8413",
"metadata": {},
"source": [
"The communication step happens in function `ghost_exchange!`. This one modifies the ghost cells in the input vector `u` by importing data using MPI point-to-point communication. See the following code:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "688638a1",
"metadata": {},
"outputs": [],
"source": [
"code3 = quote\n",
" function ghost_exchange!(u,comm)\n",
" load = length(u)-2\n",
" rank = MPI.Comm_rank(comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" if rank != 0\n",
" neig_rank = rank-1\n",
" u_snd = view(u,2:2)\n",
" u_rcv = view(u,1:1)\n",
" dest = neig_rank\n",
" source = neig_rank\n",
" MPI.Sendrecv!(u_snd,u_rcv,comm;dest,source)\n",
" end\n",
" if rank != (nranks-1)\n",
" neig_rank = rank+1\n",
" u_snd = view(u,(load+1):(load+1))\n",
" u_rcv = view(u,(load+2):(load+2))\n",
" dest = neig_rank\n",
" source = neig_rank\n",
" MPI.Sendrecv!(u_snd,u_rcv,comm;dest,source)\n",
" end\n",
" end\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "5bf5408c",
"metadata": {},
"source": [
"Note that we have used `MPI.Sendrecv!` to send and receive values."
]
},
{
"cell_type": "markdown",
"id": "d2ce54e4",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Is this other implementation based on `MPI.Send` and `MPI.Recv!` correct?\n",
"</div>\n",
"\n",
"```julia\n",
" function ghost_exchange!(u,comm)\n",
" load = length(u)-2\n",
" rank = MPI.Comm_rank(comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" if rank != 0\n",
" neig_rank = rank-1\n",
" u_snd = view(u,2:2)\n",
" u_rcv = view(u,1:1)\n",
" dest = neig_rank\n",
" source = neig_rank\n",
" MPI.Send(u_snd,comm;dest)\n",
" MPI.Recv!(u_rcv,comm;source)\n",
" end\n",
" if rank != (nranks-1)\n",
" neig_rank = rank+1\n",
" u_snd = view(u,(load+1):(load+1))\n",
" u_rcv = view(u,(load+2):(load+2))\n",
" dest = neig_rank\n",
" source = neig_rank\n",
" MPI.Send(u_snd,comm;dest)\n",
" MPI.Recv!(u_rcv,comm;source)\n",
" end\n",
" end\n",
"```\n",
"\n",
" a) It is correct.\n",
" c) It is incorrect, but it might provide the right result depending on the MPI implementation.\n",
" b) It is incorrect, and it is guaranteed that it will result in a dead lock.\n",
" d) This implementation does not work when distributing over just a single MPI rank.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8498c7e2",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c or d\n",
"sndrcv_check(answer)"
]
},
{
"cell_type": "markdown",
"id": "d863cb89",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> How would you fix the implementation above, while still using `MPI.Send` and `MPI.Recv!` instead of `MPI.Sendrecv!` ?\n",
"</div>\n",
"\n",
"Think about the answer. To uncover the the solution run next cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "629a3356",
"metadata": {},
"outputs": [],
"source": [
"uncover = false\n",
"sndrcv_fix_answer(uncover)"
]
},
{
"cell_type": "markdown",
"id": "82e21f4e",
"metadata": {},
"source": [
"### Local computation\n",
"\n",
"Once the ghost cells have the right values, we can perform the Jacobi update locally at each process. This is done in function `local_update!`. Note that here we only update the data *owned* by the current MPI rank, i.e. we do not modify the ghost values. There is no need to modify the ghost values since they will updated by another rank. In the code, this is reflected in the loop over `i`. We do not visit the first nor the last entry in `u_new`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f43560e5",
"metadata": {},
"outputs": [],
"source": [
"code4 = quote\n",
" function local_update!(u,u_new)\n",
" load = length(u)-2\n",
" for i in 2:(load+1)\n",
" u_new[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" end\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "47861c19",
"metadata": {},
"source": [
"### Running the code\n",
"\n",
"Let us put all pieces together and run the code. If not done yet, install MPI."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "53674411",
"metadata": {},
"outputs": [],
"source": [
"] add MPI"
]
},
{
"cell_type": "markdown",
"id": "c966375a",
"metadata": {},
"source": [
"The following cells includes all previous code snippets into a final one. We are eventually calling function `jacobi_mpi` and showing the result vector `u`. Run the following code for 1 MPI rank, then for 2 and 3 MPI ranks. Look into the values of `u`. Does it make sense?"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f91e4759",
"metadata": {},
"outputs": [],
"source": [
"using MPI\n",
"code = quote\n",
" using MPI\n",
" MPI.Init()\n",
" $code1\n",
" $code2\n",
" $code3\n",
" $code4\n",
" n = 9\n",
" niters = 200\n",
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
" u = jacobi_mpi(n,niters,comm)\n",
" @show u\n",
"end\n",
"run(`$(mpiexec()) -np 3 julia --project=. -e $code`);"
]
},
{
"cell_type": "markdown",
"id": "8e4fe21d",
"metadata": {},
"source": [
"### Checking the result\n",
"\n",
"Checking the result visually is not enough in general. To check the parallel implementation we want to compare it against the sequential implementation. However, how can we compare the sequential and the parallel result? The parallel version gives a distributed vector. We cannot compare this one directly with the result of the sequential function. A possible solution is to gather all the pieces of the parallel result in a single rank and compare there against the parallel implementation.\n",
"\n",
"\n",
"The following function gather the distributed vector in rank 0."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "49a220c6",
"metadata": {},
"outputs": [],
"source": [
"code5 = quote\n",
" function gather_final_result(u,comm)\n",
" load = length(u)-2\n",
" rank = MPI.Comm_rank(comm)\n",
" if rank !=0\n",
" # If I am not rank 0\n",
" # I send my own data to rank 0\n",
" u_snd = view(u,2:(load+1))\n",
" MPI.Send(u_snd,comm,dest=0)\n",
" u_root = zeros(0) # This will nevel be used\n",
" else\n",
" # If I am rank 0\n",
" nranks = MPI.Comm_size(comm)\n",
" n = load*nranks\n",
" u_root = zeros(n+2)\n",
" # Set boundary\n",
" u_root[1] = -1\n",
" u_root[end] = 1\n",
" # Set data for rank 0\n",
" lb = 2\n",
" ub = load+1\n",
" u_root[lb:ub] = view(u,lb:ub)\n",
" # Receive and set data from other ranks\n",
" for other_rank in 1:(nranks-1)\n",
" lb += load\n",
" ub += load\n",
" u_rcv = view(u_root,lb:ub)\n",
" MPI.Recv!(u_rcv,comm;source=other_rank)\n",
" end\n",
" end\n",
" # NB onle the root (rank 0) will\n",
" # contain meaningfull data\n",
" return u_root\n",
" end\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "e66bad1b",
"metadata": {},
"source": [
"Run the following cell to see the result. Is the result as expected?"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4a9f4a54",
"metadata": {},
"outputs": [],
"source": [
"code = quote\n",
" using MPI\n",
" MPI.Init()\n",
" $code1\n",
" $code2\n",
" $code3\n",
" $code4\n",
" $code5\n",
" n = 9\n",
" niters = 200\n",
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
" u = jacobi_mpi(n,niters,comm)\n",
" u_root = gather_final_result(u,comm)\n",
" @show u_root\n",
"end\n",
"run(`$(mpiexec()) -np 3 julia --project=. -e $code`);"
]
},
{
"cell_type": "markdown",
"id": "dc9b2b51",
"metadata": {},
"source": [
"Now that we have collected the parallel vector into a single array, we can compare it against the sequential implementation. This is done in the following cells."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb053382",
"metadata": {},
"outputs": [],
"source": [
"code6 = quote\n",
" function jacobi(n,niters)\n",
" u = zeros(n+2)\n",
" u[1] = -1\n",
" u[end] = 1\n",
" u_new = copy(u)\n",
" for t in 1:niters\n",
" for i in 2:(n+1)\n",
" u_new[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" u, u_new = u_new, u\n",
" end\n",
" u\n",
" end\n",
"end;"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ffe6c605",
"metadata": {},
"outputs": [],
"source": [
"code = quote\n",
" using MPI\n",
" MPI.Init()\n",
" $code1\n",
" $code2\n",
" $code3\n",
" $code4\n",
" $code5\n",
" $code6\n",
" n = 12\n",
" niters = 100\n",
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
" u = jacobi_mpi(n,niters,comm)\n",
" u_root = gather_final_result(u,comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" if rank == 0\n",
" # Compare agains serial\n",
" u_seq = jacobi(n,niters)\n",
" if isapprox(u_root,u_seq)\n",
" println(\"Test passed 🥳\")\n",
" else\n",
" println(\"Test failed\")\n",
" end\n",
" end\n",
"end\n",
"run(`$(mpiexec()) -np 3 julia --project=. -e $code`);"
]
},
{
"cell_type": "markdown",
"id": "c9aa2901",
"metadata": {},
"source": [
"## Latency hiding\n",
"\n",
"We have now a correct parallel implementation. But. can our implementation above be improved? Note that we only need communications to update the values at the boundary of the portion owned by each process. The other values (the one in green in the figure below) can be updated without communications. This provides the opportunity of overlapping the computation of the interior values (green cells in the figure) with the communication of the ghost values. This technique is called latency hiding, since we are hiding communication latency by overlapping it with computation that we need to do anyway. The actual implementation is left as an exercise (see Exercise 1)."
]
},
{
"attachments": {
"fig16.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"id": "7d66b1a2",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig16.png\" align=\"left\" width=\"450\"/>\n",
"</div>\n"
]
},
{
"cell_type": "markdown",
"id": "c2d48c45",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Which MPI directives would you use to implement latency hiding in the communication the ghost values?\n",
"</div>\n",
"\n",
" a) MPI_Send and MPI_Recv\n",
" b) MPI_Bsend and MPI_Recv\n",
" c) MPI_Isend and MPI_Irecv \n",
" d) MPI_Sendrecv"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "29ade8f6",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c or d\n",
"lh_check(answer)"
]
},
{
"cell_type": "markdown",
"id": "9bd014b0",
"metadata": {},
"source": [
"## Conclusion\n",
"\n",
"- We learned how to parallelize the Jacobi method efficiently.\n",
"- Using block partitions the communication overhead is small if the problem size is larger than the number of processors.\n",
"- In addition, one can use latency hiding to further reduce the overhead caused by communication.\n",
"- Both are not true if we use cyclic data partitions.\n",
"- Gauss-Seidel is a simple variation of Jacobi but is much more challenging to parallelize.\n",
"- One needs to consider a special order (red-black) when updating the values to parallelize the method.\n",
"- We learned how to implement a 1D Jacobi method with MPI.\n",
"- Once needs to be careful when using blocking directives to avoid dead locks."
]
},
{
"cell_type": "markdown",
"id": "47643bf6",
"metadata": {},
"source": [
"## Exercises"
]
},
{
"cell_type": "markdown",
"id": "6527d24f",
"metadata": {},
"source": [
"### Exercise 1\n",
"\n",
"The following code implements the 1D Jacobi method studied in this notebook, but using non-blocking sends and receives. Modify this code so that you overlap the communication of the ghost values with local computations as explained above in the section \"latency hiding\". You only need to modify function `jacobi_mpi_latency_hiding`. Copy the code below to a file called `ex1.jl`. Modify the file (e.g. with vscode). Run it from the Julia REPL using the `run` function as explained in the [Getting Started tutorial](https://www.francescverdugo.com/XM_40017/dev/getting_started_with_julia/#Running-MPI-code)."
]
},
{
"cell_type": "markdown",
"id": "9b57f876",
"metadata": {},
"source": [
"\n",
"```julia\n",
"# file ex1.jl (begin)\n",
"\n",
"using MPI\n",
"MPI.Init()\n",
"\n",
"function jacobi_mpi_latency_hiding(n,niters,comm)\n",
" u, u_new = init(n,comm)\n",
" load = length(u)-2\n",
" rank = MPI.Comm_rank(comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" nreqs = 2*((rank != 0) + (rank != (nranks-1)))\n",
" reqs = MPI.MultiRequest(nreqs)\n",
" for t in 1:niters\n",
" ireq = 0\n",
" if rank != 0\n",
" neig_rank = rank-1\n",
" u_snd = view(u,2:2)\n",
" u_rcv = view(u,1:1)\n",
" dest = neig_rank\n",
" source = neig_rank\n",
" ireq += 1\n",
" MPI.Isend(u_snd,comm,reqs[ireq];dest)\n",
" ireq += 1\n",
" MPI.Irecv!(u_rcv,comm,reqs[ireq];source)\n",
" end\n",
" if rank != (nranks-1)\n",
" neig_rank = rank+1\n",
" u_snd = view(u,(load+1):(load+1))\n",
" u_rcv = view(u,(load+2):(load+2))\n",
" dest = neig_rank\n",
" source = neig_rank\n",
" ireq += 1\n",
" MPI.Isend(u_snd,comm,reqs[ireq];dest)\n",
" ireq += 1\n",
" MPI.Irecv!(u_rcv,comm,reqs[ireq];source)\n",
" end\n",
" MPI.Waitall(reqs)\n",
" for i in 2:load+1\n",
" u_new[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" u, u_new = u_new, u\n",
" end\n",
" return u\n",
"end\n",
"\n",
"function init(n,comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" if mod(n,nranks) != 0\n",
" println(\"n must be a multiple of nranks\")\n",
" MPI.Abort(comm,1)\n",
" end\n",
" load = div(n,nranks)\n",
" u = zeros(load+2)\n",
" if rank == 0\n",
" u[1] = -1\n",
" end\n",
" if rank == nranks-1\n",
" u[end] = 1\n",
" end\n",
" u_new = copy(u)\n",
" u, u_new\n",
"end\n",
"\n",
"function gather_final_result(u,comm)\n",
" load = length(u)-2\n",
" rank = MPI.Comm_rank(comm)\n",
" if rank !=0\n",
" u_snd = view(u,2:(load+1))\n",
" MPI.Send(u_snd,comm,dest=0)\n",
" u_root = zeros(0)\n",
" else\n",
" nranks = MPI.Comm_size(comm)\n",
" n = load*nranks\n",
" u_root = zeros(n+2)\n",
" u_root[1] = -1\n",
" u_root[end] = 1\n",
" lb = 2\n",
" ub = load+1\n",
" u_root[lb:ub] = view(u,lb:ub)\n",
" for other_rank in 1:(nranks-1)\n",
" lb += load\n",
" ub += load\n",
" u_rcv = view(u_root,lb:ub)\n",
" MPI.Recv!(u_rcv,comm;source=other_rank)\n",
" end\n",
" end\n",
" return u_root\n",
"end\n",
"\n",
"function jacobi(n,niters)\n",
" u = zeros(n+2)\n",
" u[1] = -1\n",
" u[end] = 1\n",
" u_new = copy(u)\n",
" for t in 1:niters\n",
" for i in 2:(n+1)\n",
" u_new[i] = 0.5*(u[i-1]+u[i+1])\n",
" end\n",
" u, u_new = u_new, u\n",
" end\n",
" u\n",
"end\n",
"\n",
"n = 12\n",
"niters = 100\n",
"comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
"u = jacobi_mpi_latency_hiding(n,niters,comm)\n",
"u_root = gather_final_result(u,comm)\n",
"rank = MPI.Comm_rank(comm)\n",
"if rank == 0\n",
" u_seq = jacobi(n,niters)\n",
" if isapprox(u_root,u_seq)\n",
" println(\"Test passed 🥳\")\n",
" else\n",
" println(\"Test failed 😢\")\n",
" end\n",
"end\n",
"\n",
"# file ex1.jl (end)\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "1af362aa",
"metadata": {},
"source": [
"### Exercise 2\n",
"\n",
"In the parallel implementation of the Jacobi method, we assumed that the method runs for a given number of iterations. In function, `jacobi_with_tol` at the beginning of the notebook shows how the Jacobi iterations can be stopped when the difference between iterations is small. Implement a parallel version of this function. Start with the code in Exercise 1 and add the stopping criterion implemented in `jacobi_with_tol`. Use a text editor and the Julia REPL. Do not try to implement the code in a notebook."
]
},
{
"cell_type": "markdown",
"id": "6d3430ad",
"metadata": {},
"source": [
"# License\n",
"\n",
"\n",
"\n",
"This notebook is part of the course [Programming Large Scale Parallel Systems](https://www.francescverdugo.com/XM_40017) at Vrije Universiteit Amsterdam and may be used under a [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.10.0",
"language": "julia",
"name": "julia-1.10"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.10.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}