diff --git a/.gitignore b/.gitignore index 4ea83cbf7e12..f402cb1e83e0 100644 --- a/.gitignore +++ b/.gitignore @@ -98,3 +98,5 @@ dist/ # For Hive metastore_db/ + +.ipynb_checkpoints diff --git a/tools/workload/benchmark_velox/README.md b/tools/workload/benchmark_velox/README.md index 5f080077f606..b1e7a2f795b8 100644 --- a/tools/workload/benchmark_velox/README.md +++ b/tools/workload/benchmark_velox/README.md @@ -36,3 +36,30 @@ We also provide a script [run_tpc_workload.sh](./run_tpc_workload.sh). This scri ## Analyzing Performance Results You can check the **Show Performance** section in the output notebook after execution. It shows the cpu% per query, and draws charts for the cpu%, memory throughput, disk throughput/util%, network throughput and pagefaults. + +## Set up Performance Analysis Tools + +Please check the **Set up perf analysis tools (optional)** section in [initialize.ipynb](./initialize.ipynb) to set up the environment required for running performance analysis scripts. Once the setup is complete, update the following variables in your YAML file (as documented in [params.yaml.template](./params.yaml.template)) before running TPC-H/TPC-DS Benchmarks: + +- server: Hostname or IP to server for perf analysis. Able to connect via ssh. Can be localhost if you deploy the perf analysis scripts on the local cluster. +- base_dir: Specify the directory on perf analysis server. Usually a codename for this run. +- analyze_perf: Whether to upload profile to perf analysis server and run perf analysis scripts. Only takes effect if server is set. In this case set to `True` +- proxy: Proxy used to connect to server for perf analysis. Only needed if the perf analysis server is accessed via proxy. + +After the workload completes, the tool generates a notebook, executes it automatically, and saves the output notebook in the `$HOME/PAUS/base_dir` directory with a suffix of `[APPLICATION ID].nbconvert.ipynb`. Additionally, the output notebook is converted into an HTML format for improved readability, with the same filename, and stored in the `html` sub-folder. + +A sample generated notebook for TPCH Q1 and its corresponding HTML file are available for reference: +- Notebook: [tpch_q1.nbconvert.ipynb](./sample/tpch_q1.nbconvert.ipynb) +- HTML file: [tpch_q1.html](./sample/tpch_q1.html) + +The notebook also produces a trace-viewer JSON file to analyze workload statistics. This includes SAR metrics and stage/task-level breakdowns. Using this tool, users can compare statistics across stages and queries, identify performance bottlenecks, and target specific stages for optimization. + +You can explore the sample trace-viewer JSON file using the Google Chrome browser. To do so: + +1. Download the sample file [trace_result_tpch_q1.json](./sample/trace_result_tpch_q1.json) +2. Launch Google Chrome. In the address bar, enter "chrome://tracing/". +3. Use the "Load" button to upload the sample JSON file. + +This will allow you to check the sample trace data interactively. + +![trace-result-tpch-q1](./sample/Trace-viewer.png) diff --git a/tools/workload/benchmark_velox/analysis/perf_analysis_template.ipynb b/tools/workload/benchmark_velox/analysis/perf_analysis_template.ipynb new file mode 100644 index 000000000000..8682b209d5f1 --- /dev/null +++ b/tools/workload/benchmark_velox/analysis/perf_analysis_template.ipynb @@ -0,0 +1,436 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "appid=''\n", + "disk=''\n", + "nic=''\n", + "tz=''\n", + "base_dir=''\n", + "name=''\n", + "notebook=''\n", + "notebook_html=''\n", + "proxy=''\n", + "emails=''\n", + "pr=''\n", + "\n", + "comp_appid=''\n", + "comp_base_dir=''\n", + "comp_name=''\n", + "\n", + "baseline_appid=''\n", + "baseline_base_dir=''" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import findspark\n", + "findspark.init()\n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "from pyspark import SparkConf, SparkContext\n", + "from pyspark.sql import SQLContext\n", + "\n", + "def get_py4jzip():\n", + " spark_home=os.environ['SPARK_HOME']\n", + " py4jzip = !ls {spark_home}/python/lib/py4j*.zip\n", + " return py4jzip[0]\n", + "\n", + "conf = (SparkConf()\n", + " .set('spark.app.name', f'perf_analysis_{appid}')\n", + " .set('spark.serializer','org.apache.spark.serializer.KryoSerializer')\n", + " .set('spark.executor.instances', '4')\n", + " .set('spark.executor.cores','4')\n", + " .set('spark.executor.memory', '8g')\n", + " .set('spark.driver.memory','20g')\n", + " .set('spark.memory.offHeap.enabled','True')\n", + " .set('spark.memory.offHeap.size','20g')\n", + " .set('spark.executor.memoryOverhead','1g')\n", + " .set('spark.executor.extraJavaOptions',\n", + " '-XX:+UseParallelGC -XX:+UseParallelOldGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps')\n", + " .set('spark.executorEnv.PYTHONPATH',f\"{os.environ['SPARK_HOME']}/python:{get_py4jzip()}:{':'.join(sys.path)}\")\n", + " .set('spark.sql.inMemoryColumnarStorage.compressed','False')\n", + " .set('spark.sql.inMemoryColumnarStorage.batchSize','100000')\n", + " .set('spark.sql.execution.arrow.pyspark.fallback.enabled','True')\n", + " .set('spark.sql.execution.arrow.pyspark.enabled','True')\n", + " .set('spark.sql.execution.arrow.maxRecordsPerBatch','100000')\n", + " .set(\"spark.sql.repl.eagerEval.enabled\", True)\n", + " .set(\"spark.sql.legacy.timeParserPolicy\",\"LEGACY\") \n", + " .set(\"spark.sql.session.timeZone\", tz)\n", + " )\n", + "\n", + "sc = SparkContext(conf=conf,master='yarn')\n", + "sc.setLogLevel(\"ERROR\")\n", + "spark = SQLContext(sc)\n", + "time.sleep(10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "%run ~/PAUS/sparklog.ipynb" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "os.environ[\"https_proxy\"] = proxy\n", + "os.environ[\"http_proxy\"] = proxy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "emonmetric=['emon_cpuutil',\n", + " 'emon_cpufreq',\n", + " 'emon_instr_retired',\n", + " 'emon_ipc']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "disk_prefix=[f\"'{dev}'\" for dev in disk.split(',')]\n", + "nic_prefix=[f\"'{dev}'\" for dev in nic.split(',')]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "display(HTML(' 1 App info'))\n", + "display(HTML(f\" 2 Compare to {comp_name}\"))\n", + "display(HTML(' 3 Config compare'))\n", + "display(HTML(' 4 Compare to baseline'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# App info" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "app=Application_Run(appid, basedir=base_dir)\n", + "appals=app.analysis['app']['als']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "stats=appals.get_basic_state()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "summary=app.get_summary(show_metric=emonmetric,disk_prefix=disk_prefix,nic_prefix=nic_prefix)\n", + "display(summary.style)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "traceview=app.generate_trace_view(showemon=True,show_metric=emonmetric,disk_prefix=disk_prefix,nic_prefix=nic_prefix)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "appals.get_app_name()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if 'gluten' in name:\n", + " shuffle_df, dfx=appals.get_shuffle_stat()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "appals.get_app_info(disk_prefix=disk_prefix,nic_prefix=nic_prefix)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "appals.show_critical_path_time_breakdown().T" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if emails:\n", + " mail_list=' '.join(emails.split(','))\n", + " body,title=generate_email_body_title(appid, base_dir, name, comp_appid, comp_base_dir, comp_name, baseline_appid, baseline_base_dir, notebook, notebook_html, traceview, stats, summary, pr)\n", + " !mail -a \"Content-type: text/html; charset=utf-8\" -s \"$title\" $mail_list < $body" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Compare to" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if comp_appid:\n", + " comp_app=Application_Run(comp_appid,basedir=comp_base_dir)\n", + " output=app.compare_app(rapp=comp_app,show_metric=emonmetric,show_queryplan_diff=False,disk_prefix=disk_prefix,nic_prefix=nic_prefix)\n", + " display(HTML(output))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Config compare" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if comp_appid:\n", + " comp_appals=comp_app.analysis['app']['als']\n", + " display(comp_spark_conf(appals, comp_appals))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Compare to baseline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if baseline_appid:\n", + " baseline_app=Application_Run(baseline_appid,basedir=baseline_base_dir)\n", + " output=app.compare_app(rapp=baseline_app,show_metric=emonmetric,show_queryplan_diff=False,disk_prefix=disk_prefix,nic_prefix=nic_prefix)\n", + " display(HTML(output))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Convert to HTML" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%javascript\n", + "IPython.notebook.kernel.execute('nb_name = \"' + IPython.notebook.notebook_name + '\"')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# htmlname=nb_name.replace(\"ipynb\",\"html\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# !jupyter nbconvert --to html ./{nb_name} --no-input --output html/{htmlname} --template classic" + ] + } + ], + "metadata": { + "celltoolbar": "Tags", + "hide_input": false, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.12" + }, + "nbTranslate": { + "displayLangs": [ + "*" + ], + "hotkey": "alt-t", + "langInMainMenu": true, + "sourceLang": "en", + "targetLang": "fr", + "useGoogleTranslate": true + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": false, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "197px", + "left": "2188px", + "top": "111px", + "width": "269px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tools/workload/benchmark_velox/analysis/requirements.txt b/tools/workload/benchmark_velox/analysis/requirements.txt new file mode 100644 index 000000000000..f230f8aa99de --- /dev/null +++ b/tools/workload/benchmark_velox/analysis/requirements.txt @@ -0,0 +1,174 @@ +ansicolors==1.1.8 +anyio==4.4.0 +argon2-cffi==23.1.0 +argon2-cffi-bindings==21.2.0 +arrow==1.3.0 +asttokens==2.4.1 +attrs==23.2.0 +Automat==20.2.0 +Babel==2.8.0 +bcrypt==3.2.0 +beautifulsoup4==4.12.3 +black==24.4.2 +bleach==6.1.0 +blinker==1.4 +certifi==2020.6.20 +cffi==1.16.0 +chardet==4.0.0 +charset-normalizer==3.4.0 +click==8.0.3 +colorama==0.4.4 +comm==0.2.2 +configobj==5.0.6 +constantly==15.1.0 +contourpy==1.2.1 +cryptography==3.4.8 +cycler==0.12.1 +debugpy==1.8.1 +decorator==5.1.1 +defusedxml==0.7.1 +distro==1.7.0 +entrypoints==0.4 +exceptiongroup==1.2.1 +executing==2.0.1 +fastjsonschema==2.19.1 +findspark==2.0.1 +fire==0.7.0 +fonttools==4.52.4 +fqdn==1.5.1 +gitdb==4.0.11 +GitPython==3.1.43 +greenlet==3.0.3 +httplib2==0.20.2 +hyperlink==21.0.0 +idna==3.10 +importlib-metadata==4.6.4 +incremental==21.3.0 +ipykernel==6.29.4 +ipython==8.24.0 +ipython-genutils==0.2.0 +ipywidgets==8.1.3 +isoduration==20.11.0 +jedi==0.19.1 +jeepney==0.7.1 +Jinja2==3.0.3 +jsonpatch==1.32 +jsonpointer==2.0 +jsonschema==4.22.0 +jsonschema-specifications==2023.12.1 +jupyter_client==7.4.9 +jupyter_contrib_core==0.4.2 +jupyter_contrib_nbextensions==0.7.0 +jupyter_core==5.7.2 +jupyter-events==0.10.0 +jupyter-highlight-selected-word==0.2.0 +jupyter-nbextensions-configurator==0.6.3 +jupyter_server==2.14.0 +jupyter-server-mathjax==0.2.6 +jupyter_server_terminals==0.5.3 +jupyterlab_pygments==0.3.0 +jupyterlab_widgets==3.0.11 +keyring==23.5.0 +kiwisolver==1.4.5 +launchpadlib==1.10.16 +lazr.restfulclient==0.14.4 +lazr.uri==1.0.6 +lxml==5.2.2 +MarkupSafe==2.0.1 +matplotlib==3.5.2 +matplotlib-inline==0.1.7 +metakernel==0.30.2 +mistune==3.0.2 +more-itertools==8.10.0 +mypy-extensions==1.0.0 +nbclassic==1.1.0 +nbclient==0.10.0 +nbconvert==7.16.4 +nbdime==4.0.1 +nbformat==5.10.4 +nest-asyncio==1.6.0 +netifaces==0.11.0 +notebook==6.5.6 +notebook_shim==0.2.4 +NotebookScripter==6.0.0 +numpy==1.26.4 +oauthlib==3.2.0 +overrides==7.7.0 +packaging==24.0 +pandas==1.5.3 +pandasql==0.7.3 +pandocfilters==1.5.1 +papermill==2.6.0 +parso==0.8.4 +pathspec==0.12.1 +pexpect==4.8.0 +pillow==10.3.0 +pip==24.2 +platformdirs==4.2.2 +prometheus_client==0.20.0 +prompt_toolkit==3.0.45 +psutil==5.9.8 +ptyprocess==0.7.0 +pure-eval==0.2.2 +pyarrow==16.1.0 +pyasn1==0.4.8 +pyasn1-modules==0.2.1 +pycparser==2.22 +Pygments==2.11.2 +PyHamcrest==2.0.2 +PyHDFS==0.3.1 +PyJWT==2.3.0 +pyOpenSSL==21.0.0 +pyparsing==2.4.7 +pyrsistent==0.18.1 +pyserial==3.5 +pyspark==3.3.1 +python-dateutil==2.9.0.post0 +python-json-logger==2.0.7 +pytz==2022.1 +PyYAML==6.0.2 +pyzmq==24.0.1 +referencing==0.35.1 +requests==2.32.3 +rfc3339-validator==0.1.4 +rfc3986-validator==0.1.1 +rfc3987==1.3.8 +rpds-py==0.18.1 +seaborn==0.13.2 +SecretStorage==3.3.1 +Send2Trash==1.8.3 +service-identity==18.1.0 +setuptools==75.1.0 +simplejson==3.19.2 +six==1.16.0 +smmap==5.0.1 +sniffio==1.3.1 +soupsieve==2.5 +spylon==0.3.0 +spylon-kernel==0.4.1 +SQLAlchemy==1.4.46 +ssh-import-id==5.11 +stack-data==0.6.3 +tenacity==8.3.0 +termcolor==2.5.0 +terminado==0.18.1 +tinycss2==1.3.0 +tomli==2.0.1 +tornado==6.4 +tqdm==4.66.4 +traitlets==5.14.3 +Twisted==22.1.0 +types-python-dateutil==2.9.0.20240316 +typing_extensions==4.12.0 +tzdata==2024.1 +uri-template==1.3.0 +urllib3==1.26.5 +wadllib==1.3.6 +wcwidth==0.2.13 +webcolors==1.13 +webencodings==0.5.1 +websocket-client==1.8.0 +wheel==0.44.0 +widgetsnbextension==4.0.11 +zipp==1.0.0 +zope.interface==5.4.0 diff --git a/tools/workload/benchmark_velox/analysis/run_perf_analysis.sh b/tools/workload/benchmark_velox/analysis/run_perf_analysis.sh new file mode 100755 index 000000000000..af30250d4812 --- /dev/null +++ b/tools/workload/benchmark_velox/analysis/run_perf_analysis.sh @@ -0,0 +1,180 @@ +#! /bin/bash + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +set -x + +SCRIPT_LOCATION=$(dirname $0) +PAUS=$HOME/PAUS + +while [[ $# -gt 0 ]]; do + case $1 in + --base-dir) + BASEDIR="$2" + shift # past argument + shift # past value + ;; + --name) + NAME="$2" + shift # past argument + shift # past value + ;; + --appid) + APPID="$2" + shift # past argument + shift # past value + ;; + --pr) + PR="$2" + shift # past argument + shift # past value + ;; + --disk) + DISK="$2" + shift # past argument + shift # past value + ;; + --nic) + NIC="$2" + shift # past argument + shift # past value + ;; + --tz) + SPARK_TZ="$2" + shift # past argument + shift # past value + ;; + --proxy) + PROXY="$2" + shift # past argument + shift # past value + ;; + --emails) + EMAILS="$2" + shift # past argument + shift # past value + ;; + --comp-appid) + COMP_APPID="$2" + shift # past argument + shift # past value + ;; + --comp-base-dir) + COMP_BASEDIR="$2" + shift # past argument + shift # past value + ;; + --comp-name) + COMP_NAME="$2" + shift # past argument + shift # past value + ;; + --baseline-appid) + BASELINE_APPID="$2" + shift # past argument + shift # past value + ;; + --baseline-base-dir) + BASELINE_BASEDIR="$2" + shift # past argument + shift # past value + ;; + *) + echo "Error: Unknown argument: $1" + exit 1 + ;; + esac +done + +# Validation: Check if any of the required variables are empty +if [[ -z "${BASEDIR+x}" || -z "${NAME+x}" || -z "${APPID+x}" || -z "${DISK+x}" || -z "${NIC+x}" || -z "${SPARK_TZ+x}" ]]; then + echo "Error: One or more required arguments are missing or empty." + exit 1 +fi + +mkdir -p $PAUS +if [ ! -f "$PAUS/perf_analysis_template.ipynb" ]; then + cp $SCRIPT_LOCATION/perf_analysis_template.ipynb $PAUS/ +fi +if [ ! -f "$PAUS/sparklog.ipynb" ]; then + cp $SCRIPT_LOCATION/sparklog.ipynb $PAUS/ +fi + +workdir=$PAUS/$BASEDIR +mkdir -p $workdir +mkdir -p $workdir/html + +nb_name0=${NAME}_${APPID} +nb_name=${nb_name0}.ipynb + +# Upload eventlog +cp -f $PAUS/perf_analysis_template.ipynb $workdir/$nb_name +hdfs dfs -mkdir -p /history +hdfs dfs -ls /history/$APPID >/dev/null 2>&1 || { hdfs dfs -cp /$BASEDIR/$APPID/app.log /history/$APPID || exit 1; } + +EXTRA_ARGS="" +if [ -v COMP_APPID ] +then + if [[ -z "${COMP_BASEDIR+x}" || -z "${COMP_NAME+x}" ]]; then + echo "Missing --comp-base-dir or --comp-name" + exit 1 + fi + hdfs dfs -ls /history/$COMP_APPID >/dev/null 2>&1 || { hdfs dfs -cp /$COMP_BASEDIR/$COMP_APPID/app.log /history/$COMP_APPID || exit 1; } + EXTRA_ARGS=$EXTRA_ARGS" -r comp_appid $COMP_APPID -r comp_base_dir $COMP_BASEDIR -r comp_name $COMP_NAME" + sed -i "s/# Compare to\"/# Compare to $COMP_NAME\"/g" $workdir/$nb_name +fi +if [ -v BASELINE_APPID ] +then + if [[ -z "${BASELINE_BASEDIR+x}" ]]; then + echo "Missing --baseline-base-dir" + exit 1 + fi + hdfs dfs -ls /history/$BASELINE_APPID >/dev/null 2>&1 || { hdfs dfs -cp /$BASELINE_BASEDIR/$BASELINE_APPID/app.log /history/$BASELINE_APPID || exit 1; } + EXTRA_ARGS=$EXTRA_ARGS" -r baseline_appid $BASELINE_APPID -r baseline_base_dir $BASELINE_BASEDIR" +fi + + +if [ -n "${PR}" ] +then + EXTRA_ARGS=$EXTRA_ARGS" -r pr $PR" +fi + +if [ -n "${PROXY}" ] +then + EXTRA_ARGS=$EXTRA_ARGS" -r proxy $PROXY" +fi + +if [ -n "${EMAILS}" ] +then + EXTRA_ARGS=$EXTRA_ARGS" -r emails $EMAILS" +fi + +source ~/paus-env/bin/activate + +notebook_html=html/${nb_name0}.html + +papermill --cwd $workdir \ + -r appid $APPID \ + -r disk $DISK \ + -r nic $NIC \ + -r tz $SPARK_TZ \ + -r base_dir $BASEDIR \ + -r name $NAME \ + -r notebook $nb_name \ + -r notebook_html $notebook_html \ + $EXTRA_ARGS $workdir/$nb_name $workdir/$nb_name + +jupyter nbconvert --to html --no-input $workdir/$nb_name --output $workdir/$notebook_html --template classic > /dev/null 2>&1 diff --git a/tools/workload/benchmark_velox/analysis/sparklog.ipynb b/tools/workload/benchmark_velox/analysis/sparklog.ipynb new file mode 100644 index 000000000000..79713c8d1be3 --- /dev/null +++ b/tools/workload/benchmark_velox/analysis/sparklog.ipynb @@ -0,0 +1,6137 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# initialize" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "from __future__ import nested_scopes\n", + "from IPython.display import display, HTML\n", + "display(HTML(''))\n", + "display(HTML(''))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true, + "lang": "en" + }, + "outputs": [], + "source": [ + "import logging\n", + "logger = logging.getLogger()\n", + "logger.setLevel(logging.ERROR)\n", + "\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import os\n", + "import datetime\n", + "from datetime import date\n", + "import time\n", + "import threading\n", + "import gzip\n", + "import json\n", + "import math\n", + "import re\n", + "import html\n", + "import builtins\n", + "\n", + "import collections\n", + "import numpy\n", + "import pandas\n", + "pandas.options.display.max_rows=50\n", + "pandas.options.display.max_columns=200\n", + "pandas.options.display.float_format = '{:,}'.format\n", + "\n", + "import matplotlib\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib.ticker as mtick\n", + "import matplotlib.lines as mlines\n", + "from matplotlib import colors\n", + "from matplotlib import rcParams\n", + "rcParams['font.sans-serif'] = 'Courier New'\n", + "rcParams['font.family'] = 'Courier New'\n", + "rcParams['font.size'] = '12'\n", + "%matplotlib inline\n", + "\n", + "from ipywidgets import IntProgress,Layout\n", + "\n", + "import pyspark\n", + "import pyspark.sql\n", + "import pyspark.sql.functions as F\n", + "from pyspark.sql import SparkSession\n", + "from pyspark.sql.functions import to_date, floor, lit, rank, col, lag, when, pandas_udf, PandasUDFType, avg, sum as _sum\n", + "from pyspark.sql.window import Window\n", + "from pyspark.sql.types import *\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.feature import StringIndexer, VectorAssembler\n", + "from pyspark.ml.clustering import KMeans\n", + "from pyspark.storagelevel import StorageLevel\n", + "\n", + "import seaborn as sns\n", + "from functools import reduce\n", + "from pandasql import sqldf\n", + "from itertools import chain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import pyhdfs\n", + "import socket\n", + "localhost=socket.gethostname()\n", + "local_ip=socket.gethostbyname(localhost)\n", + "\n", + "fs = pyhdfs.HdfsClient(hosts=f'{local_ip}:9870', user_name='sparkuser')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# fs functions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def getexecutor_stat(pdir):\n", + " appfolder=fs.list_status(pdir)\n", + " total_rchar=0\n", + " total_wchar=0\n", + " total_read_bytes=0\n", + " total_write_bytes=0\n", + " total_cancelled_write_bytes=0\n", + "\n", + " for t in appfolder:\n", + " if t['type']=='DIRECTORY' and t['pathSuffix']!=\"summary.parquet\":\n", + " cdir=pdir+t['pathSuffix']\n", + " for cntfile in fs.listdir(cdir):\n", + " if cntfile.endswith(\".stat\"):\n", + " with fs.open(cdir+\"/\"+cntfile) as f:\n", + " cnt=f.readlines()\n", + " rchar=0\n", + " wchar=0\n", + " read_bytes=0\n", + " write_bytes=0\n", + " cancelled_write_bytes=0\n", + " for c in cnt:\n", + " c=c.decode('ascii')\n", + " if c.startswith(\"rchar\"):\n", + " v=int(c.split(\" \")[-1])\n", + " rchar=v-rchar\n", + " elif c.startswith(\"wchar\"):\n", + " v=int(c.split(\" \")[-1])\n", + " wchar=v-wchar\n", + " elif c.startswith(\"read_bytes\"):\n", + " v=int(c.split(\" \")[-1])\n", + " read_bytes=v-read_bytes\n", + " elif c.startswith(\"write_bytes\"):\n", + " v=int(c.split(\" \")[-1])\n", + " write_bytes=v-write_bytes\n", + " elif c.startswith(\"cancelled_write_bytes\"):\n", + " v=int(c.split(\" \")[-1])\n", + " cancelled_write_bytes=v-cancelled_write_bytes\n", + " total_rchar+=rchar/1024/1024\n", + " total_wchar+=wchar/1024/1024\n", + " total_read_bytes+=read_bytes/1024/1024\n", + " total_write_bytes+=write_bytes/1024/1024\n", + " total_cancelled_write_bytes+=cancelled_write_bytes/1024/1024\n", + " return (total_rchar,total_wchar,total_read_bytes,total_write_bytes,total_cancelled_write_bytes)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def background_gradient(s, m, M, cmap='PuBu', low=0, high=0):\n", + " from matplotlib import colors\n", + " rng = M - m\n", + " norm = colors.Normalize(m - (rng * low),\n", + " M + (rng * high))\n", + " normed = norm(s.values)\n", + " c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]\n", + " return ['background-color: {:s}'.format(color) for color in c]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": "true", + "heading_collapsed": true + }, + "source": [ + "# base class" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class SparkLog_Analysis:\n", + " def __init__(self, appid,jobids,clients):\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Analysis:\n", + " def __init__(self,file):\n", + " self.file=file\n", + " self.starttime=0\n", + " self.df=None\n", + " \n", + " def load_data(self):\n", + " pass\n", + " \n", + " def generate_trace_view_list(self,id=0, **kwargs):\n", + " if self.df==None:\n", + " self.load_data()\n", + " trace_events=[]\n", + " node=kwargs.get('node',\"node\")\n", + " trace_events.append(json.dumps({\"name\": \"process_name\",\"ph\": \"M\",\"pid\":id,\"tid\":0,\"args\":{\"name\":\" \"+node}}))\n", + " return trace_events\n", + " \n", + " def generate_trace_view(self, trace_output, **kwargs):\n", + " traces=[]\n", + " traces.extend(self.generate_trace_view_list(0,**kwargs))\n", + " \n", + " output='''\n", + " {\n", + " \"traceEvents\": [\n", + " \n", + " ''' + \\\n", + " \",\\n\".join(traces)\\\n", + " + '''\n", + " ],\n", + " \"displayTimeUnit\": \"ns\"\n", + " }'''\n", + "\n", + " if(\"home\" in trace_output):\n", + " outputfolder=trace_output\n", + " appidx=trace_output.split(\"/\")[-1]\n", + " else:\n", + " outputfolder='/home/sparkuser/trace_result/'+trace_output+'.json'\n", + " appidx=trace_output\n", + " with open(outputfolder, 'w') as outfile: \n", + " outfile.write(output)\n", + " \n", + " traceview_link=f'http://{localhost}:1088/tracing_examples/trace_viewer.html#/tracing/test_data/{appidx}.json'\n", + " display(HTML(f\"{traceview_link}\"))\n", + " return traceview_link" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# EMON process" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def get_alias_name(metric,func):\n", + " return metric+\"_\"+func.__name__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def splits_fill0(x):\n", + " fi=[]\n", + " for l in x:\n", + " li=re.split(r'\\s+',l.strip())\n", + " li=[l.replace(\",\",\"\") for l in li]\n", + " for j in range(len(li),192*4+5):\n", + " li.append('0')\n", + " fi.append(li)\n", + " return iter(fi)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def background_gradient(s, m, M, cmap='PuBu', low=0, high=0):\n", + " from matplotlib import colors\n", + " rng = M - m\n", + " norm = colors.Normalize(m - (rng * low),\n", + " M + (rng * high))\n", + " normed = norm(s.values)\n", + " c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]\n", + " return ['background-color: {:s}'.format(color) for color in c]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "class Emon_Analysis(Analysis):\n", + " def __init__(self,emon_file):\n", + " Analysis.__init__(self,emon_file)\n", + " \n", + " paths=os.path.split(self.file)\n", + " if fs.exists(paths[0]+\"/emonv.txt\"):\n", + " self.totalcores=0\n", + " self.numberofpackages=0\n", + " self.coresperpackage=0\n", + " self.threadsperpackage=0\n", + " self.tsc=0\n", + " self.unc_cha_cnt=0\n", + " self.unc_mdf_cnt=0\n", + " self.unc_imc_cnt=0\n", + " self.unc_cxlcm_cnt=0\n", + " self.unc_cxldp_cnt=0\n", + " self.unc_mchbm_cnt=0\n", + " self.unc_m2hbm_cnt=0\n", + " self.unc_pmem_fc_cnt=0\n", + " self.unc_pmem_mc_cnt=0\n", + " self.unc_m2m_cnt=0\n", + " self.unc_qpi_cnt=0\n", + " self.unc_r3qpi_cnt=0\n", + " self.unc_iio_cnt=0\n", + " self.unc_irp_cnt=0\n", + " self.unc_pcu_cnt=0\n", + " self.unc_ubox_cnt=0\n", + " self.unc_m2pcie_cnt=0\n", + " self.unc_rdt_cnt=0\n", + " with fs.open(paths[0]+\"/emonv.txt\") as f:\n", + " allcnt = f.read().decode('ascii')\n", + " for l in allcnt.split(\"\\n\"):\n", + " if l.startswith(\"number_of_online_processors\"):\n", + " self.totalcores=int(re.split(\" +\",l)[2])\n", + " elif re.search(\"Number of Packages: +(\\d+)\",l):\n", + " self.numberofpackages=int(re.search(\"Number of Packages: +(\\d+)\",l).group(1))\n", + " elif re.search(\"Cores Per Package: +(\\d+)\",l):\n", + " self.coresperpackage=int(re.search(\"Cores Per Package: +(\\d+)\",l).group(1))\n", + " elif re.search(\"Threads Per Package: +(\\d+)\",l):\n", + " self.threadsperpackage=int(re.search(\"Threads Per Package: +(\\d+)\",l).group(1))\n", + " elif re.search(\"TSC Freq +[.]+ +([0-9.]+)\",l):\n", + " self.tsc=int(float(re.search(\"TSC Freq +[.]+ +([0-9.]+)\",l).group(1))*1000000)\n", + " elif l.startswith(\" cha\"):\n", + " self.unc_cha_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" mdf\"):\n", + " self.unc_mdf_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" imc\"):\n", + " self.unc_imc_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" cxlcm\"):\n", + " self.unc_cxlcm_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" cxldp\"):\n", + " self.unc_cxldp_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" mchbm\"):\n", + " self.unc_mchbm_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" m2hbm\"):\n", + " self.unc_m2hbm_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" pmem_fc\"):\n", + " self.unc_pmem_fc_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" pmem_mc\"):\n", + " self.unc_pmem_mc_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" m2m\"):\n", + " self.unc_m2m_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" qpi\"):\n", + " self.unc_qpi_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" r3qpi\"):\n", + " self.unc_r3qpi_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" iio\"):\n", + " self.unc_iio_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" irp\"):\n", + " self.unc_irp_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" pcu\"):\n", + " self.unc_pcu_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" ubox\"):\n", + " self.unc_ubox_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" m2pcie\"):\n", + " self.unc_m2pcie_cnt=int(re.split(\" +\",l)[-1])*2\n", + " elif l.startswith(\" rdt\"):\n", + " self.unc_rdt_cnt=int(re.split(\" +\",l)[-1])*2\n", + " else:\n", + " raise Exception(\"Wrong, no emonv specified\")\n", + " \n", + " self.begin_clk=0\n", + " self.end_clk=0\n", + " \n", + " self.corecnt=self.totalcores\n", + " \n", + " self.emon_metrics=collections.OrderedDict({\n", + " 'emon_cpuutil':{\n", + " 'sum_func':self.cores_sum, \n", + " 'events':{\n", + " 'a':'CPU_CLK_UNHALTED.REF_TSC'\n", + " },\n", + " 'formula':{\n", + " 'cpu%':'a/({:f}*{:d})'.format(self.tsc,self.corecnt)\n", + " },\n", + " 'fmt':lambda l: F.round(l, 3)\n", + " },\n", + " 'emon_cpufreq':{\n", + " 'sum_func':self.cores_sum, \n", + " 'events':{\n", + " 'a':'CPU_CLK_UNHALTED.THREAD',\n", + " 'b':'CPU_CLK_UNHALTED.REF_TSC'\n", + " },\n", + " 'formula':{\n", + " 'cpu freq':'a/b*{:f}'.format(self.tsc/1000000)\n", + " },\n", + " 'fmt':lambda l: F.round(l, 3)\n", + " },\n", + " 'emon_instr_retired':{\n", + " 'sum_func':self.cores_sum, \n", + " 'events':{\n", + " 'a':'INST_RETIRED.ANY'\n", + " },\n", + " 'formula':{\n", + " 'pathlength':'a/1000000000'\n", + " },\n", + " 'fmt':lambda l: F.round(l, 0)\n", + " },\n", + " 'emon_ipc':{\n", + " 'sum_func':self.cores_sum, \n", + " 'events':{\n", + " 'a':'CPU_CLK_UNHALTED.THREAD',\n", + " 'b':'INST_RETIRED.ANY'\n", + " },\n", + " 'formula':{\n", + " 'ipc':'b/a'\n", + " },\n", + " 'fmt':lambda l: F.round(l, 3)\n", + " }\n", + " })\n", + " self.effective_metric=None\n", + " self.appclients=[] # there is no appid and client column\n", + "\n", + " def count_sum(self,collected_cores):\n", + " return F.expr('+'.join(['_{:d}/_2*{:d}'.format(c+3,self.tsc) for c in collected_cores]))\n", + "\n", + " def cores_sum(self,collected_cores):\n", + " return self.count_sum(collected_cores)\n", + "\n", + " def mem_sum(self,collected_cores):\n", + " return self.count_sum(collected_cores)\n", + "\n", + " def pcie_sum(self,collected_cores):\n", + " return self.count_sum([2,3,7,8])\n", + " \n", + " def list_metric(self):\n", + " if self.effective_metric is None:\n", + " self.get_effective_metric()\n", + " for k in self.effective_metric:\n", + " m=self.emon_metrics[k]\n", + " print(k)\n", + " for fk,fm in m['formula'].items():\n", + " print(\" \",fk)\n", + " \n", + " def load_data(self):\n", + " paths=os.path.split(self.file)\n", + " if fs.exists(paths[0]+\"/emon.parquet/_SUCCESS\"):\n", + " self.df=spark.read.parquet(paths[0]+\"/emon.parquet\")\n", + " self.df.cache()\n", + " return\n", + " \n", + " emondata=sc.textFile(self.file)\n", + " emondf=emondata.mapPartitions(splits_fill0).toDF()\n", + " emondf=emondf.withColumn(\"id\", F.monotonically_increasing_id())\n", + " giddf=emondf.where(emondf._1.rlike(\"======\")).selectExpr(\"id as g_id\")\n", + " \n", + " iddf=emondf.where(emondf._1.rlike(\"\\d\\d/\")).selectExpr(\"_1 as r_1\",\"_2 as r_2\",\"id as r_id\")\n", + " jfid=emondf.where(emondf._2.rlike(\"^[1-9][0-9][0-9]+\")).join(iddf,on=[emondf.id>iddf.r_id]).groupBy('id').agg(F.max('r_id').alias('r_id'))\n", + " iddf=iddf.join(jfid,on='r_id',how='left')\n", + " emondf=emondf.where(emondf._2.rlike(\"^[1-9][0-9][0-9]+\")).join(iddf,on='id',how='left')\n", + " \n", + " jfid=emondf.join(giddf,on=[emondf.id>giddf.g_id]).groupBy('id').agg(F.max('g_id').alias('g_id'))\n", + " giddf=giddf.join(jfid,on='g_id',how='left')\n", + " emondf=emondf.join(giddf,on='id',how='inner')\n", + " \n", + " df=emondf\n", + "\n", + " select_list = []\n", + " for idx, c in enumerate(df.columns):\n", + " if idx >= 2 and c.startswith('_'):\n", + " select_list.append(col(c).cast(LongType()).alias(c))\n", + " else:\n", + " select_list.append(col(c))\n", + " df=df.select(select_list)\n", + "\n", + " df=df.withColumn(\"timestamp\",F.unix_timestamp(F.concat_ws(' ','r_1','r_2'),'MM/dd/yyyy HH:mm:ss')*F.lit(1000)+(F.split(F.col('r_2'),'\\.')[1]).astype(IntegerType()))\n", + " df=df.drop(\"r_1\")\n", + " df=df.drop(\"r_2\")\n", + " \n", + " cores=list(range(0,self.totalcores))\n", + " df=df.withColumn('sum',\n", + " F.when(F.col(\"_1\").startswith(\"UNC_IIO\"),self.pcie_sum(cores))\n", + " .otherwise(self.cores_sum(cores)))\n", + " if self.begin_clk>0 and self.end_clk>0:\n", + " df=df.withColumn('valid',((F.col(\"timestamp\")>F.lit(self.begin_clk)) & (F.col(\"timestamp\")0:\n", + " effective_metric.append(k)\n", + " progress.value=progress.value+1\n", + " self.effective_metric=effective_metric\n", + " emondf.unpersist()\n", + " \n", + " def gen_metric(self,emondf, m):\n", + " join_df=None\n", + " for alias,event in m['events'].items():\n", + " if join_df is None:\n", + " join_df=emondf.where(\"_1='{:s}'\".format(event)).select('timestamp','_1','_2','r_id','g_id',*self.appclients,F.col('sum').alias(alias))\n", + " else:\n", + " tdf=emondf.where(\"_1='{:s}'\".format(event)).select('_1','_2','r_id','g_id',*self.appclients,F.col('sum').alias(alias))\n", + " join_dft=join_df.join(tdf.drop('g_id'),on=['r_id',*self.appclients],how='inner')\n", + " if join_dft.count()==0:\n", + " join_df=join_df.join(tdf.drop('r_id'),on=['g_id',*self.appclients],how='inner')\n", + " else:\n", + " join_df=join_dft\n", + " return join_df\n", + "\n", + " \n", + " \n", + " def generate_trace_view_list(self,id=0, **kwargs):\n", + " trace_events=Analysis.generate_trace_view_list(self,id, **kwargs)\n", + " \n", + " cores=list(range(0,self.totalcores))\n", + " \n", + " emondf=self.df\n", + " if 'collected_cores' in kwargs:\n", + " cores=kwargs.get(\"collected_cores\",None)\n", + " emondf=emondf.withColumn('sum',\n", + " F.when(F.col(\"_1\").startswith(\"UNC_IIO\"),self.pcie_sum(cores))\n", + " .otherwise(self.cores_sum(cores)))\n", + " show_metric= kwargs.get('show_metric', None)\n", + " \n", + " if show_metric is None and self.effective_metric is None:\n", + " self.get_effective_metric()\n", + "\n", + " self.effective_metric=show_metric if show_metric is not None else self.effective_metric\n", + " \n", + " emondf=self.df\n", + " \n", + " tid=0\n", + " for k in self.effective_metric:\n", + " m=self.emon_metrics[k]\n", + " join_df=self.gen_metric(emondf,m)\n", + " rstdf=join_df.select(\n", + " F.lit(tid).alias('tid'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.lit(k).alias('name'),\n", + " (F.col('timestamp')-F.lit(self.starttime)).alias(\"ts\"),\n", + " F.struct(*[m['fmt'](F.expr(formula)).alias(col_name) for col_name,formula in m['formula'].items() ]).alias('args')\n", + " ).where(F.col(\"ts\").isNotNull()).orderBy('ts')\n", + " trace_events.extend(rstdf.toJSON().collect())\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":tid,\"args\":{\"sort_index \":tid}}))\n", + " tid=tid+1 \n", + "\n", + " return trace_events\n", + " \n", + " def show_emon_metric(self,metric,sub_metric,core,draw=True,metric_define=None, **kwargs):\n", + " if self.df==None:\n", + " self.load_data()\n", + " emondf=self.df\n", + " \n", + " showalltime=kwargs.get(\"showalltime\",True)\n", + " \n", + " if not showalltime:\n", + " emondf=emondf.filter(F.col(\"valid\")==F.lit(True))\n", + " \n", + " if metric is None or metric=='':\n", + " for k in self.effective_metric:\n", + " m=self.emon_metrics[k]\n", + " if sub_metric in m['formula']:\n", + " break\n", + " else:\n", + " print(\"can't find metric\",sub_metric)\n", + " return \n", + " else:\n", + " k=metric\n", + " if metric_define is None:\n", + " m= self.emon_metrics[k]\n", + " else:\n", + " m= metric_define[k]\n", + "\n", + " if type(core)==int:\n", + " core=[core,]\n", + " emondf=emondf.withColumn('sum',\n", + " F.when(F.col(\"_1\").startswith(\"UNC_IIO\"),self.pcie_sum(core))\n", + " .otherwise(self.count_sum(core)))\n", + " \n", + " join_df=self.gen_metric(emondf,m)\n", + " \n", + " rstdf=join_df.select(\n", + " F.col('timestamp').alias('ts'),\n", + " m['fmt'](F.expr(m['formula'][sub_metric])).alias(sub_metric),\n", + " 'r_id'\n", + " ).where(F.col(\"timestamp\").isNotNull()).orderBy('timestamp')\n", + " \n", + " metric_sum=rstdf.select(sub_metric).summary().toPandas()\n", + " display(metric_sum)\n", + " \n", + " if draw:\n", + " pddf=rstdf.toPandas()\n", + " pddf['ts']=(pddf['ts']-pddf.loc[0,'ts'])/1000\n", + " fig, axs = plt.subplots(nrows=1, ncols=2, sharey=True,figsize=(30,8),gridspec_kw = {'width_ratios':[1, 5]})\n", + " plt.subplots_adjust(wspace=0.01)\n", + " sns.violinplot(y=sub_metric, data=pddf, ax=axs[0],palette=['g'])\n", + " axs[0].yaxis.grid(True, which='major')\n", + " ax=axs[1]\n", + " ax.stackplot(pddf['ts'], pddf[sub_metric],colors=['bisque'])\n", + " #ymin, ymax = ax.get_ylim()\n", + " ax2 = ax.twinx()\n", + " ax2.set_ylim(ax.get_ylim())\n", + " ax2.axhline(y=float(metric_sum.loc[4,sub_metric]), linewidth=2, color='r')\n", + " ax2.axhline(y=float(metric_sum.loc[5,sub_metric]), linewidth=2, color='r')\n", + " ax2.axhline(y=float(metric_sum.loc[6,sub_metric]), linewidth=2, color='r')\n", + " ax2.axhline(y=float(metric_sum.loc[7,sub_metric]), linewidth=2, color='r')\n", + " ax.set_xlabel('time (s)')\n", + " ax.yaxis.grid(True, which='major')\n", + " plt.show()\n", + " \n", + " hist_elapsedtime=rstdf.select('`{:s}`'.format(sub_metric)).rdd.flatMap(lambda x: x).histogram(15)\n", + " fig, axs = plt.subplots(figsize=(30, 5))\n", + " ax=axs\n", + " binSides, binCounts = hist_elapsedtime\n", + " binSides=[builtins.round(l,2) for l in binSides]\n", + "\n", + " N = len(binCounts)\n", + " ind = numpy.arange(N)\n", + " width = 0.5\n", + "\n", + " rects1 = ax.bar(ind+0.5, binCounts, width, color='b')\n", + "\n", + " ax.set_ylabel('Frequencies')\n", + " ax.set_title(sub_metric)\n", + " ax.set_xticks(numpy.arange(N+1))\n", + " ax.set_xticklabels(binSides)\n", + " return rstdf\n", + " \n", + "\n", + " def gen_reduce_metric(self,metric,core,sub_metric,agg_func):\n", + " if self.df==None:\n", + " self.load_data()\n", + " emondf=self.df\n", + " \n", + " emondf=emondf.where(F.col(\"valid\")==F.lit(True))\n", + " \n", + " k=metric\n", + " m= self.emon_metrics[k]\n", + "\n", + " if type(core)==int:\n", + " core=[core,]\n", + " \n", + " if len(core)(date.today() - timedelta(days=60)).strftime(\"%Y_%m_%d\"):\n", + " for r in fs.listdir(\"/gluten/\"+l):\n", + " if fs.exists(\"/gluten/\"+l+\"/\"+r+\"/app.log\"):\n", + " apps.append(\"/gluten/\"+l+\"/\"+r+\"/app.log\")\n", + " if currentdir not in apps:\n", + " apps.append(currentdir)\n", + " appdf=spark.read.json(apps)\n", + " appdf=appdf.withColumn(\"filename\", F.input_file_name())\n", + " starttime=appdf.where(\"Properties.`spark.app.name` like '\"+namelike+\"%' and Event='SparkListenerJobStart'\").select(\"filename\",F.col('Properties.`spark.app.name`').alias(\"appname\"),F.col('Submission Time').alias(\"starttime\"))\n", + " finishtime=appdf.where(\"Event='SparkListenerJobEnd'\").select(\"filename\",F.col('Completion Time').alias(\"finishtime\"))\n", + " starttime=starttime.groupBy(\"filename\").agg(F.max(\"appname\").alias(\"appname\"),F.min(\"starttime\").alias(\"starttime\"))\n", + " finishtime=finishtime.groupBy(\"filename\").agg(F.max(\"finishtime\").alias(\"finishtime\"))\n", + " elapsedtime=starttime.join(finishtime,\"filename\").orderBy(\"starttime\").select(F.date_format(F.from_unixtime(F.col('starttime')/1000),\"yyyy_MM_dd\").alias(\"test_date\"),(F.col(\"finishtime\")/1000-F.col(\"starttime\")/1000).alias(\"elapsedtime\"))\n", + " epsdf=elapsedtime.toPandas()\n", + " epsdf.plot(x='test_date',y=['elapsedtime'],style=\"-*\",figsize=(30,8))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "from pyspark.sql.functions import udf\n", + "@udf(\"long\")\n", + "def isfinish_udf(s):\n", + " import json\n", + " s=json.loads(s)\n", + " def isfinish(root):\n", + " if \"isFinalPlan=false\" in root['simpleString'] or root['children'] is None:\n", + " return 0\n", + " for c in root[\"children\"]:\n", + " if isfinish(c)==0:\n", + " return 0\n", + " return 1\n", + " if len(s)>0:\n", + " return isfinish(s[0])\n", + " else:\n", + " return 0\n", + " \n", + "@pandas_udf(\"taskid long, start long, dur long, name string\", PandasUDFType.GROUPED_MAP)\n", + "def time_breakdown(pdf):\n", + " ltime=pdf['Launch Time'][0]+2\n", + " pdf['start']=0\n", + " pdf['dur']=0\n", + " outpdf=[]\n", + " ratio=(pdf[\"Finish Time\"][0]-pdf[\"Launch Time\"][0])/pdf[\"Update\"].sum()\n", + " ratio=1 if ratio>1 else ratio\n", + " for idx,l in pdf.iterrows():\n", + " if(l[\"Update\"]*ratio>1):\n", + " outpdf.append([l[\"Task ID\"],ltime,int(l[\"Update\"]*ratio),l[\"mname\"]])\n", + " ltime=ltime+int(l[\"Update\"]*ratio)\n", + " if len(outpdf)>0:\n", + " return pandas.DataFrame(outpdf)\n", + " else:\n", + " return pandas.DataFrame({'taskid': pandas.Series([], dtype='long'),\n", + " 'start': pandas.Series([], dtype='long'),\n", + " 'dur': pandas.Series([], dtype='long'),\n", + " 'name': pandas.Series([], dtype='str'),\n", + " })\n", + " \n", + "class App_Log_Analysis(Analysis):\n", + " def __init__(self, file, jobids):\n", + " Analysis.__init__(self,file)\n", + " self.jobids=[] if jobids is None else [str(l) for l in jobids]\n", + " self.df=None\n", + " self.pids=[]\n", + " \n", + " def load_data(self):\n", + " print(\"load data \", self.file)\n", + " jobids=self.jobids\n", + " df=spark.read.json(self.file)\n", + " \n", + " if 'App ID' in df.columns:\n", + " self.appid=df.where(\"`App ID` is not null\").collect()[0][\"App ID\"]\n", + " else:\n", + " self.appid=\"Application-00000000\"\n", + " \n", + " if df.where(\"Event='org.apache.spark.sql.execution.ui.SparkListenerDriverAccumUpdates'\").count()>0:\n", + " self.dfacc=df.where(\"Event='org.apache.spark.sql.execution.ui.SparkListenerDriverAccumUpdates'\").select(F.col(\"executionId\").alias(\"queryid\"),F.explode(\"accumUpdates\"))\n", + " else:\n", + " self.dfacc = None\n", + " \n", + " if \"sparkPlanInfo\" in df.columns:\n", + " self.queryplans=df.where(\"(Event='org.apache.spark.sql.execution.ui.SparkListenerSQLExecutionStart' or Event='org.apache.spark.sql.execution.ui.SparkListenerSQLAdaptiveExecutionUpdate') \\\n", + " and (sparkPlanInfo.nodeName!='AdaptiveSparkPlan' or sparkPlanInfo.simpleString='AdaptiveSparkPlan isFinalPlan=true') \").select(F.col(\"executionId\").alias(\"queryid\"),'physicalPlanDescription',\"sparkPlanInfo.*\")\n", + " else:\n", + " self.queryplans=None\n", + " \n", + " seen = set()\n", + " \n", + " if self.queryplans is not None:\n", + " self.queryplans=self.queryplans.where(isfinish_udf(F.to_json(\"children\"))==1)\n", + " \n", + " self.allmetrics=[]\n", + " if self.queryplans.count() > 0:\n", + " metrics=self.queryplans.collect()\n", + " def get_metric(root):\n", + " for l in root[\"metrics\"]:\n", + " if l['accumulatorId'] not in seen:\n", + " seen.add(l['accumulatorId'])\n", + " self.allmetrics.append([l['accumulatorId'],l[\"metricType\"],l['name'],root[\"nodeName\"]])\n", + " if root['children'] is not None:\n", + " for c in root[\"children\"]:\n", + " get_metric(c)\n", + " for c in metrics:\n", + " get_metric(c)\n", + " \n", + " amsdf=spark.createDataFrame(self.allmetrics)\n", + " amsdf=amsdf.withColumnRenamed(\"_1\",\"ID\").withColumnRenamed(\"_2\",\"type\").withColumnRenamed(\"_3\",\"Name\").withColumnRenamed(\"_4\",\"nodeName\")\n", + " \n", + " \n", + " if self.dfacc is not None:\n", + " self.dfacc=self.dfacc.select(\"queryid\",(F.col(\"col\")[0]).alias(\"ID\"),(F.col(\"col\")[1]).alias(\"Update\")).join(amsdf,on=[\"ID\"])\n", + " \n", + " if self.queryplans is not None:\n", + " self.metricscollect=[l for l in self.allmetrics if l[1] in ['nsTiming','timing'] and (l[2].startswith(\"time to\") or l[2].startswith(\"time of\") or l[2].startswith(\"scan time\") or l[2].startswith(\"shuffle write time\") or l[2].startswith(\"time to spill\") or l[2].startswith(\"task commit time\")) \n", + " and l[2] not in(\"time to collect batch\", \"time of scan\") ]\n", + " \n", + " #config=df.where(\"event='SparkListenerJobStart' and Properties.`spark.executor.cores` is not null\").select(\"Properties.*\").limit(1).collect()\n", + " config=df.select(\"`Spark Properties`.*\").where(\"`spark.app.id` is not null\").limit(1).collect()\n", + " \n", + " configdic=config[0].asDict()\n", + " self.parallelism=int(configdic['spark.sql.shuffle.partitions']) if 'spark.sql.shuffle.partitions' in configdic else 1\n", + " self.executor_cores=int(configdic['spark.executor.cores']) if 'spark.executor.cores' in configdic else 1\n", + " self.executor_instances=int(configdic['spark.executor.instances']) if 'spark.executor.instances' in configdic else 1\n", + " self.taskcpus= int(configdic['spark.task.cpus'])if 'spark.task.cpus' in configdic else 1\n", + " self.batchsize= int(configdic['spark.gluten.sql.columnar.maxBatchSize'])if 'spark.gluten.sql.columnar.maxBatchSize' in configdic else 4096\n", + " \n", + " self.realexecutors = df.where(~F.isnull(F.col(\"Executor ID\"))).select(\"Executor ID\").distinct().count()\n", + " \n", + " execstart = df.where(\"Event='org.apache.spark.sql.execution.ui.SparkListenerSQLExecutionStart'\").select(\"executionId\",\"time\")\n", + " execend = df.where(\"Event='org.apache.spark.sql.execution.ui.SparkListenerSQLExecutionEnd'\").select(\"executionId\",\"time\")\n", + " execstart=execstart.withColumnRenamed(\"time\",\"query_starttime\").withColumnRenamed(\"executionId\",\"queryid\")\n", + " execend=execend.withColumnRenamed(\"time\",\"query_endtime\").withColumnRenamed(\"executionId\",\"queryid\")\n", + " exectime = execstart.join(execend,on=[\"queryid\"])\n", + "\n", + " if \"spark.sql.execution.id\" in df.where(\"Event='SparkListenerJobStart'\").select(\"Properties.*\").columns:\n", + " df_jobstart=df.where(\"Event='SparkListenerJobStart'\").select(\"Job ID\",\"Submission Time\",F.col(\"Properties.`spark.sql.execution.id`\").alias(\"queryid\"),\"Stage IDs\")\n", + " else:\n", + " df_jobstart=df.where(\"Event='SparkListenerJobStart'\").select(\"Job ID\",\"Submission Time\",F.lit(0).alias(\"queryid\"),\"Stage IDs\")\n", + " \n", + " df_jobend=df.where(\"Event='SparkListenerJobEnd'\").select(\"`Job ID`\",\"Completion Time\")\n", + " df_job=df_jobstart.join(df_jobend,\"Job ID\")\n", + " df_job=df_job.withColumnRenamed(\"Submission Time\",\"job_start_time\")\n", + " df_job=df_job.withColumnRenamed(\"Completion Time\",\"job_stop_time\")\n", + " self.df_job=df_job\n", + " \n", + " jobstage=df_job.select(\"*\",F.explode(\"Stage IDs\").alias(\"Stage ID\"))\n", + " task=df.where(\"(Event='SparkListenerTaskEnd' or Event='SparkListenerTaskStart') \").select(\"Event\",\"Stage ID\",\"task info.*\",\"task metrics.*\")\n", + " \n", + " self.failed_stages = [str(l['Stage ID']) for l in task.where(\"Failed='true'\").select(\"Stage ID\").distinct().collect()]\n", + " \n", + " self.speculativetask = task.where(\"speculative = 'true'\").count()\n", + " self.speculativekilledtask = task.where(\"speculative = true and killed='true'\").count()\n", + " self.speculativestage = task.where(\"speculative = true and killed='true'\").select(\"`Stage ID`\").distinct().count()\n", + " \n", + " validtsk = task.where(\"Event = 'SparkListenerTaskEnd' and (Failed<>'true' or killed<>'true')\").select(\"`Task ID`\")\n", + " task=task.join(validtsk,on='Task ID',how='inner')\n", + " \n", + " taskjob=task.\\\n", + " select(\"Host\",\"`Event`\",\"`Launch Time`\",\"`Executor ID`\",\"`Task ID`\",\"`Finish Time`\",\n", + " \"`Stage ID`\",\"`Input Metrics`.`Bytes Read`\",\"`Disk Bytes Spilled`\",\"`Memory Bytes Spilled`\",\"`Shuffle Read Metrics`.`Local Bytes Read`\",\"`Shuffle Read Metrics`.`Remote Bytes Read`\",\n", + " \"`Shuffle Write Metrics`.`Shuffle Bytes Written`\",\"`Executor Deserialize Time`\",\"`Shuffle Read Metrics`.`Fetch Wait Time`\",\"`Executor Run Time`\",\"`Shuffle Write Metrics`.`Shuffle Write Time`\",\n", + " \"`Result Serialization Time`\",\"`Getting Result Time`\",\"`JVM GC Time`\",\"`Executor CPU Time`\",\"Accumulables\",\"Peak Execution Memory\",\n", + " F.when(task['Finish Time']==0,task['Launch Time']).otherwise(task['Finish Time']).alias('eventtime')\n", + " ).join(jobstage,\"Stage ID\").where(\"`Finish Time` is null or `Finish Time` <=job_stop_time+5\")\n", + " \n", + " taskjob = taskjob.join(exectime,on=['queryid'],how='left')\n", + " \n", + " self.df=taskjob\n", + " \n", + " if len(jobids)>0:\n", + " self.df=self.df.where('`Job ID` in ({:s})'.format(','.join(jobids)))\n", + " \n", + " queryids=self.df.select(F.col(\"queryid\").astype(IntegerType())).distinct().where(\"queryid is not null\").orderBy(\"queryid\").toPandas()\n", + " \n", + " self.query_num=len(queryids)\n", + " if self.query_num>0:\n", + " queryidx=queryids.reset_index()\n", + " queryidx['index']=queryidx['index']+1\n", + " #tpcds query\n", + " if self.query_num==103:\n", + " queryidx['index']=queryidx['index'].map(tpcds_query_map)\n", + " qidx=spark.createDataFrame(queryidx)\n", + " qidx=qidx.withColumnRenamed(\"index\",\"real_queryid\")\n", + " self.df=self.df.join(qidx,on=\"queryid\",how=\"left\")\n", + " if self.dfacc is not None:\n", + " self.dfacc=self.dfacc.join(qidx,on=\"queryid\",how='left')\n", + "\n", + " if self.queryplans:\n", + " self.queryplans=self.queryplans.join(qidx,\"queryid\",how=\"right\")\n", + " \n", + " self.df=self.df.fillna(0)\n", + " self.df=self.df.withColumn('Executor ID',F.when(F.col(\"Executor ID\")==\"driver\",1).otherwise(F.col(\"Executor ID\")))\n", + " self.df.cache()\n", + " \n", + " \n", + " \n", + " ##############################\n", + " \n", + " dfx=self.df.where(\"Event='SparkListenerTaskEnd'\").select(\"Stage ID\",\"Launch Time\",\"Finish Time\",\"Task ID\")\n", + " dfxpds=dfx.toPandas()\n", + " dfxpds.columns=[l.replace(\" \",\"_\") for l in dfxpds.columns]\n", + " dfxpds_ods=sqldf('''select * from dfxpds order by finish_time desc''')\n", + " criticaltasks=[]\n", + " idx=0\n", + " prefinish=0\n", + " launchtime=dfxpds_ods[\"Launch_Time\"][0]\n", + " criticaltasks.append([dfxpds_ods[\"Task_ID\"][0],launchtime,dfxpds_ods[\"Finish_Time\"][0]])\n", + " total_row=len(dfxpds_ods)\n", + "\n", + " while True:\n", + " while idx=launchtime else cur_finish\n", + " launchtime=dfxpds_ods[\"Launch_Time\"][idx]\n", + " criticaltasks.append([dfxpds_ods[\"Task_ID\"][idx],launchtime,cur_finish])\n", + " self.criticaltasks=criticaltasks\n", + "\n", + " def get_physical_plan(appals,**kwargs):\n", + " if appals.df is None:\n", + " appals.load_data()\n", + " queryid=kwargs.get('queryid',None)\n", + " shownops=kwargs.get(\"shownops\",['ArrowRowToColumnarExec','ColumnarToRow','RowToArrowColumnar',\n", + " 'VeloxNativeColumnarToRowExec','ArrowColumnarToRow','Filter','HashAggregate','Project','SortAggregate','SortMergeJoin','window'])\n", + " \n", + " desensitization=kwargs.get('desensitization',True)\n", + " \n", + " def get_fields(colss):\n", + " lvls=0\n", + " colns=[]\n", + " ks=\"\"\n", + " for c in colss:\n", + " if c==\",\" and lvls==0:\n", + " colns.append(ks)\n", + " ks=\"\"\n", + " continue\n", + " if c==\" \" and ks==\"\":\n", + " continue\n", + " if c==\"(\":\n", + " lvls+=1\n", + " if c==\")\":\n", + " lvls-=1\n", + " ks+=c\n", + " if ks!=\"\":\n", + " colns.append(ks)\n", + " return colns\n", + " \n", + " def get_column_names(s, opname, resultname, prefix, columns, funcs):\n", + " p=re.search(r\" \"+opname+\" \",s[0])\n", + " if p:\n", + " for v in s[1].split(\"\\n\"):\n", + " if v.startswith(resultname):\n", + " cols=re.search(\"\\[([^0-9].+)\\]\",v)\n", + " if cols:\n", + " colss=cols.group(1)\n", + " colns=get_fields(colss)\n", + " if opname+str(len(columns)) not in funcs:\n", + " funcs[opname+str(len(columns))]=[]\n", + " funcs[opname+str(len(columns))].extend(colns)\n", + " for c in colns:\n", + " if \" AS \" in c:\n", + " c=re.sub(\"#\\d+L*\",\"\",c)\n", + " colname=re.search(r\" AS (.+)\",c).group(1)\n", + " if colname not in columns:\n", + " columns[colname]=prefix\n", + " \n", + " plans=appals.queryplans.select('real_queryid','physicalPlanDescription').collect() if queryid is None else appals.queryplans.where(f\"real_queryid='{queryid}'\").select(\"physicalPlanDescription\").collect()\n", + " \n", + " for pr in range(0,len(plans)):\n", + " plan=plans[pr]['physicalPlanDescription']\n", + " nodes={}\n", + " lines=plan.split(\"\\n\")\n", + " for idx in range(0,len(lines)):\n", + " l=lines[idx]\n", + " if l=='+- == Final Plan ==':\n", + " while l!='+- == Initial Plan ==':\n", + " idx+=1\n", + " l=lines[idx]\n", + " if not l.endswith(\")\"):\n", + " break\n", + " idv=re.search(\"\\(\\d+\\)$\",l).group(0)\n", + " nodes[idv]=[l]\n", + " if l==\"== Physical Plan ==\":\n", + " while not lines[idx+1].startswith(\"(\"):\n", + " idx+=1\n", + " l=lines[idx]\n", + " if not l.endswith(\")\"):\n", + " break\n", + " idv=re.search(\"\\(\\d+\\)$\",l).group(0)\n", + " nodes[idv]=[l]\n", + " \n", + " if l.startswith(\"(\"):\n", + " idv=re.search(\"^\\(\\d+\\)\",l).group(0)\n", + " if idv in nodes:\n", + " desc=\"\"\n", + " while l.strip()!=\"\":\n", + " desc+=l+\"\\n\"\n", + " idx+=1\n", + " l=lines[idx]\n", + " desc=re.sub(r\"#\\d+L*\",r\"\",desc)\n", + " desc=re.sub(r\"= [^)]+\",r\"=\",desc)\n", + " desc=re.sub(r\"IN \\([^)]\\)\",r\"IN ()\",desc)\n", + " desc=re.sub(r\"In\\([^)]\\)\",r\"In()\",desc)\n", + " desc=re.sub(r\"EqualTo\\(([^,]+),[^)]+\\)\",r\"EqualTo(\\1,)\",desc)\n", + " desc=re.sub(r\"搜索广告\",r\"xxx\",desc)\n", + " ## add all keyword replace here\n", + " nodes[idv].append(desc)\n", + " tables={}\n", + " columns={}\n", + " functions={}\n", + " for s in nodes.values():\n", + " p=re.search(r\"Scan arrow [^.]*\\.([^ ]+)\",s[0])\n", + " if p:\n", + " tn=p.group(1)\n", + " if not tn in tables:\n", + " tables[tn]=\"table\"\n", + " if desensitization:\n", + " s[0]=s[0].replace(tn,tables[tn])\n", + " s[1]=s[1].replace(tn,tables[tn])\n", + " colsv=[]\n", + " schema=[]\n", + " for v in s[1].split(\"\\n\"):\n", + " if v.startswith(\"ReadSchema\"):\n", + " cols=re.search(\"<(.*)>\",v)\n", + " if cols:\n", + " colss=cols.group(1).split(\",\")\n", + " for c in colss:\n", + " cts=c.split(\":\")\n", + " ct=cts[0]\n", + " if not ct in columns:\n", + " if len(cts)==2:\n", + " cts[1]=cts[1]\n", + " columns[ct]=cts[1]+\"_\"\n", + " else:\n", + " columns[ct]=\"c_\"\n", + " if v.startswith(\"Location\") and desensitization:\n", + " s[1]=s[1].replace(v+\"\\n\",\"\")\n", + " \n", + " get_column_names(s, \"Project\", \"Output\", \"proj_\", columns, functions)\n", + " get_column_names(s, \"HashAggregate\", \"Results\", \"shagg_\", columns, functions)\n", + " get_column_names(s, \"SortAggregate\", \"Results\", \"stagg_\", columns, functions)\n", + " get_column_names(s, \"ColumnarConditionProject\", \"Arguments\", \"cproj_\", columns, functions)\n", + " get_column_names(s, \"ColumnarHashAggregate\", \"Results\", \"cshagg_\", columns, functions)\n", + " get_column_names(s, \"Window\", \"Arguments\", \"window_\", columns, functions)\n", + "\n", + " keys=[]\n", + " ckeys=list(columns.keys())\n", + " for l in range(0,len(ckeys)):\n", + " k1=ckeys[l]\n", + " for k in range(0,len(keys)):\n", + " if keys[k] in k1:\n", + " keys.insert(k,k1)\n", + " break\n", + " else:\n", + " keys.append(k1)\n", + " \n", + " for s in nodes.values():\n", + " s[1]=html.escape(s[1])\n", + " if desensitization:\n", + " for c in keys:\n", + " v=columns[c]\n", + " if v.startswith(\"array\") or v.startswith(\"map\") or v.startswith(\"struct\"):\n", + " s[1]=re.sub(c, ''+html.escape(v)+\"\",s[1])\n", + " else:\n", + " s[1]=re.sub(c, \"\"+html.escape(v)+\"\",s[1])\n", + "\n", + "\n", + " htmls=['''''']\n", + " qid=pr+1 if queryid is None else queryid\n", + " htmls.append(f\"\")\n", + " for l in nodes.values():\n", + " if shownops is not None:\n", + " for k in shownops:\n", + " if \" \"+k+\" \" in l[0]:\n", + " break\n", + " else:\n", + " continue\n", + " htmls.append(\"\")\n", + " htmls.append('\")\n", + " htmls.append('\")\n", + " htmls.append(\"\")\n", + " htmls.append(\"
{qid}
')\n", + " htmls.append(l[0].replace(\" \",\"_\")\n", + " .replace(\"ColumnarToRow\",\"ColumnarToRow\")\n", + " .replace(\"RowToArrowColumnar\",\"RowToArrowColumnar\")\n", + " .replace(\"ArrowColumnarToRow\",\"ArrowColumnarToRow\")\n", + " .replace(\"ArrowRowToColumnar\",\"ArrowRowToColumnar\")\n", + " .replace(\"VeloxNativeColumnarToRowExec\",\"VeloxNativeColumnarToRowExec\")\n", + " )\n", + " htmls.append(\"
')\n", + " ls=l[1].split(\"\\n\")\n", + " lsx=[]\n", + " for t in ls:\n", + " cols=re.search(\"\\[([^0-9].+)\\]\",t)\n", + " if cols:\n", + " colss=cols.group(1)\n", + " colns=get_fields(colss)\n", + " t=re.sub(\"\\[([^0-9].+)\\]\",\"\",t)\n", + " t+=\"[\"+';'.join(colns)+\"]\" \n", + " if \":\" in t:\n", + " lsx.append(re.sub(r'^([^:]+:)',r'\\1',t))\n", + " else:\n", + " lsx.append(t)\n", + " htmls.append(\"
\".join(lsx))\n", + " htmls.append(\"
\")\n", + " display(HTML(\"\\n\".join(htmls)))\n", + " \n", + " for k, v in functions.items():\n", + " functions[k]=[l for l in v if \"(\" in l]\n", + " for f in functions.values():\n", + " for idx in range(0,len(f)):\n", + " for c in keys:\n", + " v=columns[c]\n", + " if v.startswith(\"array\") or v.startswith(\"map\") or v.startswith(\"struct\"):\n", + " f[idx]=re.sub(c, ''+html.escape(v)+\"\",f[idx])\n", + " else:\n", + " f[idx]=re.sub(c, \"\"+html.escape(v)+\"\",f[idx])\n", + " funchtml=\"\"\n", + " for k,v in functions.items():\n", + " if shownops is not None:\n", + " for ks in shownops:\n", + " if \" \"+ks+\" \" in k:\n", + " break\n", + " else:\n", + " continue\n", + " funchtml+=\"\"\n", + " funchtml+=\"
\"+k+''\n", + " for f in v:\n", + " funchtml+='\"\n", + " funchtml+=\"
'+f+\"
\" \n", + " display(HTML(funchtml))\n", + " \n", + " return plans\n", + " \n", + " def get_physical_allnodes(appals,**kwargs):\n", + " if appals.df is None:\n", + " appals.load_data()\n", + " queryid=None\n", + " \n", + " plans=appals.queryplans.select('real_queryid','physicalPlanDescription').collect() if queryid is None else appals.queryplans.where(f\"real_queryid='{queryid}'\").select(\"physicalPlanDescription\").collect()\n", + " \n", + " allnodes={}\n", + " for pr in range(0,len(plans)):\n", + " plan=plans[pr]['physicalPlanDescription']\n", + " allnodes[pr]={}\n", + " nodes=allnodes[pr]\n", + " if plan is None:\n", + " continue\n", + " lines=plan.split(\"\\n\")\n", + " for idx in range(0,len(lines)):\n", + " l=lines[idx]\n", + " if l=='+- == Final Plan ==':\n", + " while l!='+- == Initial Plan ==':\n", + " idx+=1\n", + " l=lines[idx]\n", + " if not l.endswith(\")\"):\n", + " break\n", + " idv=re.search(\"\\(\\d+\\)$\",l).group(0)\n", + " nodes[idv]=[l]\n", + " if l.startswith(\"(\"):\n", + " idv=re.search(\"^\\(\\d+\\)\",l).group(0)\n", + " if idv in nodes:\n", + " desc=\"\"\n", + " while l!=\"\":\n", + " desc+=l+\"\\n\"\n", + " idx+=1\n", + " l=lines[idx]\n", + " nodes[idv].append(desc)\n", + " return allnodes\n", + " \n", + " \n", + " def get_basic_state(appals):\n", + " if appals.df is None:\n", + " appals.load_data()\n", + " display(HTML(f\"http://{localhost}:18080/history/{appals.appid}\"))\n", + " \n", + " errorcolor=\"#000000\" if appals.executor_instances == appals.realexecutors else \"#c0392b\"\n", + " \n", + " qtime=appals.get_query_time(plot=False)\n", + " sums=qtime.sum()\n", + " \n", + " total_rchar,total_wchar,total_read_bytes,total_write_bytes,total_cancelled_write_bytes = getexecutor_stat(appals.file[:-len(\"app.log\")])\n", + " \n", + " if len(appals.failed_stages)>0:\n", + " failure=\"
\".join([\"query: \" + str(l[\"real_queryid\"])+\"|stage: \" + str(l[\"Stage ID\"]) for l in appals.df.where(\"`Stage ID` in (\"+\",\".join(appals.failed_stages)+\")\").select(\"real_queryid\",\"Stage ID\").distinct().collect()])\n", + " else:\n", + " failure=\"\"\n", + " \n", + " stats={\"appid\":appals.appid,\n", + " \"executor.instances\":appals.executor_instances,\n", + " \"executor.cores\":appals.executor_cores,\n", + " \"shuffle.partitions\":appals.parallelism,\n", + " \"batch size\":appals.batchsize,\n", + " \"real executors\":appals.realexecutors,\n", + " \"Failed Tasks\":failure,\n", + " \"Speculative Tasks\":appals.speculativetask,\n", + " \"Speculative Killed Tasks\":appals.speculativekilledtask,\n", + " \"Speculative Stage\":appals.speculativestage,\n", + " \"runtime\":round(sums['runtime'],2),\n", + " \"disk spilled\":round(sums['disk spilled'],2),\n", + " \"memspilled\":round(sums['memspilled'],2),\n", + " \"local_read\":round(sums['local_read'],2),\n", + " \"remote_read\":round(sums['remote_read'],2),\n", + " \"shuffle_write\":round(sums['shuffle_write'],2),\n", + " \"task run time\":round(sums['run_time'],2),\n", + " \"ser_time\":round(sums['ser_time'],2),\n", + " \"f_wait_time\":round(sums['f_wait_time'],2),\n", + " \"gc_time\":round(sums['gc_time'],2),\n", + " \"input read\":round(sums['input read'],2),\n", + " \"acc_task_time\":round(sums['acc_task_time'],2),\n", + " \"file read size\":round(total_rchar,2),\n", + " \"file write size\":round(total_wchar,2),\n", + " \"disk read size\":round(total_read_bytes,2),\n", + " \"disk write size\":round(total_write_bytes,2),\n", + " \"disk cancel size\":round(total_cancelled_write_bytes,2)\n", + " }\n", + " \n", + " display(HTML(f'''\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
appid{appals.appid}
executor.instances{appals.executor_instances}
executor.cores{appals.executor_cores}
shuffle.partitions{(appals.parallelism)}
batch size{(appals.batchsize):,}
real executors{(appals.realexecutors)}
Failed Tasks{(failure)}
Speculative Tasks{(appals.speculativetask)}
Speculative Killed Tasks{(appals.speculativekilledtask)}
Speculative Stage{(appals.speculativestage)}
runtime{round(sums['runtime'],2):,}
disk spilled{round(sums['disk spilled'],2):,}
memspilled{round(sums['memspilled'],2):,}
local_read{round(sums['local_read'],2):,}
remote_read{round(sums['remote_read'],2):,}
shuffle_write{round(sums['shuffle_write'],2):,}
task run time{round(sums['run_time'],2):,}
ser_time{round(sums['ser_time'],2):,}
f_wait_time{round(sums['f_wait_time'],2):,}
gc_time{round(sums['gc_time'],2):,}
input read{round(sums['input read'],2):,}
acc_task_time{round(sums['acc_task_time'],2):,}
file read size{round(total_rchar,2):,}
file write size{round(total_wchar,2):,}
disk read size{round(total_read_bytes,2):,}
disk write size{round(total_write_bytes,2):,}
disk cancel size{round(total_cancelled_write_bytes,2):,}
\n", + "\n", + " '''))\n", + " return stats\n", + " \n", + " \n", + " def generate_trace_view_list_exec(self,id=0,**kwargs):\n", + " Analysis.generate_trace_view_list(self,**kwargs)\n", + " showcpu=kwargs.get('showcpu',False)\n", + " shownodes=kwargs.get(\"shownodes\",None)\n", + " \n", + " showdf=self.df.where(F.col(\"Host\").isin(shownodes)) if shownodes else self.df\n", + " \n", + " events=showdf.toPandas()\n", + " coretrack={}\n", + " trace_events=[]\n", + " starttime=self.starttime\n", + " taskend=[]\n", + " trace={\"traceEvents\":[]}\n", + " exec_hosts={}\n", + " hostsdf=showdf.select(\"Host\").distinct().orderBy(\"Host\")\n", + " hostid=100000\n", + " ended_event=[]\n", + " \n", + " for i,l in hostsdf.toPandas().iterrows():\n", + " exec_hosts[l['Host']]=hostid\n", + " hostid=hostid+100000\n", + "\n", + " for idx,l in events.iterrows():\n", + " if l['Event']=='SparkListenerTaskStart':\n", + " hostid=exec_hosts[l['Host']]\n", + "\n", + " tsk=l['Task ID']\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " self.pids.append(pid)\n", + " stime=l['Launch Time']\n", + " #the task's starttime and finishtime is the same, ignore it.\n", + " if tsk in ended_event:\n", + " continue\n", + " if not pid in coretrack:\n", + " tids={}\n", + " trace_events.append({\n", + " \"name\": \"process_name\",\n", + " \"ph\": \"M\",\n", + " \"pid\":pid,\n", + " \"tid\":0,\n", + " \"args\":{\"name\":\"{:s}.{:s}\".format(l['Host'],l['Executor ID'])}\n", + " })\n", + "\n", + " else:\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==-1:\n", + " tids[t]=[tsk,stime]\n", + " break\n", + " else:\n", + " t=len(tids)\n", + " tids[t]=[tsk,stime]\n", + " #print(\"task {:d} tid is {:s}.{:d}\".format(tsk,pid,t))\n", + " coretrack[pid]=tids\n", + "\n", + " if l['Event']=='SparkListenerTaskEnd':\n", + " sevt={}\n", + " eevt={}\n", + " hostid=exec_hosts[l['Host']]\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " tsk=l['Task ID']\n", + " fintime=l['Finish Time']\n", + "\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==tsk:\n", + " tids[t]=[-1,-1]\n", + " break\n", + " else:\n", + " ended_event.append(tsk)\n", + " continue\n", + " for ps in reversed([key for key in tids.keys()]) :\n", + " if tids[ps][1]-fintime<0 and tids[ps][1]-fintime>=-2:\n", + " fintime=tids[ps][1]\n", + " tids[t]=tids[ps]\n", + " tids[ps]=[-1,-1]\n", + " break\n", + " if starttime==0:\n", + " starttime=l['Launch Time']\n", + " print(f'applog start time: {starttime}')\n", + "\n", + " sstime=l['Launch Time']-starttime\n", + "\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':sstime,\n", + " 'dur':fintime-l['Launch Time'],\n", + " 'pid':pid,\n", + " \"ph\":'X',\n", + " 'name':\"stg{:d}\".format(l['Stage ID']),\n", + " 'args':{\"job id\": l['job id'],\n", + " \"stage id\": l['Stage ID'],\n", + " \"tskid\":tsk,\n", + " \"input\":builtins.round(l[\"Bytes Read\"]/1024/1024,2),\n", + " \"spill\":builtins.round(l[\"Memory Bytes Spilled\"]/1024/1024,2),\n", + " \"Shuffle Read Metrics\": \"\",\n", + " \"|---Local Read\": builtins.round(l[\"Local Bytes Read\"]/1024/1024,2),\n", + " \"|---Remote Read\":builtins.round(l[\"Remote Bytes Read\"]/1024/1024,2),\n", + " \"Shuffle Write Metrics\": \"\",\n", + " \"|---Write\":builtins.round(l['Shuffle Bytes Written']/1024/1024,2)\n", + " }\n", + " })\n", + "\n", + " des_time=l['Executor Deserialize Time']\n", + " read_time=l['Fetch Wait Time']\n", + " exec_time=l['Executor Run Time']\n", + " write_time=math.floor(l['Shuffle Write Time']/1000000)\n", + " ser_time=l['Result Serialization Time']\n", + " getrst_time=l['Getting Result Time']\n", + " durtime=fintime-sstime-starttime;\n", + "\n", + " times=[0,des_time,read_time,exec_time,write_time,ser_time,getrst_time]\n", + " time_names=['sched delay','deserialize time','read time','executor time','write time','serialize time','result time']\n", + " evttime=reduce((lambda x, y: x + y),times)\n", + " if evttime>durtime:\n", + " times=[math.floor(l*1.0*durtime/evttime) for l in times]\n", + " else:\n", + " times[0]=durtime-evttime\n", + "\n", + " esstime=sstime\n", + " for idx in range(0,len(times)):\n", + " if times[idx]>0:\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':esstime,\n", + " 'dur':times[idx], \n", + " 'pid':pid,\n", + " 'ph':'X',\n", + " 'name':time_names[idx]})\n", + " if idx==3:\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':esstime,\n", + " 'dur':l['JVM GC Time'],\n", + " 'pid':pid,\n", + " 'ph':'X',\n", + " 'name':'GC Time'})\n", + " if showcpu:\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':esstime,\n", + " 'pid':pid,\n", + " 'ph':'C',\n", + " 'name':'cpu% {:d}'.format(pid+int(t)),\n", + " 'args':{'value':l['Executor CPU Time']/1000000.0/times[idx]}})\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':esstime+times[idx],\n", + " 'pid':pid,\n", + " 'ph':'C',\n", + " 'name':'cpu% {:d}'.format(pid+int(t)),\n", + " 'args':{'value':0}})\n", + " esstime=esstime+times[idx]\n", + " self.starttime=starttime\n", + " return [json.dumps(l) for l in trace_events]\n", + "\n", + " def generate_trace_view_list(self,id=0,**kwargs):\n", + " Analysis.generate_trace_view_list(self,**kwargs)\n", + " showcpu=kwargs.get('showcpu',False)\n", + " shownodes=kwargs.get(\"shownodes\",None)\n", + " \n", + " showdf=self.df.where(F.col(\"Host\").isin(shownodes)) if shownodes else self.df\n", + " \n", + " showdf=showdf.orderBy([\"eventtime\", \"Finish Time\"], ascending=[1, 0])\n", + " \n", + " events=showdf.drop(\"Accumulables\").toPandas()\n", + " coretrack={}\n", + " trace_events=[]\n", + " starttime=self.starttime\n", + " taskend=[]\n", + " trace={\"traceEvents\":[]}\n", + " exec_hosts={}\n", + " hostsdf=showdf.select(\"Host\").distinct().orderBy(\"Host\")\n", + " hostid=100000\n", + " ended_event=[]\n", + " \n", + " for i,l in hostsdf.toPandas().iterrows():\n", + " exec_hosts[l['Host']]=hostid\n", + " hostid=hostid+100000\n", + "\n", + " tskmap={}\n", + " for idx,l in events.iterrows():\n", + " if l['Event']=='SparkListenerTaskStart':\n", + " hostid=exec_hosts[l['Host']]\n", + "\n", + " tsk=l['Task ID']\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " self.pids.append(pid)\n", + " stime=l['Launch Time']\n", + " #the task's starttime and finishtime is the same, ignore it.\n", + " if tsk in ended_event:\n", + " continue\n", + " if not pid in coretrack:\n", + " tids={}\n", + " trace_events.append({\n", + " \"name\": \"process_name\",\n", + " \"ph\": \"M\",\n", + " \"pid\":pid,\n", + " \"tid\":0,\n", + " \"args\":{\"name\":\"{:s}.{:s}\".format(l['Host'],l['Executor ID'])}\n", + " })\n", + "\n", + " else:\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==-1:\n", + " tids[t]=[tsk,stime]\n", + " break\n", + " else:\n", + " t=len(tids)\n", + " tids[t]=[tsk,stime]\n", + " #print(f\"task {tsk} tid is {pid}.{t}\")\n", + " coretrack[pid]=tids\n", + "\n", + " if l['Event']=='SparkListenerTaskEnd':\n", + " sevt={}\n", + " eevt={}\n", + " hostid=exec_hosts[l['Host']]\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " tsk=l['Task ID']\n", + " fintime=l['Finish Time']\n", + " \n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==tsk:\n", + " tids[t]=[-1,-1]\n", + " break\n", + " else:\n", + " ended_event.append(tsk)\n", + " continue\n", + " for ps in reversed([key for key in tids.keys()]) :\n", + " if tids[ps][1]-fintime<0 and tids[ps][1]-fintime>=-2:\n", + " fintime=tids[ps][1]\n", + " tids[t]=tids[ps]\n", + " tids[ps]=[-1,-1]\n", + " break\n", + " if starttime==0:\n", + " starttime=l['Launch Time']\n", + " print(f'applog start time: {starttime}')\n", + "\n", + " sstime=l['Launch Time']-starttime\n", + "\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':sstime,\n", + " 'dur':fintime-l['Launch Time'],\n", + " 'pid':pid,\n", + " \"ph\":'X',\n", + " 'name':\"stg{:d}\".format(l['Stage ID']),\n", + " 'args':{\"job id\": l['Job ID'],\n", + " \"stage id\": l['Stage ID'],\n", + " \"tskid\":tsk,\n", + " \"input\":builtins.round(l[\"Bytes Read\"]/1024/1024,2),\n", + " \"spill\":builtins.round(l[\"Memory Bytes Spilled\"]/1024/1024,2),\n", + " \"Shuffle Read Metrics\": \"\",\n", + " \"|---Local Read\": builtins.round(l[\"Local Bytes Read\"]/1024/1024,2),\n", + " \"|---Remote Read\":builtins.round(l[\"Remote Bytes Read\"]/1024/1024,2),\n", + " \"Shuffle Write Metrics\": \"\",\n", + " \"|---Write\":builtins.round(l['Shuffle Bytes Written']/1024/1024,2)\n", + " }\n", + " })\n", + " tskmap[tsk]={'pid':pid,'tid':pid+int(t)}\n", + "\n", + " self.starttime=starttime\n", + " self.tskmap=tskmap\n", + " output=[json.dumps(l) for l in trace_events]\n", + " \n", + " df=self.df\n", + " \n", + " if showcpu and len(self.metricscollect)>0:\n", + " metricscollect=self.metricscollect\n", + " metrics_explode=df.where(\"Event='SparkListenerTaskEnd'\").withColumn(\"metrics\",F.explode(\"Accumulables\"))\n", + " m1092=metrics_explode.select(F.col(\"Executor ID\"),F.col(\"`Stage ID`\"),\"`Task ID`\",F.col(\"`Finish Time`\"),F.col(\"`Launch Time`\"),(F.col(\"`Finish Time`\")-F.col(\"`Launch Time`\")).alias(\"elapsedtime\"),\"metrics.*\").where(F.col(\"ID\").isin([l[0] for l in metricscollect]))\n", + " metric_name_df = spark.createDataFrame(metricscollect)\n", + " metric_name_df=metric_name_df.withColumnRenamed(\"_1\",\"ID\")\n", + " metric_name_df=metric_name_df.withColumnRenamed(\"_2\",\"unit\")\n", + " metric_name_df=metric_name_df.withColumnRenamed(\"_3\",\"mname\")\n", + "\n", + " met_df=m1092.join(metric_name_df,on=\"ID\")\n", + " met_df=met_df.withColumn(\"Update\",F.when(F.col(\"unit\")=='nsTiming',F.col(\"Update\")/1000000).otherwise(F.col(\"Update\")+0))\n", + " met_df=met_df.where(\"Update>1\")\n", + "\n", + " metdfx=met_df.groupBy(\"Task ID\",\"elapsedtime\").agg(F.sum(\"Update\").alias(\"totalCnt\"))\n", + " taskratio=metdfx.withColumn(\"ratio\",F.when(F.col(\"totalCnt\") 'time to collect batch' and mname <> 'time of scan'\")\n", + "\n", + " met_df=m1092.join(metric_name_df,on=\"ID\")\n", + " met_df=met_df.withColumn(\"Update\",F.when(F.col(\"unit\")=='nsTiming',F.col(\"Update\")/1000000).otherwise(F.col(\"Update\")+0))\n", + " \n", + " #pandas UDF doesn't work. hang\n", + " #tmbk=met_df.groupBy('Task ID').apply(time_breakdown)\n", + " \n", + " w=Window.partitionBy('Task ID')\n", + " met_df1=met_df.withColumn(\"sum_update\",F.sum(\"Update\").over(w))\n", + " met_df2=met_df1.withColumn(\"ratio\",(F.col(\"Finish Time\")-F.col(\"Launch Time\")-2)/F.col(\"sum_update\"))\n", + " met_df3=met_df2.withColumn(\"ratio\",F.when(F.col(\"ratio\")>1,1).otherwise(F.col(\"ratio\")))\n", + " met_df4=met_df3.withColumn(\"update_ratio\",F.floor(F.col(\"ratio\")*F.col(\"Update\")))\n", + " met_df5=met_df4.where(F.col(\"update_ratio\")>2)\n", + " w = (Window.partitionBy('Task ID').orderBy(F.desc(\"update_ratio\")).rowsBetween(Window.unboundedPreceding, Window.currentRow))\n", + " met_df6=met_df5.withColumn('ltime_dur', F.sum('update_ratio').over(w))\n", + " met_df8=met_df6.withColumn(\"ltime\",F.col(\"ltime_dur\")+F.col(\"Launch Time\")-F.col(\"update_ratio\"))\n", + "\n", + " tmbk=met_df8.withColumn(\"taskid\",F.col(\"Task ID\")).withColumn(\"start\",F.col(\"ltime\")+F.lit(1)).withColumn(\"dur\",F.col(\"update_ratio\")-F.lit(1)).withColumn(\"name\",F.col(\"mname\"))\n", + " \n", + " \n", + " traces.extend(tmbk.select(\n", + " F.lit(38).alias(\"tid\"),\n", + " (F.col(\"start\")-F.lit(self.starttime)).alias(\"ts\"),\n", + " (F.col(\"dur\")).alias(\"dur\"),\n", + " F.lit(pid).alias(\"pid\"),\n", + " F.lit(\"X\").alias(\"ph\"),\n", + " F.col(\"name\").alias(\"name\")).toJSON().collect())\n", + " traces.append(json.dumps({\n", + " \"name\": \"process_name\",\n", + " \"ph\": \"M\",\n", + " \"pid\":pid,\n", + " \"tid\":0,\n", + " \"args\":{\"name\":\"critical path\"}\n", + " }))\n", + " return traces \n", + " \n", + " def show_Stage_histogram(apps,stageid,bincount):\n", + " if apps.df is None:\n", + " apps.load_data()\n", + " \n", + " inputsize = apps.df.where(\"`Stage ID`={:d}\".format(stageid)).select(\"Stage ID\",\"Executor ID\", \"Task ID\", F.explode(\"Accumulables\")) \\\n", + " .select(\"Stage ID\",\"Executor ID\", \"Task ID\",\"col.*\") \\\n", + " .where(\"Name='input size in bytes' or Name='size of files read'\") \\\n", + " .groupBy(\"Task ID\") \\\n", + " .agg((F.sum(\"Update\")).alias(\"input read\"))\n", + "\n", + "\n", + " stage37=apps.df.where(\"`Stage ID`={:d} and event='SparkListenerTaskEnd'\".format(stageid) )\\\n", + " .join(inputsize,on=[\"Task ID\"],how=\"left\")\\\n", + " .fillna(0) \\\n", + " .select(F.col('Host'), \n", + " F.round((F.col('Finish Time')/1000-F.col('Launch Time')/1000),2).alias('elapsedtime'),\n", + " F.round((F.col('`input read`')+F.col('`Bytes Read`')+F.col('`Local Bytes Read`')+F.col('`Remote Bytes Read`'))/1024/1024,2).alias('input'))\n", + " stage37=stage37.cache()\n", + " hist_elapsedtime=stage37.select('elapsedtime').rdd.flatMap(lambda x: x).histogram(15)\n", + " hist_input=stage37.select('input').rdd.flatMap(lambda x: x).histogram(15)\n", + " fig, axs = plt.subplots(figsize=(30, 5),nrows=1, ncols=2)\n", + " ax=axs[0]\n", + " binSides, binCounts = hist_elapsedtime\n", + " binSides=[builtins.round(l,2) for l in binSides]\n", + "\n", + " N = len(binCounts)\n", + " ind = numpy.arange(N)\n", + " width = 0.5\n", + "\n", + " rects1 = ax.bar(ind+0.5, binCounts, width, color='b')\n", + "\n", + " ax.set_ylabel('Frequencies')\n", + " ax.set_title('stage{:d} elapsed time breakdown'.format(stageid))\n", + " ax.set_xticks(numpy.arange(N+1))\n", + " ax.set_xticklabels(binSides)\n", + "\n", + " ax=axs[1]\n", + " binSides, binCounts = hist_input\n", + " binSides=[builtins.round(l,2) for l in binSides]\n", + "\n", + " N = len(binCounts)\n", + " ind = numpy.arange(N)\n", + " width = 0.5\n", + " rects1 = ax.bar(ind+0.5, binCounts, width, color='b')\n", + "\n", + " ax.set_ylabel('Frequencies')\n", + " ax.set_title('stage{:d} input data breakdown'.format(stageid))\n", + " ax.set_xticks(numpy.arange(N+1))\n", + " ax.set_xticklabels(binSides)\n", + "\n", + " out=stage37\n", + " outpds=out.toPandas()\n", + "\n", + " fig, axs = plt.subplots(nrows=1, ncols=3, sharey=False,figsize=(30,8),gridspec_kw = {'width_ratios':[1, 1, 1]})\n", + " plt.subplots_adjust(wspace=0.01)\n", + "\n", + " groups= outpds.groupby('Host')\n", + " for name, group in groups:\n", + " axs[0].plot(group.input, group.elapsedtime, marker='o', linestyle='', ms=5, label=name)\n", + " axs[0].set_xlabel('input size (MB)')\n", + " axs[0].set_ylabel('elapsed time (s)')\n", + "\n", + " axs[0].legend()\n", + "\n", + " axs[0].get_shared_y_axes().join(axs[0], axs[1])\n", + "\n", + " sns.violinplot(y='elapsedtime', x='Host', data=outpds,palette=['g'],ax=axs[1])\n", + "\n", + " sns.violinplot(y='input', x='Host', data=outpds,palette=['g'],ax=axs[2])\n", + "\n", + " #ax.xaxis.set_major_formatter(mtick.FormatStrFormatter(''))\n", + " #ax.yaxis.set_major_formatter(mtick.FormatStrFormatter(''))\n", + "\n", + " if False:\n", + " out=stage37\n", + " vecAssembler = VectorAssembler(inputCols=[\"input\",'elapsedtime'], outputCol=\"features\").setHandleInvalid(\"skip\")\n", + " new_df = vecAssembler.transform(out)\n", + " kmeans = KMeans(k=2, seed=1) # 2 clusters here\n", + " model = kmeans.fit(new_df.select('features'))\n", + " transformed = model.transform(new_df)\n", + "\n", + "\n", + " outpds=transformed.select('Host','elapsedtime','input','prediction').toPandas()\n", + "\n", + " fig, axs = plt.subplots(nrows=1, ncols=2, sharey=False,figsize=(30,8),gridspec_kw = {'width_ratios':[1, 1]})\n", + " plt.subplots_adjust(wspace=0.01)\n", + "\n", + " groups= outpds.groupby('prediction')\n", + " for name, group in groups:\n", + " axs[0].plot(group.input, group.elapsedtime, marker='o', linestyle='', ms=5, label=name)\n", + " axs[0].legend()\n", + "\n", + " bars=transformed.where('prediction=1').groupBy(\"Host\").count().toPandas()\n", + "\n", + " axs[1].bar(bars['Host'], bars['count'], 0.4, color='coral')\n", + " axs[1].set_title('cluster=1')\n", + "\n", + " plt.show()\n", + " \n", + " def show_Stages_hist(apps,**kwargs):\n", + " if apps.df is None:\n", + " apps.load_data()\n", + " \n", + " bincount=kwargs.get(\"bincount\",15)\n", + " threshold=kwargs.get(\"threshold\",0.9)\n", + " \n", + " query=kwargs.get(\"queryid\",None)\n", + " if query and type(query)==int:\n", + " query = [query,]\n", + " df=apps.df.where(F.col(\"real_queryid\").isin(query)) if query else apps.df\n", + " \n", + " totaltime=df.where(\"event='SparkListenerTaskEnd'\" ).agg(F.sum(F.col('Finish Time')-F.col('Launch Time')).alias('total_time')).collect()[0]['total_time']\n", + " stage_time=df.where(\"event='SparkListenerTaskEnd'\" ).groupBy('`Stage ID`').agg(F.sum(F.col('Finish Time')-F.col('Launch Time')).alias('total_time')).orderBy('total_time', ascending=False).toPandas()\n", + " stage_time['acc_total'] = stage_time['total_time'].cumsum()/totaltime\n", + " stage_time=stage_time.reset_index()\n", + " fig, ax = plt.subplots(figsize=(30, 5))\n", + "\n", + " rects1 = ax.plot(stage_time['index'],stage_time['acc_total'],'b.-')\n", + " ax.set_xticks(stage_time['index'])\n", + " ax.set_xticklabels(stage_time['Stage ID'])\n", + " ax.set_xlabel('stage')\n", + " ax.grid(which='major', axis='x')\n", + " plt.show()\n", + " shownstage=[]\n", + " for x in stage_time.index:\n", + " if stage_time['acc_total'][x]<=threshold:\n", + " shownstage.append(stage_time['Stage ID'][x])\n", + " else:\n", + " shownstage.append(stage_time['Stage ID'][x])\n", + " break\n", + " for row in shownstage:\n", + " apps.show_Stage_histogram(row,bincount) \n", + " \n", + " def get_hottest_stages(apps,**kwargs):\n", + " if apps.df is None:\n", + " apps.load_data()\n", + " \n", + " bincount=kwargs.get(\"bincount\",15)\n", + " threshold=kwargs.get(\"threshold\",0.9)\n", + " plot=kwargs.get(\"plot\",True)\n", + " \n", + " query=kwargs.get(\"queryid\",None)\n", + " if query and type(query)==int:\n", + " query = [query,]\n", + " df=apps.df.where(F.col(\"real_queryid\").isin(query)) if query else apps.df.where(\"queryid is not NULL\")\n", + "\n", + " stage_time=df.where(\"event='SparkListenerTaskEnd'\" ).groupBy('`Stage ID`','Job ID','real_queryid').agg(\n", + " F.sum(F.col('Finish Time')-F.col('Launch Time')).alias('total_time'),\n", + " F.stddev(F.col('Finish Time')/1000-F.col('Launch Time')/1000).alias('stdev_time'),\n", + " F.count(\"*\").alias(\"cnt\"),\n", + " F.first('queryid').astype(IntegerType()).alias('queryid')\n", + " )\\\n", + " .select('`Stage ID`','Job ID','real_queryid','queryid',\n", + " (F.col(\"total_time\")/1000/(F.when(F.col(\"cnt\")>F.lit(apps.executor_instances*apps.executor_cores/apps.taskcpus),F.lit(apps.executor_instances*apps.executor_cores/apps.taskcpus)).otherwise(F.col(\"cnt\")))).alias(\"total_time\"),\n", + " F.col(\"stdev_time\")\n", + " ).orderBy('total_time', ascending=False).toPandas()\n", + "\n", + " totaltime=stage_time['total_time'].sum()\n", + " stage_time['acc_total'] = stage_time['total_time'].cumsum()/totaltime\n", + " stage_time['total'] = stage_time['total_time']/totaltime\n", + " stage_time=stage_time.reset_index()\n", + "\n", + " shownstage=stage_time.loc[stage_time['acc_total'] <=threshold]\n", + " shownstage['stg']=shownstage['real_queryid'].astype(str)+'_'+shownstage['Job ID'].astype(str)+'_'+shownstage['Stage ID'].astype(str)\n", + " if plot:\n", + " shownstage.plot.bar(x=\"stg\",y=\"total\",figsize=(30,8))\n", + "\n", + "\n", + "\n", + " norm = matplotlib.colors.Normalize(vmin=0, vmax=max(stage_time.queryid))\n", + " cmap = matplotlib.cm.get_cmap('brg')\n", + " def setbkcolor(x):\n", + " rgba=cmap(norm(x['queryid']))\n", + " return ['background-color:rgba({:d},{:d},{:d},1); color:white'.format(int(rgba[0]*255),int(rgba[1]*255),int(rgba[2]*255))]*9\n", + "\n", + " if plot:\n", + " display(stage_time.style.apply(setbkcolor,axis=1).format({\"total_time\":lambda x: '{:,.2f}'.format(x),\"acc_total\":lambda x: '{:,.2%}'.format(x),\"total\":lambda x: '{:,.2%}'.format(x)}))\n", + " \n", + " return stage_time\n", + "\n", + " def scatter_elapsetime_input(apps,stageid):\n", + " if apps.df is None:\n", + " apps.load_data()\n", + " stage37=apps.df.where(\"`Stage ID`={:d} and event='SparkListenerTaskEnd'\".format(stageid) ).select(F.round((F.col('Finish Time')/1000-F.col('Launch Time')/1000),2).alias('elapsedtime'),F.round((F.col('`Bytes Read`')+F.col('`Local Bytes Read`')+F.col('`Remote Bytes Read`'))/1024/1024,2).alias('input')).toPandas()\n", + " stage37.plot.scatter('input','elapsedtime',figsize=(30, 5))\n", + "\n", + " def get_critical_path_stages(self): \n", + " df=self.df.where(\"Event='SparkListenerTaskEnd'\")\n", + " criticaltasks=self.criticaltasks\n", + " cripds=pandas.DataFrame(criticaltasks)\n", + " cripds.columns=['task_id',\"launch\",\"finish\"]\n", + " cridf=spark.createDataFrame(cripds)\n", + " df_ctsk=df.join(cridf,on=[F.col(\"task_id\")==F.col(\"Task ID\")],how=\"inner\")\n", + " df_ctsk=df_ctsk.withColumn(\"elapsed\",(F.col(\"Finish Time\")-F.col(\"Launch Time\"))/1000)\n", + " return df_ctsk.where(\"elapsed>10\").orderBy(F.desc(\"elapsed\")).select(\"real_queryid\",F.round(\"elapsed\",2).alias(\"elapsed\"),\"Host\",\"executor ID\",\"Stage ID\",\"Task ID\",F.round(F.col(\"Bytes Read\")/1000000,0).alias(\"file read\"),F.round((F.col(\"Local Bytes Read\")+F.col(\"Remote Bytes Read\"))/1000000,0).alias(\"shuffle read\")).toPandas()\n", + " \n", + " def show_time_metric(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + " shownodes=kwargs.get(\"shownodes\",None)\n", + " query=kwargs.get(\"queryid\",None)\n", + " plot=kwargs.get(\"plot\",True)\n", + " taskids=kwargs.get(\"taskids\",None)\n", + " \n", + " if query and type(query)==int:\n", + " query = [query,]\n", + " \n", + " showexecutor=kwargs.get(\"showexecutor\",True) if not taskids else False\n", + " queryid = query[0] if query else 0\n", + " \n", + " df=self.df.where(F.col(\"Host\").isin(shownodes)) if shownodes else self.df\n", + " df=df.where(F.col(\"real_queryid\").isin(query)) if query else df.where(\"queryid is not NULL\")\n", + "\n", + " df=df.where(F.col(\"Task ID\").isin(taskids)) if taskids else df\n", + "\n", + " exec_cores=1 if taskids else self.executor_cores\n", + " execs=1 if taskids else self.executor_instances\n", + "\n", + " metricscollect=self.metricscollect\n", + "\n", + " metrics_explode=df.where(\"Event='SparkListenerTaskEnd'\").withColumn(\"metrics\",F.explode(\"Accumulables\"))\n", + " m1092=metrics_explode.select(F.col(\"Executor ID\"),F.col(\"`Stage ID`\"),\"`Task ID`\",F.col(\"`Finish Time`\"),F.col(\"`Launch Time`\"),(F.col(\"`Finish Time`\")-F.col(\"`Launch Time`\")).alias(\"elapsedtime\"),\"metrics.*\").where(F.col(\"ID\").isin([l[0] for l in metricscollect]))\n", + " metric_name_df = spark.createDataFrame(metricscollect)\n", + " metric_name_df=metric_name_df.withColumnRenamed(\"_1\",\"ID\")\n", + " metric_name_df=metric_name_df.withColumnRenamed(\"_2\",\"unit\")\n", + " metric_name_df=metric_name_df.withColumnRenamed(\"_3\",\"mname\")\n", + " metric_name_df=metric_name_df.withColumnRenamed(\"_4\",\"node\")\n", + "\n", + " runtime=metrics_explode.agg(F.round(F.max(\"Finish Time\")/1000-F.min(\"Launch Time\")/1000,2).alias(\"runtime\")).collect()[0][\"runtime\"]\n", + "\n", + " met_df=m1092.join(metric_name_df,on=\"ID\")\n", + " met_df=met_df.withColumn(\"Update\",F.when(F.col(\"unit\")=='nsTiming',F.col(\"Update\")/1000000).otherwise(F.col(\"Update\")+0))\n", + " outpdf=met_df.groupBy(\"`Executor ID`\",\"mname\").sum(\"Update\").orderBy(\"Executor ID\").toPandas()\n", + "\n", + " met_time_cnt=df.where(\"Event='SparkListenerTaskEnd'\")\n", + " exectime=met_time_cnt.groupBy(\"Executor ID\").agg((F.max(\"Finish Time\")-F.min(\"Launch Time\")).alias(\"totaltime\"),F.sum(F.col(\"`Finish Time`\")-F.col(\"`Launch Time`\")).alias(\"tasktime\"))\n", + "\n", + " totaltime_query=met_time_cnt.groupBy(\"real_queryid\").agg((F.max(\"Finish Time\")-F.min(\"Launch Time\")).alias(\"totaltime\")).agg(F.sum(\"totaltime\").alias(\"totaltime\")).collect()\n", + " totaltime_query=totaltime_query[0][\"totaltime\"]\n", + " \n", + " pdf=exectime.toPandas()\n", + " exeids=set(outpdf['Executor ID'])\n", + " outpdfs=[outpdf[outpdf[\"Executor ID\"]==l] for l in exeids]\n", + " tasktime=pdf.set_index(\"Executor ID\").to_dict()['tasktime']\n", + "\n", + " def comb(l,r):\n", + " execid=list(r['Executor ID'])[0]\n", + " lp=r[['mname','sum(Update)']]\n", + " lp.columns=[\"mname\",\"val_\"+execid]\n", + " idle=totaltime_query*exec_cores-tasktime[execid]\n", + " nocount=tasktime[execid]-sum(lp[\"val_\"+execid])\n", + " if idle<0:\n", + " idle=0\n", + " if nocount<0:\n", + " nocount=0\n", + " lp=lp.append([{\"mname\":\"idle\",\"val_\"+execid:idle}])\n", + " lp=lp.append([{\"mname\":\"not_counted\",\"val_\"+execid:nocount}])\n", + " if l is not None:\n", + " return pandas.merge(lp, l,on=[\"mname\"],how='outer')\n", + " else:\n", + " return lp\n", + "\n", + " rstpdf=None\n", + " for l in outpdfs[0:]:\n", + " rstpdf=comb(rstpdf,l)\n", + " \n", + " for l in [l for l in rstpdf.columns if l!=\"mname\"]:\n", + " rstpdf[l]=rstpdf[l]/1000/exec_cores\n", + " \n", + " rstpdf=rstpdf.sort_values(by=\"val_\"+list(exeids)[0],axis=0,ascending=False)\n", + " if showexecutor and plot:\n", + " rstpdf.set_index(\"mname\").T.plot.bar(stacked=True,figsize=(30,8))\n", + " pdf_sum=pandas.DataFrame(rstpdf.set_index(\"mname\").T.sum())\n", + " totaltime=totaltime_query/1000\n", + " pdf_sum[0]=pdf_sum[0]/(execs)\n", + " pdf_sum[0][\"idle\"]=(totaltime_query-sum(tasktime.values())/execs/exec_cores)/1000\n", + " pdf_sum=pdf_sum.sort_values(by=0,axis=0,ascending=False)\n", + " pdf_sum=pdf_sum.T\n", + " pdf_sum.columns=[\"{:>2.0f}%_{:s}\".format(pdf_sum[l][0]/totaltime*100,l) for l in pdf_sum.columns]\n", + " matplotlib.rcParams['font.sans-serif'] = \"monospace\"\n", + " matplotlib.rcParams['font.family'] = \"monospace\"\n", + " import matplotlib.font_manager as font_manager\n", + " if plot:\n", + " ax=pdf_sum.plot.bar(stacked=True,figsize=(30,8))\n", + " font = font_manager.FontProperties(family='monospace',\n", + " style='normal', size=14)\n", + " ax.legend(prop=font,loc=4)\n", + " plt.title(\"{:s} q{:d} executors={:d} cores_per_executor={:d} parallelism={:d} sumtime={:.0f} runtime={:.0f}\".format(self.file.split(\"/\")[2],queryid,self.executor_instances,self.executor_cores,self.parallelism,totaltime,runtime),fontdict={'fontsize':24})\n", + " return pdf_sum\n", + "\n", + " def show_critical_path_time_breakdown(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + " return self.show_time_metric(taskids=[l[0].item() for l in self.criticaltasks])\n", + " \n", + " def get_spark_config(self):\n", + " df=spark.read.json(self.file)\n", + " self.appid=df.where(\"`App ID` is not null\").collect()[0][\"App ID\"]\n", + " pandas.set_option('display.max_rows', None)\n", + " pandas.set_option('display.max_columns', None)\n", + " pandas.set_option('display.max_colwidth', 100000)\n", + " return df.select(\"Properties.*\").where(\"`spark.app.id` is not null\").limit(1).toPandas().T\n", + " \n", + " def get_app_name(self):\n", + " cfg=self.get_spark_config()\n", + " display(HTML(\"\" + cfg.loc[cfg.index=='spark.app.name'][0][0]+\"\"))\n", + " \n", + " \n", + " def get_query_time(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + " queryid=kwargs.get(\"queryid\",None)\n", + " showtable=kwargs.get(\"showtable\",True)\n", + " plot=kwargs.get(\"plot\",True)\n", + " \n", + " if queryid and type(queryid)==int:\n", + " queryid = [queryid,]\n", + " \n", + " df=self.df.where(F.col(\"real_queryid\").isin(queryid)) if queryid else self.df.where(\"queryid is not NULL\")\n", + " \n", + " \n", + " stages=df.select(\"real_queryid\",\"Stage ID\").distinct().orderBy(\"Stage ID\").groupBy(\"real_queryid\").agg(F.collect_list(\"Stage ID\").alias(\"stages\")).orderBy(\"real_queryid\")\n", + " runtimeacc=df.where(\"Event='SparkListenerTaskEnd'\") \\\n", + " .groupBy(\"real_queryid\") \\\n", + " .agg(F.round(F.sum(F.col(\"Finish Time\")-F.col(\"Launch Time\"))/1000/self.executor_instances/self.executor_cores*self.taskcpus,2).alias(\"acc_task_time\"))\n", + " inputsize = df.select(\"real_queryid\",\"Stage ID\",\"Executor ID\", \"Task ID\", F.explode(\"Accumulables\")) \\\n", + " .select(\"real_queryid\",\"Stage ID\",\"Executor ID\", \"Task ID\",\"col.*\") \\\n", + " .where(\"Name='input size in bytes' or Name='size of files read'\") \\\n", + " .groupBy(\"real_queryid\") \\\n", + " .agg(F.round(F.sum(\"Update\")/1024/1024/1024,2).alias(\"input read\")).orderBy(\"real_queryid\")\n", + " if self.dfacc is not None:\n", + " inputsizev1 = self.dfacc.where(\"Name='size of files read'\").groupBy(\"real_queryid\").agg(F.round(F.sum(\"Update\")/1024/1024/1024,2).alias(\"input read v1\")).orderBy(\"real_queryid\")\n", + " inputsize=inputsize.join(inputsizev1,on=\"real_queryid\",how=\"outer\")\n", + " inputsize=inputsize.withColumn(\"input read\",F.coalesce(F.col(\"input read\"),F.col(\"input read v1\"))).drop(\"input read v1\")\n", + " \n", + " outputrows = df.select(\"real_queryid\",\"Stage ID\",\"Stage ID\",F.explode(\"Accumulables\"))\\\n", + " .select(\"real_queryid\",\"Stage ID\",\"Stage ID\",\"col.*\")\\\n", + " .where(\"Name='number of output rows'\")\\\n", + " .groupBy(\"real_queryid\")\\\n", + " .agg(F.round(F.sum(\"Update\")/1000000000,2).alias(\"output rows\"))\n", + " \n", + " stages=runtimeacc.join(stages,on=\"real_queryid\",how=\"left\")\n", + " stages=inputsize.join(stages,on=\"real_queryid\",how=\"left\")\n", + " stages=stages.join(outputrows,on='real_queryid',how=\"left\")\n", + " \n", + " out=df.groupBy(\"real_queryid\").agg(\n", + " F.round(F.max(\"query_endtime\")/1000-F.min(\"query_starttime\")/1000,2).alias(\"runtime\"),\n", + " F.round(F.sum(\"Disk Bytes Spilled\")/1024/1024/1024,2).alias(\"disk spilled\"),\n", + " F.round(F.sum(\"Memory Bytes Spilled\")/1024/1024/1024,2).alias(\"memspilled\"),\n", + " F.round(F.sum(\"Local Bytes Read\")/1024/1024/1024,2).alias(\"local_read\"),\n", + " F.round(F.sum(\"Remote Bytes Read\")/1024/1024/1024,2).alias(\"remote_read\"),\n", + " F.round(F.sum(\"Shuffle Bytes Written\")/1024/1024/1024,2).alias(\"shuffle_write\"),\n", + " F.round(F.sum(\"Executor Deserialize Time\")/1000/self.parallelism,2).alias(\"deser_time\"),\n", + " F.round(F.sum(\"Executor Run Time\")/1000/self.parallelism,2).alias(\"run_time\"),\n", + " F.round(F.sum(\"Result Serialization Time\")/1000/self.parallelism,2).alias(\"ser_time\"),\n", + " F.round(F.sum(\"Fetch Wait Time\")/1000/self.parallelism,2).alias(\"f_wait_time\"),\n", + " F.round(F.sum(\"JVM GC Time\")/1000/self.parallelism,2).alias(\"gc_time\"),\n", + " F.round(F.max(\"Peak Execution Memory\")/1000000000*self.executor_instances*self.executor_cores,2).alias(\"peak_mem\"),\n", + " F.max(\"queryid\").alias(\"queryid\")\n", + " ).join(stages,\"real_queryid\",how=\"left\").orderBy(\"real_queryid\").toPandas().set_index(\"real_queryid\")\n", + " out[\"executors\"]=self.executor_instances\n", + " out[\"core/exec\"]=self.executor_cores\n", + " out[\"task.cpus\"]=self.taskcpus\n", + " out['parallelism']=self.parallelism\n", + " \n", + " if not showtable:\n", + " return out\n", + "\n", + " def highlight_greater(x):\n", + " m1 = x['acc_task_time'] / x['runtime'] * 100\n", + " m2 = x['run_time'] / x['runtime'] * 100\n", + " m3 = x['f_wait_time'] / x['runtime'] * 100\n", + " \n", + "\n", + " df1 = pandas.DataFrame('', index=x.index, columns=x.columns)\n", + "\n", + " df1['acc_task_time'] = m1.apply(lambda x: 'background-image: linear-gradient(to right,#5fba7d {:f}%,white {:f}%)'.format(x,x))\n", + " df1['run_time'] = m2.apply(lambda x: 'background-image: linear-gradient(to right,#5fba7d {:f}%,white {:f}%)'.format(x,x))\n", + " df1['f_wait_time'] = m3.apply(lambda x: 'background-image: linear-gradient(to right,#d65f5f {:f}%,white {:f}%)'.format(x,x))\n", + " return df1\n", + "\n", + "\n", + " cm = sns.light_palette(\"green\", as_cmap=True)\n", + " if plot:\n", + " display(out.style.apply(highlight_greater, axis=None).background_gradient(cmap=cm,subset=['input read', 'shuffle_write']))\n", + " \n", + " return out\n", + " \n", + " def get_query_time_metric(self):\n", + " if self.df is None:\n", + " self.load_data()\n", + " querids=self.df.select(\"queryid\").distinct().collect()\n", + " for idx,q in enumerate([l[\"queryid\"] for l in querids]):\n", + " self.show_time_metric(query=[q,],showexecutor=False)\n", + " \n", + " def getOperatorCount(self):\n", + " if self.df is None:\n", + " self.load_data()\n", + " df=spark.read.json(self.file)\n", + " queryids=self.df.select(F.col(\"queryid\").astype(LongType()),F.col(\"real_queryid\")).distinct().orderBy(\"real_queryid\")\n", + " queryplans=self.queryplans.collect()\n", + " list_queryid=[l.real_queryid for l in queryids.collect()]\n", + "\n", + " def get_child(execid,node):\n", + " #wholestagetransformer not counted\n", + " if node['nodeName'] is not None and not node['nodeName'].startswith(\"WholeStageCodegenTransformer\"):\n", + " if node[\"nodeName\"] not in qps:\n", + " qps[node[\"nodeName\"]]={l:0 for l in list_queryid}\n", + " qps[node[\"nodeName\"]][execid]=qps[node[\"nodeName\"]][execid]+1\n", + " if node[\"children\"] is not None:\n", + " for c in node[\"children\"]:\n", + " get_child(execid,c)\n", + "\n", + " qps={}\n", + " for c in queryplans:\n", + " get_child(c['real_queryid'],c)\n", + "\n", + " return pandas.DataFrame(qps).T.sort_index(axis=0) \n", + " \n", + " def get_query_plan(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " queryid=kwargs.get(\"queryid\",None)\n", + " stageid=kwargs.get(\"stageid\",None)\n", + " \n", + " outputstage=kwargs.get(\"outputstage\",None)\n", + " \n", + " show_plan_only=kwargs.get(\"show_plan_only\",False)\n", + " show_simple_string=kwargs.get(\"show_simple_string\",False)\n", + "\n", + " plot=kwargs.get(\"plot\",True)\n", + " \n", + " colors=[\"#{:02x}{:02x}{:02x}\".format(int(l[0]*255),int(l[1]*255),int(l[2]*255)) for l in matplotlib.cm.get_cmap('tab20').colors]\n", + " \n", + " if queryid is not None:\n", + " if type(queryid)==int or type(queryid)==str:\n", + " queryid = [queryid,]\n", + " shown_stageid = [l[\"Stage ID\"] for l in self.df.where(F.col(\"real_queryid\").isin(queryid)).select(\"Stage ID\").distinct().collect()]\n", + " if stageid is not None:\n", + " if type(stageid)==int:\n", + " shown_stageid = [stageid,]\n", + " elif type(stageid)==list:\n", + " shown_stageid = stageid\n", + " queryid = [l[\"real_queryid\"] for l in self.df.where(F.col(\"`Stage ID`\").isin(shown_stageid)).select(\"real_queryid\").limit(1).collect()]\n", + "\n", + "\n", + " queryplans=[]\n", + " queryplans = self.queryplans.where(F.col(\"real_queryid\").isin(queryid)).orderBy(\"real_queryid\").collect() if queryid else self.queryplans.orderBy(\"real_queryid\").collect()\n", + " dfmetric=self.df.where(\"Event='SparkListenerTaskEnd'\").select(\"queryid\",\"real_queryid\",\"Stage ID\",\"Job ID\",F.explode(\"Accumulables\").alias(\"metric\")).select(\"*\",\"metric.*\").select(\"Stage ID\",\"ID\",\"Update\").groupBy(\"ID\",\"Stage ID\").agg(F.round(F.sum(\"Update\"),1).alias(\"value\"),F.round(F.stddev(\"Update\"),1).alias(\"stdev\")).collect()\n", + " accid2stageid={l.ID:(l[\"Stage ID\"],l[\"value\"],l[\"stdev\"]) for l in dfmetric}\n", + "\n", + " stagetime=self.df.where((F.col(\"real_queryid\").isin(queryid))).where(F.col(\"Event\")=='SparkListenerTaskEnd').groupBy(\"Stage ID\").agg(\n", + " F.round(F.sum(F.col(\"Finish Time\")-F.col(\"Launch Time\"))/1000/self.executor_instances/self.executor_cores*self.taskcpus,1).alias(\"elapsed time\"),\n", + " F.round(F.stddev(F.col(\"Finish Time\")-F.col(\"Launch Time\"))/1000,1).alias(\"time stdev\"),\n", + " F.count(F.col(\"Task ID\")).alias(\"partitions\")\n", + " ).orderBy(F.desc(\"elapsed time\")).collect()\n", + "\n", + " apptotaltime=reduce(lambda x,y: x+y['elapsed time'], stagetime,0)\n", + " if apptotaltime==0:\n", + " display(HTML(\"Error, totaltime is 0 \"))\n", + " apptotaltime=1\n", + " return \"\"\n", + "\n", + " stagemap={l[\"Stage ID\"]:l[\"elapsed time\"] for l in stagetime}\n", + " stage_time_stdev_map={l[\"Stage ID\"]:l[\"time stdev\"] for l in stagetime}\n", + " stagepartmap={l[\"Stage ID\"]:l[\"partitions\"] for l in stagetime}\n", + "\n", + " keystage=[]\n", + " keystagetime=[]\n", + " subtotal=0\n", + " for s in stagetime:\n", + " subtotal=subtotal+s['elapsed time']\n", + " keystage.append(s['Stage ID'])\n", + " keystagetime.append(s['elapsed time'])\n", + " if subtotal/apptotaltime>0.9:\n", + " break\n", + " keystagetime=[\"{:02x}{:02x}\".format(int(255*l/keystagetime[0]),255-int(255*l/keystagetime[0])) for l in keystagetime if keystagetime[0]>0]\n", + " keystagemap=dict(zip(keystage,keystagetime))\n", + " outstr=[]\n", + " def print_plan(real_queryid,level,node,parent_stageid):\n", + " stageid = accid2stageid[int(node[\"metrics\"][0][\"accumulatorId\"])][0] if node[\"metrics\"] is not None and len(node[\"metrics\"])>0 and node[\"metrics\"][0][\"accumulatorId\"] in accid2stageid else parent_stageid\n", + "\n", + " if stageid in shown_stageid:\n", + " fontcolor=f\"color:#{keystagemap[stageid]}00;font-weight:bold\" if stageid in keystagemap else \"color:#000000\"\n", + " stagetime=0 if stageid not in stagemap else stagemap[stageid]\n", + " stageParts=0 if stageid not in stagepartmap else stagepartmap[stageid]\n", + "\n", + " input_rowcntstr=\"\"\n", + " output_rowcntstr=\"\"\n", + " timename={}\n", + " input_columnarbatch=\"\"\n", + " output_columnarbatch=\"\"\n", + " output_row_batch=\"\"\n", + " other_metric_name={}\n", + "\n", + " outputrows=0\n", + " outputbatches=0\n", + " if node[\"metrics\"] is not None:\n", + " for m in node[\"metrics\"]:\n", + "\n", + " if m[\"accumulatorId\"] not in accid2stageid:\n", + " continue\n", + " \n", + " if m[\"name\"].endswith(\"block wall nanos\") or m['name'].endswith(\"cpu nanos\"):\n", + " continue\n", + " \n", + " \n", + " value=accid2stageid[m[\"accumulatorId\"]][1]\n", + " stdev_value=accid2stageid[m[\"accumulatorId\"]][2]\n", + " stdev_value=0 if stdev_value is None else stdev_value\n", + " if m[\"metricType\"] in ['nsTiming','timing']:\n", + " totaltime=value/1000 if m[\"metricType\"] == 'timing' else value/1000000000\n", + " stdev_value=stdev_value/1000 if m[\"metricType\"] == 'timing' else stdev_value/1000000000\n", + " \n", + " timeratio= 0 if stagetime==0 else totaltime/self.executor_instances/self.executor_cores*self.taskcpus/stagetime*100\n", + " timeratio_query = totaltime/self.executor_instances/self.executor_cores*self.taskcpus/apptotaltime*100\n", + " if timeratio > 10 or timeratio_query>10:\n", + " timename[m[\"name\"]]=\"{:.2f}s ({:.1f}%, {:.1f}%, {:.2f})\".format(totaltime,timeratio, totaltime/self.executor_instances/self.executor_cores*self.taskcpus/apptotaltime*100,stdev_value)\n", + " else:\n", + " timename[m[\"name\"]]=\"{:.2f}s ({:.1f}%, {:.1f}%, {:.2f})\".format(totaltime,timeratio, totaltime/self.executor_instances/self.executor_cores*self.taskcpus/apptotaltime*100,stdev_value)\n", + " elif m[\"name\"] in [\"number of output rows\",\"number of final output rows\"]:\n", + " output_rowcntstr=\"{:,.1f}\".format(value/1000/1000)+\" M\"\n", + " outputrows=value\n", + " elif m[\"name\"] in [\"number of output columnar batches\",\"number of output batches\",\"output_batches\", \"number of output vectors\",\"number of final output vectors\", \"records read\"]: \n", + " # records reads is the output of shuffle\n", + " output_columnarbatch=\"{:,d}\".format(int(value))\n", + " outputbatches=value\n", + " elif m[\"name\"]==\"number of input rows\":\n", + " input_rowcntstr=\"{:,.1f}\".format(value/1000/1000)+\" M\"\n", + " elif m[\"name\"] in [\"number of input batches\",\"input_batches\",\"number of input vectors\"]:\n", + " input_columnarbatch=\"{:,d}\".format(int(value))\n", + " else:\n", + " if value>1000000000:\n", + " other_metric_name[m[\"name\"]]=\"{:,.1f} G ({:,.1f})\".format(value/1000000000,stdev_value/1000000000)\n", + " elif value>1000000:\n", + " other_metric_name[m[\"name\"]]=\"{:,.1f} M ({:,.1f})\".format(value/1000000,stdev_value/1000000)\n", + " elif value>1000:\n", + " other_metric_name[m[\"name\"]]=\"{:,.1f} K ({:,.1f})\".format(value/1000,stdev_value/1000)\n", + " else:\n", + " other_metric_name[m[\"name\"]]=\"{:,d} ({:,.1f})\".format(int(value),stdev_value)\n", + "\n", + "\n", + " if outputrows>0 and outputbatches>0:\n", + " output_row_batch=\"{:,d}\".format(int(outputrows/outputbatches))\n", + "\n", + "\n", + " fontcolor=f\"color:#{keystagemap[stageid]}00;font-weight:bold\" if stageid in keystage else \"color:#000000\"\n", + " stagetime=0 if stageid not in stagemap else stagemap[stageid]\n", + " stage_time_stdev=0 if stageid not in stage_time_stdev_map else stage_time_stdev_map[stageid]\n", + " \n", + " nodenamestr=node[\"nodeName\"]\n", + " if nodenamestr is None:\n", + " nodenamestr=\"\"\n", + " if nodenamestr in ['ColumnarToRow','RowToArrowColumnar','ArrowColumnarToRow','ArrowRowToColumnarExec','GlutenColumnarToRowExec','GlutenRowToArrowColumnar']:\n", + " nodename=''+nodenamestr+''\n", + " else:\n", + " nodename=nodenamestr\n", + " if outputstage is not None:\n", + " outputstage.append({\"queryid\":real_queryid,\"stageid\":stageid,\"stagetime\":stagetime,\"stageParts\":stageParts,\"nodename\":nodenamestr,\"output_rowcnt\":outputrows,\"nodename_level\":\" \".join([\"|_\" for l in range(0,level)]) + \" \" + nodenamestr})\n", + " if not show_plan_only:\n", + " nodestr= \" \".join([\"|_\" for l in range(0,level)]) + \" \" + nodename\n", + " if show_simple_string :\n", + " simstr=node['simpleString']\n", + " nodestr = nodestr + \"
\\n\" + simstr \n", + " \n", + " timenametable='\\n'\n", + " \n", + " timenameSort=list(timename)\n", + " \n", + " for nameidx in sorted(timename):\n", + " timenametable+=f\"\"\n", + " timenametable+=\"
{nameidx}{timename[nameidx]}
\\n\"\n", + " \n", + " \n", + " othertable='\\n'\n", + " for nameidx in sorted(other_metric_name):\n", + " othertable+=f\"\"\n", + " othertable+=\"
{nameidx}{other_metric_name[nameidx]}
\\n\"\n", + " \n", + " outstr.append(f\"{stageid}\"+\n", + " f\" {stagetime}({stage_time_stdev}) \"+\n", + " f\" {stageParts} \"+\n", + " f\"\" + nodestr + f\"\"+\n", + " f\" {input_rowcntstr} \"+\n", + " f\" {input_columnarbatch} \"+\n", + " f\" {output_rowcntstr} \"+\n", + " f\" {output_columnarbatch} \"+\n", + " f\" {output_row_batch} \"+\n", + " f\" {timenametable} \"+\n", + " f\" {othertable} \"+\n", + " \"\")\n", + " else:\n", + " outstr.append(f\"{stageid}\"+\n", + " f\" {stagetime} \"+\n", + " f\" {stageParts} \"+\n", + " f\"\" + \" \".join([\"|_\" for l in range(0,level)]) + \" \" + nodename + f\"\"+\n", + " f\" {output_rowcntstr} \")\n", + " \n", + " if node[\"children\"] is not None:\n", + " for c in node[\"children\"]:\n", + " print_plan(real_queryid, level+1,c,stageid)\n", + "\n", + " for c in queryplans:\n", + " outstr.append(\"\"+str(c['real_queryid'])+\"\")\n", + " if not show_plan_only:\n", + " outstr.append('''\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " ''')\n", + " else:\n", + " outstr.append('''\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " ''')\n", + "\n", + " print_plan(c['real_queryid'],0,c,0)\n", + " outstr.append(\"
stage idstage timepartionsoperatorinput rowsinput batchesoutput rowsoutput batchesoutput rows/batchtime metric nametime(%stage,%total,stdev)other metric namevalue(stdev)
stage idstage timepartionsoperatoroutput rows
\")\n", + " if plot:\n", + " display(HTML(\" \".join(outstr)))\n", + " return \" \".join(outstr)\n", + " \n", + " def get_metric_output_rowcnt(self, **kwargs):\n", + " return self.get_metric_rowcnt(\"number of output rows\",**kwargs)\n", + " \n", + " def get_metric_input_rowcnt(self, **kwargs):\n", + " return self.get_metric_rowcnt(\"number of input rows\",**kwargs)\n", + " \n", + " def get_metric_rowcnt(self,rowname, **kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " queryid=kwargs.get(\"queryid\",None)\n", + " stageid=kwargs.get(\"stageid\",None)\n", + " show_task=kwargs.get(\"show_task\",False)\n", + " \n", + " if queryid and type(queryid)==int:\n", + " queryid = [queryid,]\n", + " \n", + " if stageid and type(stageid)==int:\n", + " stageid = [stageid,]\n", + " \n", + " queryplans = self.queryplans.where(F.col(\"real_queryid\").isin(queryid)).orderBy(\"real_queryid\").collect() if queryid else self.queryplans.orderBy(\"real_queryid\").collect()\n", + " qps=[]\n", + "\n", + " rownames=rowname if type(rowname)==list else [rowname,]\n", + " def get_child(execid,node):\n", + " if node['metrics'] is not None:\n", + " outputrows=[x for x in node[\"metrics\"] if \"name\" in x and x[\"name\"] in rownames]\n", + " if len(outputrows)>0:\n", + " qps.append([node[\"nodeName\"],execid,outputrows[0]['accumulatorId']])\n", + " if node[\"children\"] is not None:\n", + " for c in node[\"children\"]:\n", + " get_child(execid,c)\n", + " for c in queryplans:\n", + " get_child(c['real_queryid'],c)\n", + "\n", + " if len(qps)==0:\n", + " print(\"Metric \",rowname,\" is not found. \")\n", + " return None\n", + " stagetime=self.df.where(\"Event='SparkListenerTaskEnd'\").groupBy(\"Stage ID\").agg(F.round(F.sum(F.col(\"Finish Time\")-F.col(\"Launch Time\"))/1000/self.executor_instances/self.executor_cores*self.taskcpus,2).alias(\"stage time\"))\n", + " dfmetric=self.df.where(\"Event='SparkListenerTaskEnd'\").select(\"queryid\",\"real_queryid\",\"Stage ID\",\"Job ID\",F.explode(\"Accumulables\").alias(\"metric\")).select(\"*\",\"metric.*\").drop(\"metric\")\n", + " numrowmetric=spark.createDataFrame(qps)\n", + " numrowmetric=numrowmetric.withColumnRenamed(\"_1\",\"metric\").withColumnRenamed(\"_2\",\"real_queryid\").withColumnRenamed(\"_3\",\"metricid\")\n", + " dfmetric_rowcnt=dfmetric.join(numrowmetric.drop(\"real_queryid\"),on=[F.col(\"metricid\")==F.col(\"ID\")],how=\"right\")\n", + " if show_task:\n", + " stagemetric=dfmetric_rowcnt.join(stagetime,\"Stage ID\")\n", + " else:\n", + " stagemetric=dfmetric_rowcnt.groupBy(\"queryid\",\"real_queryid\",\"Job ID\",\"Stage ID\",\"metricid\").agg(F.round(F.sum(\"Update\")/1000000,2).alias(\"total_row\"),F.max(\"metric\").alias(\"nodename\")).join(stagetime,\"Stage ID\")\n", + "\n", + " if queryid:\n", + " if stageid:\n", + " return stagemetric.where(F.col(\"real_queryid\").isin(queryid) & F.col(\"Stage ID\").isin(stageid)).orderBy(\"Stage ID\")\n", + " else:\n", + " return stagemetric.where(F.col(\"real_queryid\").isin(queryid)).orderBy(\"Stage ID\")\n", + " else:\n", + " noderow=stagemetric.groupBy(\"real_queryid\",\"nodename\").agg(F.round(F.sum(\"total_row\"),2).alias(\"total_row\")).orderBy(\"nodename\").collect()\n", + " out={}\n", + " qids=set([r.real_queryid for r in noderow])\n", + " for r in noderow:\n", + " if r.nodename not in out:\n", + " out[r.nodename]={c:0 for c in qids}\n", + " out[r.nodename][r.real_queryid]=r.total_row\n", + " return pandas.DataFrame(out).T.sort_index(axis=0)\n", + " \n", + " def get_query_info(self,queryid):\n", + " display(HTML(\" time stat info \",))\n", + " tmp=self.get_query_time(queryid=queryid)\n", + " display(HTML(\" stage stat info \",))\n", + " display(self.get_stage_stat(queryid=queryid))\n", + " display(HTML(\" query plan \",))\n", + " self.get_query_plan(queryid=queryid)\n", + " display(HTML(\" stage hist info \",))\n", + " self.show_Stages_hist(queryid=queryid)\n", + " display(HTML(\" time info \",))\n", + " display(self.show_time_metric(queryid=queryid))\n", + " display(HTML(\" operator and rowcount \",))\n", + " display(self.get_metric_input_rowcnt(queryid=queryid))\n", + " display(self.get_metric_output_rowcnt(queryid=queryid))\n", + " \n", + " def get_app_info(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " display(HTML(f\" {self.appid} \",))\n", + " display(HTML(f\"http://{localhost}:18080/history/{self.appid}\"))\n", + " display(HTML(\" query time \",))\n", + " tmp=self.get_query_time(**kwargs)\n", + " display(HTML(\" operator count \",))\n", + " pdf=self.getOperatorCount()\n", + " display(pdf.style.apply(background_gradient,\n", + " cmap='OrRd',\n", + " m=pdf.min().min(),\n", + " M=pdf.max().max(),\n", + " low=0,\n", + " high=1))\n", + " \n", + " display(HTML(\" operator input row count \",))\n", + " pdf=self.get_metric_input_rowcnt(**kwargs)\n", + " if pdf is not None:\n", + " display(pdf.style.apply(background_gradient,\n", + " cmap='OrRd',\n", + " m=pdf.min().min(),\n", + " M=pdf.max().max(),\n", + " low=0,\n", + " high=1))\n", + " display(HTML(\" operator output row count \",))\n", + " pdf=self.get_metric_output_rowcnt(**kwargs)\n", + " if pdf is not None:\n", + " display(pdf.style.apply(background_gradient,\n", + " cmap='OrRd',\n", + " m=pdf.min().min(),\n", + " M=pdf.max().max(),\n", + " low=0,\n", + " high=1))\n", + " self.show_time_metric(**kwargs)\n", + " \n", + " def get_stage_stat(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " queryid=kwargs.get(\"queryid\",None)\n", + "\n", + " if queryid and type(queryid)==int:\n", + " queryid = [queryid,]\n", + " \n", + " df=self.df.where(F.col(\"real_queryid\").isin(queryid)).where(F.col(\"Event\")=='SparkListenerTaskEnd')\n", + " \n", + " inputsize = df.select(\"real_queryid\",\"Stage ID\",\"Executor ID\", \"Task ID\", F.explode(\"Accumulables\")) \\\n", + " .select(\"real_queryid\",\"Stage ID\",\"Executor ID\", \"Task ID\",\"col.*\") \\\n", + " .where(\"Name='input size in bytes' or Name='size of files read'\") \\\n", + " .groupBy(\"Stage ID\") \\\n", + " .agg(F.round(F.sum(\"Update\")/1024/1024/1024,2).alias(\"input read\"))\n", + " \n", + " return df.groupBy(\"Job ID\",\"Stage ID\").agg(\n", + " F.round(F.sum(F.col(\"Finish Time\")-F.col(\"Launch Time\"))/1000/self.executor_instances/self.executor_cores*self.taskcpus,1).alias(\"elapsed time\"),\n", + " F.round(F.sum(F.col(\"Disk Bytes Spilled\"))/1024/1024/1024,1).alias(\"disk spilled\"),\n", + " F.round(F.sum(F.col(\"Memory Bytes Spilled\"))/1024/1024/1024,1).alias(\"mem spilled\"),\n", + " F.round(F.sum(F.col(\"Local Bytes Read\"))/1024/1024/1024,1).alias(\"local read\"),\n", + " F.round(F.sum(F.col(\"Remote Bytes Read\"))/1024/1024/1024,1).alias(\"remote read\"),\n", + " F.round(F.sum(F.col(\"Shuffle Bytes Written\"))/1024/1024/1024,1).alias(\"shuffle write\"),\n", + " F.round(F.sum(F.col(\"Executor Deserialize Time\"))/1000,1).alias(\"deseri time\"),\n", + " F.round(F.sum(F.col(\"Fetch Wait Time\"))/1000,1).alias(\"fetch wait time\"),\n", + " F.round(F.sum(F.col(\"Shuffle Write Time\"))/1000000000,1).alias(\"shuffle write time\"),\n", + " F.round(F.sum(F.col(\"Result Serialization Time\"))/1000,1).alias(\"seri time\"),\n", + " F.round(F.sum(F.col(\"Getting Result Time\"))/1000,1).alias(\"get result time\"),\n", + " F.round(F.sum(F.col(\"JVM GC Time\"))/1000,1).alias(\"gc time\"),\n", + " F.round(F.sum(F.col(\"Executor CPU Time\"))/1000000000,1).alias(\"exe cpu time\") \n", + " ).join(inputsize,on=[\"Stage ID\"],how=\"left\").orderBy(\"Stage ID\").toPandas()\n", + " \n", + " def get_metrics_by_node(self,node_name):\n", + " if self.df is None:\n", + " self.load_data()\n", + " \n", + " if type(node_name)==str:\n", + " node_name=[node_name]\n", + " metrics=self.queryplans.collect()\n", + " coalesce=[]\n", + " metricsid=[0]\n", + " def get_metric(root):\n", + " if root['nodeName'] in node_name:\n", + " metricsid[0]=metricsid[0]+1\n", + " for l in root[\"metrics\"]:\n", + " coalesce.append([l['accumulatorId'],l[\"metricType\"],l['name'],root[\"nodeName\"],metricsid[0]])\n", + " if root[\"children\"] is not None:\n", + " for c in root[\"children\"]:\n", + " get_metric(c)\n", + " for c in metrics:\n", + " get_metric(c)\n", + "\n", + " df=self.df.select(\"queryid\",\"real_queryid\",'Stage ID','Task ID','Job ID',F.explode(\"Accumulables\"))\n", + " df=df.select(\"*\",\"col.*\")\n", + " metricdf=spark.createDataFrame(coalesce)\n", + " metricdf=metricdf.withColumnRenamed(\"_1\",\"ID\").withColumnRenamed(\"_2\",\"Unit\").withColumnRenamed(\"_3\",\"metricName\").withColumnRenamed(\"_4\",\"nodeName\").withColumnRenamed(\"_5\",\"nodeID\")\n", + " df=df.join(metricdf,on=[\"ID\"],how=\"right\")\n", + " shufflemetric=set(l[2] for l in coalesce)\n", + " metricdfs=[df.where(F.col(\"Name\")==l).groupBy(\"real_queryid\",\"nodeID\",\"Stage ID\").agg(F.stddev(\"Update\").alias(l+\"_stddev\"),F.mean(\"Update\").alias(l+\"_mean\"),F.mean(\"Update\").alias(l) if l.startswith(\"avg\") else F.sum(\"Update\").alias(l)) for l in shufflemetric]\n", + " \n", + " stagetimedf=self.df.where(\"Event='SparkListenerTaskEnd'\").groupBy(\"Stage ID\").agg(F.count(\"*\").alias(\"partnum\"),F.round(F.sum(F.col(\"Finish Time\")-F.col(\"Launch Time\"))/1000,2).alias(\"ElapsedTime\"))\n", + " \n", + " nodemetric=reduce(lambda x,y: x.join(y, on=['nodeID',\"Stage ID\",\"real_queryid\"],how=\"full\"),metricdfs)\n", + " return nodemetric.join(stagetimedf,on=\"Stage ID\")\n", + " \n", + " \n", + " def get_coalesce_batch_row_cnt(self,**kwargs):\n", + " stagesum=self.get_metrics_by_node(\"CoalesceBatches\")\n", + " \n", + " pandas.options.display.float_format = '{:,}'.format\n", + " \n", + " stagesum=stagesum.withColumnRenamed(\"number of output rows\",\"rows\")\n", + " \n", + " coalescedf = stagesum.orderBy(\"real_queryid\",'Stage ID').where(\"rows>4000\").toPandas()\n", + " \n", + " coalescedf[\"row/input_batch\"] = coalescedf[\"rows\"]/coalescedf[\"input_batches\"]\n", + " coalescedf[\"row/out_batch\"] = coalescedf[\"rows\"]/coalescedf[\"output_batches\"]\n", + " coalescedf['stage']=coalescedf[\"real_queryid\"].astype(str)+\"_\"+coalescedf['Stage ID'].astype(str)\n", + " \n", + " ax=coalescedf.plot(y=[\"row/input_batch\",\"row/out_batch\"],figsize=(30,8),style=\"-*\")\n", + " coalescedf.plot(ax=ax,y=['rows'],secondary_y=['rows'],style=\"k_\")\n", + " self.print_real_queryid(ax,coalescedf)\n", + " \n", + " return coalescedf\n", + " \n", + " def print_real_queryid(self,ax,dataset):\n", + " ax.axes.get_xaxis().set_ticks([])\n", + "\n", + " ymin, ymax = ax.get_ybound()\n", + "\n", + " real_queryid=list(dataset['real_queryid'])\n", + " s=real_queryid[0]\n", + " lastx=0\n", + " for idx,v in enumerate(real_queryid):\n", + " if v!=s:\n", + " xmin = xmax = idx-1+0.5\n", + " l = mlines.Line2D([xmin,xmax], [ymin,ymax],color=\"green\")\n", + " ax.add_line(l)\n", + " ax.text(lastx+(xmin-lastx)/2-0.25,ymin-(ymax-ymin)/20,f\"{s}\",size=20)\n", + " s=v\n", + " lastx=xmin\n", + "\n", + " def get_shuffle_stat(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + " \n", + " shufflesize=kwargs.get(\"shuffle_size\",1000000)\n", + " queryid=kwargs.get(\"queryid\",None)\n", + " if queryid is not None:\n", + " if type(queryid) is str or type(queryid) is int:\n", + " queryid=[queryid,]\n", + "\n", + " exchangedf=self.get_metrics_by_node([\"ColumnarExchange\",\"ColumnarExchangeAdaptor\"])\n", + " exchangedf.cache()\n", + " if exchangedf.count() == 0:\n", + " return (None, None)\n", + "\n", + " mapdf=exchangedf.where(\"`time to split` is not null\").select(\"nodeID\",F.col(\"Stage ID\").alias(\"map_stageid\"),\"real_queryid\",F.floor(F.col(\"time to split\")/F.col(\"time to split_mean\")).alias(\"map_partnum\"),\"time to compress\",\"time to split\",\"shuffle write time\",\"time to spill\",'shuffle records written','data size','shuffle bytes written','shuffle bytes written_mean','shuffle bytes written_stddev','shuffle bytes spilled','number of input rows','number of input batches')\n", + " reducerdf=exchangedf.where(\"`time to split` is null\").select(\"nodeID\",F.col(\"Stage ID\").alias(\"reducer_stageid\"),\"real_queryid\",'local blocks read','local bytes read',F.floor(F.col(\"records read\")/F.col(\"records read_mean\")).alias(\"reducer_partnum\"),(F.col('avg read batch num rows')/10).alias(\"avg read batch num rows\"),'remote bytes read','records read','remote blocks read',(F.col(\"number of output rows\")/F.col(\"records read\")).alias(\"avg rows per split recordbatch\"))\n", + " shuffledf=mapdf.join(reducerdf,on=[\"nodeID\",\"real_queryid\"],how=\"full\")\n", + " if queryid is not None:\n", + " shuffledf=shuffledf.where(F.col(\"real_queryid\").isin(queryid))\n", + " shuffle_pdf=shuffledf.where(\"`shuffle bytes written`>1000000\").orderBy(\"real_queryid\",\"map_stageid\",\"nodeID\").toPandas()\n", + " if shuffle_pdf.shape[0] == 0:\n", + " return (shuffledf, None)\n", + "\n", + " shuffle_pdf[\"shuffle bytes written\"]=shuffle_pdf[\"shuffle bytes written\"]/1000000000\n", + " shuffle_pdf[\"data size\"]=shuffle_pdf[\"data size\"]/1000000000\n", + " shuffle_pdf[\"shuffle bytes written_mean\"]=shuffle_pdf[\"shuffle bytes written_mean\"]/1000000\n", + " shuffle_pdf[\"shuffle bytes written_stddev\"]=shuffle_pdf[\"shuffle bytes written_stddev\"]/1000000\n", + " ax=shuffle_pdf.plot(y=[\"avg read batch num rows\",'avg rows per split recordbatch'],figsize=(30,8),style=\"-*\",title=\"average batch size after split\")\n", + " self.print_real_queryid(ax,shuffle_pdf)\n", + " shuffle_pdf[\"split_ratio\"]=shuffle_pdf[\"records read\"]/shuffle_pdf['number of input batches']\n", + " ax=shuffle_pdf.plot(y=[\"split_ratio\",\"records read\"],secondary_y=[\"records read\"],figsize=(30,8),style=\"-*\",title=\"Split Ratio\")\n", + " self.print_real_queryid(ax,shuffle_pdf)\n", + " shuffle_pdf[\"compress_ratio\"]=shuffle_pdf[\"data size\"]/shuffle_pdf['shuffle bytes written']\n", + " ax=shuffle_pdf.plot(y=[\"shuffle bytes written\",\"compress_ratio\"],secondary_y=[\"compress_ratio\"],figsize=(30,8),style=\"-*\",title=\"compress ratio\")\n", + " self.print_real_queryid(ax,shuffle_pdf)\n", + " shufflewritepdf=shuffle_pdf\n", + " ax=shufflewritepdf.plot.bar(y=[\"shuffle write time\",\"time to spill\",\"time to compress\",\"time to split\"],stacked=True,figsize=(30,8),title=\"split time + shuffle write time vs. shuffle bytes written\")\n", + " ax=shufflewritepdf.plot(ax=ax,y=[\"shuffle bytes written\"],secondary_y=[\"shuffle bytes written\"],style=\"-*\")\n", + " self.print_real_queryid(ax,shufflewritepdf)\n", + " shuffle_pdf['avg input batch size']=shuffle_pdf[\"number of input rows\"]/shuffle_pdf[\"number of input batches\"]\n", + " ax=shuffle_pdf.plot(y=[\"avg input batch size\"],figsize=(30,8),style=\"b-*\",title=\"average input batch size\")\n", + " ax=shuffle_pdf.plot.bar(ax=ax,y=['number of input rows'],secondary_y=True)\n", + " self.print_real_queryid(ax,shuffle_pdf)\n", + " \n", + " metrics=self.queryplans.collect()\n", + " coalesce=[]\n", + " metricsid=[0]\n", + " def get_metric(root):\n", + " if root['nodeName'] in [\"ColumnarExchange\",\"ColumnarExchangeAdaptor\"]:\n", + " metricsid[0]=metricsid[0]+1\n", + " for l in root[\"metrics\"]:\n", + " coalesce.append([l['accumulatorId'],l[\"metricType\"],l['name'],root[\"nodeName\"],metricsid[0],root[\"simpleString\"]])\n", + " if root[\"children\"] is not None:\n", + " for c in root[\"children\"]:\n", + " get_metric(c)\n", + " for c in metrics:\n", + " get_metric(c)\n", + "\n", + " tps={}\n", + " for r in coalesce:\n", + " rx=re.search(r\"\\[OUTPUT\\] List\\((.*)\\)\",r[5])\n", + " if rx:\n", + " if r[4] not in tps:\n", + " tps[r[4]]={}\n", + " fds=rx.group(1).split(\", \")\n", + " for f in fds:\n", + " if f.endswith(\"Type\"):\n", + " tp=re.search(r\":(.+Type)\",f).group(1)\n", + " if tp not in tps[r[4]]:\n", + " tps[r[4]][tp]=1\n", + " else:\n", + " tps[r[4]][tp]+=1\n", + " if len(tps)>0:\n", + " typedf=pandas.DataFrame(tps).T.reset_index()\n", + " typedf=typedf.fillna(0)\n", + " shuffle_pdf=pandas.merge(shuffle_pdf,typedf,left_on=\"nodeID\",right_on=\"index\")\n", + " shufflewritepdf=shuffle_pdf\n", + " ax=shufflewritepdf.plot.bar(y=[\"number of input rows\"],stacked=True,figsize=(30,8),title=\"rows vs. shuffle data type\")\n", + " ax=shufflewritepdf.plot(ax=ax,y=list(typedf.columns[1:]),secondary_y=list(typedf.columns[1:]),style=\"-o\")\n", + " self.print_real_queryid(ax,shufflewritepdf)\n", + " ax=shufflewritepdf.plot.bar(y=[\"time to split\"],stacked=True,figsize=(30,8),title=\"split time vs. shuffle data type\")\n", + " ax=shufflewritepdf.plot(ax=ax,y=list(typedf.columns[1:]),secondary_y=list(typedf.columns[1:]),style=\"-o\")\n", + " self.print_real_queryid(ax,shufflewritepdf)\n", + "\n", + " \n", + " \n", + " shufflewritepdf.plot(x=\"shuffle bytes written\",y=[\"shuffle write time\",\"time to split\"],figsize=(30,8),style=\"*\")\n", + " shufflewritepdf[\"avg shuffle batch size after split\"]=shufflewritepdf[\"shuffle bytes written\"]*1000000/shufflewritepdf['records read']\n", + " shufflewritepdf[\"avg raw batch size after split\"]=shufflewritepdf[\"data size\"]*1000000/shufflewritepdf['records read']\n", + " ax=shufflewritepdf.plot(y=[\"avg shuffle batch size after split\",\"avg raw batch size after split\",\"shuffle bytes written\"],secondary_y=[\"shuffle bytes written\"],figsize=(30,8),style=\"-*\",title=\"avg batch KB after split\")\n", + " self.print_real_queryid(ax,shufflewritepdf)\n", + " shufflewritepdf[\"avg batch# per splitted partition\"]=shufflewritepdf['records read']/(shufflewritepdf['local blocks read']+shufflewritepdf['remote blocks read'])\n", + " ax=shufflewritepdf.plot(y=[\"avg batch# per splitted partition\",'records read'],secondary_y=['records read'],figsize=(30,8),style=\"-*\",title=\"avg batch# per splitted partition\")\n", + " self.print_real_queryid(ax,shufflewritepdf)\n", + " fig, ax = plt.subplots(figsize=(30,8))\n", + " ax.set_title('shuffle wite bytes with stddev')\n", + " ax.errorbar(x=shuffle_pdf.index,y=shuffle_pdf['shuffle bytes written_mean'], yerr=shuffle_pdf['shuffle bytes written_stddev'], linestyle='None', marker='o')\n", + " self.print_real_queryid(ax,shuffle_pdf)\n", + " shuffle_pdf['record batch per mapper per reducer']=shuffle_pdf['records read']/(shuffle_pdf[\"map_partnum\"]*shuffle_pdf['reducer_partnum'])\n", + " ax=shuffle_pdf.plot(y=[\"record batch per mapper per reducer\"],figsize=(30,8),style=\"b-*\",title=\"record batch per mapper per reducer\")\n", + " self.print_real_queryid(ax,shuffle_pdf)\n", + " \n", + " inputsize = self.df.select(\"Stage ID\",\"Executor ID\", \"Task ID\", F.explode(\"Accumulables\")) \\\n", + " .select(\"Stage ID\",\"Executor ID\", \"Task ID\",\"col.*\") \\\n", + " .where(\"Name='input size in bytes' or Name='size of files read'\") \\\n", + " .groupBy(\"Task ID\") \\\n", + " .agg((F.sum(\"Update\")).alias(\"input read\"))\n", + " stageinput=self.df.where(\"event='SparkListenerTaskEnd'\" )\\\n", + " .join(inputsize,on=[\"Task ID\"],how=\"left\")\\\n", + " .fillna(0) \\\n", + " .select(F.col('Host'), F.col(\"real_queryid\"),F.col('Stage ID'),F.col('Task ID'),\n", + " F.round((F.col('Finish Time')/1000-F.col('Launch Time')/1000),2).alias('elapsedtime'),\n", + " F.round((F.col('`input read`')+F.col('`Bytes Read`')+F.col('`Local Bytes Read`')+F.col('`Remote Bytes Read`'))/1024/1024,2).alias('input'))\n", + " baisstage=stageinput.groupBy(\"real_queryid\",\"Stage ID\").agg(F.mean(\"elapsedtime\").alias(\"elapsed\"),F.mean(\"input\").alias(\"input\"),\n", + " (F.stddev(\"elapsedtime\")).alias(\"elapsedtime_err\"),\n", + " (F.stddev(\"input\")).alias(\"input_err\"),\n", + " (F.max(\"elapsedtime\")-F.mean(\"elapsedtime\")).alias(\"elapsed_max\"),\n", + " (F.mean(\"elapsedtime\")-F.min(\"elapsedtime\")).alias(\"elapsed_min\"),\n", + " (F.max(\"input\")-F.mean(\"input\")).alias(\"input_max\"),\n", + " (F.mean(\"input\")-F.min(\"input\")).alias(\"input_min\")).orderBy(\"real_queryid\",\"Stage ID\")\n", + " dfx=baisstage.toPandas()\n", + " fig, ax = plt.subplots(figsize=(30,8))\n", + " ax.set_title('input size')\n", + " ax.errorbar(x=dfx.index,y=dfx['input'], yerr=dfx['input_err'], fmt='ok', ecolor='red', lw=3)\n", + " ax.errorbar(x=dfx.index,y=dfx['input'],yerr=[dfx['input_min'],dfx['input_max']],\n", + " fmt='.k', ecolor='gray', lw=1)\n", + " self.print_real_queryid(ax,dfx)\n", + " \n", + " fig, ax = plt.subplots(figsize=(30,8))\n", + " ax.set_title('stage time')\n", + "\n", + " ax.errorbar(x=dfx.index,y=dfx['elapsed'], yerr=dfx['elapsedtime_err'], fmt='ok', ecolor='red', lw=5)\n", + " ax.errorbar(x=dfx.index,y=dfx['elapsed'],yerr=[dfx['elapsed_min'],dfx['elapsed_max']],\n", + " fmt='.k', ecolor='gray', lw=1)\n", + "\n", + " self.print_real_queryid(ax,dfx)\n", + " return (shuffle_pdf,dfx)\n", + " \n", + " def get_stages_w_odd_partitions(appals,**kwargs):\n", + " if appals.df is None:\n", + " appals.load_data()\n", + " return appals.df.where(\"Event='SparkListenerTaskEnd'\")\\\n", + " .groupBy(\"Stage ID\",\"real_queryid\")\\\n", + " .agg((F.sum(F.col('Finish Time')-F.col('Launch Time'))/1000).alias(\"elapsed time\"),\n", + " F.count('*').alias('partitions'))\\\n", + " .where(F.col(\"partitions\")%(appals.executor_cores*appals.executor_instances/appals.taskcpus)!=0)\\\n", + " .orderBy(F.desc(\"elapsed time\")).toPandas()\n", + " \n", + " def get_scaned_column_v1(appals):\n", + " def get_scans(node):\n", + " if node['nodeName'].startswith(\"Scan arrow\"):\n", + " scans.append(node)\n", + " for c in node['children']:\n", + " get_scans(c)\n", + "\n", + " alltable=[]\n", + " for qid in range(1,23):\n", + " scans=[]\n", + " plans=appals.queryplans.where(\"real_queryid=\"+str(qid)).collect()\n", + " get_scans(plans[0])\n", + " for s in scans:\n", + " alltable.append([qid,\",\".join([l.split(\":\")[0] for l in re.split(r'[<>]',s['metadata']['ReadSchema'])[1].split(\",\")])])\n", + " return alltable\n", + " \n", + " def get_scaned_column_v2(appals):\n", + " def get_scans(node):\n", + " if node['nodeName'].startswith(\"ColumnarBatchScan\"):\n", + " scans.append(node)\n", + " for c in node['children']:\n", + " get_scans(c)\n", + "\n", + " alltable=[]\n", + " for qid in range(1,23):\n", + " scans=[]\n", + " plans=appals.queryplans.where(\"real_queryid=\"+str(qid)).collect()\n", + " get_scans(plans[0])\n", + " for s in scans:\n", + " alltable.append([qid,\",\".join([l.split(\"#\")[0] for l in re.split(r\"[\\[\\]]\",s['simpleString'])[1].split(\",\")])])\n", + " return alltable\n", + " \n", + " def compare_query(appals,queryid,appbaseals):\n", + " print(f\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~Query{queryid}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\")\n", + " appals.show_critical_path_time_breakdown(queryid=22)\n", + " s1=appals.get_stage_stat(queryid=queryid)\n", + " s2=appbaseals.get_stage_stat(queryid=queryid)\n", + " ls=s1[['Stage ID','elapsed time']]\n", + " ls.columns=['l sid','l time']\n", + " rs=s2[['Stage ID','elapsed time']]\n", + " rs.columns=['r sid','r time']\n", + " js=ls.join(rs)\n", + " js['gap']=js['r time'] - js['l time']\n", + " js['gap']=js['gap'].round(2)\n", + " display(js)\n", + " display(s1)\n", + " display(s2)\n", + " stagesmap={}\n", + " for x in range(0,min(len(s1),len(s2))):\n", + " stagesmap[s1['Stage ID'][x]]=s2['Stage ID'][x]\n", + " totaltime=sum(s1['elapsed time'])\n", + " acctime=0\n", + " s1time=s1.sort_values(\"elapsed time\",ascending=False,ignore_index=True)\n", + " ldfx=appals.get_metric_output_rowcnt(queryid=queryid)\n", + " rdfx=appbaseals.get_metric_output_rowcnt(queryid=queryid)\n", + "\n", + " for x in range(0,len(s1time)):\n", + " sid1=int(s1time['Stage ID'][x])\n", + " sid2=int(stagesmap[sid1])\n", + " print(f\"============================================================\")\n", + " display(ldfx[ldfx['Stage ID']==sid1])\n", + " display(rdfx[ldfx['Stage ID']==sid2])\n", + " print(f\" Gazelle Query {queryid} Stage {sid1}\")\n", + " xf=appals.get_query_plan(stageid=sid1,show_simple_string=True)\n", + " print(f\" Photon Query {queryid} Stage {sid2}\")\n", + " xf=appbaseals.get_query_plan(stageid=sid2,show_simple_string=True)\n", + " acctime+=s1time['elapsed time'][x]\n", + " if acctime/totaltime>=0.9:\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "notlist=['resource.executor.cores',\n", + " 'spark.app.id',\n", + " 'spark.app.initial.file.urls',\n", + " 'spark.app.name',\n", + " 'spark.app.startTime',\n", + " 'spark.driver.port',\n", + " 'spark.job.description',\n", + " 'spark.jobGroup.id',\n", + " 'spark.org.apache.hadoop.yarn.server.webproxy.amfilter.AmIpFilter.param.PROXY_HOSTS',\n", + " 'spark.org.apache.hadoop.yarn.server.webproxy.amfilter.AmIpFilter.param.PROXY_URI_BASES',\n", + " 'spark.rdd.scope',\n", + " 'spark.sql.execution.id',\n", + " '__fetch_continuous_blocks_in_batch_enabled',\n", + " 'spark.driver.appUIAddress'\n", + " 'spark.driver.appUIAddress',\n", + " 'spark.driver.host',\n", + " 'spark.driver.appUIAddress',\n", + " 'spark.driver.extraClassPath',\n", + " 'spark.eventLog.dir',\n", + " 'spark.executorEnv.CC',\n", + " 'spark.executorEnv.LD_LIBRARY_PATH',\n", + " 'spark.executorEnv.LD_PRELOAD',\n", + " 'spark.executorEnv.LIBARROW_DIR',\n", + " 'spark.files',\n", + " 'spark.history.fs.logDirectory',\n", + " 'spark.sql.warehouse.dir',\n", + " 'spark.yarn.appMasterEnv.LD_PRELOAD',\n", + " 'spark.yarn.dist.files'\n", + "]\n", + "def comp_spark_conf(app0,app1): \n", + " pdf_sparkconf_0=app0.get_spark_config()\n", + " pdf_sparkconf_1=app1.get_spark_config()\n", + " pdfc=pdf_sparkconf_0.join(pdf_sparkconf_1,lsuffix=app0.appid[-8:],rsuffix=app1.appid[-8:])\n", + " pdfc[\"0\"+app0.appid[-8:]]=pdfc[\"0\"+app0.appid[-8:]].str.lower()\n", + " pdfc[\"0\"+app1.appid[-8:]]=pdfc[\"0\"+app1.appid[-8:]].str.lower()\n", + " \n", + " pdfc['comp']=(pdfc[\"0\"+app0.appid[-8:]]==pdfc[\"0\"+app1.appid[-8:]])\n", + " return pdfc.loc[(pdfc['comp']==False) & (~pdfc.index.isin(notlist))]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "## Node log analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "@pandas_udf(\"host string, id string,taskid int, time double\", PandasUDFType.GROUPED_MAP)\n", + "def collect_udf_time(pdf):\n", + " proxy_handler = request.ProxyHandler({})\n", + " opener = request.build_opener(proxy_handler)\n", + "\n", + " rst=[]\n", + " for idx,l in pdf.iterrows():\n", + " ip=\"10.1.2.19\"+l['Host'][-1:]\n", + " execid=\"{:06d}\".format(int(l['Executor ID'])+1)\n", + " appid=l['appid']\n", + " url = f'http://{ip}:8042/node/containerlogs/container_{appid}_01_{execid}/sparkuser/stderr/?start=0'\n", + " # open the website with the opener\n", + " req = opener.open(url)\n", + " data = req.read().decode('utf8')\n", + " cnt=data.split(\"\\n\")\n", + " cnt_udf=[l.split(\" \") for l in cnt if l.startswith('start UDF') or l.startswith('stop UDF')]\n", + " unf_pdf=pandas.DataFrame(cnt_udf)\n", + " srst=unf_pdf.loc[:,[0,4,6]]\n", + " srst.columns=['id','taskid','time']\n", + " srst['host']=l['Host']\n", + " srst['taskid']=srst['taskid'].astype(int)\n", + " srst['time']=srst['time'].apply(lambda f: float(re.search('\\d+\\.\\d+',f).group(0)))\n", + " rst.append(srst)\n", + " return pandas.concat(rst)\n", + "\n", + "\n", + "class App_Log_Analysis_Node_log(App_Log_Analysis):\n", + " def __init__(self, appid,jobids):\n", + " App_Log_Analysis.__init__(self, appid,jobids)\n", + " \n", + " def generate_trace_view_list(self,id=0, **kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " showcpu=kwargs['showcpu'] if 'showcpu' in kwargs else False\n", + " \n", + " appid=self.appid\n", + " events=self.df.toPandas()\n", + " coretrack={}\n", + " trace_events=[]\n", + " starttime=0\n", + " taskend=[]\n", + " trace={\"traceEvents\":[]}\n", + " exec_hosts={}\n", + " hostsdf=self.df.select(\"Host\").distinct().orderBy(\"Host\")\n", + " hostid=100000\n", + " ended_event=[]\n", + "\n", + " for i,l in hostsdf.toPandas().iterrows():\n", + " exec_hosts[l['Host']]=hostid\n", + " hostid=hostid+100000\n", + "\n", + " tskmap={}\n", + " for idx,l in events.iterrows():\n", + " if l['Event']=='SparkListenerTaskStart':\n", + " hostid=exec_hosts[l['Host']]\n", + "\n", + " tsk=l['Task ID']\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " stime=l['Launch Time']\n", + " #the task's starttime and finishtime is the same, ignore it.\n", + " if tsk in ended_event:\n", + " continue\n", + " if not pid in coretrack:\n", + " tids={}\n", + " trace_events.append({\n", + " \"name\": \"process_name\",\n", + " \"ph\": \"M\",\n", + " \"pid\":pid,\n", + " \"tid\":0,\n", + " \"args\":{\"name\":\"{:s}.{:s}\".format(l['Host'],l['Executor ID'])}\n", + " })\n", + "\n", + " else:\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==-1:\n", + " tids[t]=[tsk,stime]\n", + " break\n", + " else:\n", + " t=len(tids)\n", + " tids[t]=[tsk,stime]\n", + " #print(\"task {:d} tid is {:s}.{:d}\".format(tsk,pid,t))\n", + " coretrack[pid]=tids\n", + "\n", + " if l['Event']=='SparkListenerTaskEnd':\n", + " sevt={}\n", + " eevt={}\n", + " hostid=exec_hosts[l['Host']]\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " tsk=l['Task ID']\n", + " fintime=l['Finish Time']\n", + "\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==tsk:\n", + " tids[t]=[-1,-1]\n", + " break\n", + " else:\n", + " ended_event.append(tsk)\n", + " continue\n", + " for ps in reversed([key for key in tids.keys()]) :\n", + " if tids[ps][1]-fintime<0 and tids[ps][1]-fintime>=-2:\n", + " fintime=tids[ps][1]\n", + " tids[t]=tids[ps]\n", + " tids[ps]=[-1,-1]\n", + " break\n", + " if starttime==0:\n", + " starttime=l['Launch Time']\n", + "\n", + " sstime=l['Launch Time']-starttime\n", + "\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':sstime,\n", + " 'dur':fintime-l['Launch Time'],\n", + " 'pid':pid,\n", + " \"ph\":'X',\n", + " 'name':\"stg{:d}\".format(l['Stage ID']),\n", + " 'args':{\"job id\": l['job id'],\n", + " \"stage id\": l['Stage ID'],\n", + " \"tskid\":tsk,\n", + " \"input\":builtins.round(l[\"Bytes Read\"]/1024/1024,2),\n", + " \"spill\":builtins.round(l[\"Memory Bytes Spilled\"]/1024/1024,2),\n", + " \"Shuffle Read Metrics\": \"\",\n", + " \"|---Local Read\": builtins.round(l[\"Local Bytes Read\"]/1024/1024,2),\n", + " \"|---Remote Read\":builtins.round(l[\"Remote Bytes Read\"]/1024/1024,2),\n", + " \"Shuffle Write Metrics\": \"\",\n", + " \"|---Write\":builtins.round(l['Shuffle Bytes Written']/1024/1024,2)\n", + " }\n", + " })\n", + " tskmap[tsk]={'pid':pid,'tid':pid+int(t)}\n", + "\n", + " self.starttime=starttime\n", + " self.tskmap=tskmap\n", + "\n", + " hostdf=self.df.select('Host','Executor ID',F.lit(appid[len('application_'):]).alias('appid')).distinct().orderBy('Host')\n", + " rst=hostdf.groupBy('Host').apply(collect_udf_time)\n", + " rst.cache()\n", + " start_df=rst.where(\"id='start'\").select(F.col('taskid').alias('start_taskid'),F.col('time').alias(\"starttime\"))\n", + " stop_df=rst.where(\"id='stop'\").select('taskid',F.col('time').alias(\"stop_time\"))\n", + " df=start_df.join(stop_df, on=[start_df.start_taskid==stop_df.taskid,stop_df['stop_time']>=start_df['starttime']],how='left').groupBy('taskid','starttime').agg(F.min('stop_time').alias('stop_time'))\n", + " pdf=df.toPandas() \n", + " for idx,l in pdf.iterrows():\n", + " trace_events.append({\n", + " 'tid':self.tskmap[l['taskid']]['tid'],\n", + " 'ts':l['starttime']*1000-self.starttime,\n", + " 'dur':(l['stop_time']-l['starttime'])*1000, \n", + " 'pid':self.tskmap[l['taskid']]['pid'],\n", + " 'ph':'X',\n", + " 'name':'udf'})\n", + " \n", + " return [json.dumps(l) for l in trace_events]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class App_Log_Analysis_Node_log(App_Log_Analysis):\n", + " def __init__(self, appid,jobids):\n", + " App_Log_Analysis.__init__(self, appid,jobids)\n", + " \n", + " def generate_trace_view_list(self,id=0, **kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " showcpu=kwargs['showcpu'] if 'showcpu' in kwargs else False\n", + " \n", + " appid=self.appid\n", + " events=self.df.toPandas()\n", + " coretrack={}\n", + " trace_events=[]\n", + " starttime=0\n", + " taskend=[]\n", + " trace={\"traceEvents\":[]}\n", + " exec_hosts={}\n", + " hostsdf=self.df.select(\"Host\").distinct().orderBy(\"Host\")\n", + " hostid=100000\n", + " ended_event=[]\n", + "\n", + " for i,l in hostsdf.toPandas().iterrows():\n", + " exec_hosts[l['Host']]=hostid\n", + " hostid=hostid+100000\n", + "\n", + " tskmap={}\n", + " for idx,l in events.iterrows():\n", + " if l['Event']=='SparkListenerTaskStart':\n", + " hostid=exec_hosts[l['Host']]\n", + "\n", + " tsk=l['Task ID']\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " stime=l['Launch Time']\n", + " #the task's starttime and finishtime is the same, ignore it.\n", + " if tsk in ended_event:\n", + " continue\n", + " if not pid in coretrack:\n", + " tids={}\n", + " trace_events.append({\n", + " \"name\": \"process_name\",\n", + " \"ph\": \"M\",\n", + " \"pid\":pid,\n", + " \"tid\":0,\n", + " \"args\":{\"name\":\"{:s}.{:s}\".format(l['Host'],l['Executor ID'])}\n", + " })\n", + "\n", + " else:\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==-1:\n", + " tids[t]=[tsk,stime]\n", + " break\n", + " else:\n", + " t=len(tids)\n", + " tids[t]=[tsk,stime]\n", + " #print(\"task {:d} tid is {:s}.{:d}\".format(tsk,pid,t))\n", + " coretrack[pid]=tids\n", + "\n", + " if l['Event']=='SparkListenerTaskEnd':\n", + " sevt={}\n", + " eevt={}\n", + " hostid=exec_hosts[l['Host']]\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " tsk=l['Task ID']\n", + " fintime=l['Finish Time']\n", + "\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==tsk:\n", + " tids[t]=[-1,-1]\n", + " break\n", + " else:\n", + " ended_event.append(tsk)\n", + " continue\n", + " for ps in reversed([key for key in tids.keys()]) :\n", + " if tids[ps][1]-fintime<0 and tids[ps][1]-fintime>=-2:\n", + " fintime=tids[ps][1]\n", + " tids[t]=tids[ps]\n", + " tids[ps]=[-1,-1]\n", + " break\n", + " if starttime==0:\n", + " starttime=l['Launch Time']\n", + "\n", + " sstime=l['Launch Time']-starttime\n", + "\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':sstime,\n", + " 'dur':fintime-l['Launch Time'],\n", + " 'pid':pid,\n", + " \"ph\":'X',\n", + " 'name':\"stg{:d}\".format(l['Stage ID']),\n", + " 'args':{\"job id\": l['job id'],\n", + " \"stage id\": l['Stage ID'],\n", + " \"tskid\":tsk,\n", + " \"input\":builtins.round(l[\"Bytes Read\"]/1024/1024,2),\n", + " \"spill\":builtins.round(l[\"Memory Bytes Spilled\"]/1024/1024,2),\n", + " \"Shuffle Read Metrics\": \"\",\n", + " \"|---Local Read\": builtins.round(l[\"Local Bytes Read\"]/1024/1024,2),\n", + " \"|---Remote Read\":builtins.round(l[\"Remote Bytes Read\"]/1024/1024,2),\n", + " \"Shuffle Write Metrics\": \"\",\n", + " \"|---Write\":builtins.round(l['Shuffle Bytes Written']/1024/1024,2)\n", + " }\n", + " })\n", + " tskmap[tsk]={'pid':pid,'tid':pid+int(t)}\n", + "\n", + " self.starttime=starttime\n", + " self.tskmap=tskmap\n", + "\n", + " hostdf=self.df.select('Host','Executor ID',F.lit(appid[len('application_'):]).alias('appid')).distinct().orderBy('Host')\n", + " rst=hostdf.groupBy('Host').apply(collect_udf_time)\n", + " rst.cache()\n", + " start_df=rst.where(\"id='start'\").select(F.col('taskid').alias('start_taskid'),F.col('time').alias(\"starttime\"))\n", + " stop_df=rst.where(\"id='stop'\").select('taskid',F.col('time').alias(\"stop_time\"))\n", + " df=start_df.join(stop_df, on=[start_df.start_taskid==stop_df.taskid,stop_df['stop_time']>=start_df['starttime']],how='left').groupBy('taskid','starttime').agg(F.min('stop_time').alias('stop_time'))\n", + " pdf=df.toPandas() \n", + " for idx,l in pdf.iterrows():\n", + " trace_events.append({\n", + " 'tid':self.tskmap[l['taskid']]['tid'],\n", + " 'ts':l['starttime']*1000-self.starttime,\n", + " 'dur':(l['stop_time']-l['starttime'])*1000, \n", + " 'pid':self.tskmap[l['taskid']]['pid'],\n", + " 'ph':'X',\n", + " 'name':'udf'})\n", + " \n", + " return [json.dumps(l) for l in trace_events]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class App_Log_Analysis_Node_Log_Uni(App_Log_Analysis):\n", + " def __init__(self, file,jobids):\n", + " App_Log_Analysis.__init__(self, file,jobids)\n", + " \n", + " def generate_trace_view_list(self,id=0, **kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " showcpu=False\n", + " \n", + " shownodes=kwargs.get(\"shownodes\",None)\n", + "\n", + " showdf=self.df #self.df.where(F.col(\"Host\").isin(shownodes)) if shownodes else self.df\n", + "\n", + " events=showdf.drop(\"Accumulables\",\"Stage IDs\").orderBy(\"Launch Time\",\"Finish Time\").toPandas()\n", + " coretrack={}\n", + " trace_events=[]\n", + " starttime=0\n", + " taskend=[]\n", + " trace={\"traceEvents\":[]}\n", + " exec_hosts={}\n", + " hostsdf=showdf.select(\"Host\").distinct().orderBy(\"Host\")\n", + " hostid=100000\n", + " ended_event=[]\n", + "\n", + " applog=os.path.splitext(self.file)[0]+\".stdout\"\n", + " logdfs=[]\n", + " if fs.exists(applog):\n", + " logdata=sc.textFile(os.path.splitext(self.file)[0]+\".stdout\",84)\n", + " logdf=logdata.mapPartitions(splits).toDF()\n", + " logdfs.append(logdf)\n", + "\n", + " p=os.path.split(self.file)\n", + " for c in shownodes:\n", + " f=p[0]+\"/\"+c+\"/xgbtck.txt\"\n", + " if fs.exists(f):\n", + " logdata=sc.textFile(f,84)\n", + " logdf=logdata.mapPartitions(splits).toDF()\n", + " logdfs.append(logdf)\n", + " logdf=reduce(lambda l,r: l.concat(r),logdfs)\n", + " logdf=logdf.cache()\n", + " logdf.count()\n", + "\n", + " firstrow=logdf.limit(1).collect()\n", + "\n", + " for c in logdf.columns:\n", + " if firstrow[0][c]!=\"xgbtck\":\n", + " logdf=logdf.drop(c)\n", + " else:\n", + " break\n", + "\n", + " usefulc=[\"xgbtck\",\"event\",\"ts\",\"elapsed\",\"threadid\",\"taskid\"]\n", + " for i in range(0,len(usefulc)):\n", + " logdf=logdf.withColumnRenamed(logdf.columns[i],usefulc[i])\n", + "\n", + " logdf=logdf.where(F.col(\"event\").isin(['load_library','data_load','data_convert']))\n", + " \n", + " task_thread=logdf.where(\"event='data_convert'\").select(F.col(\"taskid\").astype(IntegerType()),F.col(\"threadid\").astype(IntegerType())).distinct().toPandas().set_index('taskid').to_dict('index')\n", + " #task_thread={}\n", + "\n", + " for i,l in hostsdf.toPandas().iterrows():\n", + " exec_hosts[l['Host']]=hostid\n", + " hostid=hostid+100000\n", + "\n", + " tskmap={}\n", + " for idx,l in events.iterrows():\n", + " if l['Event']=='SparkListenerTaskStart':\n", + " hostid=exec_hosts[l['Host']]\n", + "\n", + " tsk=l['Task ID']\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " stime=l['Launch Time']\n", + " #the task's starttime and finishtime is the same, ignore it.\n", + " if tsk in ended_event:\n", + " continue\n", + " if not pid in coretrack:\n", + " tids={}\n", + " trace_events.append({\n", + " \"name\": \"process_name\",\n", + " \"ph\": \"M\",\n", + " \"pid\":pid,\n", + " \"tid\":0,\n", + " \"args\":{\"name\":\"{:s}.{:s}\".format(l['Host'],l['Executor ID'])}\n", + " })\n", + "\n", + " else:\n", + " tids=coretrack[pid]\n", + "\n", + " tidarr=[tsk,stime]\n", + "\n", + " for t in tids.keys():\n", + " if tids[t][0]==-1:\n", + " tids[t]=tidarr\n", + " break\n", + " else:\n", + " t=len(tids)\n", + " tids[t]=tidarr\n", + " #print(\"task {:d} tid is {:s}.{:d}\".format(tsk,pid,t))\n", + " coretrack[pid]=tids\n", + "\n", + " if l['Event']=='SparkListenerTaskEnd':\n", + " sevt={}\n", + " eevt={}\n", + " hostid=exec_hosts[l['Host']]\n", + " pid=int(l['Executor ID'])*100+hostid\n", + " tsk=l['Task ID']\n", + " fintime=l['Finish Time']\n", + "\n", + " tids=coretrack[pid]\n", + " for t in tids.keys():\n", + " if tids[t][0]==tsk:\n", + " tids[t]=[-1,-1]\n", + " break\n", + " else:\n", + " ended_event.append(tsk)\n", + " continue\n", + " for ps in reversed([key for key in tids.keys()]):\n", + " if (tids[ps][1]-fintime<0 and tids[ps][1]-fintime>=-2) or \\\n", + " (tsk in task_thread and tids[ps][0] in task_thread and task_thread[tsk][\"threadid\"]==task_thread[tids[ps][0]][\"threadid\"]):\n", + " fintime=tids[ps][1]\n", + " tids[t]=tids[ps]\n", + " tids[ps]=[-1,-1]\n", + " break\n", + " if starttime==0:\n", + " starttime=l['Launch Time']\n", + "\n", + " sstime=l['Launch Time']-starttime\n", + "\n", + " trace_events.append({\n", + " 'tid':pid+int(t),\n", + " 'ts':sstime,\n", + " 'dur':fintime-l['Launch Time'],\n", + " 'pid':pid,\n", + " \"ph\":'X',\n", + " 'name':\"stg{:d}\".format(l['Stage ID']),\n", + " 'args':{\"job id\": l['Job ID'],\n", + " \"stage id\": l['Stage ID'],\n", + " \"tskid\":tsk,\n", + " \"input\":builtins.round(l[\"Bytes Read\"]/1024/1024,2),\n", + " \"spill\":builtins.round(l[\"Memory Bytes Spilled\"]/1024/1024,2),\n", + " \"Shuffle Read Metrics\": \"\",\n", + " \"|---Local Read\": builtins.round(l[\"Local Bytes Read\"]/1024/1024,2),\n", + " \"|---Remote Read\":builtins.round(l[\"Remote Bytes Read\"]/1024/1024,2),\n", + " \"Shuffle Write Metrics\": \"\",\n", + " \"|---Write\":builtins.round(l['Shuffle Bytes Written']/1024/1024,2)\n", + " }\n", + " })\n", + " tskmap[tsk]={'pid':pid,'tid':pid+int(t)}\n", + "\n", + " self.starttime=starttime\n", + " self.tskmap=tskmap\n", + "\n", + " tskmapdf = spark.createDataFrame(pandas.DataFrame(self.tskmap).T.reset_index())\n", + " logdf=logdf.withColumn(\"ts\",F.col(\"ts\").astype(LongType()))\n", + " logdf=logdf.withColumn(\"taskid\",F.col(\"taskid\").astype(LongType()))\n", + " logdf=logdf.withColumnRenamed(\"event\",'type')\n", + " mgd=logdf.join(tskmapdf,on=(F.col('taskid')==F.col(\"index\")),how=\"right\")\n", + " rstdf=mgd.select(F.col('tid').alias(\"tid\"),\n", + " (F.round(F.col('ts')-F.lit(self.starttime),3)).alias(\"ts\"),\n", + " F.round(F.col(\"elapsed\"),3).alias(\"dur\"),\n", + " F.lit(F.col('pid')).alias(\"pid\"),\n", + " F.lit(\"X\").alias(\"ph\"),\n", + " F.col(\"type\").alias(\"name\")\n", + " ).where(F.col(\"ts\").isNotNull()).orderBy('ts')\n", + "\n", + " # logdf=logdf.withColumn(\"type\",F.substring_index(\"event\",\"_\",1))\n", + " # window= Window.partitionBy(logdf['taskid']).orderBy(\"type\",\"ts\")\n", + " # logdfx=logdf.select(\"taskid\",\"event\",\"type\",\"ts\",F.lag('ts',1).over(window).alias(\"last\"),F.lag('rownum',1).over(window).alias(\"rownum\")).orderBy(\"taskid\",\"ts\").where(\"event like '%end'\")\n", + "\n", + "\n", + " output=[json.dumps(l) for l in trace_events]\n", + " output.extend(rstdf.toJSON().collect())\n", + "\n", + " return output" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# perf trace analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "def split_trace(x):\n", + " fi=[]\n", + " for l in x:\n", + " rst1=re.search(r\"^(\\d+\\.\\d+).*sched:(sched_switch):.+:(\\d+) \\[\\d+\\] (\\S+) ==> .+:(\\d+) \"\"\",l)\n", + " rst2=re.search(r\"(\\d+\\.\\d+) \\( +(\\d+\\.\\d+) +ms\\):[^/]+/(\\d+) (recvfrom|sendto)\\(fd: \\d+<\\S+:\\[\\d+\\]>, \\S+: 0x[a-f0-9]+, \\S+: (\\d+)\",l)\n", + " rst3=re.search(r\"(\\d+\\.\\d+) \\( +\\): [^/]+/(\\d+) (recvfrom|sendto)\\(fd: \\d+<\\S+:\\[\\d+\\]>, \\S+: 0x[a-f0-9]+, \\S+: (\\d+)\",l)\n", + " rst4=re.search(r\"(\\d+\\.\\d+) \\( *(\\d+\\.\\d+) ms\\): [^/]+/(\\d+) ... \\[continued\\]: (sendto|recvfrom|poll)\",l)\n", + " rst5=re.search(r\"(\\d+\\.\\d+) \\( +(\\d+\\.\\d+) +ms\\): [^/]+/(\\d+) (poll)\",l)\n", + " rst6=re.search(r\"(\\d+\\.\\d+) \\( +\\): [^/]+/(\\d+) (poll)\",l)\n", + "\n", + " rstx=re.search(r\"(\\d+\\.\\d+)*sched:(sched_switch):.*prev_pid=(\\d+).*prev_state=(\\S+) ==> .*next_pid=(\\d+)\"\"\",l)\n", + " if not rst1:\n", + " rst1=rstx\n", + " \n", + " if rst1:\n", + " fi.append((rst1.group(1),rst1.group(2),rst1.group(3),rst1.group(4),rst1.group(5))) #time, switch, src, status, dst\n", + " elif rst2:\n", + " fi.append((rst2.group(1),rst2.group(4),rst2.group(3),rst2.group(2),rst2.group(5))) #time, sed/rcv, pid, ms, size \n", + " elif rst3:\n", + " fi.append((rst3.group(1),rst3.group(3),rst3.group(2),0, rst3.group(4))) #time, sed/rcv, pid, 0, size\n", + " elif rst4:\n", + " fi.append((rst4.group(1),rst4.group(4),rst4.group(3),rst4.group(2), 0)) #time, sed/rcv, pid, ms, 0\n", + " elif rst5:\n", + " fi.append((rst5.group(1),rst5.group(4),rst5.group(3),rst5.group(2), 0)) #time, sed/rcv, pid, ms, 0\n", + " elif rst6:\n", + " fi.append((rst6.group(1),rst6.group(3),rst6.group(2),0, 0)) #time, sed/rcv, pid, ms0, 0\n", + " elif not re.match(r\"^ +?\",l):\n", + " fi.append((0,l,'','',''))\n", + " return iter(fi)\n", + " \n", + "\n", + "\n", + "class Perf_trace_analysis(Analysis):\n", + " def __init__(self,sar_file):\n", + " Analysis.__init__(self,sar_file)\n", + " self.starttime=None\n", + " \n", + " def load_data(self):\n", + " sardata=sc.textFile(self.file)\n", + " sardf=sardata.mapPartitions(split_trace).toDF()\n", + " display(sardf.where(\"_1=0\").limit(5).collect())\n", + " sardf=sardf.withColumn(\"_1\",F.col(\"_1\").astype(DoubleType()))\n", + " sardf=sardf.where(\"_1>0\")\n", + " starttime=sardf.agg(F.min(\"_1\")).collect()[0][0]\n", + " if self.starttime is None:\n", + " self.starttime=(float(starttime))\n", + " else:\n", + " paths=os.path.split(self.file)\n", + " if fs.exists(paths[0]+\"/uptime.txt\"):\n", + " with fs.open(paths[0]+\"/uptime.txt\") as f:\n", + " strf=f.read().decode('ascii')\n", + " print(\"input starttime:\",self.starttime,\"uptime:\",float(strf)*1000,\"record starttime:\",starttime)\n", + " self.starttime=self.starttime-float(strf)*1000\n", + " else:\n", + " print(\"uptime.txt isn't found, wrong\")\n", + " return\n", + " \n", + " self.df=sardf\n", + " return sardf\n", + "\n", + " def generate_sched_view_list(self,id=0,**kwargs):\n", + " sardf=self.df\n", + " starttime=self.starttime\n", + " starttime=starttime+kwargs.get(\"sched_time_offset\",0)\n", + " print(\"offset time\",starttime)\n", + " \n", + " swdf=sardf.where(\"_2='sched_switch'\")\n", + " \n", + " cputhreshold=kwargs.get(\"cpu_threshold\",0.1)\n", + " sched_cnt = kwargs.get(\"sched_cnt\",10)\n", + " \n", + " pidstat_tids=kwargs.get(\"pidstat_tids\",None)\n", + " pidstat_tids_txt=kwargs.get(\"pidstat_tids_txt\",\"sched_threads.txt\")\n", + " \n", + " if pidstat_tids:\n", + " if type(pidstat_tids) is list:\n", + " tids=pidstat_tids\n", + " else:\n", + " tids=[re.split(r'\\s+',t) for t in pidstat_tids.split(\"\\n\")]\n", + " tids=[t[3] for t in tids if len(t)>4]\n", + " else:\n", + " paths=os.path.split(self.file)\n", + " if fs.exists(paths[0]+\"/\"+pidstat_tids_txt):\n", + " with fs.open(paths[0]+\"/\"+pidstat_tids_txt) as f:\n", + " tids=[l.strip() for l in f.read().decode('ascii').split(\"\\n\") if len(l)>0] \n", + " else:\n", + " print(\"Wrong, no pidstat_tids args and no sched_threads.txt file\")\n", + " return []\n", + " tidcnt=swdf.where(F.col(\"_5\").isin(tids)).groupBy(\"_5\").count()\n", + " tidm10=tidcnt.where(\"count>{:d}\".format(sched_cnt)).select(\"_5\").collect()\n", + " rtids=[t[0] for t in tidm10]\n", + " rtiddf=swdf.where(F.col(\"_5\").isin(rtids) | F.col(\"_3\").isin(rtids))\n", + " rtiddf=rtiddf.withColumn(\"_1\",F.col(\"_1\").astype(DoubleType())-starttime)\n", + " rtiddf=rtiddf.withColumn(\"_3\",F.col(\"_3\").astype(IntegerType()))\n", + " rtiddf=rtiddf.withColumn(\"_5\",F.col(\"_5\").astype(IntegerType()))\n", + " rtiddf=rtiddf.withColumn(\"_1\",F.round(F.col(\"_1\"),3))\n", + " rtidcol=rtiddf.collect()\n", + " tidmap={}\n", + " tidtotal={}\n", + " for t in rtids:\n", + " tidmap[int(t)]=0\n", + " tidtotal[int(t)]=0\n", + " trace_events=[]\n", + " mintime=rtidcol[0][\"_1\"]\n", + " maxtime=0\n", + " for r in rtidcol:\n", + " if r[\"_3\"] in tidtotal:\n", + " tidtotal[r[\"_3\"]]=tidtotal[r[\"_3\"]]+r[\"_1\"]-tidmap[r[\"_3\"]]\n", + " tidmap[r[\"_3\"]]=r[\"_1\"]\n", + " maxtime=r[\"_1\"]\n", + " if r[\"_5\"] in tidmap:\n", + " tidmap[r[\"_5\"]]=r[\"_1\"]\n", + " for r in rtidcol:\n", + " if r[\"_3\"] in tidmap and tidtotal[r[\"_3\"]]/(maxtime-mintime)>cputhreshold:\n", + " trace_events.append({\n", + " 'tid':r[\"_3\"],\n", + " 'ts':tidmap[r[\"_3\"]],\n", + " 'pid':id,\n", + " 'ph':'X',\n", + " 'dur':round(r[\"_1\"]-tidmap[r[\"_3\"]],3),\n", + " 'name':r[\"_4\"]\n", + " })\n", + "\n", + " tidmap[r[\"_3\"]]=r[\"_1\"]\n", + " if r[\"_5\"] in tidmap:\n", + " tidmap[r[\"_5\"]]=r[\"_1\"]\n", + " return [json.dumps(l) for l in trace_events]\n", + "\n", + " def generate_nic_view_list(self,id=0,**kwargs):\n", + " sardf=self.df\n", + " starttime=self.starttime\n", + " starttime=starttime+kwargs.get(\"sched_time_offset\",0)\n", + " print(\"offset time\",starttime)\n", + " \n", + " nicdf=sardf.where(\"_2<>'sched_switch'\")\n", + " cntdf=nicdf.where(\"_2='continued'\")\n", + " cntdf=cntdf.select(\"_1\",\"_3\",\"_4\").withColumnRenamed(\"_4\",\"cnt_4\")\n", + " nicdf=nicdf.join(cntdf,on=[\"_1\",\"_3\"],how=\"leftouter\")\n", + " nicdf=nicdf.where(\"_2<>'continued'\")\n", + " nicdf=nicdf.select(F.col(\"_1\"),F.col(\"_2\"),F.col(\"_3\"),F.when(F.col(\"cnt_4\").isNull(), F.col(\"_4\")).otherwise(F.col(\"cnt_4\")).alias(\"_4\"),F.col(\"_5\"))\n", + " nicdf=nicdf.withColumn(\"_1\",F.col(\"_1\").astype(DoubleType())-starttime)\n", + " nicdf=nicdf.withColumn(\"_3\",F.col(\"_3\").astype(IntegerType()))\n", + " nicdf=nicdf.withColumn(\"_5\",F.col(\"_5\").astype(IntegerType()))\n", + " nicdf=nicdf.withColumn(\"_1\",F.col(\"_1\").astype(IntegerType()))\n", + " nicdf=nicdf.withColumn(\"_4\",F.col(\"_4\").astype(DoubleType()))\n", + " nicdf=nicdf.withColumn(\"_4\",F.col(\"_4\").astype(LongType()))\n", + " return nicdf.select(\n", + " F.col(\"_3\").alias('tid'),\n", + " (F.col(\"_1\")).alias('ts'),\n", + " F.lit(0).alias('pid'),\n", + " F.lit('X').alias('ph'),\n", + " F.col(\"_4\").alias('dur'),\n", + " F.col(\"_2\").alias('name'),\n", + " F.struct(\n", + " F.col(\"_5\").alias(\"size\")\n", + " ).alias('args')\n", + " ).toJSON().collect()\n", + " \n", + " def generate_trace_view_list(self,id=0,**kwargs):\n", + " trace_events=Analysis.generate_trace_view_list(self,id,**kwargs)\n", + " sardf=self.df\n", + " starttime=self.starttime\n", + " \n", + " events=self.generate_sched_view_list(id,**kwargs)\n", + " events.extend(self.generate_nic_view_list(id,**kwargs))\n", + " events.extend(trace_events)\n", + " \n", + "# events.extend(nicdf.where(\"_5>1000 and _2='sendto'\").select(\n", + "# F.lit(0).alias('tid'),\n", + "# F.col(\"_1\").alias('ts'),\n", + "# F.lit(0).alias('pid'),\n", + "# F.lit('i').alias('ph'),\n", + "# F.col(\"_2\").alias('name'),\n", + "# F.lit(\"g\").alias(\"s\")\n", + "# ).toJSON().collect())\n", + "\n", + "\n", + " return events\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Sar analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "def splits(x):\n", + " fi=[]\n", + " for l in x:\n", + " li=re.split(r'\\s+',l)\n", + " for j in range(len(li),118):\n", + " li.append('')\n", + " fi.append(li)\n", + " return iter(fi)\n", + "\n", + "class Sar_analysis(Analysis):\n", + " def __init__(self,sar_file):\n", + " Analysis.__init__(self,sar_file)\n", + " \n", + " def load_data(self):\n", + " sardata=sc.textFile(self.file)\n", + " sardf=sardata.mapPartitions(splits).toDF()\n", + " sardf=sardf.where(\"_1<>'Average:'\")\n", + " \n", + " colstart=1;\n", + " ampm=sardf.where(\"_2='AM' or _2='PM'\").count()\n", + " if ampm==0:\n", + " for i in range(len(sardf.columns),1,-1):\n", + " sardf=sardf.withColumnRenamed(f'_{i}',f'_{i+1}')\n", + " self.timeformat='yyyy-MM-dd HH:mm:ss '\n", + " sardf=sardf.withColumn('_2',F.lit(''))\n", + " #print('no PM/AM')\n", + " colstart=1\n", + " else:\n", + " self.timeformat='yyyy-MM-dd hh:mm:ss a'\n", + " colstart=2\n", + " #print('with PM/AM')\n", + " \n", + " f=fs.open(self.file)\n", + " t=f.readline()\n", + " t=f.readline()\n", + " while len(t)==1:\n", + " t=f.readline()\n", + " cols=t.decode('ascii')\n", + " li=re.split(r'\\s+',cols)\n", + " ci=3;\n", + " for c in li[colstart:]:\n", + " sardf=sardf.withColumnRenamed(f\"_{ci}\",c)\n", + " ci=ci+1\n", + " \n", + " sardf=sardf.where(F.col(li[-2])!=li[-2]).where(F.col(\"_1\")!=F.lit(\"Linux\")) \n", + " \n", + " sardf.cache()\n", + " self.df=sardf\n", + " \n", + " self.sarversion=\"\"\n", + " paths=os.path.split(self.file)\n", + " if fs.exists(paths[0]+\"/sarv.txt\"):\n", + " with fs.open(paths[0]+\"/sarv.txt\") as f:\n", + " allcnt = f.read().decode('ascii')\n", + " #print(allcnt)\n", + " self.sarversion=allcnt.split(\"\\n\")[0].split(\" \")[2]\n", + " \n", + " return sardf\n", + "\n", + " def col_df(self,cond,colname,args,slaver_id=0, thread_id=0):\n", + " sardf=self.df\n", + " starttime=self.starttime\n", + " cpudf=sardf.where(cond)\n", + " #cpudf.select(F.date_format(F.from_unixtime(F.lit(starttime/1000)), 'yyyy-MM-dd HH:mm:ss').alias('starttime'),'_1').show(1)\n", + "\n", + " cpudf=cpudf.withColumn('time',F.unix_timestamp(F.concat_ws(' ',F.date_format(F.from_unixtime(F.lit(starttime/1000)), 'yyyy-MM-dd'),F.col('_1'),F.col('_2')),self.timeformat))\n", + "\n", + " cols=cpudf.columns\n", + " \n", + " cpudf=cpudf.groupBy('time').agg(\n", + " F.sum(F.when(F.col(cols[1]).rlike('^\\d+(\\.\\d+)*$'),F.col(cols[1]).astype(FloatType())).otherwise(0)).alias(cols[1]),\n", + " F.sum(F.when(F.col(cols[2]).rlike('^\\d+(\\.\\d+)*$'),F.col(cols[2]).astype(FloatType())).otherwise(0)).alias(cols[2]),\n", + " *[F.sum(F.col(c)).alias(c) for c in cols[3:] if not c.startswith(\"_\") and c!=\"\" and c!=\"time\"]\n", + " )\n", + " \n", + " traces=cpudf.orderBy(F.col(\"time\")).select(\n", + " F.lit(thread_id).alias('tid'),\n", + " (F.expr(\"time*1000\")-F.lit(self.starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(slaver_id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.lit(colname).alias('name'),\n", + " args(cpudf).alias('args')\n", + " ).toJSON().collect()\n", + " return traces\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_events=Analysis.generate_trace_view_list(self,id, **kwargs)\n", + " return trace_events\n", + "\n", + " def get_stat(self,**kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + " \n", + "class Sar_cpu_analysis(Sar_analysis):\n", + " def __init__(self,sar_file):\n", + " Sar_analysis.__init__(self,sar_file)\n", + " \n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_events=Sar_analysis.generate_trace_view_list(self,id, **kwargs)\n", + " \n", + " self.df=self.df.withColumn(\"%iowait\",F.when(F.col(\"%iowait\")>100,F.lit(100)).otherwise(F.col(\"%iowait\")))\n", + " \n", + " trace_events.extend(self.col_df(\"CPU='all'\", \"all cpu%\", lambda l: F.struct(\n", + " F.floor(F.col('%user').astype(FloatType())).alias('user'),\n", + " F.floor(F.col('%system').astype(FloatType())).alias('system'),\n", + " F.floor(F.col('%iowait').astype(FloatType())).alias('iowait')\n", + " ), id, 0))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":0,\"args\":{\"sort_index \":0}}))\n", + " \n", + " return trace_events \n", + " def get_stat(sar_cpu,**kwargs):\n", + " Sar_analysis.get_stat(sar_cpu)\n", + " \n", + " cpuutil=sar_cpu.df.where(\"CPU='all'\").groupBy(\"_1\").agg(*[F.mean(F.col(l).astype(FloatType())).alias(l) for l in [\"%user\",\"%system\",\"%iowait\"]]).orderBy(\"_1\")\n", + " cnt=cpuutil.count()\n", + " user_morethan_90=cpuutil.where(\"`%user`>0.9\").count()\n", + " kernel_morethan_10=cpuutil.where(\"`%system`>0.1\").count()\n", + " iowait_morethan_10=cpuutil.where(\"`%iowait`>0.1\").count()\n", + " out=[['%user>90%',user_morethan_90/cnt],['%kernel>10%',kernel_morethan_10/cnt],[\"%iowait>10%\",iowait_morethan_10/cnt]]\n", + " avgutil=cpuutil.agg(*[F.mean(l).alias(l) for l in [\"%user\",\"%system\",\"%iowait\"]]).collect()\n", + " out.extend([[\"avg \" + l,avgutil[0][l]] for l in [\"%user\",\"%system\",\"%iowait\"]])\n", + " pdout=pandas.DataFrame(out).set_index(0)\n", + " pdout.columns=[sar_cpu.file.split(\"/\")[-2]]\n", + " return pdout\n", + " \n", + "class Sar_mem_analysis(Sar_analysis):\n", + " def __init__(self,sar_file):\n", + " Sar_analysis.__init__(self,sar_file)\n", + " \n", + " def load_data(self):\n", + " Sar_analysis.load_data(self)\n", + " sarv=[int(l) for l in self.sarversion.split(\".\")]\n", + " if sarv[0]>=12 and sarv[1]>=2:\n", + " self.df=self.df.withColumn(\"kbrealused\",F.col(\"kbmemused\"))\n", + " else:\n", + " # sar 10.1.5, sar 11.6.1\n", + " self.df=self.df.withColumn(\"kbrealused\",F.col(\"kbmemused\")-F.col(\"kbcached\")-F.col(\"kbbuffers\"))\n", + " \n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_events=Sar_analysis.generate_trace_view_list(self,id, **kwargs)\n", + " \n", + " \n", + " trace_events.extend(self.col_df(F.col('kbmemfree').rlike('^\\d+$'),\"mem % \", lambda l: F.struct(F.floor(l['kbcached']*l['%memused']/l['kbmemused']).alias('cached'), # kbcached / (kbmemfree+kbmemused)\n", + " F.floor(l['kbbuffers']*l['%memused']/l['kbmemused']).alias('buffered'),# kbbuffers / (kbmemfree+kbmemused)\n", + " F.floor(l['kbrealused']*l['%memused']/l['kbmemused']).alias('used')), # (%memused- kbcached-kbbuffers )/ (kbmemfree+kbmemused)\n", + " id,1))\n", + " #trace_events.extend(self.col_df(self.df._3.rlike('^\\d+$'),\"mem cmt % \", lambda l: F.struct(F.floor(l._8*F.lit(100)/(l._3+l._4)).alias('commit/phy'),\n", + " # F.floor(l._10-l._8*F.lit(100)/(l._3+l._4)).alias('commit/all')), id))\n", + " trace_events.extend(self.col_df(F.col('kbmemfree').rlike('^\\d+$'),\"pagecache % \", lambda l: F.struct(F.floor((l['kbcached']-l['kbdirty'])*l['%memused']/l['kbmemused']).alias('clean'), \n", + " F.floor(l['kbdirty']*l['%memused']/l['kbmemused']).alias('dirty')),\n", + " id,2))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":1,\"args\":{\"sort_index \":1}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":2,\"args\":{\"sort_index \":2}}))\n", + " return trace_events \n", + " def get_stat(sar_mem,**kwargs):\n", + " Sar_analysis.get_stat(sar_mem)\n", + " \n", + " memutil=sar_mem.df.where(F.col('kbmemfree').rlike('^\\d+$')).select(F.floor(F.col('kbcached').astype(FloatType())*F.lit(100)*F.col('%memused')/F.col('kbmemused')).alias('cached'), \n", + " F.floor(F.col('kbbuffers').astype(FloatType())*F.lit(100)*F.col('%memused')/F.col('kbmemused')).alias('buffered'),\n", + " F.floor(F.col('kbrealused').astype(FloatType())*F.lit(100)*F.col('%memused')/F.col('kbmemused')).alias('used'),\n", + " F.floor(F.col('kbdirty').astype(FloatType())*F.lit(100)*F.col('%memused')/F.col('kbmemused')).alias('dirty'))\n", + " memsum=memutil.summary().toPandas()\n", + " memsum=memsum.set_index(\"summary\")\n", + " out=[\n", + " [[l + ' mean',float(memsum[l][\"mean\"])],\n", + " [l + ' 75%',float(memsum[l][\"75%\"])],\n", + " [l + ' max',float(memsum[l][\"max\"])]] for l in [\"cached\",\"used\",\"dirty\"]]\n", + " out=[*out[0],*out[1]]\n", + " pdout=pandas.DataFrame(out).set_index(0)\n", + " pdout.columns=[sar_mem.file.split(\"/\")[-2]]\n", + " return pdout\n", + " \n", + "class Sar_PageCache_analysis(Sar_analysis):\n", + " def __init__(self,sar_file):\n", + " Sar_analysis.__init__(self,sar_file)\n", + " \n", + " def load_data(self):\n", + " Sar_analysis.load_data(self)\n", + " \n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_events=Sar_analysis.generate_trace_view_list(self,id, **kwargs)\n", + " \n", + " \n", + " trace_events.extend(self.col_df(F.col('pgpgin/s').rlike('^\\d'),\"page inout\", lambda l: F.struct(\n", + " F.floor(l['pgpgin/s']/1024).alias('in'),\n", + " F.floor(l['pgpgout/s']/1024).alias('out')),\n", + " id,11))\n", + " trace_events.extend(self.col_df(F.col('pgpgin/s').rlike('^\\d'),\"faults\", lambda l: F.struct(F.floor((l['majflt/s'])).alias('major'), \n", + " F.floor(l['fault/s']-l['majflt/s']).alias('minor')),\n", + " id,12))\n", + " trace_events.extend(self.col_df(F.col('pgpgin/s').rlike('^\\d'),\"page free\", lambda l: F.struct(F.floor((l['pgfree/s']*4/1024)).alias('free')),\n", + " id,13))\n", + " trace_events.extend(self.col_df(F.col('pgpgin/s').rlike('^\\d'),\"scan\", lambda l: F.struct(F.floor((l['pgscank/s'])*4/1024).alias('kernel'), \n", + " F.floor(l['pgscand/s']*4/1024).alias('app')),\n", + " id,14))\n", + " trace_events.extend(self.col_df(F.col('pgpgin/s').rlike('^\\d'),\"vmeff\", lambda l: F.struct(F.floor((l['%vmeff'])).alias('steal')),\n", + " id,15))\n", + " \n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":11,\"args\":{\"sort_index \":11}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":12,\"args\":{\"sort_index \":12}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":13,\"args\":{\"sort_index \":13}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":14,\"args\":{\"sort_index \":14}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":15,\"args\":{\"sort_index \":15}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":16,\"args\":{\"sort_index \":16}}))\n", + " return trace_events \n", + " def get_stat(sar_mem,**kwargs):\n", + " Sar_analysis.get_stat(sar_mem)\n", + " \n", + " memutil=sar_mem.df.where(F.col('pgpgin/s').rlike('^\\d')).select(F.floor(F.col('pgpgin/s').astype(FloatType())/1024).alias('pgin'), \n", + " F.floor(F.col('pgpgout/s').astype(FloatType())/1024).alias('pgout'),\n", + " F.floor(F.col('fault/s').astype(FloatType())-F.col('majflt/s').astype(FloatType())).alias('fault')\n", + " )\n", + " memsum=memutil.summary().toPandas()\n", + " memsum=memsum.set_index(\"summary\")\n", + " out=[\n", + " [[l + ' mean',float(memsum[l][\"mean\"])],\n", + " [l + ' 75%',float(memsum[l][\"75%\"])],\n", + " [l + ' max',float(memsum[l][\"max\"])]] for l in [\"pgin\",\"pgout\",\"fault\"]]\n", + " out=[*out[0],*out[1],*out[2]]\n", + " pdout=pandas.DataFrame(out).set_index(0)\n", + " pdout.columns=[sar_mem.file.split(\"/\")[-2]]\n", + " return pdout\n", + " \n", + " \n", + "class Sar_disk_analysis(Sar_analysis):\n", + " def __init__(self,sar_file):\n", + " Sar_analysis.__init__(self,sar_file)\n", + " \n", + " def load_data(self):\n", + " Sar_analysis.load_data(self)\n", + " \n", + " self.df=self.df.withColumn(\"%util\",F.col(\"%util\").astype(IntegerType()))\n", + " used_disk=self.df.groupBy(\"DEV\").agg(F.max(F.col(\"%util\")).alias(\"max_util\"),F.mean(\"%util\").alias(\"avg_util\")).where(F.col(\"max_util\")>10).collect()\n", + " self.df=self.df.where(F.col(\"DEV\").isin([l['DEV'] for l in used_disk]))\n", + " #print(\"used disks with its max util% and avg util% are: \")\n", + " #display([(l['DEV'],l[\"max_util\"],l[\"avg_util\"]) for l in used_disk])\n", + " \n", + " if \"rd_sec/s\" in self.df.columns:\n", + " self.df=self.df.withColumn(\"rkB/s\",F.expr('cast(`rd_sec/s` as float)*512/1024'))\n", + " if \"wr_sec/s\" in self.df.columns:\n", + " self.df=self.df.withColumn(\"wkB/s\",F.expr('cast(`wr_sec/s` as float)*512/1024'))\n", + " \n", + " if \"areq-sz\" in self.df.columns:\n", + " self.df=self.df.withColumnRenamed(\"areq-sz\",\"avgrq-sz\")\n", + " if \"aqu-sz\" in self.df.columns:\n", + " self.df=self.df.withColumnRenamed(\"aqu-sz\",\"avgqu-sz\")\n", + " \n", + " if \"rkB/s\" in self.df.columns:\n", + " self.df=self.df.withColumn(\"rkB/s\",F.expr('cast(`rkB/s` as float)/1024'))\n", + " if \"wkB/s\" in self.df.columns:\n", + " self.df=self.df.withColumn(\"wkB/s\",F.expr('cast(`wkB/s` as float)/1024'))\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_events=Sar_analysis.generate_trace_view_list(self,id, **kwargs)\n", + "\n", + " disk_prefix=kwargs.get('disk_prefix',\"\")\n", + " \n", + " if type(disk_prefix)==str:\n", + " diskfilter = \"DEV like '\"+disk_prefix+\"%'\"\n", + " elif type(disk_prefix)==list:\n", + " diskfilter = \"DEV in (\"+\",\".join(disk_prefix)+\")\"\n", + " else:\n", + " diskfilter = \"DEV like '%'\"\n", + "\n", + " print(diskfilter)\n", + " devcnt=self.df.where(diskfilter).select(\"DEV\").distinct().count()\n", + " \n", + " trace_events.extend(self.col_df(diskfilter, \"disk b/w\", lambda l: F.struct(\n", + " F.floor(F.col(\"rKB/s\")).alias('read'),\n", + " F.floor(F.col(\"wKB/s\")).alias('write')),id, 3))\n", + " trace_events.extend(self.col_df(diskfilter, \"disk%\", lambda l: F.struct(\n", + " (F.col(\"%util\")/F.lit(devcnt)).alias('%util')),id, 4))\n", + " trace_events.extend(self.col_df(diskfilter, \"req size\", lambda l: F.struct(\n", + " (F.col(\"avgrq-sz\")/F.lit(devcnt)).alias('avgrq-sz')),id, 5))\n", + " trace_events.extend(self.col_df(diskfilter, \"queue size\", lambda l: F.struct(\n", + " (F.col(\"avgqu-sz\")/F.lit(512*devcnt/1024)).alias('avgqu-sz')),id, 6))\n", + " trace_events.extend(self.col_df(diskfilter, \"await\", lambda l: F.struct(\n", + " (F.col(\"await\")/F.lit(devcnt)).alias('await')),id,7))\n", + " \n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":3,\"args\":{\"sort_index \":3}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":4,\"args\":{\"sort_index \":4}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":5,\"args\":{\"sort_index \":5}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":6,\"args\":{\"sort_index \":6}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":7,\"args\":{\"sort_index \":7}}))\n", + " return trace_events \n", + "\n", + " def get_stat(sar_disk,**kwargs):\n", + " Sar_analysis.get_stat(sar_disk)\n", + " disk_prefix=kwargs.get('disk_prefix',\"\")\n", + " \n", + " if type(disk_prefix)==str:\n", + " diskfilter = \"DEV like '\"+disk_prefix+\"%'\"\n", + " elif type(disk_prefix)==list:\n", + " diskfilter = \"DEV in (\"+\",\".join(disk_prefix)+\")\"\n", + " else:\n", + " diskfilter = \"DEV like '%'\"\n", + "\n", + " diskutil=sar_disk.df.where(diskfilter).groupBy(\"_1\").agg(F.mean(F.col(\"%util\").astype(FloatType())).alias(\"%util\")).orderBy(\"_1\")\n", + " totalcnt=diskutil.count()\n", + " time_morethan_90=diskutil.where(F.col(\"%util\")>90).count()/totalcnt\n", + " avgutil=diskutil.agg(F.mean(\"%util\")).collect()\n", + " out=[[\"avg disk util\",avgutil[0][\"avg(%util)\"]],\n", + " [\"time more than 90%\", time_morethan_90]]\n", + " diskbw=sar_disk.df.where(diskfilter).groupBy(\"_1\").agg(F.sum(F.col(\"rKB/s\")).alias(\"rd_bw\"),F.sum(F.col(\"wKB/s\")).alias(\"wr_bw\"))\n", + " bw=diskbw.agg(F.sum(\"rd_bw\").alias(\"total read\"),F.sum(\"wr_bw\").alias(\"total write\"),F.mean(\"rd_bw\").alias(\"read bw\"),F.mean(\"wr_bw\").alias(\"write bw\"),F.max(\"rd_bw\").alias(\"max read\"),F.max(\"wr_bw\").alias(\"max write\")).collect()\n", + " maxread=bw[0][\"max read\"]\n", + " maxwrite=bw[0][\"max write\"]\n", + " rdstat, wrstat = diskbw.stat.approxQuantile(['rd_bw','wr_bw'],[0.75,0.95,0.99],0.0)\n", + " time_rd_morethan_95 = diskbw.where(F.col(\"rd_bw\")>rdstat[1]).count()/totalcnt\n", + " time_wr_morethan_95 = diskbw.where(F.col(\"wr_bw\")>rdstat[1]).count()/totalcnt\n", + " out.append(['total read (G)' , bw[0][\"total read\"]/1024])\n", + " out.append(['total write (G)', bw[0][\"total write\"]/1024])\n", + " out.append(['avg read bw (MB/s)', bw[0][\"read bw\"]])\n", + " out.append(['avg write bw (MB/s)', bw[0][\"write bw\"]])\n", + " out.append(['read bw %75', rdstat[0]])\n", + " out.append(['read bw %95', rdstat[1]])\n", + " out.append(['read bw max', rdstat[2]])\n", + " out.append(['time_rd_morethan_95', time_rd_morethan_95])\n", + " out.append(['write bw %75', wrstat[0]])\n", + " out.append(['write bw %95', wrstat[1]])\n", + " out.append(['write bw max', wrstat[2]])\n", + " out.append(['time_wr_morethan_95', time_wr_morethan_95])\n", + " pdout=pandas.DataFrame(out).set_index(0)\n", + " pdout.columns=[sar_disk.file.split(\"/\")[-2]]\n", + " return pdout\n", + " \n", + "class Sar_nic_analysis(Sar_analysis):\n", + " def __init__(self,sar_file):\n", + " Sar_analysis.__init__(self,sar_file)\n", + " \n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_events=Sar_analysis.generate_trace_view_list(self,id, **kwargs)\n", + " \n", + " nicfilter=\"\"\n", + " if 'nic_prefix' in kwargs.keys():\n", + " nicfilter= \"IFACE in (\" + \",\".join(kwargs.get('nic_prefix',[\"'eth3'\",\"'enp24s0f1'\"])) + \")\"\n", + " else:\n", + " nicfilter= \"IFACE != 'lo'\"\n", + " \n", + " trace_events.extend(self.col_df(nicfilter, \"eth \", lambda l: F.struct(F.floor(F.expr('cast(`rxkB/s` as float)/1024')).alias('rxmb/s'),F.floor(F.expr('cast(`txkB/s` as float)/1024')).alias('txmb/s')), id, 8))\n", + " trace_events.extend(self.col_df(\"_3 like 'ib%'\", \"ib \", lambda l: F.struct(F.floor(F.expr('cast(`rxkB/s` as float)/1024')).alias('rxmb/s'),F.floor(F.expr('cast(`txkB/s` as float)/1024')).alias('txmb/s')), id, 9))\n", + " trace_events.extend(self.col_df(\"_3 = 'lo'\", \"lo \", lambda l: F.struct(F.floor(F.expr('cast (`rxkB/s` as float)/1024')).alias('rxmb/s'),F.floor(F.expr('cast (`txkB/s` as float)/1024')).alias('txmb/s')), id, 10))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":8,\"args\":{\"sort_index \":8}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":9,\"args\":{\"sort_index \":9}}))\n", + " trace_events.append(json.dumps({\"name\": \"thread_sort_index\",\"ph\": \"M\",\"pid\":id,\"tid\":10,\"args\":{\"sort_index \":10}}))\n", + " return trace_events \n", + " \n", + " def get_stat(sar_nic,**kwargs):\n", + " Sar_analysis.get_stat(sar_nic)\n", + " nicfilter=\"\"\n", + " \n", + " if 'nic_prefix' in kwargs.keys():\n", + " nicfilter= \"IFACE in (\" + \",\".join(kwargs.get('nic_prefix',[\"'eth3'\",\"'enp24s0f1'\"])) + \")\"\n", + " else:\n", + " nicfilter= \"IFACE != 'lo'\"\n", + " \n", + " nicbw=sar_nic.df.where(nicfilter).groupBy(\"_1\").agg(F.sum(F.col(\"rxkB/s\").astype(FloatType())/1024).alias(\"rx MB/s\")).orderBy(\"_1\")\n", + " if nicbw.count()==0:\n", + " out=[[\"rx MB/s 75%\",0],[\"rx MB/s 95%\",0],[\"rx MB/s 99%\",0]]\n", + " else:\n", + " out=nicbw.stat.approxQuantile(['rx MB/s'],[0.75,0.95,0.99],0.0)[0]\n", + " out=[[\"rx MB/s 75%\",out[0]],[\"rx MB/s 95%\",out[1]],[\"rx MB/s 99%\",out[2]]]\n", + " pdout=pandas.DataFrame(out).set_index(0)\n", + " pdout.columns=[sar_nic.file.split(\"/\")[-2]]\n", + " return pdout" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# PID State analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Pidstat_analysis(Analysis):\n", + " def __init__(self,sar_file):\n", + " Analysis.__init__(self,sar_file)\n", + " \n", + " def load_data(self):\n", + " sardata=sc.textFile(self.file)\n", + " sardf=sardata.mapPartitions(splits).toDF()\n", + " sardf=sardf.where(\"_1<>'Average:'\")\n", + " \n", + " headers=sardf.where(\"_4='TID' or _5='TID'\").limit(1).collect()\n", + " r=headers[0].asDict()\n", + " findtime=False\n", + " for i,v in r.items():\n", + " if(v==\"Time\"):\n", + " findtime=True\n", + " if not findtime:\n", + " r[\"_1\"]=\"Time\"\n", + " for i,v in r.items():\n", + " if(v!=\"\"):\n", + " sardf=sardf.withColumnRenamed(i,v)\n", + " sardf=sardf.where(\"TGID='0' or TGID='-'\") \n", + "\n", + " self.df=sardf\n", + " return sardf\n", + "\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_list=Analysis.generate_trace_view_list(self,id,**kwargs)\n", + " sardf=self.df\n", + " starttime=self.starttime\n", + " \n", + " sardf=sardf.withColumn(\"%CPU\",F.col(\"%CPU\").astype(FloatType()))\n", + " sardf=sardf.withColumn(\"Time\",F.col(\"Time\").astype(LongType()))\n", + " sardf=sardf.withColumn(\"TID\",F.col(\"TID\").astype(LongType()))\n", + " hotthreads=sardf.where(\"`%CPU`>30\").groupBy(\"TID\").count().collect()\n", + " hts=[(r[0],r[1]) for r in hotthreads]\n", + " htc=[r[1] for r in hotthreads]\n", + " if len(htc)==0:\n", + " return trace_list\n", + " maxcnt=max(htc)\n", + " hts=[r[0] for r in hts if r[1]>maxcnt/2]\n", + " tdfs=list(map(lambda x: sardf.withColumnRenamed(\"TID\",\"TID_\"+str(x)).withColumnRenamed(\"%CPU\",\"CPU_\"+str(x)).where(F.col(\"TID\")==x).select(\"Time\",\"TID_\"+str(x),\"CPU_\"+str(x)),hts))\n", + " finaldf=reduce(lambda x,y: x.join(y,on=[\"Time\"]),tdfs)\n", + " othersdf=sardf.where(\"TID not in (\"+\",\".join(map(lambda x: str(x),hts))+\")\").groupBy(\"Time\").agg(F.sum(\"%CPU\").alias(\"CPU_Other\"))\n", + " finaldf=finaldf.join(othersdf,on=[\"Time\"])\n", + " finaldf=finaldf.orderBy(\"Time\")\n", + " hts.append(\"Other\")\n", + " stt=[F.col(\"CPU_\"+str(x)).alias(str(x)) for x in hts]\n", + " args=F.struct(*stt)\n", + " \n", + " trace_list.extend(finaldf.select(\n", + " F.lit(6).alias('tid'),\n", + " (F.expr(\"Time*1000\")-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.lit(\"pidstat\").alias('name'),\n", + " args.alias('args')\n", + " ).toJSON().collect())\n", + " return trace_list\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Perf stat Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Perfstat_analysis(Analysis):\n", + " def __init__(self,sar_file):\n", + " Analysis.__init__(self,sar_file)\n", + " \n", + " def load_data(self):\n", + " sardata=sc.textFile(self.file)\n", + " sardf=sardata.mapPartitions(splits).toDF()\n", + " \n", + " paths=os.path.split(self.file)\n", + " if fs.exists(paths[0]+\"/perfstarttime\"):\n", + " with fs.open(paths[0]+\"/perfstarttime\") as f:\n", + " strf=f.read().decode('ascii')\n", + " else:\n", + " print(\"error, perfstarttime not found\")\n", + " return\n", + " \n", + " tsc_freq_file = os.path.join(paths[0], 'tsc_freq')\n", + " if fs.exists(tsc_freq_file):\n", + " self.tsc_freq = int(spark.read.text(tsc_freq_file).collect()[0][0])\n", + " else:\n", + " print(f'{tsc_freq_file} not exists')\n", + " return\n", + " \n", + " totalcores_file = os.path.join(paths[0], 'totalcores')\n", + " if fs.exists(totalcores_file):\n", + " self.totalcores = int(spark.read.text(totalcores_file).collect()[0][0])\n", + " else:\n", + " print(f'{totalcores_file} not exists')\n", + " return\n", + " \n", + " strf=strf[len(\"# started on \"):].strip()\n", + " starttime=datetime.strptime(strf, \"%a %b %d %H:%M:%S %Y\").timestamp()*1000\n", + " sardf=sardf.where(\"_1<>'#'\")\n", + " sardf=sardf.withColumn(\"ts\",F.col(\"_2\").astype(DoubleType())*1000+F.lit(starttime)).where(\"ts is not null\").select(\"ts\",\"_3\",\"_4\")\n", + " sardf=sardf.withColumn('_3', F.regexp_replace('_3', ',', '').astype(LongType()))\n", + " sardf=sardf.cache()\n", + " self.df=sardf\n", + " return sardf\n", + "\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_list=Analysis.generate_trace_view_list(self,id,**kwargs)\n", + " sardf=self.df\n", + " starttime=self.starttime\n", + " \n", + " stringIndexer = StringIndexer(inputCol=\"_4\", outputCol=\"syscall_idx\")\n", + " model = stringIndexer.fit(sardf)\n", + " sardf=model.transform(sardf)\n", + " \n", + "# cnts=sardf.select(\"_4\").distinct().collect()\n", + "# cnts=[l['_4'] for l in cnts]\n", + "# cntmap={ cnts[i]:i for i in range(0, len(cnts) ) }\n", + "# mapexpr=F.create_map([F.lit(x) for x in chain(*cntmap.items())])\n", + "# sardf.select(mapexpr.getItem(F.col(\"_4\")))\n", + " \n", + " sardf=sardf.withColumn(\"syscall_idx\",F.col(\"syscall_idx\").astype(IntegerType()))\n", + " \n", + " trace_list.extend(sardf.select(\n", + " (F.lit(100)+F.col(\"syscall_idx\")).alias('tid'),\n", + " (F.col(\"ts\")-F.lit(starttime)).astype(LongType()).alias('ts'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.col(\"_4\").alias('name'),\n", + " F.struct(F.col(\"_3\").alias(\"cnt\")).alias('args')\n", + " ).toJSON().collect())\n", + " return trace_list\n", + " \n", + " def get_stat(self, **kwargs):\n", + " if self.df is None:\n", + " self.load_data()\n", + "\n", + " raw_data = spark.read.text(self.file)\n", + "\n", + " # Filter out non-data lines and split the data into columns\n", + " filtered_data = raw_data.filter(\n", + " ~raw_data.value.startswith('#') & raw_data.value.rlike(r\"^\\s*\\d\")\n", + " )\n", + "\n", + " split_data = filtered_data.rdd.map(lambda row: row[0].split()).map(\n", + " lambda parts: (float(parts[0]), int(parts[1].replace(\",\", \"\")), parts[2], '' if len(parts) == 3 else parts[4])\n", + " )\n", + "\n", + " schema = [\"time\", \"counts\", \"events\", \"ipc\"]\n", + " df = split_data.toDF(schema)\n", + "\n", + " events_df = df.filter(col('ipc') == '')\n", + " ipc_df = df.filter(col('ipc') != '')\n", + "\n", + " instructions = ipc_df.select(_sum(col(\"counts\"))).collect()[0][0] / 1e9\n", + " avg_ipc = ipc_df.select(avg(col(\"ipc\"))).collect()[0][0]\n", + "\n", + " df_ccu_ref_tsc = events_df.select(col('time'), col('counts')).filter(col('events') == 'cpu_clk_unhalted.ref_tsc').withColumnRenamed('counts', 'cpu_clk_unhalted_ref_tsc')\n", + " df_ccu_thread = events_df.select(col('time'), col('counts')).filter(col('events') == 'cpu_clk_unhalted.thread').withColumnRenamed('counts', 'cpu_clk_unhalted_thread')\n", + "\n", + " window_spec = Window.orderBy(\"time\")\n", + " df_ccu_ref_tsc = df_ccu_ref_tsc.withColumn(\"prev_time\", lag(\"time\").over(window_spec))\n", + " df_ccu_ref_tsc = df_ccu_ref_tsc.withColumn(\"prev_time\", when(col(\"prev_time\").isNull(), 0).otherwise(col(\"prev_time\")))\n", + " df_ccu_ref_tsc = df_ccu_ref_tsc.withColumn(\"tsc\", (col(\"time\") - col(\"prev_time\")) * self.tsc_freq)\n", + "\n", + " joined_df = df_ccu_ref_tsc.join(df_ccu_thread, on=[\"time\"], how=\"inner\")\n", + " cpu_freq_df = joined_df.withColumn(\"freq\", joined_df.cpu_clk_unhalted_thread / joined_df.cpu_clk_unhalted_ref_tsc * self.tsc_freq / 1e9)\n", + " cpu_freq = cpu_freq_df.select(avg(col('freq'))).collect()[0][0]\n", + "\n", + " cpu_util_df = df_ccu_ref_tsc.withColumn(\"cpu%\", col(\"cpu_clk_unhalted_ref_tsc\") / col(\"tsc\") / self.totalcores * 100)\n", + " cpu_util = cpu_util_df.select(avg(col('cpu%'))).collect()[0][0]\n", + "\n", + " out = [['ipc', avg_ipc], ['instructions', instructions], ['cpu_freq', cpu_freq], ['cpu%', cpu_util]]\n", + " pdout=pandas.DataFrame(out).set_index(0)\n", + " \n", + " return pdout" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# GPU analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class gpu_analysis(Analysis):\n", + " def __init__(self,gpu_file):\n", + " Analysis.__init__(self,gpu_file)\n", + " \n", + " def load_data(self):\n", + " df_pf=spark.read.format(\"com.databricks.spark.csv\").option(\"header\",\"true\").option(\"mode\", \"DROPMALFORMED\").option(\"delimiter\", \",\").load(self.file)\n", + " df_pf2=df_pf.withColumn('timestamp',F.unix_timestamp(F.col('timestamp'),'yyyy/MM/dd HH:mm:ss')*1000+(F.split(F.col('timestamp'),'\\.')[1]).astype(IntegerType()))\n", + " df_pf2=df_pf2.withColumnRenamed(' utilization.gpu [%]','gpu_util')\n", + " df_pf2=df_pf2.withColumnRenamed(' utilization.memory [%]','mem_util')\n", + " df_pf2=df_pf2.withColumnRenamed(' memory.used [MiB]','mem_used')\n", + " df_pf2=df_pf2.withColumnRenamed(' index','index')\n", + " df_pf2=df_pf2.withColumn('gpu_util', (F.split('gpu_util',' ')[1]).astype(IntegerType()))\n", + " df_pf2=df_pf2.withColumn('mem_util', (F.split('mem_util',' ')[1]).astype(IntegerType()))\n", + " df_pf2=df_pf2.withColumn('mem_used', (F.split('mem_used',' ')[1]).astype(IntegerType()))\n", + " df_pf.cache()\n", + " self.df=df_pf2\n", + " return df_pf2\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " Analysis.generate_trace_view_list(self,id)\n", + " \n", + " df_pf2=self.df\n", + " starttime=self.starttime\n", + " trace_events=[]\n", + " \n", + " trace_events.extend(df_pf2.orderBy(df_pf2['timestamp']).select(\n", + " F.col('index').alias('tid'),\n", + " (F.expr(\"timestamp\")-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.concat(F.lit('gpu_util_'),F.col('index')).alias('name'),\n", + " F.struct(F.col('gpu_util').alias('gpu')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " trace_events.extend(df_pf2.orderBy(df_pf2['timestamp']).select(\n", + " F.col('index').alias('tid'),\n", + " (F.expr(\"timestamp\")-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(int(id)+1).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.concat(F.lit('mem_util_'),F.col('index')).alias('name'),\n", + " F.struct((F.col('mem_used')/F.lit(32768)).alias('mem')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " return trace_events" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "def splits_dmon(x):\n", + " fi=[]\n", + " for l in x:\n", + " l=l.strip()\n", + " if l.startswith('20'):\n", + " li=re.split(r'\\s+',l)\n", + " if len(li)==11:\n", + " fi.append(li)\n", + " return iter(fi)\n", + "\n", + "class gpu_dmon_analysis(Analysis):\n", + " def __init__(self,gpu_file):\n", + " Analysis.__init__(self,gpu_file)\n", + " \n", + " def load_data(self):\n", + " df_pf=sc.textFile(self.file)\n", + " df_pf=df_pf.mapPartitions(splits_dmon).toDF()\n", + " \n", + " df_pf2=df_pf.withColumn('_1',F.unix_timestamp(F.concat_ws(' ',F.col('_1'),F.col('_2')),'yyyyMMdd HH:mm:ss')*1000)\n", + " for c in range(3,12):\n", + " df_pf2=df_pf2.withColumn(f'_{c}',F.col(f'_{c}').astype(IntegerType()))\n", + "\n", + " df_pf.cache()\n", + " self.df=df_pf2\n", + " return df_pf2\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " Analysis.generate_trace_view_list(self,id)\n", + "\n", + " df_pf2=self.df\n", + " starttime=self.starttime\n", + " trace_events=[]\n", + " \n", + " trace_events.extend(df_pf2.orderBy(df_pf2['_1']).select(\n", + " F.col('_3').alias('tid'),\n", + " (F.expr(\"_1\")-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.concat(F.lit('gpu_util_'),F.col('_3')).alias('name'),\n", + " F.struct(F.col('_4').alias('gpu')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " trace_events.extend(df_pf2.orderBy(df_pf2['_1']).select(\n", + " F.col('_3').alias('tid'),\n", + " (F.expr(\"_1\")-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(id+1).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.concat(F.lit('mem_util_'),F.col('_3')).alias('name'),\n", + " F.struct(F.col('_5').alias('mem')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " trace_events.extend(df_pf2.orderBy(df_pf2['_1']).select(\n", + " F.col('_3').alias('tid'),\n", + " (F.expr(\"_1\")-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(id+2).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.concat(F.lit('gpu_freq_'),F.col('_3')).alias('name'),\n", + " F.struct(F.col('_9').alias('gpu_freq')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " trace_events.extend(df_pf2.orderBy(df_pf2['_1']).select(\n", + " F.col('_3').alias('tid'),\n", + " (F.expr(\"_1\")-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(id+3).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.concat(F.lit('pcie_'),F.col('_3')).alias('name'),\n", + " F.struct(F.col('_10').alias('tx'),F.col('_11').alias('rx')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " return trace_events\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# DASK analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "def split_dask(x):\n", + " fi=[]\n", + " for l in x:\n", + " print(l)\n", + " li=[]\n", + " if l.startswith('('):\n", + " lx=re.split(r'[()]',l)\n", + " lv=lx[1]\n", + " p=re.search(r\"'(.*)-([0-9a-f]+)', *(\\d+)\",lv)\n", + " if not p:\n", + " print(\"dask log first field doesn't match (.*)-[0-9a-f]+', *(\\d+)\")\n", + " return\n", + " li.append(p.group(1))\n", + " li.extend(lx[2].split(\",\")[1:])\n", + " li.append(p.group(3))\n", + " else:\n", + " li=l.split(',')\n", + " p=re.search(r\"(.*)-([0-9a-f]+-[0-9a-f]+-[0-9a-f]+-[0-9a-f]+-[0-9a-f]+)$\",li[0])\n", + " if not p:\n", + " p=re.search(r\"(.*)-([0-9a-f]+)$\",li[0])\n", + " \n", + " li[0]=p.group(1)\n", + " li.append(p.group(2))\n", + " fi.append(li)\n", + " return iter(fi)\n", + "\n", + "class dask_analysis(Analysis):\n", + " def __init__(self,dask_file):\n", + " Analysis.__init__(self,dask_file)\n", + "\n", + " def load_data(self):\n", + " rdds=sc.textFile(self.file)\n", + " df_pf=rdds.mapPartitions(split_dask).toDF()\n", + " df_pf=df_pf.withColumnRenamed('_1','_c0')\n", + " df_pf=df_pf.withColumnRenamed('_2','_c1')\n", + " df_pf=df_pf.withColumnRenamed('_3','_c2')\n", + " df_pf=df_pf.withColumnRenamed('_4','_c3')\n", + " df_pf=df_pf.withColumnRenamed('_5','_id')\n", + " \n", + " df_pf=df_pf.withColumn('_c1',F.split(F.col('_c1'),\":\")[2])\n", + " df_pf=df_pf.withColumn('_c3',df_pf._c3.astype(DoubleType())*1000) \n", + " df_pf=df_pf.withColumn('_c2',df_pf._c2.astype(DoubleType())*1000)\n", + " \n", + " df_pf.cache()\n", + " self.df=df_pf\n", + " self.starttime=df_pf.agg(F.min(\"_c2\")).collect()[0]['min(_c2)']\n", + " return df_pf\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " Analysis.generate_trace_view_list(self,id)\n", + " \n", + " df_pf=self.df\n", + "\n", + " window = Window.partitionBy(\"_c1\").orderBy(\"_c3\")\n", + " df_pf=df_pf.withColumn(\"last_tsk_done\", F.lag('_c3', 1, None).over(window))\n", + " df_pf=df_pf.withColumn('last_tsk_done',F.coalesce('last_tsk_done','_c2'))\n", + " df_pf=df_pf.withColumn('last_tsk_done',F.when(F.col('_c2')>F.col('last_tsk_done'),F.col('_c2')).otherwise(F.col('last_tsk_done')) )\n", + " \n", + " trace_events=[]\n", + " \n", + " trace_events.extend(df_pf.select(\n", + " F.col('_c1').alias('tid'),\n", + " (F.col('last_tsk_done')-F.lit(self.starttime)).astype(IntegerType()).alias('ts'),\n", + " F.expr('_c3 - last_tsk_done ').alias('dur'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('X').alias('ph'),\n", + " F.col('_c0').alias('name'),\n", + " F.struct(F.col('_id').alias('uuid')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " return trace_events" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class dask_analysis_log(dask_analysis):\n", + " def __init__(self,dask_file,logs):\n", + " Analysis.__init__(self,dask_file)\n", + "\n", + " def load_data(self):\n", + " rdds=sc.textFile(self.file)\n", + " df_pf=rdds.mapPartitions(split_dask).toDF()\n", + " df_pf=df_pf.withColumnRenamed('_1','_c0')\n", + " df_pf=df_pf.withColumnRenamed('_2','_c1')\n", + " df_pf=df_pf.withColumnRenamed('_3','_c2')\n", + " df_pf=df_pf.withColumnRenamed('_4','_c3')\n", + " df_pf=df_pf.withColumnRenamed('_5','_id')\n", + " \n", + " df_pf=df_pf.withColumn('_c1',F.split(F.col('_c1'),\":\")[2])\n", + " df_pf=df_pf.withColumn('_c3',df_pf._c3.astype(DoubleType())*1000) \n", + " df_pf=df_pf.withColumn('_c2',df_pf._c2.astype(DoubleType())*1000)\n", + " \n", + " df_pf.cache()\n", + " self.df=df_pf\n", + " self.starttime=df_pf.agg(F.min(\"_c2\")).collect()[0]['min(_c2)']\n", + " return df_pf\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " Analysis.generate_trace_view_list(self,id)\n", + " \n", + " df_pf=self.df\n", + "\n", + " window = Window.partitionBy(\"_c1\").orderBy(\"_c3\")\n", + " df_pf=df_pf.withColumn(\"last_tsk_done\", F.lag('_c3', 1, None).over(window))\n", + " df_pf=df_pf.withColumn('last_tsk_done',F.coalesce('last_tsk_done','_c2'))\n", + " df_pf=df_pf.withColumn('last_tsk_done',F.when(F.col('_c2')>F.col('last_tsk_done'),F.col('_c2')).otherwise(F.col('last_tsk_done')) )\n", + " \n", + " trace_events=[]\n", + " \n", + " trace_events.extend(df_pf.select(\n", + " F.col('_c1').alias('tid'),\n", + " (F.col('last_tsk_done')-F.lit(self.starttime)).astype(IntegerType()).alias('ts'),\n", + " F.expr('_c3 - last_tsk_done ').alias('dur'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('X').alias('ph'),\n", + " F.col('_c0').alias('name'),\n", + " F.struct(F.col('_id').alias('uuid')).alias('args')\n", + " ).toJSON().collect())\n", + "\n", + " return trace_events" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# instantevent analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "## format: _2 = Name; _3 = time\n", + "\n", + "class InstantEvent_analysis(Analysis):\n", + " def __init__(self,sar_file):\n", + " Analysis.__init__(self,sar_file)\n", + " \n", + " def load_data(self):\n", + " sardata=sc.textFile(self.file)\n", + " sardf=sardata.mapPartitions(splits).toDF()\n", + " self.df=sardf\n", + " return sardf\n", + "\n", + "\n", + " def generate_trace_view_list(self,id=0,**kwargs):\n", + " Analysis.generate_trace_view_list(self,id)\n", + " sardf=self.df\n", + " starttime=self.starttime\n", + " return sardf.select(F.lit(0).alias('tid'),\n", + " (F.col(\"_3\").astype(DoubleType())*1000-F.lit(starttime)).astype(IntegerType()).alias('ts'),\n", + " F.lit(0).alias('pid'),\n", + " F.lit('i').alias('ph'),\n", + " F.col(\"_2\").alias('name'),\n", + " F.lit(\"g\").alias(\"s\")\n", + " ).toJSON().collect()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# HBM_Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class HBM_analysis(Analysis):\n", + " def __init__(self,file):\n", + " Analysis.__init__(self,file)\n", + " \n", + " def load_data(self):\n", + " df=spark.read.option(\"delimiter\", \", \").option(\"header\", \"true\").csv(self.file)\n", + " self.df=df.withColumn(\"ts\", F.unix_timestamp(df.timestamp)).withColumn(\"size\", df.size.cast(LongType())).withColumn(\"free\", df.free.cast(LongType()))\n", + " return self.df\n", + "\n", + " def generate_trace_view_list(self,id,**kwargs):\n", + " trace_list=Analysis.generate_trace_view_list(self,id,**kwargs)\n", + " hbmdf=self.df\n", + " starttime=self.starttime\n", + " \n", + " trace_list.extend(hbmdf.select(\n", + " F.lit(0).alias('tid'),\n", + " (F.col(\"ts\") * F.lit(1000)-F.lit(starttime)).astype(LongType()).alias('ts'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.lit(\"hbm\").alias('name'),\n", + " F.struct((F.col(\"size\")-F.col(\"free\")).alias('hbmused'), F.col(\"free\").alias('hbmfree')).alias('args')\n", + " ).toJSON().collect())\n", + " \n", + " trace_list.extend(hbmdf.select(\n", + " F.lit(0).alias('tid'),\n", + " (F.col(\"ts\") * F.lit(1000)-F.lit(starttime)).astype(LongType()).alias('ts'),\n", + " F.lit(id).alias('pid'),\n", + " F.lit('C').alias('ph'),\n", + " F.lit(\"hbm %\").alias('name'),\n", + " F.struct(((F.lit(1) - F.col(\"free\") / F.col(\"size\")) * F.lit(100)).alias('%hbmused')).alias('args')\n", + " ).toJSON().collect())\n", + " return trace_list" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Run base" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Run:\n", + " def __init__(self,samples):\n", + " self.samples=samples\n", + " \n", + " def generate_trace_view(self,appid,**kwargs):\n", + " traces=[]\n", + " \n", + " for idx, s in enumerate(self.samples):\n", + " traces.extend(s.generate_trace_view_list(idx,**kwargs)) \n", + " output='''\n", + " {\n", + " \"traceEvents\": [\n", + " \n", + " ''' + \\\n", + " \",\\n\".join(traces)\\\n", + " + '''\n", + " ]\n", + " }'''\n", + "\n", + " with open('/home/sparkuser/trace_result/'+appid+'.json', 'w') as outfile: \n", + " outfile.write(output)\n", + "\n", + " print(f\"http://{localhost}:1088/tracing_examples/trace_viewer.html#/tracing/test_data/{appid}.json\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Dask Application Run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Dask_Application_Run:\n", + " def __init__(self, appid):\n", + " self.appid=appid\n", + " self.filedir=\"/tmp/dgx-2Log/\"+self.appid+\"/\"\n", + " \n", + " self.analysis={\n", + " 'dask':{'als':dask_analysis(self.filedir+\"cluster.log\"),'pid':8000},\n", + " 'sar_cpu':{'als':Sar_cpu_analysis(self.filedir + \"/\"+\"sar_cpu.sar\"),'pid':10*0+0},\n", + " 'sar_disk':{'als':Sar_disk_analysis(self.filedir + \"/\"+\"sar_disk.sar\"),'pid':10*0+1},\n", + " 'sar_mem':{'als':Sar_mem_analysis(self.filedir + \"/\"+\"sar_mem.sar\"),'pid':10*0+2},\n", + " 'sar_nic':{'als':Sar_nic_analysis(self.filedir + \"/\"+\"sar_nic.sar\"),'pid':10*0+3},\n", + " 'emon':{'als':Emon_Analysis(self.filedir + \"/\"+\"emon.rst\"),'pid':10*0+4},\n", + " 'gpu':{'als':gpu_analysis(self.filedir + \"/gpu.txt\"),'pid':10*0+5},\n", + " }\n", + " \n", + " \n", + " def generate_trace_view(self,showsar=True,showemon=False,showgpu=True,**kwargs):\n", + " traces=[]\n", + " daskals=self.analysis['dask']['als']\n", + " traces.extend(daskals.generate_trace_view_list(self.analysis['dask']['pid'],**kwargs))\n", + " if showsar:\n", + " sarals=self.analysis['sar_cpu']['als']\n", + " sarals.starttime=daskals.starttime\n", + " traces.extend(sarals.generate_trace_view_list(self.analysis['sar_cpu']['pid'],**kwargs))\n", + " sarals=self.analysis['sar_disk']['als']\n", + " sarals.starttime=daskals.starttime\n", + " traces.extend(sarals.generate_trace_view_list(self.analysis['sar_disk']['pid'],**kwargs))\n", + " sarals=self.analysis['sar_mem']['als']\n", + " sarals.starttime=daskals.starttime\n", + " traces.extend(sarals.generate_trace_view_list(self.analysis['sar_mem']['pid'],**kwargs))\n", + " sarals=self.analysis['sar_nic']['als']\n", + " sarals.starttime=daskals.starttime\n", + " traces.extend(sarals.generate_trace_view_list(self.analysis['sar_nic']['pid'],**kwargs))\n", + " if showemon:\n", + " emonals=self.analysis['emon']['als']\n", + " emonals.starttime=daskals.starttime\n", + " traces.extend(emonals.generate_trace_view_list(self.analysis['emon']['pid'],**kwargs))\n", + " if showgpu:\n", + " gpuals=self.analysis['gpu']['als']\n", + " gpuals.starttime=daskals.starttime\n", + " traces.extend(gpuals.generate_trace_view_list(self.analysis['gpu']['pid'],**kwargs))\n", + " \n", + " output='''\n", + " {\n", + " \"traceEvents\": [\n", + " \n", + " ''' + \\\n", + " \",\\n\".join(traces)\\\n", + " + '''\n", + " ]\n", + " }'''\n", + "\n", + " with open('/home/sparkuser/trace_result/'+self.appid+'.json', 'w') as outfile: \n", + " outfile.write(output)\n", + "\n", + " print(\"http://sr219:1088/tracing_examples/trace_viewer.html#/tracing/test_data/\"+self.appid+\".json\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "datetime.fromtimestamp(1546439400)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Dask_Application_Run2:\n", + " def __init__(self, appid):\n", + " self.appid=appid\n", + " \n", + " self.filedir=\"/tmp/dgx-2Log/\"+self.appid+\"/\"\n", + " self.dask=self.load_dask()\n", + " self.sar=self.load_sar()\n", + " self.gpu=self.load_gpu()\n", + " \n", + " \n", + " def load_dask(self):\n", + " return dask_analysis(self.filedir+\"cluster.log\")\n", + " \n", + " def load_sar(self):\n", + " return Sar_analysis(self.filedir+\"sar_data.sar\")\n", + " \n", + " def load_emon(self):\n", + " return Emon_Analysis(self.filedir+\"emon.rst\")\n", + " \n", + " def load_gpu(self):\n", + " return gpu_dmon_analysis(self.filedir+\"gpu_dmon.txt\")\n", + " \n", + " def generate_dask_trace_view(self):\n", + " return self.dask.generate_dask_trace_view(8000)\n", + " \n", + " def generate_sar_trace_view(self):\n", + " return self.sar.generate_sar_trace_view(0)\n", + " \n", + " def generate_gpu_trace_view(self):\n", + " return self.gpu.generate_gpu_trace_view(1)\n", + "\n", + " def generate_emon_trace_view(self,collected_cores):\n", + " return self.emon.generate_emon_trace_view(5,collected_cores)\n", + " \n", + " def generate_trace_view(self,showsar=True,showemon=False,showgpu=True):\n", + " traces=[]\n", + " traces.extend(self.generate_dask_trace_view())\n", + " if showsar:\n", + " self.sar.starttime=self.dask.starttime\n", + " traces.extend(self.generate_sar_trace_view())\n", + " if showemon:\n", + " traces.extend(self.generate_emon_trace_view(collected_cores))\n", + " if showgpu:\n", + " self.gpu.starttime=self.dask.starttime\n", + " traces.extend(self.generate_gpu_trace_view())\n", + " \n", + " output='''\n", + " {\n", + " \"traceEvents\": [\n", + " \n", + " ''' + \\\n", + " \",\\n\".join(traces)\\\n", + " + '''\n", + " ]\n", + " }'''\n", + "\n", + " with open('/home/sparkuser/trace_result/'+self.appid+'.json', 'w') as outfile: \n", + " outfile.write(output)\n", + "\n", + " print(f\"http://{localhost}:1088/tracing_examples/trace_viewer.html#/tracing/test_data/{appid}.json\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Application RUN STD" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Application_Run_STD:\n", + " def __init__(self, appid):\n", + " self.appid=appid\n", + " self.filedir=\"/tmp/dgx-2Log/\"+self.appid+\"/\"\n", + " \n", + " self.analysis={\n", + " 'sar':{'als':Sar_analysis(self.filedir+\"sar_data.sar\"),'pid':0},\n", + " 'emon':{'als':Emon_Analysis(self.filedir+\"emon.rst\"),'pid':1},\n", + " 'gpu':{'als':gpu_analysis(self.filedir+\"gpu.txt\"),'pid':100},\n", + " }\n", + " \n", + " \n", + " def generate_trace_view(self,showsar=True,showemon=False,showgpu=True,**kwargs):\n", + " traces=[]\n", + " starttime=time.time()*1000\n", + " if showsar:\n", + " sarals=self.analysis['sar']['als']\n", + " sarals.starttime=starttime\n", + " traces.extend(sarals.generate_trace_view_list(self.analysis['sar']['pid'],**kwargs))\n", + " if showemon:\n", + " emonals=self.analysis['emon']['als']\n", + " emonals.starttime=starttime\n", + " traces.extend(emonals.generate_trace_view_list(self.analysis['emon']['pid'],**kwargs))\n", + " if showgpu:\n", + " gpuals=self.analysis['gpu']['als']\n", + " gpuals.starttime=starttime\n", + " traces.extend(gpuals.generate_trace_view_list(self.analysis['gpu']['pid'],**kwargs))\n", + " \n", + " output='''\n", + " {\n", + " \"traceEvents\": [\n", + " \n", + " ''' + \\\n", + " \",\\n\".join(traces)\\\n", + " + '''\n", + " ]\n", + " }'''\n", + "\n", + " with open('/home/sparkuser/trace_result/'+self.appid+'.json', 'w') as outfile: \n", + " outfile.write(output)\n", + "\n", + " print(f\"http://{localhost}:1088/tracing_examples/trace_viewer.html#/tracing/test_data/{appid}.json\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Application Run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "class Application_Run:\n", + " def __init__(self, appid,**kwargs):\n", + " self.appid=appid\n", + " \n", + " basedir=kwargs.get(\"basedir\",\"skylake\")\n", + " self.filedir=\"/\"+basedir+\"/\"+self.appid+\"/\"\n", + " self.basedir=basedir\n", + " \n", + " slaves=fs.list_status(\"/\"+basedir+\"/\"+appid)\n", + " slaves=[f['pathSuffix'] for f in slaves if f['type']=='DIRECTORY' and f['pathSuffix']!=\"summary.parquet\"]\n", + " \n", + " jobids=kwargs.get(\"jobids\",None)\n", + " \n", + " self.clients=slaves\n", + " \n", + " sarclnt={}\n", + " for idx,l in enumerate(self.clients):\n", + " sarclnt[l]={'sar_cpu':{'als':Sar_cpu_analysis(self.filedir + l + \"/\"+\"sar_cpu.sar\"),'pid':idx},\n", + " 'sar_disk':{'als':Sar_disk_analysis(self.filedir + l + \"/\"+\"sar_disk.sar\"),'pid':idx},\n", + " 'sar_mem':{'als':Sar_mem_analysis(self.filedir + l + \"/\"+\"sar_mem.sar\"),'pid':idx},\n", + " 'sar_nic':{'als':Sar_nic_analysis(self.filedir + l + \"/\"+\"sar_nic.sar\"),'pid':idx}\n", + " }\n", + " if fs.exists(self.filedir + l + \"/sar_page.sar\"):\n", + " sarclnt[l]['sar_page']={'als':Sar_PageCache_analysis(self.filedir + l + \"/\"+\"sar_page.sar\"),'pid':idx}\n", + " \n", + " if fs.exists(self.filedir + l + \"/pidstat.out\"):\n", + " sarclnt[l]['sar_pid']={'als':Pidstat_analysis(self.filedir + l + \"/pidstat.out\"),'pid':idx}\n", + " if fs.exists(self.filedir + l + \"/sched.txt\"):\n", + " sarclnt[l]['sar_perf']={'als':Perf_trace_analysis(self.filedir + l + \"/sched.txt\"),'pid':100+idx}\n", + " if fs.exists(self.filedir + l + \"/emon.rst\"):\n", + " self.show_emon=True\n", + " sarclnt[l]['emon']={'als':Emon_Analysis(self.filedir + l + \"/emon.rst\"),'pid':200+idx}\n", + " if fs.exists(self.filedir + l + \"/perfstat.txt\"):\n", + " self.show_perfstat=True\n", + " sarclnt[l]['perfstat']={'als':Perfstat_analysis(self.filedir + l + \"/perfstat.txt\"),'pid':300+idx}\n", + " if fs.exists(self.filedir + l + \"/gpu.txt\"):\n", + " sarclnt[l]['gpu']={'als':gpu_analysis(self.filedir + l + \"/gpu.txt\"),'pid':400+idx}\n", + " \n", + " \n", + " self.analysis={\n", + " \"sar\": sarclnt\n", + " }\n", + " \n", + " if fs.exists(self.filedir+\"app.log\"):\n", + " self.analysis['app']={'als':App_Log_Analysis(self.filedir+\"app.log\",jobids)}\n", + " \n", + " if fs.exists(self.filedir+\"instevent.out\"):\n", + " self.analysis['instant']={'als':InstantEvent_analysis(self.filedir+\"instevent.out\")}\n", + " \n", + " self.starttime=0\n", + " if fs.exists(self.filedir+\"starttime\"):\n", + " with fs.open(self.filedir+\"starttime\") as f:\n", + " st = f.read().decode('ascii')\n", + " self.starttime=int(st)\n", + " \n", + " def generate_trace_view(self,showsar=True,showgpu=True,showhbm=False,**kwargs):\n", + " traces=[]\n", + " shownodes=kwargs.get(\"shownodes\",self.clients)\n", + " for l in shownodes:\n", + " if l not in self.clients:\n", + " print(l,\"is not in clients\",self.clients)\n", + " return\n", + " self.clients=shownodes\n", + " \n", + " xgbtcks=kwargs.get('xgbtcks',(\"calltrain\",'enter','begin','end'))\n", + " \n", + " if \"app\" in self.analysis:\n", + " appals=self.analysis['app']['als']\n", + " appals.starttime=self.starttime\n", + " traces.extend(appals.generate_trace_view_list(self.analysis['app'],**kwargs))\n", + " self.starttime=appals.starttime\n", + " \n", + " if 'instant' in self.analysis:\n", + " als=self.analysis['instant']['als']\n", + " als.starttime=self.starttime\n", + " traces.extend(als.generate_trace_view_list(**kwargs))\n", + " \n", + " counttime=kwargs.get(\"counttime\",False)\n", + " \n", + " pidmap={}\n", + " if showsar:\n", + " for l in self.clients:\n", + " for alskey, sarals in self.analysis[\"sar\"][l].items():\n", + " t1 = time.time()\n", + " if alskey!=\"emon\":\n", + " sarals['als'].starttime=self.starttime\n", + " traces.extend(sarals['als'].generate_trace_view_list(sarals['pid'],node=l, **kwargs))\n", + " elif self.show_emon:\n", + " sarals['als'].load_data()\n", + " pidmap[l]=sarals['pid']\n", + " if counttime:\n", + " print(l,alskey,\" spend time: \", time.time()-t1)\n", + " if self.show_emon:\n", + " t1 = time.time()\n", + " emondfs=get_emon_parquets([self.appid,],self.basedir)\n", + " emons=Emon_Analysis_All(emondfs)\n", + " emons.starttime=self.starttime\n", + " traces.extend(emons.generate_trace_view_list(0,pidmap=pidmap,**kwargs))\n", + " if counttime:\n", + " print(\"emon process spend time: \", time.time()-t1)\n", + " self.emons=emons\n", + " \n", + " if showhbm:\n", + " for l in self.clients:\n", + " t1 = time.time()\n", + " hbm_analysis=HBM_analysis(self.filedir + l + \"/numactl.csv\")\n", + " hbm_analysis.starttime=self.starttime\n", + " traces.extend(hbm_analysis.generate_trace_view_list(0,**kwargs))\n", + " if counttime:\n", + " print(l, \" hbm process spend time: \", time.time()-t1)\n", + " \n", + " for idx,l in enumerate(self.clients):\n", + " traces.append(json.dumps({\"name\": \"process_sort_index\",\"ph\": \"M\",\"pid\":idx,\"tid\":0,\"args\":{\"sort_index \":idx}}))\n", + " traces.append(json.dumps({\"name\": \"process_sort_index\",\"ph\": \"M\",\"pid\":idx+100,\"tid\":0,\"args\":{\"sort_index \":idx+100}}))\n", + " traces.append(json.dumps({\"name\": \"process_sort_index\",\"ph\": \"M\",\"pid\":idx+200,\"tid\":0,\"args\":{\"sort_index \":idx+200}}))\n", + " \n", + " if \"app\" in self.analysis:\n", + " for pid in self.analysis['app']['als'].pids:\n", + " traces.append(json.dumps({\"name\": \"process_sort_index\",\"ph\": \"M\",\"pid\":pid+200,\"tid\":0,\"args\":{\"sort_index \":pid+200}}))\n", + "\n", + " allcnt=\"\"\n", + " for c in self.clients:\n", + " paths=self.filedir+c\n", + " if fs.exists(paths+\"/xgbtck.txt\"):\n", + " with fs.open(paths+\"/xgbtck.txt\") as f:\n", + " tmp = f.read().decode('ascii')\n", + " allcnt=allcnt+tmp\n", + " allcnt=allcnt.strip().split(\"\\n\")\n", + " if len(allcnt) > 1:\n", + " allcnt=[l.split(\" \") for l in allcnt]\n", + " cnts=pandas.DataFrame([[l[0],l[1],l[2],l[3]] for l in allcnt if len(l)>1 and l[1] in xgbtcks])\n", + " if len(cnts) > 0:\n", + " cnts.columns=['xgbtck','name','rank','time']\n", + " cntgs=cnts.groupby(\"name\").agg({\"time\":\"min\"})\n", + " cntgs=cntgs.reset_index()\n", + " cntgs.columns=['name','ts']\n", + " cntgs['ph']=\"i\"\n", + " cntgs['ts']=pandas.to_numeric(cntgs['ts'])-self.starttime\n", + " cntgs['pid']=0\n", + " cntgs['tid']=0\n", + " cntgs['s']='g'\n", + " traces.extend([json.dumps(l) for l in cntgs.to_dict(orient='records')])\n", + " \n", + " output='''\n", + " {\n", + " \"traceEvents\": [\n", + " \n", + " ''' + \\\n", + " \",\\n\".join(traces)\\\n", + " + '''\n", + " ],\n", + " \"displayTimeUnit\": \"ns\"\n", + " }'''\n", + "\n", + " with open('/home/sparkuser/trace_result/'+self.appid+'.json', 'w') as outfile: \n", + " outfile.write(output)\n", + " \n", + " traceview_link=f'http://{localhost}:1088/tracing_examples/trace_viewer.html#/tracing/test_data/{self.appid}.json'\n", + " display(HTML(f\"{traceview_link}\"))\n", + " return traceview_link\n", + "\n", + " def getemonmetric(app,**kwargs):\n", + " emondfs=get_emon_parquets([app.appid],app.basedir)\n", + " emons=Emon_Analysis_All(emondfs)\n", + " metric_msg_map={\n", + " 'emon_instr_retired':F.sum\n", + " }\n", + " \n", + " emonmetric=kwargs.get(\"show_metric\",None)\n", + "\n", + " outdf=None\n", + " for k in emonmetric:\n", + " m=emons.emon_metrics[k]\n", + " for fk,fm in m['formula'].items():\n", + " if k not in metric_msg_map:\n", + " metric_msg_map[k]=F.avg\n", + " df=emons.gen_reduce_metric(k,list(range(0,emons.totalcores)),fk,metric_msg_map[k])\n", + " tmpdf=df.groupBy(\"appid\",'client').agg(*[l(\"`{:s}`\".format(fk)).alias(get_alias_name(fk,l)) for l in [metric_msg_map[k]]]).toPandas()\n", + " tmpdf=tmpdf.set_index(\"client\").drop(columns=['appid']).T\n", + " if outdf is None:\n", + " outdf=tmpdf\n", + " else:\n", + " outdf=outdf.append(tmpdf)\n", + " pandas.options.display.float_format = '{:,.2f}'.format\n", + " return outdf\n", + " \n", + " def get_sar_stat(app,**kwargs):\n", + " disk_prefix=kwargs.get(\"disk_prefix\",\"dev259\")\n", + " nic_prefix = kwargs.get(\"nic_prefix\",[\"'eth3'\",\"'enp24s0f1'\"])\n", + " cpustat=[app.analysis[\"sar\"][l]['sar_cpu']['als'].get_stat() for l in app.clients]\n", + " cpustat=reduce(lambda l,r:l.join(r),cpustat)\n", + " diskstat=[app.analysis[\"sar\"][l]['sar_disk']['als'].get_stat(disk_prefix=disk_prefix) for l in app.clients]\n", + " diskstat=reduce(lambda l,r:l.join(r),diskstat)\n", + " memstat=[app.analysis[\"sar\"][l]['sar_mem']['als'].get_stat() for l in app.clients]\n", + " memstat=reduce(lambda l,r:l.join(r),memstat)\n", + " nicstat=[app.analysis[\"sar\"][l]['sar_nic']['als'].get_stat(nic_prefix=nic_prefix) for l in app.clients]\n", + " nicstat=reduce(lambda l,r:l.join(r),nicstat)\n", + " pagestat=[app.analysis[\"sar\"][l]['sar_page']['als'].get_stat() for l in app.clients]\n", + " pagestat=reduce(lambda l,r:l.join(r),pagestat)\n", + " pandas.options.display.float_format = '{:,.2f}'.format\n", + " return pandas.concat([cpustat,diskstat,memstat,nicstat,pagestat])\n", + " \n", + " def get_perf_stat(self, **kwargs):\n", + " perfstat=[self.analysis[\"sar\"][l]['perfstat']['als'].get_stat() for l in self.clients]\n", + " return reduce(lambda l,r: l.join(r), perfstat)\n", + " \n", + " def get_summary(app, **kwargs):\n", + " output=[]\n", + " \n", + " appals=app.analysis[\"app\"][\"als\"]\n", + " \n", + " out=appals.get_query_time(plot=False)\n", + " \n", + " lrun=app.appid\n", + " \n", + " cmpcolumns=['runtime','disk spilled','shuffle_write','f_wait_time','input read','acc_task_time','output rows']\n", + " outcut=out[cmpcolumns]\n", + " \n", + " pdsout=pandas.DataFrame(outcut.sum(),columns=[lrun])\n", + " pdstime=pdsout \n", + "\n", + " if app.show_emon:\n", + " emondf=app.getemonmetric(**kwargs)\n", + " def get_agg(emondf):\n", + " aggs=[]\n", + " for x in emondf.index:\n", + " if x.endswith(\"avg\"):\n", + " aggs.append(emondf.loc[x].mean())\n", + " else:\n", + " aggs.append(emondf.loc[x].sum())\n", + "\n", + " emondf['agg']=aggs\n", + " return emondf\n", + " emondf=get_agg(emondf)\n", + "\n", + " emonsum=emondf[[\"agg\"]]\n", + "\n", + " emonsum.columns=[lrun]\n", + "\n", + " print(\"sar metric\")\n", + " sardf=app.get_sar_stat(**kwargs)\n", + " \n", + " def get_sar_agg(sardf):\n", + " aggs=[]\n", + " for x in sardf.index:\n", + " if \"total\" in x:\n", + " aggs.append(sardf.loc[x].sum())\n", + " elif \"max\" in x:\n", + " aggs.append(sardf.loc[x].max())\n", + " else:\n", + " aggs.append(sardf.loc[x].mean())\n", + "\n", + " sardf['agg']=aggs\n", + " return sardf\n", + " sardf=get_sar_agg(sardf)\n", + "\n", + " sarsum=sardf[[\"agg\"]]\n", + "\n", + " sarsum.columns=[lrun]\n", + " \n", + " summary=pandas.concat([pdstime,sarsum])\n", + " if app.show_emon:\n", + " summary=pandas.concat([summary,emonsum])\n", + " elif app.show_perfstat:\n", + " print(\"perf stat metric\")\n", + " perf_stat = app.get_perf_stat(**kwargs)\n", + " perf_stat = get_sar_agg(perf_stat)[['agg']]\n", + " perf_stat.columns=[lrun]\n", + " summary=pandas.concat([summary,perf_stat])\n", + " \n", + " df_sum=spark.createDataFrame(summary.T.reset_index())\n", + " for c in df_sum.columns:\n", + " df_sum=df_sum.withColumnRenamed(c,c.replace(\" \",\"_\").replace(\"(\",\"\").replace(\")\",\"\"))\n", + " df_sum.write.mode(\"overwrite\").parquet(app.filedir+\"summary.parquet\")\n", + " \n", + " return summary\n", + " \n", + " def compare_app(app2,**kwargs):\n", + " output=[]\n", + " \n", + " lbasedir=kwargs.get(\"basedir\",app2.basedir)\n", + " r_appid=kwargs.get(\"r_appid\",app2.appid)\n", + " \n", + " app=kwargs.get(\"rapp\",Application_Run(r_appid,basedir=lbasedir))\n", + "\n", + " show_queryplan_diff=kwargs.get(\"show_queryplan_diff\",True)\n", + " \n", + " queryids=kwargs.get(\"queryids\",None)\n", + " \n", + " appals=app.analysis[\"app\"][\"als\"]\n", + " appals2=app2.analysis[\"app\"][\"als\"]\n", + "\n", + " out=appals.get_query_time(plot=False)\n", + " out2=appals2.get_query_time(plot=False)\n", + "\n", + " lrun=app.appid\n", + " rrun=app2.appid\n", + " cmpcolumns=['runtime','shuffle_write','f_wait_time','input read','acc_task_time','output rows']\n", + " outcut=out[cmpcolumns]\n", + " out2cut=out2[cmpcolumns]\n", + " cmp=outcut.join(out2cut,lsuffix='_'+lrun,rsuffix='_'+rrun)\n", + "\n", + " pdsout=pandas.DataFrame(outcut.sum(),columns=[lrun])\n", + " pdsout2=pandas.DataFrame(out2cut.sum(),columns=[rrun])\n", + " pdstime=pdsout.join(pdsout2)\n", + "\n", + " showemon=app.show_emon and app2.show_emon\n", + " if showemon:\n", + " print(\"emon metric\")\n", + "\n", + " emondf=app.getemonmetric(**kwargs)\n", + " emondf2=app2.getemonmetric(**kwargs)\n", + " #in case we comare with two clsuter\n", + " emondf.columns=emondf2.columns\n", + " def get_agg(emondf):\n", + " aggs=[]\n", + " for x in emondf.index:\n", + " if x.endswith(\"avg\"):\n", + " aggs.append(emondf.loc[x].mean())\n", + " else:\n", + " aggs.append(emondf.loc[x].sum())\n", + "\n", + " emondf['agg']=aggs\n", + " return emondf\n", + " emondf=get_agg(emondf)\n", + " emondf2=get_agg(emondf2)\n", + "\n", + " emoncolumns=emondf.columns\n", + " emoncmp=emondf.join(emondf2,lsuffix='_'+lrun,rsuffix='_'+rrun)\n", + " emonsum=emoncmp[[\"agg_\"+lrun,\"agg_\"+rrun]]\n", + "\n", + " emonsum.columns=[lrun,rrun]\n", + "\n", + " print(\"sar metric\")\n", + " sardf=app.get_sar_stat(**kwargs)\n", + " sardf2=app2.get_sar_stat(**kwargs)\n", + " \n", + " def get_sar_agg(sardf):\n", + " aggs=[]\n", + " for x in sardf.index:\n", + " if \"total\" in x:\n", + " aggs.append(sardf.loc[x].sum())\n", + " elif \"max\" in x:\n", + " aggs.append(sardf.loc[x].max())\n", + " else:\n", + " aggs.append(sardf.loc[x].mean())\n", + "\n", + " sardf['agg']=aggs\n", + " return sardf\n", + " sardf=get_sar_agg(sardf)\n", + " sardf2=get_sar_agg(sardf2)\n", + " #in case we compare two clusters\n", + " sardf2.columns=sardf.columns\n", + "\n", + " sarcolumns=sardf.columns\n", + " sarcmp=sardf.join(sardf2,lsuffix='_'+lrun,rsuffix='_'+rrun)\n", + " sarsum=sarcmp[[\"agg_\"+lrun,\"agg_\"+rrun]]\n", + "\n", + " sarsum.columns=[lrun,rrun]\n", + " \n", + " summary=pandas.concat([pdstime,sarsum])\n", + " if showemon:\n", + " summary=pandas.concat([summary,emonsum])\n", + " \n", + " summary[\"diff\"]=numpy.where(summary[rrun] > 0, summary[lrun]/summary[rrun]-1, 0)\n", + " \n", + " \n", + " def highlight_diff(x):\n", + " styles=[]\n", + " mx=x.max()\n", + " mn=x.min()\n", + " mx=max(mx,-mn,0.2)\n", + " for j in x.index:\n", + " m1=(x[j])/mx*100 if x[j]!=None else 0\n", + " if m1>0:\n", + " styles.append(f'width: 400px ; background-image: linear-gradient(to right, transparent 50%, #5fba7d 50%, #5fba7d {50+m1/2}%, transparent {50+m1/2}%)')\n", + " else:\n", + " styles.append(f'width: 400px ;background-image: linear-gradient(to left, transparent 50%, #f1a863 50%, #f1a863 {50-m1/2}%, transparent {50-m1/2}%)')\n", + " return styles\n", + "\n", + " output.append(summary.style.apply(highlight_diff,subset=['diff']).format({lrun:\"{:,.2f}\",rrun:\"{:,.2f}\",'diff':\"{:,.2%}\"}).render())\n", + "\n", + " cmp_plot=cmp\n", + " cmp_plot['diff']=cmp_plot['runtime_'+lrun]-cmp_plot['runtime_'+rrun]\n", + "\n", + " pltx=cmp_plot.sort_values(by='diff',axis=0).plot.bar(y=['runtime_'+lrun,'runtime_'+rrun],figsize=(30,8))\n", + " better_num=sqldf('''select count(*) from cmp_plot where diff>0''')['count(*)'][0]\n", + " pltx.text(0.1, 0.8,'{:d} queries are better'.format(better_num), ha='center', va='center', transform=pltx.transAxes)\n", + "\n", + " df1 = pandas.DataFrame('', index=cmp.index, columns=cmpcolumns)\n", + " for l in cmpcolumns:\n", + " for j in cmp.index:\n", + " df1[l][j]=[cmp[l+\"_\"+lrun][j],cmp[l+\"_\"+rrun][j],cmp[l+\"_\"+lrun][j]/cmp[l+\"_\"+rrun][j]-1]\n", + "\n", + " def highlight_greater(x,columns):\n", + " df1 = pandas.DataFrame('', index=x.index, columns=x.columns)\n", + " for l in columns:\n", + " m={}\n", + " for j in x.index:\n", + " m[j] = (x[l][j][1] / x[l][j][0])*100 if x[l][j][0]!=0 else 100\n", + " mx=max(m.values())-100\n", + " mn=100-min(m.values())\n", + " mx=max(mx,mn)\n", + " for j in x.index:\n", + " m1=-(100-m[j])/mx*100 if x[l][j][0]!=0 else 0\n", + " if m1>0:\n", + " df1[l][j] = f'background-image: linear-gradient(to right, transparent 50%, #5fba7d 50%, #5fba7d {50+m1/2}%, transparent {50+m1/2}%)'\n", + " else:\n", + " df1[l][j] = f'background-image: linear-gradient(to left, transparent 50%, #f1a863 50%, #f1a863 {50-m1/2}%, transparent {50-m1/2}%)'\n", + "\n", + " return df1\n", + "\n", + " def display_compare(df,columns):\n", + " output.append(df.style.set_properties(**{'width': '300px','border-style':'solid','border-width':'1px'}).apply(lambda x: highlight_greater(x,columns), axis=None).format(lambda x: '''\n", + "
{:,.2f}
\n", + "
{:,.2f}
\n", + "
{:,.2f}%
\n", + " '''.format(x[0],x[1],x[2]*100)).render())\n", + " display_compare(df1,cmpcolumns)\n", + "\n", + " df3 = pandas.DataFrame('', index=sarcmp.index, columns=sarcolumns)\n", + " for l in sarcolumns:\n", + " for j in df3.index:\n", + " df3[l][j]=[sarcmp[l+\"_\"+lrun][j],sarcmp[l+\"_\"+rrun][j],sarcmp[l+\"_\"+lrun][j]/sarcmp[l+\"_\"+rrun][j]-1]\n", + " display_compare(df3,sarcolumns)\n", + "\n", + " if showemon:\n", + " df2 = pandas.DataFrame('', index=emoncmp.index, columns=emoncolumns)\n", + " for l in emoncolumns:\n", + " for j in df2.index:\n", + " df2[l][j]=[emoncmp[l+\"_\"+lrun][j],emoncmp[l+\"_\"+rrun][j],emoncmp[l+\"_\"+lrun][j]/emoncmp[l+\"_\"+rrun][j]-1]\n", + " display_compare(df2,emoncolumns)\n", + "\n", + " print(\"time breakdown\")\n", + " ################################ time breakdown ##################################################################################################\n", + " timel=appals.show_time_metric(plot=False)\n", + " timer=appals2.show_time_metric(plot=False)\n", + " timer.columns=[l.replace(\"scan time\",\"time_batchscan\") for l in timer.columns]\n", + " timel.columns=[l.replace(\"scan time\",\"time_batchscan\") for l in timel.columns]\n", + " rcols=timer.columns\n", + " lcols=[]\n", + " for c in [l.split(\"%\")[1][1:] for l in rcols]:\n", + " for t in timel.columns:\n", + " if t.endswith(c):\n", + " lcols.append(t)\n", + " for t in timel.columns:\n", + " if t not in lcols:\n", + " lcols.append(t)\n", + " timel_adj=timel[lcols]\n", + "\n", + " fig, axs = plt.subplots(nrows=1, ncols=2, sharey=True,figsize=(30,8),gridspec_kw = {'width_ratios':[1, 1]})\n", + " plt.subplots_adjust(wspace=0.01)\n", + " ax=timel_adj.plot.bar(ax=axs[0],stacked=True)\n", + " list_values=timel_adj.loc[0].values\n", + " for rect, value in zip(ax.patches, list_values):\n", + " h = rect.get_height() /2.\n", + " w = rect.get_width() /2.\n", + " x, y = rect.get_xy()\n", + " ax.text(x+w, y+h,\"{:,.2f}\".format(value),horizontalalignment='center',verticalalignment='center',color=\"white\")\n", + " ax=timer.plot.bar(ax=axs[1],stacked=True)\n", + " list_values=timer.loc[0].values\n", + " for rect, value in zip(ax.patches, list_values):\n", + " h = rect.get_height() /2.\n", + " w = rect.get_width() /2.\n", + " x, y = rect.get_xy()\n", + " ax.text(x+w, y+h,\"{:,.2f}\".format(value),horizontalalignment='center',verticalalignment='center',color=\"white\")\n", + "\n", + "################################ critical time breakdown ##################################################################################################\n", + " timel=appals.show_time_metric(plot=False,taskids=[l[0].item() for l in appals.criticaltasks])\n", + " timer=appals2.show_time_metric(plot=False,taskids=[l[0].item() for l in appals2.criticaltasks])\n", + " timer.columns=[l.replace(\"scan time\",\"time_batchscan\") for l in timer.columns]\n", + " timel.columns=[l.replace(\"scan time\",\"time_batchscan\") for l in timel.columns]\n", + " rcols=timer.columns\n", + " lcols=[]\n", + " for c in [l.split(\"%\")[1][1:] for l in rcols]:\n", + " for t in timel.columns:\n", + " if t.endswith(c):\n", + " lcols.append(t)\n", + " for t in timel.columns:\n", + " if t not in lcols:\n", + " lcols.append(t)\n", + " timel_adj=timel[lcols]\n", + "\n", + " fig, axs = plt.subplots(nrows=1, ncols=2, sharey=True,figsize=(30,8),gridspec_kw = {'width_ratios':[1, 1]})\n", + " plt.subplots_adjust(wspace=0.01)\n", + " ax=timel_adj.plot.bar(ax=axs[0],stacked=True)\n", + " list_values=timel_adj.loc[0].values\n", + " for rect, value in zip(ax.patches, list_values):\n", + " h = rect.get_height() /2.\n", + " w = rect.get_width() /2.\n", + " x, y = rect.get_xy()\n", + " ax.text(x+w, y+h,\"{:,.2f}\".format(value),horizontalalignment='center',verticalalignment='center',color=\"white\")\n", + " ax=timer.plot.bar(ax=axs[1],stacked=True)\n", + " list_values=timer.loc[0].values\n", + " for rect, value in zip(ax.patches, list_values):\n", + " h = rect.get_height() /2.\n", + " w = rect.get_width() /2.\n", + " x, y = rect.get_xy()\n", + " ax.text(x+w, y+h,\"{:,.2f}\".format(value),horizontalalignment='center',verticalalignment='center',color=\"white\")\n", + "\n", + "\n", + " ################################ hot stage ##########################################################################################################\n", + "\n", + " hotstagel=appals.get_hottest_stages(plot=False)\n", + " hotstager=appals2.get_hottest_stages(plot=False)\n", + " hotstagel.style.format(lambda x: '''{:,.2f}'''.format(x))\n", + "\n", + " norm = matplotlib.colors.Normalize(vmin=0, vmax=max(hotstager.queryid))\n", + " cmap = matplotlib.cm.get_cmap('brg')\n", + " def setbkcolor(x):\n", + " rgba=cmap(norm(x['queryid']))\n", + " return ['background-color:rgba({:d},{:d},{:d},1); color:white'.format(int(rgba[0]*255),int(rgba[1]*255),int(rgba[2]*255))]*9\n", + "\n", + " output.append(\"
\" + hotstagel.style.apply(setbkcolor,axis=1).format({\"total_time\":lambda x: '{:,.2f}'.format(x),\"stdev_time\":lambda x: '{:,.2f}'.format(x),\"acc_total\":lambda x: '{:,.2%}'.format(x),\"total\":lambda x: '{:,.2%}'.format(x)}).render()+\n", + " \"\" + hotstager.style.apply(setbkcolor,axis=1).format({\"total_time\":lambda x: '{:,.2f}'.format(x),\"stdev_time\":lambda x: '{:,.2f}'.format(x),\"acc_total\":lambda x: '{:,.2%}'.format(x),\"total\":lambda x: '{:,.2%}'.format(x)}).render()+ \"
\")\n", + "\n", + " if not show_queryplan_diff:\n", + " return \"\\n\".join(output)\n", + " \n", + " print(\"hot stage\")\n", + "\n", + " loperators=appals.getOperatorCount()\n", + " roperators=appals2.getOperatorCount()\n", + " loperators_rowcnt=appals.get_metric_output_rowcnt()\n", + " roperators_rowcnt=appals2.get_metric_output_rowcnt()\n", + " \n", + " def show_query_diff(queryid, always_show=True):\n", + " lops=pandas.DataFrame(loperators[queryid])\n", + " lops.columns=['calls_l']\n", + " lops=lops.loc[lops['calls_l'] >0]\n", + "\n", + " rops=pandas.DataFrame(roperators[queryid])\n", + " rops.columns=[\"calls_r\"]\n", + " rops=rops.loc[rops['calls_r'] >0]\n", + " lops_row=pandas.DataFrame(loperators_rowcnt[queryid])\n", + " lops_row.columns=[\"rows_l\"]\n", + " lops_row=lops_row.loc[lops_row['rows_l'] >0]\n", + "\n", + " rops_row=pandas.DataFrame(roperators_rowcnt[queryid])\n", + " rops_row.columns=[\"rows_r\"]\n", + " rops_row=rops_row.loc[rops_row['rows_r'] >0]\n", + "\n", + " opscmp=pandas.merge(pandas.merge(pandas.merge(lops,rops,how=\"outer\",left_index=True,right_index=True),lops_row,how=\"outer\",left_index=True,right_index=True),rops_row,how=\"outer\",left_index=True,right_index=True)\n", + " opscmp=opscmp.fillna(\"\")\n", + " \n", + " def set_bk_color_opscmp(x):\n", + " calls_l= 0 if x['calls_l']==\"\" else x['calls_l']\n", + " calls_r= 0 if x['calls_r']==\"\" else x['calls_r']\n", + " rows_l= 0 if x['rows_l']==\"\" else x['rows_l']\n", + " rows_r= 0 if x['rows_r']==\"\" else x['rows_r']\n", + "\n", + " if calls_l > calls_r or rows_l > rows_r:\n", + " return ['background-color:#eb6b34']*4\n", + " if calls_l < calls_r or rows_l < rows_r:\n", + " return ['background-color:#8ad158']*4\n", + " return ['color:#dbd4d0']*4\n", + "\n", + " if always_show or not (opscmp[\"rows_l\"].equals(opscmp[\"rows_r\"]) and opscmp[\"calls_l\"].equals(opscmp[\"calls_r\"])):\n", + " print(f\"query {queryid} queryplan diff \")\n", + " if not always_show:\n", + " output.append(f\"

query{queryid} is different

\")\n", + " output.append(opscmp.style.apply(set_bk_color_opscmp,axis=1).render())\n", + "\n", + " planl=appals.get_query_plan(queryid=queryid,show_plan_only=True,plot=False)\n", + " planr=appals2.get_query_plan(queryid=queryid,show_plan_only=True,plot=False)\n", + " output.append(\"
\"+planl+\"\"+planr+\"
\")\n", + "\n", + " outputx=df1['output rows']\n", + " runtimex = df1['runtime']\n", + " for x in outputx.index:\n", + " if runtimex[x][0]/runtimex[x][1]<0.95 or runtimex[x][0]/runtimex[x][1]>1.05:\n", + " output.append(f\"

query{x} is different,{lrun} time: {df1['runtime'][x][0]}, {rrun} time: {df1['runtime'][x][1]}

\")\n", + " if queryids is not None and x not in queryids:\n", + " print(\"query plan skipped\")\n", + " continue\n", + " try:\n", + " show_query_diff(x, True)\n", + " except:\n", + " print(\" query diff error\")\n", + " else:\n", + " try:\n", + " show_query_diff(x, False)\n", + " except:\n", + " print(\" query diff error\")\n", + " \n", + " return \"\\n\".join(output)\n", + " \n", + "\n", + " \n", + " def show_queryplan_diff(app2, queryid,**kwargs):\n", + " lbasedir=kwargs.get(\"basedir\",app2.basedir)\n", + " r_appid=kwargs.get(\"r_appid\",app2.appid)\n", + " \n", + " app=kwargs.get(\"rapp\",Application_Run(r_appid,basedir=lbasedir))\n", + "\n", + " appals=app.analysis[\"app\"][\"als\"]\n", + " appals2=app2.analysis[\"app\"][\"als\"]\n", + "\n", + " hotstagel=appals.get_hottest_stages(plot=False)\n", + " hotstager=appals2.get_hottest_stages(plot=False)\n", + " hotstagel.style.format(lambda x: '''{:,.2f}'''.format(x))\n", + "\n", + " loperators=appals.getOperatorCount()\n", + " roperators=appals2.getOperatorCount()\n", + " loperators_rowcnt=appals.get_metric_output_rowcnt()\n", + " roperators_rowcnt=appals2.get_metric_output_rowcnt()\n", + "\n", + " lrun=app.appid\n", + " rrun=app2.appid\n", + "\n", + " output=[]\n", + "\n", + " def show_query_diff(queryid):\n", + " lops=pandas.DataFrame(loperators[queryid])\n", + " lops.columns=['calls_l']\n", + " lops=lops.loc[lops['calls_l'] >0]\n", + "\n", + " rops=pandas.DataFrame(roperators[queryid])\n", + " rops.columns=[\"calls_r\"]\n", + " rops=rops.loc[rops['calls_r'] >0]\n", + " lops_row=pandas.DataFrame(loperators_rowcnt[queryid])\n", + " lops_row.columns=[\"rows_l\"]\n", + " lops_row=lops_row.loc[lops_row['rows_l'] >0]\n", + "\n", + " rops_row=pandas.DataFrame(roperators_rowcnt[queryid])\n", + " rops_row.columns=[\"rows_r\"]\n", + " rops_row=rops_row.loc[rops_row['rows_r'] >0]\n", + "\n", + " opscmp=pandas.merge(pandas.merge(pandas.merge(lops,rops,how=\"outer\",left_index=True,right_index=True),lops_row,how=\"outer\",left_index=True,right_index=True),rops_row,how=\"outer\",left_index=True,right_index=True)\n", + " opscmp=opscmp.fillna(\"\")\n", + "\n", + " def set_bk_color_opscmp(x):\n", + " calls_l= 0 if x['calls_l']==\"\" else x['calls_l']\n", + " calls_r= 0 if x['calls_r']==\"\" else x['calls_r']\n", + " rows_l= 0 if x['rows_l']==\"\" else x['rows_l']\n", + " rows_r= 0 if x['rows_r']==\"\" else x['rows_r']\n", + "\n", + " if calls_l > calls_r or rows_l > rows_r:\n", + " return ['background-color:#eb6b34']*4\n", + " if calls_l < calls_r or rows_l < rows_r:\n", + " return ['background-color:#8ad158']*4\n", + " return ['color:#dbd4d0']*4\n", + "\n", + " output.append(opscmp.style.apply(set_bk_color_opscmp,axis=1).render())\n", + "\n", + " planl=appals.get_query_plan(queryid=queryid,show_plan_only=True,plot=False)\n", + " planr=appals2.get_query_plan(queryid=queryid,show_plan_only=True,plot=False)\n", + " output.append(\"
\"+planl+\"\"+planr+\"
\")\n", + "\n", + " x=queryid\n", + " print(\"query \",x,\" queryplan diff \")\n", + " #output.append(f\"

query{x} is different,{lrun} time: {df1['runtime'][x][0]}, {rrun} time: {df1['runtime'][x][1]}

\")\n", + " show_query_diff(x)\n", + " display(HTML(\"\\n\".join(output)))\n", + " return" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# MISC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def reduce_metric(pdrst,slave_id,metric,core,agg_func):\n", + " pdrst['rst']=pdrst.apply(lambda x:x['app_id'].get_reduce_metric(slave_id,metric,core,agg_func), axis=1)\n", + " for l in agg_func:\n", + " pdrst[get_alias_name(metric,l)]=pdrst.apply(lambda x:x['rst'].iloc[0][get_alias_name(metric,l)],axis=1)\n", + " return pdrst.drop(columns=['rst'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def cvt_number(n):\n", + " try:\n", + " if str(n).isdigit():\n", + " return f'{n:,}'\n", + " else:\n", + " return f'{round(float(n),2):,}'\n", + " except ValueError:\n", + " return n\n", + "\n", + "def parse_changelog(changelog):\n", + " out=[]\n", + " if fs.exists(changelog):\n", + " with fs.open(changelog) as f:\n", + " for l in f.readlines():\n", + " l = l.decode('ascii')\n", + " if l.startswith(\"commit\"):\n", + " out.append(re.sub(r\"commit +(.+)\",r\"commit \\1\",l))\n", + " elif l.startswith(\"Author\"):\n", + " out.append(re.sub(r\"Author: +([^<]+) <(.+)>\",r\"Author: \\1 <\\2> \",l))\n", + " elif l.startswith(\"Date\"):\n", + " out.append(re.sub(r\"Date: +(\\d\\d\\d\\d-\\d\\d-\\d\\d)\",r\"Author: \\1\",l))\n", + " else:\n", + " out.append(l)\n", + " else:\n", + " out.append(f'{os.path.basename(changelog)} not found!')\n", + " return out\n", + "\n", + "def generate_query_diff(name, comp_name, query_time_file, comp_query_time_file):\n", + " result = []\n", + " if fs.exists(query_time_file) and fs.exists(comp_query_time_file):\n", + " result.append(['query', name, comp_name, 'difference', 'percentage'])\n", + " \n", + " qtimes = {}\n", + " comp_qtimes = {}\n", + " with fs.open(query_time_file) as f:\n", + " qtimes = json.loads(f.read().decode('ascii'))\n", + " with fs.open(comp_query_time_file) as f:\n", + " comp_qtimes = json.loads(f.read().decode('ascii'))\n", + " \n", + " query_ids = sorted(qtimes.keys(), key=lambda x: str(len(x))+x if x[-1] != 'a' and x[-1] != 'b' else str(len(x)-1) + x)\n", + " \n", + " if len(comp_qtimes) != len(qtimes):\n", + " raise Exception('Number of queries mismatch!')\n", + " \n", + " query_ids.append('total')\n", + " qtimes['total'] = sum([float(i) for i in qtimes.values()])\n", + " comp_qtimes['total'] = sum([float(i) for i in comp_qtimes.values()])\n", + " \n", + " for q in query_ids:\n", + " t1 = qtimes.get(q)\n", + " t2 = comp_qtimes.get(q)\n", + " delta = str(\"{:.2f}\".format(float(t2) - float(t1)))\n", + " perc = str(\"{:.2f}\".format((float(t2) / float(t1)) * 100)) + '%'\n", + " result.append([q, str(t1), str(t2), delta, perc])\n", + " return result\n", + "\n", + "def append_summary(appid, base_dir, name, comp_appid, comp_base_dir, comp_name, baseline_appid, baseline_base_dir, statsall, output):\n", + " with open(output,\"a\") as linkfile:\n", + "\n", + " difftable=''' \n", + " '''\n", + " for k,v in statsall.items():\n", + " difftable+=f'''\n", + " \n", + " \n", + " \n", + " '''\n", + " difftable+='''\n", + " \n", + "
{k}{cvt_number(v)}
\\n'''\n", + " linkfile.write(difftable)\n", + " linkfile.write(\"\\n

\\n\")\n", + " \n", + " linkfile.write(\"\\n gluten gitlog in last 2 days
\\n\")\n", + " out=parse_changelog(os.path.join('/', base_dir, appid, 'changelog_gluten'))\n", + " linkfile.write(\"
\".join(out))\n", + " linkfile.write(\"\\n

\\n\")\n", + " \n", + " linkfile.write(\"\\n velox gitlog in last 2 days
\\n\")\n", + " out=parse_changelog(os.path.join('/', base_dir, appid, 'changelog_velox'))\n", + " linkfile.write(\"
\".join(out))\n", + " linkfile.write(\"\\n

\\n\")\n", + " \n", + " linkfile.write('''
\\n''')\n", + " \n", + " def append_query_diff(their_appid, their_base_dir, their_name):\n", + " query_diff=generate_query_diff(name, their_name, os.path.join('/', base_dir, appid, 'query_time.json'), os.path.join('/', their_base_dir, their_appid, 'query_time.json'))\n", + " if query_diff:\n", + " difftable='''\n", + " \n", + " '''\n", + " for l in query_diff:\n", + " difftable+='''\n", + " '''\n", + " base=0\n", + " pr=0\n", + " if re.match(r\"[0-9.]+\",l[1]):\n", + " base=float(l[1])\n", + " l[1]=\"{:.2f}\".format(base)\n", + " if re.match(r\"[0-9.]+\",l[2]):\n", + " pr=float(l[2])\n", + " l[2]=\"{:.2f}\".format(pr)\n", + "\n", + " for d in l:\n", + " color='#000000'\n", + " if base > pr:\n", + " color='#6F9915'\n", + " elif base < pr:\n", + " color='#F92663'\n", + " difftable += f'''\n", + " '''\n", + "\n", + " difftable+='''\n", + " '''\n", + "\n", + " difftable+='''\n", + " \n", + "
{d}
'''\n", + " linkfile.write(difftable)\n", + " linkfile.write(\"\\n

\\n\")\n", + " # return percentage\n", + " return query_diff[-1][-1]\n", + " return ''\n", + "\n", + " baseline_perc = ''\n", + " if comp_appid:\n", + " append_query_diff(comp_appid, comp_base_dir, comp_name)\n", + " if baseline_appid:\n", + " baseline_perc = append_query_diff(baseline_appid, baseline_base_dir, 'Vanilla Spark')\n", + "\n", + " linkfile.write(\"
\")\n", + " \n", + " return baseline_perc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def generate_email_body_title(appid, base_dir, name, comp_appid, comp_base_dir, comp_name, baseline_appid, baseline_base_dir, notebook, notebook_html, traceview, stats, summary, pr=''):\n", + " statsall=collections.OrderedDict()\n", + " for k,v in stats.items():\n", + " statsall[k]=v\n", + " for k,v in summary.to_dict()[appals.appid].items():\n", + " statsall[k]=v\n", + " \n", + " pr_link=''\n", + " if pr:\n", + " pr_link=f'https://github.com/apche/incubator-gluten/pull/{pr}'\n", + " title=!wget --quiet -O - $pr_link | sed -n -e 's!.*\\(.*\\).*!\\1!p'\n", + " pr_link=f'pr link: {title[0]}
'\n", + " \n", + " output=f'/tmp/{appid}.html'\n", + " with open(output, 'w+') as f:\n", + " f.writelines(f'''\n", + "\n", + "history event: http://{local_ip}:18080/tmp/sparkEventLog/{appid}/jobs/
\n", + "notebook: http://{local_ip}:8889/notebooks/{base_dir}/{notebook}
\n", + "notebook html: http://{local_ip}:8889/view/{base_dir}/{notebook_html}
\n", + "traceview: {traceview}
\n", + "{pr_link}\n", + "

''')\n", + " baseline_perc = append_summary(appid, base_dir, name, comp_appid, comp_base_dir, comp_name, baseline_appid, baseline_base_dir, statsall, output)\n", + " \n", + " title_prefix = f\"[ {datetime.now().strftime('%m_%d_%Y')} ]\" if not pr else f\"[ PR {pr} ]\"\n", + " title = f'{title_prefix} {name} {appid} {baseline_perc}'\n", + " return output,title" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# TPCDS query map" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "hidden": true + }, + "outputs": [], + "source": [ + "m='''1\tq01\n", + " 2\tq02\n", + " 3\tq03\n", + " 4\tq04\n", + " 5\tq05\n", + " 6\tq06\n", + " 7\tq07\n", + " 8\tq08\n", + " 9\tq09\n", + " 10\tq10\n", + " 11\tq11\n", + " 12\tq12\n", + " 13\tq13\n", + " 14\tq14a\n", + " 15\tq14b\n", + " 16\tq15\n", + " 17\tq16\n", + " 18\tq17\n", + " 19\tq18\n", + " 20\tq19\n", + " 21\tq20\n", + " 22\tq21\n", + " 23\tq22\n", + " 24\tq23a\n", + " 25\tq23b\n", + " 26\tq24a\n", + " 27\tq24b\n", + " 28\tq25\n", + " 29\tq26\n", + " 30\tq27\n", + " 31\tq28\n", + " 32\tq29\n", + " 33\tq30\n", + " 34\tq31\n", + " 35\tq32\n", + " 36\tq33\n", + " 37\tq34\n", + " 38\tq35\n", + " 39\tq36\n", + " 40\tq37\n", + " 41\tq38\n", + " 42\tq39a\n", + " 43\tq39b\n", + " 44\tq40\n", + " 45\tq41\n", + " 46\tq42\n", + " 47\tq43\n", + " 48\tq44\n", + " 49\tq45\n", + " 50\tq46\n", + " 51\tq47\n", + " 52\tq48\n", + " 53\tq49\n", + " 54\tq50\n", + " 55\tq51\n", + " 56\tq52\n", + " 57\tq53\n", + " 58\tq54\n", + " 59\tq55\n", + " 60\tq56\n", + " 61\tq57\n", + " 62\tq58\n", + " 63\tq59\n", + " 64\tq60\n", + " 65\tq61\n", + " 66\tq62\n", + " 67\tq63\n", + " 68\tq64\n", + " 69\tq65\n", + " 70\tq66\n", + " 71\tq67\n", + " 72\tq68\n", + " 73\tq69\n", + " 74\tq70\n", + " 75\tq71\n", + " 76\tq72\n", + " 77\tq73\n", + " 78\tq74\n", + " 79\tq75\n", + " 80\tq76\n", + " 81\tq77\n", + " 82\tq78\n", + " 83\tq79\n", + " 84\tq80\n", + " 85\tq81\n", + " 86\tq82\n", + " 87\tq83\n", + " 88\tq84\n", + " 89\tq85\n", + " 90\tq86\n", + " 91\tq87\n", + " 92\tq88\n", + " 93\tq89\n", + " 94\tq90\n", + " 95\tq91\n", + " 96\tq92\n", + " 97\tq93\n", + " 98\tq94\n", + " 99\tq95\n", + " 100\tq96\n", + " 101\tq97\n", + " 102\tq98\n", + " 103\tq99'''.split(\"\\n\")\n", + "tpcds_query_map=[l.strip().split(\"\\t\") for l in m]\n", + "tpcds_query_map={int(l[0]):l[1] for l in tpcds_query_map}" + ] + } + ], + "metadata": { + "hide_input": false, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.12" + }, + "nbTranslate": { + "displayLangs": [ + "*" + ], + "hotkey": "alt-t", + "langInMainMenu": true, + "sourceLang": "en", + "targetLang": "fr", + "useGoogleTranslate": true + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": false, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "298.275px", + "left": "1180px", + "top": "317.125px", + "width": "332px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/tools/workload/benchmark_velox/build_gluten.sh b/tools/workload/benchmark_velox/build_gluten.sh new file mode 100755 index 000000000000..95872b9ed8b3 --- /dev/null +++ b/tools/workload/benchmark_velox/build_gluten.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +set -e + +BASEDIR=$(dirname $0) +echo "Script called with: $0" +echo "BASEDIR resolved to: $BASEDIR" + +GLUTEN_HOME=$(realpath $BASEDIR/../../..) +echo "Located Gluten in: ${GLUTEN_HOME}" + +sudo rm -rf ${GLUTEN_HOME}/ep/build-velox/build/velox_ep/ || true + +spark_version=$(head -n1 $SPARK_HOME/RELEASE | awk '{print $2}') +short_version=${spark_version%.*} + +sed -i "s/3.2 3.3 3.4 3.5/$short_version/" $GLUTEN_HOME/dev/buildbundle-veloxbe.sh + +# Update local docker image to make more cache hit for vcpkg lib binary. +sudo docker pull apache/gluten:vcpkg-centos-7 + +sudo docker run --rm \ + -v ${GLUTEN_HOME}:/root/gluten \ + -v ${HOME}/.cache/vcpkg:/root/.cache/vcpkg \ + -v ${HOME}/.m2:/root/.m2 \ + -v ${HOME}/.ccache:/root/.ccache \ + -e http_proxy \ + -e https_proxy \ + --workdir /root/gluten \ + apache/gluten:vcpkg-centos-7 \ + ./dev/package-vcpkg.sh + diff --git a/tools/workload/benchmark_velox/emon.list b/tools/workload/benchmark_velox/emon.list new file mode 100644 index 000000000000..552bfefca0f1 --- /dev/null +++ b/tools/workload/benchmark_velox/emon.list @@ -0,0 +1,10 @@ +-q -c -experimental -t0.5 -l100000 -u +-C ( + +INST_RETIRED.ANY +CPU_CLK_UNHALTED.REF_TSC +CPU_CLK_UNHALTED.THREAD +MSR_EVENT:msr=0x611:type=FREERUN:scope=PACKAGE + +) + diff --git a/tools/workload/benchmark_velox/initialize.ipynb b/tools/workload/benchmark_velox/initialize.ipynb index cbbc27686951..30574f8c16eb 100644 --- a/tools/workload/benchmark_velox/initialize.ipynb +++ b/tools/workload/benchmark_velox/initialize.ipynb @@ -2,34 +2,28 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, + "metadata": {}, "source": [ "# System Setup" ] }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "**1. Install system dependencies and python packages. Prepare the environment.**" ] }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "First, install all dependencies and python packages as `root`. Run commands and make sure the installations are successful.\n", "\n", "```bash\n", "apt update\n", "\n", - "apt install -y sudo locales wget tar tzdata git ccache cmake ninja-build build-essential llvm-11-dev clang-11 libiberty-dev libdwarf-dev libre2-dev libz-dev libssl-dev libboost-all-dev libcurl4-openssl-dev openjdk-8-jdk maven vim pip sysstat gcc-9 libjemalloc-dev nvme-cli curl zip unzip bison flex\n", + "apt install -y sudo locales wget tar tzdata git ccache cmake ninja-build build-essential llvm-11-dev clang-11 libiberty-dev libdwarf-dev libre2-dev libz-dev libssl-dev libboost-all-dev libcurl4-openssl-dev openjdk-8-jdk maven vim pip sysstat gcc-9 libjemalloc-dev nvme-cli curl zip unzip bison flex linux-tools-common linux-tools-generic linux-tools-`uname -r` mailutils\n", "\n", "python3 -m pip install notebook==6.5.2\n", "python3 -m pip install jupyter_server==1.23.4\n", @@ -45,9 +39,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "***Required for Ubuntu***\n", "\n", @@ -73,18 +65,14 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "**2. Format and mount disks**" ] }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Create a python virtual environment to finish the system setup process:\n", "\n", @@ -101,18 +89,14 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Run script [init_disks.py](./init_disks.py) to format and mount disks. **Be careful when choosing the disks to format.** If you see errors like `device or resource busy`, perhaps the partition has been mounted, you should unmount it first. If you still see this error, reboot the system and try again." ] }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Exit `venv`:\n", "```bash\n", @@ -122,18 +106,14 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "**3. Create user `sparkuser`**" ] }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Create user `sparkuser` without password and with sudo priviledge. It's recommended to use one of the disks as the home directory instead of the system drive.\n", "\n", @@ -151,9 +131,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Generate ssh keys for `sparkuser`\n", "\n", @@ -172,9 +150,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Generate ssh keys for `root`, and enable no password ssh from `sparkuser`\n", "\n", @@ -188,9 +164,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Login to `sparkuser` and run the first-time ssh to the `root`\n", "\n", @@ -207,9 +181,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "***Required for Ubuntu***\n", "\n", @@ -222,18 +194,14 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "**4. Configure jupyter notebook**" ] }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "As `sparkuser`, install python packages\n", "\n", @@ -252,9 +220,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Configure jupyter notebook. Setup password when it prompts\n", "\n", @@ -341,9 +307,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Clone Gluten\n", "\n", @@ -355,9 +319,7 @@ }, { "cell_type": "markdown", - "metadata": { - "hidden": true - }, + "metadata": {}, "source": [ "Start jupyter notebook\n", "\n", @@ -546,7 +508,7 @@ "source": [ "for l in clients:\n", " !ssh root@{l} apt update > /dev/null 2>&1\n", - " !ssh root@{l} apt install -y sudo locales wget tar tzdata git ccache cmake ninja-build build-essential llvm-11-dev clang-11 libiberty-dev libdwarf-dev libre2-dev libz-dev libssl-dev libboost-all-dev libcurl4-openssl-dev openjdk-8-jdk maven vim pip sysstat gcc-9 libjemalloc-dev nvme-cli curl zip unzip bison flex > /dev/null 2>&1" + " !ssh root@{l} apt install -y sudo locales wget tar tzdata git ccache cmake ninja-build build-essential llvm-11-dev clang-11 libiberty-dev libdwarf-dev libre2-dev libz-dev libssl-dev libboost-all-dev libcurl4-openssl-dev openjdk-8-jdk maven vim pip sysstat gcc-9 libjemalloc-dev nvme-cli curl zip unzip bison flex linux-tools-common linux-tools-generic linux-tools-`uname -r` > /dev/null 2>&1" ] }, { @@ -1713,7 +1675,26 @@ "heading_collapsed": true }, "source": [ - "# Configure startup" + "# Configure monitor & startups" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "!cd ~\n", + "!git clone https://github.com/trailofbits/tsc_freq_khz.git\n", + "\n", + "for l in clients:\n", + " !scp -r tsc_freq_khz {l}:~/\n", + "\n", + "for l in hclients:\n", + " !ssh {l} 'cd tsc_freq_khz && make && sudo insmod ./tsc_freq_khz.ko' >/dev/null 2>&1\n", + " !ssh root@{l} 'dmesg | grep tsc_freq_khz'" ] }, { @@ -1732,6 +1713,10 @@ "end=$(($(nproc) - 1))\n", "for i in $(seq 0 $end); do echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor; done\n", "for file in $(find /sys/devices/system/cpu/cpu*/power/energy_perf_bias); do echo \"0\" > $file; done\n", + "\n", + "if [ -d /home/{user}/sep_installed ]; then\n", + " /home/{user}/sep_installed/sepdk/src/insmod-sep -g {user}\n", + "fi\n", "'''\n", "\n", "with open('/tmp/tmpstartup', 'w') as f:\n", @@ -1761,6 +1746,124 @@ " !ssh $l \"sudo systemctl status mystartup.service\"" ] }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "## Install Emon" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + " Get the latest offline installer from [link](https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler-download.html?operatingsystem=linux&linux-install-type=offline) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "offline_installer = 'https://registrationcenter-download.intel.com/akdlm/IRC_NAS/e7797b12-ce87-4df0-aa09-df4a272fc5d9/intel-vtune-2025.0.0.1130_offline.sh'\n", + "for l in hclients:\n", + " !ssh {l} \"wget {offline_installer} -q && chmod +x intel-vtune-2025.0.0.1130_offline.sh\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "for l in hclients:\n", + " !ssh {l} \"sudo ./intel-vtune-2025.0.0.1130_offline.sh -a -c -s --eula accept\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "for l in hclients:\n", + " !ssh {l} \"sudo chown -R {user}:{user} /opt/intel/oneapi/vtune/ && rm -f sep_installed && ln -s /opt/intel/oneapi/vtune/latest sep_installed\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "for l in hclients:\n", + " !ssh {l} \"cd sep_installed/sepdk/src/; echo -e \\\"\\\\n\\\\n\\\\n\\\" | ./build-driver\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "for l in hclients:\n", + " !ssh root@{l} \"/home/{user}/sep_installed/sepdk/src/rmmod-sep && /home/{user}/sep_installed/sepdk/src/insmod-sep -g {user}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "for l in hclients:\n", + " !ssh {l} \"source /home/{user}/sep_installed/sep_vars.sh > /dev/null 2>&1; emon -v | head -n 1\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "for l in hclients:\n", + " !ssh {l} 'echo \"source /home/{user}/sep_installed/sep_vars.sh > /dev/null 2>&1\" >> ~/.bashrc'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "for c in hclients:\n", + " !ssh {c} 'tail -n1 ~/.bashrc'" + ] + }, { "cell_type": "markdown", "metadata": { @@ -1966,6 +2069,15 @@ "!sudo -E apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin >/dev/null 2>&1" ] }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Configure docker proxy" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1987,7 +2099,32 @@ "{}\n", "'''.format(f'Environment=\"HTTP_PROXY={http_proxy}\"' if http_proxy else '', f'Environment=\"HTTPS_PROXY={https_proxy}\"' if https_proxy else '')\n", " f.writelines(s)\n", - " !sudo cp /tmp/http-proxy.conf /etc/systemd/system/docker.service.d" + " !sudo cp /tmp/http-proxy.conf /etc/systemd/system/docker.service.d\n", + " \n", + " !ssh root@localhost \"mkdir -p /root/.docker\"\n", + " with open(f'/tmp/config.json', 'w') as f:\n", + " s = f'''\n", + "{{\n", + " \"proxies\": {{\n", + " \"default\": {{\n", + " \"httpProxy\": \"{http_proxy}\",\n", + " \"httpsProxy\": \"{https_proxy}\",\n", + " \"noProxy\": \"127.0.0.0/8\"\n", + " }}\n", + " }}\n", + "}}\n", + " '''\n", + " f.writelines(s)\n", + " !ssh root@localhost \"cp -f /tmp/config.json /root/.docker\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Configure maven proxy" ] }, { @@ -2079,46 +2216,7 @@ }, "outputs": [], "source": [ - "!sudo docker pull apache/gluten:vcpkg-centos-7" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "import os\n", - "http_proxy=os.getenv('http_proxy')\n", - "https_proxy=os.getenv('https_proxy')\n", - "\n", - "container=!sudo docker run -e http_proxy={http_proxy} -e https_proxy={https_proxy} -itd apache/gluten:vcpkg-centos-7\n", - "containerid = container[0]\n", - "containerid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "!sudo docker exec {containerid} bash -c \"cd /opt && git clone https://github.com/apache/incubator-gluten.git gluten\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "!sudo docker exec {containerid} bash -c \"cd /opt && source /opt/rh/devtoolset-9/enable && cd gluten && ./dev/builddeps-veloxbe.sh --enable_vcpkg=ON --enable_hdfs=ON > build.log\"" + "%cd ~" ] }, { @@ -2130,9 +2228,8 @@ "outputs": [], "source": [ "import os\n", - "if os.path.exists(f'/home/{user}/.m2/settings.xml'):\n", - " !sudo docker exec {containerid} bash -c \"mkdir -p ~/.m2\"\n", - " !sudo docker cp /home/{user}/.m2/settings.xml {containerid}:/root/.m2/settings.xml" + "if not os.path.exists('gluten'):\n", + " !git clone https://github.com/apache/incubator-gluten.git gluten" ] }, { @@ -2143,7 +2240,7 @@ }, "outputs": [], "source": [ - "!sudo docker exec {containerid} bash -c \"cd /opt/gluten && mvn clean package -DskipTests -Pspark-3.3 -Pbackends-velox\"" + "%cd ~/gluten/tools/workload/benchmark_velox" ] }, { @@ -2154,7 +2251,7 @@ }, "outputs": [], "source": [ - "!sudo docker cp {containerid}:/opt/gluten/package/target/gluten-velox-bundle-spark3.3_2.12-centos_7_x86_64-1.3.0-SNAPSHOT.jar ~/" + "!bash build_gluten.sh" ] }, { @@ -2165,8 +2262,8 @@ }, "outputs": [], "source": [ - "for l in clients:\n", - " !scp ~/gluten-velox-bundle-spark3.3_2.12-centos_7_x86_64-1.3.0-SNAPSHOT.jar {l}:~/" + "for l in hclients:\n", + " !scp ~/gluten/package/target/gluten-velox-bundle-spark*.jar {l}:~/" ] }, { @@ -2761,16 +2858,35 @@ "heading_collapsed": true }, "source": [ - "# Install Trace-Viewer (optional)" + "# Set up perf analysis tools (optional)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "We have a set of perf analysis scripts under $GLUTEN_HOME/tools/workload/benchmark_velox/analysis. You can follow below steps to deploy the scripts on the same cluster and use them for performance analysis after each run." ] }, { "cell_type": "markdown", "metadata": { + "heading_collapsed": true, "hidden": true }, "source": [ - "Clone the master branch\n", + "## Install and deploy Trace-Viewer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Clone the master branch of project catapult:\n", "```\n", "cd ~\n", "git clone https://github.com/catapult-project/catapult.git -b master\n", @@ -2783,11 +2899,11 @@ "hidden": true }, "source": [ - "Trace-Viewer requires python version 2.7. Create a virtualenv for python2.7\n", + "Trace-Viewer requires python version 2.7. Create a virtualenv for python2.7:\n", "```\n", "sudo apt install -y python2.7\n", - "virtualenv -p /usr/bin/python2.7 py27\n", - "source py27/bin/activate\n", + "virtualenv -p /usr/bin/python2.7 py27-env\n", + "source py27-env/bin/activate\n", "```" ] }, @@ -2797,7 +2913,7 @@ "hidden": true }, "source": [ - "Apply patch\n", + "Apply patch:\n", "\n", "```\n", "cd catapult\n", @@ -2832,13 +2948,99 @@ "hidden": true }, "source": [ - "Start the service\n", + "Start the service:\n", "\n", "```\n", "mkdir -p ~/trace_result\n", "cd ~/catapult && nohup ./bin/run_dev_server --no-install-hooks -d ~/trace_result -p1088 &\n", "```" ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "## Deploy perf analysis scripts" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Create a virtualenv to run the perf analaysis scripts:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "\n", + "```bash\n", + "cd ~\n", + "virtualenv -p python3 -v paus-env\n", + "source paus-env/bin/activate\n", + "python3 -m pip install -r ~/gluten/tools/workload/benchmark_velox/analysis/requirements.txt\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "\n", + "We will put all perf analysis notebooks under `$HOME/PAUS`. Create the directory and start the notebook:\n", + "\n", + "```bash\n", + "mkdir -p ~/PAUS\n", + "cd ~/PAUS\n", + "nohup jupyter notebook --ip=0.0.0.0 --port=8889 &\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Package the virtual environment so that it can be distributed to other nodes:\n", + "```bash\n", + "cd ~\n", + "tar -czf paus-env.tar.gz paus-env\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Distribute to the worker nodes:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "for l in clients:\n", + " !scp ~/paus-env.tar.gz {l}:~/\n", + " !ssh {l} tar -zxf paus-env.tar.gz" + ] } ], "metadata": { @@ -2858,7 +3060,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.10.12" }, "nbTranslate": { "displayLangs": [ diff --git a/tools/workload/benchmark_velox/native_sql_initialize.ipynb b/tools/workload/benchmark_velox/native_sql_initialize.ipynb index ee6bf443f6b4..0772232d70c9 100644 --- a/tools/workload/benchmark_velox/native_sql_initialize.ipynb +++ b/tools/workload/benchmark_velox/native_sql_initialize.ipynb @@ -69,6 +69,20 @@ "# System Settings" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from pathlib import Path\n", + "home = os.path.realpath(str(Path.home()))\n", + "cwd = os.getcwd()\n", + "print(f'home: {home}')\n", + "print(f'cwd: {cwd}')" + ] + }, { "cell_type": "code", "execution_count": null, @@ -237,7 +251,7 @@ "import spylon_kernel\n", "from collections import namedtuple\n", "from concurrent.futures import ThreadPoolExecutor\n", - "from datetime import date\n", + "from datetime import date, datetime\n", "from functools import reduce\n", "from IPython.display import display, HTML\n", "from matplotlib import rcParams\n", @@ -273,24 +287,25 @@ "import socket\n", "import os\n", "import sys\n", - "\n", - "from pathlib import Path\n", - "home = str(Path.home())\n", + "import json\n", "\n", "def upload_profile(server, base_dir, appid):\n", " local_profile_dir = os.path.join(home, 'profile')\n", " !mkdir -p {local_profile_dir}\n", - " !cd {local_profile_dir}; rm -f {appid}.tar.gz; tar zcvf {appid}.tar.gz {appid} >/dev/null 2>&1\n", + " !(cd {local_profile_dir}; rm -f {appid}.tar.gz; tar zcvf {appid}.tar.gz {appid}) >/dev/null 2>&1\n", " \n", " server_local_dir=os.path.join('PAUS', base_dir)\n", " server_local_profile_dir=os.path.join(server_local_dir, 'profile')\n", " server_hdfs_dir=f'/{base_dir}/'\n", "\n", " !ssh {server} \"mkdir -p {server_local_profile_dir}\"\n", - " !ssh {server} \"cd {server_local_profile_dir}; rm {appid}.tar.gz; rm -r {appid} >/dev/null 2>&1\"\n", + " !ssh {server} \"cd {server_local_profile_dir} && rm {appid}.tar.gz >/dev/null 2>&1\"\n", + " !ssh {server} \"cd {server_local_profile_dir} && rm -r {appid} >/dev/null 2>&1\"\n", " !scp {local_profile_dir}/{appid}.tar.gz {server}:{server_local_profile_dir}/\n", " !ssh {server} \"cd {server_local_profile_dir} && tar zxf {appid}.tar.gz\"\n", - " !ssh {server} \"hdfs dfs -mkdir -p {server_hdfs_dir}; hdfs dfs -rm -r {server_hdfs_dir}{appid}; hdfs dfs -put {server_local_profile_dir}/{appid} {server_hdfs_dir}\"\n", + " !ssh {server} \"hdfs dfs -mkdir -p {server_hdfs_dir}\"\n", + " !ssh {server} \"hdfs dfs -rm -r {server_hdfs_dir}{appid} >/dev/null 2>&1\"\n", + " !ssh {server} \"hdfs dfs -put {server_local_profile_dir}/{appid} {server_hdfs_dir}\"\n", " !ssh {server} \"cd {server_local_profile_dir}; rm {appid}.tar.gz; rm -r {appid}\"\n", "\n", "def killsar(clients):\n", @@ -306,6 +321,8 @@ " out=!ssh $l \"ps aux | grep -w perf | grep -v grep | tr -s ' ' | cut -d' ' -f2\"\n", " for x in out:\n", " !ssh root@$l \"kill $x > /dev/null 2>&1\"\n", + " for l in clients:\n", + " !ssh $l \"emon -stop > /dev/null 2>&1\"\n", "\n", "def killnumactl(clients):\n", " for l in clients:\n", @@ -313,7 +330,7 @@ " for x in out:\n", " !ssh $l \"kill $x > /dev/null 2>&1\"\n", "\n", - "def startmonitor(clients,appid,**kwargs):\n", + "def startmonitor(clients, appid, collect_emon, **kwargs):\n", " local_profile_dir=os.path.join(home, 'profile')\n", " prof=os.path.join(local_profile_dir, appid)\n", " !mkdir -p {prof}\n", @@ -323,6 +340,11 @@ " \n", " killsar(clients)\n", " \n", + " if collect_emon:\n", + " !cp -f {emon_list} {home}/emon.list\n", + " for l in clients:\n", + " !scp {home}/emon.list {l}:{home}/emon.list > /dev/null 2>&1\n", + " \n", " perfsyscalls=kwargs.get(\"collect_perf_syscall\",None)\n", " \n", " for l in clients:\n", @@ -331,13 +353,19 @@ " !ssh {l} mkdir -p {prof_client}\n", " !ssh {l} \"sar -o {prof_client}/sar.bin -r -u -d -B -n DEV 1 >/dev/null 2>&1 &\"\n", " !ssh root@{l} \"jps | grep CoarseGrainedExecutorBackend | cut -d' ' -f 1 | xargs -I % bash -c '(cat /proc/%/status >> {prof_client}/%.stat; cat /proc/%/io >> {prof_client}/%.stat)'\"\n", + " if collect_emon:\n", + " !ssh {l} \"emon -i {home}/emon.list -f {prof_client}/emon.rst >/dev/null 2>&1 & \"\n", + " else:\n", + " !ssh root@{l} \"perf stat -e 'instructions,cycles,cpu_clk_unhalted.thread,cpu_clk_unhalted.ref_tsc' -a -I 500 -o {prof_client}/perfstat.txt >/dev/null 2>&1 & \"\n", + " !ssh {l} \"cat /sys/devices/system/cpu/cpu0/tsc_freq_khz | xargs -I% echo %000 > {prof_client}/tsc_freq 2>/dev/null &\"\n", + " !ssh {l} \"lscpu | grep '^CPU(s):' | cut -d ':' -f 2 | tr -d ' ' > {prof_client}/totalcores 2>/dev/null &\"\n", " if kwargs.get(\"collect_pid\",False):\n", " !ssh {l} \"jps | grep CoarseGrainedExecutorBackend | head -n 1 | cut -d' ' -f 1 | xargs -I % pidstat -h -t -p % 1 > {prof_client}/pidstat.out 2>/dev/null &\"\n", " !ssh root@{l} 'cat /proc/uptime | cut -d\" \" -f 1 | xargs -I ^ date -d \"- ^ seconds\" +%s.%N' > $prof/$l/uptime.txt\n", " if kwargs.get(\"collect_sched\",False):\n", " !ssh root@{l} 'perf trace -e \"sched:sched_switch\" -C 8-15 -o {prof_client}/sched.txt -T -- sleep 10000 >/dev/null 2>/dev/null &'\n", " if perfsyscalls is not None:\n", - " !ssh root@{l} \"perf stat -e 'syscalls:sys_exit_poll,syscalls:sys_exit_epoll_wait' -a -I 1000 -o {prof_client}/perfstat.txt >/dev/null 2>&1 & \"\n", + " !ssh root@{l} \"perf stat -e 'syscalls:sys_exit_poll,syscalls:sys_exit_epoll_wait' -a -I 1000 -o {prof_client}/perfsyscalls.txt >/dev/null 2>&1 & \"\n", " if kwargs.get(\"collect_hbm\",False):\n", " hbm_nodes = kwargs.get(\"hbm_nodes\")\n", " if hbm_nodes is not None:\n", @@ -350,9 +378,8 @@ " !ssh $hbm_l \"while :; do echo \\$(numactl -H | grep '$hbm_numa_nodes' | grep 'size' | awk '{ print \\$4 }' | awk '{ s += \\$1 } END { print s }'), \\$(numactl -H | grep '$hbm_numa_nodes' | grep 'free' | awk '{ print \\$4 }' | awk '{ s += \\$1 } END { print s }') | ts '%Y-%m-%d %H:%M:%S,' >> $hbm_prof/$hbm_l/numactl.csv; sleep 1; done >/dev/null 2>&1 &\"\n", " else:\n", " print(\"Missing argument: hbm_nodes. e.g. hbm_nodes = list(range(8,16))\")\n", - " return prof\n", "\n", - "def stopmonitor(clients, sc, appid, **kwargs):\n", + "def stopmonitor(clients, sc, appid, result, collect_emon, **kwargs):\n", " %cd ~\n", " \n", " local_profile_dir=os.path.join(home, 'profile')\n", @@ -360,23 +387,31 @@ " !mkdir -p {prof}\n", "\n", " killsar(clients)\n", - " killnumactl(clients) \n", - " \n", - " with open(f\"{prof}/starttime\",\"w\") as f:\n", - " f.write(\"{:d}\".format(int(time.time()*1000)))\n", + " killnumactl(clients)\n", " \n", " for l in clients:\n", " prof_client=os.path.join(prof, l)\n", " !ssh {l} \"sar -f {prof_client}/sar.bin -r > {prof_client}/sar_mem.sar;sar -f {prof_client}/sar.bin -u > {prof_client}/sar_cpu.sar;sar -f {prof_client}/sar.bin -d -p > {prof_client}/sar_disk.sar;sar -f {prof_client}/sar.bin -n DEV > {prof_client}/sar_nic.sar;sar -f {prof_client}/sar.bin -B > {prof_client}/sar_page.sar;\" \n", " !ssh root@{l} \"jps | grep CoarseGrainedExecutorBackend | cut -d' ' -f 1 | xargs -I % bash -c '(cat /proc/%/status >> {prof_client}/%.stat; cat /proc/%/io >> {prof_client}/%.stat)'\"\n", + " if collect_emon:\n", + " !ssh {l} \"source ~/sep_install/sep_vars.sh>/dev/null 2>&1; emon -v \" > {prof}/{l}/emonv.txt\n", " !ssh {l} \"sar -V \" > {prof_client}/sarv.txt\n", - " !test -f {prof_client}/perfstat.txt && head -n 1 {prof_client}/perfstat.txt > {prof_client}/perfstarttime\n", + " !ssh {l} \"test -f {prof_client}/perfstat.txt && head -n 1 {prof_client}/perfstat.txt > {prof_client}/perfstarttime\"\n", " if l!= socket.gethostname():\n", " !scp -r {l}:{prof_client} {prof}/ > /dev/null 2>&1\n", " \n", " if sc is not None:\n", " sc.stop()\n", + " \n", + " !git --git-dir=\"{gluten_home}/.git\" log --format=\"commit %H%nAuthor: %an <%ae>%nDate: %cs%n %n %s %n\" --since=`date --date='2 days ago' +'%m/%d/%Y'` > {prof}/changelog_gluten\n", + " !git --git-dir=\"{gluten_home}/ep/build-velox/build/velox_ep/.git\" log --format=\"commit %H%nAuthor: %an <%ae>%nDate: %cs%n %n %s %n\" --since=`date --date='2 days ago' +'%m/%d/%Y'` > {prof}/changelog_velox\n", + " \n", + " with open(f\"{prof}/starttime\",\"w\") as f:\n", + " f.write(\"{:d}\".format(int(time.time()*1000)))\n", " \n", + " with open(f'{prof}/query_time.json', 'w') as f:\n", + " json.dump(result, f)\n", + "\n", " if hdfs_event_dir != '':\n", " !hadoop fs -copyToLocal {hdfs_event_dir}/{appid} {prof}/app.log\n", " elif local_event_dir != '':\n", @@ -731,6 +766,32 @@ " return etc_gmt" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_last_run(records_file, appid=''):\n", + " if os.path.exists(records_file):\n", + " if appid:\n", + " lines=!tail -n2 $records_file\n", + " if len(lines) == 2:\n", + " # Check appid match\n", + " last_appid = lines[1].split('\\t')[1]\n", + " if last_appid != appid:\n", + " print(f'appid not match. Required {appid}. Got {last_appid}')\n", + " else:\n", + " l=lines[0].split('\\t')\n", + " return l[1],l[2],l[3]\n", + " else:\n", + " lines=!tail -n1 $records_file\n", + " if len(lines) == 1:\n", + " l=lines[0].split('\\t')\n", + " return l[1],l[2],l[3]\n", + " return None, None, None" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -765,10 +826,16 @@ " tpctables=[]\n", " tpc_query_path = ''\n", " \n", + " RECORDS_SPARK_TPCH = f\"records_spark_tpch.csv\"\n", + " RECORDS_SPARK_TPCDS = f\"records_spark_tpcds.csv\"\n", + " RECORDS_GLUTEN_TPCH = f\"records_gluten_tpch.csv\"\n", + " RECORDS_GLUTEN_TPCDS = f\"records_gluten_tpcds.csv\"\n", + " \n", " def __init__(self, spark, table_dir, run_gluten, workload, server, base_dir, nb_name, data_source = 'parquet'):\n", " self.spark = spark\n", " self.sc = spark.sparkSession.sparkContext\n", " self.appid = self.sc.applicationId\n", + " self.app_name = '_'.join(self.sc.appName.split(' '))\n", " self.run_gluten = run_gluten\n", " self.workload = workload\n", " self.table_dir = table_dir\n", @@ -778,7 +845,9 @@ " self.data_source = data_source\n", " self.table_loaded = False\n", " self.result = {}\n", + " self.duration = 0\n", " self.stopped = False\n", + " self.collect_emon = False\n", " self.perf_html = ''\n", " self.finished_nb = ''\n", " for l in os.listdir(self.tpc_query_path):\n", @@ -788,40 +857,65 @@ " self.query_ids = sorted(self.query_infos.keys(), key=lambda x: str(len(x))+x if x[-1] != 'a' and x[-1] != 'b' else str(len(x)-1) + x)\n", " print(\"http://{}:18080/history/{}/jobs/\".format(local_ip, self.sc.applicationId))\n", " \n", - " def start_monitor(self, clients, **kw):\n", - " startmonitor(clients, self.appid, **kw)\n", + " def start_monitor(self, clients, emon_list='', **kw):\n", + " if emon_list:\n", + " self.collect_emon = True\n", + " startmonitor(clients, self.appid, self.collect_emon, **kw)\n", " \n", " def stop_monitor(self, clients, **kw):\n", " if self.stopped:\n", " return\n", - " stopmonitor(clients, self.sc, self.appid, **kw)\n", - " if self.server:\n", - " output_nb = f'{self.nb_name[:-6]}-{self.appid}.ipynb'\n", - " if output_nb.startswith(home):\n", - " output_nb_name = os.path.relpath(output_nb, home)\n", + " stopmonitor(clients, self.sc, self.appid, self.result, self.collect_emon, **kw)\n", + "\n", + " output_nb = f'{self.nb_name[:-6]}-{self.appid}.ipynb'\n", + " \n", + " record_file = ''\n", + " if self.workload == 'tpch':\n", + " if self.run_gluten:\n", + " record_file = self.RECORDS_GLUTEN_TPCH\n", + " else:\n", + " record_file = self.RECORDS_SPARK_TPCH\n", + " else:\n", + " if self.run_gluten:\n", + " record_file = self.RECORDS_GLUTEN_TPCDS\n", " else:\n", - " output_nb_name = output_nb\n", - " output_nb_dir = os.path.dirname(output_nb_name)\n", - " server_nb_dir = os.path.join('PAUS', self.base_dir, output_nb_dir)\n", - " !ssh {self.server} \"mkdir -p {server_nb_dir}\"\n", - " !scp {output_nb} {self.server}:{server_nb_dir}\n", - " self.finished_nb = f\"http://{self.server}:8888/tree/{self.base_dir}/{output_nb_name}\"\n", + " record_file = self.RECORDS_SPARK_TPCDS\n", + " record_file = os.path.join(cwd, record_file)\n", + " with open(record_file, 'a+') as f:\n", + " f.write(f'{datetime.now()}\\t{self.appid}\\t{self.base_dir}\\t{self.app_name}\\t{output_nb}\\t{self.duration}')\n", + "\n", + " if self.server:\n", + " if output_nb.startswith(cwd):\n", + " output_nb = os.path.relpath(output_nb, cwd)\n", + " self.finished_nb = f\"http://{localhost}:8888/tree/{output_nb}\"\n", + " upload_profile(self.server, self.base_dir, self.appid)\n", + " \n", " self.stopped = True\n", "\n", - " def run_perf_analysis(self, disk_dev, nic_dev):\n", + " def run_perf_analysis(self, disk_dev, nic_dev, proxy, emails):\n", " if not self.server:\n", " return\n", "\n", - " upload_profile(self.server, self.base_dir, self.appid)\n", - "\n", - " ts=time.strftime(\"%Y_%m_%d_%H%M%S\")\n", - " name=f'{self.workload}_gluten' if self.run_gluten else f'{self.workload}_vanilla'\n", " run_script=f'{gluten_home}/tools/workload/benchmark_velox/analysis/run_perf_analysis.sh'\n", " \n", " disk=','.join(disk_dev)\n", " nic=','.join(nic_dev)\n", "\n", - " command =' '.join(['bash', run_script, '--ts', ts, '--base-dir', self.base_dir, '--name', name, '--appid', self.appid, '--disk', disk, '--nic', nic, '--tz', convert_to_etc_gmt()])\n", + " command =' '.join(['bash', run_script, '--base-dir', self.base_dir, '--name', self.app_name, '--appid', self.appid, '--disk', disk, '--nic', nic, '--tz', convert_to_etc_gmt(), '--proxy', proxy if proxy != '' else \"''\", '--emails', ','.join(emails) if emails else \"''\"])\n", + " \n", + " if self.run_gluten:\n", + " if self.workload == 'tpch':\n", + " comp_file = os.path.join(cwd, self.RECORDS_GLUTEN_TPCH)\n", + " baseline_file = os.path.join(cwd, self.RECORDS_SPARK_TPCH)\n", + " else:\n", + " comp_file = os.path.join(cwd, self.RECORDS_GLUTEN_TPCDS)\n", + " baseline_file = os.path.join(cwd, self.RECORDS_SPARK_TPCDS)\n", + " comp_appid, comp_base_dir, comp_name = get_last_run(comp_file, self.appid)\n", + " if comp_appid:\n", + " command += ' '.join(['', '--comp-appid', comp_appid, '--comp-base-dir', comp_base_dir, '--comp-name', comp_name])\n", + " baseline_appid, baseline_base_dir, _ = get_last_run(baseline_file, '')\n", + " if baseline_appid:\n", + " command += ' '.join(['', '--baseline-appid', baseline_appid, '--baseline-base-dir', baseline_base_dir])\n", " print(command)\n", "\n", " # Block if running on local cluster.\n", @@ -830,7 +924,7 @@ " else:\n", " !ssh {self.server} \"{command} > /dev/null 2>&1 &\"\n", "\n", - " self.perf_html=f'http://{self.server}:8888/view/{self.base_dir}/html/{ts}_{name}_{self.appid}.html'\n", + " self.perf_html=f'http://{self.server}:8889/view/{self.base_dir}/html/{self.app_name}_{self.appid}.html'\n", " display(HTML(f'{self.perf_html}'))\n", " \n", " def load_table(self, table):\n", @@ -869,6 +963,7 @@ " display(HTML(('Completed Query. Time(sec): {:f}'.format(duration))))\n", " \n", " self.result[query] = duration\n", + " self.duration += float(duration)\n", " if print_result:\n", " print(collect)\n", "\n", @@ -881,18 +976,15 @@ " def print_result(self):\n", " print(self.result)\n", " print()\n", - " durations = [float(i) for i in self.result.values()]\n", - " print(\"total duration:\")\n", - " print(sum(durations))\n", - " print()\n", + " print(f\"total duration:\\n{self.duration}\\n\")\n", " if self.server:\n", " print(self.finished_nb)\n", " print(f\"http://{self.server}:1088/tracing_examples/trace_viewer.html#/tracing/test_data/{self.appid}.json\")\n", " print(f\"http://{self.server}:18080/history/{self.appid}\")\n", " print(self.perf_html)\n", " print(self.appid)\n", - " for i in durations:\n", - " print(i)\n", + " for t in self.result.values():\n", + " print(t)\n", " \n", "class TestTPCH(TestTPC):\n", " tpctables = ['customer', 'lineitem', 'nation', 'orders', 'part', 'partsupp', 'region', 'supplier']\n", @@ -998,7 +1090,7 @@ " if run_gluten:\n", " offheap_ratio = gluten_offheap_ratio\n", " else:\n", - " offheap_ratio = vanilla_offheap_ratio\n", + " offheap_ratio = spark_offheap_ratio\n", " driver_memory = convert_to_bytes('20g')\n", " executor_memory_overhead = convert_to_bytes('1g')\n", " \n", @@ -1126,7 +1218,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Vanilla Spark" + "## Spark" ] }, { @@ -1135,10 +1227,10 @@ "metadata": {}, "outputs": [], "source": [ - "def vanilla_tpch_conf_overwrite(conf):\n", + "def spark_tpch_conf_overwrite(conf):\n", " return conf\n", "\n", - "def vanilla_tpcds_conf_overwrite(conf):\n", + "def spark_tpcds_conf_overwrite(conf):\n", " conf.set('spark.sql.optimizer.runtime.bloomFilter.applicationSideScanSizeThreshold', '0')\\\n", " .set('spark.sql.optimizer.runtime.bloomFilter.enabled', 'true')\n", " return conf" @@ -1150,7 +1242,7 @@ "metadata": {}, "outputs": [], "source": [ - "def create_cntx_vanilla(executors_per_node, cores_per_executor, task_per_core, memory_per_node, extra_jars, app_name='', master='yarn', conf_overwrite=None):\n", + "def create_cntx_spark(executors_per_node, cores_per_executor, task_per_core, memory_per_node, extra_jars, app_name='', master='yarn', conf_overwrite=None):\n", " conf = default_conf(executors_per_node, cores_per_executor, task_per_core, memory_per_node, extra_jars, app_name, master, run_gluten=False)\n", " conf.set(\"spark.sql.execution.arrow.maxRecordsPerBatch\",20480)\\\n", " .set(\"spark.sql.parquet.columnarReaderBatchSize\",20480)\\\n", @@ -1229,12 +1321,12 @@ "\n", " if workload.lower() == 'tpch':\n", " if not app_name:\n", - " app_name = 'tpch_power'\n", + " app_name = f\"tpch_spark{''.join(spark_version.split('.'))}\"\n", " tabledir = tpch_tabledir\n", " is_tpch_workload=True\n", " elif workload.lower() == 'tpcds':\n", " if not app_name:\n", - " app_name = 'tpcds_power'\n", + " app_name = f\"tpcds_spark{''.join(spark_version.split('.'))}\"\n", " tabledir = tpcds_tabledir\n", " is_tpcds_workload=True\n", " else:\n", @@ -1276,14 +1368,14 @@ " task_per_core = gluten_tpcds_task_per_core\n", " workload_conf_overwrite = gluten_tpcds_conf_overwrite\n", " else:\n", - " app_name = ' '.join(['vanilla', app_name, lastgit[:6]])\n", - " create_cntx_func=create_cntx_vanilla\n", + " app_name = ' '.join(['spark', app_name, lastgit[:6]])\n", + " create_cntx_func=create_cntx_spark\n", " if is_tpch_workload:\n", - " task_per_core = vanilla_tpch_task_per_core\n", - " workload_conf_overwrite = vanilla_tpch_conf_overwrite\n", + " task_per_core = spark_tpch_task_per_core\n", + " workload_conf_overwrite = spark_tpch_conf_overwrite\n", " elif is_tpcds_workload:\n", - " task_per_core = vanilla_tpcds_task_per_core\n", - " workload_conf_overwrite = vanilla_tpcds_conf_overwrite\n", + " task_per_core = spark_tpcds_task_per_core\n", + " workload_conf_overwrite = spark_tpcds_conf_overwrite\n", " \n", " conf_overwrite = lambda conf: app_conf_overwrite(workload_conf_overwrite(conf))\n", " \n", diff --git a/tools/workload/benchmark_velox/params.yaml.template b/tools/workload/benchmark_velox/params.yaml.template index 1c70e428bc99..73e02b728f7b 100644 --- a/tools/workload/benchmark_velox/params.yaml.template +++ b/tools/workload/benchmark_velox/params.yaml.template @@ -20,22 +20,10 @@ disk_dev: nic_dev: - ens787f0 -# Hostname or IP to server for perf analysis. Able to connect via ssh. -server: '' - -# Specify the directory on perf analysis server. Usually a codename for this run. -base_dir: emr - -# Proxy used to connect to server for perf analysis. -proxy: '' - -# Whether to upload profile to perf analysis server and run perf analysis scripts. Only takes effect if server is set. -analyze_perf: True - # Select workload. Can be either 'tpch' or 'tpcds'. workload: tpch -# Run with gluten. If False, run vanilla Spark. +# Run with gluten. If False, run Spark. run_gluten: True # TPC tables @@ -48,20 +36,20 @@ cores_per_executor: 8 gluten_tpch_task_per_core: 2 gluten_tpcds_task_per_core: 2 -vanilla_tpch_task_per_core: 4 -vanilla_tpcds_task_per_core: 4 +spark_tpch_task_per_core: 4 +spark_tpcds_task_per_core: 4 # Physical memory on each worker node. memory_per_node: 1000g -# Offheap ratio. 0 to disable offheap for vanilla Spark. +# Offheap ratio. 0 to disable offheap for Spark. # onheap:offheap = 1:2 -vanilla_offheap_ratio: 2.0 +spark_offheap_ratio: 2.0 # onheap:offheap = 1:7 gluten_offheap_ratio: 7.0 # spark.io.compression.codec -vanilla_codec: lz4 +spark_codec: lz4 # spark.gluten.sql.columnar.shuffle.codec gluten_codec: lz4 # spark.gluten.sql.columnar.shuffle.codecBackend @@ -69,3 +57,22 @@ gluten_codec_backend: '' # spark.gluten.sql.columnar.maxBatchSize max_batch_size: 4096 +# Hostname or IP to server for perf analysis. Able to connect via ssh. +server: '' + +# Specify the directory on perf analysis server. Usually a codename for this run. +base_dir: test + +# Proxy used to connect to server for perf analysis. +proxy: '' + +# Emon event file for `emon -i`. Set to emptry string '' if emon is unavailable. +# Supported emon events on platform can be verified via `emon -i emon.list` +emon_list: /home/sparkuser/ipython/emon.list + +# Whether to run perf analysis scripts. Only takes effect if server is set. +analyze_perf: True + +# List of email to receive perf analysis results. +emails: + - diff --git a/tools/workload/benchmark_velox/sample/Trace-viewer.png b/tools/workload/benchmark_velox/sample/Trace-viewer.png new file mode 100644 index 000000000000..eef24863c918 Binary files /dev/null and b/tools/workload/benchmark_velox/sample/Trace-viewer.png differ diff --git a/tools/workload/benchmark_velox/sample/tpch_q1.html b/tools/workload/benchmark_velox/sample/tpch_q1.html new file mode 100644 index 000000000000..c401c35ec87c --- /dev/null +++ b/tools/workload/benchmark_velox/sample/tpch_q1.html @@ -0,0 +1,16401 @@ + + + + + +2024_12_06_055328_tpch_gluten_application_1733153225851_0048.nbconvert + + + + + + + + + + +
+
+
+
+
+

Parameters

+
+
+
+
+
+
+
+
+
+

start analysis cluster and run

+
+
+
+
+
+
+
+
+
+
+
+
+
Setting default log level to "WARN".
+To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
+
+
+
+
+
+
24/12/06 05:53:36 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
+
+
+
+
+
+
24/12/06 05:53:37 WARN DomainSocketFactory: The short-circuit local reads feature cannot be used because libhadoop cannot be loaded.
+24/12/06 05:53:37 WARN Client: Neither spark.yarn.jars nor spark.yarn.archive is set, falling back to uploading libraries under SPARK_HOME.
+
+
+
+
+
+
/home/sparkuser/spark/python/pyspark/sql/context.py:112: FutureWarning: Deprecated in 3.0.0. Use SparkSession.builder.getOrCreate() instead.
+  warnings.warn(
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Sparklog

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Content

+
+
+
+ +
+
+

Self app info

+
+
+
+
+
+
+
+
+
+
+
load data  /sr213/application_1733153225851_0048/app.log
+
+
+
+
+
+
[Stage 0:>                                                          (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 1:>                                                          (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 4:>                                                          (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 5:>                                                          (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 17:>                                                         (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 39:>                                                      (0 + 16) / 200]

[Stage 39:=>                                                     (6 + 16) / 200]
+
+
+
+
+
[Stage 39:===>                                                  (14 + 16) / 200]
+
+
+
+
+
[Stage 39:========>                                             (33 + 16) / 200]

[Stage 39:==================>                                   (67 + 16) / 200]
+
+
+
+
+
[Stage 39:==========================>                           (97 + 16) / 200]

[Stage 39:==================================>                  (131 + 16) / 200]
+
+
+
+
+
[Stage 39:=================================================>   (185 + 15) / 200]

                                                                                
+
+
+ +
+
+
[Stage 42:(177 + 5) / 200][Stage 43:>   (0 + 1) / 1][Stage 44:>(0 + 11) / 200]

                                                                                
+
+
+
+
+
[Stage 44:(113 + 12) / 200][Stage 45:>   (0 + 1) / 1][Stage 46:> (0 + 3) / 200]

[Stage 44:(182 + 5) / 200][Stage 46:>(4 + 11) / 200][Stage 47:> (0 + 0) / 200]
+
+
+
+
+
[Stage 46:(43 + 16) / 200][Stage 47:> (0 + 0) / 200][Stage 48:> (0 + 0) / 200]

[Stage 46:(110 + 8) / 200][Stage 47:> (0 + 8) / 200][Stage 48:> (0 + 0) / 200]
+
+
+
+
+
[Stage 46:(155 + 8) / 200][Stage 47:>(47 + 8) / 200][Stage 48:> (0 + 0) / 200]

[Stage 46:(194 + 4) / 200][Stage 47:>(73 + 4) / 200][Stage 48:> (8 + 8) / 200]
+
+
+
+
+
[Stage 47:(114 + 8) / 200][Stage 48:>(57 + 4) / 200][Stage 49:>  (0 + 4) / 16]

[Stage 47:(185 + 4) / 200][Stage 48:>(73 + 4) / 200][Stage 49:>  (0 + 8) / 16]
+
+
+
+
+
[Stage 48:(126 + 8) / 200][Stage 49:>  (0 + 8) / 16][Stage 51:>   (0 + 0) / 1]

[Stage 48:(184 + 4) / 200][Stage 49:> (4 + 12) / 16][Stage 51:>   (0 + 0) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
appidapplication_1733153225851_0048
executor.instances4
executor.cores4
shuffle.partitions32
batch size4,096
real executors4
Failed Tasks
Speculative Tasks0
Speculative Killed Tasks0
Speculative Stage0
runtime17.65
disk spilled0.0
memspilled0.0
local_read0.0
remote_read0.0
shuffle_write0.0
task run time6.79
ser_time0.0
f_wait_time0.0
gc_time0.03
input read22.54
acc_task_time13.99
file read size5,951.35
file write size24.52
disk read size5.05
disk write size15.31
disk cancel size0.0
+
+
+
+
+
{'appid': 'application_1733153225851_0048',
+ 'executor.instances': 4,
+ 'executor.cores': 4,
+ 'shuffle.partitions': 32,
+ 'batch size': 4096,
+ 'real executors': 4,
+ 'Failed Tasks': '',
+ 'Speculative Tasks': 0,
+ 'Speculative Killed Tasks': 0,
+ 'Speculative Stage': 0,
+ 'runtime': 17.65,
+ 'disk spilled': 0.0,
+ 'memspilled': 0.0,
+ 'local_read': 0.0,
+ 'remote_read': 0.0,
+ 'shuffle_write': 0.0,
+ 'task run time': 6.79,
+ 'ser_time': 0.0,
+ 'f_wait_time': 0.0,
+ 'gc_time': 0.03,
+ 'input read': 22.54,
+ 'acc_task_time': 13.99,
+ 'file read size': 5951.35,
+ 'file write size': 24.52,
+ 'disk read size': 5.05,
+ 'disk write size': 15.31,
+ 'disk cancel size': 0.0}
+
+
+
+
+
+
+
+
+
+
+
[Stage 92:(161 + 4) / 200][Stage 93:>(68 + 9) / 200][Stage 94:> (8 + 4) / 200]

[Stage 93:(151 + 4) / 200][Stage 94:>(66 + 8) / 200][Stage 95:>  (1 + 4) / 16]
+
+
+
+
+
                                                                                
+
+
+
+
+
/sr213/application_1733153225851_0048/sr217/emon.parquet is not found, trying to load data ...
+
+
+
+
+
+
[Stage 129:>                (0 + 2) / 2][Stage 130:>                (0 + 2) / 2]

[Stage 129:>  (0 + 2) / 2][Stage 130:>  (0 + 2) / 2][Stage 131:>  (0 + 4) / 4]
+
+
+
+
+
[Stage 129:=> (1 + 1) / 2][Stage 130:=> (1 + 1) / 2][Stage 131:>  (1 + 3) / 4]

[Stage 129:========>        (1 + 1) / 2][Stage 131:====>            (1 + 3) / 4]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 143:==>                                                  (16 + 16) / 400]

[Stage 143:==>                                                  (17 + 16) / 400]
+
+
+
+
+
[Stage 143:===>                                                 (24 + 16) / 400]

[Stage 143:====>                                                (34 + 16) / 400]
+
+
+
+
+
[Stage 143:=====>                                               (43 + 16) / 400]

[Stage 143:=======>                                             (53 + 16) / 400]
+
+
+
+
+
[Stage 143:========>                                            (65 + 16) / 400]

[Stage 143:=========>                                           (72 + 16) / 400]
+
+
+
+
+
[Stage 143:==========>                                          (83 + 16) / 400]

[Stage 143:===========>                                         (90 + 16) / 400]
+
+
+
+
+
[Stage 143:=============>                                       (99 + 16) / 400]

[Stage 143:=============>                                      (106 + 16) / 400]
+
+
+
+
+
[Stage 143:==============>                                     (113 + 16) / 400]

[Stage 143:===============>                                    (118 + 16) / 400]
+
+
+
+
+
[Stage 143:================>                                   (126 + 16) / 400]

[Stage 143:=================>                                  (132 + 16) / 400]
+
+
+
+
+
[Stage 143:==================>                                 (140 + 16) / 400]

[Stage 143:==================>                                 (146 + 16) / 400]
+
+
+
+
+
[Stage 143:===================>                                (153 + 16) / 400]

[Stage 143:====================>                               (160 + 16) / 400]
+
+
+
+
+
[Stage 143:======================>                             (170 + 16) / 400]

[Stage 143:======================>                             (173 + 16) / 400]
+
+
+
+
+
[Stage 143:=======================>                            (182 + 16) / 400]

[Stage 143:========================>                           (186 + 16) / 400]
+
+
+
+
+
[Stage 143:=========================>                          (194 + 16) / 400]

[Stage 143:=========================>                          (197 + 16) / 400]
+
+
+
+
+
[Stage 143:==========================>                         (204 + 16) / 400]

[Stage 143:===========================>                        (211 + 16) / 400]
+
+
+
+
+
[Stage 143:===========================>                        (214 + 16) / 400]

[Stage 143:============================>                       (222 + 16) / 400]
+
+
+
+
+
[Stage 143:=============================>                      (230 + 16) / 400]

[Stage 143:==============================>                     (236 + 16) / 400]
+
+
+
+
+
[Stage 143:===============================>                    (243 + 16) / 400]

[Stage 143:================================>                   (249 + 16) / 400]
+
+
+
+
+
[Stage 143:=================================>                  (256 + 16) / 400]

[Stage 143:==================================>                 (263 + 16) / 400]
+
+
+
+
+
[Stage 143:===================================>                (272 + 16) / 400]

[Stage 143:====================================>               (279 + 16) / 400]
+
+
+
+
+
[Stage 143:======================================>             (294 + 16) / 400]

[Stage 143:======================================>             (299 + 16) / 400]
+
+
+
+
+
[Stage 143:========================================>           (311 + 16) / 400]

[Stage 143:=========================================>          (322 + 16) / 400]
+
+
+
+
+
[Stage 143:===========================================>        (333 + 17) / 400]

[Stage 143:=============================================>      (348 + 16) / 400]
+
+
+
+
+
[Stage 143:==============================================>     (360 + 16) / 400]

[Stage 143:================================================>   (372 + 16) / 400]
+
+
+
+
+
[Stage 143:==================================================> (386 + 14) / 400]
+
+
+
+
+
[Stage 148:>                                                        (0 + 1) / 1]
+
+
+
+
+
[Stage 154:>                                                        (0 + 3) / 3]
+
+
+
+
+
[Stage 154:===================>                                     (1 + 2) / 3]

[Stage 154:======================================>                  (2 + 1) / 3]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 157:>                                                        (0 + 3) / 3]

[Stage 157:===================>                                     (1 + 2) / 3]
+
+
+
+
+
[Stage 157:======================================>                  (2 + 1) / 3]

                                                                                
+
+
+
+
+
sar metric
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 application_1733153225851_0048
runtime17.650000
disk spilled0.000000
shuffle_write0.000000
f_wait_time0.000000
input read22.540000
acc_task_time13.990000
output rows1.180000
%user>90%0.931034
%kernel>10%0.965517
%iowait>10%0.620690
avg %user41.216207
avg %system4.514138
avg %iowait0.743793
avg disk util32.206897
time more than 90%0.000000
total read (G)5.388613
total write (G)1.121773
avg read bw (MB/s)190.273771
avg write bw (MB/s)39.610183
read bw %75411.578125
read bw %95484.542969
read bw max510.351562
time_rd_morethan_950.034483
write bw %751.074219
write bw %95165.687500
write bw max812.511719
time_wr_morethan_950.034483
cached mean93.896552
cached 75%145.000000
cached max188.000000
used mean834.000000
used 75%852.000000
used max859.000000
rx MB/s 75%0.000000
rx MB/s 95%0.000000
rx MB/s 99%0.000000
pgin mean190.206897
pgin 75%412.000000
pgin max509.000000
pgout mean40.965517
pgout 75%1.000000
pgout max840.000000
fault mean117653.310345
fault 75%205151.000000
fault max256538.000000
cpu%_avg0.448817
cpu freq_avg3241.915617
pathlength_sum1933.000000
ipc_avg1.137983
+
+
+
+
+
+
+
+
+
+
+
[Stage 330:>                                                        (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 341:>                                                        (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
DEV in ('nvme0n1')
+
+
+
+
+
+
[Stage 388:>                                                        (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 396:>                                                        (0 + 1) / 1]
+
+
+
+
+
                                                                                
+
+
+
+
+
{'sr217': 200}
+
+
+
+
+
[Stage 490:===================>                                     (1 + 2) / 3]

                                                                                
+
+
+ +
+
+
+
+
+
+
+
gluten tpch_power 6600a1
+
+
+
+
+
+
+
+
+
+
[Stage 605:==>                                                   (11 + 0) / 200]

[Stage 531:(174 + 16) / 200][Stage 532:>(0 + 0) / 200][Stage 533:>(0 + 0) / 200]
+
+
+
+
+
[Stage 532:(102 + 16) / 200][Stage 533:>(0 + 0) / 200][Stage 534:>(0 + 0) / 200]

[Stage 533:(72 + 16) / 200][Stage 534:>(0 + 0) / 200][Stage 535:>(0 + 0) / 200]
+
+
+
+
+
[Stage 534:(63 + 16) / 200][Stage 535:>(0 + 0) / 200][Stage 536:>(0 + 0) / 200]

[Stage 535:(75 + 16) / 200][Stage 536:>(0 + 0) / 200][Stage 537:>(0 + 0) / 200]
+
+
+
+
+
[Stage 536:(102 + 17) / 200][Stage 537:>(0 + 0) / 200][Stage 538:>(3 + 0) / 200]

[Stage 537:(114 + 16) / 200][Stage 538:>(3 + 0) / 200][Stage 539:>(0 + 0) / 200]
+
+
+
+
+
[Stage 538:(105 + 16) / 200][Stage 539:>(0 + 0) / 200][Stage 540:>(0 + 0) / 200]

[Stage 539:(67 + 16) / 200][Stage 540:>(0 + 0) / 200][Stage 541:>(0 + 0) / 200]
+
+
+
+
+
[Stage 540:(59 + 16) / 200][Stage 541:>(0 + 0) / 200][Stage 542:>(0 + 0) / 200]

[Stage 541:(104 + 16) / 200][Stage 542:>(0 + 0) / 200][Stage 543:>(0 + 0) / 200]
+
+
+
+
+
[Stage 542:(115 + 16) / 200][Stage 543:>(0 + 0) / 200][Stage 544:>(0 + 0) / 200]

[Stage 543:(148 + 16) / 200][Stage 544:>(0 + 0) / 200][Stage 545:>(0 + 0) / 200]
+
+
+
+
+
[Stage 545:(0 + 16) / 200][Stage 546:>(0 + 0) / 200][Stage 547:>(0 + 0) / 200]

[Stage 546:(38 + 16) / 200][Stage 547:>(0 + 0) / 200][Stage 548:>(0 + 0) / 200]
+
+
+
+
+
[Stage 547:(58 + 17) / 200][Stage 548:>(0 + 0) / 200][Stage 549:>(0 + 0) / 200]

[Stage 548:(94 + 16) / 200][Stage 549:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+
+
+
+
[Stage 549:(113 + 17) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]

[Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+
+
+
+
[Stage 551:(16 + 1) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]

[Stage 551:(179 + 16) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]
+
+
+
+
+
[Stage 553:(16 + 0) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]

[Stage 553:(54 + 17) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]
+
+
+
+
+
[Stage 555:>(8 + 8) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]

[Stage 555:(16 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+
+
+
+
[Stage 555:(199 + 1) / 200][Stage 557:(0 + 15) / 200][Stage 559:>(0 + 0) / 200]

[Stage 557:(16 + 0) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]
+
+
+
+
+
[Stage 557:(84 + 16) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]

[Stage 559:(16 + 0) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]
+
+
+
+
+
[Stage 559:(29 + 16) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]

[Stage 560:(85 + 16) / 200][Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200]
+
+
+
+
+
[Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]
+
+
+
+
+
[Stage 564:(16 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]
+
+
+
+
+
[Stage 564:(149 + 16) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]

[Stage 566:(16 + 0) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]
+
+
+
+
+
[Stage 566:(71 + 16) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]

[Stage 568:(16 + 0) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]
+
+
+
+
+
[Stage 568:(16 + 2) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]

[Stage 569:(42 + 18) / 200][Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200]
+
+
+
+
+
[Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
+
+
+
+
[Stage 573:(0 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]

[Stage 573:(16 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
+
+
+
+
[Stage 573:(67 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]

[Stage 575:(16 + 0) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]
+
+
+
+
+
[Stage 575:(144 + 16) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]

[Stage 577:(16 + 0) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]
+
+
+
+
+
[Stage 577:(184 + 16) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]

[Stage 578:(197 + 3) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]
+
+
+
+
+
[Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]

[Stage 580:(58 + 16) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]
+
+
+
+
+
[Stage 580:(176 + 17) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]

[Stage 581:(195 + 5) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
+
+
+
+
[Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]

[Stage 583:(69 + 17) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
+
+
+
+
[Stage 583:(170 + 16) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]

[Stage 585:(16 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]
+
+
+
+
+
[Stage 585:(75 + 16) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]
+
+
+
+
+
[Stage 587:(16 + 0) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]
+
+
+
+
+
[Stage 587:(16 + 6) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]

[Stage 589:>(8 + 8) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]
+
+
+
+
+
[Stage 589:(16 + 0) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]
+
+
+
+
+
[Stage 589:(182 + 17) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]

[Stage 591:(16 + 0) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]
+
+
+
+
+
[Stage 591:(133 + 17) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]

[Stage 593:(16 + 0) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]
+
+
+
+
+
[Stage 593:(39 + 18) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]

[Stage 595:(16 + 0) / 200][Stage 597:>(0 + 0) / 200][Stage 599:>(0 + 0) / 200]
+
+
+
+
+
[Stage 597:(16 + 0) / 200][Stage 599:>(0 + 0) / 200][Stage 600:>(0 + 0) / 200]
+
+
+
+
+
[Stage 599:(0 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]

[Stage 599:(16 + 0) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]
+
+
+
+
+
[Stage 599:(169 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]

[Stage 605:==>                                                   (11 + 0) / 200]
+
+
+
+
+
[Stage 602:======>     (102 + 18) / 200][Stage 605:>             (11 + 0) / 200]

[Stage 605:==>                                                  (11 + 16) / 200]
+
+
+
+
+
[Stage 606:============================================>       (170 + 16) / 200]
+
+
+
+
+
[Stage 607:===================================>                (135 + 16) / 200]
+
+
+
+
+
                                                                                
+
+
+
+
+
[Stage 932:====================================================>(197 + 3) / 200]

                                                                                
+
+
+
+
+
+
+
+
+
+
application_1733153225851_0048
+
+ +
+
query time
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 runtimedisk spilledmemspilledlocal_readremote_readshuffle_writedeser_timerun_timeser_timef_wait_timegc_timepeak_memqueryidinput readacc_task_timestagesoutput rowsexecutorscore/exectask.cpusparallelism
real_queryid                     
117.6500000.0000000.0000000.0000000.0000000.0000000.2000006.7900000.0000000.0000000.0300001.340000822.54000013.990000[ 8 10 12 15]1.18000044132
+
+
+
+
operator count
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 01
AQEShuffleRead02
AdaptiveSparkPlan01
ColumnarExchange02
FilterExecTransformer01
FlushableHashAggregateExecTransformer01
InputAdapter02
InputIteratorTransformer02
ProjectExecTransformer02
RegularHashAggregateExecTransformer01
Scan parquet 01
ShuffleQueryStage02
SortExecTransformer01
VeloxColumnarToRow01
VeloxResizeBatches02
+
+
+
+
operator input row count
+
+
+
+ + + + + + + + + + + + + + + + + +
 1
ColumnarExchange0.000000
VeloxResizeBatches0.000000
+
+
+
+
operator output row count
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 1
ColumnarExchange0.000000
FlushableHashAggregateExecTransformer0.000000
InputIteratorTransformer0.000000
ProjectExecTransformer591.600000
RegularHashAggregateExecTransformer0.000000
Scan parquet 591.600000
SortExecTransformer0.000000
VeloxColumnarToRow0.000000
VeloxResizeBatches0.000000
+
+
+
+
+No description has been provided for this image +
+
+
+
+No description has been provided for this image +
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0
44%_time of scan and filter7.53
36%_time of project6.13
16%_not_counted2.69
3%_idle0.55
0%_time of input iterator0.06
0%_time of aggregation0.03
0%_time to append / split batches0.00
0%_time of rowConstruction0.00
0%_time to split0.00
0%_time to deserialize0.00
0%_time of sort0.00
0%_time of extraction0.00
0%_shuffle write time0.00
0%_time to convert0.00
0%_time to compress0.00
0%_time to spill0.00
0%_time to decompress0.00
+
+
+
+
+No description has been provided for this image +
+
+
+
+
+
+
+

Compare to vanilla

+
+
+
+
+
+
+
+
+
load data  /sr213/application_1733153225851_0029/app.log
+
+
+
+
+
+
emon metric
+
+
+
+
+
+
[Stage 1319:>                                                       (0 + 3) / 3]
+
+
+
+
+
[Stage 1319:==================>                                     (1 + 2) / 3]

                                                                                
+
+
+
+
+
sar metric
+
+
+
+
+
+
time breakdown
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 application_1733153225851_0029application_1733153225851_0048diff
runtime132.1417.65648.67%
shuffle_write0.000.000.00%
f_wait_time0.000.000.00%
input read22.5422.540.00%
acc_task_time128.0113.99815.01%
output rows1.791.1851.69%
%user>90%0.990.935.91%
%kernel>10%0.990.972.85%
%iowait>10%0.310.62-49.30%
avg %user82.1141.2299.21%
avg %system6.104.5135.11%
avg %iowait0.170.74-76.60%
avg disk util7.1332.21-77.85%
time more than 90%0.000.000.00%
total read (G)5.245.39-2.75%
total write (G)0.021.12-97.81%
avg read bw (MB/s)37.52190.27-80.28%
avg write bw (MB/s)0.1839.61-99.55%
read bw %7559.27411.58-85.60%
read bw %95173.05484.54-64.29%
read bw max236.70510.35-53.62%
time_rd_morethan_950.050.0341.96%
write bw %750.071.07-93.45%
write bw %951.23165.69-99.25%
write bw max1.70812.51-99.79%
time_wr_morethan_950.000.03-100.00%
cached mean88.3393.90-5.93%
cached 75%132.00145.00-8.97%
cached max160.00188.00-14.89%
used mean2,060.73834.00147.09%
used 75%2,343.00852.00175.00%
used max2,346.00859.00173.11%
rx MB/s 75%0.000.000.00%
rx MB/s 95%0.000.000.00%
rx MB/s 99%0.000.000.00%
pgin mean37.37190.21-80.35%
pgin 75%59.00412.00-85.68%
pgin max352.00509.00-30.84%
pgout mean0.1340.97-99.68%
pgout 75%0.001.00-100.00%
pgout max2.00840.00-99.76%
fault mean952,586.87117,653.31709.66%
fault 75%1,426,717.00205,151.00595.45%
fault max2,628,392.00256,538.00924.56%
cpu%_avg0.880.4596.45%
cpu freq_avg3,460.223,241.926.73%
pathlength_sum17,960.001,933.00829.13%
ipc_avg1.271.1411.30%
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 runtimeshuffle_writef_wait_timeinput readacc_task_timeoutput rows
real_queryid      
1 +
132.14
+
17.65
+
648.67%
+
+
0.00
+
0.00
+
nan%
+
+
0.00
+
0.00
+
nan%
+
+
22.54
+
22.54
+
0.00%
+
+
128.01
+
13.99
+
815.01%
+
+
1.79
+
1.18
+
51.69%
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 sr217agg
0  
%user>90% +
0.99
+
0.93
+
5.91%
+
+
0.99
+
0.93
+
5.91%
+
%kernel>10% +
0.99
+
0.97
+
2.85%
+
+
0.99
+
0.97
+
2.85%
+
%iowait>10% +
0.31
+
0.62
+
-49.30%
+
+
0.31
+
0.62
+
-49.30%
+
avg %user +
82.11
+
41.22
+
99.21%
+
+
82.11
+
41.22
+
99.21%
+
avg %system +
6.10
+
4.51
+
35.11%
+
+
6.10
+
4.51
+
35.11%
+
avg %iowait +
0.17
+
0.74
+
-76.60%
+
+
0.17
+
0.74
+
-76.60%
+
avg disk util +
7.13
+
32.21
+
-77.85%
+
+
7.13
+
32.21
+
-77.85%
+
time more than 90% +
0.00
+
0.00
+
nan%
+
+
0.00
+
0.00
+
nan%
+
total read (G) +
5.24
+
5.39
+
-2.75%
+
+
5.24
+
5.39
+
-2.75%
+
total write (G) +
0.02
+
1.12
+
-97.81%
+
+
0.02
+
1.12
+
-97.81%
+
avg read bw (MB/s) +
37.52
+
190.27
+
-80.28%
+
+
37.52
+
190.27
+
-80.28%
+
avg write bw (MB/s) +
0.18
+
39.61
+
-99.55%
+
+
0.18
+
39.61
+
-99.55%
+
read bw %75 +
59.27
+
411.58
+
-85.60%
+
+
59.27
+
411.58
+
-85.60%
+
read bw %95 +
173.05
+
484.54
+
-64.29%
+
+
173.05
+
484.54
+
-64.29%
+
read bw max +
236.70
+
510.35
+
-53.62%
+
+
236.70
+
510.35
+
-53.62%
+
time_rd_morethan_95 +
0.05
+
0.03
+
41.96%
+
+
0.05
+
0.03
+
41.96%
+
write bw %75 +
0.07
+
1.07
+
-93.45%
+
+
0.07
+
1.07
+
-93.45%
+
write bw %95 +
1.23
+
165.69
+
-99.25%
+
+
1.23
+
165.69
+
-99.25%
+
write bw max +
1.70
+
812.51
+
-99.79%
+
+
1.70
+
812.51
+
-99.79%
+
time_wr_morethan_95 +
0.00
+
0.03
+
-100.00%
+
+
0.00
+
0.03
+
-100.00%
+
cached mean +
88.33
+
93.90
+
-5.93%
+
+
88.33
+
93.90
+
-5.93%
+
cached 75% +
132.00
+
145.00
+
-8.97%
+
+
132.00
+
145.00
+
-8.97%
+
cached max +
160.00
+
188.00
+
-14.89%
+
+
160.00
+
188.00
+
-14.89%
+
used mean +
2,060.73
+
834.00
+
147.09%
+
+
2,060.73
+
834.00
+
147.09%
+
used 75% +
2,343.00
+
852.00
+
175.00%
+
+
2,343.00
+
852.00
+
175.00%
+
used max +
2,346.00
+
859.00
+
173.11%
+
+
2,346.00
+
859.00
+
173.11%
+
rx MB/s 75% +
0.00
+
0.00
+
nan%
+
+
0.00
+
0.00
+
nan%
+
rx MB/s 95% +
0.00
+
0.00
+
nan%
+
+
0.00
+
0.00
+
nan%
+
rx MB/s 99% +
0.00
+
0.00
+
nan%
+
+
0.00
+
0.00
+
nan%
+
pgin mean +
37.37
+
190.21
+
-80.35%
+
+
37.37
+
190.21
+
-80.35%
+
pgin 75% +
59.00
+
412.00
+
-85.68%
+
+
59.00
+
412.00
+
-85.68%
+
pgin max +
352.00
+
509.00
+
-30.84%
+
+
352.00
+
509.00
+
-30.84%
+
pgout mean +
0.13
+
40.97
+
-99.68%
+
+
0.13
+
40.97
+
-99.68%
+
pgout 75% +
0.00
+
1.00
+
-100.00%
+
+
0.00
+
1.00
+
-100.00%
+
pgout max +
2.00
+
840.00
+
-99.76%
+
+
2.00
+
840.00
+
-99.76%
+
fault mean +
952,586.87
+
117,653.31
+
709.66%
+
+
952,586.87
+
117,653.31
+
709.66%
+
fault 75% +
1,426,717.00
+
205,151.00
+
595.45%
+
+
1,426,717.00
+
205,151.00
+
595.45%
+
fault max +
2,628,392.00
+
256,538.00
+
924.56%
+
+
2,628,392.00
+
256,538.00
+
924.56%
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
clientsr217agg
cpu%_avg +
0.88
+
0.45
+
96.45%
+
+
0.88
+
0.45
+
96.45%
+
cpu freq_avg +
3,460.22
+
3,241.92
+
6.73%
+
+
3,460.22
+
3,241.92
+
6.73%
+
pathlength_sum +
17,960.00
+
1,933.00
+
829.13%
+
+
17,960.00
+
1,933.00
+
829.13%
+
ipc_avg +
1.27
+
1.14
+
11.30%
+
+
1.27
+
1.14
+
11.30%
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 indexStage IDJob IDreal_queryidqueryidtotal_timestdev_timeacc_totaltotal
008818127.981.9199.65%99.65%
11109180.29nan99.87%0.23%
221210180.09nan99.94%0.07%
331511180.07nan100.00%0.06%
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 indexStage IDJob IDreal_queryidqueryidtotal_timestdev_timeacc_totaltotal
00881813.860.3286.65%86.65%
111210180.98nan92.80%6.15%
22109180.74nan97.43%4.63%
331511180.41nan100.00%2.57%
+
+
+
+
+No description has been provided for this image +
+
+
+
+No description has been provided for this image +
+
+
+
+No description has been provided for this image +
+
+
+
+
+
+
+

Config compare

+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0851_00480851_0029comp
callSite.shortcollect at /tmp/ipykernel_265482/1936321720.py:117collect at /tmp/ipykernel_234307/1936321720.py:117False
spark.app.submitTime17334643016691733457038427False
spark.executor.extraClassPathfile:///data0/home/sparkuser/jars/6600a164407ae0e4f5ea5b33dc4b902f23a27730/gluten-velox-bundle-spark3.3_2.12-centos_7_x86_64-1.3.0-snapshot.jarFalse
spark.executor.extraJavaOptions-xx:+ignoreunrecognizedvmoptions --add-opens=java.base/java.lang=all-unnamed --add-opens=java.base/java.lang.invoke=all-unnamed --add-opens=java.base/java.lang.reflect=all-unnamed --add-opens=java.base/java.io=all-unnamed --add-opens=java.base/java.net=all-unnamed --add-opens=java.base/java.nio=all-unnamed --add-opens=java.base/java.util=all-unnamed --add-opens=java.base/java.util.concurrent=all-unnamed --add-opens=java.base/java.util.concurrent.atomic=all-unnamed --add-opens=java.base/sun.nio.ch=all-unnamed --add-opens=java.base/sun.nio.cs=all-unnamed --add-opens=java.base/sun.security.action=all-unnamed --add-opens=java.base/sun.util.calendar=all-unnamed --add-opens=java.security.jgss/sun.security.krb5=all-unnamed -xx:+useparalleloldgc -xx:parallelgcthreads=2 -xx:newratio=1 -xx:survivorratio=1 -xx:+usecompressedoops -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:errorfile=/home/sparkuser/logs/java/hs_err_pid%p.log-xx:+ignoreunrecognizedvmoptions --add-opens=java.base/java.lang=all-unnamed --add-opens=java.base/java.lang.invoke=all-unnamed --add-opens=java.base/java.lang.reflect=all-unnamed --add-opens=java.base/java.io=all-unnamed --add-opens=java.base/java.net=all-unnamed --add-opens=java.base/java.nio=all-unnamed --add-opens=java.base/java.util=all-unnamed --add-opens=java.base/java.util.concurrent=all-unnamed --add-opens=java.base/java.util.concurrent.atomic=all-unnamed --add-opens=java.base/sun.nio.ch=all-unnamed --add-opens=java.base/sun.nio.cs=all-unnamed --add-opens=java.base/sun.security.action=all-unnamed --add-opens=java.base/sun.util.calendar=all-unnamed --add-opens=java.security.jgss/sun.security.krb5=all-unnamed -xx:+useparalleloldgc -xx:parallelgcthreads=2 -xx:newratio=1 -xx:survivorratio=1 -xx:+usecompressedoops -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:errorfile=/data0/home/sparkuser/logs/java/hs_err_pid%p.logFalse
spark.executor.memory10944m29184mFalse
spark.gluten.memory.conservative.task.offHeap.size.in.bytes10041163776NaNFalse
spark.gluten.memory.dynamic.offHeap.sizing.enabledfalseNaNFalse
spark.gluten.memory.offHeap.size.in.bytes80329310208NaNFalse
spark.gluten.memory.overAcquiredMemoryRatio0NaNFalse
spark.gluten.memory.task.offHeap.size.in.bytes20082327552NaNFalse
spark.gluten.memoryOverhead.size.in.bytes1073741824NaNFalse
spark.gluten.numTaskSlotsPerExecutor4NaNFalse
spark.gluten.sql.columnar.backend.libveloxNaNFalse
spark.gluten.sql.columnar.coalesce.batchestrueNaNFalse
spark.gluten.sql.columnar.forceshuffledhashjointrueNaNFalse
spark.gluten.sql.columnar.maxBatchSize4096NaNFalse
spark.gluten.sql.columnar.shuffle.codeclz4NaNFalse
spark.gluten.sql.columnar.shuffle.codecBackendNaNFalse
spark.gluten.sql.session.timeZone.defaultetc/utcNaNFalse
spark.memory.offHeap.size8032931020858368mFalse
spark.pluginsorg.apache.gluten.glutenpluginNaNFalse
spark.repl.class.outputDir/tmp/tmpypqh85b0/tmp/tmpynceqaxdFalse
spark.repl.class.urispark://sr213:40521/classesspark://sr213:34951/classesFalse
spark.shuffle.managerorg.apache.spark.shuffle.sort.columnarshufflemanagerNaNFalse
spark.sql.adaptive.customCostEvaluatorClassorg.apache.spark.sql.execution.adaptive.glutencostevaluatorNaNFalse
spark.sql.extensionsorg.apache.gluten.extension.glutensessionextensionsNaNFalse
spark.sql.files.maxPartitionBytes4gNaNFalse
spark.sql.shuffle.partitions3264False
+
+
+
+
+
+
+
+

Convert to HTML

+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/tools/workload/benchmark_velox/sample/tpch_q1.nbconvert.ipynb b/tools/workload/benchmark_velox/sample/tpch_q1.nbconvert.ipynb new file mode 100644 index 000000000000..122f1c3c7dec --- /dev/null +++ b/tools/workload/benchmark_velox/sample/tpch_q1.nbconvert.ipynb @@ -0,0 +1,4984 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4371325d", + "metadata": { + "papermill": { + "duration": 0.003812, + "end_time": "2024-12-06T05:53:34.206544", + "exception": false, + "start_time": "2024-12-06T05:53:34.202732", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c61021c1", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:53:34.214595Z", + "iopub.status.busy": "2024-12-06T05:53:34.214315Z", + "iopub.status.idle": "2024-12-06T05:53:34.220494Z", + "shell.execute_reply": "2024-12-06T05:53:34.220105Z" + }, + "papermill": { + "duration": 0.011601, + "end_time": "2024-12-06T05:53:34.221688", + "exception": false, + "start_time": "2024-12-06T05:53:34.210087", + "status": "completed" + }, + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "appid=''\n", + "disk=''\n", + "nic=''\n", + "tz=''\n", + "base_dir=''\n", + "name=''\n", + "proxy=''\n", + "\n", + "comp_appid=''\n", + "comp_base_dir=''\n", + "comp_name=''" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "f4c7b29a", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:53:34.229763Z", + "iopub.status.busy": "2024-12-06T05:53:34.229436Z", + "iopub.status.idle": "2024-12-06T05:53:34.232162Z", + "shell.execute_reply": "2024-12-06T05:53:34.231769Z" + }, + "papermill": { + "duration": 0.008176, + "end_time": "2024-12-06T05:53:34.233387", + "exception": false, + "start_time": "2024-12-06T05:53:34.225211", + "status": "completed" + }, + "tags": [ + "injected-parameters" + ] + }, + "outputs": [], + "source": [ + "# Parameters\n", + "appid = \"application_1733153225851_0048\"\n", + "disk = \"nvme0n1\"\n", + "nic = \"enp61s0f0\"\n", + "tz = \"Etc/GMT+0\"\n", + "base_dir = \"sr213\"\n", + "name = \"tpch_gluten\"\n", + "comp_appid = \"application_1733153225851_0029\"\n", + "comp_base_dir = \"sr213\"\n", + "comp_name = \"vanilla\"\n", + "proxy = \"http://10.239.44.250:8080\"\n" + ] + }, + { + "cell_type": "markdown", + "id": "51887dbb", + "metadata": { + "papermill": { + "duration": 0.003585, + "end_time": "2024-12-06T05:53:34.240616", + "exception": false, + "start_time": "2024-12-06T05:53:34.237031", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# start analysis cluster and run" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "11b3e5f6", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:53:34.248767Z", + "iopub.status.busy": "2024-12-06T05:53:34.248529Z", + "iopub.status.idle": "2024-12-06T05:53:34.251294Z", + "shell.execute_reply": "2024-12-06T05:53:34.250897Z" + }, + "papermill": { + "duration": 0.008331, + "end_time": "2024-12-06T05:53:34.252497", + "exception": false, + "start_time": "2024-12-06T05:53:34.244166", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import findspark\n", + "findspark.init()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "58fa24f6", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:53:34.260508Z", + "iopub.status.busy": "2024-12-06T05:53:34.260287Z", + "iopub.status.idle": "2024-12-06T05:53:34.263142Z", + "shell.execute_reply": "2024-12-06T05:53:34.262754Z" + }, + "papermill": { + "duration": 0.008226, + "end_time": "2024-12-06T05:53:34.264308", + "exception": false, + "start_time": "2024-12-06T05:53:34.256082", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import os\n", + "def get_py4jzip():\n", + " spark_home=os.environ['SPARK_HOME']\n", + " py4jzip = !ls {spark_home}/python/lib/py4j*.zip\n", + " return py4jzip[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6608ae2f", + "metadata": { + "code_folding": [], + "execution": { + "iopub.execute_input": "2024-12-06T05:53:34.272550Z", + "iopub.status.busy": "2024-12-06T05:53:34.272222Z", + "iopub.status.idle": "2024-12-06T05:54:05.226922Z", + "shell.execute_reply": "2024-12-06T05:54:05.226384Z" + }, + "papermill": { + "duration": 30.960697, + "end_time": "2024-12-06T05:54:05.228547", + "exception": false, + "start_time": "2024-12-06T05:53:34.267850", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Setting default log level to \"WARN\".\n", + "To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "24/12/06 05:53:36 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "24/12/06 05:53:37 WARN DomainSocketFactory: The short-circuit local reads feature cannot be used because libhadoop cannot be loaded.\n", + "24/12/06 05:53:37 WARN Client: Neither spark.yarn.jars nor spark.yarn.archive is set, falling back to uploading libraries under SPARK_HOME.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/sparkuser/spark/python/pyspark/sql/context.py:112: FutureWarning: Deprecated in 3.0.0. Use SparkSession.builder.getOrCreate() instead.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "from pyspark import SparkConf, SparkContext\n", + "from pyspark.sql import SQLContext\n", + "import time\n", + "import sys\n", + "conf = (SparkConf()\n", + " .set('spark.app.name', f'perf_analysis_{appid}')\n", + " .set('spark.serializer','org.apache.spark.serializer.KryoSerializer')\n", + " .set('spark.executor.instances', '4')\n", + " .set('spark.executor.cores','4')\n", + " .set('spark.executor.memory', '8g')\n", + " .set('spark.driver.memory','20g')\n", + " .set('spark.memory.offHeap.enabled','True')\n", + " .set('spark.memory.offHeap.size','20g')\n", + " .set('spark.executor.memoryOverhead','1g')\n", + " .set('spark.executor.extraJavaOptions',\n", + " '-XX:+UseParallelGC -XX:+UseParallelOldGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps')\n", + " .set('spark.executorEnv.PYTHONPATH',f\"{os.environ['SPARK_HOME']}/python:{get_py4jzip()}:{':'.join(sys.path)}\")\n", + " .set('spark.sql.inMemoryColumnarStorage.compressed','False')\n", + " .set('spark.sql.inMemoryColumnarStorage.batchSize','100000')\n", + " .set('spark.sql.execution.arrow.pyspark.fallback.enabled','True')\n", + " .set('spark.sql.execution.arrow.pyspark.enabled','True')\n", + " .set('spark.sql.execution.arrow.maxRecordsPerBatch','100000')\n", + " .set(\"spark.sql.repl.eagerEval.enabled\", True)\n", + " .set(\"spark.sql.legacy.timeParserPolicy\",\"LEGACY\") \n", + " .set(\"spark.sql.session.timeZone\", tz)\n", + " )\n", + "\n", + "sc = SparkContext(conf=conf,master='yarn')\n", + "sc.setLogLevel(\"ERROR\")\n", + "spark = SQLContext(sc)\n", + "time.sleep(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "beaceea2", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:05.237940Z", + "iopub.status.busy": "2024-12-06T05:54:05.237576Z", + "iopub.status.idle": "2024-12-06T05:54:05.243620Z", + "shell.execute_reply": "2024-12-06T05:54:05.243229Z" + }, + "papermill": { + "duration": 0.01213, + "end_time": "2024-12-06T05:54:05.244853", + "exception": false, + "start_time": "2024-12-06T05:54:05.232723", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "96ff6bfd", + "metadata": { + "papermill": { + "duration": 0.004098, + "end_time": "2024-12-06T05:54:05.253289", + "exception": false, + "start_time": "2024-12-06T05:54:05.249191", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Sparklog" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "96db8a10", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:05.287175Z", + "iopub.status.busy": "2024-12-06T05:54:05.286902Z", + "iopub.status.idle": "2024-12-06T05:54:07.652568Z", + "shell.execute_reply": "2024-12-06T05:54:07.652028Z" + }, + "papermill": { + "duration": 2.397178, + "end_time": "2024-12-06T05:54:07.654334", + "exception": false, + "start_time": "2024-12-06T05:54:05.257156", + "status": "completed" + }, + "scrolled": false, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%run ~/PAUS/sparklog.ipynb" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "f2087dbe", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:07.664430Z", + "iopub.status.busy": "2024-12-06T05:54:07.664039Z", + "iopub.status.idle": "2024-12-06T05:54:07.666809Z", + "shell.execute_reply": "2024-12-06T05:54:07.666368Z" + }, + "papermill": { + "duration": 0.009062, + "end_time": "2024-12-06T05:54:07.668029", + "exception": false, + "start_time": "2024-12-06T05:54:07.658967", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "os.environ[\"https_proxy\"] = proxy\n", + "os.environ[\"http_proxy\"] = proxy" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "df22c6c4", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:07.677489Z", + "iopub.status.busy": "2024-12-06T05:54:07.677198Z", + "iopub.status.idle": "2024-12-06T05:54:07.679618Z", + "shell.execute_reply": "2024-12-06T05:54:07.679199Z" + }, + "papermill": { + "duration": 0.008559, + "end_time": "2024-12-06T05:54:07.680791", + "exception": false, + "start_time": "2024-12-06T05:54:07.672232", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "emonmetric=['emon_cpuutil',\n", + " 'emon_cpufreq',\n", + " 'emon_instr_retired',\n", + " 'emon_ipc']" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "44921944", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:07.690327Z", + "iopub.status.busy": "2024-12-06T05:54:07.689959Z", + "iopub.status.idle": "2024-12-06T05:54:07.692308Z", + "shell.execute_reply": "2024-12-06T05:54:07.691898Z" + }, + "papermill": { + "duration": 0.008606, + "end_time": "2024-12-06T05:54:07.693519", + "exception": false, + "start_time": "2024-12-06T05:54:07.684913", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "e3b53125", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:07.702902Z", + "iopub.status.busy": "2024-12-06T05:54:07.702567Z", + "iopub.status.idle": "2024-12-06T05:54:07.705136Z", + "shell.execute_reply": "2024-12-06T05:54:07.704728Z" + }, + "papermill": { + "duration": 0.008666, + "end_time": "2024-12-06T05:54:07.706366", + "exception": false, + "start_time": "2024-12-06T05:54:07.697700", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "disk_prefix=[f\"'{dev}'\" for dev in disk.split(',')]\n", + "nic_prefix=[f\"'{dev}'\" for dev in nic.split(',')]" + ] + }, + { + "cell_type": "markdown", + "id": "04d5c054", + "metadata": { + "papermill": { + "duration": 0.00437, + "end_time": "2024-12-06T05:54:07.715026", + "exception": false, + "start_time": "2024-12-06T05:54:07.710656", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Content" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "004663b7", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:07.725014Z", + "iopub.status.busy": "2024-12-06T05:54:07.724613Z", + "iopub.status.idle": "2024-12-06T05:54:07.729656Z", + "shell.execute_reply": "2024-12-06T05:54:07.729270Z" + }, + "papermill": { + "duration": 0.011505, + "end_time": "2024-12-06T05:54:07.730819", + "exception": false, + "start_time": "2024-12-06T05:54:07.719314", + "status": "completed" + }, + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + " 5 Self app info" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " 6 Compare to vanilla" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " 7 Config compare" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(HTML(' 5 Self app info'))\n", + "display(HTML(f\" 6 Compare to {comp_name}\"))\n", + "display(HTML(' 7 Config compare'))" + ] + }, + { + "cell_type": "markdown", + "id": "64cbb5ba", + "metadata": { + "papermill": { + "duration": 0.004589, + "end_time": "2024-12-06T05:54:07.739936", + "exception": false, + "start_time": "2024-12-06T05:54:07.735347", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Self app info" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "0c621763", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:07.749952Z", + "iopub.status.busy": "2024-12-06T05:54:07.749546Z", + "iopub.status.idle": "2024-12-06T05:54:07.832927Z", + "shell.execute_reply": "2024-12-06T05:54:07.832513Z" + }, + "papermill": { + "duration": 0.090016, + "end_time": "2024-12-06T05:54:07.834415", + "exception": false, + "start_time": "2024-12-06T05:54:07.744399", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "app=Application_Run(appid, basedir=base_dir)\n", + "appals=app.analysis['app']['als']" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0195d322", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:07.844603Z", + "iopub.status.busy": "2024-12-06T05:54:07.844367Z", + "iopub.status.idle": "2024-12-06T05:54:33.914699Z", + "shell.execute_reply": "2024-12-06T05:54:33.914257Z" + }, + "papermill": { + "duration": 26.07688, + "end_time": "2024-12-06T05:54:33.916079", + "exception": false, + "start_time": "2024-12-06T05:54:07.839199", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "load data /sr213/application_1733153225851_0048/app.log\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 0:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 1:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 4:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 5:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 17:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 39:> (0 + 16) / 200]\r", + "\r", + "[Stage 39:=> (6 + 16) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 39:===> (14 + 16) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 39:========> (33 + 16) / 200]\r", + "\r", + "[Stage 39:==================> (67 + 16) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 39:==========================> (97 + 16) / 200]\r", + "\r", + "[Stage 39:==================================> (131 + 16) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 39:=================================================> (185 + 15) / 200]\r", + "\r", + " \r" + ] + }, + { + "data": { + "text/html": [ + "http://sr213:18080/history/application_1733153225851_0048" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 42:(177 + 5) / 200][Stage 43:> (0 + 1) / 1][Stage 44:>(0 + 11) / 200]\r", + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 44:(113 + 12) / 200][Stage 45:> (0 + 1) / 1][Stage 46:> (0 + 3) / 200]\r", + "\r", + "[Stage 44:(182 + 5) / 200][Stage 46:>(4 + 11) / 200][Stage 47:> (0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 46:(43 + 16) / 200][Stage 47:> (0 + 0) / 200][Stage 48:> (0 + 0) / 200]\r", + "\r", + "[Stage 46:(110 + 8) / 200][Stage 47:> (0 + 8) / 200][Stage 48:> (0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 46:(155 + 8) / 200][Stage 47:>(47 + 8) / 200][Stage 48:> (0 + 0) / 200]\r", + "\r", + "[Stage 46:(194 + 4) / 200][Stage 47:>(73 + 4) / 200][Stage 48:> (8 + 8) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 47:(114 + 8) / 200][Stage 48:>(57 + 4) / 200][Stage 49:> (0 + 4) / 16]\r", + "\r", + "[Stage 47:(185 + 4) / 200][Stage 48:>(73 + 4) / 200][Stage 49:> (0 + 8) / 16]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 48:(126 + 8) / 200][Stage 49:> (0 + 8) / 16][Stage 51:> (0 + 0) / 1]\r", + "\r", + "[Stage 48:(184 + 4) / 200][Stage 49:> (4 + 12) / 16][Stage 51:> (0 + 0) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
appidapplication_1733153225851_0048
executor.instances4
executor.cores4
shuffle.partitions32
batch size4,096
real executors4
Failed Tasks
Speculative Tasks0
Speculative Killed Tasks0
Speculative Stage0
runtime17.65
disk spilled0.0
memspilled0.0
local_read0.0
remote_read0.0
shuffle_write0.0
task run time6.79
ser_time0.0
f_wait_time0.0
gc_time0.03
input read22.54
acc_task_time13.99
file read size5,951.35
file write size24.52
disk read size5.05
disk write size15.31
disk cancel size0.0
\n", + "\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "{'appid': 'application_1733153225851_0048',\n", + " 'executor.instances': 4,\n", + " 'executor.cores': 4,\n", + " 'shuffle.partitions': 32,\n", + " 'batch size': 4096,\n", + " 'real executors': 4,\n", + " 'Failed Tasks': '',\n", + " 'Speculative Tasks': 0,\n", + " 'Speculative Killed Tasks': 0,\n", + " 'Speculative Stage': 0,\n", + " 'runtime': 17.65,\n", + " 'disk spilled': 0.0,\n", + " 'memspilled': 0.0,\n", + " 'local_read': 0.0,\n", + " 'remote_read': 0.0,\n", + " 'shuffle_write': 0.0,\n", + " 'task run time': 6.79,\n", + " 'ser_time': 0.0,\n", + " 'f_wait_time': 0.0,\n", + " 'gc_time': 0.03,\n", + " 'input read': 22.54,\n", + " 'acc_task_time': 13.99,\n", + " 'file read size': 5951.35,\n", + " 'file write size': 24.52,\n", + " 'disk read size': 5.05,\n", + " 'disk write size': 15.31,\n", + " 'disk cancel size': 0.0}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "appals.get_basic_state()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "4be7e21a", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:54:33.929243Z", + "iopub.status.busy": "2024-12-06T05:54:33.928978Z", + "iopub.status.idle": "2024-12-06T05:55:12.939373Z", + "shell.execute_reply": "2024-12-06T05:55:12.938897Z" + }, + "papermill": { + "duration": 39.018383, + "end_time": "2024-12-06T05:55:12.940731", + "exception": false, + "start_time": "2024-12-06T05:54:33.922348", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 92:(161 + 4) / 200][Stage 93:>(68 + 9) / 200][Stage 94:> (8 + 4) / 200]\r", + "\r", + "[Stage 93:(151 + 4) / 200][Stage 94:>(66 + 8) / 200][Stage 95:> (1 + 4) / 16]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/sr213/application_1733153225851_0048/sr217/emon.parquet is not found, trying to load data ...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 129:> (0 + 2) / 2][Stage 130:> (0 + 2) / 2]\r", + "\r", + "[Stage 129:> (0 + 2) / 2][Stage 130:> (0 + 2) / 2][Stage 131:> (0 + 4) / 4]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 129:=> (1 + 1) / 2][Stage 130:=> (1 + 1) / 2][Stage 131:> (1 + 3) / 4]\r", + "\r", + "[Stage 129:========> (1 + 1) / 2][Stage 131:====> (1 + 3) / 4]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:==> (16 + 16) / 400]\r", + "\r", + "[Stage 143:==> (17 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:===> (24 + 16) / 400]\r", + "\r", + "[Stage 143:====> (34 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:=====> (43 + 16) / 400]\r", + "\r", + "[Stage 143:=======> (53 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:========> (65 + 16) / 400]\r", + "\r", + "[Stage 143:=========> (72 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:==========> (83 + 16) / 400]\r", + "\r", + "[Stage 143:===========> (90 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:=============> (99 + 16) / 400]\r", + "\r", + "[Stage 143:=============> (106 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:==============> (113 + 16) / 400]\r", + "\r", + "[Stage 143:===============> (118 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:================> (126 + 16) / 400]\r", + "\r", + "[Stage 143:=================> (132 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:==================> (140 + 16) / 400]\r", + "\r", + "[Stage 143:==================> (146 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:===================> (153 + 16) / 400]\r", + "\r", + "[Stage 143:====================> (160 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:======================> (170 + 16) / 400]\r", + "\r", + "[Stage 143:======================> (173 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:=======================> (182 + 16) / 400]\r", + "\r", + "[Stage 143:========================> (186 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:=========================> (194 + 16) / 400]\r", + "\r", + "[Stage 143:=========================> (197 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:==========================> (204 + 16) / 400]\r", + "\r", + "[Stage 143:===========================> (211 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:===========================> (214 + 16) / 400]\r", + "\r", + "[Stage 143:============================> (222 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:=============================> (230 + 16) / 400]\r", + "\r", + "[Stage 143:==============================> (236 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:===============================> (243 + 16) / 400]\r", + "\r", + "[Stage 143:================================> (249 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:=================================> (256 + 16) / 400]\r", + "\r", + "[Stage 143:==================================> (263 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:===================================> (272 + 16) / 400]\r", + "\r", + "[Stage 143:====================================> (279 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:======================================> (294 + 16) / 400]\r", + "\r", + "[Stage 143:======================================> (299 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:========================================> (311 + 16) / 400]\r", + "\r", + "[Stage 143:=========================================> (322 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:===========================================> (333 + 17) / 400]\r", + "\r", + "[Stage 143:=============================================> (348 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:==============================================> (360 + 16) / 400]\r", + "\r", + "[Stage 143:================================================> (372 + 16) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 143:==================================================> (386 + 14) / 400]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 148:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 154:> (0 + 3) / 3]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 154:===================> (1 + 2) / 3]\r", + "\r", + "[Stage 154:======================================> (2 + 1) / 3]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 157:> (0 + 3) / 3]\r", + "\r", + "[Stage 157:===================> (1 + 2) / 3]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 157:======================================> (2 + 1) / 3]\r", + "\r", + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sar metric\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 application_1733153225851_0048
runtime17.650000
disk spilled0.000000
shuffle_write0.000000
f_wait_time0.000000
input read22.540000
acc_task_time13.990000
output rows1.180000
%user>90%0.931034
%kernel>10%0.965517
%iowait>10%0.620690
avg %user41.216207
avg %system4.514138
avg %iowait0.743793
avg disk util32.206897
time more than 90%0.000000
total read (G)5.388613
total write (G)1.121773
avg read bw (MB/s)190.273771
avg write bw (MB/s)39.610183
read bw %75411.578125
read bw %95484.542969
read bw max510.351562
time_rd_morethan_950.034483
write bw %751.074219
write bw %95165.687500
write bw max812.511719
time_wr_morethan_950.034483
cached mean93.896552
cached 75%145.000000
cached max188.000000
used mean834.000000
used 75%852.000000
used max859.000000
rx MB/s 75%0.000000
rx MB/s 95%0.000000
rx MB/s 99%0.000000
pgin mean190.206897
pgin 75%412.000000
pgin max509.000000
pgout mean40.965517
pgout 75%1.000000
pgout max840.000000
fault mean117653.310345
fault 75%205151.000000
fault max256538.000000
cpu%_avg0.448817
cpu freq_avg3241.915617
pathlength_sum1933.000000
ipc_avg1.137983
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "summary=app.get_summary(show_metric=emonmetric,disk_prefix=disk_prefix,nic_prefix=nic_prefix)\n", + "display(summary.style)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "ae213d2c", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:55:12.957566Z", + "iopub.status.busy": "2024-12-06T05:55:12.957206Z", + "iopub.status.idle": "2024-12-06T05:55:33.180803Z", + "shell.execute_reply": "2024-12-06T05:55:33.180353Z" + }, + "papermill": { + "duration": 20.233292, + "end_time": "2024-12-06T05:55:33.182105", + "exception": false, + "start_time": "2024-12-06T05:55:12.948813", + "status": "completed" + }, + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 330:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 341:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DEV in ('nvme0n1')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 388:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 396:> (0 + 1) / 1]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "data": { + "text/plain": [ + "{'sr217': 200}" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 490:===================> (1 + 2) / 3]\r", + "\r", + " \r" + ] + }, + { + "data": { + "text/html": [ + "http://sr213:1088/tracing_examples/trace_viewer.html#/tracing/test_data/application_1733153225851_0048.json" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "app.generate_trace_view(showemon=True,show_metric=emonmetric,disk_prefix=disk_prefix,nic_prefix=nic_prefix)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "adde42f3", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:55:33.200290Z", + "iopub.status.busy": "2024-12-06T05:55:33.199984Z", + "iopub.status.idle": "2024-12-06T05:55:33.930601Z", + "shell.execute_reply": "2024-12-06T05:55:33.930143Z" + }, + "papermill": { + "duration": 0.741184, + "end_time": "2024-12-06T05:55:33.931895", + "exception": false, + "start_time": "2024-12-06T05:55:33.190711", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "gluten tpch_power 6600a1" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "appals.get_app_name()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "b20c9ef4", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:55:33.949596Z", + "iopub.status.busy": "2024-12-06T05:55:33.949323Z", + "iopub.status.idle": "2024-12-06T05:56:11.412960Z", + "shell.execute_reply": "2024-12-06T05:56:11.412450Z" + }, + "papermill": { + "duration": 37.473642, + "end_time": "2024-12-06T05:56:11.414122", + "exception": false, + "start_time": "2024-12-06T05:55:33.940480", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 605:==> (11 + 0) / 200]\r", + "\r", + "[Stage 531:(174 + 16) / 200][Stage 532:>(0 + 0) / 200][Stage 533:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 532:(102 + 16) / 200][Stage 533:>(0 + 0) / 200][Stage 534:>(0 + 0) / 200]\r", + "\r", + "[Stage 533:(72 + 16) / 200][Stage 534:>(0 + 0) / 200][Stage 535:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 534:(63 + 16) / 200][Stage 535:>(0 + 0) / 200][Stage 536:>(0 + 0) / 200]\r", + "\r", + "[Stage 535:(75 + 16) / 200][Stage 536:>(0 + 0) / 200][Stage 537:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 536:(102 + 17) / 200][Stage 537:>(0 + 0) / 200][Stage 538:>(3 + 0) / 200]\r", + "\r", + "[Stage 537:(114 + 16) / 200][Stage 538:>(3 + 0) / 200][Stage 539:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 538:(105 + 16) / 200][Stage 539:>(0 + 0) / 200][Stage 540:>(0 + 0) / 200]\r", + "\r", + "[Stage 539:(67 + 16) / 200][Stage 540:>(0 + 0) / 200][Stage 541:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 540:(59 + 16) / 200][Stage 541:>(0 + 0) / 200][Stage 542:>(0 + 0) / 200]\r", + "\r", + "[Stage 541:(104 + 16) / 200][Stage 542:>(0 + 0) / 200][Stage 543:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 542:(115 + 16) / 200][Stage 543:>(0 + 0) / 200][Stage 544:>(0 + 0) / 200]\r", + "\r", + "[Stage 543:(148 + 16) / 200][Stage 544:>(0 + 0) / 200][Stage 545:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 545:(0 + 16) / 200][Stage 546:>(0 + 0) / 200][Stage 547:>(0 + 0) / 200]\r", + "\r", + "[Stage 546:(38 + 16) / 200][Stage 547:>(0 + 0) / 200][Stage 548:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 547:(58 + 17) / 200][Stage 548:>(0 + 0) / 200][Stage 549:>(0 + 0) / 200]\r", + "\r", + "[Stage 548:(94 + 16) / 200][Stage 549:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 549:(113 + 17) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]\r", + "\r", + "[Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 551:(16 + 1) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]\r", + "\r", + "[Stage 551:(179 + 16) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 553:(16 + 0) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]\r", + "\r", + "[Stage 553:(54 + 17) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 555:>(8 + 8) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]\r", + "\r", + "[Stage 555:(16 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 555:(199 + 1) / 200][Stage 557:(0 + 15) / 200][Stage 559:>(0 + 0) / 200]\r", + "\r", + "[Stage 557:(16 + 0) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 557:(84 + 16) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]\r", + "\r", + "[Stage 559:(16 + 0) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 559:(29 + 16) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]\r", + "\r", + "[Stage 560:(85 + 16) / 200][Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 564:(16 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 564:(149 + 16) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]\r", + "\r", + "[Stage 566:(16 + 0) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 566:(71 + 16) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]\r", + "\r", + "[Stage 568:(16 + 0) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 568:(16 + 2) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]\r", + "\r", + "[Stage 569:(42 + 18) / 200][Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 573:(0 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]\r", + "\r", + "[Stage 573:(16 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 573:(67 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]\r", + "\r", + "[Stage 575:(16 + 0) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 575:(144 + 16) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]\r", + "\r", + "[Stage 577:(16 + 0) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 577:(184 + 16) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]\r", + "\r", + "[Stage 578:(197 + 3) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]\r", + "\r", + "[Stage 580:(58 + 16) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 580:(176 + 17) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]\r", + "\r", + "[Stage 581:(195 + 5) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]\r", + "\r", + "[Stage 583:(69 + 17) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 583:(170 + 16) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]\r", + "\r", + "[Stage 585:(16 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 585:(75 + 16) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 587:(16 + 0) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 587:(16 + 6) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]\r", + "\r", + "[Stage 589:>(8 + 8) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 589:(16 + 0) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 589:(182 + 17) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]\r", + "\r", + "[Stage 591:(16 + 0) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 591:(133 + 17) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]\r", + "\r", + "[Stage 593:(16 + 0) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 593:(39 + 18) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]\r", + "\r", + "[Stage 595:(16 + 0) / 200][Stage 597:>(0 + 0) / 200][Stage 599:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 597:(16 + 0) / 200][Stage 599:>(0 + 0) / 200][Stage 600:>(0 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 599:(0 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]\r", + "\r", + "[Stage 599:(16 + 0) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 599:(169 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]\r", + "\r", + "[Stage 605:==> (11 + 0) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 602:======> (102 + 18) / 200][Stage 605:> (11 + 0) / 200]\r", + "\r", + "[Stage 605:==> (11 + 16) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 606:============================================> (170 + 16) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 607:===================================> (135 + 16) / 200]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " \r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 932:====================================================>(197 + 3) / 200]\r", + "\r", + " \r" + ] + } + ], + "source": [ + "if not 'vanilla' in name:\n", + " shuffle_df, dfx=appals.get_shuffle_stat()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "110d231a", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:56:11.436348Z", + "iopub.status.busy": "2024-12-06T05:56:11.436046Z", + "iopub.status.idle": "2024-12-06T05:56:19.512226Z", + "shell.execute_reply": "2024-12-06T05:56:19.511740Z" + }, + "papermill": { + "duration": 8.089268, + "end_time": "2024-12-06T05:56:19.514108", + "exception": false, + "start_time": "2024-12-06T05:56:11.424840", + "status": "completed" + }, + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + " application_1733153225851_0048 " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "http://sr213:18080/history/application_1733153225851_0048" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " query time " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 runtimedisk spilledmemspilledlocal_readremote_readshuffle_writedeser_timerun_timeser_timef_wait_timegc_timepeak_memqueryidinput readacc_task_timestagesoutput rowsexecutorscore/exectask.cpusparallelism
real_queryid                     
117.6500000.0000000.0000000.0000000.0000000.0000000.2000006.7900000.0000000.0000000.0300001.340000822.54000013.990000[ 8 10 12 15]1.18000044132
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " operator count " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 01
AQEShuffleRead02
AdaptiveSparkPlan01
ColumnarExchange02
FilterExecTransformer01
FlushableHashAggregateExecTransformer01
InputAdapter02
InputIteratorTransformer02
ProjectExecTransformer02
RegularHashAggregateExecTransformer01
Scan parquet 01
ShuffleQueryStage02
SortExecTransformer01
VeloxColumnarToRow01
VeloxResizeBatches02
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " operator input row count " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 1
ColumnarExchange0.000000
VeloxResizeBatches0.000000
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " operator output row count " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 1
ColumnarExchange0.000000
FlushableHashAggregateExecTransformer0.000000
InputIteratorTransformer0.000000
ProjectExecTransformer591.600000
RegularHashAggregateExecTransformer0.000000
Scan parquet 591.600000
SortExecTransformer0.000000
VeloxColumnarToRow0.000000
VeloxResizeBatches0.000000
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAACUYAAAKyCAYAAAAT/5YnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd1gU1/s28HvpHRREQSn2EguosaMYe+/GGmvUJBqj0dgSu181xthLEqPYTWLE2HvFgoKdiB0s2GmCSJ33D96d3w5sL7Tcn+vai13mzJkzs1POnnnmHJkgCAKIiIiIiIiIiIiIiIiIiIiIiIiKELP8LgAREREREREREREREREREREREZGxMTCKiIiIiIiIiIiIiIiIiIiIiIiKHAZGERERERERERERERERERERERFRkcPAKCIiIiIiIiIiIiIiIiIiIiIiKnIYGEVEREREREREREREREREREREREUOA6OIiIiIiIiIiIiIiIiIiIiIiKjIYWAUEREREREREREREREREREREREVOQyMIiIiIiIiIiIiIiIiIiIiIiKiIoeBUUREREREREREREREREREREREVOQwMIqoAImPj4dMJlP5CgwMNNqyBg8eLOYbFBRktHz/K6KiosTt5+vrm9/FISIiIiIiIiIiIgDffPON2jbWU6dO6ZTf0qVL1eaX322r165dU1u+wYMHG21ZgYGBem9HItJdUFCQSY5lIlJN8RpKREUHA6OIiChPpKWlITQ0FEuWLEGvXr1QpkwZnRulFAPS9HkpW0ZGRgbCwsKwYsUKDBs2DA0aNECpUqVgbW0NOzs7eHt7o3Pnzli7di2SkpI0llEQBNy8eRO//vorRo0ahYCAAJQuXRo2NjawsbGBp6cn2rRpg59++glv377VaRvGxMRg586dGD9+PBo2bAhra2u9Aidnzpyp03arW7eu2vxevXqF4OBgTJ06FR07dkSVKlXg6OgIS0tLuLq6ok6dOhgzZgzCw8O1LuObN2+wceNGDBw4ELVq1UKxYsVgaWmJ4sWLo1atWhg9ejSuXLmidX6JiYn4888/MXz4cNStWxeurq6wtLSEs7MzqlatimHDhunUoKfrvrdv3z6t8o2NjcVPP/2Eli1bivuhg4MDypcvj969e2Pnzp3IyMjQmI9iQ6U2rwkTJmhVPmPtg6YUGxuLRYsWoX79+ihRogRs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sGrVKhw6dAh37txBYmKipDcSTSpWrIgbN25g8+bN2LVrF65evYo3b97AysoKnp6eaN68OYYOHaq2R2EyjRkzZog9DF2+fBlv376Fu7s7GjVqhFGjRok9qarzww8/oHXr1li+fDnOnDmDV69ewcHBAd7e3ujcuTNGjBiB0qVL49SpU6ZfISVM3T4IZPdKffXqVfz444/YvXs3oqKi8OHDB73zK168OM6dO4dly5bhjz/+wN27d/H+/Xud8jDWtVgZmUyGDRs2oE2bNvjll19w9epVJCQk6LqaRuHo6Ii3b9/i+PHjOHnyJC5fvox79+4hNjYWMplMbH9r164dBg0aBFdX13wpp7EU9PZBUzBFfdDGxgZHjhzBihUrsHXrVty5cwcymQy+vr7o1q0bvvrqK5QsWRIHDx7MgzXUzBjX4sLA0PpgYZOcnIy//vpL/CzvgbGoMmXbjCls374d3bp1w9atW3H16lXxGlqUVK5cGaGhoTh06BCCg4MREhKC58+fIzExEY6OjvD29oafnx9atGiB9u3bw83NLb+LbDDF33vVq1eHv79/PpaGigqZkN+RFUR5LDAwUBx65uTJkzrdIFVm8ODB2LhxI4DsE/XgwYMNLCERERHRf4evry+io6MBAI8ePYKvr2/+FoiIiIqcoKAgDBkyBED2sBf6Bp4QEeWVmTNnikO0zJgxAzNnzszfAhERERERERVihbfLBiIiIiIiIiIiIiIiIiIiIiIiIhUYGEVEREREREREREREREREREREREUOA6OIiIiIiIiIiIiIiIiIiIiIiKjIYWAUEREREREREREREREREREREREVOQyMIiIiIiIiIiIiIiIiIiIiIiKiIoeBUUREREREREREREREREREREREVOTIBEEQ8rsQqmRlZSEmJgaOjo6QyWT5XRwioiLrq6++wvbt242W36RJkzBp0iSj5UdEhZ+fnx8eP35stPz27NmDJk2aGC0/IiIiyl/8TWKYx48fw8/Pz6h5xsbGGjU/IiIiIiIiIiJjEgQB7969g6enJ8zMVPcLVaADo54+fQovL6/8LgYRERERERERERERERERERERERUwT548QZkyZVROt8jDsujM0dERQPZKODk55XNpiIiIiPLPr9+czu8iEBERERERERFRATBiabP8LgIRERFRvktMTISXl5cYW6RKgQ6Mkg+f5+TkxMAoIiIi+k/rcP67/C4CEREREREREREVAE5Ot/O7CEREREQFhjy2SBXVg+wREREREREREREREREREREREREVUgyMIiIiIiIiIiIiIiIiIiIiIiKiIoeBUUREREREREREREREREREREREVOQwMIqIiIiIiIiIiIiIiIiIiIiIiIocBkYREREREREREREREREREREREVGRw8AoIiIiIiIiIiIiIiIiIiIiIiIqchgYRURERERERERERERERERERERERQ4Do4iIiIiIiIiIiIiIiIiIiIiIqMhhYBQRERERERERERERERERERERERU5DIwiIiIiIiIiIiIiIiIiIiIiIqIih4FRRERERERERERERERERERERERU5DAwioiIiIiIiIiIiIiIiIiIiIiIihwGRhERERERERERERERERERERERUZHDwCgiIiIiIiIiIiIiIiIiIiIiIipyGBhFRERERERERERERERERERERERFDgOjiIiIiIiIiIiIiIiIiIiIiIioyGFgFBERERERERERERERERERERERFTkMjCIiIiIiIiIiIiIiIiIiIiIioiKHgVFERERERERERERERERERERERFTkMDCKiIiIiIiIiIiIiIiIiIiIiIiKHAZGERERERERERERERERERERERFRkcPAKCIiIiIiIiIiIiIiIiIiIiIiKnIYGEVEREREREREREREREREREREREUOA6OIiIiIiIiIiIiIiIiIiIiIiKjIYWAUEREREREREREREREREREREREVOQyMIiIiIiIiIiIiIiIiIiIiIiKiIscivwtARERERJr1nsJqGxERERERERERATfzuwBEREREhQh7jCIiIiIiIiIiIiIiIiIiIiIioiJH58Co9PR0zJkzB61bt4aTkxNkMhlOnTqVK50gCFi7di1q1qwJW1tbuLu7o3PnzkhKSjJGuYmIiIiIiIiIiIiIiIiIiIiIiFTSOTAqOTkZ06dPx/3791GjRg2V6aZOnYovvvgCVapUwfLlyzFlyhRYWloiJSXFoAITERERERERERERERERERERERFpYqHrDI6Ojnj8+DG8vLywc+dOnD9/PleayMhILFq0CFOnTsW8efPE/48bN86w0hIREREREREREREREREREREREWlB5x6jzM3N4eXlpTbN9u3bYWlpiSlTpgAAh88jIiIiIiIiIiIiIiIiIiIiIqI8pXNglDZCQ0NRo0YN7NmzB+7u7nB0dISXlxe2b99uisURERERERERERERERERERERERFJmCQw6tmzZ3j9+jVGjRqFiRMn4o8//kC5cuXQv39/XLlyReV8qampSExMlLyIiIiIiIiIiIiIiIiIiIiIiIh0ZZLAqPfv3yMqKgoLFizAxIkT0bt3b+zfvx8ODg5YtGiRyvnmz58PZ2dn8aVpyD4iIiIiIiIiIiIiIiIiIiIiIiJlTBIYZWVlBQDo3r27+D8HBwc0atQIN27cUDnflClTkJCQIL6ePHliiuIREREREREREREREREREREREVERZ5LAqBIlSkj+yhUvXhyvXr1SOZ+1tTWcnJwkLyIiIiIiIiIiIiIiIiIiIiIiIl2ZJDCqWrVqAIAXL15I/v/69Wt4enqaYpFEREREREREREREREREREREREQikwRGtW3bFgCwbds28X9v377FuXPnULduXVMskoiIiIiIiIiIiIiIiIiIiIiISGShz0wrV65EfHw8IiIiAACbN29GSEgIXFxcMHr0aHTu3Bl16tTB1KlT8erVK3h7e+O3335DZmYmJk+ebNQVICIiIiIiIiIiIiIiIiIiIiIiykkmCIKg60y+vr6Ijo7O9X8fHx9ERUUByB42b8KECdi3bx+Sk5Ph7++P+fPnIzAwUOvlJCYmwtnZGQkJCXByctK1mERERERFRo2NNfK7CEREREREREREVADcHHQzv4tARERElO+0jSnSq8coefCTOiVKlMDGjRv1yZ6IiIiIiIiIiIiIiIiIiIiIiMggZvldACIiIiIiIiIiIiIiIiIiIiIiImNjYBQRERERERERERERERERERERERU5DIwiIiIiIiIiIiIiIiIiIiIiIqIih4FRRERERERERERERERERERERERU5DAwioiIiIiIiIiIiIiIiIiIiIiIihwGRhERERERERERERERERERERERUZHDwCgiIiIiIiIiIiIiIiIiIiIiIipyGBhFRERERERERERERERERERERERFDgOjiIiIiIiIiIiIiIiIiIiIiIioyGFgFBERERERERERERERERERERERFTkMjCIiIiIiIiIiIiIiIiIiIiIioiKHgVFERERERERERERERERERERERFTkMDCKiIiIiIiIiIiIiIiIiIiIiIiKHAZGERERERERERERERERERERERFRkcPAKCIiIiIiIiIiIiIiIiIiIiIiKnIYGEVEREREREREREREREREREREREUOA6OIiIiIiIiIiIiIiIiIiIiIiKjIYWAUEREREREREREREREREREREREVOQyMIiIiIiIiIiIiIiIiIiIiIiKiIoeBUUREREREREREREREREREREREVOQwMIqIiIiIiIiIiIiIiIiIiIiIiIocBkYREREREREREREREREREREREVGRw8AoIiIiIiIiIiIiIiIiIiIiIiIqchgYRURERERERERERERERERERERERQ4Do4iIiIiIiIiIiIiIiIiIiIiIqMhhYBQRERERERERERERERERERERERU5DIwiIiIiIiIiIiIiIiIiIiIiIqIih4FRRERERERERERERERERERERERU5DAwioiIiIiIiIiIiIiIiIiIiIiIihwGRhERERERERERERERERERERERUZHDwCgiIiIiIiIiIiIiIiIiIiIiIipyGBhFRERERERERERERERERERERERFDgOjiIiIiIiIiIiIiIiIiIiIiIioyGFgFBERERERERERERERERERERERFTkMjCIiIiIiIiIiIiIiIiIiIiIioiKHgVFERERERERERERERERERERERFTkMDCKiIiIiIiIiIiIiIiIiIiIiIiKHAZGERERERERERERERERERERERFRkcPAKCIiIiIiIiIiIiIiIiIiIiIiKnIYGEVEREREREREREREREREREREREUOA6OIiIiIiIiIiIiIiIiIiIiIiKjIYWAUEREREREREREREREREREREREVOQyMIiIiIiIiIiIiIiIiIiIiIiKiIoeBUUREREREREREREREREREREREVOQwMIqIiIiIiIiIiIiIiIiIiIiIiIocBkYREREREREREREREREREREREVGRw8AoIiIiIiIiIiIiIiIiIiIiIiIqchgYRURERERERERERERERERERERERQ4Do4iIiIiIiIiIiIiIiIiIiIiIqMhhYBQRERERERERERERERERERERERU5DIwiIiIiIiIiIiIiIiIiIiIiIqIixyK/C0BEREREREREREREREREVFRkZmYiPT09v4tBRERUqFhYWMDc3Bwymcy4+Ro1NyIiIiIiIiIiIiIiIiKi/yBBEPDixQvEx8fnd1GIiIgKJXNzc7i7u8PZ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enl54fr168ZeLBERERERERERERERERER5ZMZM2bg+fPnYk8uujp69Ci2bdsGPz8/SUBHixYtcOvWLaxevRq//fYbwsLCcOnSJfj7+2Po0KFo3LgxoqOjMXr0aCOtifH5+PgAALy9vQEA5cuXBwDxPro82OKff/7B8+fPMXLkSElQFABx5KWdO3fqXY5du3YBACZPniz5/9dffw1bW1txel7JzMyEubl5rk5VHB0dc/WgFBMTg71796JSpUqSUajkWrduLflctWrVXEFRwP8F3d28eVNpmSZNmiS+t7S0ROvWrZGZmYl79+5pt1JKuLu75wqK0qYs48aNE4OiAKBjx44Asnugktu7dy8yMjIwdOhQSeBW37594enpqXeZi4K1a9fC3NwcK1asEIOigOxAtW7duuHEiRMqh0kUBAFLlizJtW8q69mLCj6j9xhVsmRJ7N27N9f/O3XqhA4dOmDUqFGoWLGisRdLRERERERERERERERERET5ICwsDD///DN+/PFHlClTRuf579+/j379+qF48eL4+++/JUEMQHZgUbdu3bBmzRrUrVsXNWrUwKxZs9CxY0eYmRm9LxCjkw97Jv8rHypQ/jklJQUAcPnyZQDA48ePc/WEk5GRASB7W+nr9u3bsLe3z3W/3tnZGWXLlsW///6LhIQEODs7670MXfTo0QPTp09HgwYN0LdvX9SvXx8ff/yx0p6Zrly5AgAICAiAubm5xryzsrKwbt06bNy4Ebdu3cK7d+8gCII4/d27d7nmcXNzQ/HixXP9DwCSkpJ0Wrecjh8/jiVLluDy5ct4+/YtMjMz1ZYFACpVqqSxLPIgqZxDwpmbm6N69eqIiYkxqNyF1bt37xAZGYlixYphxYoVuaZHRUVBEAQ8ePAAdevWzTW9TJkyubY/FV56BUatXLkS8fHxiIiIAABs3rwZISEhcHFxwejRo8VIxZx8fX1VTiMiIiIiIiIiIiIiIiIiosJn2LBhqFatGr7++mud533+/DnatGmDDx8+4NixYyhXrpxk+q1bt/Djjz9i//79+PTTT3Hy5EmULl0a3377LYYNGwYbGxsMGzYM33//fa6AqoJCJpMBgBjEJf8s/ysPkomPjwcABAcHIzg4WGleyoaY01ZSUpLKXoRcXV0BZAeU5FVg1LRp0+Dq6or169fj+++/hyAIsLS0RK9evbBmzRpJ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E3L2TVeAJCYmwtnZGQkJCXBycsrv4hARERHlmxoba+R3EYiIiIiIiIiIqAC4OehmfheBlPjw4QMePXqEsmXLwsbGJr+LQ0REVGhpe03VNqbIzBSFJCIiIiIiIiIiIiIiIiIiIiIiyk8MjCIiIiIiIiIiIiIiIiIiIiIioiKHgVFERERERERERERERERERERERFTkWOR3AYiIiIiIiIiIiIiIiIiIiAzVp08fXLx4Uau0FhYWuH//volLRERE+Y2BUUREREREREREREREREREVOjt2LEjv4tAREQFDIfSIyIiIiIiIiIiIiIiIiIiIiKiIoeBUUREREREREREREREREREREREVOQwMIqIiIiIiIiIiIiIiIiIiIiIiIocBkYREREREREREREREREREREREVGRw8AoIiIiIiIiIiIiIiIiIiIiIiIqchgYRURERERERERERERERERERERERQ4Do4iIiIiIiIiIiIiIiIiIiIiIqMhhYBQRERERERERERERERERERERERU5DIwiIiIiIiIiIiIiIiIiIiIiIqIixyK/C0BEREREREREREREREREVKTNdM7vEqg2MyG/S1CoyWQyNGvWDKdOncrvopiUIAj48ccfsW7dOkRHRyM9PR2DBg1CUFBQfhfNJP4r3yvRfwF7jCIiIiIiIiIiIiIiIiIiIr3du3cPQ4YMgZ+fH1xdXWFnZ4eqVatizJgxiImJyZX+1KlTkMlkSl9lypSRpP3w4QPGjh2LkiVLwt3dHfPnz0dWVpZJ1sPX1xe+vr4mybuw27ZtGyZPngxnZ2dMmDABM2bMQNeuXfO7WEVaUFAQZDJZkQ0+I8or7DGKiIiIiIiIiP4fe/cd1nX1/3/88XbEVBwojhTIAWrmiPo4E0eluXBrWqJWfr6miVofycHIDMcnV6aWA8TMSlypNBxAWYqj3JqSQllm5WCjMn5/+Hu/P74FFN4spfvturjwfV7nnNfzNYjrisd1DgAAAAAAFjtx4oQ2bNig9u3bq23btqpQoYJOnz6tpUuXau3atfr+++/l7u6ebVyHDh3k6elp1laxYkWzzz4+PgoNDdXw4cOVlJSk6dOny9raWhMmTCjKS8qzU6dOydbWtqTLKHLh4eGSpK1bt6pmzZolXE3R+6c8V+CfgGAUAADAA+DY+V9KugQAAAAAAAAAyNHTTz+ty5cvq3z5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t5eHh4eOHDli1n/btm3q1KmTHBwcZGtrq1atWmnLli0Frv3MmTN644031KJFC1WuXFk2NjZq3Lix3nrrLaWmppr1Nb5jBoNBq1evliS5urqaPac7t9a7fYzx624seWd++uknvfHGG6pVq5asra3Vtm1bHT169K7nAYoKK0YBAAAAAAAAAAAAAIrN3r17JUnt2rUza2/WrJkcHBxMx6tUqaL69evLz89Py5cvV3JysoKCgtSqVSuzcbGxsYqPj1ezZs3yXYu3t7cp2LRgwQJJt7bvM6pUqdJdxwQGBt7zHKtWrdLAgQP1wQcfyNvbW46OjvL29lZwcLBGjhxpFjCJiIhQjx49lJ6err59+6p27dqKjo6Wr6+vTp8+reDg4Hxfo1Fqaqo6dOigY8eOqWPHjnr++ed16tQphYSEaMeOHfrhhx9UvXp1U38vLy9TMCwkJERxcXHy9/c3HW/evLnFtUjSmDFjVLduXbVr10516tTR5cuXtXHjRj311FP68ssv1bFjR1Pfv/76S+3bt9fvv/+uvn37qn79+vryyy/1wgsv5Dj3N998o65du8rKykovvviibG1ttWzZMlWpUuWedf36669q27atmjRpoldeeUXXrl1TRESEzp8/b3rHZs+eLV9fX1WvXl0DBw6UjY2NvvjiC3l5eSk4ONgs7JTf2jdu3KhFixapY8eOatu2rWxsbHTgwAH5+/vru+++05dffmkKM90eytu8ebOOHDmi8ePHm723d77Dt48xPtfc5PedMRo9erSuXLmiwYMH6+zZs9q2bZu6d++us2fPytraOtfzAUWBYBQAAAAAAAAAAAAAoNicP39eVatWlb29vX788UeNGTNGY8eO1dChQ+Xs7KyjR48qLS1N1tbWWrZsmby8vOTk5CRJcnJyMoWDoqKitHDhQu3atUszZ860OBhlZFxFKCAgIM9j8hKMmj9/vrp27aq//vpLn376qdasWaOePXvKxsZGQUFBunDhgh5++GGlpaVp6NChyszM1N69e9WyZUvTHGPGjNHSpUs1atSobIGyvFq8eLGOHTumkSNHauXKlab2GTNmyM/PT2+99ZYWL15savfy8pKXl5ekW6spxcXF3fPe5MeOHTvUvn17s7Zp06apUaNG8vf3NwtGvfPOO/rtt98UFBQkX19fU91PPvlkjnOPHz9eN2/eVFRUlFq3bi1J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jx5KT09X3759Vbt2bUVHR8vX11enT59WcHBwvq/RyN/fX5J07do1LVy4UM2aNZOXl5fpePPmzc36nzx5Uq1bt1ZycrIGDRqkunXraufOnXrrrbe0b98+ffnllwVajWjMmDGqW7eu2rVrpzp16ujy5cvauHGjnnrqKX355Zfq2LFjtjHjx49Xenq6hg8frqtXr2rt2rXy9PTUvn371KRJk2z9n376aVWrVk3jxo3T8ePHtWbNGh06dEgHDx6UjY2NqZ8l9/306dPq3r27evXqpccff1xhYWGaOXOmatasqVdffdXU7+LFi2rXrp3++usvDRgwQC4uLtq2bZtpFbTCFhoaqt9//12LFi0yCx5a6sUXX1RYWJhat26tf//737p+/bpOnjypd999VxMmTFCNGjWyjcnrfc+v20OIISEhiouLy7Vvft93SyQkJKhLly564oknNH78eH333XdavHixjh07pt27d6tMmf+tVZSf992S2nft2qVevXrpxo0b6tWrl9zc3HT16lVt375d5cuXV0hIiFn/69evq3PnznJ2dtZLL72k3bt367PPPlNmZqbWr19v1nf27Nny9fVV9erVNXDgQNnY2OiLL76Ql5eXgoODswW1LHlnihLBKAAAAAAAAAAAAABAsTl//ryqVq0qe3t7/fjjjxozZozGjh2roUOHytnZWUePHlVaWpqsra21bNkyeXl5ycnJSZLk5ORkCqlERUVp4cKF2rVrl2bOnGlxMMrIGBwICAjI85i8BKPmz5+vrl276q+//tKnn36qNWvWqGfPnrKxsVFQUJAuXLighx9+WGlpaRo6dKgyMzO1d+9etWzZ0jTHmDFjtHTpUo0aNSpboCyvjNcVGxurhQsXqnnz5ne91jfeeEMJCQkKDQ3VCy+8IEmaOXOmnn32WX399dfasGGD+vfvb1EtkrRjxw61b9/erG3atGlq1KiR/P39cwxGJSUl6eTJk6pcubIkqWfPnurTp4/efPNNff7559n6169fX+Hh4aYAl4+PjxYuXKilS5dq4sSJkmTxfY+OjlZ4eLi6desmSRo3bpzc3Ny0evVqs2DUjBkzdOnSJc2fP98UugsICJCHh0d+b9k9ZWZmau7cuXJ0dNSoUaMKPF9CQoI2bNig1q1b67vvvjMLwv3666+m53CnvNx3S3h6eprCUZGRkXcNRuX3fbfE1atX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pUqRHKUnSTVr1tSqVat09epVZWZm6uDBg5xhCQAAAAAAAAAAAAD/49auXStJeuedd8yhKEmaPHmyJGn16tWSpPT0dN2+fVtNmjQx92natKl++eWXJ1aLj4+PDAaDDAaDkpOTlZycbP5sMBhyPVrv/jEGgyHPfwcPDg6WwWDQ7Nmz5ejoKGdnZ23dulULFixQtWrVVL9+fe3atSvHuFOnTmnw4MFydHSUtbW13N3dNXPmTGVnZxd6vSkpKRo3bpxcXFz01FNPydnZWcOHD9fly5dz9A0ICDCvMTo6WpIs1h0QEFDoer766it17txZ9vb2qlixotq2bavIyEiLPllZWfLy8pKtra1Onz5tcS0tLU1ubm6qUaOGfvzxR0lSTEyMucbhw4dLkoYPH25Re27H05nGBQcH69SpU+rdu7eqVaumypUry9PTUydOnDD3DQ0Nla+vr1xcXGRtba0aNWrI19dXcXFxea41JSVF7777rpo0aSJbW1vVqlVLf/nLX7R169YcNTxO7fePMf3ExMTkWcfdu3c1d+5cNWvWTDY2NqpWrZp69Oih2NjYHH3vP85vxYoVaty4sWxsbNSoUSN9+eWXed4DKE2KZMcoAAAAAAAAAAAAAAByc/DgQUlShw4dLNqbN28ue3t78/Xq1aurQYMGmjp1qpYvX66MjAyFhISobdu2FuOSkpKUmpqq5s2bP3YtAQEB5mDTvHnzJN07vs+katWqDx0zbdq0R94jNDRUAwcO1LJlyxQQEKAaNWooICBAYWFhGjFihEUoKTo6Wr169VJWVpb69eun2rVrKy4uToGBgTpz5ozCwsIee40mt27dkre3t77//nt16tRJL7/8shISEhQeHq7du3fr2LFjqlWrlrm/n5+fORgWHh6u5ORkBQUFma+3aNGiwLVI0syZMxUYGKhatWpp4MCBsrW11ddffy0/Pz+FhYWZg1fly5fXF198oRYtWujll19WXFycrK2tJUl/+9vflJSUpMjISD399NOSJFdXV3Od3333nSIjI9WnTx+Leh9W+6VLl9S+fXs1bdpUo0aN0vXr1xUdHa2LFy+a37ExY8aoXr166tChg+rWraurV69q8+bN6tixo/75z3+qU6dOFnP++OOP6tChgy5evKj27durd+/eysrKUkxMjMaPHy8/P78C137/mJiYGO3bt++hz3306NFasWKF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Zyd/f3/dvn3b3N/0HuzcuVN///vfVbNmTVWqVEldunTR0aNH86zd9G5dv35dr7/+upydnWVjY6OGDRua/wyZPO47s379erVv3141atRQpUqV5O7urtdee02JiYk5+t66dUszZszQn/70J9nZ2alatWpq2bKl3nnnnSfyHgBFjR2jAAAAAAAAAAAAAADF5uDBg5KkDh06WLQ3b95c9vb25uvVq1dXgwYNNHXqVC1fvlwZGRkKCQlR27ZtLcYlJSUpNTVVzZs3f+xaAgICzMGmefPmSbp3fJ9J1apVHzpm2rRpj7xHaGioBg4cqGXLlikgIEA1atRQQECAwsLCNGLECF2+fNncNzo6Wr169VJWVpb69eun2rVrKy4uToGBgTpz5ozCwsIee40mQUFBkqTr169r/vz5at68ufz8/MzXW7RoYdH/9OnTateunTIyMjRo0CDVq1dPe/bs0QcffKDY2Fj985//NB95+Lju3r2r3r17a9++fXr++efVvn17HTt2TH/5y19kNBpVpUoVi/7Z2dny8/PTjh071LRpU40ePVo3btzQpk2b5OXlpQMHDqhZs2YWY6KiouTr66vbt2/L19dX7u7uSklJ0Y4dO1ShQgWFh4eb+65Zs0avvvqqqlWrpldffVXW1tbauHGjhg0bpsuXL5tDeyZbt27VsGHD9Oyzz+qrr77Sv//9b3Xv3l12dnZav369unTpotdee81izLhx45SVlaVhw4YpJSVFa9eulY+Pj2JjY9W0adM8n9MLL7yga9euaeDAgSpXrpwOHTqkI0eOaMiQIZIe/5357LPPNHbsWLm5uenll1+WjY2NEhMTtWHDBnXt2lUNGjSw6P/qq69q06ZNateunV5//XX9/vvvOn36tD799FNNmDBBTk5Oj/7CgRJkMBqNxpIuIi9paWmyt7dXampqjv/hAwAA+F/iGrijpEsAAAAAAABAKZA0o2dJl4BcZGZm6uLFi3Jzc5ONjU2O6wkejUugqvxpfCah2O/p4OAgg8Gg3377TcePH9eYMWM0duxYDRkyRM2bN9fJkyd169Yt2djYKCoqSn5+frpx44YkydHRUXv37lWTJk20b98+zZ8/X1FRUZo+fbrGjh1bqLpMu0MlJSXle4zBYJC3t7diYmJyXAsODta0adP09ddfq3v37ho8eLA2bNigbdu2qXfv3po8ebJCQkJ0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AAAAAAAAAAAAeKAqKiq0aNEide/eXWazWV26dNErr7yisrIyu35lZWWaPn26fHx85O3trcTERFVVVTVITV26dFGXLl0a5NmNSX5+vgzDUExMjKNLwR2kpKTIMAylpKQ4uhTgocaOUQAAAAAAAAAAAACAB+qFF15QcnKyHnvsMY0bN045OTlauHChjh8/rl27dskwDElSbGysUlNTNWnSJJWUlOi1116T2WzWjBkzHLyC2/Ly8tSyZUtHlwEAqAXBKAAAAAAAAAAAAADAA5Odna3k5GSFhYUpIyNDzZrd/rV1RESEtmzZorS0NIWHh6u8vFzJyclKSUnRhAkTJEk9evTQihUrGk0wqkePHo4uAQBwBxylBwAAAAAAAAAAAAB4YDZs2CBJmjNnji0UJUlz586VJK1fv16SVFxcrFu3bqlnz562Pr169dKlS5fqrZawsDAZhiHDMFRQUKCCggLbtWEYNR6t9+MxhmEoLCysxmcnJCTIMAwtWbJEPj4+at++vXbs2KHly5erTZs26tq1q/bu3Vtt3JdffqmoqCj5+PjIZDIpKChIixcvVmVlZZ3Waq03ICBAkrRu3Tq7ddR0tF5eXp6effZZeXl5yWQyKTAwUPHx8dWOPLxflZWVWrFihUJDQ+Xu7i53d3eFhIQoKSlJt27dsut79epVTZ8+Xf7+/mrRooXat2+v559/Xt99912158bExMgwDH399deaPXu2OnToILPZrIEDByo3N7fGvj9tl6Ty8nJ5enqqe/fu1e7t3r1bv/71r+Xh4aGWLVsqNDRUaWlpta7V+vfGYrHozTffVGBgoMxmszp06KA//vGPkqSsrCzb+3j++eclSc8//7zde+JoPeDnYccoAAAAAAAAAAAAAMADc/DgQUnS448/btfeu3dveXh42O63bdtW3bp107x587R69WqVlpYqMTFRoaGhduPy8/NVWFio3r17/+xaYmJibMGmZcuWSbp9fJ9V69at7zhm/vz5d51j7dq1ioiI0KpVqxQTEyMvLy/FxMQoOTlZkydPtgv2ZGZmauTIkaqoqNDYsWPl5+ennJwcxcXF6auvvlJycvLPXqNVfHy8JOnatWtKSkpS7969FR4ebrvfp08fu/6nTp1S//79VVpaqsjISHXu3Fn79u3T66+/ruzsbH3yySe2Iw/vR2VlpUaNGqX09HR169ZNMTEx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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "appals.get_app_info(disk_prefix=disk_prefix,nic_prefix=nic_prefix)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "1263e7ae", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:56:19.542523Z", + "iopub.status.busy": "2024-12-06T05:56:19.542250Z", + "iopub.status.idle": "2024-12-06T05:56:21.623772Z", + "shell.execute_reply": "2024-12-06T05:56:21.623288Z" + }, + "papermill": { + "duration": 2.097246, + "end_time": "2024-12-06T05:56:21.625534", + "exception": false, + "start_time": "2024-12-06T05:56:19.528288", + "status": "completed" + }, + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0
44%_time of scan and filter7.53
36%_time of project6.13
16%_not_counted2.69
3%_idle0.55
0%_time of input iterator0.06
0%_time of aggregation0.03
0%_time to append / split batches0.00
0%_time of rowConstruction0.00
0%_time to split0.00
0%_time to deserialize0.00
0%_time of sort0.00
0%_time of extraction0.00
0%_shuffle write time0.00
0%_time to convert0.00
0%_time to compress0.00
0%_time to spill0.00
0%_time to decompress0.00
\n", + "
" + ], + "text/plain": [ + " 0\n", + "44%_time of scan and filter 7.53\n", + "36%_time of project 6.13\n", + "16%_not_counted 2.69\n", + " 3%_idle 0.55\n", + " 0%_time of input iterator 0.06\n", + " 0%_time of aggregation 0.03\n", + " 0%_time to append / split batches 0.00\n", + " 0%_time of rowConstruction 0.00\n", + " 0%_time to split 0.00\n", + " 0%_time to deserialize 0.00\n", + " 0%_time of sort 0.00\n", + " 0%_time of extraction 0.00\n", + " 0%_shuffle write time 0.00\n", + " 0%_time to convert 0.00\n", + " 0%_time to compress 0.00\n", + " 0%_time to spill 0.00\n", + " 0%_time to decompress 0.00" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAACUYAAAKyCAYAAAAT/5YnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd1gU1/s28HvpHRREQSn2rqDGjmLsxt5i71ETNUajsSV2v2qMsZdEo9hNYsTee0fBTsQOFuw0KVLn/YOX+e3A9kLL/bmuvdhlz5w9szvl7NlnniMTBEEAERERERERERERERERERERERFRIWKS1w0gIiIiIiIiIiIiIiIiIiIiIiIyNAZGERERERERERERERERERERERFRocPAKCIiIiIiIiIiIiIiIiIiIiIiKnQYGEVERERERERERERERERERERERIUOA6OIiIiIiIiIiIiIiIiIiIiIiKjQYWAUEREREREREREREREREREREREVOgyMIiIiIiIiIiIiIiIiIiIiIiKiQoeBUUREREREREREREREREREREREVOgwMIqIiIiIiIiIiIiIiIiIiIiIiAodBkYR5SMxMTGQyWRKb/7+/gZ7rUGDBon1BgQEGKze/4rw8HDx/fP29s7r5hARERERERERERGA7777TuUY65kzZ7Sqb+nSpSrry+ux1Zs3b6ps36BBgwz2Wv7+/jq/j0SkvYCAAKPsy0SknPw5lIgKDwZGERFRrkhJSUFQUBCWLFmCHj16oFSpUloPSskHpOlyU/QaaWlpCA4OxooVKzB06FDUr18fJUqUgKWlJWxsbODp6YmOHTti7dq1iI+PV9tGQRBw584d/P777xg5ciT8/PxQsmRJWFlZwcrKCu7u7mjdujV++eUXfPjwQav3MDIyErt27cL48ePRoEEDWFpa6hQ4OXPmTK3etzp16qis7+3btwgMDMTUqVPRvn17VKpUCfb29jA3N4ezszNq166NMWPGICQkROM2vn//Hps2bUL//v1Rs2ZNFClSBObm5ihatChq1qyJ0aNH4/r16xrXFxcXh7/++gvDhg1DnTp14OzsDHNzczg6OqJy5coYOnSoVgN62m57Bw4c0KjeqKgo/PLLL2jRooW4HdrZ2aFs2bLo2bMndu3ahbS0NLX1yA9UanKbMGGCRu0z1DZoTFFRUVi0aBHq1auHYsWKwdra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jhzB/fv3ERcXJ8lGok758uVx+/ZtbNmyBbt378aNGzfw/v17WFhYwN3dHc2aNcOQIUNUZhQm45gxY4aYYejatWv48OEDXF1d0bBhQ4wcOVLMpKrKTz/9hFatWmH58uU4d+4c3r59Czs7O3h6eqJjx44YPnw4SpYsiTNnzhh/hRQw9vggkJmV+saNG/j555+xZ88ehIeH49OnTzrXV7RoUVy8eBHLli3Dn3/+iQcPHiAxMVGrOgx1LlZEJpNh48aNaN26NX777TfcuHEDsbGx2q6mQdjb2+PDhw84efIkTp8+jWvXruHhw4eIioqCTCYTx9/atm2LgQMHwtnZOU/aaSj5fXzQGIzRH7SyssKxY8ewYsUKbNu2Dffv34dMJoO3tze6dOmCUaNGoXjx4jh8+HAurKF6hjgXFwT69gcLmoSEBPz999/i46wMjIWVMcdmjGHHjh3o0qULtm3bhhs3bojn0MKkYsWKCAoKwpEjRxAYGIgLFy7g1atXiIuLg729PTw9PeHj44PmzZujXbt2cHFxyesm603++161atXg6+ubh62hwkIm5HVkBVEu8/f3F6eeOX36tFY/kCoyaNAgbNq0CUDmgXrQoEF6tpCIiIjov8Pb2xsREREAgKdPn8Lb2ztvG0RERIVOQEAABg8eDCBz2gtdA0+IiHLLzJkzxSlaZsyYgZkzZ+Ztg4iIiIiIiAqwgpuygYiIiIiIiIiIiIiIiIiIiIiISAkGRhERERERERERERERERERERERUaHDwCgiIiIiIiIiIiIiIiIiIiIiIip0GBhFRERERERERERERERERERERESFDgOjiIiIiIiIiIiIiIiIiIiIiIio0GFgFBERERERERERERERERERERERFToyQRCEvG6EMhkZGYiMjIS9vT1kMlleN4eIqNAaNWoUduzYYbD6Jk2ahEmTJhmsPiIq+Hx8fPDs2TOD1bdv3z40btzYYPURERFR3uJ3Ev08e/YMPj4+Bq0zKirKoPURERERERERERmSIAj4+PEj3N3dYWKiPC9Uvg6MevHiBTw8PPK6GURERERERERERERERERERERElM88f/4cpUqVUvq8WS62RWv29vYAMlfCwcEhj1tDRERElHdWDOqR100gIiIiIiIiIqJ8YEzA33ndBCIiIqI8FxcXBw8PDzG2SJl8HRiVNX2eg4MDA6OIiIjoP83J9b8zFQwRERERERERESnH38yIiIiI/k9WbJEyyifZIyIiIiIiIiIiIiIiIiIiIiIiKqDydcYoIiIiIsr0+ZlRed0EIiIiIiIiIiLKF+7ldQOIiIiICgxmjCIiIiIiIiIiIiIiIiIiIiIiokKHgVFERERERERERERERERERERERFToMDCKiIiIiIiIiIiIiIiIiIiIiIgKHQZGERERERERERERERERERERERFRocPAKCIiIiIiIiIiIiIiIiIiIiIiKnQYGEVERERERERERERERERERERERIUOA6OIiIiIiIiIiIiIiIiIiIiIiKjQYWAUEREREREREREREREREREREREVOgyMIiIiIiIiIiIiIiIiIiIiIiKiQoeBUUREREREREREREREREREREREVOgwMIqIiIiIiIiIiIiIiIiIiIiIiAodBkYREREREREREREREREREREREVGhw8AoIiIiIiIiIiIiIiIiIiIiIiIqdBgYRUREREREREREREREREREREREhQ4Do4iIiIiIiIiIiIiIiIiIiIiIqNBhYBQRERERERERERERERERERERERU6DIwiIiIiIiIiIiIiIiIiIiIiIqJCh4FRRERERERERERERERERERERERU6DAwioiIiIiIiIiIiIiIiIiIiIiICh2zvG4AEREREanXcwq7bUREREREREREBNzJ6wYQERERFSDMGEVERERERERERERERERERERERIUOA6OIiIiIiIiIiIiIiIiIiIiIiKjQYWAUEREREREREREREREREREREREVOgyMIiIiIiIiIiIiIiIiIiIiIiKiQoeBUUREREREREREREREREREREREVOgwMIqIiIiIiIiIiIiIiIiIiIiIiAodrQOjUlNTMWfOHLRq1QoODg6QyWQ4c+ZMjnKCIGDt2rWoUaMGrK2t4erqio4dOyI+Pt4Q7SYiIiIiIiIiIiIiIiIiIiIiIlJK68CohIQETJ8+HY8ePUL16tWVlps6dSq+/vprVKpUCcuXL8eUKVNgbm6OpKQkvRpMRERERERERERERERERERERESkjpm2C9jb2+PZs2fw8PDArl27cOnSpRxlwsLCsGjRIkydOhXz5s0T/z9u3Dj9WktERERERERERERERERERERERKQBrTNGmZqawsPDQ2WZHTt2wNzcHFOmTAEATp9HRERERERERERERERERERERES5SuvAKE0EBQWhevXq2LdvH1xdXWFvbw8PDw/s2LHDGC9HREREREREREREREREREREREQkYZTAqJcvX+Ldu3cYOXIkJk6ciD///BNlypRB3759cf36daXLJScnIy4uTnIjIiIiIiIiIiIiIiIiIiIiIiLSllECoxITExEeHo4FCxZg4sSJ6NmzJw4ePAg7OzssWrRI6XLz58+Ho6OjeFM3ZR8REREREREREREREREREREREZEiRgmMsrCwAAB07dpV/J+dnR0aNmyI27dvK11uypQpiI2NFW/Pnz83RvOIiIiIiIiIiIiIiIiIiIiIiKiQM0pgVLFixSR/sxQtWhRv375VupylpSUcHBwkNyIiIiIiIiIiIiIiIiIiIiIiIm0ZJTCqSpUqAIDXr19L/v/u3Tu4u7sb4yWJiIiIiIiIiIiIiIiIiIiIiIhERgmMatOmDQBg+/bt4v8+fPiAixcvok6dOsZ4SSIiIiIiIiIiIiIiIiIiIiIiIpGZLgutXLkSMTExCA0NBQBs2bIFFy5cgJOTE0aPHo2OHTuidu3amDp1Kt6+fQtPT0+sW7cO6enpmDx5skFXgIiIiIiIiIiIiIiIiIiIiIiIKDuZIAiCtgt5e3sjIiIix/+9vLwQHh4OIHPavAkTJuDAgQNISEiAr68v5s+fD39/f41fJy4uDo6OjoiNjYWDg4O2zSQiIiIqNKpvqp7XTSAiIiIiIiIionzgzsA7ed0EIiIiojynaUyRThmjsoKfVClWrBg2bdqkS/VERERERERERERERERERERERER6McnrBhARERERERERERERERERERERERkaA6OIiIiIiIiIiIiIiIiIiIiIiKjQYWAUEREREREREREREREREREREREVOgyMIiIiIiIiIiIiIiIiIiIiIiKiQoeBUUREREREREREREREREREREREVOgwMIqIiIiIiIiIiIiIiIiIiIiIiAodBkYREREREREREREREREREREREVGhw8AoIiIiIiIiIiIiIiIiIiIiIiIqdBgYRUREREREREREREREREREREREhQ4Do4iIiIiIiIiIiIiIiIiIiIiIqNBhYBQRERERERERERERERERERERERU6DIwiIiIiIiIiIiIiIiIiIiIiIqJCh4FRRERERERERERERERERERERERU6DAwioiIiIiIiIiIiIiIiIiIiIiICh0GRhERERERERERERERERERERERUaHDwCgiIiIiIiIiIiIiIiIiIiIiIip0GBhFRERERERERERERERERERERESFDgOjiIiIiIiIiIiIiIiIiIiIiIio0GFgFBERERERERERERERERERERERFToMjCIiIiIiIiIiIiIiIiIiIiIiokKHgVFERERERERERERERERERERERFToMDCKiIiIiIiIiIiIiIiIiIiIiIgKHQZGERERERERERERERERERERERFRocPAKCIiIiIiIiIiIiIiIiIiIiIiKnQYGEVERERERERERERERERERERERIUOA6OIiIiIiIiIiIiIiIiIiIiIiKjQYWAUEREREREREREREREREREREREVOgyMIiIiIiIiIiIiIiIiIiIiIiKiQoeBUUREREREREREREREREREREREVOgwMIqIiIiIiIiIiIiIiIiIiIiIiAodBkYREREREREREREREREREREREVGhw8AoIiIiIiIiIiIiIiIiIiIiIiIqdBgYRUREREREREREREREREREREREhQ4Do4iIiIiIiIiIiIiIiIiIiIiIqNBhYBQRERERERERERERERERERERERU6DIwiIiIiIiIiIiIiIiIiIiIiIqJCh4FRRERERERERERERERERERERERU6DAwioiIiIiIiIiIiIiIiIiIiIiICh0GRhERERERERERERERERERERERUaHDwCgiIiIiIiIiIiIiIiIiIiIiIip0GBhFRERERERERERERERERERERESFDgOjiIiIiIiIiIiIiIiIiIiIiIio0GFgFBERERERERERERERERERERERFToMjCIiIiIiIiIiIiIiIiIiIiIiokKHgVFERERERERERERERERERERERFToMDCKiIiIiIiIiIiIiIiIiIiIiIgKHQZGERERERERERERERERERERERFRocPAKCIiIiIiIiIiIiIiIiIiIiIiKnQYGEVERERERERERERERERERERERIUOA6OIiIiIiIiIiIiIiIiIiIiIiKjQYWAUEREREREREREREREREREREREVOmZ53QAiIiIiIiIiIiIiIiIiosIiPT0dqamped0MIiKiAsXMzAympqaQyWSGrdegtRERERERERERERERERER/QcJgoDXr18jJiYmr5tCRERUIJmamsLV1RWOjo4GC5BiYBQRERERERERERERERERkZ6ygqJcXV1hY2Nj8IwXREREhZUgCEhLS0NcXBxevXqFpKQkuLm5GaRuBkYREREREREREREREREREekhPT1dDIpydnbO6+YQEREVSPb29rC0tMT79+/h6uoKU1NTves0MUC7iIiIiIiIiIiIiIiIiIj+s1JTUwEANjY2edwSIiKigs3W1haCIIjnVn0xMIqIiIiIiIiIiIiIiIiIyAA4fR4REZF+DH0uZWAUEREREREREREREREREREREREVOloHRqWmpmLOnDlo1aoVHBwcIJPJcObMGZXLTJgwATKZDKNHj9a1nURERERERERERERERERERERERBrTOjAqISEB06dPx6NHj1C9enW15Z88eYLff/9dp8YRERERERERERERERERERERERHpQuvAKHt7ezx79gxPnjzBuHHj1Jb/4YcfMHjwYJ0aR0RERERERERERERERERElF/JZDL4+/vndTOMThAELFy4EOXLl4eFhQVkMhkGDRqU180iFQYNGgSZTIbw8HCD1XngwAHUrl0bdnZ2kMlk8Pb2Vlr2zJkzkMlkmDlzpsLnb968CZlMJrkFBAQYrK1EWcy0XcDU1BQeHh4alb1w4QKOHj2Kx48fY/ny5Vo3joiIiIiIiIiIiIiIiIiooPOefDCvm6BU+IIvjFJv//79sXXrVpQtWxaPHj1SWTYpKQk1a9bEw4cPMXToUKxfv1587tOnT5g0aRJ27twJQRAwbtw4TJo0CSYmWucAUSsryMOQgSSFxfbt2zF58mTUrl0bEyZMgIWFBXx8fPK6WZSLnjx5gm7dusHZ2RkjR46EnZ0dnJycdK6vRIkSmDFjBoDMIKm9e/dqvCz3VdKG1oFRmhIEAePHj8e4cePg6upqrJchIiIiIiIiIiIiIiIiIqJ85NChQ/j77781Lj9jxgxEREQofO67777D5s2bMXDgQMTHx+Onn36ClZWVRrMb5YZ79+7BxsYmr5thdIcOHQIA7N+/H25ubnncGsoLJ0+eREpKChYvXozevXurLV+3bl3cu3cPLi4uCp8vUaKEmE0qICBAq8AoIm0YPoz2/9u2bRuePHmCCRMmaLxMcnIy4uLiJDciIiIiIiIiIiIiIiIiIioYPn78iJEjR+KHH37QqHxwcDCWLFmisHxqaio2btyIP/74A2vW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6NChqF69Or755huVZZs3b467d+9i9erVWLduHYKDg3H16lX4+vpiyJAhaNSoESIiIjB69GgDrYnheXl5AQA8PT0BAGXLlgUA8Xf0rGCLvXv34tWrVxgxYoQkKAqAOPPSrl27dG7H7t27AQCTJ0+W/P/bb7+FtbW1+HxuSU9Ph6mpaY6kKvb29jkyKEVGRmL//v2oUKGCZBaqLK1atZI8rly5co6gKAD44osvAAB37txR2KZJkyaJ983NzdGqVSukp6fj4cOHmq2UAq6urjmCojRpy7hx48SgKABo3749gMwMVFn279+PtLQ0DBkyRBK41bt3b7i7u+vc5sJg7dq1MDU1xYoVK8SgKCAzUK1Lly44deqU0mkSBUHAkiVLcmybijJ7Uf5n8IxRxYsXx/79+3P8v0OHDvjiiy8wcuRIlC9f3tAvS0REREREREREREREREREeSA4OBi//vorfv75Z5QqVUpt+eXLl+Pq1au4cuUKTEzU5/Lw8vJCly5dsGbNGtSpUwfVq1fHrFmz0L59e42Wz2tZ055l/bW2tpY8TkpKAgBcu3YNAPDs2bMcmXDS0tIAAI8ePdK5Hffu3YOtrW2O3+sdHR1RunRp/Pvvv4iNjYWjo6POr6GNbt26Yfr06ahfvz569+6NevXq4bPPPlOYmen69esAAD8/P5iamqqtOyMjA+vXr8emTZtw9+5dfPz4EYIgiM9//PgxxzIuLi4oWrRojv8BQHx8vFbrlt3JkyexZMkSXLt2DR8+fEB6errKtgBAhQoV1LYlK0gq+5RwpqamqFatGiIjI/Vqd0H18eNHhIWFoUiRIlixYkWO58PDwyEIAh4/fow6derkeL5UqVI53n8quHQKjFq5ciViYmIQGhoKANiyZQsuXLgAJycnjB49WoxUzM7b21vpc0REREREREREREREREREVPAMHToUVapUwbfffqu27IsXLzBt2jSMGDECn332mdryd+/exc8//4yDBw/iyy+/xOnTp1GyZEl8//33GDp0KKysrDB06FD8+OOPkqww+YlMJgMAMYgr63HW36wgmZiYGABAYGAgAgMDFdalaIo5TcXHxyvNIuTs7AwgM6AktwKjpk2bBmdnZ2zYsAE//vgjBEGAubk5evTogTVr1kgCpLLeG00z9nz77bdYtWoVihcvju7du8PNzQ1mZmYIDw/Hpk2bxEAz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bg4REVGBpek5VdOYImaMIiIiIioA7jx9ltdNICIiIiIiIiIiIiIiIipQTPK6AURERERERERERERERERERERERIbGwCgiIiIiIiIiIiIiIiIiIiIiIip0OJUeEREREREREREREREREREVeL169cKVK1c0KmtmZoZHjx4ZuUVERJTXGBhFREREREREREREREREREQF3s6dO/O6CURElM9wKj0iIiIiIiIiIiIiIiIiIiIiIip0GBhFRERERERERERERERERERERESFDgOjiIiIiIiIiIiIiIiIiIiIiIio0GFgFBERERERERERERERERERERERFToMjCIiIiIiIiIiIiIiIiIiIiIiokKHgVFERERERERERERERERERERERFToMDCKiIiIiIiIiIiIiIiIiIiIiIgKHQZGERERERERERERERERERERERFRocPAKCIiIiIiIiIiIiIiIiIiIiIiKnTM8roBRERERERERERERERERESF2kzHvG6BcjNj87oFBZpMJkPTpk1x5syZvG6KUQmCgJ9//hnr169HREQEUlNTMXDgQAQEBOR104ziv/K5Ev0XMGMUERERERERERERERERERHp7OHDhxg8eDB8fHzg7OwMGxsbVK5cGWPGjEFkZKTS5UJCQtC9e3eUKFEClpaW8PDwQI8ePfDy5UuxzKdPnzB27FgUL14crq6umD9/PjIyMoyyHt7e3vD29jZK3QXd9u3bMXnyZDg6OmLChAmYMWMGOnfunNfNKtQCAgIgk8kKbfAZUW5hxigiIiIiIiIiIiIiIiIiItJZaGgo/vnnH/j5+aFRo0awt7dHWFgY1qxZg23btuH/sXfnYVVW+///X9shQFAcUFBUIAdwyiHs65g4lbM4a3oStZN9zHKqE8dUsDIcTg5oajmAqMdKc0hFywEwS3EoZ0xJIS2zUgGZHIDfH/72Pm4Bhc2k9Hxcl5ftda+17vd978Xhuo6va63vv/9eHh4eZmO+/PJLDR48WDY2Nurdu7eqV6+uP//8U2FhYbp06ZKcnZ0lSePHj1dISIiGDx+uxMRETZ06VdbW1powYUJRPGomUVFRKlOmTFGXUeBCQ0MlSVu3blXVqlWLuJqC93f5XoG/A4JRAAAAAAAAAAAAAACLde7cWdeuXVPp0qXN2tetW6eXXnpJfn5++vzzz03tV69e1ciRI1WjRg1F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pk2b6p133sm0Dix577lhXAf3/8mOJevdEj/++KOef/550xp44403dPPmzUz9crPeLa397Nmz8vHxUY0aNWRlZaWaNWtq6NChOnbsWJb9f/31Vw0YMEDly5dX2bJlNWjQIN24cSPLvtu2bVOHDh1kb2+vMmXKqEWLFtnu8pWbNVMY2DEKAAAAAAAAAAAAAFBoDhw4IElq06aNWXvjxo1lb29vul6xYkXVrl1b06ZN07Jly5SUlKSAgAC1aNHCbFxMTIzi4+PVuHHjXNfi4+NjCjbNnz9f0r3j+4zKly//0DHTp09/5D1WrlypgQMH6pNPPpGPj48cHBzk4+OjoKAgjRw5UpcvXzb1DQsLU48ePXT37l317dtXzs7OioyMlK+vr86ePaugoKBcP6ORn5+fJCkuLk4LFixQ48aN5e3tbbrepEkTs/5nzpxRy5YtlZSUpEGDBqlmzZravXu33nvvPR08eFA7d+7M025EY8aMUc2aNdWmTRvVqFFD165d08aNG/X8889r586dat++faYx48aN0927dzV8+HDduHFDa9eulZeXlw4ePKgGDRpk6t+5c2dVrlxZb7zxhk6dOqXVq1fr6NGjOnLkiGxsbEz9LHnvZ8+eVffu3dWrVy89++yz2rBhg2bMmKGqVavq9ddfN/W7cuWK2rRpoz///FMDBgyQq6urtm3bZtoFLb+FhITot99+U2BgoFnw0FIvv/yyNmzYoJYtW+q1117TrVu3dObMGX300UeaMGGCnJycMo3J6XvPrftDiMHBwYqNjc22b27XuyUSEhLUqVMnNW/eXOPGjdN3332nRYsW6eTJk9q7d69KlPjfXkW5We+W1L5nzx716tVLt2/fVq9eveTu7q4bN25o+/btKl26tIKDg83637p1Sx07dpSLi4teeeUV7d27V1988YXS09O1fv16s76zZs2Sr6+vqlSpooEDB8rGxkY7duyQt7e3goKCMgW1LFkzBcmQkVVc8TGRkJAge3t7xcfHq1y5ckVdDgAAQNHxty/qCgAAAAAAAPA48I8v6gqQhdTUVF28eFFubm6ytrbOdP2y77dFUFXOVJ/ZttDvWalSJRkMBv3111/68ccfNWbMGI0dO1ZDhw5V48aNdeLECaWkpMja2lp79uyRt7e3EhMTJUmOjo7au3ev6tevr4iICC1YsEB79uzRjBkzNHbs2DzV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OTm6efOmWrdube7Tpk0bff/99w+9pg0bNqhz585ydXWVg4ODfHx89MorrygtLa3EMStXrlSrVq1kZ2enFi1a6NNPPy3SJyQkRAaDQenp6RbtiYmJMhgMioyMtGj38vKSwWCQwWCQ0WjUwYMHzZ8NBoPFTk/p6enm9q5du0qSpk+fbtH/l/M+qKtXr2rChAny9vZWjRo11KBBA73++uu6evVqqe/ZuHFji3danO+++04Gg0EjR460aPf39zc/mzlz5qhFixays7NTgwYN9Oabb1r0vfs5FPesTSIjI819Vq9eLUny9vb+1ee4Y8cOde/eXc7OzqpZs6b8/PwUHx9//w+iGKbvxd1rHzlyZInfgV+OMf0kJiYWe3+DwaDBgwfr+eefl729vfr166d//vOf6tSpk5ycnBQcHKybN29ajCkoKNCCBQvUvn172dvbq3bt2urfv79OnjxZprUCFaVCdoy6cOGCPvnkk4qYCgAAAAAAAAAAAABQiR0+fFiS1KVLF4v2du3aydnZ2Xy9bt26atasmaZNm6YVK1YoLy9PUVFR8vPzsxiXnp6urKwstWvXrlT1fPzxxxo3bpy8vb314osvys7OTmlpadq4caN69OihZs2aFRkTGxurs2fPauDAgerUqZPWrVun4OBgtWzZUo899lip6pDuHB147do1SXdCTp6engoJCTFfb9++vfnPtWvXVkREhKQ7z2D16tXq2rWr/P39LfqU1pUrV9SlSxdduHBBzz77rIYMGaKLFy/qk08+0d///nclJyfLwcHhge/bqVMnbd68WdnZ2apVq1axfY4cOWLuW5w333xT0dHRGjRokFxdXZWamqrPP//cos8vn01J7n5e27ZtU0pKisaPH2/x7H75HGfPnq3w8HDVr19fgYGBsre311//+lcFBAQoJibG4p09CC8vL3PdX3/9teLj4zVgwACL9373n385JjExUQcPHrznHNu2bdOIESP02GOPaceOHfrHP/6hXr16ycnJSRs2bNCzzz6rV155RZJUWFiogIAA7dy5U23atNGrr76q3Nxcbd68WZ06ddIXX3yhtm3blmqtQEWpkGDUn/70J40cOVKLFi2qiOkAAAAAAAAAAAAAAJXUxYsX5eLiIkdHRx0/flxjx47VuHHjNGzYMHl6eurEiRPKz8+XnZ2dli1bpoCAALm5uUmS3NzcFBMT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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "appals.show_critical_path_time_breakdown().T" + ] + }, + { + "cell_type": "markdown", + "id": "94f75901", + "metadata": { + "papermill": { + "duration": 0.014921, + "end_time": "2024-12-06T05:56:21.656661", + "exception": false, + "start_time": "2024-12-06T05:56:21.641740", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Compare to vanilla" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "f9051ad7", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:56:21.687372Z", + "iopub.status.busy": "2024-12-06T05:56:21.687092Z", + "iopub.status.idle": "2024-12-06T05:56:57.099205Z", + "shell.execute_reply": "2024-12-06T05:56:57.098700Z" + }, + "papermill": { + "duration": 35.429191, + "end_time": "2024-12-06T05:56:57.100672", + "exception": false, + "start_time": "2024-12-06T05:56:21.671481", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "load data /sr213/application_1733153225851_0029/app.log\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "emon metric\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 1319:> (0 + 3) / 3]\r" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + "[Stage 1319:==================> (1 + 2) / 3]\r", + "\r", + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sar metric\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "time breakdown\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 application_1733153225851_0029application_1733153225851_0048diff
runtime132.1417.65648.67%
shuffle_write0.000.000.00%
f_wait_time0.000.000.00%
input read22.5422.540.00%
acc_task_time128.0113.99815.01%
output rows1.791.1851.69%
%user>90%0.990.935.91%
%kernel>10%0.990.972.85%
%iowait>10%0.310.62-49.30%
avg %user82.1141.2299.21%
avg %system6.104.5135.11%
avg %iowait0.170.74-76.60%
avg disk util7.1332.21-77.85%
time more than 90%0.000.000.00%
total read (G)5.245.39-2.75%
total write (G)0.021.12-97.81%
avg read bw (MB/s)37.52190.27-80.28%
avg write bw (MB/s)0.1839.61-99.55%
read bw %7559.27411.58-85.60%
read bw %95173.05484.54-64.29%
read bw max236.70510.35-53.62%
time_rd_morethan_950.050.0341.96%
write bw %750.071.07-93.45%
write bw %951.23165.69-99.25%
write bw max1.70812.51-99.79%
time_wr_morethan_950.000.03-100.00%
cached mean88.3393.90-5.93%
cached 75%132.00145.00-8.97%
cached max160.00188.00-14.89%
used mean2,060.73834.00147.09%
used 75%2,343.00852.00175.00%
used max2,346.00859.00173.11%
rx MB/s 75%0.000.000.00%
rx MB/s 95%0.000.000.00%
rx MB/s 99%0.000.000.00%
pgin mean37.37190.21-80.35%
pgin 75%59.00412.00-85.68%
pgin max352.00509.00-30.84%
pgout mean0.1340.97-99.68%
pgout 75%0.001.00-100.00%
pgout max2.00840.00-99.76%
fault mean952,586.87117,653.31709.66%
fault 75%1,426,717.00205,151.00595.45%
fault max2,628,392.00256,538.00924.56%
cpu%_avg0.880.4596.45%
cpu freq_avg3,460.223,241.926.73%
pathlength_sum17,960.001,933.00829.13%
ipc_avg1.271.1411.30%
\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 runtimeshuffle_writef_wait_timeinput readacc_task_timeoutput rows
real_queryid      
1\n", + "
132.14
\n", + "
17.65
\n", + "
648.67%
\n", + "
\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
\n", + "
22.54
\n", + "
22.54
\n", + "
0.00%
\n", + "
\n", + "
128.01
\n", + "
13.99
\n", + "
815.01%
\n", + "
\n", + "
1.79
\n", + "
1.18
\n", + "
51.69%
\n", + "
\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 sr217agg
0  
%user>90%\n", + "
0.99
\n", + "
0.93
\n", + "
5.91%
\n", + "
\n", + "
0.99
\n", + "
0.93
\n", + "
5.91%
\n", + "
%kernel>10%\n", + "
0.99
\n", + "
0.97
\n", + "
2.85%
\n", + "
\n", + "
0.99
\n", + "
0.97
\n", + "
2.85%
\n", + "
%iowait>10%\n", + "
0.31
\n", + "
0.62
\n", + "
-49.30%
\n", + "
\n", + "
0.31
\n", + "
0.62
\n", + "
-49.30%
\n", + "
avg %user\n", + "
82.11
\n", + "
41.22
\n", + "
99.21%
\n", + "
\n", + "
82.11
\n", + "
41.22
\n", + "
99.21%
\n", + "
avg %system\n", + "
6.10
\n", + "
4.51
\n", + "
35.11%
\n", + "
\n", + "
6.10
\n", + "
4.51
\n", + "
35.11%
\n", + "
avg %iowait\n", + "
0.17
\n", + "
0.74
\n", + "
-76.60%
\n", + "
\n", + "
0.17
\n", + "
0.74
\n", + "
-76.60%
\n", + "
avg disk util\n", + "
7.13
\n", + "
32.21
\n", + "
-77.85%
\n", + "
\n", + "
7.13
\n", + "
32.21
\n", + "
-77.85%
\n", + "
time more than 90%\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
total read (G)\n", + "
5.24
\n", + "
5.39
\n", + "
-2.75%
\n", + "
\n", + "
5.24
\n", + "
5.39
\n", + "
-2.75%
\n", + "
total write (G)\n", + "
0.02
\n", + "
1.12
\n", + "
-97.81%
\n", + "
\n", + "
0.02
\n", + "
1.12
\n", + "
-97.81%
\n", + "
avg read bw (MB/s)\n", + "
37.52
\n", + "
190.27
\n", + "
-80.28%
\n", + "
\n", + "
37.52
\n", + "
190.27
\n", + "
-80.28%
\n", + "
avg write bw (MB/s)\n", + "
0.18
\n", + "
39.61
\n", + "
-99.55%
\n", + "
\n", + "
0.18
\n", + "
39.61
\n", + "
-99.55%
\n", + "
read bw %75\n", + "
59.27
\n", + "
411.58
\n", + "
-85.60%
\n", + "
\n", + "
59.27
\n", + "
411.58
\n", + "
-85.60%
\n", + "
read bw %95\n", + "
173.05
\n", + "
484.54
\n", + "
-64.29%
\n", + "
\n", + "
173.05
\n", + "
484.54
\n", + "
-64.29%
\n", + "
read bw max\n", + "
236.70
\n", + "
510.35
\n", + "
-53.62%
\n", + "
\n", + "
236.70
\n", + "
510.35
\n", + "
-53.62%
\n", + "
time_rd_morethan_95\n", + "
0.05
\n", + "
0.03
\n", + "
41.96%
\n", + "
\n", + "
0.05
\n", + "
0.03
\n", + "
41.96%
\n", + "
write bw %75\n", + "
0.07
\n", + "
1.07
\n", + "
-93.45%
\n", + "
\n", + "
0.07
\n", + "
1.07
\n", + "
-93.45%
\n", + "
write bw %95\n", + "
1.23
\n", + "
165.69
\n", + "
-99.25%
\n", + "
\n", + "
1.23
\n", + "
165.69
\n", + "
-99.25%
\n", + "
write bw max\n", + "
1.70
\n", + "
812.51
\n", + "
-99.79%
\n", + "
\n", + "
1.70
\n", + "
812.51
\n", + "
-99.79%
\n", + "
time_wr_morethan_95\n", + "
0.00
\n", + "
0.03
\n", + "
-100.00%
\n", + "
\n", + "
0.00
\n", + "
0.03
\n", + "
-100.00%
\n", + "
cached mean\n", + "
88.33
\n", + "
93.90
\n", + "
-5.93%
\n", + "
\n", + "
88.33
\n", + "
93.90
\n", + "
-5.93%
\n", + "
cached 75%\n", + "
132.00
\n", + "
145.00
\n", + "
-8.97%
\n", + "
\n", + "
132.00
\n", + "
145.00
\n", + "
-8.97%
\n", + "
cached max\n", + "
160.00
\n", + "
188.00
\n", + "
-14.89%
\n", + "
\n", + "
160.00
\n", + "
188.00
\n", + "
-14.89%
\n", + "
used mean\n", + "
2,060.73
\n", + "
834.00
\n", + "
147.09%
\n", + "
\n", + "
2,060.73
\n", + "
834.00
\n", + "
147.09%
\n", + "
used 75%\n", + "
2,343.00
\n", + "
852.00
\n", + "
175.00%
\n", + "
\n", + "
2,343.00
\n", + "
852.00
\n", + "
175.00%
\n", + "
used max\n", + "
2,346.00
\n", + "
859.00
\n", + "
173.11%
\n", + "
\n", + "
2,346.00
\n", + "
859.00
\n", + "
173.11%
\n", + "
rx MB/s 75%\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
rx MB/s 95%\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
rx MB/s 99%\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
\n", + "
0.00
\n", + "
0.00
\n", + "
nan%
\n", + "
pgin mean\n", + "
37.37
\n", + "
190.21
\n", + "
-80.35%
\n", + "
\n", + "
37.37
\n", + "
190.21
\n", + "
-80.35%
\n", + "
pgin 75%\n", + "
59.00
\n", + "
412.00
\n", + "
-85.68%
\n", + "
\n", + "
59.00
\n", + "
412.00
\n", + "
-85.68%
\n", + "
pgin max\n", + "
352.00
\n", + "
509.00
\n", + "
-30.84%
\n", + "
\n", + "
352.00
\n", + "
509.00
\n", + "
-30.84%
\n", + "
pgout mean\n", + "
0.13
\n", + "
40.97
\n", + "
-99.68%
\n", + "
\n", + "
0.13
\n", + "
40.97
\n", + "
-99.68%
\n", + "
pgout 75%\n", + "
0.00
\n", + "
1.00
\n", + "
-100.00%
\n", + "
\n", + "
0.00
\n", + "
1.00
\n", + "
-100.00%
\n", + "
pgout max\n", + "
2.00
\n", + "
840.00
\n", + "
-99.76%
\n", + "
\n", + "
2.00
\n", + "
840.00
\n", + "
-99.76%
\n", + "
fault mean\n", + "
952,586.87
\n", + "
117,653.31
\n", + "
709.66%
\n", + "
\n", + "
952,586.87
\n", + "
117,653.31
\n", + "
709.66%
\n", + "
fault 75%\n", + "
1,426,717.00
\n", + "
205,151.00
\n", + "
595.45%
\n", + "
\n", + "
1,426,717.00
\n", + "
205,151.00
\n", + "
595.45%
\n", + "
fault max\n", + "
2,628,392.00
\n", + "
256,538.00
\n", + "
924.56%
\n", + "
\n", + "
2,628,392.00
\n", + "
256,538.00
\n", + "
924.56%
\n", + "
\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
clientsr217agg
cpu%_avg\n", + "
0.88
\n", + "
0.45
\n", + "
96.45%
\n", + "
\n", + "
0.88
\n", + "
0.45
\n", + "
96.45%
\n", + "
cpu freq_avg\n", + "
3,460.22
\n", + "
3,241.92
\n", + "
6.73%
\n", + "
\n", + "
3,460.22
\n", + "
3,241.92
\n", + "
6.73%
\n", + "
pathlength_sum\n", + "
17,960.00
\n", + "
1,933.00
\n", + "
829.13%
\n", + "
\n", + "
17,960.00
\n", + "
1,933.00
\n", + "
829.13%
\n", + "
ipc_avg\n", + "
1.27
\n", + "
1.14
\n", + "
11.30%
\n", + "
\n", + "
1.27
\n", + "
1.14
\n", + "
11.30%
\n", + "
\n", + "\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 indexStage IDJob IDreal_queryidqueryidtotal_timestdev_timeacc_totaltotal
008818127.981.9199.65%99.65%
11109180.29nan99.87%0.23%
221210180.09nan99.94%0.07%
331511180.07nan100.00%0.06%
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 indexStage IDJob IDreal_queryidqueryidtotal_timestdev_timeacc_totaltotal
00881813.860.3286.65%86.65%
111210180.98nan92.80%6.15%
22109180.74nan97.43%4.63%
331511180.41nan100.00%2.57%
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAACVAAAAKnCAYAAABqVPSgAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAABuFElEQVR4nOzdbZiVZb03/u8I44DAIIKA6SiEkXo3iWZPJOIOfCBBxVSyh43ZFq1k32roDjLDcqdUpImZtz1IYrubQlOw0EiDNLoxNZWdWSYikCKCCoIyIKz/i/6s7QTImnHGMa7P5zjW0cy5fus8f+d1rZwXfI/rrCqVSqUAAAAAAAAAAAAU0C5t3QAAAAAAAAAAAEBbEaACAAAAAAAAAAAKS4AKAAAAAAAAAAAoLAEqAAAAAAAAAACgsASoAAAAAAAAAACAwhKgAgAAAAAAAAAACkuACgAAAAAAAAAAKKz2bd1AS9i8eXOeeuqpdOnSJVVVVW3dDgAAAAAAAAAA0MZKpVJefPHFvOUtb8kuu2z/OVM7RYDqqaeeSl1dXVu3AQAAAAAAAAAAvMksXbo0++yzz3bf3ykCVF26dEny983W1ta2cTcAAAAAAAAAAEBbW7NmTerq6srZou3ZKQJUW47tq62tFaACAAAAAAAAAADKtmSLtmf7h/sBAAAAAAAAAADs5ASoAAAAAAAAAACAwhKgAgAAAAAAAAAACkuACgAAAAAAAAAAKCwBKgAAAAAAAAAAoLDat3UDAAAAAAAAALwxSqVSNm3alFdeeaWtWwGAZquurk67du1abD4BKgAAAAAAAICdXKlUygsvvJBnn302mzZtaut2AOB123333dO7d+9UVVW97rkEqAAAAAAAAAB2csuXL88LL7yQ2tra1NbWpn379i3yD84A8EYrlUp56aWXsmLFiiTJXnvt9brnFKACAAAAAAAA2Ilt2rQpq1evzp577pkePXq0dTsA8Lp17NgxSbJixYr07NnzdR/nt0tLNAUAAAAAAADAm9PGjRtTKpXSqVOntm4FAFrMbrvtluTvf+deLwEqAAAAAAAAgAJwZB8AO5OW/LsmQAUAAAAAAAAAABSWABUAAAAAAAAAAFBYAlQAAAAAAAAA8AaYOHGioxT/fx//+MdTVVVVfs2dO3eHn3mzX783e3/A9glQAQAAAAAAAEAz3XLLLbnyyivbuo1/Op/5zGcybdq0TJgwoa1beU3/7Pd348aN+cpXvpKjjz46tbW12w2r9enTp1Gg7dWvo446qlx3xx135Ljjjsvee++dDh06pF+/fhk7dmxWrVrVaL5K6yrtb+rUqdvs7cgjj2zWur///e9zxhlnZP/9989uu+2W/v3754ILLsiLL77YrLpK+0uSu+++O//yL/+Sbt26pUePHjn66KOzYMGCZs1X6fVriueffz6nn356unXrlq5du2bUqFFZsWJFs+oqvX5JMmPGjBxyyCHp0KFD9txzz5xxxhlb3bfW1P4NWwkAAAAAAACAN50+n/95W7eQxZcf19YtNNstt9ySuXPn5txzz91h7UUXXZTPf/7zrd/UP4GBAwdm4MCBmTt3br761a9W9Jm2uH7/7Pd33bp1ufjii9O3b9/U19dn/vz526y78sors3bt2kZjixcvzhe/+MVGAaqHHnoo1dXV+exnP5tevXpl6dKl+fa3v50777wzDzzwQDp06NCkukr72+KKK65Ijx49yr/36tWr0fuVrjt58uTMnz8/H/nIR9K/f//86U9/ypQpU3LXXXdlwYIFad++fZPqKu3vwQcfzNChQ3PwwQfn0ksvzcaNG/Od73wnQ4YMyX333ZcDDjigSfM19fpVYuTIkbn//vszfvz4VFdXZ9KkSRk2bFjuvffetGvXrkl1lV6/X//61znllFPygQ98IJMnT86yZctyxRVX5I9//GN+97vfZZddWv/5UAJUAAAAAAAAAPAGaN++/VaBCyr3Zr9+b8b+unTpkiVLlqSuri4zZszYbsDmxBNP3Grsy1/+cqqqqnLaaaeVxy688MKt6t71rnfl+OOPz2233ZaTTz65SXWV9vfqPvv06bPd9ytd97zzzsuNN97Y6H7tu+++OffcczNz5sycdNJJTaqrtL/rr78+VVVV+dWvfpXa2tokybBhw3LAAQdkxowZueiii5o0X1Ov347MmTMn8+bNy9SpUzN69OgkyUEHHZThw4fnpptuyqmnntqkukqv36WXXpq99947d911V3bdddckydve9rZ86lOfys9//vOMGDHide2rEo7wAwAAAAAAAOCfXlVVVSZOnJhbbrkl9fX15eO7fvGLXyT5nyOxFi9e3Ohzffr0yemnn17+fUvdvffem5EjR6ZLly7p169fvv/972+1XlVVVX74wx/mySefbHTM1tSpUxvV7r///o3e/0eLFy9OVVVVJkyYkB49euSggw7K/PnzM2DAgHTv3j3f+c53GtU/++yzGTNmTHr37p0OHTrk0EMPLe+zqZ577rmMGzcu73znO9OlS5fU1tZm6NChWwUxJk6cmKqqqsyfPz8HH3xwOnTokHe961255557mlXXFDu6fq/2m9/8JkcffXS6du2arl275sgjj8wvf/nLJu+3Je/vFo888kg+9KEPpUuXLunSpUuOO+64PProo41qKv3+Vapdu3apq6tr1mdvvPHGHH744Tv8/F577ZUk2zzmbUd1Te2vVCplzZo1KZVKFX9mW+u+973v3SrsNnTo0CTJn//85ybXVdrfM888kw4dOpTDU0nSs2fP7fa+o/lez/3dllmzZqWmpiajRo0qjw0bNizdu3fPzJkzm1xX6fVbuHBhjjjiiHJ4KvmfUF9z/9vWVAJUAAAAAAAAAOwU7r333nzyk5/Mhz70oVx55ZUZOnToVoGpSv3rv/5r3vKWt2TSpEnZY4898m//9m954IEHyu9PmzYt06ZNy6BBg9KjR4/y79OmTcsRRxzRaK7Jkydn2rRpGTly5GuuOWfOnHzhC1/I4sWL88EPfjAnnHBCPvCBD2TcuHHZuHFjkmTNmjUZNGhQbrrpppx99tn55je/mW7duuX444/P3Llzm7zPRYsW5fvf/34GDx6cK664Il/60peybNmyDBkyZKtwT5KcdNJJGTJkSC677LK8+OKLGTZsWJ544olm11Wi0us3a9asfPCDH8ySJUty4YUX5hvf+Eb23nvvXHfddU3eb0vf3xUrVmTw4MG57777MmHChEyYMCH33ntvBg8enJUrV25Vv6PvX2tbsGBBHnvssXz0ox/d5vurV6/OM888k3vuuSfnnHNOqqqqMnDgwGbXVerggw8uh+M+/elP56WXXnpd/b3as88+m+R/AlfNqdtRf4MHD87q1aszbty4LFq0KI8++mjGjh2bPffcs1GQs6n7bSkLFy5M//79y0cdJskuu+yS+vr6LFy4sMl127Kt67d+/fpGcyVJx44dkyR/+tOfmr+hJnhzPTsOAAAAAAAAAJrpjjvuyH333ZdDDjmkPLZp06ZmzTVixIh8/etfL/+833775bbbbsuhhx6aJPn4xz+eJPnVr36VJUuWlH/flhNOOCFJ8te//jU/+9nPtlt33nnn5aMf/WjuuOOOLFq0KJdcckkWLFiQWbNm5fHHH88BBxyQr3/961m0aFEeeOCBvOMd70iSnH322RkwYEAuueSSHHnkkU3a59vf/vYsWbIkXbp0KY+dcsop6dOnT37wgx/ka1/7WqP6s846K5dcckmSZOTIkenXr1+uuOKKXHXVVc2qq0Ql12/Tpk0555xz0q9fv9x3333p3LlzkuTMM8/M008/3eT9tvT9veaaa7Jy5crMnz8/73//+5MkgwYNyqBBg3LNNdfk4osvblS/o+9fa5s2bVqqq6tzyimnbPP9Y445JgsWLEiSdOvWLddcc00GDBjQ7Lod6dSpU8aMGZMjjjgi1dXV+cUvfpFrr702TzzxRG6//fYWWfc73/lOOnfuvMPj4rZVV2l/Z555Zh566KFceeWVmTx5cpK/fyd/97vfZZ999mn2flvK8uXLy30MHTo0zz77bH7/+9+nZ8+eeeSRR5pcty3bun79+vXLQw891Kju//2//5fkfwJXrU2ACgAAAAAAAICdwlFHHdUoPJX8/Yir5nj104Tq6urSo0ePLFu27HX1tyNbjvLq3r171q5dmyTZY489kiTPP/98kuTmm2/Ou9/97vTu3bvRk4sGDhyY66+/Pps2bWrSnl8dJHrllVeyevXq7LbbbunRo8c2nxh12mmnlX/u06dP3vOe92TevHnNrmsp999/f5YsWZIpU6aUw1NbvPpJN03db0uZO3du3vrWt5bDU0ly+OGHp2/fvpk7d+5WAaq2+P5tsXHjxkyfPj1HH310unfvvs2aKVOmZOXKlXnooYdy66235i1vecvrqtuRU045pVGY69RTT02PHj0yefLk/OY3v9nqqWBNXfcnP/lJfvKTn+Rb3/rWdvf8WnWV9te+ffv0798/H/nIRzJixIi8/PLLmTRpUk444YTMmzevPGdT99tSGhoaysfoLV68OM8//3w2btyYmpqarF+/vsl1/2h71+9Tn/pUxo4dm4kTJ+Zf//Vfs3Tp0px99tnZfffd09DQ0Cp7/UcCVAAAAAAAAADsFA444IAWm6t3796Nft9tt92yYcOGFpt/W9q3//s/4VdXVzf6OUl57ccffzwNDQ3Zc889tznHmjVr0q1bt4rX3Lx5c6ZMmZKrr746TzzxRKMndm0rCFFXV9fo93322Se//vWvm13XUraEnw488MDXrGvqflvK008/nX333Xer8X333Td/+9vfthpvi+/fFrNnz87KlSu3e3xfkrz73e9OkgwbNiyDBg3KEUcckblz52bQoEHNqmuOT3/605k8eXLmzZu3VaCoKes+/PDD+dSnPpWTTz45Y8eO3e56lda9Vn+XXXZZrr322jz22GPlANKQIUOy//77Z/LkyfnqV7/arP22lJqamvL37MEHH8ymTZvSqVOnNDQ0NDpir9K6V3ut63fWWWfl97//fS655JJccsklqaqqyrnnnpsHHnggzz33XKvs9R8JUAEAAAAAAACwU9h9992b/JntHfG3yy67vM5uWlapVEqSVFVV5Zhjjsm4ceO2WfePT1/akUmTJmXChAn52Mc+lksvvbT8VJjTTjutvOaObAmCtFRda2qJ/b4R2vL7N23atHTq1Kl8NOGOfOADH0ivXr3yve997zWDUZXWVWrLU6W2PJ2tOes+/fTTGT58eA488MDccMMNqaqq2uYcldbtqL/rrrsuRxxxRKP/L9TV1eXAAw/M/PnzmzxfS+vdu3eeeeaZJI3/W7JixYpGob5K67bY0fWrrq7OD3/4w3z1q1/NokWLst9++2XfffdN3759dxiKbCkCVAAAAAAAAADs9LYEFl566aXy2ObNm7NixYrXNW8lQYqW9Na3vjUvv/xyhg4d2iLzTZ8+PUcccURuvPHG8tjGjRvzwgsvbLN+6dKljZ70tWzZsq2eNtWUui335ZVXXmnuFpIkffv2TZI88sgjGTJkyHbrmrrflrq/e+21V5YsWbLV+JNPPlnu/c1g9erVue222zJy5Mh06tSp4s9t2LChHKhpibpKLF26NEm2+zS2Ha27du3aHHfccamurs5tt92Wjh07bvOzldZV0t/f/va3bYY2N23alHXr1jV5vpZWX1+f6667LuvXry8/SWrz5s1ZuHBhjj322CbXJU27fnvvvXf23nvvJMmiRYuyePHijB49uqW3uU1vrsgsAAAAAAAAALSCLf8of//995fHZs6c+bqPRevSpUtWrlz5ugNAlRo5cmTuvvvubT6tZkvAoinatWtXPiZwi+9973vb3c+Pf/zj8s+LFy/Ovffem8GDBze7bp999kmS/PWvf21y76/2rne9K3V1dfnWt76VF198sdF7rw7JNXW/LXV/jzzyyCxatCi/+93vymN33313Fi9enCOPPPJ1zd2SfvrTn2b9+vXbPb5vy1GJr/bLX/4yq1atahSYq7SuUitXrtxq7KqrrkqSHHXUUU1e95VXXsnJJ5+cpUuX5vbbb0/Pnj23uW6ldZX217dv39x1111Zu3Zteezxxx/Po48+mvr6+ibP19KGDx+ehoaGTJ8+vTw2e/bsrFq1KiNGjGhyXaXXb1tPf7v44ovTrl27nHbaaS2xtR3yBCoAAAAAAAAAdnrve9/70qNHj5x//vlZunRpXnrppUyfPr18hFtzDRw4MFOmTMmYMWNy4oknZtddd019fX05sPXwww/n4YcfLv+cpPz0o86dO+fEE09s0noXXnhhZsyYkaFDh+ass87KgQcemGXLluXOO+9MbW1tZs+e3aT5jj/++EycODFnn312Dj300PzhD3/Irbfemh49emyz/tprr83atWtTV1eXa665JjU1NRk7dmyz6/bdd9+85z3vyVe+8pVs3rw5tbW1Oeyww8phl0qvX7t27fLtb387I0eOzGGHHZbRo0enZ8+eueeee7Ju3br89Kc/bdZ+W+r+fuYzn8m3v/3tnHjiiTn33HOTJFdccUV69uyZz3zmM9u5Oy3j6quvzgsvvJA//vGPSf5+RN8999yT3XffPeecc06j2mnTpqV79+455phjtjnXBz/4wbztbW/LMccck65du+a///u/c91112WPPfYo76spdZX2N2jQoBx66KE55JBD0rFjx8yZMye33nprPvGJT+Swww5r8rqf+9zncscdd2Ts2LFZsGBBFixYUH6vX79+ef/739+kukr7GzduXMaMGZPDDz88Z5xxRtavX5+rr7461dXVOf/888t1lc7X1Pu7I0cddVQGDRqUsWPH5qmnnkp1dXUuv/zyDBgwIB/+8IebXFfp9XvyySczevToHH/88encuXN+9rOf5Y477siECRPy9re/vUl7aLbSTmD16tWlJKXVq1e3dSsAAAAAAAAAbyovv/xy6ZFHHim9/PLLbd1Kq0pS+tKXvvSaNb/73e9KAwYMKHXs2LH03ve+t3T//feX9ttvv9Lo0aPLNddff30pSemJJ55o9Nl/rNti06ZNpc997nOlXr16laqqqkpJStdff335/S996UulJNt87bfffqVSqVR64oknSklKv/71r0ulUqk0evTo0uDBg7f5XqlUKq1cubL02c9+trTPPvuUdt1111JdXV3plFNOKc2ZM6eyi/UqDQ0NpQsuuKD0lre8pdSxY8fS4MGDSw899FCpX79+peOOO26rfcybN6/0jne8o1RTU1M65JBDSnPnzm00X6V1r/bXv/61NHjw4FJNTU0pSemKK65o0vV7tblz55aGDh1a6tKlS6lLly6lI444onT77bc3eb9btMT93eKPf/xj6dhjjy116tSp1KlTp9Kxxx5beuSRRxrVNPX7V4n99tuvov4WL15cqqqqKp111lnbnetrX/taaeDAgaU999yztOuuu5b69u1bOv3000tPPvlks+oq7e/zn/986YADDih16dKlVF1dXerfv3/psssuK73yyivNWnfw4MHbvW+vvs6V1lXaX6lUKt18882l973vfaXa2tpSp06dSkOHDi0tWLCgUU1T5qv0/lZq1apVpU984hOlrl27lrp06VI65ZRTSk8//XSz6iq9fs8991xp2LBhpe7du5dqampK9fX1pWuvvba0efPm1+y1kr9vlWaKqkqlbTwH65/MmjVr0rVr16xevTq1tbVt3Q4AQJvp8/mft3ULAABtbvHlx7V1CwAA8Kayfv36PPHEE+nbt286dOjQ1u3wT2rixIm55JJLtnnUVnPqAF6vSv6+VZop2qW1mgQAAAAAAAAAAHiza9/WDQAAAAAAAAAALWf58uUV1fXu3buVO6E1uL80he9LZQSoAAAAAAAAAGAnstdee1VUt3HjxrRvLzbwz8b9pSl8XypT3J0DAAAAAAAAwE5ozpw5FdW1a9eu4jknTpyYiRMntlgdzdca95edl+9LZQSoAAAAAAAAAGAnMnTo0LZugVbk/tIUvi+V2aWtGwAAAAAAAAAAAGgrAlQAAAAAAAAAAEBhCVABAAAAAAAAAACFJUAFAAAAAAAAAAAUlgAVAAAAAAAAAABQWAJUAAAAAAAAAABAYQlQAQAAAAAAAAAAhSVABQAAAAAAAABvgIkTJ6aqqqqt23hT+PjHP56qqqrya+7cuTv8zJv9+r3Z+wO2T4AKAAAAAAAAoMgmdm371z+xW265JVdeeWVbt/FP5zOf+UymTZuWCRMmtHUrr+mf/f5u3LgxX/nKV3L00UentrZ2u2G1Pn36NAq0vfp11FFHlevuuOOOHHfccdl7773ToUOH9OvXL2PHjs2qVasazVdpXaX9TZ06dZu9HXnkkc1a9/e//33OOOOM7L///tltt93Sv3//XHDBBXnxxRebVVdpf0ly991351/+5V/SrVu39OjRI0cffXQWLFjQrPkqvX5N8fzzz+f0009Pt27d0rVr14waNSorVqxodt2rjRs3LlVVVTnnnHO2eq+S69Ka2r9hKwEAAAAAAADATuaWW27J3Llzc+655+6w9qKLLsrnP//51m/qn8DAgQMzcODAzJ07N1/96lcr+kxbXL9/9vu7bt26XHzxxenbt2/q6+szf/78bdZdeeWVWbt2baOxxYsX54tf/GKjANVDDz2U6urqfPazn02vXr2ydOnSfPvb386dd96ZBx54IB06dGhSXaX9bXHFFVekR48e5d979erV6P1K1508eXLmz5+fj3zkI+nfv3/+9Kc/ZcqUKbnrrruyYMGCtG/fvkl1lfb34IMPZujQoTn44INz6aWXZuPGjfnOd76TIUOG5L777ssBBxzQpPmaev0qMXLkyNx///0ZP358qqurM2nSpAwbNiz33ntv2rVr1+S6LRYtWpTrrrtum2s29bq0BgEqAAAAAAAAAHgDtG/ffqvABZV7s1+/N2N/Xbp0yZIlS1JXV5cZM2ZsN2Bz4oknbjX25S9/OVVVVTnttNPKYxdeeOFWde9617ty/PHH57bbbsvJJ5/cpLpK+3t1n3369Nnu+5Wue9555+XGG29sdL/23XffnHvuuZk5c2ZOOumkJtVV2t/111+fqqqq/OpXv0ptbW2SZNiwYTnggAMyY8aMXHTRRU2ar6nXb0fmzJmTefPmZerUqRk9enSS5KCDDsrw4cNz00035dRTT21S3atdeOGF+eQnP5mrrrpqq/eael1agyP8AAAAAAAAAPinV1VVlYkTJ+aWW25JfX19+fiuX/ziF0n+50isxYsXN/pcnz59cvrpp5d/31J37733ZuTIkenSpUv69euX73//+1utV1VVlR/+8Id58sknGx2zNXXq1Ea1+++/f6P3/9HixYtTVVWVCRMmpEePHjnooIMyf/78DBgwIN27d893vvOdRvXPPvtsxowZk969e6dDhw459NBDy/tsqueeey7jxo3LO9/5znTp0iW1tbUZOnToVkGMiRMnpqqqKvPnz8/BBx+cDh065F3velfuueeeZtU1xY6u36v95je/ydFHH52uXbuma9euOfLII/PLX/6yyfttyfu7xSOPPJIPfehD6dKlS7p06ZLjjjsujz76aKOaSr9/lWrXrl3q6uqa9dkbb7wxhx9++A4/v9deeyXJDo9v21ZdU/srlUpZs2ZNSqVSxZ/Z1rrvfe97twq7DR06NEny5z//ucl1lfb3zDPPpEOHDuWQUJL07Nlzu73vaL7Xc3+3ZdasWampqcmoUaPKY8OGDUv37t0zc+bMJtdtcc899+SOO+7IF77whW2u29Tr0hoEqAAAAAAAAADYKdx777355Cc/mQ996EO58sorM3To0K0CU5X613/917zlLW/JpEmTsscee+Tf/u3f8sADD5TfnzZtWqZNm5ZBgwalR48e5d+nTZuWI444otFckydPzrRp0zJy5MjXXHPOnDn5whe+kMWLF+eDH/xgTjjhhHzgAx/IuHHjsnHjxiTJmjVrMmjQoNx00005++yz881vfjPdunXL8ccfn7lz5zZ5n4sWLcr3v//9DB48OFdccUW+9KUvZdmyZRkyZMhW4Z4kOemkkzJkyJBcdtllefHFFzNs2LA88cQTza6rRKXXb9asWfngBz+YJUuW5MILL8w3vvGN7L333o2ODat0vy19f1esWJHBgwfnvvvuy4QJEzJhwoTce++9GTx4cFauXLlV/Y6+f61twYIFeeyxx/LRj350m++vXr06zzzzTO65556cc845qaqqysCBA5tdV6mDDz64HI779Kc/nZdeeul19fdqzz77bJL/CVw1p25H/Q0ePDirV6/OuHHjsmjRojz66KMZO3Zs9txzz0ZBzqbut6UsXLgw/fv3Lx91mCS77LJL6uvrs3DhwibXJX8PgZ1//vk577zzthuKaup1aQ1vrmfHAQAAAAAAAEAz3XHHHbnvvvtyyCGHlMc2bdrUrLlGjBiRr3/96+Wf99tvv9x222059NBDkyQf//jHkyS/+tWvsmTJkvLv23LCCSckSf7617/mZz/72XbrzjvvvHz0ox/NHXfckUWLFuWSSy7JggULMmvWrDz++OM54IAD8vWvfz2LFi3KAw88kHe84x1JkrPPPjsDBgzIJZdckiOPPLJJ+3z729+eJUuWpEuXLuWxU045JX369MkPfvCDfO1rX2tUf9ZZZ+WSSy5JkowcOTL9+vXLFVdcsdWxXJXWVaKS67dp06acc8456devX+6777507tw5SXLmmWfm6aefbvJ+W/r+XnPNNVm5cmXmz5+f97///UmSQYMGZdCgQbnmmmty8cUXN6rf0fevtU2bNi3V1dU55ZRTtvn+MccckwULFiRJunXrlmuuuSYDBgxodt2OdOrUKWPGjMkRRxyR6urq/OIXv8i1116bJ554IrfffnuLrPud73wnnTt3zogRI5pcV2l/Z555Zh566KFceeWVmTx5cpK/fyd/97vfZZ999mn2flvK8uXLy30MHTo0zz77bH7/+9+nZ8+eeeSRR5pclyQ/+tGPsmjRoowbN26761Z6XVqTABUAAAAAAAAAO4WjjjqqUXgq+fsRV83x6qcJ1dXVpUePHlm2bNnr6m9HtjydpXv37lm7dm2SZI899kiSPP/880mSm2++Oe9+97vTu3fvRk8uGjhwYK6//vps2rSpSXt+dZDolVdeyerVq7PbbrulR48e23xi1GmnnVb+uU+fPnnPe96TefPmNbuupdx///1ZsmRJpkyZUg5PbfHqJwU1db8tZe7cuXnrW99aDk8lyeGHH56+fftm7ty5WwWo2uL7t8XGjRszffr0HH300enevfs2a6ZMmZKVK1fmoYceyq233pq3vOUtr6tuR0455ZRGYa5TTz01PXr0yOTJk/Ob3/xmq6eCNXXdn/zkJ/nJT36Sb33rW9vd82vVVdpf+/bt079//3zkIx/JiBEj8vLLL2fSpEk54YQTMm/evPKcTd1vS2loaMiuu+6a5O9Hiz7//PPZuHFjampqsn79+ibXvfzyy5kwYULGjx/f6Hi+f1TpdWlNAlQAAAAAAAAA7BQOOOCAFpurd+/ejX7fbbfdsmHDhhabf1vat//7P+FXV1c3+jlJee3HH388DQ0N2XPPPbc5x5o1a9KtW7eK19y8eXOmTJmSq6++Ok888USjJ3a9OgixRV1dXaPf99lnn/z6179udl1L2RJ+OvDAA1+zrqn7bSlPP/109t13363G99133/ztb3/barwtvn9bzJ49OytXrtzu8X1J8u53vztJMmzYsAwaNChHHHFE5s6dm0GDBjWrrjk+/elPZ/LkyZk3b95WgaKmrPvwww/nU5/6VE4++eSMHTt2u+tVWvda/V122WW59tpr89hjj5UDSEOGDMn++++fyZMn56tf/Wqz9ttSampqyt+zBx98MJs2bUqnTp3S0NDQ6Li+SusmT56cUqmUz372s6+57uu5Li1FgAoAAAAAAACAncLuu+/e5M9s74i/XXbZ5XV207JKpVKSpKqqKsccc8x2j8P6x6cv7cikSZMyYcKEfOxjH8ull15aftLLaaedVl5zR7YEHlqqrjW1xH7fCG35/Zs2bVo6depUPppwRz7wgQ+kV69e+d73vveawahK6yq15alSW57O1px1n3766QwfPjwHHnhgbrjhhlRVVW1zjkrrdtTfddddlyOOOKLR/xfq6upy4IEHZv78+U2er6X17t07zzzzTJLG/y1ZsWJFo1BfJXWrV6/OpEmT8h//8R+NnpaXJOvWrcuyZcvSq1evVFdXv67r0lIEqAAAAAAAAADY6W35h/mXXnqpPLZ58+asWLHidc1bSZCiJb31rW/Nyy+/nKFDh7bIfNOnT88RRxyRG2+8sTy2cePGvPDCC9usX7p0aaMnfS1btmyrp001pW7LfXnllVeau4UkSd++fZMkjzzySIYMGbLduqbut6Xu71577ZUlS5ZsNf7kk0+We38zWL16dW677baMHDkynTp1qvhzGzZsKAdqWqKuEkuXLk2S7T6NbUfrrl27Nscdd1yqq6tz2223pWPHjtv8bKV1lfT3t7/9bZuhzU2bNmXdunVNnq+l1dfX57rrrsv69evLT5LavHlzFi5cmGOPPbZJdc8//3zWrl2bL37xi/niF7/YaJ2pU6dm6tSp+f3vf5/DDjvsdV2XlvLmiswCAAAAAAAAQCvYe++9kyT3339/eWzmzJmv+1i0Ll26ZOXKla87AFSpkSNH5u67797mU1m2BCyaol27duVjArf43ve+t939/PjHPy7/vHjx4tx7770ZPHhws+v22WefJMlf//rXJvf+au9617tSV1eXb33rW3nxxRcbvffqkFxT99tS9/fII4/MokWL8rvf/a48dvfdd2fx4sU58sgjX9fcLemnP/1p1q9fv93j+7Yclfhqv/zlL7Nq1apGgblK6yr1j08wSpKrrroqSXLUUUc1ed1XXnklJ598cpYuXZrbb789PXv23Oa6ldZV2l/fvn1z1113Ze3ateWxxx9/PI8++mjq6+ubPF9LGz58eBoaGjJ9+vTy2OzZs7Nq1aqMGDGiSXW9evXKrFmztnolyXHHHZdZs2blbW97W5LKr0tr8gQqAAAAAAAAAHZ673vf+9KjR4+cf/75Wbp0aV566aVMnz69fIRbcw0cODBTpkzJmDFjcuKJJ2bXXXdNfX19ObD18MMP5+GHHy7/nKT89KPOnTvnxBNPbNJ6F154YWbMmJGhQ4fmrLPOyoEHHphly5blzjvvTG1tbWbPnt2k+Y4//vhMnDgxZ599dg499ND84Q9/yK233poePXpss/7aa6/N2rVrU1dXl2uuuSY1NTUZO3Zss+v23XffvOc978lXvvKVbN68ObW1tTnssMPKYZdKr1+7du3y7W9/OyNHjsxhhx2W0aNHp2fPnrnnnnuybt26/PSnP23Wflvq/n7mM5/Jt7/97Zx44ok599xzkyRXXHFFevbsmc985jPbuTst4+qrr84LL7yQP/7xj0n+fkTfPffck9133z3nnHNOo9pp06ale/fuOeaYY7Y51wc/+MG87W1vyzHHHJOuXbvmv//7v3Pddddljz32KO+rKXWV9jdo0KAceuihOeSQQ9KxY8fMmTMnt956az7xiU/ksMMOa/K6n/vc53LHHXdk7NixWbBgQRYsWFB+r1+/fnn/+9/fpLpK+xs3blzGjBmTww8/PGeccUbWr1+fq6++OtXV1Tn//PPLdZXO19T7uyNHHXVUBg0alLFjx+app55KdXV1Lr/88gwYMCAf/vCHm1TXsWPHDB8+fJvr9OnTp9F7lV6X1iRABQAAAAAAAFBkE1e3dQdviJqamsyaNSuf/vSnc+mll+ad73xnpk+fnpNOOul1zXvqqafmvvvuy4033pipU6emVCrl+uuvz+mnn54kufnmm3PJJZc0+swnPvGJJMl+++3X5ABVbW1tfvvb3+ZLX/pSZsyYkRUrVqRXr1553/velzFjxjS5//Hjx2fdunX50Y9+lBtuuCHvec97cvvtt2/3uvz0pz/NZz/72Tz22GM56KCDMnv27G0ezVdpXZL813/9Vz71qU/l/PPPT0NDQ6644opygKop12/EiBG58847c+mll+byyy9PkhxyyCGZMGFCs/fbUve3Z8+emTdvXj73uc/lP//zP5P8PSTzzW9+c7vhrZbyjW98I08++WT59x/84Afl/l4dsHnyySdz9913Z8yYMVs9pWuLz3zmM7nlllsyadKkrF69OnvvvXdGjRqVSy65JPvuu2+T6yrt78QTT8wtt9ySWbNmZf369enbt28uu+yyXHDBBc3q76GHHkqSTJkyZas9jh49uhyMqrSu0v7OPPPM9OjRI1/72tfyxS9+MZs2bcr73//+zJgxI+94xzvKdZXOV+n1q1RV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r702zz77bO6///4ceuihSZK+ffvmjDPOaNZ8X//617No0aI88MADecc73pEkOfvsszNgwIBccskl2wzE3HHHHbnvvvtyyCGHlMc2bdpU/vmEE05Ikvz1r3/dboCq0nX/9Kc/5cknn8x3v/vd/Nu//Vv586+88kqz9vv2t789S5YsSZcuXcpjp5xySvr06ZMf/OAH+drXvtak/Tbn+lVixIgR+d73vpckGT16dPbdd99cdtllue2225q07sc//vEkya9+9assWbKk/Ps/qrSuNb4vAAAAAAAAAIAj/KBiv/71r7P//vuXw1NJMmrUqNc8Ku+13HzzzXn3u9+d3r17Z+XKlVm5cmWee+65DBw4MPPnz99m0OWoo45qFIZJ/n5UYWus26lTpyTJb3/722zYsKH8+fbtm5e77NKlSzk89corr2TVqlXZbbfd0qNHjzzxxBPb/Mxr7bc5168So0aNKv9cW1ubYcOG5Te/+U15rLXW3ZG2+r4AAAAAAAAAwM7OE6igQsuWLcs+++zTaGy33XZL9+7dmzXf448/noaGhuy5557bfH/NmjXp1q1bo7FtHXPXWuvuv//+GTNmTK677rrcfPPN+cAHPpAhQ4bkjDPO2KqvSmzevDlTpkzJ1VdfnSeeeKJR4Gf9+vXb/Mxr7bc5168S/3iP99lnn7z44ot58cUX06VLl1Zbd0fa6vsCAAAAAAAAADs7ASqoUE1Nzev6/D8+IaiqqirHHHNMxo0bt836zp07bzW2++67v64emrru//k//ydnnXVWbr/99tx+++0ZN25cvvvd7+bBBx9Mhw4dmrTupEmTMmHChHzsYx/LpZdeWg6enXbaaSmVStv8zGvttznXr7mqqqrK9/+NXPcfe2iL7wsAAAAAAAAA7OwEqKBCdXV1eeyxxxqNvfTSS1m1alWjsV133bX83habN2/OihUrGtW99a1vzcsvv5yhQ4e2Usfb1tR1Dz300Bx66KGZMGFCvvnNb+Zzn/tc7rzzzhx33HFNWnf69Ok54ogjcuONN5bHNm7cmBdeeKFJ82zRWtdv2bJl+V//6381+r13797l+9rUdSs94nFHdW31fQEAAAAAAACAnd0ubd0A/LM48sgj89hjj+XBBx8sj02fPn2rpyftvffeSZL777+/PDZz5sxs2LChUd3IkSNz9913Z/78+VuttXTp0hbsvLFK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+cEPfpAbb7wxF154Ya1HAQAAAICNElABAAAAUDWHHnpoTj311BxxxBG1HuUT66KLLsrbb79d6zEAAAAACquu1gMAAAAAQJHV1dWlrs6v6QAAAABqxR2oAAAAAAqkVCpl4sSJueOOO9LU1JSuXbtmr732yt13313Zs2zZsowdOzaNjY3p2rVrBg8e3OF4kqxYsSIXXHBBBg0alB49eqShoSHDhw/P3Llzq34NLS0tGTp0aHbYYYcMHDgwd955Z/r165fTTz+9smfq1KkplUpZuHBhh/f+975ky673fZv7/N5+++00NDTke9/73gbvu/7661MqlfLUU09V1gYMGJBSqVR5bcqDDz6YwYMHp2vXrhk0aFD++te/fviHBAAAAMAW86dtAAAAAAXz6KOP5le/+lXGjh2b/v3758knn6yERqtWrcrQoUOzbNmyjBs3Lr179860adNy9NFH5/7778/hhx+eJFmwYEGuv/76nHrqqTnnnHOycuXK/O53v8uwYcPy5JNPZp999qnK7K+//nqGDRuWLl265NJLL83q1avz3e9+N+vWrdum823p9X7Qpj6/HXbYIcccc0xmzJiR6667rsNdpW677bbst99+OeCAAyprV155ZVavXp3p06dnxowZG53vmWeeyTe+8Y30798/kyZNyksvvZTRo0dv07UCAAAAsHECKgAAAICCue+++/L444/nC1/4QmXt3XffTZL88pe/zIIFC/LEE09k//33T5KcffbZOfDAA3PJJZdUgqK99947L7/8cnr06FE5xwknnJB+/frlD3/4Q6644oqqzP7rX/86y5Yty7x58zJ48OAkSf/+/XPGGWds0/m29Ho/aHOf37e//e3ceOONmT17do488sgk792ta/bs2bn44os7nOdb3/pWkuT555/fZEB1xRVXpK2tLQ888EAaGxuTJN26dcsvfvGLbbpeAAAAADbkEX4AAAAABXPEEUd0iH+SpHPnzkmS6dOn56CDDkpjY2Nef/31vP7661mxYkUOPfTQzJ07txIK9ejRoxJPrV+/PsuXL0+3bt2y66675sUXX6za7A8++GAGDBhQiaeSZMyYMZt9BN7mbOn1ftDmPr/hw4end+/eaW5urhybMWNG1q9fn5NOOmmr55szZ04OO+ywSjyVJKeccspWnwcAAACATXMHKgAAAICC2dzj9V544YW0trbmM5/5zEaPr1q1KjvvvHPa2toyZcqUXHPNNXnxxRc7hEbvvPPO/3zm9y1evDh77LFHh7Vu3bqlV69e23S+Lb3eD9rc51dXV5cTTjght9xyS37zm9+kvr4+t912Ww466KAMGDBgq+d75ZVXNrgLVt++fbf6PAAAAABsmoAKAAAAoGB22mmnTR4rlUo58sgjc8EFF2z0ePfu3ZMkkydPzoUXXphTTjkll112WSVgOvnkk9Pe3v4/n/l95XL5I73/v+8otaXX+0Gb+/yS9x7jd+2112bWrFkZMmRIZs+evc2PNOzates2vQ8AAACALSegAgAAAKBizz33zNtvv53hw4dvdl9zc3MOO+yw3HTTTZW1devW5c0339zo/i5duiR573F/H0WfPn3y3HPPdVhbs2ZNli9fvtHvt2bNmspaW1tbli5d2mHfll7v1jj00EPTr1+/NDc359VXX01bW1tOPPHEbTpX3759s3jx4g5rL7/88v9iTAAAAAD+n061HgAAAACAT45jjz02f/nLXzJ37twNji1atKjy786dO6e+vr7D8d///vebDKTef+ze888//5HmO/zww/Pcc89l/vz5lbXm5uYN7nr1uc99Lkkyb968ytrMmTOzdu3aDvu29Hq31sknn5w777wzN910U4YOHVqZZ2sNGzYsDz/8cJYsWVJZu/nmm7d5LgAAAAA25A5UAAAAAFT85Cc/ye23357hw4fnrLPOyr777pvFixdn9uzZaWhoyD333JMkOfroozNx4sScffbZGTx4cJ588snceeed2XXXXTd63r59++bggw/Oz372s7S1taWhoSFf+tKXss8++2zVfGPHjs3kyZMzatSonHvuuVm9enWuueaaDR61N2TIkOy66645//zzs2jRoqxZsybNzc2VRw1u7fVurZNPPjmXX3555syZk+uuu26D408//XSefvrpyr+TVO7m1b179xxzzDFJknPPPTe//e1v8/Wvfz1nnXVWFi5cmD/96U/bNBMAAAAAGyegAgAAAKCioaEhf/vb33LxxRfn9ttvz9KlS7PbbrtlyJAhGTt2bGXfhAkT8tZbb+Xmm2/ODTfckIMPPjj33ntvjjvuuE2e+5ZbbsmZZ56Z888/P62trbnqqqu2OqDq2bNnZs2alR/+8Ie56KKL0qdPn/zxj3/MOeec02FfuVzOXXfdle9///u57LLLMmjQoDQ3N28w35Ze79ZqamrK/vvvn2eeeSajR4/e4Pj06dNzySWXdFj7zne+kyT5/Oc/Xwmo+vfvn7vvvjvnnXdefvrTn2bvvffO9OnT85WvfGWbZwMAAACgo1L7f9/fHAAAAAC2M/369cvhhx+eqVOn1nqUii9+8YvZZZddMmvWrFqPAgAAAMBmdKr1AAAAAADwafPUU0/liSeeyCmnnFLrUQAAAAD4EB7hBwAAAEBNLVmyZIv2NTY2VnmSj+7vf/97Hn/88Vx11VXp3bt3TjjhhFqPBAAAAMCHEFABAAAAUFO77777Fu1bt25d6uo+2b/Ouv3223PppZdm7733zowZM7LjjjvWeiQAAAAAPkSpvb29vdZDAAAAAFBc999//xbtGzZsWEqlUpWnAQAAAKBoBFQAAAAAAAAAAEBhdar1AAAAAAAAAAAAALUioAIAAAAAAAAAAApLQAUAAAAAAAAAABSWgAoAAAAAAAAAACgsARUAAAAAAAAAAFBYAioAAAAAAAAAAKCwBFQAAAAAAAAAAEBh/R/ZA7WZDV/5KgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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Zyd/f39lZmZKklq3bq21a9eqd+/eys/P1+7duzVmzBhT/IEDB/TEE0+oadOmFs/76aefSpISExOVlZWlBQsWmM4FBgaaxc6bN0+XL19WcnKyNmzYcNMxt23bphkzZmjGjBkKDg7W1KlTdfjwYU2ePFljx46Vo6OjiouLFRQUpMLCQkVFRcloNGr9+vV66aWXtH37dvXs2dPiGqypo6CgQD169DA1eknS/Pnz1aNHD33zzTfy8PCwat6srCz17dtXvr6+SkhI0KlTp/TKK69Ui7O03rKyMoWHh6usrEwxMTFq0qSJjh8/ro0bN5o1UdXm+u3fv18LFy5UZGSkfH19dfjwYeXk5JjOW3J/s7Oz9ec//1nDhw/Xm2++qUuXLmnZsmXq1auXDh8+rDZt2lh1/Sydt23btqZ7XGXr1q1avXq12T2r6+cKD496aaBKTEzUCy+8YGqekqTmzZurbdu2Zl2HXl5eys/PlyQ1atTIdLygoEBeXl43Hd/JyUlOTk71kDkAAAAAAAAeBHx/BAAAAOB+k5eXp2bNmkmSQkJCVFhYqAMHDshoNOrYsWOSbvzHIqGhoWrbtq0kaeTIkercubPmzJmjVatWydPTU3PnzrWqgWr48OGSpO3bt+v06dOm9zUZOHCgJOn777+/ZQPVxIkTNWzYMG3dulXZ2dmKj4/X119/rU2bNunEiRNq06aN5s6dq+zsbB06dEjt27eXJL3++uvq1KmT4uPjrW50sbSOpUuXqqioSOnp6Xr22WclSUFBQQoKCtLSpUv13nvvWTXvnDlzVFFRoZ07d5r6HB599FHTwjJVLK03KytLp06d0rJlyzR27FjT569fv16r8X5p69atysjIUOfOnU3HysvLTa8tub9PPfWUTp8+LRcXF9OxV199VU8++aT+8pe/aM6cObe8XjWxZN7HH3/c7J6ePXtW0dHR+o//+A/179/fdLyunys8POplC7+zZ8+a/SWrUl5erqtXr5re+/v763//93/NtuurqKhQZmam/P396yM1AAAAAAAAAAAAAADuOaWlpaZFSnJycpSbm6tr167JycnJ9G/qnp6eysjI0L59+/T++++roKBAISEhKikpUUpKinbt2qUuXbrYsgxJktFolCS5u7ubXjdp0kSSdPHiRUlScnKynnnmGXl5eamoqEhFRUX64YcfFBgYqPT09Bp7DupC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mWeekZeXl4qKilRUVKQffvhBgYGBSk9PV3l5eb3klpqaqpYtW5qapyTp+eefl6+vr1JTU60er2HDhpKkffv2qayszHTcwaHm9WyGDh1qev3kk0+qa9euSktLs3peAHWLBioAAAAAAAAAAAAAAGzMycnJ1IBz5MgRZWdnq2HDhiotLTVt65eXl6c33nhDw4YN05kzZ/Tuu+9q2rRpWrBggTp06KBp06bZsgSTquYhR0dHs9eSTDWeOHFC6enp8vT0NPvzySefqKysTMXFxfWS2/nz5+Xj41PtuI+Pj86ePWv1eK1atVJkZKSSkpLk6empvn37at68eaZGsV9r3ry52ftmzZrVal4AdYst/AAAAAAAAAAAAAAAsDEvLy/l5+dLkho1amQ6XlBQIC8vL0nSI488ouDgYC1cuFDOzv9fe/cepnVV743/fc+BGQQGEBwGFU8oCU+zRbeWWmxRsUChQNta+9mlWVlZFJ5FK+XJtrDb1pNmPdunfqLbXdvygGihkSae2h4wlLQ8pCiIHEUGkBkOM78/5nFswgODjPcM83pd11wz9/qu71qfdV9dQ37nfa9VmaeeeipHHnlkpkyZkoEDB+bMM8/MAQcc0GqXo46mqakpSVIoFPLRj340Z5999pv2++v3oKP793//93zxi1/M7bffnttvvz1nn312/u///b+ZN29eS/jt7by+8xhQPAJUAAAAAAAAAFBktbW1ueqqq1JfX98SumlsbMz8+fMzevToJEnv3r1z0kkntdzzm9/8JkcddVTLzlMvv/xybr755m0KUBUKhe2wiq23zz77ZP369Rk1atR2Hfed1jFw4MC8+OKLW7S/8MIL2Xvvvbd53oMOOigHHXRQLrjggnzve9/LWWedlTvvvDPHHXdcq34LFy7M/vvv3/J60aJFW+xK1Ravh682bdq0XfpBV+UIPwAAAAAAAAAosrFjx6ahoSHXX399S9usWbOycuXKjBs37k3vKSkpSUNDQ8vr+vr6bQ5C9erVKytWrHjPAjYTJkzIvffemwceeGCLawsXLtzmcd9pHSNHjsxzzz2X3//+9y1t9957bxYsWJCRI0e2eb66urot5no9iPX68YV/7ec//3nLzwsWLMhDDz2UI444os3zvm733XdPkjz77LPbpR90VXagAgAAAAAAAIAiO+aYYzJixIhMnDgxixcvTnl5eaZO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h+aDH/zge1prWVmZv+kDO5SS93Kypqam/PCHP2zVtvPOO+faa6/Nq6++mrq6uvziF79ITU3Ne1kWAAAAAAAAABTVrbfemoqKipx00kktbWPGjEm/fv0yc+bMJMkDDzyQs846K5/61KcyadKkHHvssbnvvvve1byFQiGFQiHXXHNNXnjhhZbXhUIh06dPb9V33333bXX9by1YsCCFQiEXXHBB+vfvn2HDhuWBBx7I8OHD069fv/z4xz9u1X/58uU57bTTUlNTk8rKyhx00EH59a9/3e7rePLJJ3PsscemV69e6dWrV4477rj8+c9/3qZ5X3fPPffkIx/5SHr37p3evXtn5MiR+c1vftPmeadPn55CoZCHHnooEyZMSK9evTJ48OD89Kc/belTV1eXysrKfOMb39iijm984xvp1q1bXn311Za2trzPhUIhF198cWbMmJHa2tpUVlZm8ODBLf3b8j5DZyISCgAAAAAAAABFNn/+/AwZMiSVlZUtbSUlJamtrc38+fOTJEOGDMn111+fj3zkI1m6dGnuueeenHrqqS39H3744ey6667Zbbfdtnre//iP/0iSXHXVVfnTn/6U73//+y3XDj/88FZ9L7vssqxZsyY33XRTbr755rccc/bs2bnwwgtz4YUX5qijjsp5552XP/zhDzn77LPz+c9/PuXl5amrq8uIESOyfPnyTJw4MdXV1bnxxhvzsY99LL/97W8zcuTIrV5DW9axbNmyHHHEES1BryT53ve+lyOOOCJPPPFE+vfv36Z5k+bw24QJE7Lvvvvm3HPPTXV1de6+++5cddVV+chHPrJN837mM5/J0UcfnWnTpuXqq6/O5z//+Rx44IE56KCDUlVVlVGjRmXGjBm55JJLWt1388035+ijj06fPn2SZJve54ceeig/+MEPctppp2XvvffOH/7whyxYsKBN7zN0NgJUAAAAAAAAAFBkS5Ysye67754kGTVqVJYvX56HH3441dXVefLJJ5MkkydPzjHHHJOhQ4cmaQ7ZHHjggfnXf/3XXHvttdlll13y3e9+t00Bqn/+539Okvz2t7/Niy++2PL6zXz84x9Pkjz77LNvG6A644wz8k//9E+544478txzz2XKlCl58MEHc+utt+Yvf/lL9t9//3z3u9/Nc889l0cffTTvf//7kyRf+tKXMnz48EyZMqXNAaqtXceP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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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LVtKKpscg2Re7mDGjBnKz8/Xd999J29vb0lSlSpV9Prrr5dmmmWWYwCA0qCACgAAAACA29CvXz/169fP9Lx///7y8PDQrFmztHXrVrVv316enp7avXu3du7cqe+++047duxQWFiYBg4cqPj4eDVs2NCGM/gfLy8vSZK7u7suXbokSapZs6Yk6fz585KklStX6sEHH5S3t7cyMjJMrw0ODtZHH32kvLw82dvbWzz2gAEDTI9dXV3VvXt3ff3116ZjNxYSXbt2TRcuXFCVKlXk4eGho0ePWjzenj17lJKSovnz55uKmAoUbI9woxu/gevr6ysPDw+dOHHCdKxq1aqSpB07dmjIkCGqVKmSJMnBoXDqxdxxLZ1vSfEBAAAAAO4d8+fPV0ZGhn7++Wd9+eWXql27tumcLXMMCQkJat++val4SpKeeuqpUhdQlVWOAQBKgy38AAAAAACwsmeffVaStGXLFklSamqqnnvuOT355JM6fvy4XnnlFU2aNElz5sxR8+bNNWnSJFuGa1JQ7OPo6FjosXR9izpJOnLkiBITE+Xp6Vno57333lNOTo4yMzNLNXbdunWLPL948aIuXrwoScrPz9fcuXN13333ydnZWR4eHvL09FR6erqysrIsHq+gCKngG7sluTE5LF3/hm3BNZGkhg0bKiIiQnFxcfL09FSPHj00a9YsU+GZpeNaOt+S4gMAAAAA3DsefPBBde/eXZMmTdI///lPhYeHa9u2bZJsm2M4depUkc/vfn5+pe6vrHIMAFAarEAFAAAAAICVFXwztKB4pnLlygoNDdXcuXPl7OysX3/9VY8++qhiY2Pl4+OjqKgotWjRQgMHDrRl2LdkNBolSQaDQV27dtW4ceOKbffnVZVuh8FgkJOTkyRp+vTpio6O1lNPPaWpU6fK3d1dkjRw4EBTbGXJzq7k76C99957GjFihNavX6/169dr3Lhxev/99/XTTz/J2dnZovEsna858QEAAAAA7j0PP/ywatWqpUWLFikkJMSmOQZLP9uW5E7mGACgJBRQAQAAAABgZcePH5d0fVl9SXJzcyu0Rd0333yj0NBQ07dCT58+rVWrVpUquWkwGKwQsfkaNGigq1evKiwszKr9njhxQv/v//2/Qs+9vb1NW+EtW7ZM7du318cff2xqk5ubqz/++KPY/kq6Lv7+/pKkgwcPqlOnTrcZ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BQcHV4lNTk7Wjz/+qLS0NG3YsOGmfW7btk0zZ87UzJkz1adPH02bNk0HDx7U1KlTNX78eDk7O6ukpEQhISEqKipSdHS0jEaj1q9fr2effVbbt29XaGio1XOwZR6FhYXq1auXpdBLkubPn69evXrpq6++kpeXl03jSteL3yIjI9W6dWu9/vrrMhqNysjIUEpKivr161ercUePHq2+fftq7ty5Wr58ucaPH6+uXbsqKChI7u7uMplMSk9P15w5c6qct2HDBvXt21cPP/ywJNXqOu/du1cLFy5UVFSU/P39dfDgQeXl5dl0nYF7DQVUAAAAAAAAAAAAAADYWX5+vpo3by5JMplMKioq0r59+2Q0GnXkyBFJ0owZMxQWFqb27dtLul5k07VrV7399ttauXKlvL29NW/ePJsKqEaOHClJ2r59u06fPm35XpMhQ4ZIkr755ptfLaCaPHmyXnzxRW3dulW5ublKTEzUl19+qU2bNunEiRNq166d5s2bp9zcXB04cEAdO3aUJL300kvq0qWLEhMTbS6gsnYeS5cuVXFxsbKysvTkk09KkkJCQhQSEqKlS5fqD3/4g03jlpeX65VXXlFAQICys7PVuHFjSdKECRN07ty5Wo87ePBgzZs3z/K5ZcuW+uc//6mgoCBJ0vPPP69x48bpm2++UevWrSVJX3/9tY4cOaLJkydb+qnNdd66dauys7PVtWvXKvOUbHtegHsJW/gBAAAAAAAAAAAAAGBnZrNZDRo0kHR9K7yzZ8/q6tWrcnFxUWlpqSTJ29tb2dnZ2rNnj958800VFhbKZDKptLRU6enp+vzzz9WtWzd7TkOSZDQaJUmenp6Wz02bNpUkXbhwQZKUlpamJ554Qj4+PiouLlZxcbG+//57BQcHKysry1KwU9cyMjLUqlUrSxGTJD399NPy9/dXRkaGzf3t379fp0+fVnR0tKV46gZfX99ajxsZGWn53KJFC3l5eens2bOWtiFDhsjJyalKIduGDRvk6OiooUOHWtpqc53DwsKqFE9JkqOj460vBnAPYwUqAAAAAAAAAAAAAADszMXFRWVlZZKkQ4cOqby8XI0aNZLZbLZs65efn6/Zs2dr69at6t+/v9544w19/fXXiomJUVJSkl599VUlJSXZcxqSJCen66UIzs7OVT5LsszxxIkTMpvN8vb2rrGPkpISNWnSpM5z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ri5nnnlmevbsmWeeeSZTp07dJESVJJ///Odzwgkn5OSTT85VV12VUaNG5cknn8yAAQMa+zT35wxsPQJUAAAAAAAAAFBkS5YsSd++fZMkI0aMyPLlyzN79uxUVFTk6aefTpJMmDAhhx12WAYPHpwk+cpXvpJ99903P/rRj3Lddddlxx13zI9//OMWBai+/OUvJ0nuvvvuvPTSS43Xm/O5z30uSfL888+/Y7DnjDPOyAknnJA777wz8+bNy6RJk/LII49k2rRpeeGFF/LhD384P/7xjzNv3rw88cQT2WuvvZIk3/jGNzJ06NBMmjSpxQGq5q7jyiuvzIoVKzJr1qx8/OMfT5IMHz48w4cPz5VXXpnvfOc7LZp37ty5WbBgQX72s5/llFNOaWxft27dZvufeuqpmTRpUpJkzJgxGThwYC699NJcfvnljX2a+3MGth5H+AEAAAAAAABAkdXW1qZTp05JNhyFt2jRoqxduzZlZWVZs2ZNkmTHHXfMY489locffjjf+973smzZsowYMSJr1qzJrbfemvvuuy/7779/MZeRJKmoqEiS9OrVq/F1z549kySrVq1Kktx888054IADUllZmRUrVmTFihV59dVXM2zYsMyaNSvr169vldpmzpyZ3XffvTE8lSSf/OQnM2DAgMycObPF43Xp0iVJ8vDDD6eurq6xvWPHze9nc/zxxze+3m233fLRj340999/f4vnBbYuASoAAAAAAAAAKLKysrLGAM6cOXMyb968dOnSJbW1tY3H+i1ZsiSnn356TjjhhCxcuDDf/va3c/755+fSSy/N3nvvnfPPP7+YS2i0MTxUWlra5HWSxjW+8MILmTVrVnbccccmX1dffXXq6upSU1PTKrW98sor6d+//ybt/fv3z8svv9zi8fbYY4+MHTs2U6ZMyY477pgjjjgiF198cWNQ7O/169evyXXfvn23aF5g63KEHwAAAAAAAAAUWWVlZZYuXZok2X777Rvbly1blsrKyiRJ586dc8ghh+Syyy5LeXl5nnnmmXz605/OpEmT0qdPn5x55pnZZ599muxy1NY0NDQkSQqFQj7zmc/k7LPP3my///0zaOuuvvrqnHrqqbnjjjtyxx135Oyzz87PfvazzJkzpzH89k427jwGFI8AFQAAAAAAAAAUWVVVVa655pqsWbOmMXRTX1+f6urqjBw5MknSvXv3HHfccY3vueuuu3LIIYc07jz1yiuv5JZbbtmiAFWhUNgKq2i+3XffPW+99VZGjBixVcd9t3X06dMnL7300ibtCxYsyIABA7Z43v322y/77bdfLrjgglxyySU566yzcs899+TII49s0m/hwoX58Ic/3Hi9aNGiTXalaomN4at169ZtlX7QXjnCDwAAAAAAAACKbPTo0amtrc0NN9zQ2DZ9+vSsXLkyRx111GbfU1JSktra2sbrNWvWbHEQqmvXrlmxYsX7FrAZM2ZMHnzwwcyaNWuTewsXLtzicd9tHQcffHDmzZuX3//+941tDz74YObPn5+DDz64xfPV1NRsMtfGINbG4wv/t1//+teNr+fPn59HH300Bx10UIvn3ahv375Jkueff36r9IP2yg5UAAAAAAAAAFBkhx12WIYPH55x48Zl8eLFKS0tzeTJkzN06NAcc8wxm33PyJEjc+aZZ2b8+PHp06dPLr744vz85z/fovmHDRuWK664ImPHjs3RRx+dTp06paqqKrvsskuS5Mknn8yTTz7Z+DpJrr/++iQbjts7+uijWzTfueeem9/+9rcZMWJETj311AwePDiLFi3KPffck27dumX69Omtso7TTjstP/3pT3P00Udn/PjxSZJLL700FRUVOe2001o837333ptx48bli1/8Yvbcc8+sXLkyV1xxRfr3759hw4Zt0v8//uM/8vrrr6dfv3658sorU1ZWlnHjxjXeb+nPuX///vnoRz+a733ve6mvr0+3bt2y//77N9nlqiX9oL0SoAIAAAAAAACgzTrrhv8udgnvi0KhkFtvvTXjx4/PRRddlPr6+owcOTKXX375ZncySpKBAwfmV7/6Vc4555y8/vrrOeecc5oc8dcSxx57bB577LFcf/31mTJlShoaGvKLX/wiJ598cpLk5ptvzqRJk5q858QTT0yS7Lrrri0OUHXr1i0PP/xwvvvd7+a3v/1tli1blp122ikHHnhgxo4du0VraM46Kioqcv/99+ess87KD37wgyTJ8OHDc8kll6R3794tnm+fffbJiBEjcsstt+SVV15Jjx49Mnz48Hz/+99P165dN+l/44035vTTT89zzz2XIUOGZPr06U2O8NuSn/OvfvWrfO1rX8uZZ56Z2traXHrppZsNRjW3H7RHhYaGhoZiF/Fe1dTUpHv37lm9enW6detW7HKAdmi3839X7BIAAIpi/uQji10C0E619HmQ50cAANB2rVmzJi+++GIGDBiQ8vLyYpcDrWLixImZNGlSPgARDWgzmvPnR3OfCZW0VpEAAAAAAAAAAABtnSP8AAAAAAAAAOADZMmSJc3qV1lZ2cqVAGwbBKgAAAAAAAAA4AOkT58+zeq3du3adOwoNgDwvv0mPPvss3PxxRfn9NNPz09+8pPG9lWrVuWMM87Ibbfdlvr6+owcOTJXXHFFKioq3q/SAAAAAAAAAOADY8aMGc3q16FDh1auhI0mTpyYiRMnFrsM4G28LwGqefPm5ZprrtnsvTFjxuTxxx/PhAkTUlpamosuuiijRo3Ko48+6pc1AAAAAAAAALTQiBEjil0CwDal5P2Y5Nxzz83/+T//Z5P2GTNm5P77789PfvKTXHDBBTnnnHNy7bXX5oknnshNN930fpQGAAAAAAAAAAC0Y60eoHrooYdy55135sILL9zk3rRp01JWVpbjjjuusW3UqFHp1atXpk6d2tqlAQAAAAAAAAAA7VyrHuHX0NCQM888M2eccUYqKio2uV9dXZ1BgwalvLy8sa2kpCRVVVWprq5+23Fra2tTW1vbeF1TU7N1CwcAAABgm+b5EQAAAADN1ao7UP3yl7/MvHnzcvbZZ2/2/pIlS7LTTjsl2XAG6z777JO6urpUVFRkyZIlbzvuD3/4w3Tv3r3xq1+/fq1SPwAAAADbJs+PAAAAAGiuVgtQvfXWW7ngggsyYcKEdOvWbbN9amtr06lTpyTJ/Pnzs2jRoqxduzZlZWVZs2bN2449YcKErF69uvFr4cKFrbIGAAAAALZNnh8BAAAA0FytdoTfxRdfnIaGhpx++ulv26esrCx1dXVJkjlz5mT9+vXp0qVLamtrmxzrt7n3lZWVbfWaAQAAAPhg8PwIAAAAgOZqlQDV6tWrc9FFF+W8887LihUrmtx74403smjRouy0006prKzM0qVLkyTbb799Y59ly5alsrKyNUoDAAAAAAAAAABo1CpH+K1atSqvv/56vv3tb6dfv36NX0kyZcqU9OvXL3/6059SVVWVZ599tslxffX19amurk5VVVVrlAYAAAAAAAAAvAcTJ05MoVAodhltWqFQyMSJE4tdBtBMrbID1U477ZRp06Zt0n7UUUflyCOPzDe+8Y186EMfyujRo3PFFVfkhhtuyEknnZQkmT59elauXJmjjjqqNUoDAAAAAAAAYBuy6PwHi11C+k4e/r7Ms2rVqpxxxhm57bbbUl9fn5EjR+aKK65IRUVFk351dXUpLS3dqiGmW2+9NfPnz8/48eO32pjF8EFZB/D+apUAVefOnTN69OjN3tttt90a7x122GEZPnx4xo0bl8WLF6e0tDSTJ0/O0KFDc8wxx7RGaQAAAAAAAADQJo0ZMyaPP/54JkyYkNLS0lx00UUZNWpUHn300XTo0CG1tbX5+te/nv/3//5ftttuu0yaNCn/8i//slXmvvXWWzNz5sxmBY++9a1v5fzzz98q825tLVkHwEatEqBqrkKhkFtvvTXjx4/PRRdd1Jigvfzyy9OxY1FLAwAAAAAAAID3zYwZM3L//fdnypQpjSc4DRkyJKNHj85NN92UY489NhdffHHuv//+XHvttVm6dGnOO++8HHjggfnYxz72vtbasWNHf6cPfKCUvJ+TNTQ05Cc/+UmTtp49e+a6667LX//619TU1OQ3v/lNKisr38+yAAAAAAAAAKCopk2blrKyshx33HGNbaNGjUqvXr0yderUJMmsWbNy1lln5fjjj8/48eNzxBFH5KGHHnpP8xYKhRQKhVx77bVZsGBB43WhUMiUKVOa9N1jjz2a3P978+fPT6FQyAUXXJDevXtnyJAhmTVrVoYOHZpevXrlqquuatJ/+fLlGTt2bCorK1NeXp799tsvt99+e6uv4+mnn84RRxyRrl27pmvXrjnyyCPzl7/8ZYvmTZL77rsv++23X8rLy7P33nu/7WfSkvU+8MADOfzww9O9e/d07949Bx98cO66664WraMln8fEiRNTKBQya9as7LPPPikvL89HPvKRt11LoVDIxIkTc+utt6aqqirl5eUZOHBgk/U0d71z587N5z73uVRUVKRLly7Za6+9MnHixC3uB1tCJBQAAAAAAAAAiqy6ujqDBg1KeXl5Y1tJSUmqqqpSXV2dJBk0aFBuuOGGHH744Vm6dGkeeOCBfPWrX23sP3v27Oy8887ZZZddmj3vf/3XfyVJrrnmmsydOzeXXnpp471hw4Y16XvxxRfntddey80335xbbrnlbcecMWNGLrzwwlx44YU55JBDct555+WPf/xjzj777JxyyikpRsKdmgAAJ5pJREFULS1NTU1Nhg8fnuXLl2fcuHGpqKjITTfdlM9+9rO5++67c/DBBzd7DS1Zx7Jly3LQQQc1BouS5JJLLslBBx2Up556Kr17927RvHPnzs0RRxyRAQMGZPLkyVmwYEGOOeaYTfq1ZL3Tpk3LmDFjsscee+Tcc89NRUVFZs6cmWuuuSaHH354i9fRnM9jo89//vM54YQTcvLJJ+eqq67KqFGj8uSTT2bAgAGbrOnRRx/NZZddlrFjx2bAgAH54x//mPnz57dovXV1dRk1alTq6upy5plnpmfPnnnmmWcyderUJuGo5vaDLSVABQAAAAAAAABFtmTJkvTt2zdJMmLEiCxfvjyzZ89ORUVFnn766STJhAkTcthhh2Xw4MFJkq985SvZd99986Mf/SjXXXdddtxxx/z4xz9uUYDqy1/+cpLk7rvvzksvvdR4vTmf+9znkiTPP//8OwaozjjjjJxwwgm58847M2/evEyaNCmPPPJIpk2blhdeeCEf/vCH8+Mf/zjz5s3LE088kb322itJ8o1vfCNDhw7NpEmTWhygau46rrzyyqxYsSKzZs3Kxz/+8STJ8OHDM3z48Fx55ZX5zne+06J5f/SjH6W+vj733ntv42lb2223Xf71X/+1Sb/mrnf9+vX553/+5wwcODCPPfZYtt9++yTJ17/+9bzyyitbtI7mfB4bnXrqqZk0aVKSZMyYMRk4cGAuvfTSXH755Zus/c4778xjjz2Wfffdt7Ft/fr1LVrv3Llzs2DBgvzsZz/LKaec0jjOunXrmszV3H6wpd7XI/wAAAAAAAAAgE3V1tamU6dOSTYcvbZo0aKsXbs2ZWVlWbNmTZJkxx13zGOPPZaHH3443/ve97Js2bKMGDEia9asya233pr77rsv+++/fzGXkSSpqKhIkvTq1avxdc+ePZMkq1atSpLcfPPNOeCAA1JZWZkVK1ZkxYoVefXVVzNs2LDMmjWrMYiztc2cOTO77757Y+goST75yU9mwIABmTlz5haN96lPfaoxPJUk//iP/7hJv+au9/HHH89LL72UcePGNYanNurTp88WraM5n8dGxx9/fOPr3XbbLR/96Edz//33b3bthx12WJPwVJJ06NChRevt0qVLkuThhx9OXV1d4zgdOzbdD6i5/WBL+S8JAAAAAAAAAIqsrKysMRgyZ86crF+/Pl26dEltbW3jsX5LlizJd7/73dx55535zGc+k29/+9t57rnnMn78+EyePDnf/OY3M3ny5GIuI8nfQi2lpaVNXidpXOMLL7yQ2tra7Ljjjpsdo6amJj169Njqtb3yyivp37//Ju39+/fPyy+/3OLxFi9evMluWZsbv7nrffHFF5OkcZext9OSdTTn89ioX79+Ta779u2b++67b7M1/O+dq/5ec9e7xx57ZOzYsbnmmmty88035xOf+EQOPfTQfPWrX23y+Te3H2wpASoAAAAAAAAAKLLKysosXbo0SZrsPLRs2bLG3Y06d+6cQw45JJdddlnKy8vzzDPP5NOf/nQmTZqUPn365Mwzz8w+++zTZBehtqahoSFJUigU8pnPfCZnn332Zvv9/e5LbdXGcNu7aavr3fh5vJONO6P9vR122OFt39OS9V599dU59dRTc8cdd+SOO+7I2WefnZ/97GeZM2dOk59vc/vBlhCgAgAAAAAAAIAiq6qqyjXXXJM1a9Y0hkHq6+tTXV2dkSNHJkm6d++e4447rvE9d911Vw455JCcf/75STbsSnTLLbdsUYCqUChshVU03+6775633norI0aM2Krjvts6+vTpk5deemmT9gULFmTAgAEtnq9///5ZtGhRk7bNjd/c9W6s4emnn86hhx76tv229jo2WrhwYZOdpRYtWrTJrlTN0dLPd7/99st+++2XCy64IJdccknOOuus3HPPPTnyyCO3qB+0VEmxCwAAAAAAAACA9m706NGpra3NDTfc0Ng2ffr0rFy5MkcdddRm31NSUpLa2trG6zVr1mxxEKpr165ZsWJF1q1bt0Xvb6kxY8bkwQcfzKxZsza5t3Dhwi0e993WcfDBB2fevHn5/e9/39j24IMPZv78+Zscxdcchx56aB544IEsWbKkse2Xv/zlJv2au96PfOQj6devXy677LK89tprTfotW7as1dax0a9//evG1/Pnz8+jjz6agw46qMXjNHe9NTU1m3xWGwNgG48bbEk/2FL+KwIAAAAAAACAIjvssMMyfPjwjBs3LosXL05paWkmT56coUOH5phjjtnse0aOHJkzzzwz48ePT58+fXLxxRfn5z//+RbNP2zYsFxxxRUZO3Zsjj766HTq1ClVVVXZZZddkiRPPvlknnzyycbXSXL99dcn2XAc29FHH92i+c4999z89re/zYgRI3Lqqadm8ODBWbRoUe65555069Yt06dPb5V1nHba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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "if comp_appid:\n", + " comp_app=Application_Run(comp_appid,basedir=comp_base_dir)\n", + " output=app.compare_app(rapp=comp_app,show_metric=emonmetric,show_queryplan_diff=False,disk_prefix=disk_prefix,nic_prefix=nic_prefix)\n", + " display(HTML(output))" + ] + }, + { + "cell_type": "markdown", + "id": "572607be", + "metadata": { + "papermill": { + "duration": 0.019224, + "end_time": "2024-12-06T05:56:57.140390", + "exception": false, + "start_time": "2024-12-06T05:56:57.121166", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Config compare" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "0b4f3632", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:56:57.179356Z", + "iopub.status.busy": "2024-12-06T05:56:57.179070Z", + "iopub.status.idle": "2024-12-06T05:56:58.328465Z", + "shell.execute_reply": "2024-12-06T05:56:58.327997Z" + }, + "papermill": { + "duration": 1.170805, + "end_time": "2024-12-06T05:56:58.330214", + "exception": false, + "start_time": "2024-12-06T05:56:57.159409", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0851_00480851_0029comp
callSite.shortcollect at /tmp/ipykernel_265482/1936321720.py:117collect at /tmp/ipykernel_234307/1936321720.py:117False
spark.app.submitTime17334643016691733457038427False
spark.executor.extraClassPathfile:///data0/home/sparkuser/jars/6600a164407ae0e4f5ea5b33dc4b902f23a27730/gluten-velox-bundle-spark3.3_2.12-centos_7_x86_64-1.3.0-snapshot.jarFalse
spark.executor.extraJavaOptions-xx:+ignoreunrecognizedvmoptions --add-opens=java.base/java.lang=all-unnamed --add-opens=java.base/java.lang.invoke=all-unnamed --add-opens=java.base/java.lang.reflect=all-unnamed --add-opens=java.base/java.io=all-unnamed --add-opens=java.base/java.net=all-unnamed --add-opens=java.base/java.nio=all-unnamed --add-opens=java.base/java.util=all-unnamed --add-opens=java.base/java.util.concurrent=all-unnamed --add-opens=java.base/java.util.concurrent.atomic=all-unnamed --add-opens=java.base/sun.nio.ch=all-unnamed --add-opens=java.base/sun.nio.cs=all-unnamed --add-opens=java.base/sun.security.action=all-unnamed --add-opens=java.base/sun.util.calendar=all-unnamed --add-opens=java.security.jgss/sun.security.krb5=all-unnamed -xx:+useparalleloldgc -xx:parallelgcthreads=2 -xx:newratio=1 -xx:survivorratio=1 -xx:+usecompressedoops -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:errorfile=/home/sparkuser/logs/java/hs_err_pid%p.log-xx:+ignoreunrecognizedvmoptions --add-opens=java.base/java.lang=all-unnamed --add-opens=java.base/java.lang.invoke=all-unnamed --add-opens=java.base/java.lang.reflect=all-unnamed --add-opens=java.base/java.io=all-unnamed --add-opens=java.base/java.net=all-unnamed --add-opens=java.base/java.nio=all-unnamed --add-opens=java.base/java.util=all-unnamed --add-opens=java.base/java.util.concurrent=all-unnamed --add-opens=java.base/java.util.concurrent.atomic=all-unnamed --add-opens=java.base/sun.nio.ch=all-unnamed --add-opens=java.base/sun.nio.cs=all-unnamed --add-opens=java.base/sun.security.action=all-unnamed --add-opens=java.base/sun.util.calendar=all-unnamed --add-opens=java.security.jgss/sun.security.krb5=all-unnamed -xx:+useparalleloldgc -xx:parallelgcthreads=2 -xx:newratio=1 -xx:survivorratio=1 -xx:+usecompressedoops -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:errorfile=/data0/home/sparkuser/logs/java/hs_err_pid%p.logFalse
spark.executor.memory10944m29184mFalse
spark.gluten.memory.conservative.task.offHeap.size.in.bytes10041163776NaNFalse
spark.gluten.memory.dynamic.offHeap.sizing.enabledfalseNaNFalse
spark.gluten.memory.offHeap.size.in.bytes80329310208NaNFalse
spark.gluten.memory.overAcquiredMemoryRatio0NaNFalse
spark.gluten.memory.task.offHeap.size.in.bytes20082327552NaNFalse
spark.gluten.memoryOverhead.size.in.bytes1073741824NaNFalse
spark.gluten.numTaskSlotsPerExecutor4NaNFalse
spark.gluten.sql.columnar.backend.libveloxNaNFalse
spark.gluten.sql.columnar.coalesce.batchestrueNaNFalse
spark.gluten.sql.columnar.forceshuffledhashjointrueNaNFalse
spark.gluten.sql.columnar.maxBatchSize4096NaNFalse
spark.gluten.sql.columnar.shuffle.codeclz4NaNFalse
spark.gluten.sql.columnar.shuffle.codecBackendNaNFalse
spark.gluten.sql.session.timeZone.defaultetc/utcNaNFalse
spark.memory.offHeap.size8032931020858368mFalse
spark.pluginsorg.apache.gluten.glutenpluginNaNFalse
spark.repl.class.outputDir/tmp/tmpypqh85b0/tmp/tmpynceqaxdFalse
spark.repl.class.urispark://sr213:40521/classesspark://sr213:34951/classesFalse
spark.shuffle.managerorg.apache.spark.shuffle.sort.columnarshufflemanagerNaNFalse
spark.sql.adaptive.customCostEvaluatorClassorg.apache.spark.sql.execution.adaptive.glutencostevaluatorNaNFalse
spark.sql.extensionsorg.apache.gluten.extension.glutensessionextensionsNaNFalse
spark.sql.files.maxPartitionBytes4gNaNFalse
spark.sql.shuffle.partitions3264False
\n", + "
" + ], + "text/plain": [ + " 0851_0048 \\\n", + "callSite.short collect at /tmp/ipykernel_265482/1936321720.py:117 \n", + "spark.app.submitTime 1733464301669 \n", + "spark.executor.extraClassPath file:///data0/home/sparkuser/jars/6600a164407ae0e4f5ea5b33dc4b902f23a27730/gluten-velox-bundle-spark3.3_2.12-centos_7_x86_64-1.3.0-snapshot.jar \n", + "spark.executor.extraJavaOptions -xx:+ignoreunrecognizedvmoptions --add-opens=java.base/java.lang=all-unnamed --add-opens=java.base/java.lang.invoke=all-unnamed --add-opens=java.base/java.lang.reflect=all-unnamed --add-opens=java.base/java.io=all-unnamed --add-opens=java.base/java.net=all-unnamed --add-opens=java.base/java.nio=all-unnamed --add-opens=java.base/java.util=all-unnamed --add-opens=java.base/java.util.concurrent=all-unnamed --add-opens=java.base/java.util.concurrent.atomic=all-unnamed --add-opens=java.base/sun.nio.ch=all-unnamed --add-opens=java.base/sun.nio.cs=all-unnamed --add-opens=java.base/sun.security.action=all-unnamed --add-opens=java.base/sun.util.calendar=all-unnamed --add-opens=java.security.jgss/sun.security.krb5=all-unnamed -xx:+useparalleloldgc -xx:parallelgcthreads=2 -xx:newratio=1 -xx:survivorratio=1 -xx:+usecompressedoops -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:errorfile=/home/sparkuser/logs/java/hs_err_pid%p.log \n", + "spark.executor.memory 10944m \n", + "spark.gluten.memory.conservative.task.offHeap.size.in.bytes 10041163776 \n", + "spark.gluten.memory.dynamic.offHeap.sizing.enabled false \n", + "spark.gluten.memory.offHeap.size.in.bytes 80329310208 \n", + "spark.gluten.memory.overAcquiredMemoryRatio 0 \n", + "spark.gluten.memory.task.offHeap.size.in.bytes 20082327552 \n", + "spark.gluten.memoryOverhead.size.in.bytes 1073741824 \n", + "spark.gluten.numTaskSlotsPerExecutor 4 \n", + "spark.gluten.sql.columnar.backend.lib velox \n", + "spark.gluten.sql.columnar.coalesce.batches true \n", + "spark.gluten.sql.columnar.forceshuffledhashjoin true \n", + "spark.gluten.sql.columnar.maxBatchSize 4096 \n", + "spark.gluten.sql.columnar.shuffle.codec lz4 \n", + "spark.gluten.sql.columnar.shuffle.codecBackend \n", + "spark.gluten.sql.session.timeZone.default etc/utc \n", + "spark.memory.offHeap.size 80329310208 \n", + "spark.plugins org.apache.gluten.glutenplugin \n", + "spark.repl.class.outputDir /tmp/tmpypqh85b0 \n", + "spark.repl.class.uri spark://sr213:40521/classes \n", + "spark.shuffle.manager org.apache.spark.shuffle.sort.columnarshufflemanager \n", + "spark.sql.adaptive.customCostEvaluatorClass org.apache.spark.sql.execution.adaptive.glutencostevaluator \n", + "spark.sql.extensions org.apache.gluten.extension.glutensessionextensions \n", + "spark.sql.files.maxPartitionBytes 4g \n", + "spark.sql.shuffle.partitions 32 \n", + "\n", + " 0851_0029 \\\n", + "callSite.short collect at /tmp/ipykernel_234307/1936321720.py:117 \n", + "spark.app.submitTime 1733457038427 \n", + "spark.executor.extraClassPath \n", + "spark.executor.extraJavaOptions -xx:+ignoreunrecognizedvmoptions --add-opens=java.base/java.lang=all-unnamed --add-opens=java.base/java.lang.invoke=all-unnamed --add-opens=java.base/java.lang.reflect=all-unnamed --add-opens=java.base/java.io=all-unnamed --add-opens=java.base/java.net=all-unnamed --add-opens=java.base/java.nio=all-unnamed --add-opens=java.base/java.util=all-unnamed --add-opens=java.base/java.util.concurrent=all-unnamed --add-opens=java.base/java.util.concurrent.atomic=all-unnamed --add-opens=java.base/sun.nio.ch=all-unnamed --add-opens=java.base/sun.nio.cs=all-unnamed --add-opens=java.base/sun.security.action=all-unnamed --add-opens=java.base/sun.util.calendar=all-unnamed --add-opens=java.security.jgss/sun.security.krb5=all-unnamed -xx:+useparalleloldgc -xx:parallelgcthreads=2 -xx:newratio=1 -xx:survivorratio=1 -xx:+usecompressedoops -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:errorfile=/data0/home/sparkuser/logs/java/hs_err_pid%p.log \n", + "spark.executor.memory 29184m \n", + "spark.gluten.memory.conservative.task.offHeap.size.in.bytes NaN \n", + "spark.gluten.memory.dynamic.offHeap.sizing.enabled NaN \n", + "spark.gluten.memory.offHeap.size.in.bytes NaN \n", + "spark.gluten.memory.overAcquiredMemoryRatio NaN \n", + "spark.gluten.memory.task.offHeap.size.in.bytes NaN \n", + "spark.gluten.memoryOverhead.size.in.bytes NaN \n", + "spark.gluten.numTaskSlotsPerExecutor NaN \n", + "spark.gluten.sql.columnar.backend.lib NaN \n", + "spark.gluten.sql.columnar.coalesce.batches NaN \n", + "spark.gluten.sql.columnar.forceshuffledhashjoin NaN \n", + "spark.gluten.sql.columnar.maxBatchSize NaN \n", + "spark.gluten.sql.columnar.shuffle.codec NaN \n", + "spark.gluten.sql.columnar.shuffle.codecBackend NaN \n", + "spark.gluten.sql.session.timeZone.default NaN \n", + "spark.memory.offHeap.size 58368m \n", + "spark.plugins NaN \n", + "spark.repl.class.outputDir /tmp/tmpynceqaxd \n", + "spark.repl.class.uri spark://sr213:34951/classes \n", + "spark.shuffle.manager NaN \n", + "spark.sql.adaptive.customCostEvaluatorClass NaN \n", + "spark.sql.extensions NaN \n", + "spark.sql.files.maxPartitionBytes NaN \n", + "spark.sql.shuffle.partitions 64 \n", + "\n", + " comp \n", + "callSite.short False \n", + "spark.app.submitTime False \n", + "spark.executor.extraClassPath False \n", + "spark.executor.extraJavaOptions False \n", + "spark.executor.memory False \n", + "spark.gluten.memory.conservative.task.offHeap.size.in.bytes False \n", + "spark.gluten.memory.dynamic.offHeap.sizing.enabled False \n", + "spark.gluten.memory.offHeap.size.in.bytes False \n", + "spark.gluten.memory.overAcquiredMemoryRatio False \n", + "spark.gluten.memory.task.offHeap.size.in.bytes False \n", + "spark.gluten.memoryOverhead.size.in.bytes False \n", + "spark.gluten.numTaskSlotsPerExecutor False \n", + "spark.gluten.sql.columnar.backend.lib False \n", + "spark.gluten.sql.columnar.coalesce.batches False \n", + "spark.gluten.sql.columnar.forceshuffledhashjoin False \n", + "spark.gluten.sql.columnar.maxBatchSize False \n", + "spark.gluten.sql.columnar.shuffle.codec False \n", + "spark.gluten.sql.columnar.shuffle.codecBackend False \n", + "spark.gluten.sql.session.timeZone.default False \n", + "spark.memory.offHeap.size False \n", + "spark.plugins False \n", + "spark.repl.class.outputDir False \n", + "spark.repl.class.uri False \n", + "spark.shuffle.manager False \n", + "spark.sql.adaptive.customCostEvaluatorClass False \n", + "spark.sql.extensions False \n", + "spark.sql.files.maxPartitionBytes False \n", + "spark.sql.shuffle.partitions False " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "if comp_appid:\n", + " comp_appals=comp_app.analysis['app']['als']\n", + " display(comp_spark_conf(appals, comp_appals))" + ] + }, + { + "cell_type": "markdown", + "id": "20b5f6f2", + "metadata": { + "papermill": { + "duration": 0.020157, + "end_time": "2024-12-06T05:56:58.371233", + "exception": false, + "start_time": "2024-12-06T05:56:58.351076", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "# Convert to HTML" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "bd866a20", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:56:58.412619Z", + "iopub.status.busy": "2024-12-06T05:56:58.412337Z", + "iopub.status.idle": "2024-12-06T05:56:58.416007Z", + "shell.execute_reply": "2024-12-06T05:56:58.415586Z" + }, + "papermill": { + "duration": 0.025916, + "end_time": "2024-12-06T05:56:58.417156", + "exception": false, + "start_time": "2024-12-06T05:56:58.391240", + "status": "completed" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "IPython.notebook.kernel.execute('nb_name = \"' + IPython.notebook.notebook_name + '\"')\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%javascript\n", + "IPython.notebook.kernel.execute('nb_name = \"' + IPython.notebook.notebook_name + '\"')" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "83323888", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:56:58.459405Z", + "iopub.status.busy": "2024-12-06T05:56:58.459137Z", + "iopub.status.idle": "2024-12-06T05:56:58.461591Z", + "shell.execute_reply": "2024-12-06T05:56:58.461165Z" + }, + "papermill": { + "duration": 0.024889, + "end_time": "2024-12-06T05:56:58.462703", + "exception": false, + "start_time": "2024-12-06T05:56:58.437814", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# htmlname=nb_name.replace(\"ipynb\",\"html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "98b1ba3b", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-06T05:56:58.505858Z", + "iopub.status.busy": "2024-12-06T05:56:58.505587Z", + "iopub.status.idle": "2024-12-06T05:56:58.508041Z", + "shell.execute_reply": "2024-12-06T05:56:58.507614Z" + }, + "papermill": { + "duration": 0.024884, + "end_time": "2024-12-06T05:56:58.509167", + "exception": false, + "start_time": "2024-12-06T05:56:58.484283", + "status": "completed" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# !jupyter nbconvert --to html ./{nb_name} --no-input --output html/{htmlname} --template classic" + ] + } + ], + "metadata": { + "celltoolbar": "Tags", + "hide_input": false, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.12" + }, + "nbTranslate": { + "displayLangs": [ + "*" + ], + "hotkey": "alt-t", + "langInMainMenu": true, + "sourceLang": "en", + "targetLang": "fr", + "useGoogleTranslate": true + }, + "papermill": { + "default_parameters": {}, + "duration": 207.873445, + "end_time": "2024-12-06T05:57:01.150405", + "environment_variables": {}, + "exception": null, + "input_path": "2024_12_06_055328_tpch_gluten_application_1733153225851_0048.ipynb", + "output_path": "2024_12_06_055328_tpch_gluten_application_1733153225851_0048.nbconvert.ipynb", + "parameters": { + "appid": "application_1733153225851_0048", + "base_dir": "sr213", + "comp_appid": "application_1733153225851_0029", + "comp_base_dir": "sr213", + "comp_name": "vanilla", + "disk": "nvme0n1", + "name": "tpch_gluten", + "nic": "enp61s0f0", + "proxy": "http://10.239.44.250:8080", + "tz": "Etc/GMT+0" + }, + "start_time": "2024-12-06T05:53:33.276960", + "version": "2.6.0" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": false, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "197px", + "left": "2188px", + "top": "111px", + "width": "269px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/tools/workload/benchmark_velox/sample/trace_result_tpch_q1.json b/tools/workload/benchmark_velox/sample/trace_result_tpch_q1.json new file mode 100644 index 000000000000..0ca3b995a26c --- /dev/null +++ b/tools/workload/benchmark_velox/sample/trace_result_tpch_q1.json @@ -0,0 +1,776 @@ + + { + "traceEvents": [ + + {"name": "process_name", "ph": "M", "pid": 100300, "tid": 0, "args": {"name": "sr217.3"}}, +{"tid": 100300, "ts": -32615, "dur": 1647, "pid": 100300, "ph": "X", "name": "stg0", "args": {"job id": 0, "stage id": 0, "tskid": 0, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"name": "process_name", "ph": "M", "pid": 100200, "tid": 0, "args": {"name": "sr217.2"}}, +{"tid": 100200, "ts": -29154, "dur": 1639, "pid": 100200, "ph": "X", "name": "stg1", "args": {"job id": 1, "stage id": 1, "tskid": 1, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100300, "ts": -27419, "dur": 53, "pid": 100300, "ph": "X", "name": "stg2", "args": {"job id": 2, "stage id": 2, "tskid": 2, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100200, "ts": -27286, "dur": 51, "pid": 100200, "ph": "X", "name": "stg3", "args": {"job id": 3, "stage id": 3, "tskid": 3, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"name": "process_name", "ph": "M", "pid": 100400, "tid": 0, "args": {"name": "sr217.4"}}, +{"tid": 100400, "ts": -27151, "dur": 1554, "pid": 100400, "ph": "X", "name": "stg4", "args": {"job id": 4, "stage id": 4, "tskid": 4, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"name": "process_name", "ph": "M", "pid": 100100, "tid": 0, "args": {"name": "sr217.1"}}, +{"tid": 100100, "ts": -25511, "dur": 1641, "pid": 100100, "ph": "X", "name": "stg5", "args": {"job id": 5, "stage id": 5, "tskid": 5, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100400, "ts": -23791, "dur": 48, "pid": 100400, "ph": "X", "name": "stg6", "args": {"job id": 6, "stage id": 6, "tskid": 6, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100100, "ts": -23672, "dur": 53, "pid": 100100, "ph": "X", "name": "stg7", "args": {"job id": 7, "stage id": 7, "tskid": 7, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100302, "ts": -22513, "dur": 13342, "pid": 100300, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 21, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100303, "ts": -22513, "dur": 13346, "pid": 100300, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 17, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100203, "ts": -22512, "dur": 13580, "pid": 100200, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 23, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100202, "ts": -22513, "dur": 13590, "pid": 100200, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 19, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100201, "ts": -22514, "dur": 13650, "pid": 100200, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 11, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100301, "ts": -22514, "dur": 13681, "pid": 100300, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 13, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100300, "ts": -22515, "dur": 13686, "pid": 100300, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 9, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100103, "ts": -22513, "dur": 13732, "pid": 100100, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 18, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100200, "ts": -22514, "dur": 13745, "pid": 100200, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 15, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100100, "ts": -22514, "dur": 13757, "pid": 100100, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 14, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100102, "ts": -22513, "dur": 13846, "pid": 100100, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 22, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100400, "ts": -22517, "dur": 14209, "pid": 100400, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 8, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100403, "ts": -22513, "dur": 14262, "pid": 100400, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 16, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100101, "ts": -22514, "dur": 14303, "pid": 100100, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 10, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100401, "ts": -22514, "dur": 14336, "pid": 100400, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 12, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100402, "ts": -22513, "dur": 14339, "pid": 100400, "ph": "X", "name": "stg8", "args": {"job id": 8, "stage id": 8, "tskid": 20, "input": 315.73, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100300, "ts": -7787, "dur": 744, "pid": 100300, "ph": "X", "name": "stg10", "args": {"job id": 9, "stage id": 10, "tskid": 24, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.03, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100400, "ts": -7009, "dur": 980, "pid": 100400, "ph": "X", "name": "stg12", "args": {"job id": 10, "stage id": 12, "tskid": 25, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.03, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid": 100200, "ts": -5889, "dur": 451, "pid": 100200, "ph": "X", "name": "stg15", "args": {"job id": 11, "stage id": 15, "tskid": 26, "input": 0.0, "spill": 0.0, "Shuffle Read Metrics": "", "|---Local Read": 0.0, "|---Remote Read": 0.0, "Shuffle Write Metrics": "", "|---Write": 0.0}}, +{"tid":38,"ts":-32614,"dur":1646,"pid":99999,"ph":"X","name":"stg0","args":{"taskid":0,"exec_id":3,"host":"sr217"}}, +{"tid":38,"ts":-29153,"dur":1638,"pid":99999,"ph":"X","name":"stg1","args":{"taskid":1,"exec_id":2,"host":"sr217"}}, +{"tid":38,"ts":-27418,"dur":52,"pid":99999,"ph":"X","name":"stg2","args":{"taskid":2,"exec_id":3,"host":"sr217"}}, +{"tid":38,"ts":-27285,"dur":50,"pid":99999,"ph":"X","name":"stg3","args":{"taskid":3,"exec_id":2,"host":"sr217"}}, +{"tid":38,"ts":-27150,"dur":1553,"pid":99999,"ph":"X","name":"stg4","args":{"taskid":4,"exec_id":4,"host":"sr217"}}, +{"tid":38,"ts":-25510,"dur":1640,"pid":99999,"ph":"X","name":"stg5","args":{"taskid":5,"exec_id":1,"host":"sr217"}}, +{"tid":38,"ts":-23790,"dur":47,"pid":99999,"ph":"X","name":"stg6","args":{"taskid":6,"exec_id":4,"host":"sr217"}}, +{"tid":38,"ts":-23671,"dur":52,"pid":99999,"ph":"X","name":"stg7","args":{"taskid":7,"exec_id":1,"host":"sr217"}}, +{"tid":38,"ts":-22512,"dur":14338,"pid":99999,"ph":"X","name":"stg8","args":{"taskid":20,"exec_id":4,"host":"sr217"}}, +{"tid":38,"ts":-7786,"dur":743,"pid":99999,"ph":"X","name":"stg10","args":{"taskid":24,"exec_id":3,"host":"sr217"}}, +{"tid":38,"ts":-7008,"dur":979,"pid":99999,"ph":"X","name":"stg12","args":{"taskid":25,"exec_id":4,"host":"sr217"}}, +{"tid":38,"ts":-5888,"dur":450,"pid":99999,"ph":"X","name":"stg15","args":{"taskid":26,"exec_id":2,"host":"sr217"}}, +{"tid":38,"ts":-32615,"dur":8996,"pid":99999,"ph":"X","name":"qry0"}, +{"tid":38,"ts":-22517,"dur":17079,"pid":99999,"ph":"X","name":"qry1"}, +{"tid":38,"ts":-22512,"dur":7552,"pid":99999,"ph":"X","name":"time of scan and filter"}, +{"tid":38,"ts":-14959,"dur":6166,"pid":99999,"ph":"X","name":"time of project"}, +{"tid":38,"ts":-8792,"dur":32,"pid":99999,"ph":"X","name":"time of aggregation"}, +{"tid":38,"ts":-7786,"dur":21,"pid":99999,"ph":"X","name":"time of input iterator"}, +{"tid":38,"ts":-7008,"dur":20,"pid":99999,"ph":"X","name":"time of input iterator"}, +{"tid":38,"ts":-5888,"dur":11,"pid":99999,"ph":"X","name":"time of input iterator"}, +{"name": "process_name", "ph": "M", "pid": 99999, "tid": 0, "args": {"name": "critical path"}}, +{"name": "process_name", "ph": "M", "pid": 0, "tid": 0, "args": {"name": " sr217"}}, +{"tid":0,"ts":-34362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":2,"system":1,"iowait":0}}, +{"tid":0,"ts":-33362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":0,"system":0,"iowait":0}}, +{"tid":0,"ts":-32362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":11,"system":1,"iowait":0}}, +{"tid":0,"ts":-31362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":9,"system":0,"iowait":0}}, +{"tid":0,"ts":-30362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":0,"system":0,"iowait":0}}, +{"tid":0,"ts":-29362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":3,"system":0,"iowait":0}}, +{"tid":0,"ts":-28362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":14,"system":0,"iowait":0}}, +{"tid":0,"ts":-27362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":8,"system":1,"iowait":0}}, +{"tid":0,"ts":-26362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":15,"system":0,"iowait":0}}, +{"tid":0,"ts":-25362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":9,"system":1,"iowait":1}}, +{"tid":0,"ts":-24362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":12,"system":1,"iowait":2}}, +{"tid":0,"ts":-23362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":4,"system":0,"iowait":0}}, +{"tid":0,"ts":-22362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":41,"system":2,"iowait":0}}, +{"tid":0,"ts":-21362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":69,"system":10,"iowait":1}}, +{"tid":0,"ts":-20362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":69,"system":10,"iowait":1}}, +{"tid":0,"ts":-19362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":81,"system":8,"iowait":1}}, +{"tid":0,"ts":-18362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":84,"system":5,"iowait":0}}, +{"tid":0,"ts":-17362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":73,"system":8,"iowait":1}}, +{"tid":0,"ts":-16362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":76,"system":9,"iowait":1}}, +{"tid":0,"ts":-15362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":78,"system":8,"iowait":1}}, +{"tid":0,"ts":-14362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":77,"system":9,"iowait":0}}, +{"tid":0,"ts":-13362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":79,"system":9,"iowait":1}}, +{"tid":0,"ts":-12362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":83,"system":7,"iowait":0}}, +{"tid":0,"ts":-11362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":77,"system":9,"iowait":0}}, +{"tid":0,"ts":-10362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":76,"system":10,"iowait":1}}, +{"tid":0,"ts":-9362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":78,"system":8,"iowait":0}}, +{"tid":0,"ts":-8362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":26,"system":2,"iowait":0}}, +{"tid":0,"ts":-7362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":12,"system":0,"iowait":0}}, +{"tid":0,"ts":-6362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":13,"system":0,"iowait":0}}, +{"tid":0,"ts":-5362,"pid":0,"ph":"C","name":"all cpu%","args":{"user":7,"system":1,"iowait":0}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 0, "args": {"sort_index ": 0}}, +{"name": "process_name", "ph": "M", "pid": 0, "tid": 0, "args": {"name": " sr217"}}, +{"tid":3,"ts":-34362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":0}}, +{"tid":3,"ts":-33362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":0}}, +{"tid":3,"ts":-32362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":1}}, +{"tid":3,"ts":-31362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":0}}, +{"tid":3,"ts":-30362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":0}}, +{"tid":3,"ts":-29362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":1}}, +{"tid":3,"ts":-28362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":0}}, +{"tid":3,"ts":-27362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":165}}, +{"tid":3,"ts":-26362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":0}}, +{"tid":3,"ts":-25362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":505}}, +{"tid":3,"ts":-24362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":512}}, +{"tid":3,"ts":-23362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":0}}, +{"tid":3,"ts":-22362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":71,"write":1}}, +{"tid":3,"ts":-21362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":463,"write":0}}, +{"tid":3,"ts":-20362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":483,"write":0}}, +{"tid":3,"ts":-19362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":405,"write":0}}, +{"tid":3,"ts":-18362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":218,"write":0}}, +{"tid":3,"ts":-17362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":407,"write":0}}, +{"tid":3,"ts":-16362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":489,"write":0}}, +{"tid":3,"ts":-15362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":481,"write":0}}, +{"tid":3,"ts":-14362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":482,"write":0}}, +{"tid":3,"ts":-13362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":425,"write":0}}, +{"tid":3,"ts":-12362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":348,"write":0}}, +{"tid":3,"ts":-11362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":458,"write":0}}, +{"tid":3,"ts":-10362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":486,"write":0}}, +{"tid":3,"ts":-9362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":282,"write":0}}, +{"tid":3,"ts":-8362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":49,"write":0}}, +{"tid":3,"ts":-7362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":1}}, +{"tid":3,"ts":-6362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":1}}, +{"tid":3,"ts":-5362,"pid":0,"ph":"C","name":"disk b/w","args":{"read":0,"write":1}}, +{"tid":4,"ts":-34362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-33362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-32362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-31362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-30362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-29362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-28362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-27362,"pid":0,"ph":"C","name":"disk%","args":{"%util":16.0}}, +{"tid":4,"ts":-26362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-25362,"pid":0,"ph":"C","name":"disk%","args":{"%util":44.0}}, +{"tid":4,"ts":-24362,"pid":0,"ph":"C","name":"disk%","args":{"%util":47.0}}, +{"tid":4,"ts":-23362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-22362,"pid":0,"ph":"C","name":"disk%","args":{"%util":8.0}}, +{"tid":4,"ts":-21362,"pid":0,"ph":"C","name":"disk%","args":{"%util":53.0}}, +{"tid":4,"ts":-20362,"pid":0,"ph":"C","name":"disk%","args":{"%util":65.0}}, +{"tid":4,"ts":-19362,"pid":0,"ph":"C","name":"disk%","args":{"%util":48.0}}, +{"tid":4,"ts":-18362,"pid":0,"ph":"C","name":"disk%","args":{"%util":40.0}}, +{"tid":4,"ts":-17362,"pid":0,"ph":"C","name":"disk%","args":{"%util":50.0}}, +{"tid":4,"ts":-16362,"pid":0,"ph":"C","name":"disk%","args":{"%util":67.0}}, +{"tid":4,"ts":-15362,"pid":0,"ph":"C","name":"disk%","args":{"%util":71.0}}, +{"tid":4,"ts":-14362,"pid":0,"ph":"C","name":"disk%","args":{"%util":75.0}}, +{"tid":4,"ts":-13362,"pid":0,"ph":"C","name":"disk%","args":{"%util":56.0}}, +{"tid":4,"ts":-12362,"pid":0,"ph":"C","name":"disk%","args":{"%util":77.0}}, +{"tid":4,"ts":-11362,"pid":0,"ph":"C","name":"disk%","args":{"%util":72.0}}, +{"tid":4,"ts":-10362,"pid":0,"ph":"C","name":"disk%","args":{"%util":79.0}}, +{"tid":4,"ts":-9362,"pid":0,"ph":"C","name":"disk%","args":{"%util":55.0}}, +{"tid":4,"ts":-8362,"pid":0,"ph":"C","name":"disk%","args":{"%util":19.0}}, +{"tid":4,"ts":-7362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-6362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":4,"ts":-5362,"pid":0,"ph":"C","name":"disk%","args":{"%util":0.0}}, +{"tid":5,"ts":-34362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":0.0}}, +{"tid":5,"ts":-33362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":0.0}}, +{"tid":5,"ts":-32362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":102.93}}, +{"tid":5,"ts":-31362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":12.92}}, +{"tid":5,"ts":-30362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":0.0}}, +{"tid":5,"ts":-29362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":110.0}}, +{"tid":5,"ts":-28362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":0.0}}, +{"tid":5,"ts":-27362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":120.43}}, +{"tid":5,"ts":-26362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":0.0}}, +{"tid":5,"ts":-25362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":114.69}}, +{"tid":5,"ts":-24362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":127.54}}, +{"tid":5,"ts":-23362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":6.0}}, +{"tid":5,"ts":-22362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":78.52}}, +{"tid":5,"ts":-21362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":85.83}}, +{"tid":5,"ts":-20362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.81}}, +{"tid":5,"ts":-19362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.37}}, +{"tid":5,"ts":-18362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":82.5}}, +{"tid":5,"ts":-17362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":84.67}}, +{"tid":5,"ts":-16362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.64}}, +{"tid":5,"ts":-15362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.49}}, +{"tid":5,"ts":-14362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.78}}, +{"tid":5,"ts":-13362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.36}}, +{"tid":5,"ts":-12362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.82}}, +{"tid":5,"ts":-11362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.66}}, +{"tid":5,"ts":-10362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":83.41}}, +{"tid":5,"ts":-9362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":82.6}}, +{"tid":5,"ts":-8362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":79.92}}, +{"tid":5,"ts":-7362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":122.22}}, +{"tid":5,"ts":-6362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":122.22}}, +{"tid":5,"ts":-5362,"pid":0,"ph":"C","name":"req size","args":{"avgrq-sz":122.22}}, +{"tid":6,"ts":-34362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-33362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-32362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-31362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-30362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-29362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-28362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-27362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":2.8}}, +{"tid":6,"ts":-26362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-25362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":132.74}}, +{"tid":6,"ts":-24362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":65.4}}, +{"tid":6,"ts":-23362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-22362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":1.46}}, +{"tid":6,"ts":-21362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":7.8}}, +{"tid":6,"ts":-20362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":6.26}}, +{"tid":6,"ts":-19362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":4.68}}, +{"tid":6,"ts":-18362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":2.44}}, +{"tid":6,"ts":-17362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":6.5}}, +{"tid":6,"ts":-16362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":6.0}}, +{"tid":6,"ts":-15362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":5.34}}, +{"tid":6,"ts":-14362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":5.02}}, +{"tid":6,"ts":-13362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":4.84}}, +{"tid":6,"ts":-12362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":3.08}}, +{"tid":6,"ts":-11362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":4.6}}, +{"tid":6,"ts":-10362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":4.96}}, +{"tid":6,"ts":-9362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":3.0}}, +{"tid":6,"ts":-8362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.46}}, +{"tid":6,"ts":-7362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-6362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":6,"ts":-5362,"pid":0,"ph":"C","name":"queue size","args":{"avgqu-sz":0.0}}, +{"tid":7,"ts":-34362,"pid":0,"ph":"C","name":"await","args":{"await":0.0}}, +{"tid":7,"ts":-33362,"pid":0,"ph":"C","name":"await","args":{"await":0.0}}, +{"tid":7,"ts":-32362,"pid":0,"ph":"C","name":"await","args":{"await":0.13}}, +{"tid":7,"ts":-31362,"pid":0,"ph":"C","name":"await","args":{"await":0.23}}, +{"tid":7,"ts":-30362,"pid":0,"ph":"C","name":"await","args":{"await":0.0}}, +{"tid":7,"ts":-29362,"pid":0,"ph":"C","name":"await","args":{"await":0.14}}, +{"tid":7,"ts":-28362,"pid":0,"ph":"C","name":"await","args":{"await":0.0}}, +{"tid":7,"ts":-27362,"pid":0,"ph":"C","name":"await","args":{"await":0.99}}, +{"tid":7,"ts":-26362,"pid":0,"ph":"C","name":"await","args":{"await":0.0}}, +{"tid":7,"ts":-25362,"pid":0,"ph":"C","name":"await","args":{"await":14.7}}, +{"tid":7,"ts":-24362,"pid":0,"ph":"C","name":"await","args":{"await":7.94}}, +{"tid":7,"ts":-23362,"pid":0,"ph":"C","name":"await","args":{"await":0.17}}, +{"tid":7,"ts":-22362,"pid":0,"ph":"C","name":"await","args":{"await":0.78}}, +{"tid":7,"ts":-21362,"pid":0,"ph":"C","name":"await","args":{"await":0.71}}, +{"tid":7,"ts":-20362,"pid":0,"ph":"C","name":"await","args":{"await":0.53}}, +{"tid":7,"ts":-19362,"pid":0,"ph":"C","name":"await","args":{"await":0.47}}, +{"tid":7,"ts":-18362,"pid":0,"ph":"C","name":"await","args":{"await":0.45}}, +{"tid":7,"ts":-17362,"pid":0,"ph":"C","name":"await","args":{"await":0.66}}, +{"tid":7,"ts":-16362,"pid":0,"ph":"C","name":"await","args":{"await":0.5}}, +{"tid":7,"ts":-15362,"pid":0,"ph":"C","name":"await","args":{"await":0.45}}, +{"tid":7,"ts":-14362,"pid":0,"ph":"C","name":"await","args":{"await":0.42}}, +{"tid":7,"ts":-13362,"pid":0,"ph":"C","name":"await","args":{"await":0.46}}, +{"tid":7,"ts":-12362,"pid":0,"ph":"C","name":"await","args":{"await":0.36}}, +{"tid":7,"ts":-11362,"pid":0,"ph":"C","name":"await","args":{"await":0.41}}, +{"tid":7,"ts":-10362,"pid":0,"ph":"C","name":"await","args":{"await":0.41}}, +{"tid":7,"ts":-9362,"pid":0,"ph":"C","name":"await","args":{"await":0.43}}, +{"tid":7,"ts":-8362,"pid":0,"ph":"C","name":"await","args":{"await":0.37}}, +{"tid":7,"ts":-7362,"pid":0,"ph":"C","name":"await","args":{"await":0.22}}, +{"tid":7,"ts":-6362,"pid":0,"ph":"C","name":"await","args":{"await":0.22}}, +{"tid":7,"ts":-5362,"pid":0,"ph":"C","name":"await","args":{"await":0.22}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 3, "args": {"sort_index ": 3}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 4, "args": {"sort_index ": 4}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 5, "args": {"sort_index ": 5}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 6, "args": {"sort_index ": 6}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 7, "args": {"sort_index ": 7}}, +{"name": "process_name", "ph": "M", "pid": 0, "tid": 0, "args": {"name": " sr217"}}, +{"tid":1,"ts":-34362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-33362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-32362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-31362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-30362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-29362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-28362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-27362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-26362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-25362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-24362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-23362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-22362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-21362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-20362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-19362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-18362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-17362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":0,"buffered":0,"used":8}}, +{"tid":1,"ts":-16362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-15362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-14362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-13362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-12362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-11362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-10362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-9362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-8362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-7362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-6362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":1,"ts":-5362,"pid":0,"ph":"C","name":"mem % ","args":{"cached":1,"buffered":0,"used":8}}, +{"tid":2,"ts":-34362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-33362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-32362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-31362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-30362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-29362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-28362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-27362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-26362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-25362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-24362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-23362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-22362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-21362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-20362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-19362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-18362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-17362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":0,"dirty":0}}, +{"tid":2,"ts":-16362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-15362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-14362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-13362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-12362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-11362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-10362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-9362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-8362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-7362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-6362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"tid":2,"ts":-5362,"pid":0,"ph":"C","name":"pagecache % ","args":{"clean":1,"dirty":0}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 1, "args": {"sort_index ": 1}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 2, "args": {"sort_index ": 2}}, +{"name": "process_name", "ph": "M", "pid": 0, "tid": 0, "args": {"name": " sr217"}}, +{"tid":10,"ts":-34362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-33362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-32362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-31362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-30362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-29362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-28362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-27362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-26362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-25362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-24362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-23362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-22362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":53,"txmb/s":53}}, +{"tid":10,"ts":-21362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":850,"txmb/s":850}}, +{"tid":10,"ts":-20362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":888,"txmb/s":888}}, +{"tid":10,"ts":-19362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":633,"txmb/s":633}}, +{"tid":10,"ts":-18362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":435,"txmb/s":435}}, +{"tid":10,"ts":-17362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":708,"txmb/s":708}}, +{"tid":10,"ts":-16362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":865,"txmb/s":865}}, +{"tid":10,"ts":-15362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":876,"txmb/s":876}}, +{"tid":10,"ts":-14362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":893,"txmb/s":893}}, +{"tid":10,"ts":-13362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":747,"txmb/s":747}}, +{"tid":10,"ts":-12362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":731,"txmb/s":731}}, +{"tid":10,"ts":-11362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":889,"txmb/s":889}}, +{"tid":10,"ts":-10362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":964,"txmb/s":964}}, +{"tid":10,"ts":-9362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":643,"txmb/s":643}}, +{"tid":10,"ts":-8362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":157,"txmb/s":157}}, +{"tid":10,"ts":-7362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-6362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"tid":10,"ts":-5362,"pid":0,"ph":"C","name":"lo ","args":{"rxmb/s":0,"txmb/s":0}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 8, "args": {"sort_index ": 8}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 9, "args": {"sort_index ": 9}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 10, "args": {"sort_index ": 10}}, +{"name": "process_name", "ph": "M", "pid": 0, "tid": 0, "args": {"name": " sr217"}}, +{"tid":11,"ts":-34362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":0}}, +{"tid":11,"ts":-33362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":0}}, +{"tid":11,"ts":-32362,"pid":0,"ph":"C","name":"page inout","args":{"in":1,"out":1}}, +{"tid":11,"ts":-31362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":0}}, +{"tid":11,"ts":-30362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":0}}, +{"tid":11,"ts":-29362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":1}}, +{"tid":11,"ts":-28362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":0}}, +{"tid":11,"ts":-27362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":165}}, +{"tid":11,"ts":-26362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":0}}, +{"tid":11,"ts":-25362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":546}}, +{"tid":11,"ts":-24362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":471}}, +{"tid":11,"ts":-23362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":0}}, +{"tid":11,"ts":-22362,"pid":0,"ph":"C","name":"page inout","args":{"in":73,"out":1}}, +{"tid":11,"ts":-21362,"pid":0,"ph":"C","name":"page inout","args":{"in":463,"out":0}}, +{"tid":11,"ts":-20362,"pid":0,"ph":"C","name":"page inout","args":{"in":483,"out":0}}, +{"tid":11,"ts":-19362,"pid":0,"ph":"C","name":"page inout","args":{"in":404,"out":0}}, +{"tid":11,"ts":-18362,"pid":0,"ph":"C","name":"page inout","args":{"in":218,"out":0}}, +{"tid":11,"ts":-17362,"pid":0,"ph":"C","name":"page inout","args":{"in":408,"out":0}}, +{"tid":11,"ts":-16362,"pid":0,"ph":"C","name":"page inout","args":{"in":489,"out":0}}, +{"tid":11,"ts":-15362,"pid":0,"ph":"C","name":"page inout","args":{"in":481,"out":0}}, +{"tid":11,"ts":-14362,"pid":0,"ph":"C","name":"page inout","args":{"in":482,"out":0}}, +{"tid":11,"ts":-13362,"pid":0,"ph":"C","name":"page inout","args":{"in":424,"out":0}}, +{"tid":11,"ts":-12362,"pid":0,"ph":"C","name":"page inout","args":{"in":348,"out":0}}, +{"tid":11,"ts":-11362,"pid":0,"ph":"C","name":"page inout","args":{"in":458,"out":4}}, +{"tid":11,"ts":-10362,"pid":0,"ph":"C","name":"page inout","args":{"in":485,"out":0}}, +{"tid":11,"ts":-9362,"pid":0,"ph":"C","name":"page inout","args":{"in":282,"out":0}}, +{"tid":11,"ts":-8362,"pid":0,"ph":"C","name":"page inout","args":{"in":49,"out":0}}, +{"tid":11,"ts":-7362,"pid":0,"ph":"C","name":"page inout","args":{"in":1,"out":1}}, +{"tid":11,"ts":-6362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":1}}, +{"tid":11,"ts":-5362,"pid":0,"ph":"C","name":"page inout","args":{"in":0,"out":1}}, +{"tid":12,"ts":-34362,"pid":0,"ph":"C","name":"faults","args":{"major":3,"minor":34023}}, +{"tid":12,"ts":-33362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":1354}}, +{"tid":12,"ts":-32362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":50712}}, +{"tid":12,"ts":-31362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":25536}}, +{"tid":12,"ts":-30362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":161}}, +{"tid":12,"ts":-29362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":25359}}, +{"tid":12,"ts":-28362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":49819}}, +{"tid":12,"ts":-27362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":17304}}, +{"tid":12,"ts":-26362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":40662}}, +{"tid":12,"ts":-25362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":16519}}, +{"tid":12,"ts":-24362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":42377}}, +{"tid":12,"ts":-23362,"pid":0,"ph":"C","name":"faults","args":{"major":1,"minor":22581}}, +{"tid":12,"ts":-22362,"pid":0,"ph":"C","name":"faults","args":{"major":1,"minor":72419}}, +{"tid":12,"ts":-21362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":243832}}, +{"tid":12,"ts":-20362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":216635}}, +{"tid":12,"ts":-19362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":205818}}, +{"tid":12,"ts":-18362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":144239}}, +{"tid":12,"ts":-17362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":179561}}, +{"tid":12,"ts":-16362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":221768}}, +{"tid":12,"ts":-15362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":206784}}, +{"tid":12,"ts":-14362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":204236}}, +{"tid":12,"ts":-13362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":222004}}, +{"tid":12,"ts":-12362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":175002}}, +{"tid":12,"ts":-11362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":249102}}, +{"tid":12,"ts":-10362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":267591}}, +{"tid":12,"ts":-9362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":185914}}, +{"tid":12,"ts":-8362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":51858}}, +{"tid":12,"ts":-7362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":48755}}, +{"tid":12,"ts":-6362,"pid":0,"ph":"C","name":"faults","args":{"major":0,"minor":67785}}, +{"tid":12,"ts":-5362,"pid":0,"ph":"C","name":"faults","args":{"major":2,"minor":41314}}, +{"tid":13,"ts":-34362,"pid":0,"ph":"C","name":"page free","args":{"free":104}}, +{"tid":13,"ts":-33362,"pid":0,"ph":"C","name":"page free","args":{"free":5}}, +{"tid":13,"ts":-32362,"pid":0,"ph":"C","name":"page free","args":{"free":13}}, +{"tid":13,"ts":-31362,"pid":0,"ph":"C","name":"page free","args":{"free":6}}, +{"tid":13,"ts":-30362,"pid":0,"ph":"C","name":"page free","args":{"free":0}}, +{"tid":13,"ts":-29362,"pid":0,"ph":"C","name":"page free","args":{"free":29}}, +{"tid":13,"ts":-28362,"pid":0,"ph":"C","name":"page free","args":{"free":40}}, +{"tid":13,"ts":-27362,"pid":0,"ph":"C","name":"page free","args":{"free":24}}, +{"tid":13,"ts":-26362,"pid":0,"ph":"C","name":"page free","args":{"free":11}}, +{"tid":13,"ts":-25362,"pid":0,"ph":"C","name":"page free","args":{"free":19}}, +{"tid":13,"ts":-24362,"pid":0,"ph":"C","name":"page free","args":{"free":20}}, +{"tid":13,"ts":-23362,"pid":0,"ph":"C","name":"page free","args":{"free":9}}, +{"tid":13,"ts":-22362,"pid":0,"ph":"C","name":"page free","args":{"free":39}}, +{"tid":13,"ts":-21362,"pid":0,"ph":"C","name":"page free","args":{"free":287}}, +{"tid":13,"ts":-20362,"pid":0,"ph":"C","name":"page free","args":{"free":579}}, +{"tid":13,"ts":-19362,"pid":0,"ph":"C","name":"page free","args":{"free":685}}, +{"tid":13,"ts":-18362,"pid":0,"ph":"C","name":"page free","args":{"free":681}}, +{"tid":13,"ts":-17362,"pid":0,"ph":"C","name":"page free","args":{"free":460}}, +{"tid":13,"ts":-16362,"pid":0,"ph":"C","name":"page free","args":{"free":664}}, +{"tid":13,"ts":-15362,"pid":0,"ph":"C","name":"page free","args":{"free":680}}, +{"tid":13,"ts":-14362,"pid":0,"ph":"C","name":"page free","args":{"free":677}}, +{"tid":13,"ts":-13362,"pid":0,"ph":"C","name":"page free","args":{"free":664}}, +{"tid":13,"ts":-12362,"pid":0,"ph":"C","name":"page free","args":{"free":664}}, +{"tid":13,"ts":-11362,"pid":0,"ph":"C","name":"page free","args":{"free":630}}, +{"tid":13,"ts":-10362,"pid":0,"ph":"C","name":"page free","args":{"free":702}}, +{"tid":13,"ts":-9362,"pid":0,"ph":"C","name":"page free","args":{"free":701}}, +{"tid":13,"ts":-8362,"pid":0,"ph":"C","name":"page free","args":{"free":255}}, +{"tid":13,"ts":-7362,"pid":0,"ph":"C","name":"page free","args":{"free":28}}, +{"tid":13,"ts":-6362,"pid":0,"ph":"C","name":"page free","args":{"free":55}}, +{"tid":13,"ts":-5362,"pid":0,"ph":"C","name":"page free","args":{"free":53}}, +{"tid":14,"ts":-34362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-33362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-32362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-31362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-30362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-29362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-28362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-27362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-26362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-25362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-24362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-23362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-22362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-21362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-20362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-19362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-18362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-17362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-16362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-15362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-14362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-13362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-12362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-11362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-10362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-9362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-8362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-7362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-6362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":14,"ts":-5362,"pid":0,"ph":"C","name":"scan","args":{"kernel":0,"app":0}}, +{"tid":15,"ts":-34362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-33362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-32362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-31362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-30362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-29362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-28362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-27362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-26362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-25362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-24362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-23362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-22362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-21362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-20362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-19362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-18362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-17362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-16362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-15362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-14362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-13362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-12362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-11362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-10362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-9362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-8362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-7362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-6362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"tid":15,"ts":-5362,"pid":0,"ph":"C","name":"vmeff","args":{"steal":0}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 11, "args": {"sort_index ": 11}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 12, "args": {"sort_index ": 12}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 13, "args": {"sort_index ": 13}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 14, "args": {"sort_index ": 14}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 15, "args": {"sort_index ": 15}}, +{"name": "thread_sort_index", "ph": "M", "pid": 0, "tid": 16, "args": {"sort_index ": 16}}, +{"name": "process_name", "ph": "M", "pid": 200, "tid": 0, "args": {"name": " sr217"}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-33062,"args":{"cpu%":0.004}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-32562,"args":{"cpu%":0.036}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-32062,"args":{"cpu%":0.123}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-31561,"args":{"cpu%":0.193}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-31061,"args":{"cpu%":0.091}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-30561,"args":{"cpu%":0.018}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-30060,"args":{"cpu%":0.003}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-29560,"args":{"cpu%":0.003}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-29060,"args":{"cpu%":0.049}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-28559,"args":{"cpu%":0.156}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-28059,"args":{"cpu%":0.158}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-27559,"args":{"cpu%":0.102}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-27058,"args":{"cpu%":0.097}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-26558,"args":{"cpu%":0.16}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-26058,"args":{"cpu%":0.184}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-25557,"args":{"cpu%":0.08}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-25057,"args":{"cpu%":0.124}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-24557,"args":{"cpu%":0.219}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-24056,"args":{"cpu%":0.101}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-23556,"args":{"cpu%":0.095}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-23055,"args":{"cpu%":0.026}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-22555,"args":{"cpu%":0.003}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-22055,"args":{"cpu%":0.721}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-21551,"args":{"cpu%":0.689}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-21051,"args":{"cpu%":0.856}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-20551,"args":{"cpu%":0.976}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-20049,"args":{"cpu%":0.688}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-19549,"args":{"cpu%":0.96}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-19049,"args":{"cpu%":0.864}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-18549,"args":{"cpu%":0.821}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-18047,"args":{"cpu%":0.96}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-17547,"args":{"cpu%":0.664}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-17047,"args":{"cpu%":0.958}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-16543,"args":{"cpu%":0.874}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-16039,"args":{"cpu%":0.857}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-15539,"args":{"cpu%":0.953}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-15035,"args":{"cpu%":0.802}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-14535,"args":{"cpu%":0.94}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-14035,"args":{"cpu%":0.821}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-13533,"args":{"cpu%":0.959}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-13033,"args":{"cpu%":0.846}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-12533,"args":{"cpu%":0.852}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-12031,"args":{"cpu%":0.948}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-11529,"args":{"cpu%":0.818}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-11027,"args":{"cpu%":0.922}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-10527,"args":{"cpu%":0.911}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-10027,"args":{"cpu%":0.855}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-9526,"args":{"cpu%":0.926}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-9026,"args":{"cpu%":0.798}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-8526,"args":{"cpu%":0.557}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-8026,"args":{"cpu%":0.21}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-7525,"args":{"cpu%":0.114}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-7025,"args":{"cpu%":0.113}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-6525,"args":{"cpu%":0.241}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-6024,"args":{"cpu%":0.114}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-5524,"args":{"cpu%":0.14}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-5024,"args":{"cpu%":0.047}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-4524,"args":{"cpu%":0.031}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-4023,"args":{"cpu%":0.037}}, +{"tid":0,"pid":200,"ph":"C","name":"emon_cpuutil","ts":-3523,"args":{"cpu%":0.051}}, +{"name": "thread_sort_index", "ph": "M", "pid": 200, "tid": 0, "args": {"sort_index ": 0}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-33062,"args":{"cpu freq":1484.899}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-32562,"args":{"cpu freq":3490.27}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-32062,"args":{"cpu freq":3506.32}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-31561,"args":{"cpu freq":3527.429}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-31061,"args":{"cpu freq":3561.722}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-30561,"args":{"cpu freq":3319.664}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-30060,"args":{"cpu freq":1379.214}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-29560,"args":{"cpu freq":1890.723}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-29060,"args":{"cpu freq":3482.122}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-28559,"args":{"cpu freq":3513.709}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-28059,"args":{"cpu freq":3531.37}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-27559,"args":{"cpu freq":3537.36}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-27058,"args":{"cpu freq":3328.559}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-26558,"args":{"cpu freq":3507.392}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-26058,"args":{"cpu freq":3526.368}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-25557,"args":{"cpu freq":3544.389}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-25057,"args":{"cpu freq":3461.059}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-24557,"args":{"cpu freq":3485.67}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-24056,"args":{"cpu freq":3519.72}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-23556,"args":{"cpu freq":3411.889}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-23055,"args":{"cpu freq":3411.17}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-22555,"args":{"cpu freq":1626.804}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-22055,"args":{"cpu freq":3497.99}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-21551,"args":{"cpu freq":3494.923}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-21051,"args":{"cpu freq":3500.409}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-20551,"args":{"cpu freq":3500.0}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-20049,"args":{"cpu freq":3500.053}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-19549,"args":{"cpu freq":3500.0}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-19049,"args":{"cpu freq":3499.993}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-18549,"args":{"cpu freq":3498.202}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-18047,"args":{"cpu freq":3499.996}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-17547,"args":{"cpu freq":3489.839}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-17047,"args":{"cpu freq":3500.0}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-16543,"args":{"cpu freq":3500.001}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-16039,"args":{"cpu freq":3500.034}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-15539,"args":{"cpu freq":3500.0}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-15035,"args":{"cpu freq":3500.045}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-14535,"args":{"cpu freq":3499.994}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-14035,"args":{"cpu freq":3500.181}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-13533,"args":{"cpu freq":3500.0}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-13033,"args":{"cpu freq":3495.654}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-12533,"args":{"cpu freq":3499.996}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-12031,"args":{"cpu freq":3499.987}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-11529,"args":{"cpu freq":3499.992}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-11027,"args":{"cpu freq":3500.001}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-10527,"args":{"cpu freq":3499.992}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-10027,"args":{"cpu freq":3499.986}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-9526,"args":{"cpu freq":3499.986}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-9026,"args":{"cpu freq":3499.806}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-8526,"args":{"cpu freq":3475.321}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-8026,"args":{"cpu freq":3329.652}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-7525,"args":{"cpu freq":3485.31}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-7025,"args":{"cpu freq":3516.153}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-6525,"args":{"cpu freq":3488.135}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-6024,"args":{"cpu freq":3530.858}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-5524,"args":{"cpu freq":3483.958}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-5024,"args":{"cpu freq":3002.176}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-4524,"args":{"cpu freq":2303.263}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-4023,"args":{"cpu freq":2380.255}}, +{"tid":1,"pid":200,"ph":"C","name":"emon_cpufreq","ts":-3523,"args":{"cpu freq":3051.839}}, +{"name": "thread_sort_index", "ph": "M", "pid": 200, "tid": 1, "args": {"sort_index ": 1}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-33062,"args":{"pathlength":0.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-32562,"args":{"pathlength":2.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-32062,"args":{"pathlength":7.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-31561,"args":{"pathlength":12.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-31061,"args":{"pathlength":6.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-30561,"args":{"pathlength":1.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-30060,"args":{"pathlength":0.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-29560,"args":{"pathlength":0.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-29060,"args":{"pathlength":3.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-28559,"args":{"pathlength":9.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-28059,"args":{"pathlength":10.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-27559,"args":{"pathlength":7.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-27058,"args":{"pathlength":5.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-26558,"args":{"pathlength":10.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-26058,"args":{"pathlength":12.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-25557,"args":{"pathlength":5.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-25057,"args":{"pathlength":7.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-24557,"args":{"pathlength":14.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-24056,"args":{"pathlength":6.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-23556,"args":{"pathlength":5.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-23055,"args":{"pathlength":2.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-22555,"args":{"pathlength":0.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-22055,"args":{"pathlength":35.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-21551,"args":{"pathlength":29.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-21051,"args":{"pathlength":63.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-20551,"args":{"pathlength":77.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-20049,"args":{"pathlength":34.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-19549,"args":{"pathlength":77.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-19049,"args":{"pathlength":63.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-18549,"args":{"pathlength":60.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-18047,"args":{"pathlength":76.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-17547,"args":{"pathlength":38.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-17047,"args":{"pathlength":77.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-16543,"args":{"pathlength":64.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-16039,"args":{"pathlength":59.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-15539,"args":{"pathlength":75.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-15035,"args":{"pathlength":59.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-14535,"args":{"pathlength":76.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-14035,"args":{"pathlength":60.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-13533,"args":{"pathlength":77.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-13033,"args":{"pathlength":58.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-12533,"args":{"pathlength":64.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-12031,"args":{"pathlength":75.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-11529,"args":{"pathlength":60.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-11027,"args":{"pathlength":73.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-10527,"args":{"pathlength":67.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-10027,"args":{"pathlength":65.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-9526,"args":{"pathlength":74.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-9026,"args":{"pathlength":55.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-8526,"args":{"pathlength":47.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-8026,"args":{"pathlength":18.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-7525,"args":{"pathlength":6.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-7025,"args":{"pathlength":7.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-6525,"args":{"pathlength":14.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-6024,"args":{"pathlength":7.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-5524,"args":{"pathlength":8.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-5024,"args":{"pathlength":2.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-4524,"args":{"pathlength":1.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-4023,"args":{"pathlength":2.0}}, +{"tid":2,"pid":200,"ph":"C","name":"emon_instr_retired","ts":-3523,"args":{"pathlength":3.0}}, +{"name": "thread_sort_index", "ph": "M", "pid": 200, "tid": 2, "args": {"sort_index ": 2}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-33062,"args":{"ipc":0.366}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-32562,"args":{"ipc":1.114}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-32062,"args":{"ipc":1.035}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-31561,"args":{"ipc":1.127}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-31061,"args":{"ipc":1.159}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-30561,"args":{"ipc":1.101}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-30060,"args":{"ipc":0.333}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-29560,"args":{"ipc":1.057}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-29060,"args":{"ipc":1.02}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-28559,"args":{"ipc":1.042}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-28059,"args":{"ipc":1.161}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-27559,"args":{"ipc":1.135}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-27058,"args":{"ipc":0.911}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-26558,"args":{"ipc":1.078}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-26058,"args":{"ipc":1.131}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-25557,"args":{"ipc":1.191}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-25057,"args":{"ipc":1.022}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-24557,"args":{"ipc":1.108}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-24056,"args":{"ipc":1.111}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-23556,"args":{"ipc":1.054}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-23055,"args":{"ipc":1.128}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-22555,"args":{"ipc":0.754}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-22055,"args":{"ipc":0.858}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-21551,"args":{"ipc":0.761}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-21051,"args":{"ipc":1.315}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-20551,"args":{"ipc":1.402}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-20049,"args":{"ipc":0.884}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-19549,"args":{"ipc":1.43}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-19049,"args":{"ipc":1.301}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-18549,"args":{"ipc":1.306}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-18047,"args":{"ipc":1.414}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-17547,"args":{"ipc":1.03}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-17047,"args":{"ipc":1.436}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-16543,"args":{"ipc":1.302}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-16039,"args":{"ipc":1.227}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-15539,"args":{"ipc":1.411}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-15035,"args":{"ipc":1.311}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-14535,"args":{"ipc":1.436}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-14035,"args":{"ipc":1.294}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-13533,"args":{"ipc":1.429}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-13033,"args":{"ipc":1.227}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-12533,"args":{"ipc":1.334}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-12031,"args":{"ipc":1.41}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-11529,"args":{"ipc":1.307}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-11027,"args":{"ipc":1.409}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-10527,"args":{"ipc":1.313}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-10027,"args":{"ipc":1.35}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-9526,"args":{"ipc":1.422}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-9026,"args":{"ipc":1.232}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-8526,"args":{"ipc":1.505}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-8026,"args":{"ipc":1.613}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-7525,"args":{"ipc":0.968}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-7025,"args":{"ipc":1.081}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-6525,"args":{"ipc":1.016}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-6024,"args":{"ipc":1.086}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-5524,"args":{"ipc":0.983}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-5024,"args":{"ipc":1.104}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-4524,"args":{"ipc":1.039}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-4023,"args":{"ipc":1.078}}, +{"tid":3,"pid":200,"ph":"C","name":"emon_ipc","ts":-3523,"args":{"ipc":1.176}}, +{"name": "thread_sort_index", "ph": "M", "pid": 200, "tid": 3, "args": {"sort_index ": 3}}, +{"name": "process_sort_index", "ph": "M", "pid": 0, "tid": 0, "args": {"sort_index ": 0}}, +{"name": "process_sort_index", "ph": "M", "pid": 100, "tid": 0, "args": {"sort_index ": 100}}, +{"name": "process_sort_index", "ph": "M", "pid": 200, "tid": 0, "args": {"sort_index ": 200}}, +{"name": "process_sort_index", "ph": "M", "pid": 100500, "tid": 0, "args": {"sort_index ": 100500}}, +{"name": "process_sort_index", "ph": "M", "pid": 100400, "tid": 0, "args": {"sort_index ": 100400}}, +{"name": "process_sort_index", "ph": "M", "pid": 100500, "tid": 0, "args": {"sort_index ": 100500}}, +{"name": "process_sort_index", "ph": "M", "pid": 100400, "tid": 0, "args": {"sort_index ": 100400}}, +{"name": "process_sort_index", "ph": "M", "pid": 100600, "tid": 0, "args": {"sort_index ": 100600}}, +{"name": "process_sort_index", "ph": "M", "pid": 100300, "tid": 0, "args": {"sort_index ": 100300}}, +{"name": "process_sort_index", "ph": "M", "pid": 100600, "tid": 0, "args": {"sort_index ": 100600}}, +{"name": "process_sort_index", "ph": "M", "pid": 100300, "tid": 0, "args": {"sort_index ": 100300}}, +{"name": "process_sort_index", "ph": "M", "pid": 100600, "tid": 0, "args": {"sort_index ": 100600}}, +{"name": "process_sort_index", "ph": "M", "pid": 100500, "tid": 0, "args": {"sort_index ": 100500}}, +{"name": "process_sort_index", "ph": "M", "pid": 100400, "tid": 0, "args": {"sort_index ": 100400}}, +{"name": "process_sort_index", "ph": "M", "pid": 100300, "tid": 0, "args": {"sort_index ": 100300}}, +{"name": "process_sort_index", "ph": "M", "pid": 100500, "tid": 0, "args": {"sort_index ": 100500}}, +{"name": "process_sort_index", "ph": "M", "pid": 100600, "tid": 0, "args": {"sort_index ": 100600}}, +{"name": "process_sort_index", "ph": "M", "pid": 100400, "tid": 0, "args": {"sort_index ": 100400}}, +{"name": "process_sort_index", "ph": "M", "pid": 100300, "tid": 0, "args": {"sort_index ": 100300}}, +{"name": "process_sort_index", "ph": "M", "pid": 100300, "tid": 0, "args": {"sort_index ": 100300}}, +{"name": "process_sort_index", "ph": "M", "pid": 100500, "tid": 0, "args": {"sort_index ": 100500}}, +{"name": "process_sort_index", "ph": "M", "pid": 100600, "tid": 0, "args": {"sort_index ": 100600}}, +{"name": "process_sort_index", "ph": "M", "pid": 100400, "tid": 0, "args": {"sort_index ": 100400}}, +{"name": "process_sort_index", "ph": "M", "pid": 100300, "tid": 0, "args": {"sort_index ": 100300}}, +{"name": "process_sort_index", "ph": "M", "pid": 100500, "tid": 0, "args": {"sort_index ": 100500}}, +{"name": "process_sort_index", "ph": "M", "pid": 100600, "tid": 0, "args": {"sort_index ": 100600}}, +{"name": "process_sort_index", "ph": "M", "pid": 100400, "tid": 0, "args": {"sort_index ": 100400}}, +{"name": "process_sort_index", "ph": "M", "pid": 100500, "tid": 0, "args": {"sort_index ": 100500}}, +{"name": "process_sort_index", "ph": "M", "pid": 100600, "tid": 0, "args": {"sort_index ": 100600}}, +{"name": "process_sort_index", "ph": "M", "pid": 100400, "tid": 0, "args": {"sort_index ": 100400}} + ], + "displayTimeUnit": "ns" + } \ No newline at end of file diff --git a/tools/workload/benchmark_velox/tpc_workload.ipynb b/tools/workload/benchmark_velox/tpc_workload.ipynb index 5dcb50a8a066..c0232d1d52f6 100644 --- a/tools/workload/benchmark_velox/tpc_workload.ipynb +++ b/tools/workload/benchmark_velox/tpc_workload.ipynb @@ -35,22 +35,10 @@ "# List of network devices. e.g. ['ens787f0']\n", "nic_dev=[]\n", "\n", - "# Hostname or IP to server for perf analysis. Able to connect via ssh.\n", - "server=''\n", - "\n", - "# Specify the directory on perf analysis server. Usually a codename for this run.\n", - "base_dir=''\n", - "\n", - "# Proxy used to connect to server for perf analysis.\n", - "proxy=''\n", - "\n", - "# Whether to upload profile to perf analysis server and run perf analysis scripts. Only takes effect if server is set.\n", - "analyze_perf=True\n", - "\n", "# Select workload. Can be either 'tpch' or 'tpcds'.\n", "workload='tpch'\n", "\n", - "# Run with gluten. If False, run vanilla Spark.\n", + "# Run with gluten. If False, run Spark.\n", "run_gluten=True\n", "\n", "# TPC tables\n", @@ -59,30 +47,49 @@ "\n", "# Parallelism\n", "executors_per_node=32\n", - "cores_per_executor=8\n", + "cores_per_executor=7\n", "\n", "gluten_tpch_task_per_core=2\n", "gluten_tpcds_task_per_core=4\n", - "vanilla_tpch_task_per_core=8\n", - "vanilla_tpcds_task_per_core=8\n", + "spark_tpch_task_per_core=8\n", + "spark_tpcds_task_per_core=8\n", "\n", "# Physical memory on each worker node.\n", "memory_per_node='1000g'\n", "\n", - "# Offheap ratio. 0 to disable offheap for vanilla Spark.\n", + "# Offheap ratio. 0 to disable offheap for Spark.\n", "# onheap:offheap = 1:2\n", - "vanilla_offheap_ratio=2.0\n", + "spark_offheap_ratio=2.0\n", "# onheap:offheap = 1:7\n", "gluten_offheap_ratio=7.0\n", "\n", "# spark.io.compression.codec\n", - "vanilla_codec='lz4'\n", + "spark_codec='lz4'\n", "# spark.gluten.sql.columnar.shuffle.codec\n", "gluten_codec='lz4'\n", "# spark.gluten.sql.columnar.shuffle.codecBackend\n", "gluten_codec_backend=''\n", "# spark.gluten.sql.columnar.maxBatchSize\n", - "max_batch_size=4096" + "max_batch_size=4096\n", + "\n", + "# Hostname or IP to server for perf analysis. Able to connect via ssh.\n", + "server=''\n", + "\n", + "# Specify the directory on perf analysis server. Usually a codename for this run.\n", + "base_dir=''\n", + "\n", + "# Proxy used to connect to server for perf analysis.\n", + "proxy=''\n", + "\n", + "# Emon event file for `emon -i`. Set to emptry string '' if emon is unavailable.\n", + "# Supported emon events on platform can be verified via `emon -i emon.list`\n", + "emon_list=''\n", + "\n", + "# Whether to run perf analysis scripts. Only takes effect if server is set.\n", + "analyze_perf=False\n", + "\n", + "# List of email to receive perf analysis results.\n", + "emails = []" ] }, { @@ -176,8 +183,8 @@ " pass\n", " return conf\n", "\n", - "def vanilla_conf_overwrite(conf):\n", - " conf.set('spark.io.compression.codec', vanilla_codec)\\\n", + "def spark_conf_overwrite(conf):\n", + " conf.set('spark.io.compression.codec', spark_codec)\\\n", " .set('spark.executorEnv.LD_LIBRARY_PATH',f\"{os.getenv('HADOOP_HOME')}/lib/native/\") \\\n", " .set('spark.yarn.appMasterEnv.LD_LIBRARY_PATH',f\"{os.getenv('HADOOP_HOME')}/lib/native/\") \\\n", "\n", @@ -190,7 +197,7 @@ "def app_conf_overwrite(conf):\n", " if run_gluten:\n", " return gluten_conf_overwrite(conf)\n", - " return vanilla_conf_overwrite(conf)" + " return spark_conf_overwrite(conf)" ] }, { @@ -238,7 +245,7 @@ "metadata": {}, "outputs": [], "source": [ - "test_tpc.start_monitor(clients)" + "test_tpc.start_monitor(clients, emon_list=emon_list)" ] }, { @@ -266,7 +273,7 @@ "outputs": [], "source": [ "if analyze_perf:\n", - " test_tpc.run_perf_analysis(disk_dev, nic_dev)" + " test_tpc.run_perf_analysis(disk_dev, nic_dev, proxy, emails)" ] }, {