{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Benchmark" ] }, { "cell_type": "code", "execution_count": 155, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Settings\n", "root_dir = '/home/dennis/VILLASnode/tests/benchmarks'\n", "benchmark_dir = 'benchmarks_20180801_00-11-11'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load all files\n", "### Results\n", "...\n", "\n", "### Source log\n", "..." ] }, { "cell_type": "code", "execution_count": 156, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loaded /home/dennis/VILLASnode/tests/benchmarks/benchmarks_20180801_00-11-11/0_TCP-3-100000-1000000.csv\n" ] } ], "source": [ "import numpy as np\n", "import os\n", "import re\n", "\n", "# First, source log\n", "\n", "# Initialize arrays\n", "result_files = []\n", "result_paths = []\n", "log_paths = []\n", "result_array = []\n", "\n", "# Save complete path of files in an array\n", "for subdir, dirs, files in os.walk(root_dir+'/'+benchmark_dir):\n", " for file in files:\n", " # Regex to match .csv files\n", " if re.match(r'.*?csv', file, re.M|re.I):\n", " result_paths.append(os.path.join(subdir, file))\n", " # Regex to match .log files\n", " elif re.match(r'.*?log', file, re.M|re.I):\n", " log_paths.append(os.path.join(subdir, file))\n", " \n", " result_files = files\n", "\n", "# Loop through array with result files and save the comma separated data into a new array\n", "for file in result_paths:\n", " print(\"Loaded {}\".format(file))\n", " \n", " # Load file \n", " result_array.append(np.genfromtxt(file, delimiter=','))\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Save characteristics of tests\n", "All important settings are contained in the name of the file. We will save them in a separate array. The structure of the name is as follows:\n", "\n", "```bash\n", "root_dir/benchmarks_${DATE}/${ID}_${MODE}-${VALUES IN SMP}-${RATE}-${SENT SMPS}\n", "```\n", "\n", "Thus, we will structure it in the settings_array as follows:\n", "\n", "* `settings_array[*][0] = ID`\n", "* `settings_array[*][1] = MODE`\n", "* `settings_array[*][2] = VALUES IN SAMPLE`\n", "* `settings_array[*][3] = RATE`\n", "* `settings_array[*][4] = TOTAL NUMBER OF SAMPLES`" ] }, { "cell_type": "code", "execution_count": 157, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Array with settings\n", "settings_array = []\n", "\n", "for file in result_files:\n", " settings = []\n", " \n", " matchObj = re.match(r'(\\d*)_(\\w*)-(\\d*)-(\\d*)-(\\d*).csv', file, re.M|re.I)\n", "\n", " # Fill values to array\n", " if matchObj:\n", " for i in range(0,5):\n", " settings.append(matchObj.group(i+1))\n", " \n", " # Append array to big array\n", " settings_array.append(settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Get missed steps from source node\n", "..." ] }, { "cell_type": "code", "execution_count": 161, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "540\n" ] } ], "source": [ "missing_send_arr = []\n", "\n", "# This line indicates if we passed the \"node connected\" line. Only after this line\n", "# the script will start counting missed steps\n", "connected = False\n", "\n", "for i, file in enumerate(log_paths):\n", " F = open(file, \"r\")\n", " line = F.readline()\n", "\n", " missing_send_arr.append(0)\n", "\n", " # Loop through file\n", " while line:\n", " #if re.match(r'.*Connection established in node', line):\n", " connected = True\n", " \n", " if connected:\n", " #matchObj = re.match(r'.*Missed steps: (\\d*)', line, re.M|re.I)\n", " matchObj = re.match(r'.*written=0, expected=(\\d*)', line, re.M|re.I)\n", " \n", " if matchObj:\n", " missing_send_arr[i] += int(matchObj.group(1))\n", " \n", " line = F.readline()\n", " \n", " print(missing_send_arr[i])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Process data\n", "\n", "### Number of samples\n", "* First number which appears in `result_array[*][3]` will be the first sample in the benchmark. Ignore all missing samples before that entry.\n", "* After that, check how many samples are missing.\n", "* Then, calculate the percentage of missing samples." ] }, { "cell_type": "code", "execution_count": 162, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Test 0 missed 68 (0.011%) of 995605 (1000000 before correction) samples\n" ] } ], "source": [ "# Sequence number of first sample that occurs are receive side\n", "start_sequence = []\n", "# Real total number of sent messages, after subtraction of first sequence\n", "real_total_arr = []\n", "# Number of missing samples after first sample\n", "missing_recv_arr = []\n", "# Percentage of missed samples\n", "perc_miss_arr = []\n", "\n", "# Generate real total and number of missing samples.\n", "# Print percentage of missed samples\n", "for (i, csv_vec) in enumerate(result_array):\n", " start_sequence.append(csv_vec[0][3])\n", " \n", " # Real total number = total number - start_seqquence\n", " # Number missing = real total number - length of data arary\n", " real_total = int(settings_array[i][4]) - int(start_sequence[i])\n", " missing_recv = real_total - len(csv_vec)\n", " perc_miss = round(missing_recv / real_total * 100, 3)\n", " \n", " print(\"Test {} missed {} ({}%) of {} ({} before correction) samples\"\n", " .format(i, number_miss, perc_miss, real_total, settings_array[i][4]))\n", " \n", " real_total_arr.append(real_total)\n", " missing_recv_arr.append(number_miss)\n", " perc_miss_arr.append(perc_miss)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Plot data\n", "We want to plot the offset" ] }, { "cell_type": "code", "execution_count": 107, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "from matplotlib.font_manager import FontProperties\n", "import os\n", "\n", "# Start creating plots\n", "for i, val in enumerate(result_array):\n", " # Create figure\n", " fig = plt.figure(num=None, figsize=(12, 8), dpi=90, facecolor='w', edgecolor='k')\n", "\n", " # Add plot and set title\n", " ax = fig.add_subplot(111)\n", " \n", " # Set subtitle \n", " title = \"Test {} — Mode: {}, Values in Sample: {}, Rate: {}, Total number of Samples: {}\".format(settings_array[i][0],\n", " settings_array[i][1], \n", " settings_array[i][2], \n", " settings_array[i][3], \n", " settings_array[i][4])\n", " ax.set_title(title, fontsize=12, pad=12, loc='center')\n", " \n", " # Set grid\n", " ax.set_axisbelow(True)\n", " ax.grid(True, linestyle='--')\n", "\n", " bins = 6250\n", " x_limit=0.0001\n", " \n", " # Data in plot\n", " # http://www.color-hex.com/color-palette/33602\n", " val_t = val.transpose()\n", " \n", " ax.hist(val_t[2], label='t_sent -> t_recv offset', edgecolor='black', bins=bins, color='#00549f')\n", "\n", " # Set axis and calculate values above limit\n", " plt.xlim([0,x_limit])\n", " \n", "\n", " plt.xticks(np.arange(0, x_limit + 0.000001, 0.00001), fontsize=11)\n", " plt.yticks(fontsize=11)\n", "\n", " # Labels\n", " ax.set_xlabel('time [s]', fontsize=13, labelpad=20)\n", " ax.set_ylabel('frequency', fontsize=13, labelpad=20)\n", " ax.set_yscale('log')\n", "\n", " # Create text for offset\n", " off_smaller_4us = round((np.size(val_t[2][val_t[2] < 0.000004]) / np.size(val_t[2])) * 100, 3)\n", " off_smaller_5us = round((np.size(val_t[2][val_t[2] < 0.000005]) / np.size(val_t[2])) * 100, 3)\n", " off_smaller_10us = round((np.size(val_t[2][val_t[2] < 0.00001]) / np.size(val_t[2])) * 100, 3)\n", " off_bigger_100us = round((np.size(val_t[2][val_t[2] > x_limit]) / np.size(val_t[2])) * 100, 4)\n", " \n", " offset_text = 'offset < {} for {}% of samples\\n'.format('4µs', off_smaller_4us)\n", " offset_text += 'offset < {} for {}% of samples\\n'.format('5µs', off_smaller_5us)\n", " offset_text += 'offset < {} for {}% of samples\\n'.format('10µs', off_smaller_10us)\n", " offset_text += 'offset > {} for {}% of samples'.format('100µs', off_bigger_100us)\n", " \n", " # Create text for missed steps\n", " #ToDo: Add percentage\n", " missed_text = 'missed by villas-pipe: {0: <23}\\n'.format(missing_recv_arr[i])\n", " missed_text += 'missed by villas-node: {0: <23}'.format(0)\n", " \n", " # bbox accepts FancyBboxPatch prop dict\n", " font_header = FontProperties()\n", " font_header.set_weight('bold')\n", " font_header.set_size(10)\n", " \n", " # Offset boxes\n", " ax.text(0.983, 0.88, \"Offset Ranges\",\n", " verticalalignment='top', horizontalalignment='right',\n", " transform=ax.transAxes,\n", " color='black', fontproperties = font_header)\n", " ax.text(0.712, 0.84, offset_text,\n", " verticalalignment='top', horizontalalignment='left',\n", " transform=ax.transAxes,\n", " color='black', fontsize=9.25,\n", " bbox={'facecolor':'white', 'alpha':0.85, 'pad':0.3, 'boxstyle':'round',\n", " 'edgecolor':'#dbdbdb'})\n", " \n", " # Missed steps\n", " ax.text(0.983, 0.70, \"Missed steps\",\n", " verticalalignment='top', horizontalalignment='right',\n", " transform=ax.transAxes,\n", " color='black', fontproperties = font_header)\n", " ax.text(0.712, 0.66, missed_text,\n", " verticalalignment='top', horizontalalignment='left',\n", " transform=ax.transAxes,\n", " color='black', fontsize=9.25,\n", " bbox={'facecolor':'white', 'alpha':0.85, 'pad':0.3, 'boxstyle':'round',\n", " 'edgecolor':'#dbdbdb'})\n", "\n", " #Create legend\n", " ax.legend(loc=1, fontsize=12)\n", " \n", "\n", " #Show plot\n", " plt.show()\n", " \n", " #Save plot\n", " fig.savefig('./plots/test{}.png'.format(i))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 2 }