diff --git a/.github/workflows/conda-cpp-redis.yml b/.github/workflows/conda-cpp-redis.yml new file mode 100644 index 000000000..6e7f51b61 --- /dev/null +++ b/.github/workflows/conda-cpp-redis.yml @@ -0,0 +1,77 @@ +name: Conda C++/Python/Redis - gcc,OpenMPI,Redis,UCX/UCC + +on: + push: + branches: + - main + - 0.** + pull_request: + branches: + - main + - 0.** + +jobs: + build: + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash -l {0} + strategy: + fail-fast: false + # explicit include-based build matrix, of known valid options + matrix: + include: + # 20.04 supports CUDA 11.0+ + - os: ubuntu-20.04 + gcc: 9 + ucc: "master" + + steps: + - uses: actions/checkout@v2 + + # Specify the correct host compilers + - name: Install/Select gcc and g++ + run: | + sudo apt-get install -y gcc-${{ matrix.gcc }} g++-${{ matrix.gcc }} git + echo "CC=/usr/bin/gcc-${{ matrix.gcc }}" >> $GITHUB_ENV + echo "CXX=/usr/bin/g++-${{ matrix.gcc }}" >> $GITHUB_ENV + + - uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: cylon_dev + environment-file: conda/environments/cylon.yml + + - name: Activate conda + run: conda activate cylon_dev + + - name: Install UCC + run: | + git clone --single-branch -b ${{ matrix.ucc }} https://github.com/openucx/ucc.git $HOME/ucc + cd $HOME/ucc + echo "conda ucx: $(conda list | grep ucx)" + ./autogen.sh + ./configure --prefix=$HOME/ucc/install --with-ucx=$CONDA/envs/cylon_dev + make install + + - name: Install Redis + run: | + git clone https://github.com/redis/hiredis.git $HOME/hiredis + cd $HOME/hiredis + make + sudo make install + git clone https://github.com/sewenew/redis-plus-plus.git $HOME/redis-plus-plus + cd $HOME/redis-plus-plus + mkdir build + cd build + cmake -DREDIS_PLUS_PLUS_CXX_STANDARD=11 .. + make + sudo make install + + - name: Build cylon, pycylon and run cpp test + run: python build.py -cmake-flags="-DCYLON_UCX=1 -DCYLON_UCC=1 -DUCC_INSTALL_PREFIX=$HOME/ucc/install -DCYLON_USE_REDIS=1" -ipath="$HOME/cylon/install" --cpp --python --test + + - name: Run pytest + run: python build.py -ipath="$HOME/cylon/install" --pytest + + - name: Build Java + run: python build.py -ipath="$HOME/cylon/install" --java diff --git a/aws/README.md b/aws/README.md new file mode 100644 index 000000000..378b7eb52 --- /dev/null +++ b/aws/README.md @@ -0,0 +1,5 @@ +# Running Cylon on AWS ECS + +Mills Wellons Staylor, III + + diff --git a/aws/scripts/Join_Weak_Scaling.ipynb b/aws/scripts/Join_Weak_Scaling.ipynb new file mode 100644 index 000000000..b962f6948 --- /dev/null +++ b/aws/scripts/Join_Weak_Scaling.ipynb @@ -0,0 +1,279 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 473 + }, + "id": "DdPziLudpalX", + "outputId": "3c63ebcd-b960-425e-9733-7e06a43dc28d" + }, + "outputs": [ + { + "data": { + "text/plain": "
", + "image/png": "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0dERe/fuRatWrfRai7e3Nz766KNCTwumsvH48WO4uLjg+++/R//+/ct9/0V9VnX5/jYqyyKJiJTM0BB4ZmhDpXPv3j289957aNmypV7ryMrKwoABA9CjRw+91lGV5ObmIikpCZ9//jlsbGxeOFapomOYISKqohwdHfHRRx/puwyYmJhg7ty5+i6jSrlx4wY8PDzg6uqKtWvXwshI2XFA2dUTERGRzmrVqlUup0yXF56aTURERIrGMENElVZl+p8nUWVUWp9RhhkiqnSevQkhEVVceZ/R568crCuOmSGiSsfQ0BC2traaS96bm5vrdA8hIipbQgg8fvwYycnJsLW1hWEJr3nAMENElZKzszMAlMtN7ojo5dja2mo+qyXBMENElZIkSVCr1XB0dMTTp0/1XQ4RPcfY2LjEPTJ5GGaIqFIzNDQstT+YRFQxcQAwERERKRrDDBERESkawwwREREpGsMMERERKRrDDBERESkawwwREREpGsMMERERKRrDDBERESkawwwREREpGsMMERERKRrDDBERESkawwwREREpGsMMERERKRrDDBERESlahQkzwcHBkCQJU6ZM0bSNHDkSkiRpTW3atNFfkURERFThGOm7AACIiYnBt99+C29v73zLunfvjjVr1mjmTUxMyrM0IiIiquD03jOTlpaGIUOGYNWqVahWrVq+5SqVCs7OzprJzs5OD1USERFRRaX3MDNx4kS8+uqr6NKlS4HLIyMj4ejoiPr162Ps2LFITk4ucnuZmZlITU3VmoiIiKjy0uthpk2bNuHkyZOIiYkpcHmPHj3wxhtvwN3dHXFxcZgzZw46deqEEydOQKVSFfiY4OBgzJ8/vyzLJiIiogpEEkIIfew4ISEBPj4+2L9/P5o0aQIA8Pf3R9OmTbF06dICH5OYmAh3d3ds2rQJ/fv3L3CdzMxMZGZmauZTU1Ph5uaGlJQUWFtbl/rzICIiotKXmpoKGxubYn1/661n5sSJE0hOTkaLFi00bTk5OTh48CCWL1+OzMxMGBoaaj1GrVbD3d0dV65cKXS7KpWq0F4bIiIiqnz0FmY6d+6M2NhYrbZRo0bB09MTM2bMyBdkAODevXtISEiAWq0urzKJiIiogtNbmLGyskLjxo212iwsLGBvb4/GjRsjLS0N8+bNw4ABA6BWqxEfH4/Zs2fDwcEB/fr101PVRERE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DXd3d1y5ckUzD6Dcvh/1eqNJpTMxMUHLli3znbJ2+fJluLu766kqehEhBDIzMwH88wf1ypUriIiIgL29vZ6ro+e1a9euyM/YsGHD0KVLF63l3bp1w7BhwzBq1Khyq5OK70Wfu8ePHwNAvrNeDA0NkZubW251VlVCCEyaNAk7duxAZGQkPDw8XviYe/fuISEhQRNiatWqBRcXlwI/uz169Cj1mhlmXiAtLQ1//fWXZj4uLg6nT5+GnZ0datasiWnTpmHgwIHo2LEjAgICEBYWhl27diEyMlJ/RZPG7Nmz0aNHD7i5ueHRo0fYtGkTIiMjERYWhuzsbLz++us4efIkfvnlF+Tk5CApKQmAPNDNxMREz9UTALz33nto27YtFi9ejDfffBN//PEHvv32W3z77bcAAHt7+3xfhsbGxnB2dkaDBg30UXKVV9TfTRcXlxd+7jw9PVG3bl2MGzcOn332Gezt7REaGorw8HD88ssv+npaVcbEiROxYcMG/Pzzz7CystK8PzY2NjAzM0NaWhrmzZuHAQMGQK1WIz4+HrNnz4aDgwP69esHAJAkCdOmTcPcuXPRpEkTNG3aFOvWrcOff/5ZNtcLKvUDV5VMRESEAJBvGjFihGad1atXi7p16wpTU1PRpEkTERoaqr+CScvo0aOFu7u7MDExEdWrVxedO3fWDCKMi4sr8L0FICIiIvRbOGnZtWuXaNy4sVCpVMLT01N8++23Ra7PMTP6VdTfzeJ+7i5fviz69+8vHB0dhbm5ufD29s53qjaVjcLenzVr1gghhHj8+LHo2rWrqF69ujA2NhY1a9YUI0aMEDdu3Mi3reDgYOHq6irMzc2Fr6+vOHToUJnULP1/4URERESKxAHAREREpGgMM0RERKRoDDNERESkaAwzREREpGgMM0RERKRoDDNERESkaAwzREREpGgMM0SkePPmzUPTpk31XQYR6QnDDBERESkawwwREREpGsMMEZUrf39/BAUFYfr06bCzs4OzszPmzZunWX7jxg306dMHlpaWsLa2xptvvom///5baxtLliyBk5MTrKysMGbMGDx58iTfftasWYNXXnkFpqam8PT0xIoVKzTLsrKy8O6770KtVsPU1BS1atVCcHBwmT1nIipbDDNEVO7WrVsHCwsLHDt2DCEhIViwYAHCw8MhhEDfvn1x//59REVFITw8HFevXsXAgQM1j/3f//6HuXPnYtGiRTh+/DjUarVWUAGAVatW4cMPP8SiRYtw8eJFLF68GHPmzMG6desAAF9++SV27tyJ//3vf7h06RJ+/PFH1KpVqzxfAiIqRbzRJBGVK39/f+Tk5ODQoUOatlatWqFTp07o3LkzevTogbi4OLi5uQEALly4gEaNGuGPP/5Ay5Yt0bZtWzRp0gQrV67UPL5NmzZ48uQJTp8+DQCoWbMmPv30UwwaNEizzsKFC7Fnzx4cOXIEQUFBOH/+PH799VdIklQ+T5yIygx7Zoio3Hl7e2vNq9VqJCcn4+LFi3Bzc9MEGQBo2LAhbG1tcfHiRQDAxYsX4evrq/X4Z+fv3LmDhIQEjBkzBpaWlppp4cKFuHr1KgBg5MiROH36NBo0aICgoCDs37+/rJ4qEZUDI30XQERVj7Gxsda8JEnIzc2FEKLAnpLC2guSm5sLQD7U1Lp1a61lhoaGAIDmzZsjLi4Oe/fuxa+//oo333wTXbp0wdatW1/m6RCRnrFnhogqjIYNG+LGjRtISEjQtF24cAEpKSl45ZVXAACvvPIKjh49qvW4Z+ednJxQo0YNXLt2DXXr1tWaPDw8NOtZW1tj4MCBWLVqFTZv3oxt27bh/v37ZfwMiagssGeGiCqMLl26wNvbG0OGDMHSpUuRnZ2NCRMmwM/PDz4+PgCAyZMnY8SIEfDx8UH79u3x008/4fz586hdu7ZmO/PmzUNQUBCsra3Ro0cPZGZm4vjx43jw4AHef/99/Oc//4FarUbTpk1hYGCALVu2wNnZGba2tnp65kRUEuyZIaIKQ5IkhIaGolq1aujYsSO6dOmC2rVrY/PmzZp1Bg4ciI8//hgzZsxAixYtcP36dYwfP15rO2+99Ra+++47rF27Fl5eXvDz88PatWs1PTOWlpb49NNP4ePjg5YtWyI+Ph579uyBgQH/JBIpEc9mIiIiIkXjf0OIiIhI0RhmiIiISNEYZoiIiEjRGGaIiIhI0RhmiIiISNEYZoiIiEjRGGaIiIhI0RhmiIiISNEYZoiIiEjRGGaIiIhI0RhmiIiISNEYZoiIiEjR/g8TwGLPdIpx8wAAAABJRU5ErkJggg==" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# Given data\n", + "world_size = ['16', '32', '64', '128', '256']\n", + "aws_cylon = [32.217067956924437, 39.07124400138855, 38.860756039619446, 38.852088809013364, 40.244505405426025]\n", + "\n", + "\n", + "#rp_cylon_err = [1.324570749, 0.5838053194, 0.9581813981, 0.4103170195, 0.7644938386]\n", + "\n", + "\n", + "# Create a line chart\n", + "plt.plot(world_size, aws_cylon, marker='o', color='b', label='UCC/UCX/Redis AWS Cylon')\n", + "#plt.plot(world_size, rp_cylon, marker='o', color='g', label='RP-Cylon')\n", + "\n", + "#plt.errorbar(world_size, baremetal_cylon, yerr=bm_cylon_err, fmt='x', color='b', ecolor='b', capsize=5)\n", + "#plt.errorbar(world_size, rp_cylon, yerr=rp_cylon_err, fmt='o', color='g', ecolor='g', capsize=5)\n", + "\n", + "custom_text = \"9.1m rows\"\n", + "plt.text(0.3, 29, custom_text, fontsize=10, color='blue', ha='center')\n", + "\n", + "plt.ylim(15, 50)\n", + "\n", + "plt.xticks(world_size)\n", + "\n", + "# Add labels and title\n", + "plt.xlabel('nodes')\n", + "plt.ylabel('average time (s)')\n", + "plt.title('Weak Scaling of Join Operation')\n", + "\n", + "# Add a legend\n", + "plt.legend()\n", + "\n", + "plt.savefig('join-w-scaling.svg', format='svg')\n", + "\n", + "# Display the chart\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# Given data\n", + "world_size = ['16', '32', '64', '128', '256']\n", + "aws_cylon = [56.612007474899292, 33.886670994758606, 16.14104320406913, 8.0112933546304703, 3.9909562155604362]\n", + "#rp_cylon = [14.48042241, 9.80326847, 7.814679284, 6.180011416, 5.271671858, 4.710637883]\n", + "\n", + "#rp_cylon_err = [1.009763211, 0.7171293985, 0.8766151569, 1.457741798, 1.666529573, 1.440726585]\n", + "#bm_cylon_err = [1.324570749, 0.5838053194, 0.9581813981, 0.4103170195, 0.7644938386, 1.53159382]\n", + "\n", + "\n", + "# Create a line chart\n", + "plt.plot(world_size, aws_cylon, marker='o', color='b', label='UCC/UCX/Redis AWS Cylon')\n", + "#plt.plot(world_size, rp_cylon, marker='o', color='g', label='RP-Cylon')\n", + "\n", + "\n", + "#plt.errorbar(world_size, baremetal_cylon, yerr=bm_cylon_err, fmt='x', color='b', ecolor='b', capsize=5)\n", + "#plt.errorbar(world_size, rp_cylon, yerr=rp_cylon_err, fmt='o', color='g', ecolor='g', capsize=5)\n", + "\n", + "custom_text = \"145m rows\"\n", + "plt.text(0.3, 17, custom_text, fontsize=10, color='blue', ha='center')\n", + "\n", + "plt.ylim(1, 60)\n", + "\n", + "plt.xticks(world_size)\n", + "\n", + "# Add labels and title\n", + "plt.xlabel('nodes')\n", + "plt.ylabel('average time (s)')\n", + "plt.title('Strong Scaling of Join Operation')\n", + "\n", + "# Add a legend\n", + "plt.legend()\n", + "\n", + "plt.savefig('join-s-scaling.svg', format='svg')\n", + "\n", + "# Display the chart\n", + "plt.show()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 473 + }, + "id": "HvgUPka-uMRo", + "outputId": "7fd8d45a-823b-4360-c1f1-593e70d31515" + }, + "execution_count": 18, + "outputs": [ + { + "data": { + "text/plain": "
", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAHFCAYAAAAHcXhbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABs7klEQVR4nO3dd1hT1/8H8HfYGxRlCQJuEXDhAAc4cNbdat1W2/qtWsWtrVZrW1FrHa1Wa7Vq66yz2rpoBVy4xYHWiVvqBgEFgfP74/yIRECJEi6B9+t58pjcnNx8Eoh5c+4556qEEAJEREREespA6QKIiIiI3gbDDBEREek1hhkiIiLSawwzREREpNcYZoiIiEivMcwQERGRXmOYISIiIr3GMENERER6jWGGiIiI9BrDDOmlQ4cOoVOnTihbtixMTU3h6OgIf39/jBw5UqPdjz/+iGXLlilTZD46d+4cevfujXLlysHMzAylSpVCrVq1MGTIECQkJOjkOSMiIqBSqRAREaHeNnnyZKhUKp08X35au3YtqlWrBnNzc6hUKkRHR+fYLvM1rl+/XuvnyOn9yQ/Pnz/HggUL4O/vD1tbW5ibm6Nq1aoYN24cHjx4kK/PpUu5ffauXr0KlUpVJD6XVHgwzJDe+euvvxAQEICEhATMmDEDu3btwty5c9GgQQOsXbtWo21RCDMnTpxA7dq1cfbsWXzxxRfYsWMHFi5ciLZt22Lnzp14+PBhgdXy4YcfIioqqsCe703cu3cPvXv3Rvny5bFjxw5ERUWhUqVK+f48tWrVQlRUFGrVqpVv+0xOTkZwcDA+/fRT1KxZE6tXr8a2bdvQu3dvLFq0CDVr1sT58+fz7fl0KbfPnrOzM6KiotC2bduCL4qKLkGkZxo3bizKly8vnj9/nu2+9PR0jdvVqlUTgYGBedpvampqjvtUWp8+fYSlpaVISEjI8f6MjAydPG94eLgAIMLDw3Wyf13Zt2+fACDWrl372raZr3HdunUFUNnrffzxxwKAWLNmTbb7zp8/L2xtbUW1atVEWlpagdaVkZEhkpOTtXqMNp89orfFnhnSOw8ePECpUqVgZGSU7T4Dgxe/0h4eHoiJiUFkZCRUKhVUKhU8PDwAvDhE8Ntvv2HkyJEoU6YMTE1NcenSJQDAL7/8gurVq8PMzAwlS5ZEp06dcO7cOY3n6tevH6ysrHDp0iW0adMGVlZWcHNzw8iRI5GSkqLR9ubNm3j33XdhbW0NOzs79OzZE0eOHMlTd/uDBw9gY2MDKyurHO9/+bDPjh070KxZM9ja2sLCwgJVq1ZFaGio+v6jR4/i/fffh4eHB8zNzeHh4YHu3bvj2rVrr6wDyPkwk4eHB9555x3s2LEDtWrVgrm5OapUqYJffvkl2+P37dsHf39/mJmZoUyZMpg4cSIWL14MlUqFq1evvvb5t2zZAn9/f1hYWMDa2hrBwcEaPUX9+vVDw4YNAQDdunWDSqVCUFDQa/ebU53NmjWDtbU1LCwsEBAQgL/++kujTU6HmbT5nXhZXFwcfvnlF7Rs2RLdunXLdn+lSpUwduxYxMTEYPPmzertme//pk2b4OvrCzMzM5QrVw7ff/99tn0kJCRg1KhR8PT0hImJCcqUKYOQkBAkJSVptFOpVBgyZAgWLlyIqlWrwtTUFMuXLwcAfPnll6hXrx5KliwJGxsb1KpVC0uWLIHIcs7iV332cjvMlJf3fNmyZVCpVAgPD8cnn3yCUqVKwd7eHp07d8bt27df+f5S0cYwQ3rH398fhw4dwtChQ3Ho0CE8f/48x3abNm1CuXLlULNmTURFRSEqKgqbNm3SaDN+/Hhcv34dCxcuxNatW+Hg4IDQ0FAMGDAA1apVw8aNGzF37lycOnUK/v7+uHjxosbjnz9/jvbt26NZs2b4448/0L9/f8yePRvTp09Xt0lKSkKTJk0QHh6O6dOn4/fff4ejo2OOX1i5vd47d+6gZ8+eiIyMxNOnT3Ntu2TJErRp0wYZGRnq1zR06FDcvHlT3ebq1auoXLky5syZg507d2L69Om4c+cO6tSpg/v37+epppedPHkSI0eOxPDhw/HHH3/A19cXAwYMwJ49e9RtTp06heDgYCQnJ2P58uVYuHAhjh8/jm+++SZPz7Fq1Sp06NABNjY2WL16NZYsWYJHjx4hKCgI+/btAwBMnDgR8+fPBwBMnToVUVFR+PHHH7V6LZGRkWjatCni4+OxZMkSrF69GtbW1mjXrl22w5g5ycvvRE7Cw8ORlpaGjh075tom876wsDCN7dHR0QgJCcHw4cOxadMmBAQEYNiwYZg5c6a6TXJyMgIDA7F8+XIMHToU27dvx9ixY7Fs2TK0b99eI4wAwObNm7FgwQJ88cUX2LlzJxo1agRA/v4MHDgQv//+OzZu3IjOnTvj008/xVdffaV+bF4+e1lp+55/+OGHMDY2xqpVqzBjxgxERESgV69eue6figGlu4aItHX//n3RsGFDAUAAEMbGxiIgIECEhoaKJ0+eaLTNras78/BC48aNNbY/evRImJubizZt2mhsv379ujA1NRU9evRQb+vbt68AIH7//XeNtm3atBGVK1dW354/f74AILZv367RbuDAgQKAWLp06Stf77Nnz0THjh3Vr9fQ0FDUrFlTfP755+Lu3bvqdk+ePBE2NjaiYcOGWh16SktLE4mJicLS0lLMnTtXvT2nw0yTJk0SL/+34e7uLszMzMS1a9fU254+fSpKliwpBg4cqN723nvvCUtLS3Hv3j31tvT0dOHl5SUAiNjY2FxrTE9PFy4uLsLHx0fjUOKTJ0+Eg4ODCAgIyFZ3Xg4d5dS2fv36wsHBQeN3KS0tTXh7ewtXV1f1e5vT+5PX34mcTJs2TQAQO3bsyLXN06dPBQDRunVr9TZ3d3ehUqlEdHS0Rtvg4GBhY2MjkpKShBBChIaGCgMDA3HkyBGNduvXrxcAxLZt29TbAAhbW1vx8OHDV9acnp4unj9/LqZMmSLs7e01fu9y++zFxsZm+73P63u+dOlSAUAMGjRIY58zZswQAMSdO3deWS8VXeyZIb1jb2+PvXv34siRI5g2bRo6dOiACxcuYPz48fDx8dGqd6FLly4at6OiovD06VP069dPY7ubmxuaNm2Kf/75R2O7SqVCu3btNLb5+vpqHLKJjIyEtbU1WrVqpdGue/fuearR1NQUmzZtwtmzZzF79my8//77uHfvHr755htUrVpVPSD0wIEDSEhIwKBBg1454ygxMRFjx45FhQoVYGRkBCMjI1hZWSEpKSnbobS8qlGjBsqWLau+bWZmhkqVKmV7H5o2bYpSpUqptxkYGKBr166v3f/58+dx+/Zt9O7dW+NQopWVFbp06YKDBw8iOTn5jWrPKikpCYcOHcK7776rcVjP0NAQvXv3xs2bN187ADcvvxNv6+Wfb7Vq1VC9enWNbT169EBCQgKOHz8OAPjzzz/h7e2NGjVqIC0tTX1p2bJljrOymjZtihIlSmR77t27d6N58+awtbWFoaEhjI2N8cUXX+DBgwe4e/eu1q/lTd7z9u3ba9z29fUFgHx9j0m/MMyQ3vLz88PYsWOxbt063L59G8OHD8fVq1cxY8aMPO/D2dlZ43bm1NeXtwOAi4tLtqmxFhYWMDMz09hmamqKZ8+eaezT0dEx2/5y2vYqVatWRUhICFasWIHr169j1qxZePDgASZOnAhAzuIBAFdX11fup0ePHpg3bx4+/PBD7Ny5E4cPH8aRI0dQunTpVx7CehV7e/ts20xNTTX29zbvw+t+LhkZGXj06JE2Jefo0aNHEELk+jxZa8lNXn4ncpIZBmNjY3Ntk3mfm5ubxnYnJ6dsbTO3Zdb733//4dSpUzA2Nta4WFtbQwiR7Y+AnN6Dw4cPo0WLFgCAn3/+Gfv378eRI0fw+eefA8Ab/f68yXv+8u+bqanpGz8/FQ3ZR1AS6SFjY2NMmjQJs2fPxpkzZ/L8uJf/ws38T/LOnTvZ2t6+fVujVyGv7O3tcfjw4Wzb4+LitN5XJpVKheHDh2PKlCnq11u6dGkA0Bgf87L4+Hj8+eefmDRpEsaNG6fenpKSovMp3vb29vjvv/+ybc/L+/C6n4uBgUGOvQjaKlGiBAwMDHJ9HgBv9DuQF02aNIGRkRE2b96M//3vfzm2yRz4GxwcrLE9p/cwc1vme1eqVCmYm5vnODA78/6scurdW7NmDYyNjfHnn39qBLasA5K1peR7TkUHe2ZI7+T0nx4A9SGSzL/mgOy9A6/j7+8Pc3NzrFixQmP7zZs3sXv3bjRr1kzregMDA/HkyRNs375dY/uaNWvy9PjcXu/t27eRkJCgfr0BAQGwtbXFwoULsw3mzKRSqSCEUP8lm2nx4sVIT0/PUz1vKjAwELt379boAcjIyMC6dete+9jKlSujTJkyWLVqlcZrS0pKwoYNG9QznN6WpaUl6tWrh40bN2r83mRkZGDFihVwdXXVyZo1gOxJ6d+/P3bu3JnjoNcLFy5g+vTpqFatWrZBwjExMTh58qTGtlWrVsHa2lq9Ds4777yDy5cvw97eHn5+ftkumbONXkWlUsHIyAiGhobqbU+fPsVvv/2WrW1eP3tKvudUdLBnhvROy5Yt4erqinbt2qFKlSrIyMhAdHQ0vvvuO1hZWWHYsGHqtj4+PlizZg3Wrl2rXj3Xx8cn133b2dlh4sSJ+Oyzz9CnTx90794dDx48wJdffgkzMzNMmjRJ63r79u2L2bNno1evXvj6669RoUIFbN++HTt37gSgOZ08Jx9//DEeP36MLl26wNvbG4aGhvj3338xe/ZsGBgYYOzYsQDk+JHvvvsOH374IZo3b46PPvoIjo6OuHTpEk6ePIl58+bBxsYGjRs3xrfffotSpUrBw8MDkZGRWLJkCezs7LR+bdr4/PPPsXXrVjRr1gyff/45zM3NsXDhQvW04Fe9DwYGBpgxYwZ69uyJd955BwMHDkRKSgq+/fZbPH78GNOmTXur2rL2QoSGhiI4OBhNmjTBqFGjYGJigh9//BFnzpzB6tWrdboC8qxZs3D+/Hn06tULe/bsQbt27WBqaoqDBw9i5syZsLa2xoYNGzTCBCADfPv27TF58mQ4OztjxYoVCAsLw/Tp09UhLyQkBBs2bEDjxo0xfPhw+Pr6IiMjA9evX8euXbswcuRI1KtX75X1tW3bFrNmzUKPHj3w8ccf48GDB5g5c2a2cAxo99lT8j2nIkLJ0cdEb2Lt2rWiR48eomLFisLKykoYGxuLsmXLit69e4uzZ89qtL169apo0aKFsLa2FgCEu7u7EOL1M14WL14sfH19hYmJibC1tRUdOnQQMTExGm369u0rLC0tsz02pxk/169fF507dxZWVlbC2tpadOnSRWzbtk0AEH/88ccrX+/OnTtF//79hZeXl7C1tRVGRkbC2dlZdO7cWURFRWVrv23bNhEYGCgsLS2FhYWF8PLyEtOnT1fff/PmTdGlSxdRokQJYW1tLVq1aiXOnDkj3N3dRd++fdXttJnN1LZt22x1BAYGZpvNsnfvXlGvXj1hamoqnJycxOjRo8X06dMFAPH48eNXvg9CCLF582ZRr149YWZmJiwtLUWzZs3E/v37NdpoM5vpr7/+EgDE1q1bs9XZtGlTYWlpKczNzUX9+vWztcltNlNefydyk5qaKubPny/q1asnrKyshKmpqahcubIYM2aMuH//frb2me//+vXrRbVq1YSJiYnw8PAQs2bNytY2MTFRTJgwQVSuXFn9u+3j4yOGDx8u4uLi1O0AiMGDB+dY3y+//CIqV64sTE1NRbly5URoaKhYsmRJthlpuX32cprNJETe3vPM2Uwvz8jS1wUeKf+ohMilP5qIdGrq1KmYMGECrl+//tpBu0VZixYtcPXqVVy4cKHAn3v27NkYMWIEYmJi4OXlVeDPnx88PDzg7e2NP//8U+lSiBTDw0xEBWDevHkAgCpVquD58+fYvXs3vv/+e/Tq1atYBZkRI0agZs2acHNzw8OHD7Fy5UqEhYVhyZIlBVpHTEwMTpw4gRkzZqBGjRp6G2SISGKYISoAFhYWmD17Nq5evYqUlBSULVsWY8eOxYQJE5QurUClp6fjiy++QFxcHFQqFby8vPDbb78V+OqtQ4YMwbFjxxAYGIgffvihQJ+biPIfDzMRERGRXlN8avatW7fQq1cv2Nvbw8LCAjVq1MCxY8fU9wshMHnyZLi4uMDc3BxBQUGIiYlRsGIiIiIqTBQNM48ePUKDBg1gbGyM7du34+zZs/juu+80pojOmDEDs2bNwrx583DkyBE4OTkhODgYT548Ua5wIiIiKjQUPcw0btw47N+/H3v37s3xfiEEXFxcEBISol5LIyUlBY6Ojpg+fToGDhxYkOUSERFRIaRomPHy8kLLli1x8+ZNREZGokyZMhg0aBA++ugjAMCVK1dQvnx5HD9+HDVr1lQ/rkOHDrCzs8Py5cuz7TMlJQUpKSnq2xkZGXj48CHs7e258BIREZGeEELgyZMncHFxee3ioooummdqaipMTU3F+PHjxfHjx8XChQuFmZmZWL58uRBCiP379wsA4tatWxqP++ijj0SLFi1y3Gfm4lS88MILL7zwwov+X27cuPHaPKHo1OyMjAz4+flh6tSpAICaNWsiJiYGCxYsQJ8+fdTtXu5REULk2ssyfvx4jBgxQn07Pj4eZcuWxY0bN2BjY6ODV0FERET5LSEhAW5ubrC2tn5tW0XDjLOzc7bFqqpWrYoNGzYAeHEK+7i4OI3Tw9+9exeOjo457tPU1DTH84TY2NgwzBAREemZvAwRUXQ2U4MGDXD+/HmNbRcuXIC7uzsAwNPTE05OTggLC1Pfn5qaisjISAQEBBRorURERFQ4KdozM3z4cAQEBGDq1Kno2rUrDh8+jEWLFmHRokUAZBoLCQnB1KlTUbFiRVSsWBFTp06FhYUFevTooWTpREREVEgoGmbq1KmDTZs2Yfz48ZgyZQo8PT0xZ84c9OzZU91mzJgxePr0KQYNGoRHjx6hXr162LVrV56OoREREVHRV+RPZ5CQkABbW1vEx8dzzAxRMZSeno7nz58rXQYRvcTY2BiGhoa53q/N9zdPNElERZIQAnFxcXj8+LHSpRBRLuzs7ODk5PTW68AxzBBRkZQZZBwcHGBhYcFFM4kKESEEkpOTcffuXQDQmLH8JhhmiKjISU9PVwcZe3t7pcshohyYm5sDkMutODg4vPKQ0+softZsIqL8ljlGxsLCQuFKiOhVMj+jbzuujWGGiIosHloiKtzy6zPKMENERER6jWGGiIiKnX79+qFjx47q20FBQQgJCVGsnsJIn94ThhkiolykpwMREcDq1fLf9HTdPl9uXx6bN2/O1h2fmpqKGTNmoHr16rCwsECpUqXQoEEDLF26VGP8QVxcHD799FOUK1cOpqamcHNzQ7t27fDPP/9kex5PT0/s2LEDy5Ytg52dXY412tnZYdmyZRrbwsPD0aZNG9jb28PCwgJeXl4YOXIkbt26BQD48ccfYWdnhxs3bmg8bsiQIahUqRKSk5OzvQ8LFy7E1atXoVKp1BdbW1vUr18fW7duze0tfGMbN27EV1999db7qVy5MkxMTNSvHQB27NgBlUqFuLg4jbZOTk5wc3PT2Hbz5k2oVCrs2rULAHDlyhV0794dLi4uMDMzg6urKzp06IALFy68sg5tfu5FAcMMEVEONm4EPDyAJk2AHj3kvx4ecrvSUlNT0bJlS0ybNg0ff/wxDhw4gMOHD2Pw4MH44YcfEBMTAwC4evUqateujd27d2PGjBk4ffo0duzYgSZNmmDw4MEa+zx16hQePHiAJk2aaFXLTz/9hObNm8PJyQkbNmzA2bNnsXDhQsTHx+O7774DAHzyySeoW7cuBgwYoH7c7t278dNPP2HZsmUaA7UfPnyIAwcOoF27duptf//9N+7cuYNDhw6hbt266NKlC86cOaP1+/YqJUuWfOuV5fft24dnz57hvffe0wh8DRs2hJGRESIiItTbzp07h2fPniEhIQGXLl1Sbw8PD4exsTEaNGiA1NRUBAcHIyEhARs3bsT58+exdu1aeHt7Iz4+Ptc6tPm5FxmiiIuPjxcARHx8fL7uNy1NiPBwIVatkv+mpeXr7onoLTx9+lScPXtWPH369I0ev2GDECqVEIDmRaWSlw0b8rng/xcYGCiGDRuWbfumTZtE1v+up0+fLgwMDMTx48eztU1NTRWJiYlCCCFat24typQpo76d1aNHjzRuT5kyRbz77rtCCCGWLl0qbG1tc6zR1tZWLF26VAghxI0bN4SJiYkICQnJsW3W57h+/bqwtbUVCxYsEPHx8aJs2bJi9OjR2R7z66+/Cj8/PyGEELGxsQKAOHHihPr+hIQEAUB8//336m03b94UXbt2FXZ2dqJkyZKiffv2IjY2Vn1/WlqaGD58uLC1tRUlS5YUo0ePFn369BEdOnRQt3n5vZ8/f76oUKGCMDU1FQ4ODqJLly45vsas+vXrJ8aNGye2b98uypUrJzIyMtT3+fv7i4EDB6pv//jjj6Jt27aiTZs24ueff1Zv79+/v2jQoIEQQogTJ04IAOLq1auvfe6s8vJz/+CDD0Tbtm017nv+/LlwdHQUS5YsEUJkf08ePnwoevfuLezs7IS5ublo1aqVuHDhgvr+zN+bHTt2iCpVqghLS0vRsmVLcfv27VxrfdVnVZvvb/bMvIHC/BcbEeVMCCAp6fWXhARg6FDZPqd9AMCwYbJdXvanixPGrFy5Es2bN0fNmjWz3WdsbAxLS0s8fPgQO3bswODBg2FpaZmt3cuHkbZs2YIOHTpoVce6deuQmpqKMWPG5Hh/1udwc3PD7NmzMXr0aPTq1QtWVlY5HtZ5VR3Pnz/Hzz//DEC+TgBITk5GkyZNYGVlhT179mDfvn2wsrJCq1atkJqaCgD47rvv8Msvv2DJkiXYt28fHj58iE2bNuX6uo4ePYqhQ4diypQpOH/+PHbs2IHGjRu/8r148uQJ1q1bh169eiE4OBhJSUkaPTFNmjRBeHi4+nZ4eDiCgoIQGBiYbXtm71jp0qVhYGCA9evXIz2Pxzjz+nP/8MMPsWPHDty5c0d937Zt25CYmIiuXbvmuO9+/frh6NGj2LJlC6KioiCEQJs2bTQOayYnJ2PmzJn47bffsGfPHly/fh2jRo3KU+1v5bVxR8/ld8+MUn+xEVHe5fTXXmJi9s9tQVxy+OM4V3ntmTE3NxdDhw595b4OHTokAIiNGze+9nlv3rwpjI2NxYMHD4QQee+Z+eSTT4SNjc1r959V/fr1BQBx6NChbPc9e/ZMWFtbi1OnTgkhXvTMmJubC0tLS2FgYCAACA8PD3WtS5YsEZUrV9boBUlJSRHm5uZi586dQgghnJ2dxbRp09T3P3/+XLi6uubaM7NhwwZhY2MjEhIS8vy6Fi1aJGrUqKG+PWzYMNGzZ0/17V27dgkA6l4KBwcHcfjwYXHw4EHh4uIihJC9VwDEP//8o37cvHnzhIWFhbC2thZNmjQRU6ZMEZcvX861Dm1+7l5eXmL69Onq2x07dhT9+vVT3876nly4cEEAEPv371fff//+fWFubi5+//13IYT8vQEgLl26pG4zf/584ejomGsN7JlRQHq6/IvsVX+xhYTofpAgERVvQojXrs8h/v8/pbys47FlyxY0aNAAJUuWzPc6sjp58iSOHTsGCwsL7N27N9v9u3fvhr29PXx8fDS2r127FidOnMCWLVtQoUIFLF68WF3rsWPHcOnSJVhbW8PKygpWVlYoWbIknj17hsuXLyM+Ph537tyBv7+/en9GRkbw8/PLtc7g4GC4u7ujXLly6N27N1auXJltkPLLlixZgl69eqlv9+rVCxs3blSfG6xBgwYwMTFBREQEzp49i6dPn6JWrVqoXbs2EhIScPHiRYSHh8PU1BQBAQHq/QwePBhxcXFYsWIF/P39sW7dOlSrVg1hYWE51qHNz/3DDz/E0qVLAchVeP/66y/0798/x7bnzp2DkZER6tWrp95mb2+PypUr49y5c+ptFhYWKF++vPq2s7Oz+pQFusQwo4W9e4GbN3O/Xwjgxg3ZjogKFwsLIDHx9Zdt2/K2v23b8rY/bRYhtrGxyXFg5+PHjzXOGlypUiWNL5CcVKxYESqV6rXtgOyHdmxsbJCYmJjt0EZ6ejoSExNha2urriMzLLxOamoq+vTpg+7du+Onn37ChAkTss3Iye0Qk5ubGypWrIi2bdti8eLF6Natm/oLMiMjA7Vr10Z0dLTG5cKFC+jRo8dr68qJtbU1jh8/jtWrV8PZ2RlffPEFqlevnutJS8+ePYtDhw5hzJgxMDIygpGREerXr4+nT59i9erVAOSXfN26dREeHo7w8HA0bNgQhoaGMDIyQkBAgHq7v78/zMzMstXTvn17fPPNNzh58iQaNWqEr7/+OsdatPm59+nTB1euXEFUVBRWrFgBDw8PNGrUKMe2Iqe/4pE90GYe/sukUqlyfWx+YpjRQh4+r1q1I6KCo1IBlpavv7RoAbi6yva57cfNTbbLy/60WeC0SpUqOHr0aLbtR44cQeXKldW3e/Togb///hsnTpzI1jYtLQ1JSUkoWbIkWrZsifnz5yMpKSlbu8wv5sTERISHh6N9+/YadaSnp2fb//Hjx5Genq6u5d1334WJiQlmzJiR4+vJ+uU/ZcoUPHjwAHPnzkWvXr3QsmVLfPDBB8jIyAAgvxS3bt2qUUdOAgMD4e3tjW+++QYAUKtWLVy8eBEODg6oUKGCxsXW1ha2trZwdnbGwYMHNd6jY8eOvfJ5jIyM0Lx5c8yYMQOnTp3C1atXsXv37hzbLlmyBI0bN8bJkyc1AtWYMWOwZMkSdbsmTZogIiICERERCAoK0nhNmdtfN5tMpVKhSpUqOf5MAeT55w7InpWOHTti6dKlWLp0KT744INcn9fLywtpaWk4dOiQetuDBw9w4cIFVK1a9ZU1F4jXHojSc/k5ZiY8PG/HyMPD3/qpiOgt5NdsppfHx+l6bFxsbKwwNzcXgwYNEtHR0eL8+fNi3rx5wtTUVD0uQQg5tqRRo0aiRIkSYt68eSI6OlpcvnxZrF27VtSqVUs9++fKlSvCyclJeHl5ifXr14sLFy6Is2fPirlz54oqVaoIIYRYt26d8Pb2zlZL69athY+PjwgLCxNXrlwRYWFhwsfHR7Ru3Vqj3fz584VKpRL9+/cXERER4urVq2Lfvn3i448/FiNGjBBCCHHkyBFhZGQktm/frn7cnTt3RMmSJcXMmTPVbezs7MTz58813g+8NJtJCCG2bNkiTE1Nxc2bN0VSUpKoWLGiCAoKEnv27BFXrlwRERERYujQoeLGjRtCCCGmTZsmSpQoITZu3CjOnTsnPvroI2FtbZ3rmJmtW7eKuXPnihMnToirV6+KH3/8URgYGIgzZ85ke59SU1NF6dKlxYIFC7LdlznOJDo6WgghxO7duwUAYWVlJQ4ePKhut2/fPmFtbS0AiD179qi3nzhxQrRv316sW7dOxMTEiIsXL4rFixcLS0tLMWXKlGzPlykvP/dMu3btEiYmJsLQ0FDcunVL476Xx3B16NBBeHl5ib1794ro6GjRqlUrUaFCBZGamiqEyHms1cvjvV6WX2NmGGa0kJYmhKtrzgOAM/+jc3PjNG0ipb1tmBFCBhZXV83PuJub7gf5Hz16VLRs2VI4ODgIGxsb4efnJ1avXp2t3bNnz0RoaKjw8fERZmZmomTJkqJBgwZi2bJlGoHg9u3bYvDgwcLd3V2YmJiIMmXKiPbt24vw//+rq1evXuLzzz/Ptv/4+HgxfPhwUaFCBWFmZiYqVKggQkJCxOPHj7O1DQsLEy1bthQlSpQQZmZmokqVKmLUqFHi9u3b4tmzZ8LLy0t89NFH2R63cuVKYWZmJv79918xYcIEjQGzQuQeZjIyMkTlypXFJ598IoSQwahPnz6iVKlSwtTUVJQrV0589NFH6v/3nz9/LoYNGyZsbGyEnZ2dGDFixCunZu/du1cEBgaKEiVKCHNzc+Hr6yvWrl2b/YclhFi/fr0wMDAQcXFxOd7v4+MjPv30UyGE/L00NTUVVlZWGj+jlJQUYWFhIczNzUVKSop6+71798TQoUOFt7e3sLKyEtbW1sLHx0fMnDlTpKen5/h8mV73c8/6Xrq7u4s2bdpk20duU7NtbW2Fubm5aNmyZY5Ts7MqqDCjEqIADmYpKCEhAba2toiPj9c45vymNm4E3n1XXs/pnduwAejc+a2fhojewrNnzxAbGwtPT89s4w+0kZ4ux8DduQM4OwONGgGGhvlYqMLS09Ph4OCA7du3o27duorW4uvriwkTJuQ6LZh0Izk5GS4uLvjll1/QWYEvr1d9VrX5/jbSZZFFUefOwPr1clbTy4OBDQ0BFxdl6iKi/GdoCGQZ2lDkPHjwAMOHD0edOnUUrSM1NRVdunRB69atFa2jOMnIyEBcXBy+++472NravnasUmHHnpk3lPUvNicn4IcfgE2bZJg5fhxwdMy3pyIiLeVXzwxRUXX16lV4enrC1dUVy5YtQ7NmzRSpgz0zCnv5LzY/P+Dff4Fz54D33gP++Qd4aYYaERFRoeDh4VEgU6YLCqdm5xNra9kzY2Mje2wKYvVmIiIiYpjJV5UrA7/+Kq9//z2wYoWy9RAVd0XpL0+ioii/PqMMM/msQwdgwgR5/eOPgehoRcshKpaynoSQiAqvzM/oyysHa4tjZnRg8mTg2DFg+3agUyfg6FHA3l7pqoiKD0NDQ9jZ2amXvLewsNDqHEJEpFtCCCQnJ+Pu3buws7OD4VuuecAwowOGhsDKlXJQ8JUrQI8e8jwuRWl9CqLCzsnJCQAK5CR3RPRm7Ozs1J/Vt8Gp2Tp06hTg7w8kJwPjxwNTpxbo0xMR5MJwz58/V7oMInqJsbHxK3tkODW7kPD1BZYsAbp3B0JDZU8NVwcmKliGhoZv3YVNRIUbBwDr2PvvAyNGyOt9+wJnzypbDxERUVHDMFMApk+XC+wlJsoBwfHxSldERERUdDDMFAAjI2DtWsDVFbhwQfbQZGQoXRUREVHRwDBTQBwc5Bm3TU2BP/7gYGAiIqL8wjBTgOrUAX78UV7/4gu5Dg0RERG9HYaZAta/PzBwICCEXH/m8mWlKyIiItJvDDMKmDsXqF8fePxYDghOSlK6IiIiIv3FMKMAU1NgwwbA0RE4fRr48EPZU0NERETaY5hRiIsLsG6dnOm0Zg0wZ47SFREREeknhhkFNWoEzJolr48eDYSHK1sPERGRPmKYUdiQIUDv3kB6OtCtG3DjhtIVERER6ReGGYWpVMBPPwE1agD37gFdugDPnildFRERkf5gmCkEzM2BTZuAkiWBI0dkbw0HBBMREeUNw0wh4eEhBwIbGMgzbS9apHRFRERE+oFhphAJDn5xmoNPPwWiopSth4iISB8wzBQyY8bIcTPPnwPvvgvExSldERERUeHGMFPIqFTA0qWAlxdw+zbQtasMNkRERJQzhplCyNpaDgi2sQH27gVGjlS6IiIiosKLYaaQqlQJ+O03ef2HH15cJyIiIk0MM4VY+/bAxIny+scfAydOKFsPERFRYcQwU8hNngy0aSMX0uvcGXjwQOmKiIiICheGmULOwABYsQIoXx64ehXo3l2e+oCIiIgkhhk9UKKEHBBsYQGEhQETJihdERERUeGhaJiZPHkyVCqVxsXJyUl9vxACkydPhouLC8zNzREUFISYmBgFK1aOj49cGRgApk0DNmxQth4iIqLCQvGemWrVquHOnTvqy+nTp9X3zZgxA7NmzcK8efNw5MgRODk5ITg4GE+ePFGwYuW8//6Ladr9+gFnzypaDhERUaGgeJgxMjKCk5OT+lK6dGkAsldmzpw5+Pzzz9G5c2d4e3tj+fLlSE5OxqpVqxSuWjnTpgFNmwKJiUCnTkB8vNIVERERKUvxMHPx4kW4uLjA09MT77//Pq5cuQIAiI2NRVxcHFq0aKFua2pqisDAQBw4cECpchVnZCRPSOnmBly4APTpA2RkKF0VERGRchQNM/Xq1cOvv/6KnTt34ueff0ZcXBwCAgLw4MEDxP3/SYkcHR01HuPo6Ki+LycpKSlISEjQuBQ1pUsDGzcCpqbAli3AN98oXREREZFyFA0zrVu3RpcuXeDj44PmzZvjr7/+AgAsX75c3UalUmk8RgiRbVtWoaGhsLW1VV/c3Nx0U7zC/PyABQvk9UmTgG3blK2HiIhIKYofZsrK0tISPj4+uHjxonpW08u9MHfv3s3WW5PV+PHjER8fr77cuHFDpzUr6YMPgE8+AYQAevYELl1SuiIiIqKCV6jCTEpKCs6dOwdnZ2d4enrCyckJYWFh6vtTU1MRGRmJgICAXPdhamoKGxsbjUtRNmcO4O8PPH4sVwhOSlK6IiIiooKlaJgZNWoUIiMjERsbi0OHDuHdd99FQkIC+vbtC5VKhZCQEEydOhWbNm3CmTNn0K9fP1hYWKBHjx5Kll2omJgA69cDTk7A6dPAgAGyp4aIiKi4MFLyyW/evInu3bvj/v37KF26NOrXr4+DBw/C3d0dADBmzBg8ffoUgwYNwqNHj1CvXj3s2rUL1tbWSpZd6Li4AOvWAU2aAGvXAnXrAiNGKF0VERFRwVAJUbT/jk9ISICtrS3i4+OL/CGn+fOBIUMAQ0N52oMmTZSuiIiI6M1o8/1dqMbM0NsZNEiuO5OeDnTtCly/rnRFREREuscwU4SoVMDChUCtWsD9+0CXLsCzZ0pXRUREpFsMM0WMublcUM/eHjh6VPbWFO0DiUREVNwxzBRB7u7ylAcGBsDSpcBPPyldERERke4wzBRRzZsDoaHy+tChQFSUsvUQERHpCsNMETZ6NPDee8Dz53L8zCtOaUVERKS3GGaKMJUK+OUXwMsLuHNHBpvUVKWrIiIiyl8MM0WclRWwaRNgYwPs2weMHKl0RURERPmLYaYYqFQJWLlSXp83D/j1V2XrISIiyk8MM8XEO+8AkybJ6wMHAsePK1sPERFRfmGYKUa++AJo21YupNe5s1xYj4iISN8xzBQjBgbAihVAhQrAtWtA9+5AWprSVREREb0dhplixs5ODgi2tAT+/huYMEHpioiIiN4Ow0wx5O0tp2wDwPTpwPr1ytZDRET0NhhmiqmuXYFRo+T1fv2AmBhFyyEiInpjDDPFWGgo0KwZkJQEdOoEPH6sdEVERETaY5gpxoyMgNWrgbJlgYsXgT59gIwMpasiIiLSDsNMMVe6NLBxI2BqCmzdCnz9tdIVERERaYdhhlC7NrBwobw+eTLw11+KlkNERKQVhhkCIAcBDxoECAH07AlcuqR0RURERHnDMENqs2cDAQFAfLwcEJyYqHRFREREr8cwQ2omJsC6dYCTE3DmDDBggOypISIiKswYZkiDi4tcRM/ICPj9d+C775SuiIiI6NUYZiibBg2AuXPl9bFjgd27la2HiIjoVRhmKEeffAL07SvXnenWDbh+XemKiIiIcsYwQzlSqYAFC4BatYD794HOnYGnT5WuioiIKDuGGcqVublcUK9UKeDYsRdTt4mIiAoThhl6JXd3YM0awMAAWLbsxeJ6REREhQXDDL1Ws2bAtGny+rBhwIEDytZDRESUFcMM5cmoUUDXrsDz50CXLsCdO0pXREREJDHMUJ6oVMCSJUC1akBcHPDee0BqqtJVERERMcyQFqysgE2bAFtbYP9+YMQIpSsiIiJimCEtVawIrFghr8+fDyxfrmw9REREDDOktXfeASZPltcHDgSOH1e0HCIiKuYYZuiNTJwoQ01KijzD9v37SldERETFFcMMvREDA+C33+Rhp+vXgfffB9LSlK6KiIiKI4YZemN2dnJAsKUl8M8/wGefKV0REREVRwwz9FaqVQOWLpXXv/0WWLdO2XqIiKj4YZiht/bee8Do0fL6Bx8AZ84oWw8RERUvDDOUL6ZOlac9SEqSA4IfP1a6IiIiKi4YZihfGBnJE1K6uwOXLgG9ewMZGUpXRURExQHDDOWbUqWAjRsBMzPgzz+Br75SuiIiIioOGGYoX9WqBSxcKK9PnixDDRERkS4xzFC+69sXGDxYXu/VC7h4Udl6iIioaGOYIZ2YNQto0ACIj5cDghMTla6IiIiKKoYZ0gkTE7nmjLMzEBMDDBgACKF0VUREVBQxzJDOODsD69cDxsbA778DM2cqXRERERVFDDOkUwEBwNy58vq4cfK0B0RERPmJYYZ07n//kysDZ2QA3boB164pXRERERUlDDOkcyoV8OOPQO3awIMHQOfOwNOnSldFRERFBcMMFQgzM7mgXqlSwPHjwCefcEAwERHlD4YZKjBlywJr1wIGBsDy5cCCBUpXRERERUGhCTOhoaFQqVQICQlRbxNCYPLkyXBxcYG5uTmCgoIQExOjXJH01po2BaZPl9eHDQP271e2HiIi0n+FIswcOXIEixYtgq+vr8b2GTNmYNasWZg3bx6OHDkCJycnBAcH48mTJwpVSvlh5Eg5EDgtDXj3XeD2baUrIiIifaZ4mElMTETPnj3x888/o0SJEurtQgjMmTMHn3/+OTp37gxvb28sX74cycnJWLVqlYIV09tSqYAlSwBvbyAuDnjvPSA1VemqiIhIXykeZgYPHoy2bduiefPmGttjY2MRFxeHFi1aqLeZmpoiMDAQBw4cyHV/KSkpSEhI0LhQ4WNpCWzaBNjaAgcOAMOHK10RERHpK0XDzJo1a3D8+HGEhoZmuy8uLg4A4OjoqLHd0dFRfV9OQkNDYWtrq764ubnlb9GUbypUAFaufDF1e9kypSsiIiJ9pFiYuXHjBoYNG4YVK1bAzMws13YqlUrjthAi27asxo8fj/j4ePXlxo0b+VYz5b+2bYHJk+X1//0POHZM0XKIiEgPKRZmjh07hrt376J27dowMjKCkZERIiMj8f3338PIyEjdI/NyL8zdu3ez9dZkZWpqChsbG40LFW4TJgDt2gEpKXJBvXv3lK6IiIj0iWJhplmzZjh9+jSio6PVFz8/P/Ts2RPR0dEoV64cnJycEBYWpn5MamoqIiMjERAQoFTZpAMGBsBvvwEVKwLXrwPvvy9nOhEREeWF0ds8OCUlBaampm/0WGtra3h7e2tss7S0hL29vXp7SEgIpk6diooVK6JixYqYOnUqLCws0KNHj7cpmwohW1s5ILhePWD3bmD8eODbb5WuioiI9IFWPTM7d+5Ev379UL58eRgbG8PCwgLW1tYIDAzEN998g9v5vGDImDFjEBISgkGDBsHPzw+3bt3Crl27YG1tna/PQ4VDtWovBgHPnAn8/rui5RARkZ5QCfH6M+Rs3rwZY8eORXx8PNq0aYO6deuiTJkyMDc3x8OHD3HmzBns3bsXUVFR6NevH7766iuULl26IOp/rYSEBNja2iI+Pp7jZ/TEuHFylWBLS+DgQbkeDRERFS/afH/nKczUrVsXEydORNu2bWFgkHtnzq1btzB37lw4Ojpi5MiR2leuAwwz+ictDWjdGvj7bzl9+8gRwM5O6aqIiKgg5XuY0WcMM/rpwQOgdm3g2jU5fXvLFjlQmIiIigdtvr/f+ushPT0d0dHRePTo0dvuikjN3h7YuBEwMwP++guYMkXpioiIqLDSOsyEhIRgyZIlAGSQCQwMRK1ateDm5oaIiIj8ro+KsVq1gJ9+kte//BLYulXZeoiIqHDSOsysX78e1atXBwBs3boVsbGx+PfffxESEoLPP/883wuk4q1PH2DIEHm9Vy/gwgVl6yEiosJH6zBz//59ODk5AQC2bduG9957D5UqVcKAAQNw+vTpfC+QaNYsoGFDICEB6NQJSExUuiIiIipMtA4zjo6OOHv2LNLT07Fjxw712a6Tk5NhaGiY7wUSGRsD69YBzs7A2bPABx8ARXvYOhERaUPrMPPBBx+ga9eu8Pb2hkqlQnBwMADg0KFDqFKlSr4XSAQATk7Ahg0y2Kxfz9WBiYjoBa3DzOTJk7F48WJ8/PHH2L9/v/p0BoaGhhg3bly+F0iUyd8f+P57eX38eLkODREREdeZIb0iBPDhh8Avv8jp20ePAh4eSldFRET5Ld/XmVmzZk2en/zGjRvYv39/ntsTaUOlAubPB/z85MJ6nTsDT58qXRURESkpT2FmwYIFqFKlCqZPn45z585luz8+Ph7btm1Djx49ULt2bTx8+DDfCyXKZGYmx8+UKgWcOAH8738cEExEVJzlKcxERkZi5syZ2L17N7y9vWFjY4OKFSvCx8cHrq6usLe3x4ABA+Dh4YEzZ86gXbt2uq6birmyZeVZtQ0NgV9/BX78UemKiIhIKVqPmXnw4AH27duHq1ev4unTpyhVqhRq1qyJmjVrvvIklErhmJmibdYsYORIwMgICA+X69EQEZH+44kms2CYKdqEAHr0ANaskdO3jx0DXFyUroqIiN5WgZ5okkhJKhWweDHg4wPExQHvvgukpipdFRERFSSGGdJ7lpbApk2AnR0QFQWEhChdERERFSSGGSoSypcHVq6UPTULFgBLlypdERERFRSGGSoy2rQBvvxSXv/kE7mgHhERFX1vHGZSU1Nx/vx5pKWl5Wc9RG/l88+B9u2BlBS5oN69e0pXREREuqZ1mElOTsaAAQNgYWGBatWq4fr16wCAoUOHYtq0afleIJE2DAzkujOVKgE3bgDvvw8wbxMRFW1ah5nx48fj5MmTiIiIgJmZmXp78+bNsXbt2nwtjuhN2NrKAcFWVsDu3QDPf0pEVLRpHWY2b96MefPmoWHDhlCpVOrtXl5euHz5cr4WR/SmvLyAZcvk9e++A5iziYiKLq3DzL179+Dg4JBte1JSkka4IVJaly4vemX69wdOn1a2HiIi0g2tw0ydOnXw119/qW9nBpiff/4Z/v7++VcZUT74+msgOBhITgY6dQIePVK6IiIiym9G2j4gNDQUrVq1wtmzZ5GWloa5c+ciJiYGUVFRiIyM1EWNRG/M0BBYvRrw8wMuXwZ69QK2bpUDhYmIqGjQ+r/0gIAA7N+/H8nJyShfvjx27doFR0dHREVFoXbt2rqokeit2NsDGzcCZmbAtm0v1qIhIqKigSeapGJjxQqgd295feNGoEQJ4M4dwNkZaNRI9uIQEVHhoM33t9aHmTLdvXsXd+/eRUZGhsZ2X1/fN90lkU716gUcPgz88IMcHJw1xru6AnPnyoX2iIhIv2gdZo4dO4a+ffvi3LlzeLlTR6VSIT09Pd+KI8pvDRvKMPNyf+StW/KM2+vXM9AQEekbrQ8z+fr6okKFChg7diwcHR2zTcd2d3fP1wLfFg8zUab0dMDDA7h5M+f7VSrZQxMby0NORERK0+lhptjYWGzcuBEVKlR44wKJlLB3b+5BBpC9NTduyHZBQQVWFhERvSWtZzM1a9YMJ0+e1EUtRDp1507+tiMiosJB656ZxYsXo2/fvjhz5gy8vb1hbGyscX/79u3zrTii/OTsnL/tiIiocNA6zBw4cAD79u3D9u3bs93HAcBUmDVqJMfE3LqVfQBwJktLoEGDgq2LiIjejtaHmYYOHYrevXvjzp07yMjI0LgwyFBhZmgop18DcrBvTpKSgI8/loOFiYhIP2gdZh48eIDhw4fD0dFRF/UQ6VTnznL6dZkymtvd3IARI2TgWbYM+OADBhoiIn2h9WGmzp07Izw8HOXLl9dFPUQ617kz0KGDnLX08grA9esD3bsDv/0mw8zy5YDRGy8tSUREBUHr/6YrVaqE8ePHY9++ffDx8ck2AHjo0KH5VhyRrhga5jz9+r335H3dugGrVslAs2IFAw0RUWGm9aJ5np6eue9MpcKVK1feuqj8xEXz6E388YcMNs+fy5WBV60CXsrtRESkQzpfNI+oqOvQQZ6MsksXOcYmPR1YswYwMVG6MiIiepnWA4CJiot33gE2bQJMTeW/770HpKQoXRUREb0sTz0zI0aMwFdffQVLS0uMGDHilW1nzZqVL4URFQZt2shDTh07Alu2vOipMTNTujIiIsqUpzBz4sQJPH/+XH2dqDhp2RLYuhVo1w746y+gUyfZU8NAQ0RUOGg9AFjfcAAw5Zfdu2WgSU4GWrQANm8GzM2VroqIqGjS5vtb6zEz/fv3x5MnT7JtT0pKQv/+/bXdHZHeaNoU2LZNnvJg164XwYaIiJSldZhZvnw5nj59mm3706dP8euvv+ZLUUSFVWAgsH07YGUF/POPHCSclKR0VURExVuew0xCQgLi4+MhhMCTJ0+QkJCgvjx69Ajbtm2Dg4ODLmslKhQaNQJ27gSsrYHwcDlIODFR6aqIiIqvPK8zY2dnB5VKBZVKhUqVKmW7X6VS4csvv8zX4ogKq4AAeaipZUtgzx6gVSvZY2NtrXRlRETFT57DTHh4OIQQaNq0KTZs2ICSJUuq7zMxMYG7uztcXFx0UiRRYVS/PvD333Iw8P79Mtjs2AFwnDkRUcHSejbTtWvXULZsWahUKl3VlK84m4l07dgxIDgYePQIqFdPHoKytVW6KiIi/abT2Uzu7u56E2SICkLt2nIwcMmSwKFDL4INEREVDEVPZ7BgwQL4+vrCxsYGNjY28Pf3x/bt29X3CyEwefJkuLi4wNzcHEFBQYiJiVGwYqKc1awp16GxtweOHAGaNwcePlS6KiKi4kHRMOPq6opp06bh6NGjOHr0KJo2bYoOHTqoA8uMGTMwa9YszJs3D0eOHIGTkxOCg4NzXOeGSGnVq8vZTaVLA8ePA82aAQ8eKF0VEVHRV+hWAC5ZsiS+/fZb9O/fHy4uLggJCcHYsWMBACkpKXB0dMT06dMxcODAPO2PY2aooJ09KxfY++8/wNdXDhIuXVrpqoiI9ItOx8wAQFpaGv7++2/89NNP6l6S27dvI/EtFttIT0/HmjVrkJSUBH9/f8TGxiIuLg4tWrRQtzE1NUVgYCAOHDiQ635SUlI01sBJSEh445qI3oSXFxARATg5AadOyWBz967SVRERFV1ah5lr167Bx8cHHTp0wODBg3Hv3j0A8pDQqFGjtC7g9OnTsLKygqmpKf73v/9h06ZN8PLyQlxcHADA0dFRo72jo6P6vpyEhobC1tZWfXFzc9O6JqK3VaWKDDQuLsCZM0CTJsArfm2JiOgtaB1mhg0bBj8/Pzx69AjmWc6y16lTJ/zzzz9aF1C5cmVER0fj4MGD+OSTT9C3b1+cPXtWff/LM6eEEK+cTTV+/HjEx8erLzdu3NC6JqL8ULmyDDRlyshDT0FBwO3bSldFRFT05HnRvEz79u3D/v37YWJiorHd3d0dt27d0roAExMTVKhQAQDg5+eHI0eOYO7cuepxMnFxcXB2dla3v3v3brbemqxMTU1hamqqdR1EulCxIhAZKXtmzp+XgSY8XAYcIiLKH1r3zGRkZCA9PT3b9ps3b8I6H9ZyF0IgJSUFnp6ecHJyQlhYmPq+1NRUREZGIiAg4K2fh6iglC8vA427O3DxojxZJTsMiYjyj9ZhJjg4GHPmzFHfVqlUSExMxKRJk9CmTRut9vXZZ59h7969uHr1Kk6fPo3PP/8cERER6NmzJ1QqFUJCQjB16lRs2rQJZ86cQb9+/WBhYYEePXpoWzaRojw9ZaDx9AQuX5Y9NNevK10VEVHRoPVhptmzZ6NJkybw8vLCs2fP0KNHD1y8eBGlSpXC6tWrtdrXf//9h969e+POnTuwtbWFr68vduzYgeDgYADAmDFj8PTpUwwaNAiPHj1CvXr1sGvXrnzpASIqaO7ucgxN06Yy0AQGykNOHh5KV0ZEpN/eaJ2Zp0+fYvXq1Th+/DgyMjJQq1Yt9OzZU2NAcGHBdWaosLl5UwaaixeBsmVloClXTumqiIgKF22+vwvdonn5jWGGCqPbt+Wg4AsXADc3eSqE/x8HT0RE0O77W+vDTFu2bMlxu0qlgpmZGSpUqABPT09td0tUrLi4yENOzZoB587JMTS7dwOVKildGRGR/tG6Z8bAwAAqlQovPyxzm0qlQsOGDbF582aUKFEiX4t9E+yZocLsv/9koImJAZydZaCpUkXpqoiIlKfT0xmEhYWhTp06CAsLUy9MFxYWhrp16+LPP//Enj178ODBgzdaDZiouHF0lAHGxwe4c0f20GRZM5KIiPJA654Zb29vLFq0KNtaL/v378fHH3+MmJgY/P333+jfvz+uF4K5p+yZIX1w/z7QvDlw8iTg4AD88w/g7a10VUREytFpz8zly5dz3KmNjQ2uXLkCAKhYsSLu37+v7a6Jiq1SpWSAqVlTnpSySRN5kkoiIno9rcNM7dq1MXr0aPUJJgHg3r17GDNmDOrUqQMAuHjxIlxdXfOvSqJiwN5eBho/P9lT07QpEB2tdFVERIWf1mFmyZIliI2NhaurKypUqICKFSvC1dUVV69exeLFiwEAiYmJmDhxYr4XS1TUlSgBhIUBdesCDx7IQHP8uNJVEREVbm+0zowQAjt37sSFCxcghECVKlUQHBwMAwOts5HOccwM6aP4eKBVK+DgQcDOTgYcPz+lqyIiKjhcNC8LhhnSVwkJQOvWwIEDgK0tsHMnUK+e0lURERUMnS6aBwBJSUmIjIzE9evXkZqaqnHf0KFD32SXRPQSGxtgxw6gbVtg716gRQt5299f6cqIiAoXrXtmTpw4gTZt2iA5ORlJSUkoWbIk7t+/DwsLCzg4OKhnNBUW7JkhfZeUBLzzjlwx2MoK2L4daNhQ6aqIiHRLp1Ozhw8fjnbt2uHhw4cwNzfHwYMHce3aNdSuXRszZ85846KJKGeWlsBff8nBwImJcizNnj1KV0VEVHhoHWaio6MxcuRIGBoawtDQECkpKXBzc8OMGTPw2Wef6aJGomLPwgLYuhUIDpY9Na1by54aIiJ6gzBjbGwMlUoFAHB0dFSv8mtra1soVvwlKqosLIA//gBatgSSk4E2beS6NERExZ3WYaZmzZo4evQoAKBJkyb44osvsHLlSoSEhMDHxyffCySiF8zNgc2bZZB5+lSOpdm1S+mqiIiUpXWYmTp1KpydnQEAX331Fezt7fHJJ5/g7t27WLRoUb4XSESazMyAjRuBdu2AZ8+A9u3lLCciouJKq9lMQghcv34dDg4OMDc312Vd+YazmaioSk0FunWTPTUmJjLgtG2rdFVERPlDZ7OZhBCoWLEibt68+VYFEtHbMzEBfv8d6NJFBptOneQgYSKi4karMGNgYICKFSviwYMHuqqHiLRgbAysXg289x7w/LkMNps3K10VEVHB0nrMzIwZMzB69GicOXNGF/UQkZaMjYFVq4D335eB5r33gA0blK6KiKjgaL0CcIkSJZCcnIy0tDSYmJhkGzvz8OHDfC3wbXHMDBUXaWnABx8AK1YAhoYy4HTtqnRVRERvRqfnZpozZ86b1kVEOmRkBCxbJoPM8uVA9+5Aerr8l4ioKNM6zPTt21cXdRBRPjA0BJYskf/+8gvQq5cMNL16KV0ZEZHuaD1mBgAuX76MCRMmoHv37rh79y4AYMeOHYiJicnX4ohIe4aGwM8/Ax99BGRkAH36yJ4aIqKiSuswExkZCR8fHxw6dAgbN25EYmIiAODUqVOYNGlSvhdIRNozMAAWLgT+9z9ACDmW5pdflK6KiEg3tA4z48aNw9dff42wsDCYmJiotzdp0gRRUVH5WhwRvTkDA+DHH4EhQ2SgGTAA4CLdRFQUaR1mTp8+jU6dOmXbXrp0aa4/Q1TIqFTA998Dw4bJ2wMHAgsWKFsTEVF+0zrM2NnZ4c6dO9m2nzhxAmXKlMmXoogo/6hUwOzZwIgR8vagQcC8ecrWRESUn7QOMz169MDYsWMRFxcHlUqFjIwM7N+/H6NGjUKfPn10USMRvSWVCpg5ExgzRt7+9FNg7lxlayIiyi9ah5lvvvkGZcuWRZkyZZCYmAgvLy80btwYAQEBmDBhgi5qJKJ8oFIB06YB48fL2yEhwKxZipZERJQvtF4BONPly5dx4sQJZGRkoGbNmqhYsWJ+15YvuAIwkSYhgEmTgK++krenT3/RY0NEVFjodAXgyMhIBAYGonz58ihfvvwbF0lEylCpgClT5Ho0kycDY8fKUyF89pnSlRERvRmtDzMFBwejbNmyGDduHE82SaTHsvbOfP75i+tERPpG6zBz+/ZtjBkzBnv37oWvry98fX0xY8YM3Lx5Uxf1EZEOTZgAhIbK6198IXtq3uzAMxGRct54zAwAxMbGYtWqVVi9ejX+/fdfNG7cGLt3787P+t4ax8wQvd63374YNzNhgjwMpVIpWxMRFW/afH+/VZgBgPT0dGzfvh0TJ07EqVOnkJ6e/ja7y3cMM0R5k3UtmnHjgKlTGWiISDnafH+/0YkmAWD//v0YNGgQnJ2d0aNHD1SrVg1//vnnm+6OiBQ2fPiLtWemTZM9NTzkRET6QOvZTJ999hlWr16N27dvo3nz5pgzZw46duwICwsLXdRHRAVo6FA5y2nIELnIXno68N137KEhosJN6zATERGBUaNGoVu3bihVqpQuaiIiBQ0eDBgZyTNuz54tA82cOQw0RFR4aR1mDhw4oIs6iKgQGThQ9tB8/LE8UWVaGvDDD/JM3EREhY3WYSbT2bNncf36daSmpmpsb9++/VsXRUTK+/BDGWgGDAB+/FH20Pz4IwMNERU+WoeZK1euoFOnTjh9+jRUKhUyJ0Op/r8PurDNZiKiN/fBBzLQ9OsH/PSTDDQ//cRAQ0SFi9b/JQ0bNgyenp7477//YGFhgZiYGOzZswd+fn6IiIjQQYlEpKQ+fYDffpMBZvFi2VPDv1mIqDDRumcmKioKu3fvRunSpWFgYAADAwM0bNgQoaGhGDp0KE6cOKGLOolIQT17yh6aXr2AZctkmFm6VG4jIlKa1j0z6enpsLKyAgCUKlUKt2/fBgC4u7vj/Pnz+VsdERUa778PrF4tA8xvv8kem7Q0pasiInqDnhlvb2+cOnUK5cqVQ7169TBjxgyYmJhg0aJFKFeunC5qJKJC4r33ZJjp1g1YtQrIyJDBxuiNpxIQEb09rXtmJkyYgIyMDADA119/jWvXrqFRo0bYtm0bvv/++3wvkIgKl86dgfXrAWNjYM0aoEcP4PlzpasiouLsrc/NBAAPHz5EiRIl1DOaChOem4lIN/78E+jSBUhNBTp1ksHGxETpqoioqCiQczNlVbJkyUIZZIhId955B9i0CTA1lf927SqDDRFRQeNqEUT0xtq0Af74QwaaP/6QPTUpKUpXRUTFjaJhJjQ0FHXq1IG1tTUcHBzQsWPHbDOihBCYPHkyXFxcYG5ujqCgIMTExChUMRG9rGVLecjJzEz+26kT8OyZ0lURUXGiaJiJjIzE4MGDcfDgQYSFhSEtLQ0tWrRAUlKSus2MGTMwa9YszJs3D0eOHIGTkxOCg4Px5MkTBSsnoqyaNwf++gswNwe2bwc6dgSePlW6KiIqLvJlAHB+uXfvHhwcHBAZGYnGjRtDCAEXFxeEhIRg7NixAICUlBQ4Ojpi+vTpGDhw4Gv3yQHARAUnMhJo2xZISpIB548/AAsLpasiIn1U4AOA80t8fDwAOaAYAGJjYxEXF4cWLVqo25iamiIwMJBn7yYqhAIDZc+MlRXw999ykHCWjlYiIp0oNGFGCIERI0agYcOG8Pb2BgDExcUBABwdHTXaOjo6qu97WUpKChISEjQuRFRwGjUCduwArK2B8HDZU5OYqHRVRFSUFZowM2TIEJw6dQqrV6/Odt/L076FELlOBQ8NDYWtra364ubmppN6iSh3DRoAu3YBNjby0FPr1gCHuRGRrhSKMPPpp59iy5YtCA8Ph6urq3q7k5MTAGTrhbl792623ppM48ePR3x8vPpy48YN3RVORLmqXx8ICwNsbYF9+4BWrQB2lBKRLigaZoQQGDJkCDZu3Ijdu3fD09NT435PT084OTkhLCxMvS01NRWRkZEICAjIcZ+mpqawsbHRuBCRMurWBf75ByhRAjhwAGjRAvj/oXFERPlG0TAzePBgrFixAqtWrYK1tTXi4uIQFxeHp/8/p1OlUiEkJARTp07Fpk2bcObMGfTr1w8WFhbo0aOHkqUTUR7Vri0DTcmSwKFDQHAw8Pix0lURUVGi6NTs3Ma9LF26FP369QMge2++/PJL/PTTT3j06BHq1auH+fPnqwcJvw6nZhMVDidPAs2aAQ8eyICza5cMOEREOdHm+7tQrTOjCwwzRIXH6dMy0Ny7B9SoIadv29srXRURFUZ6u84MERVtPj5yuraDAxAdDTRtKoMNEdHbYJghogJVrRoQEQE4OQGnTslAc/eu0lURkT5jmCGiAle1qgw0zs7AmTNAkybAf/8pXRUR6SuGGS3t2QO0awe4uAAqFbB586vbDxwo282Zo7k9KEhuz3p5/30dFU1UCFWuLBfUK1MGOHtWfibu3FG6KiLSRwwzWkpKAqpXB+bNe33bzZvlVFQXl5zv/+gj+Z935uWnn/K11BwJAaSl6f55iPKiYkUZaNzcgH//lYHm1i2lqyIifcMwo6XWrYGvvwY6d351u1u3gCFDgJUrAWPjnNtYWMhxA5kXW9sX9129Kntrfv9dnuvG3ByoUwe4cAE4cgTw85Mn82vV6tUDKCMi5H527pSPMTUF9u4FUlKAoUPlQEwzM6BhQ7nfTLVrA9999+J2x46AkdGLFVzj4uR+z5+Xt3/8UX4xmZkBjo7Au++++v0hylS+vAw07u7y9zsoCLh5U+mqiEifMMzoQEYG0Ls3MHq0HOyYm5UrgVKlZJtRo3I+d82kScCECcDx4zJMdO8OjBkDzJ0rQ8nly8AXX7y+pjFjgNBQ4Nw5wNdX3t6wAVi+XO67QgWgZUvg4UPZPihIBiFA9ubs3StXcd23T24LD5cBrHJl4OhRGYymTJHhZscOoHFjbd4xKu48PeXvm6cncOmSPPv29etKV0VE+oJhRgemT5fBY+jQ3Nv07AmsXi3/A584UQaLnHp7Ro2SIaNqVWDYMBk8Jk6UJ/KrWRMYMEAGi9eZMkWuvFq+vOw9WbAA+PZb2dPk5QX8/LPs/VmyRLYPCpIBJiNDzjgxNJQBLTPgRETILxxAfulYWgLvvCP/uq5Z89WvnSgnHh7y96pcOeDKFfn7dfWqwkURkV5gmMlnx47JXpNly+RhmNx89BHQvDng7S0H/q5fLxcQO35cs52v74vrmefW9PHR3JaXaa1+fi+uX74MPH8uA1EmY2N5Hp1z5+Ttxo1lT9GJE/IQQGCgnHESGSnvzxpmgoNliClXTgaelSuB5OTX10T0srJl5e9YhQoyyAQGymBDRPQqDDP5bO9eGS7KlpW9M0ZGwLVrwMiR8i/P3NSqJQPFxYua27OOt8kMRy9vy8h4fV2Wli+uZ675/HLYEuLFNltbuUJrRIT8cgkKkmN3oqNljZljGwDA2lqGsNWr5VTbL76Qg6R5/h16E66u8neuUiXZ6xcUJAM4EVFuGGbyWe/e8rBMdPSLi4uLHD+zc2fuj4uJkb0lzs66r7FCBcDE5MX4F0A+99Gj8nBWpqAgeQhrzx553c5OHpL6+ms5cDhrWyMj2dM0Y4Z8/VevArt36/61UNHk4iKDdJUqwI0bsofm5aBPRJTJSOkC9E1iohygmCk2VgaWkiVlb4y9ffZzzRgbvxgsC8i/MleuBNq0kQOAz56VPTc1a2oe+tEVS0vgk09kwMqse8YMeWhowIAX7YKC5CGzkiVliMnc9sMPmuN7/vxTHgpo3FgOEt62TfYWZb5eojfh7CwDTdOm8jMSGCjDNX+viOhl7JnR0tGjMnTUrClvjxghr+dlRlEmExPgn3/kwN7KleVg2RYt5JgZQ0Pd1P2yadOALl1kT1KtWjKg7dwpw0imzBlJgYEvDj8FBgLp6S/GywCyx2bjRvmlU7UqsHChPOT0qplcRHnh6CgDjI+PXIspMPDFuC4iokw8azYRFXr378vDmCdPykOcu3fLQ1B798qQ4+wsx3QV1B8DRKR72nx/8zATERV6pUrJ3szgYDnDzt9fLjqZ9XxOrq7ysOjrFrQkoqKHh5mISC/Y28tDseXKyWUDXj4x5a1bcuXpjRuVqY+IlMMwQ0R6w9YWePYs5/syD5iHhMhxXURUfDDMEJHe2LsXuH079/uFkFO59+4tuJqISHkMM0SkN+7cyVu7VwUeIip6OACYiPRGXheVnDxZLifw7ru5n7WeiIoO9swQkd5o1EjOWnrVec8AuVpwjx5ytetZs4CEhIKpj4iUwTBDRHrD0FBOvwayBxqVSl6WLgW++kquR3P9ulxd280NGDMGuHmz4GsmIt1jmCEivdK5szzLfJkymttdXeX2fv2ACRPkCV5//lkurpeQAHz7LeDpKVe9jo5WonIi0hWuAExEeik9PW8rAGdkANu3AzNnynM9ZWrWDBg1Sp5W5HWHrYio4Gnz/c0wQ0TFxrFjwHffAb///mItGm9veY61Hj0AU1Nl6yOiF7T5/uZhJiIqNmrXBlatkmeuHzECsLICzpwB+vcHPDyA0FDg4UOlqyQibTHMEFGx4+4ue2hu3ABmzJDjb+LigM8+k4OFhw4FrlxRukoiyiuGGSIqtuzsgNGjZXD57TegenUgORn44QegYkXgvfeAQ4eUrpKIXodhhoiKPRMToFcveUbuv/8GWrWSA4fXrwfq1wcaNgQ2b+Y5n4gKK4YZIqL/p1LJWU7btwOnTwMffCBXEN6/H+jUCahaFViwQPbeEFHhwTBDRJQDb2/gl1+Aq1eB8eOBEiXkysKDBgFlywKTJgF37ypdJREBDDNERK/k4gJMnSpXE/7+e7nw3oMHwJQpMtR8/DHw779KV0lUvDHMEBHlgZUV8Omnsndm3Tqgbl0gJUWuMly1KtCuHRAZCRTtlbuICieGGSIiLRgayrNxHzwoVyDu2FGOtfnzTyAoSIactWuBtDSlKyUqPhhmiIjegEolZzlt2iQPM/3vf4CZGXD0KPD++/KM3XPmAE+eKF0pUdHHMENE9JYqVZKznK5fB778EihdWp7ocvhwuQjf2LHArVtKV0lUdDHMEBHlk9KlgS++kEFm0SKgcmUgPl6uMuzhAfTpA5w8qXSVREUPwwwRUT4zNwc++gg4exbYuhUIDJRjaH77DahRA2jRAti5k4OFifILwwwRkY4YGADvvANERABHjsixNIaGQFiYXGW4enVg2TI5K4qI3hzDDBFRAfDzA1avBi5dAkJC5FTvzFWGPT2BadOAR4+UrpJIPzHMEBEVIA8PYPZsecbu6dPlonx37shVht3cgGHDgNhYpask0i8MM0RECrCzA8aMkcFl+XLA1xdISpKrDFeoAHTrBhw+rHSVRPqBYYaISEEmJnKWU3Q0sGsX0LKlPGP3778D9eoBjRsDW7bIbUSUM4YZIqJCQKUCgoOBHTvk9O2+feUZu/fuBTp0kKdM+Okn4OlTpSslKnwYZoiIChlfXznL6epVYNw4eUjqwgW5ynDZssDkycC9e8rWSFSYMMwQERVSLi5AaKgcLDx3rhw8fP++XGW4bFkZbs6fV7pKIuUxzBARFXJWVsDQofKM3WvXAnXqAM+eycNOVarIw1B79nARPiq+GGaIiPSEkRHQtStw6JAML+3by7E2W7bIVYbr1ZMDh3nGbipuGGaIiPSMSgU0agT88Qdw7hwwcKA8Y/eRI3JKd8WK8rAUz9hNxQXDDBGRHqtcGVi4UJ6xe/JkoFQpOXA4JESOqxk3jmfspqKPYYaIqAgoXRqYNEmGmoULgUqVgMeP5SrDnp5Av37y9AlERRHDDBFREWJuLg87nTsnD0M1bgw8f/5ileGWLeWJLjlYmIoSRcPMnj170K5dO7i4uEClUmHz5s0a9wshMHnyZLi4uMDc3BxBQUGIiYlRplgiIj1iYCAHCEdGygHDXbvKbbt2AS1aADVqAL/+CqSmKl0p0dtTNMwkJSWhevXqmDdvXo73z5gxA7NmzcK8efNw5MgRODk5ITg4GE84qo2IKM/q1pVTui9dkieytLQETp2Sqwx7espDUY8fK10l0ZtTCVE4OhtVKhU2bdqEjh07ApC9Mi4uLggJCcHYsWMBACkpKXB0dMT06dMxcODAPO03ISEBtra2iI+Ph42Nja7KJyLSG48eAYsWyRlPd+7IbVZWwIcfyrDj4aFoeUQAtPv+LrRjZmJjYxEXF4cWLVqot5mamiIwMBAHDhzI9XEpKSlISEjQuBAR0QslSgBjx8pZT8uWAT4+QGIiMGcOUL488P77wNGjChdJpIVCG2bi4uIAAI6OjhrbHR0d1fflJDQ0FLa2tuqLm5ubTuskItJXJibyUNPJk8DOnfJElxkZL1YZDgwEtm7lGbup8Cu0YSaTSqXSuC2EyLYtq/HjxyM+Pl59uXHjhq5LJCLSayqVHBS8axcQHQ306SNXG85cZdjLSx6W4hm7qbAqtGHGyckJALL1wty9ezdbb01WpqamsLGx0bgQEVHeVK8up3HHxgJjxgC2tvJklgMHAu7uwJQp8mSXRIVJoQ0znp6ecHJyQlhYmHpbamoqIiMjERAQoGBlRERFn6urnOV04wYwe7YMMvfuyYX53NyATz4BLlxQukoiSdEwk5iYiOjoaERHRwOQg36jo6Nx/fp1qFQqhISEYOrUqdi0aRPOnDmDfv36wcLCAj169FCybCKiYsPaWp4a4dIlYM0awM9PnrF74UJ5xu6OHYF9+7gIHylL0anZERERaNKkSbbtffv2xbJlyyCEwJdffomffvoJjx49Qr169TB//nx4e3vn+Tk4NZuIKP8IAezdC8ycKQcHZ6pbFxg1CujUSY63IXpb2nx/F5p1ZnSFYYaISDf+/Vceglq+HEhJkds8PWVPTv/+cu0aojdVJNaZISKiwq1KFeCnn+TJLb/4ArC3lwOHhw2T42o+++zFonxEusQwQ0REb8XBAfjySxlqFiwAKlaUp0cIDZUDhz/4ADhzJvvj0tOBiAhg9Wr5b3p6ARdORQbDDBER5QsLC+B//5OHnzZvBho2lGfszlxluFUr4O+/5bibjRvlaROaNAF69JD/enjI7UTa4pgZIiLSmUOHgO++AzZseLGSsLs7cO1a9raZ66GuXw907lxwNVLhxDEzRERUKNSrB/z+O3DxIvDpp7L3JqcgA7yY3h0SwkNOpB2GGSIi0rly5YDvv5fjY15FCLlQ3+7dBVMXFQ1cDYCIiApMUlLe2rVtK3t1/P1fXP7/LDdE2TDMEBFRgXF2zlu758/lysL79r3Y5umpGW58fQFjY93USfqFA4CJiKjApKfLWUu3buV8CgSVSp4XascO4PBhICpKXs6cyd7ewgKoU0cz4JQuXSAvgwoAVwDOgmGGiKhw2bgRePddeT3rN9CrZjPFx2uGm4MH5Vo2LytfHggIeBFuvL15egV9xTCTBcMMEVHhs3GjXCn45s0X29zcgDlz8jYtOyMDOH8eOHDgRcA5ezZ7O0tLed6ozIBTv75cqZgKP4aZLBhmiIgKp/R0edLKO3fkWJpGjQBDwzff3+PHcl2bzIBz6BCQkJC9XaVKL3puAgIAL6+3e17SDYaZLBhmiIiKp/R04Nw5GWwyA87589nbWVu/mDkVECCvlyhR8PWSJoaZLBhmiIgo08OHcrxNZsA5fBhITMzermpVzd6bKlUAA67MVqAYZrJgmCEiotykp8uZUpnjbg4cAC5dyt7Ozk5z3Zt69QBb2wIvt1hhmMmCYYaIiLRx796L3puoKNl7k5ys2UalAqpV05wWXrnyixlZ9PYYZrJgmCEioreRlgacOvUi3ERFAVeuZG9XooRmuKlbV47HoTfDMJMFwwwREeW3//7TDDdHjgDPnmm2MTCQ69xkXfemQgX23uQVw0wWDDNERKRrqanAyZOaASens4OXKiXXuskcWFynjlwLh7JjmMmCYYaIiJRw+7ZmuDl2DEhJ0WxjaCjPMZV15pSnJ3tvAIYZDQwzRERUGKSkANHRmuveZF0BOZODg+bYGz8/eR6q4oZhJguGGSIiKqxu3tScFn78uDxjeFZGRkCNGpoBx9296PfeMMxkwTBDRET64tkzGWiyBpw7d7K3c3LSHFhcuzZgZlbw9eoSw0wWDDNERKSvhACuX9cMN9HRcrp4VsbGQM2amgHHzU2RkvMNw0wWDDNERFSUJCfLwcRZBxf/91/2dmXKvBhU7O8vw46pacHX+6YYZrJgmCEioqJMCCA2VjPcnDwpT9WQlYmJPByVdeaUi4syNecFw0wWDDNERFTcJCXJhfyyBpz797O3K1tWc2BxjRoy9ORFejqwd68c0+PsDDRqJKea5xeGmSwYZoiIqLgTArh8+cWU8Kgo4PRpICNDs52ZmZwKnjXgODll39/GjcCwYZpTy11dgblzgc6d86dmhpksGGaIiIiye/JE9t5kBpyDB4GHD7O38/DQHFh8+TLw/vsyIGWVOVV8/fr8CTQMM1kwzBAREb2eEMCFC5qL+sXEZA8tr6JSyR6a2Ni3P+TEMJMFwwwREdGbiY8HDh9+EXD27ZPjcV4nPBwICnq759bm+9vo7Z6KiIiIiipbWyA4WF4AYOVKoFev1z8up4X+dMmgYJ+OiIiI9FWZMnlr5+ys2zpexjBDREREedKokRwTk9t5oVQqufJwo0YFWxfDDBEREeWJoaGcfg1kDzSZt+fMyd/1ZvKCYYaIiIjyrHNnOf365UNOrq75Ny1bWxwATERERFrp3Bno0EG3KwBrg2GGiIiItGZo+PbTr/MLDzMRERGRXmOYISIiIr3GMENERER6jWGGiIiI9BrDDBEREek1hhkiIiLSawwzREREpNcYZoiIiEivMcwQERGRXmOYISIiIr3GMENERER6rcifm0kIAQBISEhQuBIiIiLKq8zv7czv8Vcp8mHmyZMnAAA3NzeFKyEiIiJtPXnyBLa2tq9soxJ5iTx6LCMjA7dv34a1tTVUKlW+7jshIQFubm64ceMGbGxs8nXfpHv8+ek//gz1H3+G+k2XPz8hBJ48eQIXFxcYGLx6VEyR75kxMDCAq6urTp/DxsaGH0I9xp+f/uPPUP/xZ6jfdPXze12PTCYOACYiIiK9xjBDREREeo1h5i2Ymppi0qRJMDU1VboUegP8+ek//gz1H3+G+q2w/PyK/ABgIiIiKtrYM0NERER6jWGGiIiI9BrDDBEREek1hhkiIiLSawwzr7Fnzx60a9cOLi4uUKlU2Lx5c7Y2586dQ/v27WFrawtra2vUr18f169fL/hiKZsFCxbA19dXvaCTv78/tm/fDgB4/vw5xo4dCx8fH1haWsLFxQV9+vTB7du3Fa6aXnbr1i306tUL9vb2sLCwQI0aNXDs2LEc2w4cOBAqlQpz5swp2CJJ7VX/b+b1cxcXF4fevXvDyckJlpaWqFWrFtavX1/Ar6R4Cg0NRZ06dWBtbQ0HBwd07NgR58+f12jTr18/qFQqjUv9+vWz7SsqKgpNmzaFpaUl7OzsEBQUhKdPn+Z7zQwzr5GUlITq1atj3rx5Od5/+fJlNGzYEFWqVEFERAROnjyJiRMnwszMrIArpZy4urpi2rRpOHr0KI4ePYqmTZuiQ4cOiImJQXJyMo4fP46JEyfi+PHj2LhxIy5cuID27dsrXTZl8ejRIzRo0ADGxsbYvn07zp49i++++w52dnbZ2m7evBmHDh2Ci4tLwRdKaq/6fzOvn7vevXvj/Pnz2LJlC06fPo3OnTujW7duOHHiREG9jGIrMjISgwcPxsGDBxEWFoa0tDS0aNECSUlJGu1atWqFO3fuqC/btm3TuD8qKgqtWrVCixYtcPjwYRw5cgRDhgx57akJ3oigPAMgNm3apLGtW7duolevXsoURG+kRIkSYvHixTned/jwYQFAXLt2rYCrotyMHTtWNGzY8LXtbt68KcqUKSPOnDkj3N3dxezZs3VfHL1WTv9vviynz52lpaX49ddfNdqVLFky188u6c7du3cFABEZGane1rdvX9GhQ4dXPq5evXpiwoQJOq5OYs/MW8jIyMBff/2FSpUqoWXLlnBwcEC9evVyPBRFyktPT8eaNWuQlJQEf3//HNvEx8dDpVLl+Fc/KWPLli3w8/PDe++9BwcHB9SsWRM///yzRpuMjAz07t0bo0ePRrVq1RSqlN5UTp+7hg0bYu3atXj48CEyMjKwZs0apKSkICgoSLE6i6v4+HgAQMmSJTW2R0REwMHBAZUqVcJHH32Eu3fvqu+7e/cuDh06BAcHBwQEBMDR0RGBgYHYt2+fbooskMhUROClvzDu3LkjAAgLCwsxa9YsceLECREaGipUKpWIiIhQrlDScOrUKWFpaSkMDQ2Fra2t+Ouvv3Js9/TpU1G7dm3Rs2fPAq6QXsXU1FSYmpqK8ePHi+PHj4uFCxcKMzMzsXz5cnWbqVOniuDgYJGRkSGEEOyZKURe/n/zZbl97h4/fixatmwpAAgjIyNhY2Mjdu3apeNq6WUZGRmiXbt22XpH16xZI/78809x+vRpsWXLFlG9enVRrVo18ezZMyGEEFFRUQKAKFmypPjll1/E8ePHRUhIiDAxMREXLlzI9zoZZrTw8ofy1q1bAoDo3r27Rrt27dqJ999/v4Cro9ykpKSIixcviiNHjohx48aJUqVKiZiYGI02qampokOHDqJmzZoiPj5eoUopJ8bGxsLf319j26effirq168vhBDi6NGjwtHRUdy6dUt9P8NM4fGqMPOqz92QIUNE3bp1xd9//y2io6PF5MmTha2trTh16lQBVE2ZBg0aJNzd3cWNGzde2e727dvC2NhYbNiwQQghxP79+wUAMX78eI12Pj4+Yty4cfleJw8zvYVSpUrByMgIXl5eGturVq3K2UyFiImJCSpUqAA/Pz+EhoaievXqmDt3rvr+58+fo2vXroiNjUVYWJhOTmNPb87Z2fmVn7G9e/fi7t27KFu2LIyMjGBkZIRr165h5MiR8PDwUKBiyotXfe4uX76MefPm4ZdffkGzZs1QvXp1TJo0CX5+fpg/f76CVRcvn376KbZs2YLw8HC4urq+sq2zszPc3d1x8eJF9W0ABfb9aJTveyxGTExMUKdOnWxT1i5cuAB3d3eFqqLXEUIgJSUFwIv/UC9evIjw8HDY29srXB29rEGDBq/8jPXu3RvNmzfXuL9ly5bo3bs3PvjggwKrk/LudZ+75ORkAMg268XQ0BAZGRkFVmdxJYTAp59+ik2bNiEiIgKenp6vfcyDBw9w48YNdYjx8PCAi4tLjp/d1q1b53vNDDOvkZiYiEuXLqlvx8bGIjo6GiVLlkTZsmUxevRodOvWDY0bN0aTJk2wY8cObN26FREREcoVTWqfffYZWrduDTc3Nzx58gRr1qxBREQEduzYgbS0NLz77rs4fvw4/vzzT6SnpyMuLg6AHOhmYmKicPUEAMOHD0dAQACmTp2Krl274vDhw1i0aBEWLVoEALC3t8/2ZWhsbAwnJydUrlxZiZKLvVf9v+ni4vLaz12VKlVQoUIFDBw4EDNnzoS9vT02b96MsLAw/Pnnn0q9rGJj8ODBWLVqFf744w9YW1urfz62trYwNzdHYmIiJk+ejC5dusDZ2RlXr17FZ599hlKlSqFTp04AAJVKhdGjR2PSpEmoXr06atSogeXLl+Pff//VzXpB+X7gqogJDw8XALJd+vbtq26zZMkSUaFCBWFmZiaqV68uNm/erFzBpKF///7C3d1dmJiYiNKlS4tmzZqpBxHGxsbm+LMFIMLDw5UtnDRs3bpVeHt7C1NTU1GlShWxaNGiV7bnmBllver/zbx+7i5cuCA6d+4sHBwchIWFhfD19c02VZt0I7efz9KlS4UQQiQnJ4sWLVqI0qVLC2NjY1G2bFnRt29fcf369Wz7Cg0NFa6ursLCwkL4+/uLvXv36qRm1f8XTkRERKSXOACYiIiI9BrDDBEREek1hhkiIiLSawwzREREpNcYZoiIiEivMcwQERGRXmOYISIiIr3GMENEem/y5MmoUaOG0mUQkUIYZoiIiEivMcwQERGRXmOYIaICFRQUhKFDh2LMmDEoWbIknJycMHnyZPX9169fR4cOHWBlZQUbGxt07doV//33n8Y+pk2bBkdHR1hbW2PAgAF49uxZtudZunQpqlatCjMzM1SpUgU//vij+r7U1FQMGTIEzs7OMDMzg4eHB0JDQ3X2molItxhmiKjALV++HJaWljh06BBmzJiBKVOmICwsDEIIdOzYEQ8fPkRkZCTCwsJw+fJldOvWTf3Y33//HZMmTcI333yDo0ePwtnZWSOoAMDPP/+Mzz//HN988w3OnTuHqVOnYuLEiVi+fDkA4Pvvv8eWLVvw+++/4/z581ixYgU8PDwK8i0gonzEE00SUYEKCgpCeno69u7dq95Wt25dNG3aFM2aNUPr1q0RGxsLNzc3AMDZs2dRrVo1HD58GHXq1EFAQACqV6+OBQsWqB9fv359PHv2DNHR0QCAsmXLYvr06ejevbu6zddff41t27bhwIEDGDp0KGJiYvD3339DpVIVzAsnIp1hzwwRFThfX1+N287Ozrh79y7OnTsHNzc3dZABAC8vL9jZ2eHcuXMAgHPnzsHf31/j8Vlv37t3Dzdu3MCAAQNgZWWlvnz99de4fPkyAKBfv36Ijo5G5cqVMXToUOzatUtXL5WICoCR0gUQUfFjbGyscVulUiEjIwNCiBx7SnLbnpOMjAwA8lBTvXr1NO4zNDQEANSqVQuxsbHYvn07/v77b3Tt2hXNmzfH+vXr3+TlEJHC2DNDRIWGl5cXrl+/jhs3bqi3nT17FvHx8ahatSoAoGrVqjh48KDG47LednR0RJkyZXDlyhVUqFBB4+Lp6aluZ2Njg27duuHnn3/G2rVrsWHDBjx8+FDHr5CIdIE9M0RUaDRv3hy+vr7o2bMn5syZg7S0NAwaNAiBgYHw8/MDAAwbNgx9+/aFn58fGjZsiJUrVyImJgblypVT72fy5MkYOnQobGxs0Lp1a6SkpODo0aN49OgRRowYgdmzZ8PZ2Rk1atSAgYEB1q1bBycnJ9jZ2Sn0yonobbBnhogKDZVKhc2bN6NEiRJo3LgxmjdvjnLlymHt2rXqNt26dcMXX3yBsWPHonbt2rh27Ro++eQTjf18+OGHWLx4MZYtWwYfHx8EBgZi2bJl6p4ZKysrTJ8+HX5+fqhTpw6uXr2Kbdu2wcCA/yUS6SPOZiIiIiK9xj9DiIiISK8xzBAREZFeY5ghIiIivcYwQ0RERHqNYYaIiIj0GsMMERER6TWGGSIiItJrDDNERESk1xhmiIiISK8xzBAREZFeY5ghIiIivcYwQ0RERHrt/wAzjHbLe59UqQAAAABJRU5ErkJggg==" + }, + "metadata": {}, + "output_type": "display_data" + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "2vSanYys6E68" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from IPython.core.display import SVG\n", + "from matplotlib import markers\n", + "import matplotlib.pyplot as plt\n", + "\n", + "#data loading\n", + "\n", + "world_size = ['4|148', '6|222', '8|296', '10|370', '12|444', '14|518']\n", + "baremetal_cylon = [18.93717813, 19.75821758, 19.84387813, 20.68476873, 21.04591821, 21.59903709]\n", + "rp_cylon = [19.27405391, 20.4443211, 20.7198427, 21.2812939, 21.50566909, 21.78800784]\n", + "\n", + "rp_cylon_err = [0.2107801437, 0.3222160003, 1.022121528, 0.349553999, 0.3169727816, 1.534950139]\n", + "bm_cylon_err = [0.6005659103, 1.614059141, 0.8212216271, 0.2230492727, 0.1857792821, 2.082797966]\n", + "\n", + "plt.plot(world_size, baremetal_cylon, marker='o', color='b', label='BM-Cylon')\n", + "plt.plot(world_size, rp_cylon, marker='o', color='g', label='RP-Cylon')\n", + "\n", + "\n", + "plt.errorbar(world_size, baremetal_cylon, yerr=bm_cylon_err, fmt='x', color='b', ecolor='b', capsize=5)\n", + "plt.errorbar(world_size, rp_cylon, yerr=rp_cylon_err, fmt='o', color='g', ecolor='g', capsize=5)\n", + "\n", + "custom_text = \"35m rows\"\n", + "plt.text(4, 24, custom_text, fontsize=10, color='orange', ha='center')\n", + "\n", + "plt.ylim(15, 25)\n", + "\n", + "plt.xticks(world_size)\n", + "\n", + "plt.xlabel('nodes | parallelism')\n", + "plt.ylabel('average time (s)')\n", + "plt.title('Weak Scaling of Sort Operation')\n", + "\n", + "plt.legend()\n", + "\n", + "#save the figure\n", + "plt.savefig('sort-w-scaling.svg', format='svg')\n", + "\n", + "#display the graph\n", + "\n", + "plt.show()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 473 + }, + "id": "eg1zeZcSLRAI", + "outputId": "3ab2569d-7c8c-4317-8a24-ea9de8c62b34" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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cn2Xk5+fH3bv3o379+9DCIGjR4/i2rVr6NKlS56vSU9PR0JCgsqDiIiIKrZyHWiWL1+OevXqoXr16jAxMUG3bt2wYsUKtGvXLs/XzJs3D7a2tsqHu7t7KdaYiIiIykK5DzSnTp3C7t27ce7cOSxatAhjxozBH3/8kedrpk+fjvj4eOUjJiamFGtMREREZaHc3radmpqKGTNmYOfOnejZsycAoFGjRoiKisKXX36JTp06aXydqakpTE1NS7OqREREVMbKbQtNZmYmMjMzYWCgWkVDQ0MoFIoyqhURERGVR2XaQpOUlIQbN24on9++fRtRUVGwt7eHh4cHAgMDMWXKFJibm8PT0xPHjh3DDz/8gMWLF5dhrYmIiKi8kQkhRFm9eVhYGDp06KC2PSgoCOvXr8fDhw8xffp0HDx4EM+ePYOnpydGjhyJDz74ADKZTKv3SEhIgK2tLeLj42FjY1Pcp0BEREQlQNfP7zINNKWBgYaIiEj/6Pr5XW7H0BARERFpi4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvlWmgOX78OHr16gU3NzfIZDLs2rVLrcyVK1fQu3dv2NrawtLSEi1btkR0dHTpV5aIiIjKrTINNMnJyWjcuDFWrFihcf/NmzcREBAAX19fhIWF4e+//8Ynn3wCMzOzUq4pERERlWcyIYQo60oAgEwmw86dO9G3b1/ltkGDBsHY2Bg//vhjoY+bkJAAW1tbxMfHw8bGphhqSkRERCVN18/vcjuGRqFQYO/evahTpw66du0KJycntGrVSmO3FBEREVVu5TbQxMXFISkpCV988QW6deuGgwcPol+/fujfvz+OHTuW5+vS09ORkJCg8iAiIqKKzaisK5AXhUIBAOjTpw8++OADAECTJk0QGRmJb775BoGBgRpfN2/ePMyaNavU6klERERlr9y20FStWhVGRkaoV6+eyva6devme5fT9OnTER8fr3zExMSUdFWJiIiojJXbFhoTExO0bNkSV69eVdl+7do1eHp65vk6U1NTmJqalnT1iIiIqBwp00CTlJSEGzduKJ/fvn0bUVFRsLe3h4eHB6ZMmYI333wT7dq1Q4cOHXDgwAH89ttvCAsLK7tKExERUblTprdth4WFoUOHDmrbg4KCsH79egDA999/j3nz5uHevXvw8fHBrFmz0KdPH63fg7dtExER6R9dP7/LzTw0JYWBhoiISP9UmHloiIiIiLTFQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPcYaIiIiEjvMdAQERGR3mOgISIiIr3HQENERER6j4GGiIiI9B4DDREREek9BhoiIiLSeww0REREpPeMyroCJU0IAQBISEgo45oQERGRtrI/t7M/xwtS4QNNYmIiAMDd3b2Ma0JERES6SkxMhK2tbYHlZELb6KOnFAoFHjx4AGtra8hksmI9dkJCAtzd3RETEwMbG5tiPTbl4HUuHbzOpYPXuXTwOpeOkrzOQggkJibCzc0NBgYFj5Cp8C00BgYGqF69eom+h42NDf+HKQW8zqWD17l08DqXDl7n0lFS11mblplsHBRMREREeo+BhoiIiPQeA00RmJqaIiQkBKampmVdlQqN17l08DqXDl7n0sHrXDrK03Wu8IOCiYiIqOJjCw0RERHpPQYaIiIi0nsMNERERKT3GGg0CA0NRXBwcFlX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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "from IPython.core.display import SVG\n", + "from matplotlib import markers\n", + "import matplotlib.pyplot as plt\n", + "\n", + "#data loading\n", + "\n", + "world_size = ['4|148', '6|222', '8|296', '10|370', '12|444', '14|518']\n", + "baremetal_cylon = [12.48204808, 8.280943102, 6.334967629, 5.099316477, 4.445687452, 3.851617681]\n", + "rp_cylon = [12.55294192, 8.420808574, 6.376633428, 5.131316051, 4.446267159, 3.95247161]\n", + "\n", + "rp_cylon_err = [0.6438074455, 0.6394383387, 0.8082996274, 1.177945473, 1.520513786, 1.981052724]\n", + "bm_cylon_err = [0.5287349256, 0.5657937827, 0.3046811328, 1.282029453, 1.70061018, 1.693347512]\n", + "\n", + "# Create a line chart\n", + "plt.plot(world_size, baremetal_cylon, marker='o', color='b', label='BM-Cylon')\n", + "plt.plot(world_size, rp_cylon, marker='o', color='g', label='RP-Cylon')\n", + "\n", + "plt.errorbar(world_size, baremetal_cylon, yerr=bm_cylon_err, fmt='x', color='b', ecolor='b', capsize=5)\n", + "plt.errorbar(world_size, rp_cylon, yerr=rp_cylon_err, fmt='o', color='g', ecolor='g', capsize=5)\n", + "\n", + "custom_text = \"3.5B rows\"\n", + "plt.text(0.3, 14, custom_text, fontsize=10, color='orange', ha='center')\n", + "\n", + "plt.ylim(1, 15)\n", + "\n", + "plt.xticks(world_size)\n", + "\n", + "plt.xlabel('nodes | parallelism')\n", + "plt.ylabel('average time (s)')\n", + "plt.title('Strong Scaling of Sort Operation')\n", + "\n", + "plt.legend()\n", + "\n", + "#save the figure\n", + "plt.savefig('sort-s-scaling.svg', format='svg')\n", + "\n", + "#display the graph\n", + "\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 473 + }, + "id": "dFHyhBGqR8cL", + "outputId": "2f2f0768-20ff-4b13-baee-fd61c2c97c8a" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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ktAIIYQQwuhJQpOKoKAgunTpYugwcoUFCxZQp04dQ4eR48l5NowuXboQFBRk6DByPDnPWSc7n+tcn9CMGzcOlUpF//7906wTFxdHly5dKFOmDGZmZrRs2fK1bR44cAAzMzPKlSunU56cnMzw4cMpWLAg1tbWFC5cmFGjRun9nApjdPfuXT777DNcXFywtramTJkyHD9+PM36p0+fpkOHDnh7e2NtbU2JEiWYOnWqTp01a9bQsGFDXF1dcXBwoGrVqmzdulWnztixY6lcuTL29va4ubnRsmVLLl26lCnHaGhv87nS5zwDTJ8+nRIlSmBtbY2fnx9//vlnijrPnj2jV69eeHh4YGlpSbFixdi8eXOGHqMh7N27l2bNmuHp6YlKpWLdunU66xVF4ccff8TDwwNra2saNGhASEjIa9vcv38/1atX1/57KF68OJMnT9ap4+vri0qlSrH06tVLWycuLo5evXrh4uKCnZ0dbdq04cGDBxl27Fnpdec5MTGRIUOGUKZMGWxtbfH09KRz587cu3dP7/bT+n38sjd9DyiKQuPGjVP9HBiTN32mX/bVV1+hUqmYMmXKa9vcvXt3qp/X+/fvp2u/UVFR9O7dGy8vL6ytrSlZsiS///57uo4vx88U/DrHjh1j1qxZ+Pv7v7ZecnIy1tbW9O3bl9WrV7+27rNnz+jcuTP169dP8Qvm559/ZubMmSxcuJBSpUpx/PhxunbtiqOjI3379n3n48luwsLCqF69OnXr1mXLli24uroSEhJCnjx50tzmxIkTuLm5sXjxYry9vTl48CBffvklpqam9O7dG9D842jYsCFjxozBycmJ+fPn06xZM44cOUL58uUB2LNnD7169aJy5cokJSXx3Xff8cEHH3D+/HlsbW2z5Pizytt8rvQ5zzNnzmTYsGHMmTOHypUrc/ToUb744gvy5MlDs2bNAEhISKBhw4a4ubmxatUq8ufPz82bN3Fycsqqw8800dHRlC1blm7dutG6desU68ePH8+vv/7KwoULKViwIMOHD6dRo0acP38eKyurVNu0tbWld+/e+Pv7Y2try/79++nRowe2trZ8+eWXgOb3UnJysnabs2fP0rBhQz7++GNt2YABA9i0aRMrV67E0dGR3r1707p1aw4cOJDBZyHzve48x8TEcPLkSYYPH07ZsmUJCwujX79+NG/e/LV/GD33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\n" + }, + "metadata": {} + } + ] + } + ] +} diff --git a/aws/scripts/S3_run_script.py b/aws/scripts/S3_run_script.py new file mode 100644 index 000000000..84bd94db0 --- /dev/null +++ b/aws/scripts/S3_run_script.py @@ -0,0 +1,67 @@ +import subprocess +import time +import argparse + +import boto3 +from botocore.exceptions import ClientError +import os + +import logging + +def environ_or_required(key, required: bool = True): + return ( + {'default': os.environ.get(key)} if os.environ.get(key) + else {'required': required} + ) + +def get_file(file_name, bucket, object_name=None): + """Upload a file to an S3 bucket + + :param file_name: File to upload + :param bucket: Bucket to upload to + :param object_name: S3 object name. If not specified then file_name is used + :return: True if file was uploaded, else False + """ + + # If S3 object_name was not specified, use file_name + if object_name is None: + object_name = os.path.basename(file_name) + + # download the file + s3_client = boto3.client('s3') + try: + with open(file_name, 'wb') as f: + s3_client.download_fileobj(bucket, object_name, f) + return f + except ClientError as e: + logging.error(e) + return None + + + +def join(data=None): + script = get_file(file_name=data['output_filename'], bucket=data['s3_bucket'], object_name=data['s3_object_name']) + + if script is None: + print(f"unable to retrieve file {data['output_filename']} from AWS S3") + + scriptargs = data['args'] + if scriptargs is not None: + cmd = scriptargs.split() + subprocess.call(['python'] + [data['output_filename']] + cmd, shell=False) + else: + subprocess.call(['python'] + [data['output_filename']], shell=False) +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="run S3 script") + + parser.add_argument('-b', dest='s3_bucket', type=str, help="S3 Bucket Name", **environ_or_required('S3_BUCKET')) + parser.add_argument('-o', dest='s3_object_name', type=str, help="S3 Object Name", **environ_or_required('S3_OBJECT_NAME')) + parser.add_argument('-f', dest='output_filename', type=str, help="Output filename", + **environ_or_required('OUTPUT_FILENAME')) + parser.add_argument('-a', dest='args', type=str, help="script exec arguments", + **environ_or_required('EXEC_ARGS', required=False)) + + + + args = vars(parser.parse_args()) + join(args) diff --git a/aws/scripts/clearDb.py b/aws/scripts/clearDb.py new file mode 100644 index 000000000..37a8ff72c --- /dev/null +++ b/aws/scripts/clearDb.py @@ -0,0 +1,30 @@ +import redis +import argparse +import os + +def environ_or_required(key): + return ( + {'default': os.environ.get(key)} if os.environ.get(key) + else {'required': True} + ) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="clear redis db") + parser.add_argument("-r", dest='redis_host', type=str, help="redis address, default to 127.0.0.1", + **environ_or_required('REDIS_HOST')) #127.0.0.1 + parser.add_argument("-p1", dest='redis_port', type=int, help="name of redis port", **environ_or_required('REDIS_PORT')) #6379 + + + + args = vars(parser.parse_args()) + + r = redis.Redis(host=args['redis_host'], port=args['redis_port'], db=0) + if r is not None: + r.flushdb() + print("flushed redisDB") + else: + print("warn - could not flush db") + + + + diff --git a/aws/scripts/cloudformation/cylon-elasticache.yaml b/aws/scripts/cloudformation/cylon-elasticache.yaml new file mode 100644 index 000000000..4d566422a --- /dev/null +++ b/aws/scripts/cloudformation/cylon-elasticache.yaml @@ -0,0 +1,74 @@ +AWSTemplateFormatVersion: 2010-09-09 + +Parameters: + AvailabilityZone1: + Type: String + + AvailabilityZone2: + Type: String + + CacheEngine: + Type: String + + CacheEngineVersion: + Type: String + + CacheNodeType: + Type: String + + CacheParameterGroupName: + Type: String + + CacheSecurityGroup: + Type: String + + CacheSubnet1: + Type: String + + CacheSubnet2: + Type: String + + Prefix: + Type: String + + Prefix2: + Type: String + + RedisPort: + Type: Number + + ReplicaCount: + Type: Number + + +Resources: + SubnetGroup: + Type: AWS::ElastiCache::SubnetGroup + Properties: + CacheSubnetGroupName: !Sub "${Prefix2}-subnetgroup" + Description: !Sub "${Prefix2}-SubnetGroup" + SubnetIds: + - !Ref CacheSubnet1 + - !Ref CacheSubnet2 + Tags: + - Key: "name" + Value: !Sub "${Prefix2}-Redis SubnetGroup" + + + + + CacheCluster: + Type: AWS::ElastiCache::CacheCluster + Properties: + ClusterName: !Sub "${Prefix2}-Redis" + CacheNodeType: !Ref CacheNodeType + CacheSubnetGroupName: !Ref SubnetGroup + Engine: !Ref CacheEngine + EngineVersion: 7.0 + NumCacheNodes: 1 #has to be 1 for redis + VpcSecurityGroupIds: + - !Ref CacheSecurityGroup + Tags: + - Key: "name" + Value: !Sub "${Prefix2}-Redis Cluster" + DependsOn: SubnetGroup \ No newline at end of file diff --git a/aws/scripts/cloudformation/cylon-redis.yaml b/aws/scripts/cloudformation/cylon-redis.yaml new file mode 100644 index 000000000..1ec6e8a23 --- /dev/null +++ b/aws/scripts/cloudformation/cylon-redis.yaml @@ -0,0 +1,95 @@ +AWSTemplateFormatVersion: "2010-09-09" +Parameters: + TemplateBucketName: + Type: String + Default: staylor.dev2 + + Prefix: + Type: String + Default: cylon + + Prefix2: + Type: String + Default: cylon + + Architecture: + Type: String + Default: arm64 + + AvailabilityZone1: + Type: String + Default: us-east-1c + + AvailabilityZone2: + Type: String + Default: us-east-1d + + CacheEngine: + Type: String + Default: redis + + CacheEngineVersion: + Type: String + Default: 6.2 + + CacheNodeType: + Type: String + Default: cache.t4g.micro + + CacheParameterGroupName: + Type: String + Default: default.redis7.cluster.on + + CacheSecurityGroupName: + Type: String + Default: sg-0da3e3dcebe706315 + + CacheSubnet1: + Type: String + Default: subnet-07995eea6c462cd73 + + CacheSubnet2: + Type: String + Default: subnet-039df5ab7fd94f516 + + ImageId: + Type: String + Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2 + + InstanceType: + Type: String + Default: t4g.nano + + ReplicaCount: + Type: Number + Default: 1 + + Runtime: + Type: String + Default: python3.8 + + RedisPort: + Type: Number + Default: 6379 + + +Resources: + ElastiCacheStack: + Type: AWS::CloudFormation::Stack + "DeletionPolicy" : "Delete" + Properties: + TemplateURL: !Sub "https://s3.amazonaws.com/${TemplateBucketName}/${Prefix}/${Prefix}-elasticache.yaml" + Parameters: + AvailabilityZone1: !Ref AvailabilityZone1 + AvailabilityZone2: !Ref AvailabilityZone2 + CacheEngine: !Ref CacheEngine + CacheEngineVersion: !Ref CacheEngineVersion + CacheNodeType: !Ref CacheNodeType + CacheParameterGroupName: !Ref CacheParameterGroupName + CacheSecurityGroup: !Ref CacheSecurityGroupName + CacheSubnet1: !Ref CacheSubnet1 + CacheSubnet2: !Ref CacheSubnet2 + Prefix: !Ref Prefix + Prefix2: !Ref Prefix2 + RedisPort: !Ref RedisPort + ReplicaCount: !Ref ReplicaCount diff --git a/aws/scripts/cylon-redis-task-def.json b/aws/scripts/cylon-redis-task-def.json new file mode 100644 index 000000000..322d75f0a --- /dev/null +++ b/aws/scripts/cylon-redis-task-def.json @@ -0,0 +1,112 @@ +{ + "taskDefinition": { + "containerDefinitions": [ + { + "name": "cylon-ucc-ucx-redis", + "image": "448324707516.dkr.ecr.us-east-1.amazonaws.com/cylon-ucc-ucx-redis:latest", + "cpu": 8192, + "memory": 32768, + "portMappings": [], + "essential": true, + "command": [ + "python", + "/cylon/aws/scripts/S3_run_script.py" + ], + "environment": [ + { + "name": "S3_BUCKET", + "value": "staylor.dev2" + }, + { + "name": "S3_OBJECT_NAME", + "value": "cylon/scripts/cylon_scaling.py" + }, + { + "name": "OUTPUT_FILENAME", + "value": "cylon_scaling.py" + }, + { + "name": "EXEC_ARGS", + "value": "-n 5000 -s w -w 1 -r cylon-redis.mveu6e.0001.use1.cache.amazonaws.com -f1 cylon_scaling_test_fargate -b staylor.dev2 -o1 cylon/scaling/cylon_scaling_test_fargate.txt -f2 cylon_summary_test_fargate -o2 cylon/scaling/cylon_summary_test_fargate.txt" + } + ], + "environmentFiles": [], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/cylon-ucc-ucx-redis-task", + "awslogs-region": "us-east-1", + "awslogs-stream-prefix": "ecs" + } + }, + "linuxParameters": { + "sharedMemorySize": 8589934592 + } + } + ], + "family": "cylon-ucc-ucx-redis-task", + "taskRoleArn": "arn:aws:iam::448324707516:role/ECSTaskRole", + "executionRoleArn": "arn:aws:iam::448324707516:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "revision": 1, + "volumes": [], + "status": "ACTIVE", + "requiresAttributes": [ + { + "name": "com.amazonaws.ecs.capability.logging-driver.awslogs" + }, + { + "name": "ecs.capability.execution-role-awslogs" + }, + { + "name": "com.amazonaws.ecs.capability.ecr-auth" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19" + }, + { + "name": "ecs.capability.increased-task-cpu-limit" + }, + { + "name": "com.amazonaws.ecs.capability.task-iam-role" + }, + { + "name": "ecs.capability.execution-role-ecr-pull" + }, + { + "name": "ecs.capability.extensible-ephemeral-storage" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18" + }, + { + "name": "ecs.capability.task-eni" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29" + } + ], + "placementConstraints": [], + "compatibilities": [ + "EC2", + "FARGATE" + ], + "runtimePlatform": { + "cpuArchitecture": "X86_64", + "operatingSystemFamily": "LINUX" + }, + "requiresCompatibilities": [ + "FARGATE" + ], + "cpu": "8192", + "memory": "32768", + "ephemeralStorage": { + "sizeInGiB": 100 + } + }, + "tags": [] +} \ No newline at end of file diff --git a/aws/scripts/cylon_scaling.py b/aws/scripts/cylon_scaling.py new file mode 100644 index 000000000..34ba2015b --- /dev/null +++ b/aws/scripts/cylon_scaling.py @@ -0,0 +1,294 @@ +import time +import argparse + +import pandas as pd +from numpy.random import default_rng +from pycylon.frame import CylonEnv, DataFrame +from cloudmesh.common.StopWatch import StopWatch +from cloudmesh.common.dotdict import dotdict +from cloudmesh.common.Shell import Shell +from cloudmesh.common.util import writefile +from pycylon.net.ucc_config import UCCConfig +from pycylon.net.redis_ucc_oob_context import UCCRedisOOBContext +from pycylon.net.reduce_op import ReduceOp +import boto3 +from botocore.exceptions import ClientError +import os + +import logging + +def environ_or_required(key): + return ( + {'default': os.environ.get(key)} if os.environ.get(key) + else {'required': True} + ) +def upload_file(file_name, bucket, object_name=None): + """Upload a file to an S3 bucket + + :param file_name: File to upload + :param bucket: Bucket to upload to + :param object_name: S3 object name. If not specified then file_name is used + :return: True if file was uploaded, else False + """ + + # If S3 object_name was not specified, use file_name + if object_name is None: + object_name = os.path.basename(file_name) + + # Upload the file + s3_client = boto3.client('s3') + try: + response = s3_client.upload_file(file_name, bucket, object_name) + except ClientError as e: + logging.error(e) + return False + return True + + +def cylon_join(data=None): + global ucc_config + StopWatch.start(f"join_total_{data['host']}_{data['rows']}_{data['it']}") + + redis_context = UCCRedisOOBContext(data['world_size'], f"tcp://{data['redis_host']}:{data['redis_port']}") + + if redis_context is not None: + ucc_config = UCCConfig(redis_context) + + if ucc_config is None: + print("unable to initialize uccconfig") + + + + env = CylonEnv(config=ucc_config, distributed=True) + + context = env.context + + if context is None: + print("unable to retrieve cylon context") + + communicator = context.get_communicator() + + u = data['unique'] + + if data['scaling'] == 'w': # weak + num_rows = data['rows'] + max_val = num_rows * env.world_size + else: # 's' strong + max_val = data['rows'] + num_rows = int(data['rows'] / env.world_size) + + rng = default_rng(seed=env.rank) + data1 = rng.integers(0, int(max_val * u), size=(num_rows, 2)) + data2 = rng.integers(0, int(max_val * u), size=(num_rows, 2)) + + df1 = DataFrame(pd.DataFrame(data1).add_prefix("col")) + df2 = DataFrame(pd.DataFrame(data2).add_prefix("col")) + + for i in range(data['it']): + env.barrier() + StopWatch.start(f"join_{i}_{data['host']}_{data['rows']}_{data['it']}") + t1 = time.time() + df3 = df1.merge(df2, on=[0], algorithm='sort', env=env) + env.barrier() + t2 = time.time() + t = (t2 - t1) * 1000 + # sum_t = comm.reduce(t) + sum_t = communicator.allreduce(t, ReduceOp.SUM) + # tot_l = comm.reduce(len(df3)) + tot_l = communicator.allreduce(len(df3), ReduceOp.SUM) + + if env.rank == 0: + avg_t = sum_t / env.world_size + print("### ", data['scaling'], env.world_size, num_rows, max_val, i, avg_t, tot_l) + print("### ", data['scaling'], env.world_size, num_rows, max_val, i, avg_t, tot_l, file=open(data['output_summary_filename'], 'a')) + StopWatch.stop(f"join_{i}_{data['host']}_{data['rows']}_{data['it']}") + + StopWatch.stop(f"join_total_{data['host']}_{data['rows']}_{data['it']}") + + if env.rank == 0: + StopWatch.benchmark(tag=str(data), filename=data['output_scaling_filename']) + upload_file(file_name=data['output_scaling_filename'], bucket=data['s3_bucket'], object_name=data['s3_stopwatch_object_name']) + upload_file(file_name=data['output_summary_filename'], bucket=data['s3_bucket'], + object_name=data['s3_summary_object_name']) + + env.finalize() + + +def cylon_sort(data=None): + StopWatch.start(f"sort_total_{data['host']}_{data['rows']}_{data['it']}") + + redis_context = UCCRedisOOBContext(data['world_size'], f"tcp://{data['redis_host']}:{data['redis_port']}") + + if redis_context is not None: + ucc_config = UCCConfig(redis_context) + + if ucc_config is None: + print("unable to initialize uccconfig") + + env = CylonEnv(config=ucc_config, distributed=True) + + context = env.context + + if context is None: + print("unable to retrieve cylon context") + + communicator = context.get_communicator() + + u = data['unique'] + + if data['scaling'] == 'w': # weak + num_rows = data['rows'] + max_val = num_rows * env.world_size + else: # 's' strong + max_val = data['rows'] + num_rows = int(data['rows'] / env.world_size) + + rng = default_rng(seed=env.rank) + data1 = rng.integers(0, int(max_val * u), size=(num_rows, 2)) + + df1 = DataFrame(pd.DataFrame(data1).add_prefix("col")) + + if env.rank == 0: + print("Task# ", data['task']) + + for i in range(data['it']): + env.barrier() + StopWatch.start(f"sort_{i}_{data['host']}_{data['rows']}_{data['it']}") + t1 = time.time() + df3 = df1.sort_values(by=[0], env=env) + env.barrier() + t2 = time.time() + t = (t2 - t1) + sum_t = communicator.allreduce(t, ReduceOp.SUM) + # tot_l = comm.reduce(len(df3)) + tot_l = communicator.allreduce(len(df3), ReduceOp.SUM) + + if env.rank == 0: + avg_t = sum_t / env.world_size + print("### ", data['scaling'], env.world_size, num_rows, max_val, i, avg_t, tot_l) + print("### ", data['scaling'], env.world_size, num_rows, max_val, i, avg_t, tot_l, + file=open(data['output_summary_filename'], 'a')) + + + StopWatch.stop(f"sort_{i}_{data['host']}_{data['rows']}_{data['it']}") + + StopWatch.stop(f"sort_total_{data['host']}_{data['rows']}_{data['it']}") + + if env.rank == 0: + StopWatch.benchmark(tag=str(data), filename=data['output_scaling_filename']) + upload_file(file_name=data['output_scaling_filename'], bucket=data['s3_bucket'], + object_name=data['s3_stopwatch_object_name']) + upload_file(file_name=data['output_summary_filename'], bucket=data['s3_bucket'], + object_name=data['s3_summary_object_name']) + redis_context.clearDB() + + +def cylon_slice(data=None): + StopWatch.start(f"slice_total_{data['host']}_{data['rows']}_{data['it']}") + + redis_context = UCCRedisOOBContext(data['world_size'], f"tcp://{data['redis_host']}:{data['redis_port']}") + + if redis_context is not None: + ucc_config = UCCConfig(redis_context) + + if ucc_config is None: + print("unable to initialize uccconfig") + + env = CylonEnv(config=ucc_config, distributed=True) + + context = env.context + + if context is None: + print("unable to retrieve cylon context") + + communicator = context.get_communicator() + + u = data['unique'] + + if data['scaling'] == 'w': # weak + num_rows = data['rows'] + max_val = num_rows * env.world_size + else: # 's' strong + max_val = data['rows'] + num_rows = int(data['rows'] / env.world_size) + + rng = default_rng(seed=env.rank) + data1 = rng.integers(0, int(max_val * u), size=(num_rows, 2)) + data2 = rng.integers(0, int(max_val * u), size=(num_rows, 2)) + + df1 = DataFrame(pd.DataFrame(data1).add_prefix("col")) + df2 = DataFrame(pd.DataFrame(data2).add_prefix("col")) + + if env.rank == 0: + print("Task# ", data['task']) + + for i in range(data['it']): + env.barrier() + StopWatch.start(f"slice_{i}_{data['host']}_{data['rows']}_{data['it']}") + t1 = time.time() + df3 = df1[0:20000000, env] # distributed slice + # print(df3) + # df3 = df1.merge(df2, on=[0], algorithm='sort', env=env) + env.barrier() + t2 = time.time() + t = (t2 - t1) + sum_t = communicator.allreduce(t, ReduceOp.SUM) + # tot_l = comm.reduce(len(df3)) + tot_l = communicator.allreduce(len(df3), ReduceOp.SUM) + + if env.rank == 0: + avg_t = sum_t / env.world_size + print("### ", data['scaling'], env.world_size, num_rows, max_val, i, avg_t, tot_l) + print("### ", data['scaling'], env.world_size, num_rows, max_val, i, avg_t, tot_l, + file=open(data['output_summary_filename'], 'a')) + StopWatch.stop(f"slice_{i}_{data['host']}_{data['rows']}_{data['it']}") + + StopWatch.stop(f"slice_total_{data['host']}_{data['rows']}_{data['it']}") + + if env.rank == 0: + StopWatch.benchmark(tag=str(data), filename=data['output_scaling_filename']) + upload_file(file_name=data['output_scaling_filename'], bucket=data['s3_bucket'], + object_name=data['s3_stopwatch_object_name']) + upload_file(file_name=data['output_summary_filename'], bucket=data['s3_bucket'], + object_name=data['s3_summary_object_name']) + + env.finalize() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="cylon scaling") + parser.add_argument('-n', dest='rows', type=int, **environ_or_required('ROWS')) + parser.add_argument('-i', dest='it', type=int, **environ_or_required('PARTITIONS')) #10 + parser.add_argument('-u', dest='unique', type=float, **environ_or_required('UNIQUENESS'), help="unique factor") #0.9 + parser.add_argument('-s', dest='scaling', type=str, **environ_or_required('SCALING'), choices=['s', 'w'], + help="s=strong w=weak") #w + parser.add_argument('-o', dest='operation', type=str, **environ_or_required('CYLON_OPERATION'), choices=['join', 'sort', 'slice'], + help="s=strong w=weak") # w + parser.add_argument('-w', dest='world_size', type=int, help="world size", **environ_or_required('WORLD_SIZE')) + parser.add_argument("-r", dest='redis_host', type=str, help="redis address, default to 127.0.0.1", + **environ_or_required('REDIS_HOST')) #127.0.0.1 + parser.add_argument("-p1", dest='redis_port', type=int, help="name of redis port", **environ_or_required('REDIS_PORT')) #6379 + parser.add_argument('-f1', dest='output_scaling_filename', type=str, help="Output filename for scaling results", + **environ_or_required('OUTPUT_SCALING_FILENAME')) + parser.add_argument('-f2', dest='output_summary_filename', type=str, help="Output filename for scaling summary results", + **environ_or_required('OUTPUT_SUMMARY_FILENAME')) + parser.add_argument('-b', dest='s3_bucket', type=str, help="S3 Bucket Name", **environ_or_required('S3_BUCKET')) + parser.add_argument('-o1', dest='s3_stopwatch_object_name', type=str, help="S3 Object Name", **environ_or_required('S3_STOPWATCH_OBJECT_NAME')) + parser.add_argument('-o2', dest='s3_summary_object_name', type=str, help="S3 Object Name", + **environ_or_required('S3_SUMMARY_OBJECT_NAME')) + + args = vars(parser.parse_args()) + args['host'] = "aws" + if args['operation'] == 'join': + print("executing cylon join operation") + cylon_join(args) + elif args['operation'] == 'sort': + print("executing cylon sort operation") + cylon_sort(args) + else: + print ("executing cylon slice operation") + cylon_slice(args) + + + # os.system(f"{git} branch | fgrep '*' ") + # os.system(f"{git} rev-parse HEAD") diff --git a/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_16node.txt b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_16node.txt new file mode 100644 index 000000000..0aa62291c --- /dev/null +++ b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_16node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-17 20:26:30.358977 | +| frequency | scpufreq(current=3409.9529375, min=0.0, max=0.0) | +| mem.active | 1.4 GiB | +| mem.available | 28.5 GiB | +| mem.free | 23.6 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 6.4 % | +| mem.total | 30.4 GiB | +| mem.used | 1.5 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-84-64.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+------------------------------+--------+-------+-------------------------------------| +| join_total_aws_145000000_10 | ok | 117.427 | 117.427 | 2023-08-17 20:24:32 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_145000000_10 | ok | 4.032 | 4.032 | 2023-08-17 20:25:50 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_145000000_10 | ok | 3.958 | 3.958 | 2023-08-17 20:25:54 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_145000000_10 | ok | 4.009 | 4.009 | 2023-08-17 20:25:58 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_145000000_10 | ok | 4.168 | 4.168 | 2023-08-17 20:26:02 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_145000000_10 | ok | 3.938 | 3.938 | 2023-08-17 20:26:06 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_145000000_10 | ok | 3.96 | 3.96 | 2023-08-17 20:26:10 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_145000000_10 | ok | 3.95 | 3.95 | 2023-08-17 20:26:14 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_145000000_10 | ok | 3.934 | 3.934 | 2023-08-17 20:26:18 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_145000000_10 | ok | 4.016 | 4.016 | 2023-08-17 20:26:22 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_145000000_10 | ok | 3.966 | 3.966 | 2023-08-17 20:26:26 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'} | | ip-172-31-84-64.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_145000000_10,ok,117.427,117.427,2023-08-17 20:24:32,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_145000000_10,ok,4.032,4.032,2023-08-17 20:25:50,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_145000000_10,ok,3.958,3.958,2023-08-17 20:25:54,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_145000000_10,ok,4.009,4.009,2023-08-17 20:25:58,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_145000000_10,ok,4.168,4.168,2023-08-17 20:26:02,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_145000000_10,ok,3.938,3.938,2023-08-17 20:26:06,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_145000000_10,ok,3.96,3.96,2023-08-17 20:26:10,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_145000000_10,ok,3.95,3.95,2023-08-17 20:26:14,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_145000000_10,ok,3.934,3.934,2023-08-17 20:26:18,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_145000000_10,ok,4.016,4.016,2023-08-17 20:26:22,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_145000000_10,ok,3.966,3.966,2023-08-17 20:26:26,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_1450000000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_16node.txt', 'host': 'aws'},None,ip-172-31-84-64.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_1node.txt b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_1node.txt new file mode 100644 index 000000000..735e9b9ec --- /dev/null +++ b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_1node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-17 19:51:44.964867 | +| frequency | scpufreq(current=3407.9141250000002, min=0.0, max=0.0) | +| mem.active | 14.0 GiB | +| mem.available | 15.8 GiB | +| mem.free | 10.9 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 48.1 % | +| mem.total | 30.4 GiB | +| mem.used | 14.2 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-85-157.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_145000000_10 | ok | 570.749 | 570.749 | 2023-08-17 19:42:13 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_145000000_10 | ok | 56.413 | 56.413 | 2023-08-17 19:42:18 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_145000000_10 | ok | 56.52 | 56.52 | 2023-08-17 19:43:14 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_145000000_10 | ok | 56.702 | 56.702 | 2023-08-17 19:44:11 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_145000000_10 | ok | 56.717 | 56.717 | 2023-08-17 19:45:08 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_145000000_10 | ok | 56.617 | 56.617 | 2023-08-17 19:46:04 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_145000000_10 | ok | 56.766 | 56.766 | 2023-08-17 19:47:01 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_145000000_10 | ok | 56.604 | 56.604 | 2023-08-17 19:47:58 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_145000000_10 | ok | 56.641 | 56.641 | 2023-08-17 19:48:54 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_145000000_10 | ok | 56.554 | 56.554 | 2023-08-17 19:49:51 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_145000000_10 | ok | 56.589 | 56.589 | 2023-08-17 19:50:48 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'} | | ip-172-31-85-157.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_145000000_10,ok,570.749,570.749,2023-08-17 19:42:13,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_145000000_10,ok,56.413,56.413,2023-08-17 19:42:18,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_145000000_10,ok,56.52,56.52,2023-08-17 19:43:14,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_145000000_10,ok,56.702,56.702,2023-08-17 19:44:11,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_145000000_10,ok,56.717,56.717,2023-08-17 19:45:08,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_145000000_10,ok,56.617,56.617,2023-08-17 19:46:04,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_145000000_10,ok,56.766,56.766,2023-08-17 19:47:01,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_145000000_10,ok,56.604,56.604,2023-08-17 19:47:58,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_145000000_10,ok,56.641,56.641,2023-08-17 19:48:54,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_145000000_10,ok,56.554,56.554,2023-08-17 19:49:51,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_145000000_10,ok,56.589,56.589,2023-08-17 19:50:48,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_1node.txt', 'host': 'aws'},None,ip-172-31-85-157.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_2node.txt b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_2node.txt new file mode 100644 index 000000000..48316cd02 --- /dev/null +++ b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_2node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-17 20:00:57.494629 | +| frequency | scpufreq(current=3412.046875, min=0.0, max=0.0) | +| mem.active | 7.3 GiB | +| mem.available | 22.5 GiB | +| mem.free | 17.7 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 25.9 % | +| mem.total | 30.4 GiB | +| mem.used | 7.4 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-80-245.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_145000000_10 | ok | 408.51 | 408.51 | 2023-08-17 19:54:08 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_145000000_10 | ok | 33.83 | 33.83 | 2023-08-17 19:55:18 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_145000000_10 | ok | 33.802 | 33.802 | 2023-08-17 19:55:52 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_145000000_10 | ok | 34.12 | 34.12 | 2023-08-17 19:56:26 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_145000000_10 | ok | 33.824 | 33.824 | 2023-08-17 19:57:00 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_145000000_10 | ok | 33.869 | 33.869 | 2023-08-17 19:57:34 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_145000000_10 | ok | 33.84 | 33.84 | 2023-08-17 19:58:07 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_145000000_10 | ok | 33.806 | 33.806 | 2023-08-17 19:58:41 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_145000000_10 | ok | 33.812 | 33.812 | 2023-08-17 19:59:15 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_145000000_10 | ok | 33.872 | 33.872 | 2023-08-17 19:59:49 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_145000000_10 | ok | 34.1 | 34.1 | 2023-08-17 20:00:23 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'} | | ip-172-31-80-245.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++-----------------------------+----------+---------+---------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_145000000_10,ok,408.51,408.51,2023-08-17 19:54:08,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_145000000_10,ok,33.83,33.83,2023-08-17 19:55:18,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_145000000_10,ok,33.802,33.802,2023-08-17 19:55:52,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_145000000_10,ok,34.12,34.12,2023-08-17 19:56:26,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_145000000_10,ok,33.824,33.824,2023-08-17 19:57:00,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_145000000_10,ok,33.869,33.869,2023-08-17 19:57:34,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_145000000_10,ok,33.84,33.84,2023-08-17 19:58:07,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_145000000_10,ok,33.806,33.806,2023-08-17 19:58:41,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_145000000_10,ok,33.812,33.812,2023-08-17 19:59:15,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_145000000_10,ok,33.872,33.872,2023-08-17 19:59:49,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_145000000_10,ok,34.1,34.1,2023-08-17 20:00:23,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strong_145000000_2node.txt', 'host': 'aws'},None,ip-172-31-80-245.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_4node.txt b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_4node.txt new file mode 100644 index 000000000..80ebe27db --- /dev/null +++ b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_4node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-17 20:13:37.510078 | +| frequency | scpufreq(current=3408.3013124999998, min=0.0, max=0.0) | +| mem.active | 3.9 GiB | +| mem.available | 25.9 GiB | +| mem.free | 21.1 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 14.7 % | +| mem.total | 30.4 GiB | +| mem.used | 4.0 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-81-123.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++-----------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|-----------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_145000000_10 | ok | 226.103 | 226.103 | 2023-08-17 20:09:51 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_145000000_10 | ok | 16.183 | 16.183 | 2023-08-17 20:10:55 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_145000000_10 | ok | 16.174 | 16.174 | 2023-08-17 20:11:11 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_145000000_10 | ok | 16.17 | 16.17 | 2023-08-17 20:11:28 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_145000000_10 | ok | 16.14 | 16.14 | 2023-08-17 20:11:44 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_145000000_10 | ok | 16.133 | 16.133 | 2023-08-17 20:12:00 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_145000000_10 | ok | 16.126 | 16.126 | 2023-08-17 20:12:16 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_145000000_10 | ok | 16.107 | 16.107 | 2023-08-17 20:12:32 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_145000000_10 | ok | 16.143 | 16.143 | 2023-08-17 20:12:48 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_145000000_10 | ok | 16.114 | 16.114 | 2023-08-17 20:13:04 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_145000000_10 | ok | 16.132 | 16.132 | 2023-08-17 20:13:21 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'} | | ip-172-31-81-123.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++-----------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_145000000_10,ok,226.103,226.103,2023-08-17 20:09:51,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_145000000_10,ok,16.183,16.183,2023-08-17 20:10:55,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_145000000_10,ok,16.174,16.174,2023-08-17 20:11:11,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_145000000_10,ok,16.17,16.17,2023-08-17 20:11:28,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_145000000_10,ok,16.14,16.14,2023-08-17 20:11:44,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_145000000_10,ok,16.133,16.133,2023-08-17 20:12:00,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_145000000_10,ok,16.126,16.126,2023-08-17 20:12:16,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_145000000_10,ok,16.107,16.107,2023-08-17 20:12:32,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_145000000_10,ok,16.143,16.143,2023-08-17 20:12:48,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_145000000_10,ok,16.114,16.114,2023-08-17 20:13:04,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_145000000_10,ok,16.132,16.132,2023-08-17 20:13:21,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt', 'host': 'aws'},None,ip-172-31-81-123.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_8node.txt b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_8node.txt new file mode 100644 index 000000000..9bfa3ace4 --- /dev/null +++ b/aws/scripts/results-145000000/cylon_scaling_ec2_strong_145000000_8node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8275CL CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-17 20:18:16.286547 | +| frequency | scpufreq(current=3613.2064375, min=0.0, max=0.0) | +| mem.active | 2.2 GiB | +| mem.available | 27.8 GiB | +| mem.free | 23.0 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 9.1 % | +| mem.total | 30.6 GiB | +| mem.used | 2.3 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-83-169.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++-----------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|-----------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_145000000_10 | ok | 142.303 | 142.303 | 2023-08-17 20:15:53 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_145000000_10 | ok | 7.954 | 7.954 | 2023-08-17 20:16:56 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_145000000_10 | ok | 8.154 | 8.154 | 2023-08-17 20:17:03 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_145000000_10 | ok | 7.971 | 7.971 | 2023-08-17 20:17:12 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_145000000_10 | ok | 7.972 | 7.972 | 2023-08-17 20:17:20 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_145000000_10 | ok | 8.02 | 8.02 | 2023-08-17 20:17:28 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_145000000_10 | ok | 7.99 | 7.99 | 2023-08-17 20:17:36 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_145000000_10 | ok | 8 | 8 | 2023-08-17 20:17:44 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_145000000_10 | ok | 8.073 | 8.073 | 2023-08-17 20:17:52 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_145000000_10 | ok | 7.917 | 7.917 | 2023-08-17 20:18:00 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_145000000_10 | ok | 8.08 | 8.08 | 2023-08-17 20:18:08 | {'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'} | | ip-172-31-83-169.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++-----------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_145000000_10,ok,142.303,142.303,2023-08-17 20:15:53,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_145000000_10,ok,7.954,7.954,2023-08-17 20:16:56,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_145000000_10,ok,8.154,8.154,2023-08-17 20:17:03,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_145000000_10,ok,7.971,7.971,2023-08-17 20:17:12,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_145000000_10,ok,7.972,7.972,2023-08-17 20:17:20,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_145000000_10,ok,8.02,8.02,2023-08-17 20:17:28,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_145000000_10,ok,7.99,7.99,2023-08-17 20:17:36,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_145000000_10,ok,8.0,8.0,2023-08-17 20:17:44,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_145000000_10,ok,8.073,8.073,2023-08-17 20:17:52,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_145000000_10,ok,7.917,7.917,2023-08-17 20:18:00,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_145000000_10,ok,8.08,8.08,2023-08-17 20:18:08,{'rows': 145000000, 'it': 10, 'unique': 0.9, 'scaling': 's', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_strong_145000000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_strong_145000000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_scaling_ec2_strong_145000000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/strong/145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt', 'host': 'aws'},None,ip-172-31-83-169.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_16node.txt b/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_16node.txt new file mode 100644 index 000000000..c3063187b --- /dev/null +++ b/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_16node.txt @@ -0,0 +1,10 @@ +### s 16 9062500 145000000 0 4029.546871781349 161101524 +### s 16 9062500 145000000 1 3956.2147110700607 161101524 +### s 16 9062500 145000000 2 4006.7496597766876 161101524 +### s 16 9062500 145000000 3 4166.1305874586105 161101524 +### s 16 9062500 145000000 4 3935.5630427598953 161101524 +### s 16 9062500 145000000 5 3957.828611135483 161101524 +### s 16 9062500 145000000 6 3947.746455669403 161101524 +### s 16 9062500 145000000 7 3931.699424982071 161101524 +### s 16 9062500 145000000 8 4014.2249763011932 161101524 +### s 16 9062500 145000000 9 3963.857814669609 161101524 diff --git a/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_1node.txt b/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_1node.txt new file mode 100644 index 000000000..ded10b15b --- /dev/null +++ b/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_1node.txt @@ -0,0 +1,10 @@ +### s 1 145000000 145000000 0 56412.89281845093 161109857 +### s 1 145000000 145000000 1 56519.5152759552 161109857 +### s 1 145000000 145000000 2 56701.70569419861 161109857 +### s 1 145000000 145000000 3 56716.846227645874 161109857 +### s 1 145000000 145000000 4 56616.804361343384 161109857 +### s 1 145000000 145000000 5 56765.65957069397 161109857 +### s 1 145000000 145000000 6 56603.74593734741 161109857 +### s 1 145000000 145000000 7 56640.29383659363 161109857 +### s 1 145000000 145000000 8 56553.63416671753 161109857 +### s 1 145000000 145000000 9 56588.97686004639 161109857 diff --git a/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_2node.txt b/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_2node.txt new file mode 100644 index 000000000..0369d4a15 --- /dev/null +++ b/aws/scripts/results-145000000/cylon_summary_test_ec2_strong_145000000_2node.txt @@ -0,0 +1,10 @@ +### s 2 72500000 145000000 0 33829.18119430542 161098554 +### s 2 72500000 145000000 1 33800.89461803436 161098554 +### s 2 72500000 145000000 2 34119.54045295715 161098554 +### s 2 72500000 145000000 3 33823.59731197357 161098554 +### s 2 72500000 145000000 4 33868.10278892517 161098554 +### s 2 72500000 145000000 5 33839.05518054962 161098554 +### s 2 72500000 145000000 6 33805.309772491455 161098554 +### s 2 72500000 145000000 7 33811.1287355423 161098554 +### s 2 72500000 145000000 8 33870.83053588867 161098554 +### s 2 72500000 145000000 9 34099.069356918335 161098554 diff --git a/aws/scripts/results-145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt b/aws/scripts/results-145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt new file mode 100644 index 000000000..9e1f02f59 --- /dev/null +++ b/aws/scripts/results-145000000/cylon_summary_test_ec2_strongt_145000000_4node.txt @@ -0,0 +1,10 @@ +### s 4 36250000 145000000 0 16181.42455816269 161112331 +### s 4 36250000 145000000 1 16173.18880558014 161112331 +### s 4 36250000 145000000 2 16169.183850288391 161112331 +### s 4 36250000 145000000 3 16138.943433761597 161112331 +### s 4 36250000 145000000 4 16131.615221500397 161112331 +### s 4 36250000 145000000 5 16124.849140644073 161112331 +### s 4 36250000 145000000 6 16106.135249137878 161112331 +### s 4 36250000 145000000 7 16141.386568546295 161112331 +### s 4 36250000 145000000 8 16113.233029842377 161112331 +### s 4 36250000 145000000 9 16130.472183227539 161112331 diff --git a/aws/scripts/results-145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt b/aws/scripts/results-145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt new file mode 100644 index 000000000..4056d6925 --- /dev/null +++ b/aws/scripts/results-145000000/cylon_summary_test_ec2_strongt_145000000_8node.txt @@ -0,0 +1,10 @@ +### s 8 18125000 145000000 0 7952.463746070862 161104569 +### s 8 18125000 145000000 1 8151.8765687942505 161104569 +### s 8 18125000 145000000 2 7969.114989042282 161104569 +### s 8 18125000 145000000 3 7970.205038785934 161104569 +### s 8 18125000 145000000 4 8018.117159605026 161104569 +### s 8 18125000 145000000 5 7988.0905747413635 161104569 +### s 8 18125000 145000000 6 7998.181223869324 161104569 +### s 8 18125000 145000000 7 8070.7429349422455 161104569 +### s 8 18125000 145000000 8 7915.852248668671 161104569 +### s 8 18125000 145000000 9 8078.289061784744 161104569 diff --git a/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_16node.txt b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_16node.txt new file mode 100644 index 000000000..c38ee3162 --- /dev/null +++ b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_16node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-15 21:07:32.993134 | +| frequency | scpufreq(current=3410.8410625, min=0.0, max=0.0) | +| mem.active | 1.4 GiB | +| mem.available | 28.5 GiB | +| mem.free | 23.6 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 6.4 % | +| mem.total | 30.4 GiB | +| mem.used | 1.5 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-89-59.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++---------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|---------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+------------------------------+--------+-------+-------------------------------------| +| join_total_aws_9100000_10 | ok | 118.549 | 118.549 | 2023-08-15 21:05:34 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_9100000_10 | ok | 3.957 | 3.957 | 2023-08-15 21:06:52 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_9100000_10 | ok | 3.955 | 3.955 | 2023-08-15 21:06:56 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_9100000_10 | ok | 3.966 | 3.966 | 2023-08-15 21:07:00 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_9100000_10 | ok | 4.084 | 4.084 | 2023-08-15 21:07:04 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_9100000_10 | ok | 4.091 | 4.091 | 2023-08-15 21:07:08 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_9100000_10 | ok | 3.971 | 3.971 | 2023-08-15 21:07:12 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_9100000_10 | ok | 3.99 | 3.99 | 2023-08-15 21:07:16 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_9100000_10 | ok | 4.294 | 4.294 | 2023-08-15 21:07:20 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_9100000_10 | ok | 4.027 | 4.027 | 2023-08-15 21:07:24 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_9100000_10 | ok | 3.93 | 3.93 | 2023-08-15 21:07:28 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'} | | ip-172-31-89-59.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++---------------------------+----------+---------+---------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_9100000_10,ok,118.549,118.549,2023-08-15 21:05:34,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_9100000_10,ok,3.957,3.957,2023-08-15 21:06:52,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_9100000_10,ok,3.955,3.955,2023-08-15 21:06:56,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_9100000_10,ok,3.966,3.966,2023-08-15 21:07:00,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_9100000_10,ok,4.084,4.084,2023-08-15 21:07:04,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_9100000_10,ok,4.091,4.091,2023-08-15 21:07:08,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_9100000_10,ok,3.971,3.971,2023-08-15 21:07:12,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_9100000_10,ok,3.99,3.99,2023-08-15 21:07:16,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_9100000_10,ok,4.294,4.294,2023-08-15 21:07:20,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_9100000_10,ok,4.027,4.027,2023-08-15 21:07:24,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_9100000_10,ok,3.93,3.93,2023-08-15 21:07:28,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 16, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_9100000_16node', 'output_summary_filename': 'cylon_summary_test_ec2_9100000_16node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_9100000_16node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_9100000_16node.txt', 'host': 'aws'},None,ip-172-31-89-59.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_1node.txt b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_1node.txt new file mode 100644 index 000000000..ccbc22c56 --- /dev/null +++ b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_1node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-15 16:57:19.199896 | +| frequency | scpufreq(current=3404.932875, min=0.0, max=0.0) | +| mem.active | 1.4 GiB | +| mem.available | 28.5 GiB | +| mem.free | 23.7 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 6.3 % | +| mem.total | 30.4 GiB | +| mem.used | 1.5 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-84-135.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_9100000_10 | ok | 32.554 | 32.554 | 2023-08-15 16:56:46 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_9100000_10 | ok | 3.21 | 3.21 | 2023-08-15 16:56:46 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_9100000_10 | ok | 3.22 | 3.22 | 2023-08-15 16:56:49 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_9100000_10 | ok | 3.221 | 3.221 | 2023-08-15 16:56:53 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_9100000_10 | ok | 3.223 | 3.223 | 2023-08-15 16:56:56 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_9100000_10 | ok | 3.216 | 3.216 | 2023-08-15 16:56:59 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_9100000_10 | ok | 3.22 | 3.22 | 2023-08-15 16:57:02 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_9100000_10 | ok | 3.225 | 3.225 | 2023-08-15 16:57:05 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_9100000_10 | ok | 3.245 | 3.245 | 2023-08-15 16:57:09 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_9100000_10 | ok | 3.218 | 3.218 | 2023-08-15 16:57:12 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_9100000_10 | ok | 3.224 | 3.224 | 2023-08-15 16:57:15 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'} | | ip-172-31-84-135.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_9100000_10,ok,32.554,32.554,2023-08-15 16:56:46,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_9100000_10,ok,3.21,3.21,2023-08-15 16:56:46,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_9100000_10,ok,3.22,3.22,2023-08-15 16:56:49,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_9100000_10,ok,3.221,3.221,2023-08-15 16:56:53,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_9100000_10,ok,3.223,3.223,2023-08-15 16:56:56,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_9100000_10,ok,3.216,3.216,2023-08-15 16:56:59,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_9100000_10,ok,3.22,3.22,2023-08-15 16:57:02,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_9100000_10,ok,3.225,3.225,2023-08-15 16:57:05,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_9100000_10,ok,3.245,3.245,2023-08-15 16:57:09,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_9100000_10,ok,3.218,3.218,2023-08-15 16:57:12,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_9100000_10,ok,3.224,3.224,2023-08-15 16:57:15,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 1, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_1node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_1node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_1node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_1node.txt', 'host': 'aws'},None,ip-172-31-84-135.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_2node.txt b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_2node.txt new file mode 100644 index 000000000..0a2f26f30 --- /dev/null +++ b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_2node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8275CL CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-15 20:50:34.410137 | +| frequency | scpufreq(current=3610.8821875000003, min=0.0, max=0.0) | +| mem.active | 1.3 GiB | +| mem.available | 28.7 GiB | +| mem.free | 23.9 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 6.3 % | +| mem.total | 30.6 GiB | +| mem.used | 1.5 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-92-255.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_9100000_10 | ok | 39.566 | 39.566 | 2023-08-15 20:49:54 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_9100000_10 | ok | 3.887 | 3.887 | 2023-08-15 20:49:54 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_9100000_10 | ok | 3.888 | 3.888 | 2023-08-15 20:49:58 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_9100000_10 | ok | 3.897 | 3.897 | 2023-08-15 20:50:02 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_9100000_10 | ok | 3.902 | 3.902 | 2023-08-15 20:50:06 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_9100000_10 | ok | 3.903 | 3.903 | 2023-08-15 20:50:10 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_9100000_10 | ok | 3.903 | 3.903 | 2023-08-15 20:50:14 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_9100000_10 | ok | 3.978 | 3.978 | 2023-08-15 20:50:18 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_9100000_10 | ok | 3.917 | 3.917 | 2023-08-15 20:50:22 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_9100000_10 | ok | 3.906 | 3.906 | 2023-08-15 20:50:26 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_9100000_10 | ok | 3.902 | 3.902 | 2023-08-15 20:50:30 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'} | | ip-172-31-92-255.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_9100000_10,ok,39.566,39.566,2023-08-15 20:49:54,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_9100000_10,ok,3.887,3.887,2023-08-15 20:49:54,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_9100000_10,ok,3.888,3.888,2023-08-15 20:49:58,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_9100000_10,ok,3.897,3.897,2023-08-15 20:50:02,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_9100000_10,ok,3.902,3.902,2023-08-15 20:50:06,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_9100000_10,ok,3.903,3.903,2023-08-15 20:50:10,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_9100000_10,ok,3.903,3.903,2023-08-15 20:50:14,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_9100000_10,ok,3.978,3.978,2023-08-15 20:50:18,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_9100000_10,ok,3.917,3.917,2023-08-15 20:50:22,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_9100000_10,ok,3.906,3.906,2023-08-15 20:50:26,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_9100000_10,ok,3.902,3.902,2023-08-15 20:50:30,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 2, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_2node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_2node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_2node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_2node.txt', 'host': 'aws'},None,ip-172-31-92-255.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_4node.txt b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_4node.txt new file mode 100644 index 000000000..bbd7f2bef --- /dev/null +++ b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_4node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-15 20:56:08.292875 | +| frequency | scpufreq(current=3406.7418124999995, min=0.0, max=0.0) | +| mem.active | 1.4 GiB | +| mem.available | 28.5 GiB | +| mem.free | 23.7 GiB | +| mem.inactive | 4.7 GiB | +| mem.percent | 6.3 % | +| mem.total | 30.4 GiB | +| mem.used | 1.5 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-80-213.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_9100000_10 | ok | 99.147 | 99.147 | 2023-08-15 20:54:28 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_9100000_10 | ok | 3.916 | 3.916 | 2023-08-15 20:55:29 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_9100000_10 | ok | 3.918 | 3.918 | 2023-08-15 20:55:33 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_9100000_10 | ok | 3.907 | 3.907 | 2023-08-15 20:55:36 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_9100000_10 | ok | 3.92 | 3.92 | 2023-08-15 20:55:40 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_9100000_10 | ok | 3.905 | 3.905 | 2023-08-15 20:55:44 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_9100000_10 | ok | 3.867 | 3.867 | 2023-08-15 20:55:48 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_9100000_10 | ok | 3.847 | 3.847 | 2023-08-15 20:55:52 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_9100000_10 | ok | 3.845 | 3.845 | 2023-08-15 20:55:56 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_9100000_10 | ok | 3.865 | 3.865 | 2023-08-15 20:56:00 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_9100000_10 | ok | 3.883 | 3.883 | 2023-08-15 20:56:04 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++---------------------------+----------+--------+--------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_9100000_10,ok,99.147,99.147,2023-08-15 20:54:28,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_9100000_10,ok,3.916,3.916,2023-08-15 20:55:29,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_9100000_10,ok,3.918,3.918,2023-08-15 20:55:33,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_9100000_10,ok,3.907,3.907,2023-08-15 20:55:36,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_9100000_10,ok,3.92,3.92,2023-08-15 20:55:40,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_9100000_10,ok,3.905,3.905,2023-08-15 20:55:44,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_9100000_10,ok,3.867,3.867,2023-08-15 20:55:48,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_9100000_10,ok,3.847,3.847,2023-08-15 20:55:52,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_9100000_10,ok,3.845,3.845,2023-08-15 20:55:56,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_9100000_10,ok,3.865,3.865,2023-08-15 20:56:00,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_9100000_10,ok,3.883,3.883,2023-08-15 20:56:04,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 4, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_4node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_4node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_4node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_4node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_8node.txt b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_8node.txt new file mode 100644 index 000000000..c1120355f --- /dev/null +++ b/aws/scripts/results-9100000/cylon_scaling_ec2_weak_9100000_8node.txt @@ -0,0 +1,75 @@ + ++---------------------+-------------------------------------------------------------------+ +| Attribute | Value | +|---------------------+-------------------------------------------------------------------| +| BUG_REPORT_URL | "https://bugs.launchpad.net/ubuntu/" | +| DISTRIB_CODENAME | jammy | +| DISTRIB_DESCRIPTION | "Ubuntu 22.04.2 LTS" | +| DISTRIB_ID | Ubuntu | +| DISTRIB_RELEASE | 22.04 | +| HOME_URL | "https://www.ubuntu.com/" | +| ID | ubuntu | +| ID_LIKE | debian | +| NAME | "Ubuntu" | +| PRETTY_NAME | "Ubuntu 22.04.2 LTS" | +| PRIVACY_POLICY_URL | "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | +| SUPPORT_URL | "https://help.ubuntu.com/" | +| UBUNTU_CODENAME | jammy | +| VERSION | "22.04.2 LTS (Jammy Jellyfish)" | +| VERSION_CODENAME | jammy | +| VERSION_ID | "22.04" | +| cpu | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | +| cpu_cores | 8 | +| cpu_count | 16 | +| cpu_threads | 16 | +| date | 2023-08-15 20:59:59.876528 | +| frequency | scpufreq(current=3407.778312499999, min=0.0, max=0.0) | +| mem.active | 1.4 GiB | +| mem.available | 28.5 GiB | +| mem.free | 23.6 GiB | +| mem.inactive | 4.6 GiB | +| mem.percent | 6.3 % | +| mem.total | 30.4 GiB | +| mem.used | 1.5 GiB | +| platform.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| python | 3.9.17 | packaged by conda-forge | (main, Aug 10 2023, 07:02:31) | +| | [GCC 12.3.0] | +| python.pip | 23.2.1 | +| python.version | 3.9.17 | +| sys.platform | linux | +| uname.machine | x86_64 | +| uname.node | ip-172-31-80-213.ec2.internal | +| uname.processor | x86_64 | +| uname.release | 4.14.318-241.531.amzn2.x86_64 | +| uname.system | Linux | +| uname.version | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| user | root | ++---------------------+-------------------------------------------------------------------+ + ++---------------------------+----------+---------+---------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +| Name | Status | Time | Sum | Start | tag | msg | Node | User | OS | Version | +|---------------------------+----------+---------+---------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------| +| join_total_aws_9100000_10 | ok | 107.328 | 107.328 | 2023-08-15 20:58:12 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_0_aws_9100000_10 | ok | 3.878 | 3.878 | 2023-08-15 20:59:20 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_1_aws_9100000_10 | ok | 3.874 | 3.874 | 2023-08-15 20:59:24 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_2_aws_9100000_10 | ok | 3.862 | 3.862 | 2023-08-15 20:59:28 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_3_aws_9100000_10 | ok | 3.898 | 3.898 | 2023-08-15 20:59:32 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_4_aws_9100000_10 | ok | 3.884 | 3.884 | 2023-08-15 20:59:36 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_5_aws_9100000_10 | ok | 3.884 | 3.884 | 2023-08-15 20:59:40 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_6_aws_9100000_10 | ok | 3.978 | 3.978 | 2023-08-15 20:59:44 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_7_aws_9100000_10 | ok | 3.876 | 3.876 | 2023-08-15 20:59:48 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_8_aws_9100000_10 | ok | 3.858 | 3.858 | 2023-08-15 20:59:52 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | +| join_9_aws_9100000_10 | ok | 3.878 | 3.878 | 2023-08-15 20:59:55 | {'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'} | | ip-172-31-80-213.ec2.internal | root | Linux | #1 SMP Tue Jun 27 21:49:00 UTC 2023 | ++---------------------------+----------+---------+---------+---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------------------------+--------+-------+-------------------------------------+ +# csv,timer,status,time,sum,start,tag,msg,uname.node,user,uname.system,platform.version +# csv,join_total_aws_9100000_10,ok,107.328,107.328,2023-08-15 20:58:12,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_0_aws_9100000_10,ok,3.878,3.878,2023-08-15 20:59:20,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_1_aws_9100000_10,ok,3.874,3.874,2023-08-15 20:59:24,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_2_aws_9100000_10,ok,3.862,3.862,2023-08-15 20:59:28,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_3_aws_9100000_10,ok,3.898,3.898,2023-08-15 20:59:32,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_4_aws_9100000_10,ok,3.884,3.884,2023-08-15 20:59:36,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_5_aws_9100000_10,ok,3.884,3.884,2023-08-15 20:59:40,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_6_aws_9100000_10,ok,3.978,3.978,2023-08-15 20:59:44,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_7_aws_9100000_10,ok,3.876,3.876,2023-08-15 20:59:48,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_8_aws_9100000_10,ok,3.858,3.858,2023-08-15 20:59:52,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 +# csv,join_9_aws_9100000_10,ok,3.878,3.878,2023-08-15 20:59:55,{'rows': 9100000, 'it': 10, 'unique': 0.9, 'scaling': 'w', 'operation': 'join', 'world_size': 8, 'redis_host': 'cylon-redis.mveu6e.0001.use1.cache.amazonaws.com', 'redis_port': 6379, 'output_scaling_filename': 'cylon_scaling_test_ec2_weak_9100000_8node', 'output_summary_filename': 'cylon_summary_test_ec2_weak_9100000_8node', 's3_bucket': 'staylor.dev2', 's3_stopwatch_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_scaling_ec2_weak_9100000_8node.txt', 's3_summary_object_name': 'cylon/scaling/ec2/weak/9100000/cylon_summary_test_ec2_weak_9100000_8node.txt', 'host': 'aws'},None,ip-172-31-80-213.ec2.internal,root,Linux,#1 SMP Tue Jun 27 21:49:00 UTC 2023 diff --git a/aws/scripts/results-9100000/cylon_summary_test_ec2_9100000_16node.txt b/aws/scripts/results-9100000/cylon_summary_test_ec2_9100000_16node.txt new file mode 100644 index 000000000..55c4ae2bd --- /dev/null +++ b/aws/scripts/results-9100000/cylon_summary_test_ec2_9100000_16node.txt @@ -0,0 +1,10 @@ +### w 16 9100000 145600000 0 3955.1253616809845 161774191 +### w 16 9100000 145600000 1 3952.8827369213104 161774191 +### w 16 9100000 145600000 2 3963.8237208127975 161774191 +### w 16 9100000 145600000 3 4081.855833530426 161774191 +### w 16 9100000 145600000 4 4089.3873125314713 161774191 +### w 16 9100000 145600000 5 3968.8504487276077 161774191 +### w 16 9100000 145600000 6 3987.659439444542 161774191 +### w 16 9100000 145600000 7 4291.653141379356 161774191 +### w 16 9100000 145600000 8 4025.2812802791595 161774191 +### w 16 9100000 145600000 9 3927.98613011837 161774191 diff --git a/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_1node.txt b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_1node.txt new file mode 100644 index 000000000..baaf6cf47 --- /dev/null +++ b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_1node.txt @@ -0,0 +1,10 @@ +### w 1 9100000 9100000 0 3209.0532779693604 10111764 +### w 1 9100000 9100000 1 3219.9573516845703 10111764 +### w 1 9100000 9100000 2 3220.4110622406006 10111764 +### w 1 9100000 9100000 3 3222.269296646118 10111764 +### w 1 9100000 9100000 4 3215.7342433929443 10111764 +### w 1 9100000 9100000 5 3219.4266319274902 10111764 +### w 1 9100000 9100000 6 3224.6077060699463 10111764 +### w 1 9100000 9100000 7 3244.480609893799 10111764 +### w 1 9100000 9100000 8 3217.606782913208 10111764 +### w 1 9100000 9100000 9 3223.5209941864014 10111764 diff --git a/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_2node.txt b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_2node.txt new file mode 100644 index 000000000..476f70d4c --- /dev/null +++ b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_2node.txt @@ -0,0 +1,10 @@ +### w 2 9100000 18200000 0 3885.681986808777 20222454 +### w 2 9100000 18200000 1 3887.1185779571533 20222454 +### w 2 9100000 18200000 2 3895.438075065613 20222454 +### w 2 9100000 18200000 3 3900.550603866577 20222454 +### w 2 9100000 18200000 4 3901.926279067993 20222454 +### w 2 9100000 18200000 5 3901.6456604003906 20222454 +### w 2 9100000 18200000 6 3976.7285585403442 20222454 +### w 2 9100000 18200000 7 3916.15629196167 20222454 +### w 2 9100000 18200000 8 3904.7634601593018 20222454 +### w 2 9100000 18200000 9 3901.23450756073 20222454 diff --git a/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_4node.txt b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_4node.txt new file mode 100644 index 000000000..1b8301f1b --- /dev/null +++ b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_4node.txt @@ -0,0 +1,10 @@ +### w 4 9100000 36400000 0 3914.8510694503784 40437898 +### w 4 9100000 36400000 1 3916.4035320281982 40437898 +### w 4 9100000 36400000 2 3906.2851667404175 40437898 +### w 4 9100000 36400000 3 3919.1325306892395 40437898 +### w 4 9100000 36400000 4 3903.8299918174744 40437898 +### w 4 9100000 36400000 5 3865.3509616851807 40437898 +### w 4 9100000 36400000 6 3845.4021215438843 40437898 +### w 4 9100000 36400000 7 3843.4287309646606 40437898 +### w 4 9100000 36400000 8 3863.954722881317 40437898 +### w 4 9100000 36400000 9 3882.117211818695 40437898 diff --git a/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_8node.txt b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_8node.txt new file mode 100644 index 000000000..197c45745 --- /dev/null +++ b/aws/scripts/results-9100000/cylon_summary_test_ec2_weak_9100000_8node.txt @@ -0,0 +1,10 @@ +### w 8 9100000 72800000 0 3875.7028579711914 80888085 +### w 8 9100000 72800000 1 3871.913105249405 80888085 +### w 8 9100000 72800000 2 3860.0634932518005 80888085 +### w 8 9100000 72800000 3 3897.0689177513123 80888085 +### w 8 9100000 72800000 4 3882.505089044571 80888085 +### w 8 9100000 72800000 5 3882.448524236679 80888085 +### w 8 9100000 72800000 6 3976.4296114444733 80888085 +### w 8 9100000 72800000 7 3874.1161227226257 80888085 +### w 8 9100000 72800000 8 3856.1716079711914 80888085 +### w 8 9100000 72800000 9 3875.669479370117 80888085 diff --git a/aws/scripts/runCylon.sh b/aws/scripts/runCylon.sh new file mode 100644 index 000000000..dce201c9a --- /dev/null +++ b/aws/scripts/runCylon.sh @@ -0,0 +1,16 @@ +#!/bin/bash --login + +# Enable strict mode. +set -euo pipefail +# ... Run whatever commands ... + +# Temporarily disable strict mode and activate conda: +set +euo pipefail +conda activate cylon_dev + +# Re-enable strict mode: +set -euo pipefail + +export LD_LIBRARY_PATH=/cylon/install/lib + +exec python /cylon/aws/scripts/S3_run_script.py \ No newline at end of file diff --git a/build.py b/build.py index 44282b14e..85d2fb741 100644 --- a/build.py +++ b/build.py @@ -169,11 +169,14 @@ def parse_cmake_flags(flag): CYLON_GLOO = parse_cmake_flags('CYLON_GLOO') GLOO_PREFIX = parse_cmake_flags('GLOO_INSTALL_PREFIX') - +CYLON_REDIS = parse_cmake_flags("CYLON_USE_REDIS") CYLON_UCX = parse_cmake_flags('CYLON_UCX') CYLON_UCC = parse_cmake_flags('CYLON_UCC') UCC_PREFIX = parse_cmake_flags('UCC_INSTALL_PREFIX') +REDIS_PREFIX = parse_cmake_flags('REDIS_INSTALL_PREFIX') +if CYLON_REDIS and (REDIS_PREFIX is None): + REDIS_PREFIX = "/usr/local" def print_line(): logger.info("=================================================================") @@ -189,6 +192,7 @@ def print_line(): logger.info(f"CMake flags : {CMAKE_FLAGS}") logger.info(f" -CYLON_GLOO : {CYLON_GLOO}") logger.info(f" -GLOO_PREFIX : {GLOO_PREFIX}") +logger.info(f" -REDIS_PREFIX : {REDIS_PREFIX}") logger.info(f" -CYLON_UCX : {CYLON_UCX}") logger.info(f" -CYLON_UCC : {CYLON_UCC}") logger.info(f" -UCC_PREFIX : {UCC_PREFIX}") @@ -279,6 +283,14 @@ def python_test(): os.path.join(UCC_PREFIX, "lib", "ucc") + os.pathsep + \ env['LD_LIBRARY_PATH'] + if CYLON_REDIS: + env['CYLON_REDIS'] = str(CYLON_REDIS) + env['REDIS_PREFIX'] = REDIS_PREFIX + env['LD_LIBRARY_PATH'] = os.path.join(REDIS_PREFIX, "lib") + os.pathsep + \ + os.path.join(REDIS_PREFIX, "lib", "redis++") + os.pathsep + \ + os.path.join(REDIS_PREFIX, "lib", "hiredis") + os.pathsep + \ + env['LD_LIBRARY_PATH'] + elif OS_NAME == 'Darwin': if 'DYLD_LIBRARY_PATH' in env: env['DYLD_LIBRARY_PATH'] = str(Path(INSTALL_DIR, "lib")) + os.pathsep \ @@ -319,6 +331,10 @@ def build_python(): env['CYLON_UCC'] = str(CYLON_UCC) env['UCC_PREFIX'] = UCC_PREFIX + if CYLON_REDIS: + env['CYLON_REDIS'] = str(CYLON_REDIS) + env['REDIS_PREFIX'] = REDIS_PREFIX + logger.info("Arrow prefix: " + str(Path(conda_prefix))) clean = '--upgrade' if args.clean else '' cmd = f'{PYTHON_EXEC} -m pip install -v {clean} .' diff --git a/conda/environments/cylon.yml b/conda/environments/cylon.yml index ab616bd1a..f5a92cc0e 100644 --- a/conda/environments/cylon.yml +++ b/conda/environments/cylon.yml @@ -11,8 +11,8 @@ dependencies: - openmpi=4.1.3=ha1ae619_105 - ucx>=1.12.1 - cython>=0.29,<0.30 - - numpy - - pandas>=1.0,<1.6.0dev0 + - numpy<1.24.4 + - pandas>=1.0,<2.0.0 - fsspec>=0.6.0 - setuptools # they are not needed for using pygcylon or compiling it diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index a5df3545a..d318761a0 100755 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -246,9 +246,7 @@ if (GCYLON_BUILD) return() endif () -# ucx -option(CYLON_UCX "Build Cylon with UCX" OFF) -option(CYLON_UCC "Build Cylon with UCC" OFF) + if (CYLON_UCX) message("Cylon UCX enabled") # Definition used for checking @@ -304,6 +302,18 @@ if (CYLON_UCX) include_directories(SYSTEM ${UCC_INCLUDE_DIRS}) link_directories(${UCC_LIBRARIES} ${UCC_LIBRARIES}/ucc) endif (CYLON_UCC) + + if(CYLON_USE_REDIS) + message("Cylon Redis Enabled") + add_definitions(-DBUILD_CYLON_REDIS) + + + find_library(HIREDIS_LIB hiredis HINTS ${REDIS_INSTALL_PREFIX}/lib) + find_library(REDIS_PLUS_PLUS_LIB redis++ HINTS ${REDIS_INSTALL_PREFIX}/lib) + set(REDIS_LIBRARIES + ${HIREDIS_LIB} + ${REDIS_PLUS_PLUS_LIB}) + endif (CYLON_USE_REDIS) endif (CYLON_UCX) # gloo diff --git a/cpp/src/cylon/CMakeLists.txt b/cpp/src/cylon/CMakeLists.txt index e3ee04a82..b4ab15239 100644 --- a/cpp/src/cylon/CMakeLists.txt +++ b/cpp/src/cylon/CMakeLists.txt @@ -33,7 +33,15 @@ if (CYLON_UCX) net/ucx/ucx_communicator.cpp net/ucx/ucx_operations.hpp net/ucx/ucx_operations.cpp + net/ucx/mpi_ucx_ucc_oob_context.hpp + net/ucx/mpi_ucx_ucc_oob_context.cpp ) + if (CYLON_USE_REDIS) + set(UCX_REDIS_CYLON_FILES + net/ucx/redis_ucx_ucc_oob_context.hpp + net/ucx/redis_ucx_ucc_oob_context.cpp + ) + endif(CYLON_USE_REDIS) if (CYLON_UCC) set(UCC_CYLON_FILES net/ucc/ucc_operations.hpp @@ -62,6 +70,7 @@ add_library(cylon SHARED ${UCX_CYLON_FILES} ${UCC_CYLON_FILES} ${CYLON_GLOO_FILES} + ${UCX_REDIS_CYLON_FILES} arrow/arrow_all_to_all.cpp arrow/arrow_all_to_all.hpp arrow/arrow_buffer.cpp @@ -234,11 +243,33 @@ target_link_libraries(cylon ${ARROW_DATASET_LIB}) target_link_libraries(cylon Threads::Threads) target_link_libraries(cylon ${PARQUET_LIB}) + if (CYLON_UCX) + message("Cylon UCX Enabled") target_link_libraries(cylon ${UCX_LIBRARIES}) if (CYLON_UCC) + message("Cylon UCC Enabled") target_link_libraries(cylon ucc) endif () + if(CYLON_USE_REDIS) + message("Cylon Redis Enabled") + add_definitions(-DBUILD_CYLON_REDIS) + # <------------ add hiredis dependency ---------------> + find_path(HIREDIS_HEADER hiredis HINTS ${REDIS_INSTALL_PREFIX}/include) + target_include_directories(cylon PUBLIC ${HIREDIS_HEADER}) + + #find_library(HIREDIS_LIB hiredis HINTS ${REDIS_INSTALL_PREFIX}/lib) + #target_link_libraries(cylon ${HIREDIS_LIB}) + + # <------------ add redis-plus-plus dependency --------------> + # NOTE: this should be *sw* NOT *redis++* + find_path(REDIS_PLUS_PLUS_HEADER sw HINTS ${REDIS_INSTALL_PREFIX}/include) + target_include_directories(cylon PUBLIC ${REDIS_PLUS_PLUS_HEADER}) + + #find_library(REDIS_PLUS_PLUS_LIB redis++ HINTS ${REDIS_INSTALL_PREFIX}/lib) + #target_link_libraries(cylon ${REDIS_PLUS_PLUS_LIB}) + target_link_libraries(cylon ${REDIS_LIBRARIES}) + endif() endif () if (CYLON_GLOO) diff --git a/cpp/src/cylon/ctx/cylon_context.cpp b/cpp/src/cylon/ctx/cylon_context.cpp index 963a70040..8d5bd98f2 100644 --- a/cpp/src/cylon/ctx/cylon_context.cpp +++ b/cpp/src/cylon/ctx/cylon_context.cpp @@ -54,6 +54,7 @@ Status CylonContext::InitDistributed(const std::shared_ptr(true); auto pool = (*ctx)->GetMemoryPool(); #ifdef BUILD_CYLON_UCC + // use UCC if we can return net::UCXUCCCommunicator::Make(config, pool, &(*ctx)->communicator); #else return net::UCXCommunicator::Make(config, pool, &(*ctx)->communicator); @@ -63,6 +64,20 @@ Status CylonContext::InitDistributed(const std::shared_ptr(true); + auto pool = (*ctx)->GetMemoryPool(); + return net::UCXUCCCommunicator::Make(config, pool, &(*ctx)->communicator); +#else + return {Code::NotImplemented, "UCX communication not implemented"}; +#endif +#else + return {Code::NotImplemented, "UCX communication not implemented"}; +#endif + } + case net::TCP:return {Code::NotImplemented, "TCP communication not implemented"}; case net::GLOO: { diff --git a/cpp/src/cylon/net/comm_config.hpp b/cpp/src/cylon/net/comm_config.hpp index 214fbb86e..12be0b3f8 100644 --- a/cpp/src/cylon/net/comm_config.hpp +++ b/cpp/src/cylon/net/comm_config.hpp @@ -22,15 +22,20 @@ namespace cylon { namespace net { class CommConfig { private: - std::unordered_map config; + std::unordered_map config; - protected: - void AddConfig(const std::string &key, void *value) { - this->config.insert(std::pair(key, value)); + public: + void AddConfig(const std::string &key, std::string value) { + this->config.insert(std::pair(key, value)); } - void *GetConfig(const std::string &key) { - return this->config.find(key)->second; + std::string GetConfig(const std::string &key) { + + auto iter = this->config.find(key); + if (iter == this->config.end()) { + return {}; + } + return iter->second; } public: virtual CommType Type() = 0; diff --git a/cpp/src/cylon/net/comm_type.hpp b/cpp/src/cylon/net/comm_type.hpp index d833ec0a5..1e1214918 100644 --- a/cpp/src/cylon/net/comm_type.hpp +++ b/cpp/src/cylon/net/comm_type.hpp @@ -23,7 +23,8 @@ enum CommType { MPI = 1, TCP = 2, UCX = 3, - GLOO = 4 + GLOO = 4, + UCC = 5 }; } // namespace net } // namespace cylon diff --git a/cpp/src/cylon/net/ucx/mpi_ucx_ucc_oob_context.cpp b/cpp/src/cylon/net/ucx/mpi_ucx_ucc_oob_context.cpp new file mode 100644 index 000000000..eb4b1f3d2 --- /dev/null +++ b/cpp/src/cylon/net/ucx/mpi_ucx_ucc_oob_context.cpp @@ -0,0 +1,84 @@ +#include + +namespace cylon { +namespace net { + + +Status UCXMPIOOBContext::InitOOB() { + int initialized; + MPI_Initialized(&initialized); + if (!initialized) { + RETURN_CYLON_STATUS_IF_MPI_FAILED(MPI_Init(nullptr, nullptr)); + } + return Status::OK(); +} + +Status UCXMPIOOBContext::getWorldSizeAndRank(int &world_size, int &rank) { + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + return Status::OK(); +} + +Status UCXMPIOOBContext::OOBAllgather(uint8_t *src, uint8_t *dst, + size_t srcSize, size_t dstSize) { + RETURN_CYLON_STATUS_IF_MPI_FAILED(MPI_Allgather( + src, srcSize, MPI_BYTE, dst, dstSize, MPI_BYTE, MPI_COMM_WORLD)); + return Status::OK(); +} + +Status UCXMPIOOBContext::Finalize() { + int mpi_finalized; + MPI_Finalized(&mpi_finalized); + if (!mpi_finalized) { + MPI_Finalize(); + } + return Status::OK(); +} + +#ifdef BUILD_CYLON_UCC + + +void UCCMPIOOBContext::InitOOB(int rank){ + CYLON_UNUSED(rank); +}; + +std::shared_ptr UCCMPIOOBContext::makeUCXOOBContext() { + return std::make_shared(); +} + +OOBType UCCMPIOOBContext::Type() { return OOBType::OOB_MPI; } + +void *UCCMPIOOBContext::getCollInfo() { return MPI_COMM_WORLD; } + +ucc_status_t UCCMPIOOBContext::oob_allgather(void *sbuf, void *rbuf, + size_t msglen, void *coll_info, + void **req) { + auto comm = (MPI_Comm)coll_info; + MPI_Request request; + + MPI_Iallgather(sbuf, (int)msglen, MPI_BYTE, rbuf, (int)msglen, MPI_BYTE, comm, + &request); + *req = (void *)request; + return UCC_OK; +} + +ucc_status_t UCCMPIOOBContext::oob_allgather_test(void *req) { + auto request = (MPI_Request)req; + int completed; + + MPI_Test(&request, &completed, MPI_STATUS_IGNORE); + return completed ? UCC_OK : UCC_INPROGRESS; +} + +ucc_status_t UCCMPIOOBContext::oob_allgather_free(void *req) { + (void)req; + return UCC_OK; +} + + Status UCCMPIOOBContext::Finalize() { + return Status::OK(); + } + +#endif +} // namespace net +} // namespace cylon \ No newline at end of file diff --git a/cpp/src/cylon/net/ucx/mpi_ucx_ucc_oob_context.hpp b/cpp/src/cylon/net/ucx/mpi_ucx_ucc_oob_context.hpp new file mode 100644 index 000000000..2ec98f403 --- /dev/null +++ b/cpp/src/cylon/net/ucx/mpi_ucx_ucc_oob_context.hpp @@ -0,0 +1,72 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CYLON_SRC_CYLON_COMM_UCXUCCOOBCONTEXTS_H_ +#define CYLON_SRC_CYLON_COMM_UCXUCCOOBCONTEXTS_H_ +#include +#include +#include +#include + +#include "cylon/util/macros.hpp" + +#include +#include + +#ifdef BUILD_CYLON_UCC +#include +#endif + +namespace cylon { +namespace net { + +class UCXMPIOOBContext : public UCXOOBContext { + public: + Status InitOOB() override; + + Status getWorldSizeAndRank(int &world_size, int &rank); + + Status OOBAllgather(uint8_t *src, uint8_t *dst, size_t srcSize, + size_t dstSize) override; + + Status Finalize() override; +}; + + +#ifdef BUILD_CYLON_UCC +class UCCMPIOOBContext : public UCCOOBContext { + public: + UCCMPIOOBContext() = default; + void InitOOB(int rank) override; + std::shared_ptr makeUCXOOBContext() override; + + OOBType Type() override; + + void *getCollInfo(); + + static ucc_status_t oob_allgather(void *sbuf, void *rbuf, size_t msglen, + void *coll_info, void **req); + + static ucc_status_t oob_allgather_test(void *req); + + static ucc_status_t oob_allgather_free(void *req); + + Status Finalize() override; +}; + +#endif + +} // namespace net +} // namespace cylon +#endif \ No newline at end of file diff --git a/cpp/src/cylon/net/ucx/oob_type.hpp b/cpp/src/cylon/net/ucx/oob_type.hpp new file mode 100644 index 000000000..25e7109c7 --- /dev/null +++ b/cpp/src/cylon/net/ucx/oob_type.hpp @@ -0,0 +1,27 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CYLON_OOB_TYPE_HPP +#define CYLON_OOB_TYPE_HPP + +namespace cylon { + namespace net { + enum OOBType { + OOB_MPI = 0, + OOB_REDIS = 1 + }; + } +} + +#endif //CYLON_OOB_TYPE_HPP diff --git a/cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.cpp b/cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.cpp new file mode 100644 index 000000000..2ba75e690 --- /dev/null +++ b/cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.cpp @@ -0,0 +1,146 @@ + +#include "redis_ucx_ucc_oob_context.hpp" + +namespace cylon { + namespace net { +#ifdef BUILD_CYLON_REDIS + UCXRedisOOBContext::UCXRedisOOBContext(int ws, std::string rds) + : redis(std::make_shared(rds)), world_size(ws) {} + + Status UCXRedisOOBContext::InitOOB() { return Status::OK(); }; + + Status UCXRedisOOBContext::getWorldSizeAndRank(int &world_size, int &rank) { + world_size = this->world_size; + int num_cur_processes = redis->incr("num_cur_processes"); + rank = this->rank = num_cur_processes - 1; + + return Status::OK(); + } + + Status UCXRedisOOBContext::OOBAllgather(uint8_t *src, uint8_t *dst, + size_t srcSize, size_t dstSize) { + CYLON_UNUSED(dstSize); + const auto ucc_worker_addr_mp_str = "ucp_worker_addr_mp"; + redis->hset(ucc_worker_addr_mp_str, std::to_string(rank), + std::string((char *)src, (char *)src + srcSize)); + std::vector v(world_size, 0); + redis->lpush("ucx_helper" + std::to_string(rank), v.begin(), v.end()); + + for (int i = 0; i < world_size; i++) { + if (i == rank) continue; + auto i_str = std::to_string(i); + auto helperName = "ucx_helper" + i_str; + + auto val = redis->hget(ucc_worker_addr_mp_str, i_str); + while (!val) { + redis->blpop(helperName); + val = redis->hget(ucc_worker_addr_mp_str, i_str); + } + + memcpy(dst + i * srcSize, val.value().data(), srcSize); + } + + return Status::OK(); + } + + Status UCXRedisOOBContext::Finalize() { return Status::OK(); } + + std::shared_ptr UCXRedisOOBContext::Make(int world_size, std::string redis_addr) { + return std::make_shared(world_size, redis_addr); + }; + + void UCCRedisOOBContext::InitOOB(int rank) { this->rank = rank; } + + std::shared_ptr UCCRedisOOBContext::makeUCXOOBContext() { + return std::make_shared(world_size, redis_addr); + } + + void *UCCRedisOOBContext::getCollInfo() { return this; } + + ucc_status_t UCCRedisOOBContext::oob_allgather(void *sbuf, void *rbuf, + size_t msglen, void *coll_info, + void **req) { + int world_size = ((UCCRedisOOBContext *)coll_info)->world_size; + int rank = ((UCCRedisOOBContext *)coll_info)->rank; + int num_comm = ((UCCRedisOOBContext *)coll_info)->num_oob_allgather; + ((UCCRedisOOBContext *)coll_info)->num_oob_allgather++; + + auto &redis = ((UCCRedisOOBContext *)coll_info)->redis; + *req = rbuf; + std::string s((char *)sbuf, ((char *)sbuf) + msglen); + + redis->hset("ucc_oob_mp" + std::to_string(num_comm), std::to_string(rank), s); + redis->lpush( + "ucc_helper" + std::to_string(num_comm) + ":" + std::to_string(rank), + "0"); + + for (int i = 0; i < world_size; i++) { + if (i == rank) { + memcpy((uint8_t*)rbuf + i * msglen, s.data(), msglen); + } else { + auto helperName = + "ucc_helper" + std::to_string(num_comm) + ":" + std::to_string(i); + + // val = redis.hget("ucp_worker_addr_mp", std::to_string(i)); + sw::redis::OptionalString val; + do { + redis->brpoplpush(helperName, helperName, 0); + val = redis->hget("ucc_oob_mp" + std::to_string(num_comm), + std::to_string(i)); + } while (!val); + + memcpy((uint8_t*)rbuf + i * msglen, val.value().data(), msglen); + } + } + + return UCC_OK; + } + + UCCRedisOOBContext::UCCRedisOOBContext(int ws, + std::string rds) + : world_size(ws), redis(std::make_shared(rds)), redis_addr(rds) {} + + UCCRedisOOBContext::UCCRedisOOBContext() { + redis_addr = "tcp://" + std::string(getenv("CYLON_UCX_OOB_REDIS_ADDR")); + world_size = std::atoi(getenv("CYLON_UCX_OOB_WORLD_SIZE")); + redis = std::make_shared(redis_addr); + } + + ucc_status_t UCCRedisOOBContext::oob_allgather_test(void *req) { + CYLON_UNUSED(req); + return UCC_OK; + } + + ucc_status_t UCCRedisOOBContext::oob_allgather_free(void *req) { + CYLON_UNUSED(req); + return UCC_OK; + } + + OOBType UCCRedisOOBContext::Type() { return OOBType::OOB_REDIS; } + + std::shared_ptr UCCRedisOOBContext::getRedis() { + return this->redis; + } + + int UCCRedisOOBContext::getWorldSize() { return world_size; } + + void UCCRedisOOBContext::setRank(int rk) { rank = rk; } + + int UCCRedisOOBContext::getRank() { return rank; } + + std::shared_ptr UCCRedisOOBContext::Make(int world_size, std::string redis_addr) { + return std::make_shared(world_size, redis_addr); + } + + Status UCCRedisOOBContext::Finalize() { + + return Status::OK(); + + } + + + +#endif + + } +} \ No newline at end of file diff --git a/cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.hpp b/cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.hpp new file mode 100644 index 000000000..cdd7f79c9 --- /dev/null +++ b/cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.hpp @@ -0,0 +1,117 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CYLON_REDIS_UCX_UCC_OOB_CONTEXT_HPP +#define CYLON_REDIS_UCX_UCC_OOB_CONTEXT_HPP + +#include +#include +#include +#include + +#include "cylon/util/macros.hpp" + +#include +#include + +#ifdef BUILD_CYLON_REDIS + +#include "sw/redis++/redis++.h" + +#endif + +#ifdef BUILD_CYLON_UCC + +#include + +#endif + +namespace cylon { + namespace net { +#ifdef BUILD_CYLON_REDIS + + class UCXRedisOOBContext : public UCXOOBContext { + public: + UCXRedisOOBContext(int world_size, std::string redis_addr); + + Status InitOOB() override; + + Status getWorldSizeAndRank(int &world_size, int &rank) override; + + Status OOBAllgather(uint8_t *src, uint8_t *dst, size_t srcSize, + size_t dstSize) override; + + Status Finalize(); + + static std::shared_ptr Make(int world_size, std::string redis_addr); + + private: + std::shared_ptr redis; + int world_size; + int rank = -1; + }; + + class UCCRedisOOBContext : public UCCOOBContext { + public: + void InitOOB(int rank) override; + + std::shared_ptr makeUCXOOBContext() override; + + void *getCollInfo() override; + + OOBType Type() override; + + UCCRedisOOBContext(int world_size, std::string redis_addr); + + static std::shared_ptr Make(int world_size, std::string redis_addr); + + /*** + * This constructor is used with python script `run_ucc_with_redis.py` + * Extracts environment variables set by the script and initializes metadata + */ + UCCRedisOOBContext(); + + static ucc_status_t oob_allgather(void *sbuf, void *rbuf, size_t msglen, + void *coll_info, void **req); + + static ucc_status_t oob_allgather_test(void *req); + + static ucc_status_t oob_allgather_free(void *req); + + std::shared_ptr getRedis(); + + int getWorldSize(); + + void setRank(int rk); + + int getRank(); + + Status Finalize() override; + + private: + int world_size; + int rank = -1; + std::shared_ptr redis; + int num_oob_allgather = 0; + std::string redis_addr; + }; + +#endif + + + } +} + + +#endif //CYLON_REDIS_UCX_UCC_OOB_CONTEXT_HPP diff --git a/cpp/src/cylon/net/ucx/ucc_oob_context.hpp b/cpp/src/cylon/net/ucx/ucc_oob_context.hpp new file mode 100644 index 000000000..0dd96e0c9 --- /dev/null +++ b/cpp/src/cylon/net/ucx/ucc_oob_context.hpp @@ -0,0 +1,47 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CYLON_UCC_OOB_CONTEXT_HPP +#define CYLON_UCC_OOB_CONTEXT_HPP + +#include +#include +#include +#include +#include "cylon/util/macros.hpp" +#include + + +namespace cylon { + namespace net { +#ifdef BUILD_CYLON_UCC + + class UCCOOBContext { + public: + virtual OOBType Type() = 0; + + virtual std::shared_ptr makeUCXOOBContext() = 0; + + virtual void InitOOB(int rank) = 0; + + virtual void *getCollInfo() = 0; + + virtual Status Finalize() = 0; + }; + +#endif + } +} + +#endif //CYLON_UCC_OOB_CONTEXT_HPP diff --git a/cpp/src/cylon/net/ucx/ucx_communicator.cpp b/cpp/src/cylon/net/ucx/ucx_communicator.cpp index 0a8e6e339..36a71bd60 100644 --- a/cpp/src/cylon/net/ucx/ucx_communicator.cpp +++ b/cpp/src/cylon/net/ucx/ucx_communicator.cpp @@ -12,11 +12,13 @@ * limitations under the License. */ -#include +#include "cylon/net/ucx/ucx_communicator.hpp" + #include +#include + #include "cylon/net/communicator.hpp" -#include "cylon/net/ucx/ucx_communicator.hpp" #include "cylon/net/ucx/ucx_channel.hpp" #include "cylon/util/macros.hpp" @@ -24,6 +26,10 @@ #include "cylon/net/ucc/ucc_operations.hpp" #endif +#ifdef BUILD_CYLON_REDIS +#include "cylon/net/ucx/redis_ucx_ucc_oob_context.hpp" +#endif + namespace cylon { namespace net { @@ -37,39 +43,76 @@ void mpi_check_and_finalize() { } } -CommType UCXConfig::Type() { - return CommType::UCX; +CommType UCXConfig::Type() { return CommType::UCX; } + +UCXConfig::UCXConfig(std::shared_ptr oobContext) { + this->oobContext = oobContext; +} + +std::shared_ptr UCXConfig::Make( + std::shared_ptr oobContext) { + return std::make_shared(oobContext); } std::shared_ptr UCXConfig::Make(MPI_Comm comm) { - return std::make_shared(comm); + return std::make_shared(comm); } UCXConfig::UCXConfig(MPI_Comm comm) : comm_(comm) {} MPI_Comm UCXConfig::GetMPIComm() const { return comm_; } -std::unique_ptr UCXCommunicator::CreateChannel() const { - return std::make_unique(this); +void UCXConfig::setOOBContext(std::shared_ptr oobContext) { + this->oobContext = oobContext; } -int UCXCommunicator::GetRank() const { - return this->rank; +std::shared_ptr UCXConfig::getOOBContext() { + return this->oobContext; } -int UCXCommunicator::GetWorldSize() const { - return this->world_size; + +#ifdef BUILD_CYLON_UCC +CommType UCCConfig::Type() { return CommType::UCC; } + +UCCConfig::UCCConfig(std::shared_ptr oob_context) + : oobContext(oob_context) {} + +std::shared_ptr UCCConfig::Make( + std::shared_ptr &oob_context) { + return std::make_shared(oob_context); } -Status UCXCommunicator::AllGather(const std::shared_ptr &table, - std::vector> *out) const { +void UCCConfig::setOOBContext(std::shared_ptr oobContext) { + this->oobContext = oobContext; +} + +std::shared_ptr UCCConfig::getOOBContext() { return oobContext; } + + UCCConfig::~UCCConfig() { + auto context = this->oobContext.get(); + if (context != nullptr) { + context->Finalize(); + } + } + + +#endif + +std::unique_ptr UCXCommunicator::CreateChannel() const { + return std::make_unique(this); +} +int UCXCommunicator::GetRank() const { return this->rank; } +int UCXCommunicator::GetWorldSize() const { return this->world_size; } + +Status UCXCommunicator::AllGather( + const std::shared_ptr
&table, + std::vector> *out) const { CYLON_UNUSED(table); CYLON_UNUSED(out); return {Code::NotImplemented, "All gather not implemented for ucx"}; } Status UCXCommunicator::Gather(const std::shared_ptr
&table, - int gather_root, - bool gather_from_root, + int gather_root, bool gather_from_root, std::vector> *out) const { CYLON_UNUSED(table); CYLON_UNUSED(gather_root); @@ -95,9 +138,12 @@ Status UCXCommunicator::AllReduce(const std::shared_ptr &column, return {Code::NotImplemented, "Allreduce not implemented for ucx"}; } +UCXCommunicator::UCXCommunicator(MemoryPool *pool) + : Communicator(pool, -1, -1) {} + UCXCommunicator::UCXCommunicator(MemoryPool *pool, bool externally_init, MPI_Comm comm) - : Communicator(pool, -1, -1), - externally_init(externally_init), mpi_comm(comm) {} + : Communicator(pool, -1, -1), + externally_init(externally_init), mpi_comm(comm) {} Status UCXCommunicator::AllReduce(const std::shared_ptr &values, net::ReduceOp reduce_op, @@ -108,8 +154,9 @@ Status UCXCommunicator::AllReduce(const std::shared_ptr &values, return {Code::NotImplemented, "Allreduce not implemented for ucx"}; } -Status UCXCommunicator::Allgather(const std::shared_ptr &values, - std::vector> *output) const { +Status UCXCommunicator::Allgather( + const std::shared_ptr &values, + std::vector> *output) const { CYLON_UNUSED(values); CYLON_UNUSED(output); return {Code::NotImplemented, "Allgather not implemented for ucx"}; @@ -122,100 +169,193 @@ Status UCXCommunicator::Allgather(const std::shared_ptr &value, return {Code::NotImplemented, "Allgather not implemented for ucx"}; } -Status UCXCommunicator::Make(const std::shared_ptr &config, MemoryPool *pool, - std::shared_ptr *out) { - const auto &mpi_config = std::static_pointer_cast(config); - auto mpi_comm = mpi_config->GetMPIComm(); - - // MPI init - int initialized; - MPI_Initialized(&initialized); - if (!initialized) { - RETURN_CYLON_STATUS_IF_MPI_FAILED(MPI_Init(nullptr, nullptr)); - } +Status UCXCommunicator::MakeOOB(const std::shared_ptr &config, MemoryPool *pool, + std::shared_ptr *out) { + const auto &ucc_config = std::static_pointer_cast(config); + auto oob_context = ucc_config->getOOBContext(); + + *out = std::make_shared(pool); + auto &comm = static_cast(**out); + comm.oobContext = oob_context; + + // Int variable used when iterating + int sIndx; + // Address of the UCP Worker for receiving + cylon::ucx::ucxWorkerAddr *ucpRecvWorkerAddr; + // Address of the UCP Worker for sending + cylon::ucx::ucxWorkerAddr *ucpSendWorkerAddr; + + // Status check when creating end-points + ucs_status_t ucxStatus; + // Variable to hold the current ucp address + ucp_address_t *address; + + RETURN_CYLON_STATUS_IF_FAILED(oob_context->InitOOB()); + + // Get the rank for checking send to self, and initializations + RETURN_CYLON_STATUS_IF_FAILED( + oob_context->getWorldSizeAndRank(comm.world_size, comm.rank)); + + int rank = comm.rank, world_size = comm.world_size; + + // Init context + RETURN_CYLON_STATUS_IF_FAILED( + cylon::ucx::initContext(&comm.ucpContext, nullptr)); + + // Init recv worker and get address + ucpRecvWorkerAddr = + cylon::ucx::initWorker(comm.ucpContext, &comm.ucpRecvWorker); + // Init send worker + ucpSendWorkerAddr = + cylon::ucx::initWorker(comm.ucpContext, &comm.ucpSendWorker); + + // Gather all worker addresses + // All addresses buffer for allGather + auto allAddresses = + std::make_unique(ucpRecvWorkerAddr->addrSize * world_size); + + RETURN_CYLON_STATUS_IF_FAILED(oob_context->OOBAllgather( + (uint8_t *)ucpRecvWorkerAddr->addr, allAddresses.get(), + (int)ucpRecvWorkerAddr->addrSize, (int)ucpRecvWorkerAddr->addrSize)); + + // Iterate and set the sends + comm.endPointMap.reserve(world_size); + for (sIndx = 0; sIndx < world_size; sIndx++) { + ucp_ep_params_t epParams; + ucp_ep_h ep; + + // If not self, then check if the worker address has been received. + // If self,then assign local worker + if (rank != sIndx) { + address = reinterpret_cast( + allAddresses.get() + sIndx * ucpRecvWorkerAddr->addrSize); + } else { + address = ucpRecvWorkerAddr->addr; + } + + // Set params for the endpoint + epParams.field_mask = UCP_EP_PARAM_FIELD_REMOTE_ADDRESS | + UCP_EP_PARAM_FIELD_ERR_HANDLING_MODE; + epParams.address = address; + epParams.err_mode = UCP_ERR_HANDLING_MODE_NONE; + + // Create an endpoint + ucxStatus = ucp_ep_create(comm.ucpSendWorker, &epParams, &ep); + + comm.endPointMap[sIndx] = ep; + // Check if the endpoint was created properly + if (ucxStatus != UCS_OK) { + LOG(FATAL) << "Error when creating the endpoint."; + return {Code::ExecutionError, + "Error when creating the endpoint: " + + std::string(ucs_status_string(ucxStatus))}; + } + } - if (mpi_comm == MPI_COMM_NULL) { - mpi_comm = MPI_COMM_WORLD; - } + // Cleanup + delete (ucpRecvWorkerAddr); + delete (ucpSendWorkerAddr); - *out = std::make_shared(pool, initialized, mpi_comm); - auto &comm = dynamic_cast(**out); - - // Int variable used when iterating - int sIndx; - // Address of the UCP Worker for receiving - cylon::ucx::ucxWorkerAddr *ucpRecvWorkerAddr; - // Address of the UCP Worker for sending - cylon::ucx::ucxWorkerAddr *ucpSendWorkerAddr; - - // Status check when creating end-points - ucs_status_t ucxStatus; - // Variable to hold the current ucp address - ucp_address_t *address; - - // Get the rank for checking send to self, and initializations - MPI_Comm_rank(mpi_comm, &comm.rank); - MPI_Comm_size(mpi_comm, &comm.world_size); - - int rank = comm.rank, world_size = comm.world_size; - - // Init context - RETURN_CYLON_STATUS_IF_FAILED(cylon::ucx::initContext(&comm.ucpContext, nullptr)); - - // Init recv worker and get address - ucpRecvWorkerAddr = cylon::ucx::initWorker(comm.ucpContext, &comm.ucpRecvWorker); - // Init send worker - ucpSendWorkerAddr = cylon::ucx::initWorker(comm.ucpContext, &comm.ucpSendWorker); - - // Gather all worker addresses - // All addresses buffer for allGather - auto allAddresses = std::make_unique(ucpRecvWorkerAddr->addrSize * world_size); - RETURN_CYLON_STATUS_IF_MPI_FAILED(MPI_Allgather(ucpRecvWorkerAddr->addr, - (int) ucpRecvWorkerAddr->addrSize, - MPI_BYTE, - allAddresses.get(), - (int) ucpRecvWorkerAddr->addrSize, - MPI_BYTE, - mpi_comm)); - - // Iterate and set the sends - comm.endPointMap.reserve(world_size); - for (sIndx = 0; sIndx < world_size; sIndx++) { - ucp_ep_params_t epParams; - ucp_ep_h ep; - - // If not self, then check if the worker address has been received. - // If self,then assign local worker - if (rank != sIndx) { - address = reinterpret_cast(allAddresses.get() - + sIndx * ucpRecvWorkerAddr->addrSize); - } else { - address = ucpRecvWorkerAddr->addr; + return Status::OK(); +} + + + +Status UCXCommunicator::Make(const std::shared_ptr &config, + MemoryPool *pool, + std::shared_ptr *out) { + const auto &mpi_config = std::static_pointer_cast(config); + auto mpi_comm = mpi_config->GetMPIComm(); + + // MPI init + int initialized; + MPI_Initialized(&initialized); + if (!initialized) { + RETURN_CYLON_STATUS_IF_MPI_FAILED(MPI_Init(nullptr, nullptr)); } - // Set params for the endpoint - epParams.field_mask = UCP_EP_PARAM_FIELD_REMOTE_ADDRESS | - UCP_EP_PARAM_FIELD_ERR_HANDLING_MODE; - epParams.address = address; - epParams.err_mode = UCP_ERR_HANDLING_MODE_NONE; - - // Create an endpoint - ucxStatus = ucp_ep_create(comm.ucpSendWorker, &epParams, &ep); - - comm.endPointMap[sIndx] = ep; - // Check if the endpoint was created properly - if (ucxStatus != UCS_OK) { - LOG(FATAL) << "Error when creating the endpoint."; - return {Code::ExecutionError, - "Error when creating the endpoint: " + std::string(ucs_status_string(ucxStatus))}; + if (mpi_comm == MPI_COMM_NULL) { + mpi_comm = MPI_COMM_WORLD; } - } - // Cleanup - delete (ucpRecvWorkerAddr); - delete (ucpSendWorkerAddr); + *out = std::make_shared(pool, initialized, mpi_comm); + auto &comm = dynamic_cast(**out); + + // Int variable used when iterating + int sIndx; + // Address of the UCP Worker for receiving + cylon::ucx::ucxWorkerAddr *ucpRecvWorkerAddr; + // Address of the UCP Worker for sending + cylon::ucx::ucxWorkerAddr *ucpSendWorkerAddr; + + // Status check when creating end-points + ucs_status_t ucxStatus; + // Variable to hold the current ucp address + ucp_address_t *address; + + // Get the rank for checking send to self, and initializations + MPI_Comm_rank(mpi_comm, &comm.rank); + MPI_Comm_size(mpi_comm, &comm.world_size); + + int rank = comm.rank, world_size = comm.world_size; + + // Init context + RETURN_CYLON_STATUS_IF_FAILED(cylon::ucx::initContext(&comm.ucpContext, nullptr)); + + // Init recv worker and get address + ucpRecvWorkerAddr = cylon::ucx::initWorker(comm.ucpContext, &comm.ucpRecvWorker); + // Init send worker + ucpSendWorkerAddr = cylon::ucx::initWorker(comm.ucpContext, &comm.ucpSendWorker); + + // Gather all worker addresses + // All addresses buffer for allGather + auto allAddresses = std::make_unique(ucpRecvWorkerAddr->addrSize * world_size); + RETURN_CYLON_STATUS_IF_MPI_FAILED(MPI_Allgather(ucpRecvWorkerAddr->addr, + (int) ucpRecvWorkerAddr->addrSize, + MPI_BYTE, + allAddresses.get(), + (int) ucpRecvWorkerAddr->addrSize, + MPI_BYTE, + mpi_comm)); + + // Iterate and set the sends + comm.endPointMap.reserve(world_size); + for (sIndx = 0; sIndx < world_size; sIndx++) { + ucp_ep_params_t epParams; + ucp_ep_h ep; + + // If not self, then check if the worker address has been received. + // If self,then assign local worker + if (rank != sIndx) { + address = reinterpret_cast(allAddresses.get() + + sIndx * ucpRecvWorkerAddr->addrSize); + } else { + address = ucpRecvWorkerAddr->addr; + } + + // Set params for the endpoint + epParams.field_mask = UCP_EP_PARAM_FIELD_REMOTE_ADDRESS | + UCP_EP_PARAM_FIELD_ERR_HANDLING_MODE; + epParams.address = address; + epParams.err_mode = UCP_ERR_HANDLING_MODE_NONE; + + // Create an endpoint + ucxStatus = ucp_ep_create(comm.ucpSendWorker, &epParams, &ep); + + comm.endPointMap[sIndx] = ep; + // Check if the endpoint was created properly + if (ucxStatus != UCS_OK) { + LOG(FATAL) << "Error when creating the endpoint."; + return {Code::ExecutionError, + "Error when creating the endpoint: " + std::string(ucs_status_string(ucxStatus))}; + } + } - return Status::OK(); + // Cleanup + delete (ucpRecvWorkerAddr); + delete (ucpSendWorkerAddr); + + return Status::OK(); } void UCXCommunicator::Finalize() { @@ -234,6 +374,8 @@ CommType UCXCommunicator::GetCommType() const { return UCX; } + + #ifdef BUILD_CYLON_UCC static ucc_status_t oob_allgather(void *sbuf, void *rbuf, size_t msglen, @@ -260,85 +402,207 @@ static ucc_status_t oob_allgather_free(void *req) { return UCC_OK; } -UCXUCCCommunicator::UCXUCCCommunicator(const std::shared_ptr &ucx_comm) - : Communicator(ucx_comm->GetMemoryPool(), ucx_comm->GetRank(), ucx_comm->GetWorldSize()), - ucx_comm_(std::static_pointer_cast(ucx_comm)) {} + UCXUCCCommunicator::UCXUCCCommunicator(const std::shared_ptr &ucx_comm) + : Communicator(ucx_comm->GetMemoryPool(), ucx_comm->GetRank(), ucx_comm->GetWorldSize()), + ucx_comm_(std::static_pointer_cast(ucx_comm)) {} + + + + + +UCXUCCCommunicator::UCXUCCCommunicator( + std::shared_ptr ucx_comm, + std::shared_ptr &oob_context) + : Communicator(ucx_comm->GetMemoryPool(), ucx_comm->GetRank(), + ucx_comm->GetWorldSize()), + ucx_comm_(std::static_pointer_cast(ucx_comm)), + oobContext(oob_context) {} + +Status UCXUCCCommunicator::MakeOOB(std::shared_ptr &ucc_oob_ctx, + MemoryPool *pool, std::shared_ptr *out) { + std::shared_ptr ucx_comm; + auto ucx_config = + std::make_shared(ucc_oob_ctx->makeUCXOOBContext()); + + UCXCommunicator::MakeOOB(ucx_config, pool, &ucx_comm); + + *out = std::make_shared(std::move(ucx_comm), ucc_oob_ctx); + + auto &comm = *std::static_pointer_cast(*out); + comm.oobContext = ucc_oob_ctx; + comm.oobContext->InitOOB(comm.GetRank()); + + // initialize UCC team and context + ucc_context_params_t ctx_params; + ucc_team_params_t team_params; + ucc_context_config_h ctx_config; + ucc_status_t status; + ucc_lib_h lib; + ucc_lib_config_h lib_config; + + // init ucc lib + ucc_lib_params_t lib_params = {.mask = UCC_LIB_PARAM_FIELD_THREAD_MODE, + .thread_mode = UCC_THREAD_SINGLE, + .coll_types = {}, + .reduction_types = {}, + .sync_type = {}}; + + RETURN_CYLON_STATUS_IF_UCC_FAILED( + ucc_lib_config_read(nullptr, nullptr, &lib_config)); + RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_init(&lib_params, lib_config, &lib)); + ucc_lib_config_release(lib_config); + + // init ucc context + ctx_params.mask = UCC_CONTEXT_PARAM_FIELD_OOB; + + if (ucc_oob_ctx->Type() == OOBType::OOB_REDIS) { +#ifdef BUILD_CYLON_REDIS + ctx_params.oob.allgather = team_params.oob.allgather = + UCCRedisOOBContext::oob_allgather; + ctx_params.oob.req_test = team_params.oob.req_test = + UCCRedisOOBContext::oob_allgather_test; + ctx_params.oob.req_free = team_params.oob.req_free = + UCCRedisOOBContext::oob_allgather_free; +#else + ctx_params.oob.allgather = team_params.oob.allgather = + UCCMPIOOBContext::oob_allgather; + ctx_params.oob.req_test = team_params.oob.req_test = + UCCMPIOOBContext::oob_allgather_test; + ctx_params.oob.req_free = team_params.oob.req_free = + UCCMPIOOBContext::oob_allgather_free; +#endif + } else if (ucc_oob_ctx->Type() == OOBType::OOB_MPI) { + ctx_params.oob.allgather = team_params.oob.allgather = + UCCMPIOOBContext::oob_allgather; + ctx_params.oob.req_test = team_params.oob.req_test = + UCCMPIOOBContext::oob_allgather_test; + ctx_params.oob.req_free = team_params.oob.req_free = + UCCMPIOOBContext::oob_allgather_free; + } else { + return {Code::NotImplemented, "UCC OOB communication type not supported."}; + } + + ctx_params.oob.coll_info = ucc_oob_ctx->getCollInfo(); + + ctx_params.oob.n_oob_eps = static_cast(comm.GetWorldSize()); + ctx_params.oob.oob_ep = static_cast(comm.GetRank()); + + RETURN_CYLON_STATUS_IF_UCC_FAILED( + ucc_context_config_read(lib, nullptr, &ctx_config)); + + RETURN_CYLON_STATUS_IF_UCC_FAILED( + ucc_context_create(lib, &ctx_params, ctx_config, &comm.uccContext)); + + ucc_context_config_release(ctx_config); + + // init ucc team + team_params.mask = UCC_TEAM_PARAM_FIELD_OOB; + + team_params.oob.coll_info = ucc_oob_ctx->getCollInfo(); + + team_params.oob.n_oob_eps = static_cast(comm.GetWorldSize()); + team_params.oob.oob_ep = static_cast(comm.GetRank()); + RETURN_CYLON_STATUS_IF_UCC_FAILED( + ucc_team_create_post(&comm.uccContext, 1, &team_params, &comm.uccTeam)); + + while (UCC_INPROGRESS == (status = ucc_team_create_test(comm.uccTeam))) { + // RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_context_progress(comm.uccContext)); + } + + RETURN_CYLON_STATUS_IF_UCC_FAILED(status); + return Status::OK(); + +} + Status UCXUCCCommunicator::Make(const std::shared_ptr &config, MemoryPool *pool, std::shared_ptr *out) { - std::shared_ptr ucx_comm; - RETURN_CYLON_STATUS_IF_FAILED(UCXCommunicator::Make(config, pool, &ucx_comm)); - - *out = std::make_shared(std::move(ucx_comm)); - auto &comm = *std::static_pointer_cast(*out); + auto ucc_config = std::static_pointer_cast(config); + auto ucc_oob_ctx = ucc_config->getOOBContext(); - auto mpi_comm = comm.ucx_comm_->mpi_comm; + if (ucc_oob_ctx != nullptr) { //call MPI Com + return UCXUCCCommunicator::MakeOOB(ucc_oob_ctx, pool, out); + } - // initialize UCC team and context - ucc_context_params_t ctx_params; - ucc_team_params_t team_params; - ucc_context_config_h ctx_config; - ucc_status_t status; - ucc_lib_h lib; - ucc_lib_config_h lib_config; - - // init ucc lib - ucc_lib_params_t lib_params = {.mask = UCC_LIB_PARAM_FIELD_THREAD_MODE, - .thread_mode = UCC_THREAD_SINGLE, - .coll_types = {}, - .reduction_types = {}, - .sync_type = {}}; - - RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_lib_config_read(nullptr, nullptr, &lib_config)); - RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_init(&lib_params, lib_config, &lib)); - ucc_lib_config_release(lib_config); - - // init ucc context - ctx_params.mask = UCC_CONTEXT_PARAM_FIELD_OOB; - ctx_params.oob.allgather = oob_allgather; - ctx_params.oob.req_test = oob_allgather_test; - ctx_params.oob.req_free = oob_allgather_free; - ctx_params.oob.coll_info = (void *) mpi_comm; - ctx_params.oob.n_oob_eps = static_cast(comm.GetWorldSize()); - ctx_params.oob.oob_ep = static_cast(comm.GetRank()); - - RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_context_config_read(lib, nullptr, &ctx_config)); - - RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_context_create(lib, &ctx_params, ctx_config, - &comm.uccContext)); - ucc_context_config_release(ctx_config); - - // init ucc team - team_params.mask = UCC_TEAM_PARAM_FIELD_OOB; - team_params.oob.allgather = oob_allgather; - team_params.oob.req_test = oob_allgather_test; - team_params.oob.req_free = oob_allgather_free; - team_params.oob.coll_info = (void *) mpi_comm; - team_params.oob.n_oob_eps = static_cast(comm.GetWorldSize()); - team_params.oob.oob_ep = static_cast(comm.GetRank()); - RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_team_create_post(&comm.uccContext, 1, &team_params, - &comm.uccTeam)); - while (UCC_INPROGRESS == (status = ucc_team_create_test(comm.uccTeam))) { + std::shared_ptr ucx_comm; + RETURN_CYLON_STATUS_IF_FAILED(UCXCommunicator::Make(config, pool, &ucx_comm)); + + *out = std::make_shared(std::move(ucx_comm)); + auto &comm = *std::static_pointer_cast(*out); + + auto mpi_comm = comm.ucx_comm_->mpi_comm; + + // initialize UCC team and context + ucc_context_params_t ctx_params; + ucc_team_params_t team_params; + ucc_context_config_h ctx_config; + ucc_status_t status; + ucc_lib_h lib; + ucc_lib_config_h lib_config; + + // init ucc lib + ucc_lib_params_t lib_params = {.mask = UCC_LIB_PARAM_FIELD_THREAD_MODE, + .thread_mode = UCC_THREAD_SINGLE, + .coll_types = {}, + .reduction_types = {}, + .sync_type = {}}; + + RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_lib_config_read(nullptr, nullptr, &lib_config)); + RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_init(&lib_params, lib_config, &lib)); + ucc_lib_config_release(lib_config); + + // init ucc context + ctx_params.mask = UCC_CONTEXT_PARAM_FIELD_OOB; + ctx_params.oob.allgather = oob_allgather; + ctx_params.oob.req_test = oob_allgather_test; + ctx_params.oob.req_free = oob_allgather_free; + ctx_params.oob.coll_info = (void *) mpi_comm; + ctx_params.oob.n_oob_eps = static_cast(comm.GetWorldSize()); + ctx_params.oob.oob_ep = static_cast(comm.GetRank()); + + RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_context_config_read(lib, nullptr, &ctx_config)); + + RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_context_create(lib, &ctx_params, ctx_config, + &comm.uccContext)); + ucc_context_config_release(ctx_config); + + // init ucc team + team_params.mask = UCC_TEAM_PARAM_FIELD_OOB; + team_params.oob.allgather = oob_allgather; + team_params.oob.req_test = oob_allgather_test; + team_params.oob.req_free = oob_allgather_free; + team_params.oob.coll_info = (void *) mpi_comm; + team_params.oob.n_oob_eps = static_cast(comm.GetWorldSize()); + team_params.oob.oob_ep = static_cast(comm.GetRank()); + RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_team_create_post(&comm.uccContext, 1, &team_params, + &comm.uccTeam)); + while (UCC_INPROGRESS == (status = ucc_team_create_test(comm.uccTeam))) { // RETURN_CYLON_STATUS_IF_UCC_FAILED(ucc_context_progress(comm.uccContext)); - } + } - RETURN_CYLON_STATUS_IF_UCC_FAILED(status); - return Status::OK(); + RETURN_CYLON_STATUS_IF_UCC_FAILED(status); + return Status::OK(); } -CommType UCXUCCCommunicator::GetCommType() const { - return UCX; -} +CommType UCXUCCCommunicator::GetCommType() const { return UCX; } std::unique_ptr UCXUCCCommunicator::CreateChannel() const { return ucx_comm_->CreateChannel(); } void UCXUCCCommunicator::Finalize() { - if (!IsFinalized()) { + if (!this->IsFinalized()) { + + auto uccoobCtx = oobContext.get(); + + if (uccoobCtx != nullptr) { + uccoobCtx->Finalize(); + } + ucc_status_t status; - while (uccTeam && (UCC_INPROGRESS == (status = ucc_team_destroy(uccTeam)))) { + while (uccTeam && + (UCC_INPROGRESS == (status = ucc_team_destroy(uccTeam)))) { if (UCC_OK != status) { LOG(ERROR) << "ucc_team_destroy failed"; break; @@ -349,6 +613,9 @@ void UCXUCCCommunicator::Finalize() { ucc_context_destroy(uccContext); } + + + ucx_comm_->Finalize(); // this will handle MPI_Finalize finalized = true; } diff --git a/cpp/src/cylon/net/ucx/ucx_communicator.hpp b/cpp/src/cylon/net/ucx/ucx_communicator.hpp index 3e9eae897..b3e9e234f 100644 --- a/cpp/src/cylon/net/ucx/ucx_communicator.hpp +++ b/cpp/src/cylon/net/ucx/ucx_communicator.hpp @@ -18,8 +18,11 @@ #include #include #include +#include + + +#include "cylon/util/macros.hpp" -#include #ifdef BUILD_CYLON_UCC #include @@ -27,28 +30,61 @@ namespace cylon { namespace net { - class UCXConfig : public CommConfig { + + public: + CommType Type() override; + explicit UCXConfig(std::shared_ptr oobContext); explicit UCXConfig(MPI_Comm comm = MPI_COMM_NULL); - ~UCXConfig() override = default; - CommType Type() override; - - MPI_Comm GetMPIComm() const; + static std::shared_ptr Make( + std::shared_ptr oobContext); static std::shared_ptr Make(MPI_Comm comm = MPI_COMM_NULL); + void setOOBContext(std::shared_ptr oobContext); + + std::shared_ptr getOOBContext(); + MPI_Comm GetMPIComm() const; private: + std::shared_ptr oobContext = nullptr; MPI_Comm comm_; }; +#ifdef BUILD_CYLON_UCC +class UCCConfig : public CommConfig { + + + public: + CommType Type() override; + + ~UCCConfig() override; + + explicit UCCConfig(std::shared_ptr oobContext); + static std::shared_ptr Make( + std::shared_ptr &oobContext); + void setOOBContext(std::shared_ptr oobContext); + std::shared_ptr getOOBContext(); + + private: + std::shared_ptr oobContext; +}; +#endif + class UCXCommunicator : public Communicator { public: - UCXCommunicator(MemoryPool *pool, bool externally_init, MPI_Comm comm); - ~UCXCommunicator() override = default; + explicit UCXCommunicator(MemoryPool *pool); + UCXCommunicator(MemoryPool *pool, bool externally_init, MPI_Comm comm); - std::unique_ptr CreateChannel() const override; + + + + ~UCXCommunicator() override = default; + + + + std::unique_ptr CreateChannel() const override; int GetRank() const override; int GetWorldSize() const override; void Finalize() override; @@ -57,8 +93,7 @@ class UCXCommunicator : public Communicator { Status AllGather(const std::shared_ptr
&table, std::vector> *out) const override; - Status Gather(const std::shared_ptr
&table, - int gather_root, + Status Gather(const std::shared_ptr
&table, int gather_root, bool gather_from_root, std::vector> *out) const override; Status Bcast(std::shared_ptr
*table, int bcast_root, @@ -74,11 +109,14 @@ class UCXCommunicator : public Communicator { Status Allgather(const std::shared_ptr &value, std::shared_ptr *output) const override; - static Status Make(const std::shared_ptr &config, MemoryPool *pool, - std::shared_ptr *out); + static Status Make(const std::shared_ptr &config, + MemoryPool *pool, std::shared_ptr *out); + + static Status MakeOOB(const std::shared_ptr &config, + MemoryPool *pool, std::shared_ptr *out); - // # UCX specific attributes - These need to be passed to the channels created from the communicator - // The worker for receiving + // # UCX specific attributes - These need to be passed to the channels created + // from the communicator The worker for receiving ucp_worker_h ucpRecvWorker{}; // The worker for sending ucp_worker_h ucpSendWorker{}; @@ -86,17 +124,29 @@ class UCXCommunicator : public Communicator { std::unordered_map endPointMap; // UCP Context - Holds a UCP communication instance's global information. ucp_context_h ucpContext{}; - bool externally_init = false; - MPI_Comm mpi_comm; + + std::shared_ptr oobContext = nullptr; + + bool externally_init = false; + MPI_Comm mpi_comm; + }; #ifdef BUILD_CYLON_UCC class UCXUCCCommunicator : public Communicator { public: + explicit UCXUCCCommunicator(std::shared_ptr ucx_comm, + std::shared_ptr &oobContext); + explicit UCXUCCCommunicator(const std::shared_ptr& ucx_comm); - static Status Make(const std::shared_ptr &config, MemoryPool *pool, - std::shared_ptr *out); + + + static Status Make(const std::shared_ptr &config, + MemoryPool *pool, std::shared_ptr *out); + + + CommType GetCommType() const override; std::unique_ptr CreateChannel() const override; @@ -104,12 +154,10 @@ class UCXUCCCommunicator : public Communicator { void Barrier() override; Status AllGather(const std::shared_ptr
&table, std::vector> *out) const override; - Status Gather(const std::shared_ptr
&table, - int gather_root, + Status Gather(const std::shared_ptr
&table, int gather_root, bool gather_from_root, std::vector> *out) const override; - Status Bcast(std::shared_ptr
*table, - int bcast_root, + Status Bcast(std::shared_ptr
*table, int bcast_root, const std::shared_ptr &ctx) const override; Status AllReduce(const std::shared_ptr &values, net::ReduceOp reduce_op, @@ -125,8 +173,14 @@ class UCXUCCCommunicator : public Communicator { ucc_team_h uccTeam{}; ucc_context_h uccContext{}; std::shared_ptr ucx_comm_; + std::shared_ptr oobContext; + +private: + static Status MakeOOB(std::shared_ptr &ucc_oob_ctx, + MemoryPool *pool, std::shared_ptr *out); + }; #endif -} -} -#endif //CYLON_SRC_CYLON_COMM_UCXCOMMUNICATOR_H_ +} // namespace net +} // namespace cylon +#endif // CYLON_SRC_CYLON_COMM_UCXCOMMUNICATOR_H_ diff --git a/cpp/src/cylon/net/ucx/ucx_oob_context.hpp b/cpp/src/cylon/net/ucx/ucx_oob_context.hpp new file mode 100644 index 000000000..386ef70ee --- /dev/null +++ b/cpp/src/cylon/net/ucx/ucx_oob_context.hpp @@ -0,0 +1,37 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CYLON_UCX_OOB_CONTEXT_HPP +#define CYLON_UCX_OOB_CONTEXT_HPP + + +#include "cylon/status.hpp" + +namespace cylon { + namespace net { + class UCXOOBContext { + public: + virtual Status InitOOB() = 0; + + virtual Status getWorldSizeAndRank(int &world_size, int &rank) = 0; + + virtual Status OOBAllgather(uint8_t *src, uint8_t *dst, size_t srcSize, + size_t dstSize) = 0; + + virtual Status Finalize() = 0; + }; + } +} + +#endif //CYLON_UCX_OOB_CONTEXT_HPP diff --git a/cpp/src/examples/CMakeLists.txt b/cpp/src/examples/CMakeLists.txt index 510e3a1c8..0605e9af6 100644 --- a/cpp/src/examples/CMakeLists.txt +++ b/cpp/src/examples/CMakeLists.txt @@ -51,6 +51,10 @@ macro(cylon_add_exe EXENAME) endif (CYLON_UCC) endif (CYLON_UCX) + if(CYLON_USE_REDIS) + target_link_libraries(${EXENAME} ${REDIS_LIBRARIES}) + endif(CYLON_USE_REDIS) + install(TARGETS ${EXENAME} RUNTIME DESTINATION cylon/examples) endmacro(cylon_add_exe) @@ -83,6 +87,9 @@ if (CYLON_UCX) cylon_add_exe(ucc_example) cylon_add_exe(ucc_operators_example) cylon_add_exe(ucc_allgather_vector_example) + if(CYLON_USE_REDIS) + cylon_add_exe(redis_ucc_ucx_example) + endif () endif () endif (CYLON_UCX) diff --git a/cpp/src/examples/demo_join.cpp b/cpp/src/examples/demo_join.cpp new file mode 100644 index 000000000..94414ef54 --- /dev/null +++ b/cpp/src/examples/demo_join.cpp @@ -0,0 +1,63 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +#define CHECK_STATUS(status, msg) \ + if (!status.is_ok()) { \ + LOG(ERROR) << msg << " " << status.get_msg(); \ + ctx->Finalize(); \ + return 1; \ + } + +int main(int argc, char *argv[]) { + + if (argc < 2) { + LOG(ERROR) << "There should be an argument to the directory for data file"; + return 1; + } + + auto mpi_config = std::make_shared(); + std::shared_ptr ctx; + auto initStatus = cylon::CylonContext::InitDistributed(mpi_config, &ctx); + + + const int rank = ctx->GetRank() + 1; + const std::string directory = argv[1] ; + const std::string csv1 = directory + "user_device_tm_" + std::to_string(rank) + ".csv"; + const std::string csv2 = directory + "user_usage_tm_" + std::to_string(rank) + ".csv"; + + std::shared_ptr first_table, second_table, joined_table; + cylon::Status status; + + status = cylon::FromCSV(ctx, csv1, first_table); + CHECK_STATUS(status, "Reading csv1 failed!") + + status = cylon::FromCSV(ctx, csv2, second_table); + CHECK_STATUS(status, "Reading csv2 failed!") + + auto join_config = cylon::join::config::JoinConfig::InnerJoin(0, 3); + status = cylon::DistributedJoin(first_table, second_table, join_config, joined_table); + CHECK_STATUS(status, "Join failed!") + + LOG(INFO) << "First table had : " << first_table->Rows() << " and Second table had : " + << second_table->Rows() << ", Joined has : " << joined_table->Rows(); + + ctx->Finalize(); + return 0; +} diff --git a/cpp/src/examples/redis_ucc_ucx_example.cpp b/cpp/src/examples/redis_ucc_ucx_example.cpp new file mode 100644 index 000000000..1f34b7c29 --- /dev/null +++ b/cpp/src/examples/redis_ucc_ucx_example.cpp @@ -0,0 +1,75 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#define CHECK_STATUS(status, msg) \ + if (!status.is_ok()) { \ + LOG(ERROR) << msg << " " << status.get_msg(); \ + ctx->Finalize(); \ + return 1; \ + } + +int main(int argc, char *argv[]) { + + if (argc < 2) { + LOG(ERROR) << "There should be an argument to the directory for data file"; + return 1; + } + + //auto mpi_config = std::make_shared(); + std::shared_ptr ctx; + //auto mpi_config = std::make_shared(); + + + auto redis_ucc_ucx_ctx = cylon::net::UCCRedisOOBContext::Make(1, + "tcp://cylon-redis.mveu6e.0001.use1.cache.amazonaws.com:6379"); + + auto ucc_config = std::make_shared(redis_ucc_ucx_ctx); + + if (!cylon::CylonContext::InitDistributed(ucc_config, &ctx).is_ok()) { + std::cerr << "ctx init failed! " << std::endl; + return 1; + } + + const int rank = ctx->GetRank() + 1; + const std::string directory = argv[1] ; + const std::string csv1 = directory + "user_device_tm_" + std::to_string(rank) + ".csv"; + const std::string csv2 = directory + "user_usage_tm_" + std::to_string(rank) + ".csv"; + + std::shared_ptr first_table, second_table, joined_table; + cylon::Status status; + + status = cylon::FromCSV(ctx, csv1, first_table); + CHECK_STATUS(status, "Reading csv1 failed!") + + status = cylon::FromCSV(ctx, csv2, second_table); + CHECK_STATUS(status, "Reading csv2 failed!") + + auto join_config = cylon::join::config::JoinConfig::InnerJoin(0, 3); + status = cylon::DistributedJoin(first_table, second_table, join_config, joined_table); + CHECK_STATUS(status, "Join failed!") + + LOG(INFO) << "First table had : " << first_table->Rows() << " and Second table had : " + << second_table->Rows() << ", Joined has : " << joined_table->Rows(); + + ctx->Finalize(); + return 0; +} diff --git a/cpp/src/examples/ucc_operators_example.cpp b/cpp/src/examples/ucc_operators_example.cpp index 422883738..926b81198 100644 --- a/cpp/src/examples/ucc_operators_example.cpp +++ b/cpp/src/examples/ucc_operators_example.cpp @@ -18,6 +18,7 @@ * mpirun -n 4 bin/ucc_example */ +#ifdef BUILD_CYLON_UCC #include #include @@ -27,6 +28,7 @@ #include #include #include +#include "net/ucx/redis_ucx_ucc_oob_context.hpp" auto read_options = cylon::io::config::CSVReadOptions() .UseThreads(false) @@ -116,18 +118,37 @@ void testScalarAllgather(std::shared_ptr& ctx) { std::cout<<"scalar gather test passed at rank "<GetRank()<& table, - std::shared_ptr& ctx) { - std::vector> out; +void testTableGather(std::shared_ptr& ctx) { + int ws = ctx->GetWorldSize(); + if (ws > 4) { + std::cout << "table gather test can only take 4 or less processes." + << std::endl; + return; + } + + std::shared_ptr table; + std::vector> out, original(ws); + + for (int i = 0; i < ws; i++) { + readInputCsv(i, ctx, original[i]); + } + + readInputCsv(ctx->GetRank(), ctx, table); auto status = ctx->GetCommunicator()->Gather(table, 0, 1, &out); - std::cout<GetRank() == 0) { - std::cout<<"out size: "<Print(); - // std::cout<get_table()->num_rows()<GetRank() + << std::endl; + return; + } } } + std::cout << "table gather test passed at rank " << ctx->GetRank() + << std::endl; } void testTableBcast(std::shared_ptr& ctx) { @@ -198,9 +219,23 @@ void testScalarAllReduce(std::shared_ptr& ctx) { } int main(int argc, char **argv) { - auto ucx_config = std::make_shared(); + // auto redis = sw::redis::Redis("tcp://127.0.0.1:6379"); + std::shared_ptr oob_ctx; + + if(argc > 1 && std::string(argv[1]) == "mpi") { + oob_ctx = std::make_shared(); + } else { + // auto redis = std::make_shared(); +#ifdef BUILD_CYLON_REDIS + oob_ctx = std::make_shared( + 4, "tcp://127.0.0.1:6379"); +#endif + } + std::shared_ptr ctx; - if (!cylon::CylonContext::InitDistributed(ucx_config, &ctx).is_ok()) { + auto ucc_config = std::make_shared(oob_ctx); + + if (!cylon::CylonContext::InitDistributed(ucc_config, &ctx).is_ok()) { std::cerr << "ctx init failed! " << std::endl; return 1; } @@ -211,4 +246,6 @@ int main(int argc, char **argv) { testTableBcast(ctx); testColumnAllReduce(ctx); testScalarAllReduce(ctx); + testTableGather(ctx); } +#endif diff --git a/cpp/src/examples/ucx_join_example.cpp b/cpp/src/examples/ucx_join_example.cpp index 34e02fccd..6cc545297 100644 --- a/cpp/src/examples/ucx_join_example.cpp +++ b/cpp/src/examples/ucx_join_example.cpp @@ -20,6 +20,9 @@ #include int main(int argc, char *argv[]) { +#ifdef BUILD_CYLON_UCC // temporarily prevent build if using UCC + return 0; +#else if (argc < 3) { LOG(ERROR) << "There should be two arguments with paths to csv files"; return 1; @@ -78,4 +81,5 @@ int main(int argc, char *argv[]) { ctx->Finalize(); return 0; +#endif } diff --git a/docker/aws/Dockerfile b/docker/aws/Dockerfile new file mode 100644 index 000000000..3c30ed1c0 --- /dev/null +++ b/docker/aws/Dockerfile @@ -0,0 +1,90 @@ +FROM --platform=linux/amd64 ubuntu:22.04 +MAINTAINER cylondata@googlegroups.com + +ARG DEBIAN_FRONTEND=noninteractive + +ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV PATH /opt/conda/bin:$PATH + +ENV CYLON_HOME=/cylon +ENV CYLON_PREFIX=/cylon/install +ENV UCC_HOME=/ucc + +#give ARG EXPOSE_ENV a default value +ARG EXPOSE_ENV=33000 + +#assign the EXPOSE_ENV arg to the EXPOSE_ENV ENV so that it can be accessed +#by the subsequent RUN call within the container +ENV EXPOSE_ENV $EXPOSE_ENV + + +WORKDIR $CYLON_HOME + +RUN DEBIAN_FRONTEND=noninteractive apt-get update -y --fix-missing && \ + apt-get install -y wget bzip2 ca-certificates curl git build-essential && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-x86_64.sh -O ~/miniconda.sh && \ + /bin/bash ~/miniconda.sh -b -p /opt/conda && \ + rm ~/miniconda.sh && \ + #/opt/conda/bin/conda clean -a && \ + ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \ + echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \ + echo "conda activate cylon_dev" >> ~/.bashrc && \ + echo "export LD_LIBRARY_PATH=$CYLON_PREFIX"/lib >> ~/.bashrc + + + + +RUN git clone https://github.com/mstaylor/cylon.git $CYLON_HOME +RUN cd $CYLON_HOME && git checkout -b aws-docker-support origin/aws-docker-support + + + +SHELL ["/bin/bash", "--login", "-c"] + +RUN conda env create -f $CYLON_HOME/conda/environments/cylon.yml + +RUN . /opt/conda/etc/profile.d/conda.sh && \ + conda activate cylon_dev && \ + conda install -n base conda-libmamba-solver && conda config --set solver libmamba && \ + conda install -c anaconda boto3 -y && pip install cloudmesh-openstack &&\ + conda install -c conda-forge redis-py -y + + + +RUN apt-get update && apt-get install autoconf -y && apt-get install libtool -y && apt-get install cmake -y && \ + apt-get install libnuma-dev -y + +#UCC install + +RUN git clone --single-branch -b master https://github.com/openucx/ucc.git $UCC_HOME +RUN cd $UCC_HOME && \ + ./autogen.sh && \ + ./configure --prefix=$UCC_HOME/install --with-ucx=/opt/conda/envs/cylon_dev && \ + make install + +#REDIS install +RUN git clone https://github.com/redis/hiredis.git /hiredis && \ + cd /hiredis && \ + make && \ + make install && \ + git clone https://github.com/sewenew/redis-plus-plus.git /redis-plus-plus && \ + cd /redis-plus-plus && \ + mkdir build && \ + cd build && \ + cmake -DREDIS_PLUS_PLUS_CXX_STANDARD=11 .. && \ + make && make install + + +RUN . /opt/conda/etc/profile.d/conda.sh && \ + conda activate cylon_dev && \ + cd $CYLON_HOME && \ + python build.py -cmake-flags="-DCYLON_UCX=1 -DCYLON_UCC=1 -DUCC_INSTALL_PREFIX=$UCC_HOME/install -DCYLON_USE_REDIS=1 " -ipath="$CYLON_PREFIX" --cpp --python --test --pytest + +RUN chmod 0755 /cylon/aws/scripts/runCylon.sh + +EXPOSE $EXPOSE_ENV + +ENTRYPOINT ["/cylon/aws/scripts/runCylon.sh"] diff --git a/docker/aws/README.md b/docker/aws/README.md new file mode 100644 index 000000000..7a8ea6a61 --- /dev/null +++ b/docker/aws/README.md @@ -0,0 +1,36 @@ +# Cylon Docker Image + +## Instructions + +- To build the Docker image, +```bash +docker build --shm-size 8589934592 -t cylondata/cylon-ucc . +``` + +- To run a container +```bash +docker run -it --name cylon1 -p 22:22 -d cylon-ucc-redis +``` + +- To attach to a container +```bash + docker attach cylon1 +``` + + + +Cylon will be installed in `/cylon/` directory. A container would have the following environment +variables and commands. +- `$CYLON_HOME` points to `/cylon` +- `$CYLON_BUILD` points to c++ build directory +- `$CYLON_ENV` points to python virtual environment + +UCX will be installed in `/opt/conda/envs/cylon_dev/` directory as part of the environment creation. + +UCC with be installed into `/ucc/` directory. A container would have the following environment +variables and commands. +- `$UCC_HOME` points to `/ucc` + +Hiredis will be be installed in '/hiredis' directory. + +Redis Plus Plus will be installed in `/redis-plus-plus` directory. \ No newline at end of file diff --git a/docker/ucc-redis/Dockerfile b/docker/ucc-redis/Dockerfile new file mode 100644 index 000000000..1c86b3805 --- /dev/null +++ b/docker/ucc-redis/Dockerfile @@ -0,0 +1,68 @@ +FROM --platform=linux/amd64 ubuntu:22.04 +MAINTAINER cylondata@googlegroups.com + +ARG DEBIAN_FRONTEND=noninteractive + +ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV PATH /opt/conda/bin:$PATH + +RUN DEBIAN_FRONTEND=noninteractive apt-get update -y --fix-missing && \ + apt-get install -y wget bzip2 ca-certificates curl git build-essential && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-x86_64.sh -O ~/miniconda.sh && \ + /bin/bash ~/miniconda.sh -b -p /opt/conda && \ + rm ~/miniconda.sh && \ + #/opt/conda/bin/conda clean -a && \ + ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \ + echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \ + echo "conda activate cylon_dev" >> ~/.bashrc + + +ENV CYLON_HOME=/cylon +ENV CYLON_PREFIX=/cylon/install +ENV UCC_HOME=/ucc + +WORKDIR $CYLON_HOME + +RUN git clone https://github.com/mstaylor/cylon.git $CYLON_HOME +RUN cd $CYLON_HOME && git checkout -b aws-docker-support origin/aws-docker-support + +RUN conda install -n base conda-libmamba-solver && conda config --set solver libmamba + +RUN conda env create -f $CYLON_HOME/conda/environments/cylon.yml + +SHELL ["/bin/bash", "--login", "-c"] + +RUN apt-get update && apt-get install autoconf -y && apt-get install libtool -y && apt-get install cmake -y && \ + apt-get install libnuma-dev -y + +#UCC install + +RUN git clone --single-branch -b master https://github.com/openucx/ucc.git $UCC_HOME +RUN cd $UCC_HOME && \ + ./autogen.sh && \ + ./configure --prefix=$UCC_HOME/install --with-ucx=/opt/conda/envs/cylon_dev && \ + make install + +#REDIS install +RUN git clone https://github.com/redis/hiredis.git /hiredis && \ + cd /hiredis && \ + make && \ + make install && \ + git clone https://github.com/sewenew/redis-plus-plus.git /redis-plus-plus && \ + cd /redis-plus-plus && \ + mkdir build && \ + cd build && \ + cmake -DREDIS_PLUS_PLUS_CXX_STANDARD=11 .. && \ + make && make install + + +RUN . /opt/conda/etc/profile.d/conda.sh && \ + conda activate cylon_dev && \ + cd $CYLON_HOME && \ + python build.py -cmake-flags="-DCYLON_UCX=1 -DCYLON_UCC=1 -DUCC_INSTALL_PREFIX=$UCC_HOME/install -DCYLON_USE_REDIS=1 " -ipath="$CYLON_PREFIX" --cpp --python --test --pytest + + +ENTRYPOINT ["/bin/bash"] diff --git a/docker/ucc-redis/README.md b/docker/ucc-redis/README.md new file mode 100644 index 000000000..ccd742042 --- /dev/null +++ b/docker/ucc-redis/README.md @@ -0,0 +1,36 @@ +# Cylon Docker Image + +## Instructions + +- To build the Docker image, +```bash +docker build -t cylon-ucc-redis . +``` + +- To run a container +```bash +docker run -it --name cylon1 -p 22:22 -d cylon-ucc-redis +``` + +- To attach to a container +```bash + docker attach cylon1 +``` + + + +Cylon will be installed in `/cylon/` directory. A container would have the following environment +variables and commands. +- `$CYLON_HOME` points to `/cylon` +- `$CYLON_BUILD` points to c++ build directory +- `$CYLON_ENV` points to python virtual environment + +UCX will be installed in `/opt/conda/envs/cylon_dev/` directory as part of the environment creation. + +UCC with be installed into `/ucc/` directory. A container would have the following environment +variables and commands. +- `$UCC_HOME` points to `/ucc` + +Hiredis will be be installed in '/hiredis' directory. + +Redis Plus Plus will be installed in `/redis-plus-plus` directory. \ No newline at end of file diff --git a/python/pycylon/examples/demo_join.py b/python/pycylon/examples/demo_join.py new file mode 100644 index 000000000..2875d5cf6 --- /dev/null +++ b/python/pycylon/examples/demo_join.py @@ -0,0 +1,64 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from pycylon import CylonContext +from pycylon import Table, CylonEnv +from pycylon.io import CSVReadOptions +from pycylon.io import read_csv +from pycylon.net import MPIConfig + +if __name__ == "__main__": + + env = CylonEnv(config=MPIConfig(), distributed=True) + csv_read_options = CSVReadOptions() \ + .use_threads(False) \ + .block_size(1 << 30) \ + .na_values(['na', 'none']) + + rank = env.rank + 1 + + print(f"rank: {rank}") + csv1 = f"/home/qad5gv/cylon/data/input/user_usage_tm_{rank}.csv" + csv2 = f"/home/qad5gv/cylon/data/input/user_device_tm_{rank}.csv" + + first_table: Table = read_csv(env, csv1, csv_read_options) + second_table: Table = read_csv(env, csv2, csv_read_options) + + print(first_table) + + first_row_count = first_table.row_count + + second_row_count = second_table.row_count + + + print(f"Table 1 & 2 Rows [{first_row_count},{second_row_count}], " + f"Columns [{first_table.column_count},{second_table.column_count}]") + + configs = {'join_type': 'inner', 'algorithm': 'sort'} + joined_table: Table = first_table.distributed_join(table=second_table, + join_type=configs['join_type'], + algorithm=configs['algorithm'], + left_on=[3], + right_on=[0] + ) + + + + join_row_count = joined_table.row_count + + print(f"First table had : {first_row_count} and Second table had : {second_row_count}, " + f"Joined has : {join_row_count}") + + + env.finalize() diff --git a/python/pycylon/examples/redis_example.py b/python/pycylon/examples/redis_example.py new file mode 100644 index 000000000..80d065541 --- /dev/null +++ b/python/pycylon/examples/redis_example.py @@ -0,0 +1,74 @@ +from pycylon.net.ucc_config import UCCConfig +from pycylon.net.redis_ucc_oob_context import UCCRedisOOBContext +from pycylon import Table, CylonEnv +from pycylon.io import CSVReadOptions +from pycylon.io import read_csv +import argparse + +if __name__ == "__main__": + print("Initializing redis...") + + parser = argparse.ArgumentParser() + parser.add_argument('--world_size', "-n", type=int, help="world size") + parser.add_argument("--redis_host", "-r", type=str, help="redis address, default to 127.0.0.1", + default="127.0.0.1") + parser.add_argument("--port", "-p", type=int, help="name of redis port", default=6379) + args = parser.parse_args() + redis_context = UCCRedisOOBContext(args.world_size, f"tcp://{args.redis_host}:{args.port}") + + if redis_context is not None: + ucc_config = UCCConfig(redis_context) + + if ucc_config is None: + print("unable to initialize uccconfig") + + env = CylonEnv(config=ucc_config) + + print("cylon env initialized") + + csv_read_options = CSVReadOptions() \ + .use_threads(False) \ + .block_size(1 << 30) \ + .na_values(['na', 'none']) + + rank = env.rank + 1 + + print(f"rank: {rank}") + csv1 = f"/home/qad5gv/cylon/data/input/user_usage_tm_{rank}.csv" + csv2 = f"/home/qad5gv/cylon/data/input/user_device_tm_{rank}.csv" + + first_table: Table = read_csv(env, csv1, csv_read_options) + second_table: Table = read_csv(env, csv2, csv_read_options) + + print(first_table) + + first_row_count = first_table.row_count + + second_row_count = second_table.row_count + + print(f"Table 1 & 2 Rows [{first_row_count},{second_row_count}], " + f"Columns [{first_table.column_count},{second_table.column_count}]") + + configs = {'join_type': 'inner', 'algorithm': 'sort'} + joined_table: Table = first_table.distributed_join(table=second_table, + join_type=configs['join_type'], + algorithm=configs['algorithm'], + left_on=[3], + right_on=[0] + ) + + join_row_count = joined_table.row_count + + print(f"First table had : {first_row_count} and Second table had : {second_row_count}, " + f"Joined has : {join_row_count}") + + env.finalize() + + + + + + + else: + print("unable to initialize redis oob context") + diff --git a/python/pycylon/pycylon/api/lib.pxd b/python/pycylon/pycylon/api/lib.pxd index 96cad6ca3..2918b8eac 100644 --- a/python/pycylon/pycylon/api/lib.pxd +++ b/python/pycylon/pycylon/api/lib.pxd @@ -23,20 +23,26 @@ from pycylon.ctx.context cimport CylonContext from pycylon.ctx.context import CylonContext from pycylon.net.comm_config cimport CCommConfig from pycylon.net.mpi_config cimport CMPIConfig + IF CYTHON_GLOO: from pycylon.net.gloo_config cimport CGlooConfig IF CYTHON_UCX & CYTHON_UCC: from pycylon.net.ucx_config cimport CUCXConfig + from pycylon.net.ucc_config cimport CUCCConfig + from pycylon.net.ucc_ucx_communicator cimport CUCXUCCCommunicator +IF CYTHON_UCX: + from pycylon.net.ucx_communicator cimport CUCXCommunicator +from pycylon.net.mpi_communicator cimport CMPICommunicator from pycylon.io.csv_read_config cimport CCSVReadOptions from pycylon.io.csv_read_config import CSVReadOptions from pycylon.io.csv_read_config cimport CSVReadOptions from pycylon.io.csv_write_config cimport CCSVWriteOptions from pycylon.io.csv_write_config import CSVWriteOptions from pycylon.io.csv_write_config cimport CSVWriteOptions -from pycylon.data.data_type cimport CType -from pycylon.data.data_type import Type -from pycylon.data.data_type cimport CLayout -from pycylon.data.data_type import Layout +from pycylon.data.ctype cimport CType +from pycylon.data.ctype import Type +from pycylon.data.layout cimport CLayout +from pycylon.data.layout import Layout from pycylon.data.data_type cimport CDataType from pycylon.data.data_type import DataType from pycylon.common.status cimport CStatus @@ -58,11 +64,21 @@ cdef api shared_ptr[CCylonContext] pycylon_unwrap_context(object context) cdef api shared_ptr[CMPIConfig] pycylon_unwrap_mpi_config(object config) + + IF CYTHON_GLOO: cdef api shared_ptr[CGlooConfig] pycylon_unwrap_gloo_config(object config) IF CYTHON_UCX & CYTHON_UCC: cdef api shared_ptr[CUCXConfig] pycylon_unwrap_ucx_config(object config) + cdef api shared_ptr[CUCCConfig] pycylon_unwrap_ucc_config(object config) + + cdef api object pycylon_wrap_ucc_ucx_communicator(const shared_ptr[CUCXUCCCommunicator] & ccommunicator) + +IF CYTHON_UCX: + cdef api object pycylon_wrap_ucx_communicator(const shared_ptr[CUCXCommunicator] & ccommunicator) + +cdef api object pycylon_wrap_mci_communicator(const shared_ptr[CMPICommunicator] & ccomunicator) cdef api shared_ptr[CTable] pycylon_unwrap_table(object table) diff --git a/python/pycylon/pycylon/api/lib.pyx b/python/pycylon/pycylon/api/lib.pyx index 67bec2700..1f30433a1 100644 --- a/python/pycylon/pycylon/api/lib.pyx +++ b/python/pycylon/pycylon/api/lib.pyx @@ -32,16 +32,22 @@ IF CYTHON_GLOO: IF CYTHON_UCX & CYTHON_UCC: from pycylon.net.ucx_config import UCXConfig from pycylon.net.ucx_config cimport CUCXConfig, UCXConfig + from pycylon.net.ucc_config cimport CUCCConfig, UCCConfig + from pycylon.net.ucc_ucx_communicator cimport CUCXUCCCommunicator, UCXUCCCommunicator +IF CYTHON_UCX: + from pycylon.net.ucx_communicator cimport CUCXCommunicator, UCXCommunicator + +from pycylon.net.mpi_communicator cimport CMPICommunicator, MPICommunicator from pycylon.io.csv_read_config cimport CCSVReadOptions from pycylon.io.csv_read_config import CSVReadOptions from pycylon.io.csv_read_config cimport CSVReadOptions from pycylon.io.csv_write_config cimport CCSVWriteOptions from pycylon.io.csv_write_config import CSVWriteOptions from pycylon.io.csv_write_config cimport CSVWriteOptions -from pycylon.data.data_type cimport CType -from pycylon.data.data_type import Type -from pycylon.data.data_type cimport CLayout -from pycylon.data.data_type import Layout +from pycylon.data.ctype cimport CType +from pycylon.data.ctype import Type +from pycylon.data.layout cimport CLayout +from pycylon.data.layout import Layout from pycylon.data.data_type cimport CDataType from pycylon.data.data_type import DataType from pycylon.data.data_type cimport DataType @@ -131,6 +137,28 @@ IF CYTHON_UCX & CYTHON_UCC: else: raise ValueError('Passed object is not an instance of UcxConfig') + cdef api shared_ptr[CUCCConfig] pycylon_unwrap_ucc_config(object config): + if isinstance(config, UCCConfig): + return ( config).ucc_config_shd_ptr + else: + raise ValueError('Passed object is not an instance of UccConfig') + + cdef api object pycylon_wrap_ucc_ucx_communicator(const shared_ptr[CUCXUCCCommunicator] & ccommunicator): + cdef UCXUCCCommunicator communicator = UCXUCCCommunicator.__new__(UCXUCCCommunicator) + communicator.init(ccommunicator) + return communicator + + +IF CYTHON_UCX: + cdef api object pycylon_wrap_ucx_communicator(const shared_ptr[CUCXCommunicator] & ccomunicator): + cdef UCXCommunicator communicator = UCXCommunicator.__new__(UCXCommunicator) + communicator.init(ccomunicator) + return communicator + +cdef api object pycylon_wrap_mci_communicator(const shared_ptr[CMPICommunicator] & ccomunicator): + cdef MPICommunicator communicator = MPICommunicator.__new__(MPICommunicator) + communicator.init(ccomunicator) + return communicator cdef api CCSVReadOptions pycylon_unwrap_csv_read_options(object csv_read_options): cdef CSVReadOptions csvrdopt if pyclon_is_csv_read_options(csv_read_options): diff --git a/python/pycylon/pycylon/ctx/context.pxd b/python/pycylon/pycylon/ctx/context.pxd index 75ee35723..d1156f649 100644 --- a/python/pycylon/pycylon/ctx/context.pxd +++ b/python/pycylon/pycylon/ctx/context.pxd @@ -47,7 +47,7 @@ cdef extern from "../../../../cpp/src/cylon/ctx/cylon_context.hpp" namespace "cy string GetConfig(const string &key, const string &defn) - shared_ptr[CCommunicator] GetCommunicator() const + shared_ptr[CCommunicator] & GetCommunicator() const int GetRank() diff --git a/python/pycylon/pycylon/ctx/context.pyx b/python/pycylon/pycylon/ctx/context.pyx index c993947ee..8ccdd6e2d 100644 --- a/python/pycylon/pycylon/ctx/context.pyx +++ b/python/pycylon/pycylon/ctx/context.pyx @@ -12,7 +12,7 @@ # limitations under the License. ## -from libcpp.memory cimport shared_ptr +from libcpp.memory cimport shared_ptr, dynamic_pointer_cast from libcpp.vector cimport vector from libcpp.string cimport string from libcpp cimport bool @@ -22,13 +22,22 @@ IF CYTHON_GLOO: from pycylon.api.lib cimport pycylon_unwrap_gloo_config IF CYTHON_UCX & CYTHON_UCC: - from pycylon.api.lib cimport pycylon_unwrap_ucx_config + from pycylon.api.lib cimport pycylon_unwrap_ucx_config, pycylon_unwrap_ucc_config, pycylon_wrap_ucc_ucx_communicator + from pycylon.net.ucc_ucx_communicator cimport CUCXUCCCommunicator, UCXUCCCommunicator +IF CYTHON_UCX: + from pycylon.api.lib cimport pycylon_wrap_ucx_communicator + from pycylon.net.ucx_communicator cimport CUCXCommunicator, UCXCommunicator +from pycylon.net.mpi_communicator cimport CMPICommunicator, MPICommunicator +from pycylon.api.lib cimport pycylon_wrap_mci_communicator from pycylon.net import CommType from pycylon.net.mpi_config cimport CMPIConfig from pycylon.net.mpi_config import MPIConfig from pycylon.net.comm_config cimport CCommConfig from pycylon.net.comm_config import CommConfig from pycylon.net.comm_config cimport CommConfig +from pycylon.net.communicator import Communicator +from pycylon.net.communicator cimport CCommunicator + cdef class CylonContext: """ @@ -85,9 +94,18 @@ cdef class CylonContext: if config.comm_type == CommType.GLOO: return pycylon_unwrap_gloo_config(config) - IF CYTHON_UCX & CYTHON_UCC: - if config.comm_type == CommType.UCX: - return pycylon_unwrap_ucx_config(config) + if CYTHON_UCX & CYTHON_UCC: + if CYTHON_UCX & CYTHON_UCC: + if config.comm_type == CommType.UCX: + return pycylon_unwrap_ucx_config(config) + if config.comm_type == CommType.UCC: + return pycylon_unwrap_ucc_config(config) + else: + if CYTHON_UCX & CYTHON_UCC: + if config.comm_type == CommType.UCX: + return pycylon_unwrap_ucx_config(config) + + raise ValueError(f"Unsupported distributed comm config {config}") @@ -119,6 +137,14 @@ cdef class CylonContext: ''' return self.ctx_shd_ptr.get().GetWorldSize() + def get_communicator(self): + IF CYTHON_UCX & CYTHON_UCC: + return pycylon_wrap_ucc_ucx_communicator(dynamic_pointer_cast[CUCXUCCCommunicator, CCommunicator](self.ctx_shd_ptr.get().GetCommunicator())) + ELIF CYTHON_UCX: + return pycylon_wrap_ucx_communicator( + dynamic_pointer_cast[CUCXCommunicator, CCommunicator](self.ctx_shd_ptr.get().GetCommunicator())) + return pycylon_wrap_mci_communicator(dynamic_pointer_cast[CMPICommunicator, CCommunicator](self.ctx_shd_ptr.get().GetCommunicator())) + def finalize(self): ''' Gracefully shuts down the context by closing any distributed processes initialization ,etc diff --git a/python/pycylon/pycylon/data/ctype.pxd b/python/pycylon/pycylon/data/ctype.pxd new file mode 100644 index 000000000..a0fd90548 --- /dev/null +++ b/python/pycylon/pycylon/data/ctype.pxd @@ -0,0 +1,75 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + + + +cdef extern from "../../../../cpp/src/cylon/data_types.hpp" namespace "cylon": + cdef cppclass CType 'cylon::Type': + enum ctype 'type': + # Boolean as 1 bit, LSB bit-packed ordering + CBOOL 'cylon::Type::BOOL' + # Unsigned 8-bit little-endian integer + CUINT8 'cylon::Type::UINT8' + # Signed 8-bit little-endian integer + CINT8 'cylon::Type::INT8' + # Unsigned 16-bit little-endian integer + CUINT16 'cylon::Type::UINT16' + # Signed 16-bit little-endian integer + CINT16 'cylon::Type::INT16' + # Unsigned 32-bit little-endian integer + CUINT32 'cylon::Type::UINT32' + # Signed 32-bit little-endian integer + CINT32 'cylon::Type::INT32' + # Unsigned 64-bit little-endian integer + CUINT64 'cylon::Type::UINT64' + # Signed 64-bit little-endian integer + CINT64 'cylon::Type::INT64' + # 2-byte floating point value + CHALF_FLOAT 'cylon::Type::HALF_FLOAT' + # 4-byte floating point value + CFLOAT 'cylon::Type::FLOAT' + # 8-byte floating point value + CDOUBLE 'cylon::Type::DOUBLE' + # UTF8 variable-length string as List + CSTRING 'cylon::Type::STRING' + # Variable-length bytes (no guarantee of UTF8-ness) + CBINARY 'cylon::Type::BINARY' + # Fixed-size binary. Each value occupies the same number of bytes + CFIXED_SIZE_BINARY 'cylon::Type::FIXED_SIZE_BINARY' + # int32_t days since the UNIX epoch + CDATE32 'cylon::Type::DATE32' + # int64_t milliseconds since the UNIX epoch + CDATE64 'cylon::Type::DATE64' + # Exact timestamp encoded with int64 since UNIX epoch + # Default unit millisecond + CTIMESTAMP 'cylon::Type::TIMESTAMP' + # Time as signed 32-bit integer, representing either seconds or + # milliseconds since midnight + CTIME32 'cylon::Type::TIME32' + # Time as signed 64-bit integer, representing either microseconds or + # nanoseconds since midnight + CTIME64 'cylon::Type::TIME64' + # YEAR_MONTH or DAY_TIME interval in SQL style + CINTERVAL 'cylon::Type::INTERVAL' + # Precision- and scale-based decimal type. Storage type depends on the + # parameters. + CDECIMAL 'cylon::Type::DECIMAL' + # A list of some logical data type + CLIST 'cylon::Type::LIST' + # Custom data type, implemented by user + CEXTENSION 'cylon::Type::EXTENSION' + # Fixed size list of some logical type + CFIXED_SIZE_LIST 'cylon::Type::FIXED_SIZE_LIST' + # or nanoseconds. + CDURATION 'cylon::Type::DURATION' diff --git a/python/pycylon/pycylon/data/ctype.pyx b/python/pycylon/pycylon/data/ctype.pyx new file mode 100644 index 000000000..84805895c --- /dev/null +++ b/python/pycylon/pycylon/data/ctype.pyx @@ -0,0 +1,73 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + + + +cpdef enum Type: + # Boolean as 1 bit, LSB bit-packed ordering + BOOL = CType.ctype.CBOOL + # Unsigned 8-bit little-endian integer + UINT8 = CType.ctype.CUINT8 + # Signed 8-bit little-endian integer + INT8 = CType.ctype.CINT8 + # Unsigned 16-bit little-endian integer + UINT16 = CType.ctype.CUINT16 + # Signed 16-bit little-endian integer + INT16 = CType.ctype.CINT16 + # Unsigned 32-bit little-endian integer + UINT32 = CType.ctype.CUINT32 + # Signed 32-bit little-endian integer + INT32 = CType.ctype.CINT32 + # Unsigned 64-bit little-endian integer + UINT64 = CType.ctype.CUINT64 + # Signed 64-bit little-endian integer + INT64 = CType.ctype.CINT64 + # 2-byte floating point value + HALF_FLOAT = CType.ctype.CHALF_FLOAT + # 4-byte floating point value + FLOAT = CType.ctype.CFLOAT + # 8-byte floating point value + DOUBLE = CType.ctype.CDOUBLE + # UTF8 variable-length string as List + STRING = CType.ctype.CSTRING + # Variable-length bytes (no guarantee of UTF8-ness) + BINARY = CType.ctype.CBINARY + # Fixed-size binary. Each value occupies the same number of bytes + FIXED_SIZE_BINARY = CType.ctype.CFIXED_SIZE_BINARY + # int32_t days since the UNIX epoch + DATE32 = CType.ctype.CDATE32 + # int64_t milliseconds since the UNIX epoch + DATE64 = CType.ctype.CDATE64 + # Exact timestamp encoded with int64 since UNIX epoch + # Default unit millisecond + TIMESTAMP = CType.ctype.CTIMESTAMP + # Time as signed 32-bit integer, representing either seconds or + # milliseconds since midnight + TIME32 = CType.ctype.CTIME32 + # Time as signed 64-bit integer, representing either microseconds or + # nanoseconds since midnight + TIME64 = CType.ctype.CTIME64 + # YEAR_MONTH or DAY_TIME interval in SQL style + INTERVAL = CType.ctype.CINTERVAL + # Precision- and scale-based decimal type. Storage type depends on the + # parameters. + DECIMAL = CType.ctype.CDECIMAL + # A list of some logical data type + LIST = CType.ctype.CLIST + # Custom data type, implemented by user + EXTENSION = CType.ctype.CEXTENSION + # Fixed size list of some logical type + FIXED_SIZE_LIST = CType.ctype.CFIXED_SIZE_LIST + # or nanoseconds. + DURATION = CType.ctype.CDURATION \ No newline at end of file diff --git a/python/pycylon/pycylon/data/data_type.pxd b/python/pycylon/pycylon/data/data_type.pxd index 6375779aa..0913bed8f 100644 --- a/python/pycylon/pycylon/data/data_type.pxd +++ b/python/pycylon/pycylon/data/data_type.pxd @@ -20,75 +20,10 @@ from libcpp.memory cimport shared_ptr from libcpp.vector cimport vector from pycylon.ctx.context cimport CCylonContext from pycylon.ctx.context import CylonContext +from pycylon.data.ctype cimport CType +from pycylon.data.layout cimport CLayout -cdef extern from "../../../../cpp/src/cylon/data_types.hpp" namespace "cylon": - cdef cppclass CType 'cylon::Type': - enum ctype 'type': - # Boolean as 1 bit, LSB bit-packed ordering - CBOOL 'cylon::Type::BOOL' - # Unsigned 8-bit little-endian integer - CUINT8 'cylon::Type::UINT8' - # Signed 8-bit little-endian integer - CINT8 'cylon::Type::INT8' - # Unsigned 16-bit little-endian integer - CUINT16 'cylon::Type::UINT16' - # Signed 16-bit little-endian integer - CINT16 'cylon::Type::INT16' - # Unsigned 32-bit little-endian integer - CUINT32 'cylon::Type::UINT32' - # Signed 32-bit little-endian integer - CINT32 'cylon::Type::INT32' - # Unsigned 64-bit little-endian integer - CUINT64 'cylon::Type::UINT64' - # Signed 64-bit little-endian integer - CINT64 'cylon::Type::INT64' - # 2-byte floating point value - CHALF_FLOAT 'cylon::Type::HALF_FLOAT' - # 4-byte floating point value - CFLOAT 'cylon::Type::FLOAT' - # 8-byte floating point value - CDOUBLE 'cylon::Type::DOUBLE' - # UTF8 variable-length string as List - CSTRING 'cylon::Type::STRING' - # Variable-length bytes (no guarantee of UTF8-ness) - CBINARY 'cylon::Type::BINARY' - # Fixed-size binary. Each value occupies the same number of bytes - CFIXED_SIZE_BINARY 'cylon::Type::FIXED_SIZE_BINARY' - # int32_t days since the UNIX epoch - CDATE32 'cylon::Type::DATE32' - # int64_t milliseconds since the UNIX epoch - CDATE64 'cylon::Type::DATE64' - # Exact timestamp encoded with int64 since UNIX epoch - # Default unit millisecond - CTIMESTAMP 'cylon::Type::TIMESTAMP' - # Time as signed 32-bit integer, representing either seconds or - # milliseconds since midnight - CTIME32 'cylon::Type::TIME32' - # Time as signed 64-bit integer, representing either microseconds or - # nanoseconds since midnight - CTIME64 'cylon::Type::TIME64' - # YEAR_MONTH or DAY_TIME interval in SQL style - CINTERVAL 'cylon::Type::INTERVAL' - # Precision- and scale-based decimal type. Storage type depends on the - # parameters. - CDECIMAL 'cylon::Type::DECIMAL' - # A list of some logical data type - CLIST 'cylon::Type::LIST' - # Custom data type, implemented by user - CEXTENSION 'cylon::Type::EXTENSION' - # Fixed size list of some logical type - CFIXED_SIZE_LIST 'cylon::Type::FIXED_SIZE_LIST' - # or nanoseconds. - CDURATION 'cylon::Type::DURATION' - - -cdef extern from "../../../../cpp/src/cylon/data_types.hpp" namespace "cylon": - cdef cppclass CLayout 'cylon::Layout': - enum clayout 'layout': - CFIXED_WIDTH 'cylon::Layout::FIXED_WIDTH' - CVARIABLE_WIDTH 'cylon::Layout::VARIABLE_WIDTH' - cdef extern from "../../../../cpp/src/cylon/data_types.hpp" namespace "cylon": cdef cppclass CDataType "cylon::DataType": diff --git a/python/pycylon/pycylon/data/data_type.pyx b/python/pycylon/pycylon/data/data_type.pyx index 90c65b032..c4eb1bf84 100644 --- a/python/pycylon/pycylon/data/data_type.pyx +++ b/python/pycylon/pycylon/data/data_type.pyx @@ -15,74 +15,18 @@ from libcpp.memory cimport shared_ptr, make_shared from pycylon.data.data_type cimport CDataType -from pycylon.data.data_type cimport CType -from pycylon.data.data_type cimport CLayout +from pycylon.data.ctype cimport CType +from pycylon.data.ctype import Type +from pycylon.data.layout cimport CLayout +from pycylon.data.layout import Layout + import pyarrow as pa -cpdef enum Type: - # Boolean as 1 bit, LSB bit-packed ordering - BOOL = CType.ctype.CBOOL - # Unsigned 8-bit little-endian integer - UINT8 = CType.ctype.CUINT8 - # Signed 8-bit little-endian integer - INT8 = CType.ctype.CINT8 - # Unsigned 16-bit little-endian integer - UINT16 = CType.ctype.CUINT16 - # Signed 16-bit little-endian integer - INT16 = CType.ctype.CINT16 - # Unsigned 32-bit little-endian integer - UINT32 = CType.ctype.CUINT32 - # Signed 32-bit little-endian integer - INT32 = CType.ctype.CINT32 - # Unsigned 64-bit little-endian integer - UINT64 = CType.ctype.CUINT64 - # Signed 64-bit little-endian integer - INT64 = CType.ctype.CINT64 - # 2-byte floating point value - HALF_FLOAT = CType.ctype.CHALF_FLOAT - # 4-byte floating point value - FLOAT = CType.ctype.CFLOAT - # 8-byte floating point value - DOUBLE = CType.ctype.CDOUBLE - # UTF8 variable-length string as List - STRING = CType.ctype.CSTRING - # Variable-length bytes (no guarantee of UTF8-ness) - BINARY = CType.ctype.CBINARY - # Fixed-size binary. Each value occupies the same number of bytes - FIXED_SIZE_BINARY = CType.ctype.CFIXED_SIZE_BINARY - # int32_t days since the UNIX epoch - DATE32 = CType.ctype.CDATE32 - # int64_t milliseconds since the UNIX epoch - DATE64 = CType.ctype.CDATE64 - # Exact timestamp encoded with int64 since UNIX epoch - # Default unit millisecond - TIMESTAMP = CType.ctype.CTIMESTAMP - # Time as signed 32-bit integer, representing either seconds or - # milliseconds since midnight - TIME32 = CType.ctype.CTIME32 - # Time as signed 64-bit integer, representing either microseconds or - # nanoseconds since midnight - TIME64 = CType.ctype.CTIME64 - # YEAR_MONTH or DAY_TIME interval in SQL style - INTERVAL = CType.ctype.CINTERVAL - # Precision- and scale-based decimal type. Storage type depends on the - # parameters. - DECIMAL = CType.ctype.CDECIMAL - # A list of some logical data type - LIST = CType.ctype.CLIST - # Custom data type, implemented by user - EXTENSION = CType.ctype.CEXTENSION - # Fixed size list of some logical type - FIXED_SIZE_LIST = CType.ctype.CFIXED_SIZE_LIST - # or nanoseconds. - DURATION = CType.ctype.CDURATION -cpdef enum Layout: - FIXED_WIDTH = CLayout.clayout.CFIXED_WIDTH - VARIABLE_WIDTH = CLayout.clayout.CVARIABLE_WIDTH + cdef class DataType: diff --git a/python/pycylon/pycylon/data/layout.pxd b/python/pycylon/pycylon/data/layout.pxd new file mode 100644 index 000000000..4dd749f9a --- /dev/null +++ b/python/pycylon/pycylon/data/layout.pxd @@ -0,0 +1,21 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + + + +cdef extern from "../../../../cpp/src/cylon/data_types.hpp" namespace "cylon": + cdef cppclass CLayout 'cylon::Layout': + enum clayout 'layout': + CFIXED_WIDTH 'cylon::Layout::FIXED_WIDTH' + CVARIABLE_WIDTH 'cylon::Layout::VARIABLE_WIDTH' \ No newline at end of file diff --git a/python/pycylon/pycylon/data/layout.pyx b/python/pycylon/pycylon/data/layout.pyx new file mode 100644 index 000000000..006f3cdfc --- /dev/null +++ b/python/pycylon/pycylon/data/layout.pyx @@ -0,0 +1,22 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + + + + + +cpdef enum Layout: + + FIXED_WIDTH = CLayout.clayout.CFIXED_WIDTH + VARIABLE_WIDTH = CLayout.clayout.CVARIABLE_WIDTH \ No newline at end of file diff --git a/python/pycylon/pycylon/net/comm_type.pxd b/python/pycylon/pycylon/net/comm_type.pxd index 86060d29c..e9bd5b276 100644 --- a/python/pycylon/pycylon/net/comm_type.pxd +++ b/python/pycylon/pycylon/net/comm_type.pxd @@ -23,4 +23,5 @@ cdef extern from "../../../../cpp/src/cylon/net/comm_type.hpp" namespace "cylon: _MPI 'cylon::net::CommType::MPI' _TCP 'cylon::net::CommType::TCP' _UCX 'cylon::net::CommType::UCX' - _GLOO 'cylon::net::CommType::GLOO' \ No newline at end of file + _GLOO 'cylon::net::CommType::GLOO' + _UCC 'cylon::net::CommType::UCC' \ No newline at end of file diff --git a/python/pycylon/pycylon/net/comm_type.pyx b/python/pycylon/pycylon/net/comm_type.pyx index 235cd921f..8b55f5c39 100644 --- a/python/pycylon/pycylon/net/comm_type.pyx +++ b/python/pycylon/pycylon/net/comm_type.pyx @@ -24,3 +24,4 @@ cpdef enum CommType: TCP = CCommType._TCP UCX = CCommType._UCX GLOO = CCommType._GLOO + UCC = CCommType._UCC diff --git a/python/pycylon/pycylon/net/communicator.pxd b/python/pycylon/pycylon/net/communicator.pxd index 4b2ccda37..4fc4abc76 100644 --- a/python/pycylon/pycylon/net/communicator.pxd +++ b/python/pycylon/pycylon/net/communicator.pxd @@ -15,11 +15,16 @@ from libcpp.memory cimport shared_ptr from pycylon.net.comm_config cimport CCommConfig from pycylon.net.comm_type cimport CCommType +from pycylon.net.reduce_op cimport CReduceOp +from pycylon.common.status cimport CStatus +from pycylon.data.scalar cimport CScalar + + cdef extern from "../../../../cpp/src/cylon/net/communicator.hpp" namespace "cylon::net": - cdef cppclass CCommunicator "cylon::net": - void Init(const shared_ptr[CCommConfig] &config) + cdef cppclass CCommunicator "cylon::net::Communicator": + # TODO: add create Channel int GetRank() int GetWorldSize() @@ -27,13 +32,12 @@ cdef extern from "../../../../cpp/src/cylon/net/communicator.hpp" namespace "cyl void Barrier() CCommType GetCommType() -cdef extern from "../../../../cpp/src/cylon/net/mpi/mpi_communicator.hpp" namespace "cylon::net": - cdef cppclass CMPICommunicator "cylon::net::MPICommunicator": - void Init(const shared_ptr[CCommConfig] &config) - int GetRank() - int GetWorldSize() - void Finalize() - void Barrier() - CCommType GetCommType() + CStatus AllReduce(const shared_ptr[CScalar] &value, + CReduceOp reduce_op, + shared_ptr[CScalar] *output) + +cdef class Communicator: + pass + diff --git a/python/pycylon/pycylon/net/communicator.pyx b/python/pycylon/pycylon/net/communicator.pyx index 102fc624a..bb1ee877a 100644 --- a/python/pycylon/pycylon/net/communicator.pyx +++ b/python/pycylon/pycylon/net/communicator.pyx @@ -12,10 +12,14 @@ # limitations under the License. ## -from pycylon.net.communicator cimport CMPICommunicator +from pycylon.net.reduce_op import ReduceOp -cdef class MPICommunicator: +cdef class Communicator: def __cinit__(self): - pass \ No newline at end of file + pass + + def allreduce(self, value, reduce_op: ReduceOp): + pass + diff --git a/python/pycylon/pycylon/net/mpi_communicator.pxd b/python/pycylon/pycylon/net/mpi_communicator.pxd new file mode 100644 index 000000000..1a9e1c90d --- /dev/null +++ b/python/pycylon/pycylon/net/mpi_communicator.pxd @@ -0,0 +1,41 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +from libcpp.memory cimport shared_ptr +from pycylon.net.comm_type cimport CCommType +from pycylon.net.reduce_op cimport CReduceOp +from pycylon.common.status cimport CStatus +from pycylon.data.scalar cimport CScalar +from pycylon.net.communicator cimport Communicator + + +cdef extern from "../../../../cpp/src/cylon/net/mpi/mpi_communicator.hpp" namespace "cylon::net": + cdef cppclass CMPICommunicator "cylon::net::MPICommunicator": + + int GetRank() + int GetWorldSize() + void Finalize() + void Barrier() + CCommType GetCommType() + + CStatus AllReduce(const shared_ptr[CScalar] & value, + CReduceOp reduce_op, + shared_ptr[CScalar] *output) + + +cdef class MPICommunicator(Communicator): + cdef: + shared_ptr[CMPICommunicator] mpi_comm_shd_ptr + + void init(self, const shared_ptr[CMPICommunicator] & communicator) \ No newline at end of file diff --git a/python/pycylon/pycylon/net/mpi_communicator.pyx b/python/pycylon/pycylon/net/mpi_communicator.pyx new file mode 100644 index 000000000..fb166c570 --- /dev/null +++ b/python/pycylon/pycylon/net/mpi_communicator.pyx @@ -0,0 +1,43 @@ + +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + + + + +from pycylon.net.communicator cimport Communicator + +from pycylon.net.reduce_op import ReduceOp +import pyarrow as pa +from pyarrow.lib cimport pyarrow_wrap_scalar +from pycylon.data.scalar cimport CScalar +from libcpp.memory cimport shared_ptr +from pycylon.data.scalar cimport Scalar + + +cdef class MPICommunicator(Communicator): + + def __cinit__(self): + pass + + cdef void init(self, const shared_ptr[CMPICommunicator]& communicator): + self.mpi_comm_shd_ptr = communicator + + def allreduce(self, value, reduce_op: ReduceOp): + cdef shared_ptr[CScalar] cresult + scalarv = Scalar(pa.scalar(value)) + + self.mpi_comm_shd_ptr.get().AllReduce(scalarv.thisPtr, reduce_op, &cresult) + + return pyarrow_wrap_scalar(cresult.get().data()).as_py() \ No newline at end of file diff --git a/python/pycylon/pycylon/net/oob_type.pxd b/python/pycylon/pycylon/net/oob_type.pxd new file mode 100644 index 000000000..264dc8e56 --- /dev/null +++ b/python/pycylon/pycylon/net/oob_type.pxd @@ -0,0 +1,23 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +''' +OOB Type mapping from Cylon C++ API +''' + +cdef extern from "../../../../cpp/src/cylon/net/ucx/oob_type.hpp" namespace "cylon::net": + + cdef enum COOBType 'cylon::net::OOBType': + _OOB_MPI 'cylon::net::OOBType::OOB_MPI' + _OOB_REDIS 'cylon::net::OOBType::OOB_REDIS' diff --git a/python/pycylon/pycylon/net/oob_type.pyx b/python/pycylon/pycylon/net/oob_type.pyx new file mode 100644 index 000000000..394023117 --- /dev/null +++ b/python/pycylon/pycylon/net/oob_type.pyx @@ -0,0 +1,24 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +''' +Mapping Cylon C++ Comm Type with PyCylon CommType +''' + +from pycylon.net.oob_type cimport COOBType + +cpdef enum OOBType: + OOB_MPI = COOBType._OOB_MPI + OOB_REDIS = COOBType._OOB_REDIS + diff --git a/python/pycylon/pycylon/net/redis_ucc_oob_context.pxd b/python/pycylon/pycylon/net/redis_ucc_oob_context.pxd new file mode 100644 index 000000000..0c64eb8ba --- /dev/null +++ b/python/pycylon/pycylon/net/redis_ucc_oob_context.pxd @@ -0,0 +1,51 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX & CYTHON_UCC & CYTHON_REDIS: + + + from libcpp.memory cimport shared_ptr + from pycylon.net.oob_type cimport COOBType + from pycylon.net.ucx_oob_context cimport CUCXOOBContext + from pycylon.net.ucc_oob_context cimport UCCOOBContext + from pycylon.net.redis_ucx_oob_context cimport CUCXRedisOOBContext + from pycylon.common.status cimport CStatus + from libcpp.string cimport string + + cdef extern from "../../../../cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.hpp" namespace "cylon::net": + cdef cppclass CUCCRedisOOBContext "cylon::net::UCCRedisOOBContext": + COOBType Type() + + CUCCRedisOOBContext(int world_size, string redis_addr) + + CUCCRedisOOBContext() + + shared_ptr[CUCXOOBContext] makeUCXOOBContext() + + int getWorldSize() + + int getRank() + + + @ staticmethod + shared_ptr[CUCCRedisOOBContext] Make(int world_size, string redis_addr); + + cdef class UCCRedisOOBContext(UCCOOBContext): + cdef: + + shared_ptr[CUCCRedisOOBContext] ucc_redis_oob_context_shd_ptr + + + + diff --git a/python/pycylon/pycylon/net/redis_ucc_oob_context.pyx b/python/pycylon/pycylon/net/redis_ucc_oob_context.pyx new file mode 100644 index 000000000..4672c4d29 --- /dev/null +++ b/python/pycylon/pycylon/net/redis_ucc_oob_context.pyx @@ -0,0 +1,47 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX & CYTHON_UCC & CYTHON_REDIS: + + from pycylon.net.redis_ucc_oob_context cimport CUCCRedisOOBContext + from pycylon.net.redis_ucx_oob_context cimport CUCXRedisOOBContext + from pycylon.net.ucx_oob_context cimport CUCXOOBContext + from libcpp.memory cimport make_shared + + ''' + UCCRedisOOBContext Mapping from Cylon C++ + ''' + + cdef class UCCRedisOOBContext: + + def __cinit__(self, world_size: int, redis_addr : str ): + + if world_size !=-1 : + self.ucc_redis_oob_context_shd_ptr = CUCCRedisOOBContext.Make(world_size, redis_addr.encode()) + else: + self.ucc_redis_oob_context_shd_ptr = make_shared[CUCCRedisOOBContext]() + + + @property + def oob_type(self): + return self.ucc_redis_oob_context_shd_ptr.get().Type() + + @property + def oob_worldsize(self): + return self.ucc_redis_oob_context_shd_ptr.get().getWorldSize() + + @property + def oob_rank(self): + return self.ucc_redis_oob_context_shd_ptr.get().getRank() + diff --git a/python/pycylon/pycylon/net/redis_ucx_oob_context.pxd b/python/pycylon/pycylon/net/redis_ucx_oob_context.pxd new file mode 100644 index 000000000..ad10fef65 --- /dev/null +++ b/python/pycylon/pycylon/net/redis_ucx_oob_context.pxd @@ -0,0 +1,33 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX & CYTHON_UCC & CYTHON_REDIS: + + from pycylon.common.status cimport CStatus + from pycylon.net.ucx_oob_context cimport UCXOOBContext + from libcpp.string cimport string + from libcpp.memory cimport shared_ptr + + cdef extern from "../../../../cpp/src/cylon/net/ucx/redis_ucx_ucc_oob_context.hpp" namespace "cylon::net": + cdef cppclass CUCXRedisOOBContext "cylon::net::UCXRedisOOBContext": + CStatus getWorldSizeAndRank(int &world_size, int &rank) + + CUCXRedisOOBContext(int world_size, string redis_addr) + + @ staticmethod + shared_ptr[CUCXRedisOOBContext] Make(int world_size, string redis_addr); + cdef class UCXRedisOOBContext(UCXOOBContext): + + cdef: + shared_ptr[CUCXRedisOOBContext] ucx_redis_oob_context_shd_ptr \ No newline at end of file diff --git a/python/pycylon/pycylon/net/redis_ucx_oob_context.pyx b/python/pycylon/pycylon/net/redis_ucx_oob_context.pyx new file mode 100644 index 000000000..ec5f739eb --- /dev/null +++ b/python/pycylon/pycylon/net/redis_ucx_oob_context.pyx @@ -0,0 +1,25 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX & CYTHON_UCC & CYTHON_REDIS: + + from pycylon.net.redis_ucx_oob_context cimport CUCXRedisOOBContext + from libcpp.memory cimport make_shared + + + cdef class UCXRedisOOBContext: + + + def __cinit__(self, int world_size, string redis_addr): + self.ucx_redis_oob_context_shd_ptr = make_shared[CUCXRedisOOBContext](world_size, redis_addr) \ No newline at end of file diff --git a/python/pycylon/pycylon/net/reduce_op.pxd b/python/pycylon/pycylon/net/reduce_op.pxd new file mode 100644 index 000000000..0e15f6f5a --- /dev/null +++ b/python/pycylon/pycylon/net/reduce_op.pxd @@ -0,0 +1,29 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +''' +OOB Type mapping from Cylon C++ API +''' + +cdef extern from "../../../../cpp/src/cylon/net/comm_operations.hpp" namespace "cylon::net": + + cdef enum CReduceOp 'cylon::net::ReduceOp': + _SUM 'cylon::net::ReduceOp::SUM' + _MIN 'cylon::net::ReduceOp::MIN' + _MAX 'cylon::net::ReduceOp::MAX' + _PROD 'cylon::net::ReduceOp::PROD' + _LAND 'cylon::net::ReduceOp::LAND' + _LOR 'cylon::net::ReduceOp::LOR' + _BAND 'cylon::net::ReduceOp::BAND' + _BOR 'cylon::net::ReduceOp::BOR' \ No newline at end of file diff --git a/python/pycylon/pycylon/net/reduce_op.pyx b/python/pycylon/pycylon/net/reduce_op.pyx new file mode 100644 index 000000000..d25e0fa83 --- /dev/null +++ b/python/pycylon/pycylon/net/reduce_op.pyx @@ -0,0 +1,29 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +''' +Mapping Cylon C++ Comm Type with PyCylon CommType +''' + +from pycylon.net.reduce_op cimport CReduceOp + +cpdef enum ReduceOp: + SUM = CReduceOp._SUM + MIN = CReduceOp._MIN + MAX = CReduceOp._MAX + PROD = CReduceOp._PROD + LAND = CReduceOp._LAND + LOR = CReduceOp._LOR + BAND = CReduceOp._BAND + BOR = CReduceOp._BOR \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucc_config.pxd b/python/pycylon/pycylon/net/ucc_config.pxd new file mode 100644 index 000000000..bbc4bd918 --- /dev/null +++ b/python/pycylon/pycylon/net/ucc_config.pxd @@ -0,0 +1,35 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +IF CYTHON_UCC: + from libcpp.memory cimport shared_ptr + + from mpi4py.libmpi cimport MPI_Comm + + from pycylon.net.comm_type cimport CCommType + from pycylon.net.comm_config cimport CommConfig + from pycylon.net.ucc_oob_context cimport CUCCOOBContext + + cdef extern from "../../../../cpp/src/cylon/net/ucx/ucx_communicator.hpp" namespace "cylon::net": + cdef cppclass CUCCConfig "cylon::net::UCCConfig": + CCommType Type() + + @ staticmethod + shared_ptr[CUCCConfig] Make(shared_ptr[CUCCOOBContext] &oobContext); + + + cdef class UCCConfig(CommConfig): + cdef: + shared_ptr[CUCCConfig] ucc_config_shd_ptr + shared_ptr[CUCCOOBContext] ucc_oob_context_ptr diff --git a/python/pycylon/pycylon/net/ucc_config.pyx b/python/pycylon/pycylon/net/ucc_config.pyx new file mode 100644 index 000000000..22294d19d --- /dev/null +++ b/python/pycylon/pycylon/net/ucc_config.pyx @@ -0,0 +1,46 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +IF CYTHON_UCC: + from pycylon.net.comm_config cimport CommConfig + from pycylon.net.ucc_config cimport CUCCConfig + from pycylon.net.ucc_oob_context cimport CUCCOOBContext + IF CYTHON_REDIS: + from pycylon.net.redis_ucc_oob_context cimport UCCRedisOOBContext + + from pycylon.net.ucc_oob_context cimport UCCOOBContext + from libcpp.memory cimport shared_ptr, dynamic_pointer_cast + + + + cdef class UCCConfig(CommConfig): + """ + UCCConfig Type mapping from libCylon to PyCylon + """ + def __cinit__(self, object context): + IF CYTHON_REDIS: + if isinstance(context, UCCRedisOOBContext): + self.ucc_oob_context_ptr = ( context).ucc_redis_oob_context_shd_ptr + + self.ucc_config_shd_ptr = CUCCConfig.Make(self.ucc_oob_context_ptr) + + print("initialized Redis UCC Config context") + + else: + raise ValueError('Passed object is not an instance of UCCOOBContext') + + + @property + def comm_type(self): + return self.ucc_config_shd_ptr.get().Type() \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucc_oob_context.pxd b/python/pycylon/pycylon/net/ucc_oob_context.pxd new file mode 100644 index 000000000..1be03ed21 --- /dev/null +++ b/python/pycylon/pycylon/net/ucc_oob_context.pxd @@ -0,0 +1,24 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCC: + + from pycylon.net.oob_type cimport COOBType + + cdef extern from "../../../../cpp/src/cylon/net/ucx/ucc_oob_context.hpp" namespace "cylon::net": + cdef cppclass CUCCOOBContext "cylon::net::UCCOOBContext": + COOBType Type() + + cdef class UCCOOBContext: + pass \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucc_oob_context.pyx b/python/pycylon/pycylon/net/ucc_oob_context.pyx new file mode 100644 index 000000000..ce32d18e1 --- /dev/null +++ b/python/pycylon/pycylon/net/ucc_oob_context.pyx @@ -0,0 +1,30 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCC: + + from pycylon.net.ucc_oob_context cimport CUCCOOBContext + + ''' + UCC Context Mapping from Cylon C++ + ''' + + + cdef class UCCOOBContext: + + def __cinit__(self): + pass + + def comm_type(self): + pass \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucc_ucx_communicator.pxd b/python/pycylon/pycylon/net/ucc_ucx_communicator.pxd new file mode 100644 index 000000000..2a9444ee6 --- /dev/null +++ b/python/pycylon/pycylon/net/ucc_ucx_communicator.pxd @@ -0,0 +1,43 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX & CYTHON_UCC: + + from libcpp.memory cimport shared_ptr + from pycylon.net.comm_type cimport CCommType + from pycylon.net.reduce_op cimport CReduceOp + from pycylon.common.status cimport CStatus + from pycylon.data.scalar cimport CScalar + from pycylon.net.communicator cimport Communicator + + + cdef extern from "../../../../cpp/src/cylon/net/ucx/ucx_communicator.hpp" namespace "cylon::net": + cdef cppclass CUCXUCCCommunicator "cylon::net::UCXUCCCommunicator": + + int GetRank() + int GetWorldSize() + void Finalize() + void Barrier() + CCommType GetCommType() + + CStatus AllReduce(const shared_ptr[CScalar] & value, + CReduceOp reduce_op, + shared_ptr[CScalar] *output) + + + cdef class UCXUCCCommunicator(Communicator): + cdef: + shared_ptr[CUCXUCCCommunicator] ucc_cucx_comm_shd_ptr + + void init(self, const shared_ptr[CUCXUCCCommunicator] & communicator) \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucc_ucx_communicator.pyx b/python/pycylon/pycylon/net/ucc_ucx_communicator.pyx new file mode 100644 index 000000000..c2b24ded7 --- /dev/null +++ b/python/pycylon/pycylon/net/ucc_ucx_communicator.pyx @@ -0,0 +1,48 @@ + +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX & CYTHON_UCC: + + + from pycylon.net.communicator cimport Communicator + from pycylon.net.ucc_ucx_communicator cimport CUCXUCCCommunicator + from pycylon.data.scalar cimport Scalar + from pycylon.data.scalar cimport CScalar + from libcpp.memory cimport shared_ptr + from pycylon.net.reduce_op import ReduceOp + import pyarrow as pa + from pyarrow.lib cimport pyarrow_wrap_scalar + + + cdef class UCXUCCCommunicator(Communicator): + + def __cinit__(self): + pass + + cdef void init(self, const shared_ptr[CUCXUCCCommunicator]& communicator): + self.ucc_cucx_comm_shd_ptr = communicator + + + def allreduce(self, value, reduce_op: ReduceOp): + cdef shared_ptr[CScalar] cresult + scalarv = Scalar(pa.scalar(value)) + + self.ucc_cucx_comm_shd_ptr.get().AllReduce(scalarv.thisPtr, reduce_op, &cresult) + + return pyarrow_wrap_scalar(cresult.get().data()).as_py() + + + + diff --git a/python/pycylon/pycylon/net/ucx_communicator.pxd b/python/pycylon/pycylon/net/ucx_communicator.pxd new file mode 100644 index 000000000..95b77e957 --- /dev/null +++ b/python/pycylon/pycylon/net/ucx_communicator.pxd @@ -0,0 +1,43 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX: + + from libcpp.memory cimport shared_ptr + from pycylon.net.comm_type cimport CCommType + from pycylon.net.reduce_op cimport CReduceOp + from pycylon.common.status cimport CStatus + from pycylon.data.scalar cimport CScalar + from pycylon.net.communicator cimport Communicator + + + cdef extern from "../../../../cpp/src/cylon/net/ucx/ucx_communicator.hpp" namespace "cylon::net": + cdef cppclass CUCXCommunicator "cylon::net::UCXCommunicator": + + int GetRank() + int GetWorldSize() + void Finalize() + void Barrier() + CCommType GetCommType() + + CStatus AllReduce(const shared_ptr[CScalar] & value, + CReduceOp reduce_op, + shared_ptr[CScalar] *output) + + + cdef class UCXCommunicator(Communicator): + cdef: + shared_ptr[CUCXCommunicator] ucc_cucx_comm_shd_ptr + + void init(self, const shared_ptr[CUCXCommunicator] & communicator) \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucx_communicator.pyx b/python/pycylon/pycylon/net/ucx_communicator.pyx new file mode 100644 index 000000000..bb2cfe442 --- /dev/null +++ b/python/pycylon/pycylon/net/ucx_communicator.pyx @@ -0,0 +1,44 @@ + +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX: + + + from pycylon.net.communicator cimport Communicator + from pycylon.net.ucx_communicator cimport CUCXCommunicator + from pycylon.data.scalar cimport Scalar + from pycylon.data.scalar cimport CScalar + from libcpp.memory cimport shared_ptr + from pycylon.net.reduce_op import ReduceOp + import pyarrow as pa + from pyarrow.lib cimport pyarrow_wrap_scalar + + + cdef class UCXCommunicator(Communicator): + + def __cinit__(self): + pass + + cdef void init(self, const shared_ptr[CUCXCommunicator]& communicator): + self.ucc_cucx_comm_shd_ptr = communicator + + + def allreduce(self, value, reduce_op: ReduceOp): + cdef shared_ptr[CScalar] cresult + scalarv = Scalar(pa.scalar(value)) + + self.ucc_cucx_comm_shd_ptr.get().AllReduce(scalarv.thisPtr, reduce_op, &cresult) + + return pyarrow_wrap_scalar(cresult.get().data()).as_py() \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucx_oob_context.pxd b/python/pycylon/pycylon/net/ucx_oob_context.pxd new file mode 100644 index 000000000..dc234775c --- /dev/null +++ b/python/pycylon/pycylon/net/ucx_oob_context.pxd @@ -0,0 +1,23 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX : + + from pycylon.common.status cimport CStatus + + cdef extern from "../../../../cpp/src/cylon/net/ucx/ucx_oob_context.hpp" namespace "cylon::net": + cdef cppclass CUCXOOBContext "cylon::net::UCXOOBContext": + CStatus getWorldSizeAndRank(int &world_size, int &rank) + cdef class UCXOOBContext: + pass \ No newline at end of file diff --git a/python/pycylon/pycylon/net/ucx_oob_context.pyx b/python/pycylon/pycylon/net/ucx_oob_context.pyx new file mode 100644 index 000000000..bbf1dc58f --- /dev/null +++ b/python/pycylon/pycylon/net/ucx_oob_context.pyx @@ -0,0 +1,28 @@ +## + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + ## + +IF CYTHON_UCX : + + from pycylon.net.ucx_oob_context cimport CUCXOOBContext + + ''' + UCXOOBContext Mapping from Cylon C++ + ''' + + + cdef class UCXOOBContext: + + def __cinit__(self): + pass + diff --git a/python/pycylon/run_ucc_with_redis.py b/python/pycylon/run_ucc_with_redis.py new file mode 100644 index 000000000..5b939850f --- /dev/null +++ b/python/pycylon/run_ucc_with_redis.py @@ -0,0 +1,26 @@ +import os +import argparse +import subprocess +import redis + +def main(world_size: int, redis_addr: str, executable_name: str): + host, port = redis_addr.split(':') + r = redis.Redis(host, int(port), db=0) + r.flushall() + d = dict(os.environ) + d["CYLON_UCX_OOB_WORLD_SIZE"] = str(world_size) + d["CYLON_UCX_OOB_REDIS_ADDR"] = redis_addr + children = [] + for _ in range(world_size): + children.append(subprocess.Popen(executable_name, env=d)) + + for child in children: + child.wait() + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('--world_size', "-n", type=int, help="world size") + parser.add_argument("--redis_addr", "-r", type=str, help="redis address, default to 127.0.0.1:6379", default="127.0.0.1:6379") + parser.add_argument("--execute", "-e", type=str, help="name of executable") + args = parser.parse_args() + main(args.world_size, args.redis_addr, args.execute) diff --git a/python/pycylon/setup.py b/python/pycylon/setup.py index b2bc9da38..b51a67f81 100644 --- a/python/pycylon/setup.py +++ b/python/pycylon/setup.py @@ -42,11 +42,19 @@ GLOO_PREFIX = os.environ.get('GLOO_PREFIX') CYLON_UCX = strtobool(os.environ.get('CYLON_UCX') or '0') CYLON_UCC = strtobool(os.environ.get('CYLON_UCC') or '0') +CYLON_REDIS = strtobool(os.environ.get('CYLON_REDIS') or '0') UCC_PREFIX = os.environ.get('UCC_PREFIX') +REDIS_PREFIX = os.environ.get('REDIS_PREFIX') print("Cylon prefix:", CYLON_PREFIX) print("Arrow prefix:", ARROW_PREFIX) print("Arrow version:", pyarrow_version) +print("UCC prefix:", UCC_PREFIX) +print("CYLON REDIS: ", CYLON_REDIS) +print("REDIS prefix:", REDIS_PREFIX) + + + OS_NAME = platform.system() @@ -142,7 +150,7 @@ macros = [] # compile_time_env serves as preprocessor macros. ref: https://github.com/cython/cython/issues/2488 -compile_time_env = {'CYTHON_GLOO': False, 'CYTHON_UCC': False, 'CYTHON_UCX': False} +compile_time_env = {'CYTHON_GLOO': False, 'CYTHON_UCC': False, 'CYTHON_UCX': False, 'CYTHON_REDIS': False} if CYLON_GLOO: libraries.append('gloo') library_dirs.append(os.path.join(GLOO_PREFIX, 'lib')) @@ -166,6 +174,18 @@ macros.append(('BUILD_CYLON_UCX', '0')) macros.append(('BUILD_CYLON_UCC', '0')) +if CYLON_REDIS: + libraries.append('hiredis') + libraries.append('redis++') + macros.append(('BUILD_CYLON_REDIS', '1')) + compile_time_env['CYTHON_REDIS'] = True + library_dirs.append(os.path.join(REDIS_PREFIX, 'lib')) + include_dirs.append(os.path.join(REDIS_PREFIX, 'include', 'sw')) + include_dirs.append(os.path.join(REDIS_PREFIX, 'include', 'hiredis')) +else: + macros.append(('BUILD_CYLON_REDIS', '0')) + + print('Libraries :', libraries) print("Lib dirs :", library_dirs) print("Include dirs :", include_dirs)