{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "da7c16b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from scipy.optimize import curve_fit\n",
    "from matplotlib.cm import get_cmap"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47341b1d",
   "metadata": {},
   "source": [
    "# Alltoall "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cc39aab",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_4897/23514614.py:3: UserWarning: Boolean Series key will be reindexed to match DataFrame index.\n",
      "  df_gather = df_multinode[df_multinode[\"benchmark_type\"]==\"Gather\"][df_multinode['msg_size_bytes']>1024][df_multinode['off_cache_flag']==-1]\n",
      "/tmp/ipykernel_4897/23514614.py:3: UserWarning: Boolean Series key will be reindexed to match DataFrame index.\n",
      "  df_gather = df_multinode[df_multinode[\"benchmark_type\"]==\"Gather\"][df_multinode['msg_size_bytes']>1024][df_multinode['off_cache_flag']==-1]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['benchmark_type',\n",
       " 'proc_num',\n",
       " 'msg_size_bytes',\n",
       " 'repetitions',\n",
       " 't_min_usec',\n",
       " 't_max_usec',\n",
       " 't_avg_usec',\n",
       " 'mpi_datatype',\n",
       " 'mpi_red_datatype',\n",
       " 'mpi_red_op',\n",
       " 'creation_time',\n",
       " 'n_nodes',\n",
       " 'off_cache_flag']"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31mnotebook controller is DISPOSED. \n",
      "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
     ]
    }
   ],
   "source": [
    "df_multinode = pd.read_csv(\"../data/data-multi-defand100cflag.csv\",delimiter = \",\")\n",
    "df_multinode['benchmark_type'].unique()\n",
    "df_gather = df_multinode[df_multinode[\"benchmark_type\"]==\"Gather\"][df_multinode['msg_size_bytes']>1024][df_multinode['off_cache_flag']==-1]\n",
    "df_gather.columns.tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4336d3c6",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_4897/866829124.py:9: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed in 3.11. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap()`` or ``pyplot.get_cmap()`` instead.\n",
      "  cmap = get_cmap('tab10')\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 416748 characters]",
      "text/plain": [
       "<Figure size 1500x1600 with 12 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    msg_size_bytes  alpha          beta  inv_alpha\n",
      "0             2048    1.0  2.453824e-24        1.0\n",
      "1             4096    1.0  6.552190e-24        1.0\n",
      "2             8192    1.0  1.941168e-23        1.0\n",
      "3            16384    1.0  8.454933e-23        1.0\n",
      "4            32768    1.0  6.710026e-22        1.0\n",
      "5            65536    1.0  2.678877e-20        1.0\n",
      "6           131072    1.0  3.818473e-18        1.0\n",
      "7           262144    1.0  3.023451e-25        1.0\n",
      "8           524288    1.0  1.541516e-21        1.0\n",
      "9          1048576    1.0  1.240501e-16        1.0\n",
      "10         2097152    1.0  1.165495e-16        1.0\n",
      "11         4194304    1.0  3.834525e-18        1.0\n"
     ]
    },
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31mnotebook controller is DISPOSED. \n",
      "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
     ]
    }
   ],
   "source": [
    "def model(proc_num, alpha, beta, msg_size):\n",
    "    return (alpha * msg_size * (proc_num - 72) * 72) / (12.5 * 1e3) + 1e6*beta\n",
    "\n",
    "results = []\n",
    "msg_sizes = sorted(df_gather['msg_size_bytes'].unique())\n",
    "n_rows = int(np.ceil(len(msg_sizes) / 3))\n",
    "n_cols = min(len(msg_sizes), 3)\n",
    "fig, axes = plt.subplots(n_rows, n_cols, figsize=(5*n_cols, 4*n_rows), squeeze=False)\n",
    "cmap = get_cmap('tab10')\n",
    "\n",
    "for idx, (msg_size, group) in enumerate(df_gather.groupby('msg_size_bytes')):\n",
    "    x = group['proc_num'].values.copy()\n",
    "    y = group['t_avg_usec'].values.copy()\n",
    "    sorted_indices = np.argsort(x)\n",
    "    x = x[sorted_indices]\n",
    "    y = y[sorted_indices]\n",
    "    fit_func = lambda proc_num, alpha, beta: model(proc_num, alpha, beta, msg_size)\n",
    "    popt, _ = curve_fit(fit_func, x, y, bounds=([1, 0], [np.inf, np.inf]))\n",
    "    alpha, beta = popt\n",
    "    results.append({'msg_size_bytes': msg_size, 'alpha': alpha, 'beta': beta})\n",
    "\n",
    "    x_fit = np.linspace(min(x), max(x), 100)\n",
    "    y_fit = fit_func(x_fit, alpha, beta)\n",
    "    y_speed = model(x_fit,1,0,msg_size)\n",
    "    row, col = divmod(idx, n_cols)\n",
    "    ax = axes[row][col]\n",
    "\n",
    "    color = cmap(idx % 10)\n",
    "    # ax.scatter(x, y/1e6, label='Data', color=color)\n",
    "    ax.plot(x, y/1e6, label='Data', color=color)\n",
    "    # ax.plot(x_fit, y_fit/1e6, linestyle='--', color=color, alpha=0.5, label='Fit')\n",
    "    # ax.plot(x_fit, y_speed/1e6, linestyle='--', color='red', alpha=0.1, label='Fit')\n",
    "    ax.set_title(f'msg_size: {msg_size} bytes')\n",
    "    ax.set_xlabel('num. proc.')\n",
    "    ax.set_ylabel('Average Time [s]')\n",
    "    ax.set_xticks(x)\n",
    "    ax.grid(True)\n",
    "    max_data =(x[-1]-72)*72*msg_size\n",
    "    min_data =(x[0]-72)*72*msg_size\n",
    "\n",
    "    textstr = \"\"\n",
    "    # if(max_data > 1e9):\n",
    "    #     textstr+=f\"max data = {max_data/1e9:0.2f}GB\\n\" \n",
    "    # else:\n",
    "    #     textstr+=f\"max data = {max_data/1e6:0.2f}MB\\n\" \n",
    "\n",
    "    # if(min_data > 1e9):\n",
    "    #     textstr+=f\"min data = {min_data/1e9:0.2f}GB\\n\" \n",
    "    # else:\n",
    "    #     textstr+=f\"min data = {min_data/1e6:0.2f}MB\\n\" \n",
    "    # textstr += r\"$\\alpha$\" +f\"= {alpha:.3e}\\n\"+r\"$b_{eff}=$\"+f\"{12.5/alpha:0.3f}Gbps\\n\"+\\\n",
    "    #            r\"$\\beta$\"+f\"= {beta:.3e} s\"\n",
    "    # ax.text(0.95, 0.05, textstr, transform=ax.transAxes,\n",
    "    #         fontsize=10, verticalalignment='bottom',\n",
    "    #         horizontalalignment='right',\n",
    "    #         bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))\n",
    "\n",
    "fig.suptitle('Alltoall Time Fit per Message Size\\nDots = Data Points | Dashed Lines = Fits\\n off_mem=-1', fontsize=14)\n",
    "fig.tight_layout(rect=[0, 0.03, 1, 0.95])\n",
    "# plt.savefig(\"plots/alltoall_analysis.png\",dpi=300)\n",
    "plt.show()\n",
    "\n",
    "fit_results = pd.DataFrame(results)\n",
    "fit_results['inv_alpha'] = 1 / fit_results['alpha']\n",
    "print(fit_results)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ce632d6f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.microsoft.datawrangler.viewer.v0+json": {
       "columns": [
        {
         "name": "index",
         "rawType": "int64",
         "type": "integer"
        },
        {
         "name": "benchmark_type",
         "rawType": "object",
         "type": "string"
        },
        {
         "name": "proc_num",
         "rawType": "int64",
         "type": "integer"
        },
        {
         "name": "msg_size_bytes",
         "rawType": "int64",
         "type": "integer"
        },
        {
         "name": "repetitions",
         "rawType": "int64",
         "type": "integer"
        },
        {
         "name": "t_min_usec",
         "rawType": "float64",
         "type": "float"
        },
        {
         "name": "t_max_usec",
         "rawType": "float64",
         "type": "float"
        },
        {
         "name": "t_avg_usec",
         "rawType": "float64",
         "type": "float"
        },
        {
         "name": "mpi_datatype",
         "rawType": "object",
         "type": "string"
        },
        {
         "name": "mpi_red_datatype",
         "rawType": "object",
         "type": "string"
        },
        {
         "name": "mpi_red_op",
         "rawType": "object",
         "type": "string"
        },
        {
         "name": "creation_time",
         "rawType": "object",
         "type": "string"
        },
        {
         "name": "n_nodes",
         "rawType": "int64",
         "type": "integer"
        },
        {
         "name": "off_cache_flag",
         "rawType": "int64",
         "type": "integer"
        }
       ],
       "ref": "606abcbf-7b0e-4a04-9beb-0d5b3e056654",
       "rows": [
        [
         "470",
         "Gather",
         "360",
         "1048576",
         "40",
         "233.94",
         "36747.9",
         "19914.01",
         "MPI_BYTE",
         "MPI_FLOAT",
         "MPI_SUM",
         "25_07_26_05-44-37",
         "5",
         "-1"
        ],
        [
         "608",
         "Gather",
         "432",
         "1048576",
         "40",
         "232.5",
         "42935.8",
         "23389.38",
         "MPI_BYTE",
         "MPI_FLOAT",
         "MPI_SUM",
         "25_07_26_05-44-37",
         "6",
         "-1"
        ],
        [
         "1096",
         "Gather",
         "504",
         "1048576",
         "40",
         "229.7",
         "48937.39",
         "26558.04",
         "MPI_BYTE",
         "MPI_FLOAT",
         "MPI_SUM",
         "25_07_26_05-44-37",
         "7",
         "-1"
        ],
        [
         "1349",
         "Gather",
         "144",
         "1048576",
         "40",
         "235.39",
         "17983.16",
         "9125.46",
         "MPI_BYTE",
         "MPI_FLOAT",
         "MPI_SUM",
         "25_07_26_05-44-37",
         "2",
         "-1"
        ],
        [
         "2228",
         "Gather",
         "288",
         "1048576",
         "40",
         "237.25",
         "31719.94",
         "16419.63",
         "MPI_BYTE",
         "MPI_FLOAT",
         "MPI_SUM",
         "25_07_26_05-44-37",
         "4",
         "-1"
        ],
        [
         "3067",
         "Gather",
         "216",
         "1048576",
         "40",
         "223.96",
         "24058.05",
         "15865.52",
         "MPI_BYTE",
         "MPI_FLOAT",
         "MPI_SUM",
         "25_07_26_05-44-37",
         "3",
         "-1"
        ]
       ],
       "shape": {
        "columns": 13,
        "rows": 6
       }
      },
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>benchmark_type</th>\n",
       "      <th>proc_num</th>\n",
       "      <th>msg_size_bytes</th>\n",
       "      <th>repetitions</th>\n",
       "      <th>t_min_usec</th>\n",
       "      <th>t_max_usec</th>\n",
       "      <th>t_avg_usec</th>\n",
       "      <th>mpi_datatype</th>\n",
       "      <th>mpi_red_datatype</th>\n",
       "      <th>mpi_red_op</th>\n",
       "      <th>creation_time</th>\n",
       "      <th>n_nodes</th>\n",
       "      <th>off_cache_flag</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>470</th>\n",
       "      <td>Gather</td>\n",
       "      <td>360</td>\n",
       "      <td>1048576</td>\n",
       "      <td>40</td>\n",
       "      <td>233.94</td>\n",
       "      <td>36747.90</td>\n",
       "      <td>19914.01</td>\n",
       "      <td>MPI_BYTE</td>\n",
       "      <td>MPI_FLOAT</td>\n",
       "      <td>MPI_SUM</td>\n",
       "      <td>25_07_26_05-44-37</td>\n",
       "      <td>5</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>608</th>\n",
       "      <td>Gather</td>\n",
       "      <td>432</td>\n",
       "      <td>1048576</td>\n",
       "      <td>40</td>\n",
       "      <td>232.50</td>\n",
       "      <td>42935.80</td>\n",
       "      <td>23389.38</td>\n",
       "      <td>MPI_BYTE</td>\n",
       "      <td>MPI_FLOAT</td>\n",
       "      <td>MPI_SUM</td>\n",
       "      <td>25_07_26_05-44-37</td>\n",
       "      <td>6</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1096</th>\n",
       "      <td>Gather</td>\n",
       "      <td>504</td>\n",
       "      <td>1048576</td>\n",
       "      <td>40</td>\n",
       "      <td>229.70</td>\n",
       "      <td>48937.39</td>\n",
       "      <td>26558.04</td>\n",
       "      <td>MPI_BYTE</td>\n",
       "      <td>MPI_FLOAT</td>\n",
       "      <td>MPI_SUM</td>\n",
       "      <td>25_07_26_05-44-37</td>\n",
       "      <td>7</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1349</th>\n",
       "      <td>Gather</td>\n",
       "      <td>144</td>\n",
       "      <td>1048576</td>\n",
       "      <td>40</td>\n",
       "      <td>235.39</td>\n",
       "      <td>17983.16</td>\n",
       "      <td>9125.46</td>\n",
       "      <td>MPI_BYTE</td>\n",
       "      <td>MPI_FLOAT</td>\n",
       "      <td>MPI_SUM</td>\n",
       "      <td>25_07_26_05-44-37</td>\n",
       "      <td>2</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2228</th>\n",
       "      <td>Gather</td>\n",
       "      <td>288</td>\n",
       "      <td>1048576</td>\n",
       "      <td>40</td>\n",
       "      <td>237.25</td>\n",
       "      <td>31719.94</td>\n",
       "      <td>16419.63</td>\n",
       "      <td>MPI_BYTE</td>\n",
       "      <td>MPI_FLOAT</td>\n",
       "      <td>MPI_SUM</td>\n",
       "      <td>25_07_26_05-44-37</td>\n",
       "      <td>4</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3067</th>\n",
       "      <td>Gather</td>\n",
       "      <td>216</td>\n",
       "      <td>1048576</td>\n",
       "      <td>40</td>\n",
       "      <td>223.96</td>\n",
       "      <td>24058.05</td>\n",
       "      <td>15865.52</td>\n",
       "      <td>MPI_BYTE</td>\n",
       "      <td>MPI_FLOAT</td>\n",
       "      <td>MPI_SUM</td>\n",
       "      <td>25_07_26_05-44-37</td>\n",
       "      <td>3</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     benchmark_type  proc_num  msg_size_bytes  repetitions  t_min_usec  \\\n",
       "470          Gather       360         1048576           40      233.94   \n",
       "608          Gather       432         1048576           40      232.50   \n",
       "1096         Gather       504         1048576           40      229.70   \n",
       "1349         Gather       144         1048576           40      235.39   \n",
       "2228         Gather       288         1048576           40      237.25   \n",
       "3067         Gather       216         1048576           40      223.96   \n",
       "\n",
       "      t_max_usec  t_avg_usec mpi_datatype mpi_red_datatype mpi_red_op  \\\n",
       "470     36747.90    19914.01     MPI_BYTE        MPI_FLOAT    MPI_SUM   \n",
       "608     42935.80    23389.38     MPI_BYTE        MPI_FLOAT    MPI_SUM   \n",
       "1096    48937.39    26558.04     MPI_BYTE        MPI_FLOAT    MPI_SUM   \n",
       "1349    17983.16     9125.46     MPI_BYTE        MPI_FLOAT    MPI_SUM   \n",
       "2228    31719.94    16419.63     MPI_BYTE        MPI_FLOAT    MPI_SUM   \n",
       "3067    24058.05    15865.52     MPI_BYTE        MPI_FLOAT    MPI_SUM   \n",
       "\n",
       "          creation_time  n_nodes  off_cache_flag  \n",
       "470   25_07_26_05-44-37        5              -1  \n",
       "608   25_07_26_05-44-37        6              -1  \n",
       "1096  25_07_26_05-44-37        7              -1  \n",
       "1349  25_07_26_05-44-37        2              -1  \n",
       "2228  25_07_26_05-44-37        4              -1  \n",
       "3067  25_07_26_05-44-37        3              -1  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31mnotebook controller is DISPOSED. \n",
      "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
     ]
    }
   ],
   "source": [
    "df_gather[df_gather['msg_size_bytes']==1048576]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "data",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
