Adapt to paper requirements

This commit is contained in:
Maximilian Schmeller 2023-02-15 17:02:20 +09:00
parent 3ae2d5595a
commit ca1fc0ea50
2 changed files with 128 additions and 138 deletions

View file

@ -65,7 +65,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--base-directory', '-d', default=os.path.expandvars('$HOME/Projects/ma-measurements'), parser.add_argument('--base-directory', '-d', default=os.path.expandvars('$HOME/runner_artifacts'),
help='The base directory containing all artifacts directories to be processed') help='The base directory containing all artifacts directories to be processed')
parser.add_argument('--name-filter', '-f', default="artifacts_*", help="A shell-style wildcard expression to filter artifact folder names within the base directory. E.g. 'artifacts_2023*'.") parser.add_argument('--name-filter', '-f', default="artifacts_*", help="A shell-style wildcard expression to filter artifact folder names within the base directory. E.g. 'artifacts_2023*'.")

View file

@ -3,6 +3,9 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"import os\n", "import os\n",
@ -21,23 +24,23 @@
"plt.rcParams['figure.dpi'] = 300\n", "plt.rcParams['figure.dpi'] = 300\n",
"\n", "\n",
"%matplotlib inline" "%matplotlib inline"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"source": [
"# User Settings"
],
"metadata": { "metadata": {
"collapsed": false "collapsed": false
} },
"source": [
"# User Settings"
]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"##################################################\n", "##################################################\n",
@ -56,13 +59,12 @@
"\n", "\n",
"# The path to the build folder of a ROS2 workspace that contains the\n", "# The path to the build folder of a ROS2 workspace that contains the\n",
"# tracetools_read and tracetools_analysis folders.\n", "# tracetools_read and tracetools_analysis folders.\n",
"TRACING_WS_BUILD_PATH = \"~/Projects/autoware/build\"\n", "TRACING_WS_BUILD_PATH = \"/path/to/tracing_ws/build\"\n",
"\n", "\n",
"# Path to trace directory (e.g. ~/.ros/my-trace/ust) or to a converted trace file.\n", "# Path to trace directory (e.g. ~/.ros/my-trace/ust) or to a converted trace file.\n",
"# Using the path \"/ust\" at the end is optional but greatly reduces processing time\n", "# Using the path \"/ust\" at the end is optional but greatly reduces processing time\n",
"# if kernel traces are also present.\n", "# if kernel traces are also present.\n",
"# TR_PATH = \"~/Downloads/iteration1_worker1/aw_replay/tracing/scenario-trace/ust\"\n", "TR_PATH = \"/path/to/tracing/session-name/ust\"\n",
"TR_PATH = \"/home/max/Projects/ma-measurements/artifacts_20221223_155956/tracing/max-ma-trace/ust\"\n",
"\n", "\n",
"# Path to the folder all artifacts from this notebook are saved to.\n", "# Path to the folder all artifacts from this notebook are saved to.\n",
"# This entails plots as well as data tables.\n", "# This entails plots as well as data tables.\n",
@ -75,7 +77,7 @@
"BW_ENABLED = False\n", "BW_ENABLED = False\n",
"# Path to a HDF5 file as output by ma-hw-perf-tools/messages/record.bash\n", "# Path to a HDF5 file as output by ma-hw-perf-tools/messages/record.bash\n",
"# Used to annotate message sizes in E2E latency calculations\n", "# Used to annotate message sizes in E2E latency calculations\n",
"BW_PATH = \"../ma-hw-perf-tools/data/messages-x86.h5\"\n", "BW_PATH = \"path/to/messages.h5\"\n",
"\n", "\n",
"# Whether to use dependencies extracted by the Clang-tools to supplement\n", "# Whether to use dependencies extracted by the Clang-tools to supplement\n",
"# automatic node-internal data flow annotations.\n", "# automatic node-internal data flow annotations.\n",
@ -83,7 +85,7 @@
"CL_ENABLED = False\n", "CL_ENABLED = False\n",
"# Path to the output directory of the ROS2 dependency checker.\n", "# Path to the output directory of the ROS2 dependency checker.\n",
"# Will only be used if CL_ENABLED is True.\n", "# Will only be used if CL_ENABLED is True.\n",
"CL_PATH = \"~/Projects/llvm-project/clang-tools-extra/ros2-internal-dependency-checker/output\"\n", "CL_PATH = \"/path/to/code_analysis/output\"\n",
"\n", "\n",
"# Whether to compute data flow graphs.\n", "# Whether to compute data flow graphs.\n",
"# If you are only interested in E2E latencies, set this to False\n", "# If you are only interested in E2E latencies, set this to False\n",
@ -209,14 +211,14 @@
" if isinstance(v, Iterable) and not isinstance(v, str):\n", " if isinstance(v, Iterable) and not isinstance(v, str):\n",
" v = (\"\\n \" + (\" \" * 44)).join(list(map(str, v)))\n", " v = (\"\\n \" + (\" \" * 44)).join(list(map(str, v)))\n",
" print(f\" {k:.<40s} := {v}\")" " print(f\" {k:.<40s} := {v}\")"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"# The last few imports can only be resolved using the user-specified paths above\n", "# The last few imports can only be resolved using the user-specified paths above\n",
@ -230,25 +232,25 @@
"from tracetools_analysis.processor.ros2 import Ros2Handler\n", "from tracetools_analysis.processor.ros2 import Ros2Handler\n",
"\n", "\n",
"from tracing_interop.tr_types import *" "from tracing_interop.tr_types import *"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [ "source": [
"# Load Trace Data\n", "# Load Trace Data\n",
"\n", "\n",
"Load (and, if necessary, convert) tracing data obtained through ros2_tracing. Build indices for fast analysis." "Load (and, if necessary, convert) tracing data obtained through ros2_tracing. Build indices for fast analysis."
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"def _load_traces():\n", "def _load_traces():\n",
@ -278,14 +280,14 @@
" globals()[name] = getattr(_tracing_context, name)\n", " globals()[name] = getattr(_tracing_context, name)\n",
"\n", "\n",
"print(\"Done.\")" "print(\"Done.\")"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"##################################################\n", "##################################################\n",
@ -320,14 +322,14 @@
"publishers.rebuild()\n", "publishers.rebuild()\n",
"print(\"Adding new topics and rebuilding topic index\")\n", "print(\"Adding new topics and rebuilding topic index\")\n",
"topics.append(tf_split_topics)" "topics.append(tf_split_topics)"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"print(\"Artificial TF topics (/tf[...]):\")\n", "print(\"Artificial TF topics (/tf[...]):\")\n",
@ -339,14 +341,14 @@
" #for node in nodes:\n", " #for node in nodes:\n",
" # if node.path.startswith(prefix) and node.path.removeprefix(prefix).count(\"/\") <= 1 and \"transform_listener_impl\" not in node.path:\n", " # if node.path.startswith(prefix) and node.path.removeprefix(prefix).count(\"/\") <= 1 and \"transform_listener_impl\" not in node.path:\n",
" # print(f\" -> {' ' * (len(prefix) - 3)}{node.path.removeprefix(prefix)}\")" " # print(f\" -> {' ' * (len(prefix) - 3)}{node.path.removeprefix(prefix)}\")"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"##################################################\n", "##################################################\n",
@ -368,24 +370,24 @@
" for f in E2E_OUTPUT_TOPIC_PATTERNS:\n", " for f in E2E_OUTPUT_TOPIC_PATTERNS:\n",
" if re.search(f, t.name):\n", " if re.search(f, t.name):\n",
" print(f\"--[DEBUG] {f:<30s}:{t.name:.<89s} | {sum(map(lambda p: len(p.instances), t.publishers)):>5d} msgs\")" " print(f\"--[DEBUG] {f:<30s}:{t.name:.<89s} | {sum(map(lambda p: len(p.instances), t.publishers)):>5d} msgs\")"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [ "source": [
"# Analyze ROS Graph\n", "# Analyze ROS Graph\n",
"Reconstruct namespace hierarchy, data flow graph between callbacks." "Reconstruct namespace hierarchy, data flow graph between callbacks."
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"import latency_graph.latency_graph_structure as lg\n", "import latency_graph.latency_graph_structure as lg\n",
@ -396,24 +398,24 @@
"\n", "\n",
"\n", "\n",
"lat_graph = cached(\"lat_graph\", _make_latency_graph, [TR_PATH], not CACHING_ENABLED)" "lat_graph = cached(\"lat_graph\", _make_latency_graph, [TR_PATH], not CACHING_ENABLED)"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [ "source": [
"## Plot ROS Graph (full)\n", "## Plot ROS Graph (full)\n",
"Plot the DFG hierarchically by node namespace. Plot each internal and external dependency between callbacks as one arrow." "Plot the DFG hierarchically by node namespace. Plot each internal and external dependency between callbacks as one arrow."
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false DFG_ENABLED\n", "%%skip_if_false DFG_ENABLED\n",
@ -426,24 +428,27 @@
"from latency_graph.latency_graph_plots import plot_latency_graph_full\n", "from latency_graph.latency_graph_plots import plot_latency_graph_full\n",
"\n", "\n",
"plot_latency_graph_full(lat_graph, _tracing_context, os.path.join(OUT_PATH, \"latency_graph_full\"))" "plot_latency_graph_full(lat_graph, _tracing_context, os.path.join(OUT_PATH, \"latency_graph_full\"))"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [ "source": [
"## Plot Latency Graph (overview)\n", "## Plot Latency Graph (overview)\n",
"Plot the DFG down to a certain hierarchy level in a flattened manner. Aggregate dependencies from multiple callbacks into corresponding node-node dependencies." "Plot the DFG down to a certain hierarchy level in a flattened manner. Aggregate dependencies from multiple callbacks into corresponding node-node dependencies."
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%%%skip_if_false DFG_ENABLED\n"
}
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false DFG_ENABLED\n", "%%skip_if_false DFG_ENABLED\n",
@ -457,27 +462,24 @@
"from latency_graph.latency_graph_plots import plot_latency_graph_overview\n", "from latency_graph.latency_graph_plots import plot_latency_graph_overview\n",
"\n", "\n",
"plot_latency_graph_overview(lat_graph, DFG_EXCL_NODE_PATTERNS, DFG_INPUT_NODE_PATTERNS, DFG_OUTPUT_NODE_PATTERNS, DFG_MAX_HIER_LEVEL, os.path.join(OUT_PATH, \"latency_graph_overview\"))" "plot_latency_graph_overview(lat_graph, DFG_EXCL_NODE_PATTERNS, DFG_INPUT_NODE_PATTERNS, DFG_OUTPUT_NODE_PATTERNS, DFG_MAX_HIER_LEVEL, os.path.join(OUT_PATH, \"latency_graph_overview\"))"
], ]
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%%%skip_if_false DFG_ENABLED\n"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [ "source": [
"# Analyze Message Flow\n", "# Analyze Message Flow\n",
"Build dependency trees ending in the specified output topics." "Build dependency trees ending in the specified output topics."
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -495,14 +497,14 @@
" import traceback\n", " import traceback\n",
" print(e)\n", " print(e)\n",
" traceback.print_exc()" " traceback.print_exc()"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -518,14 +520,14 @@
"\n", "\n",
"from bw_interop.bw_plots import dds_lat_msg_size_scatter\n", "from bw_interop.bw_plots import dds_lat_msg_size_scatter\n",
"plot_topic = \"\"" "plot_topic = \"\""
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -540,14 +542,14 @@
"trees_paths = [e2e_paths_sorted_desc(tree, E2E_INPUT_TOPIC_PATTERNS) for tree in tqdm(trees, mininterval=10.0,\n", "trees_paths = [e2e_paths_sorted_desc(tree, E2E_INPUT_TOPIC_PATTERNS) for tree in tqdm(trees, mininterval=10.0,\n",
" desc=\"Extracting E2E paths\")]\n", " desc=\"Extracting E2E paths\")]\n",
"all_paths = [p for paths in trees_paths for p in paths]" "all_paths = [p for paths in trees_paths for p in paths]"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -575,14 +577,14 @@
"df_print = df_print.sort_values((\"e2e_latency\", \"count\"), ascending=False)\n", "df_print = df_print.sort_values((\"e2e_latency\", \"count\"), ascending=False)\n",
"df_print.to_csv(os.path.join(OUT_PATH, \"e2e_overview.csv\"), sep=\"\\t\", index=False)\n", "df_print.to_csv(os.path.join(OUT_PATH, \"e2e_overview.csv\"), sep=\"\\t\", index=False)\n",
"df_print" "df_print"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"import pickle\n", "import pickle\n",
@ -590,14 +592,14 @@
"# pickle.dump((trees_paths, all_paths, cohorts), f)\n", "# pickle.dump((trees_paths, all_paths, cohorts), f)\n",
"with open(os.path.join(OUT_PATH, \"state.pkl\"), \"wb\") as f:\n", "with open(os.path.join(OUT_PATH, \"state.pkl\"), \"wb\") as f:\n",
" pickle.dump((trees_paths, all_paths, cohorts), f)" " pickle.dump((trees_paths, all_paths, cohorts), f)"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"##################################################\n", "##################################################\n",
@ -623,14 +625,14 @@
" print(f\"[WARN] Expected exactly one cohort to remain, got {len(cohorts_filt)}. Only the first one will be used.\")\n", " print(f\"[WARN] Expected exactly one cohort to remain, got {len(cohorts_filt)}. Only the first one will be used.\")\n",
"\n", "\n",
"relevant_path, relevant_dataflows = next(iter(cohorts_filt.items()))" "relevant_path, relevant_dataflows = next(iter(cohorts_filt.items()))"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"from message_tree.message_tree_algorithms import e2e_latency_breakdown\n", "from message_tree.message_tree_algorithms import e2e_latency_breakdown\n",
@ -650,14 +652,14 @@
"#e2e_breakdowns_orig = e2e_breakdowns\n", "#e2e_breakdowns_orig = e2e_breakdowns\n",
"\n", "\n",
"#relevant_dataflows, e2e_breakdowns = zip(*filt)" "#relevant_dataflows, e2e_breakdowns = zip(*filt)"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -713,14 +715,14 @@
"plt.savefig(os.path.join(OUT_PATH, \"plot_e2e_portions.png\"))\n", "plt.savefig(os.path.join(OUT_PATH, \"plot_e2e_portions.png\"))\n",
"\n", "\n",
"None\n" "None\n"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -747,14 +749,14 @@
"ax.text(np.mean(e2es) * 1.02, max_ylim * 0.98, 'Mean: {:.3f}s'.format(np.mean(e2es)))\n", "ax.text(np.mean(e2es) * 1.02, max_ylim * 0.98, 'Mean: {:.3f}s'.format(np.mean(e2es)))\n",
"plt.savefig(os.path.join(OUT_PATH, \"plot_e2es.png\"))\n", "plt.savefig(os.path.join(OUT_PATH, \"plot_e2es.png\"))\n",
"None" "None"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -806,14 +808,14 @@
"df_types.to_csv(os.path.join(OUT_PATH, \"plot_e2es_violin_types.csv\"), index=False, header=[\"type\"])\n", "df_types.to_csv(os.path.join(OUT_PATH, \"plot_e2es_violin_types.csv\"), index=False, header=[\"type\"])\n",
"\n", "\n",
"None" "None"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"for concat_pc_items in component_latency_items:\n", "for concat_pc_items in component_latency_items:\n",
@ -822,14 +824,14 @@
" dur_ts_records = [(item.location[0].timestamp, item.duration) for item in concat_pc_items]\n", " dur_ts_records = [(item.location[0].timestamp, item.duration) for item in concat_pc_items]\n",
" df_dur_ts = pd.DataFrame(dur_ts_records, columns=(\"timestamp\", \"duration\"))\n", " df_dur_ts = pd.DataFrame(dur_ts_records, columns=(\"timestamp\", \"duration\"))\n",
" df_dur_ts.to_csv(os.path.join(OUT_PATH, f\"dur_ts_{concat_pc_items[0].location[0].publisher.topic_name.replace('/', '__')}.csv\"), index=False)" " df_dur_ts.to_csv(os.path.join(OUT_PATH, f\"dur_ts_{concat_pc_items[0].location[0].publisher.topic_name.replace('/', '__')}.csv\"), index=False)"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"indices = [i for i, t in enumerate(types) if t == \"cpu\"]\n", "indices = [i for i, t in enumerate(types) if t == \"cpu\"]\n",
@ -839,14 +841,14 @@
"records = [(lbl, x.mean(), x.std(), x.min(), x.max()) for x, lbl in zip(xs, lbls)]\n", "records = [(lbl, x.mean(), x.std(), x.min(), x.max()) for x, lbl in zip(xs, lbls)]\n",
"df_cpu = pd.DataFrame(records, columns=[\"callback\", \"mean\", \"std\", \"min\", \"max\"])\n", "df_cpu = pd.DataFrame(records, columns=[\"callback\", \"mean\", \"std\", \"min\", \"max\"])\n",
"df_cpu.to_csv(os.path.join(OUT_PATH, \"calc_times.csv\"), index=False)" "df_cpu.to_csv(os.path.join(OUT_PATH, \"calc_times.csv\"), index=False)"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"%%skip_if_false E2E_ENABLED\n", "%%skip_if_false E2E_ENABLED\n",
@ -858,30 +860,18 @@
"fig.set_size_inches(16, 9)\n", "fig.set_size_inches(16, 9)\n",
"fig.set_dpi(300)\n", "fig.set_dpi(300)\n",
"None" "None"
], ]
"metadata": {
"collapsed": false
}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [], "outputs": [],
"source": [ "source": [
"print(\"Done.\")" "print(\"Done.\")"
], ]
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false
}
} }
], ],
"metadata": { "metadata": {