{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# More Debugging\n", "\n", "CSDL provides a few tools to help you debug your code. This section will cover some of the most common debugging techniques in CSDL.\n", "\n", "| Tools | Description |\n", "| -------- | ------- |\n", "| ```Recorder(inline = True), print(Variable.value)``` | Computes values right as operations are defined |\n", "| ```Recorder(debug = True), Variable.print_trace()``` | Debug mode stores a trace of the file and line # of where the variable was created. ```print_trace()``` prints a trace of a variable. |\n", "| ```Recorder.visualize_graph()``` | Saves an image of the graph itself (can be slow for large models). |\n", "| ```Recorder.visualize_adjacency_matrix()``` | Displays the adjency matrix of the graph itself (can be slow for large models). |\n", "| ```csdl.inline_export(summary_csv=True)``` | Saves the variables' values to a csv file. |\n", "| ```Recorder.print_graph_structure()``` | Displays the graph hierarchy of the recorder (useful to visualize nested for loops, nonlinear solvers and composed operations). |\n", "| ```Recorder.count_origins()``` | Lists how many variables created per file/function |\n", "| ```Recorder.count_operations()``` | Lists how many operation instances per type of operation |\n", "| ```Recorder.print_largest_variables()``` | Lists the largest variables in terms of number of elements |\n", "\n", "We will go through a few examples to show how some of these examples work" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Inline evaluation\n", "With ```inline = True```, print the values of your variables as soon as they are computed. If a value is not given when instantiating a variable, the inline evaluation will throw an error, so make sure to set a value when you can." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "inline = True:\n", " value: [35.]\n", " value type: \n", " value shape: (1,)\n", "\n" ] } ], "source": [ "import csdl_alpha as csdl\n", "recorder = csdl.Recorder(inline=True)\n", "recorder.start()\n", "\n", "a = csdl.Variable(name='a', value=10.0)\n", "b = csdl.Variable(name='b', value=5.0)\n", "c = a+b**2.0\n", "\n", "recorder.stop()\n", "\n", "# The value of c is a numpy array populated with the value of the expression\n", "print('inline = True:')\n", "print(' value: ', c.value)\n", "print(' value type: ', type(c.value))\n", "print(' value shape: ', c.value.shape)\n", "print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With ```inline = False```, the graph is built but the actual computations are not evaluated as the graph is built. We can see that a variable's ```value``` is empty if inline evaluation is turned off." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "inline = False:\n", " value: None\n", " value type: \n", "\n" ] } ], "source": [ "import csdl_alpha as csdl\n", "recorder = csdl.Recorder()\n", "recorder.start()\n", "\n", "a = csdl.Variable(name='a', value=5.0)\n", "b = csdl.Variable(name='b', value=15.0)\n", "c = a+b**2.0\n", "\n", "recorder.stop()\n", "\n", "# The value of c is None because the expression was not evaluated\n", "print('inline = False:')\n", "print(' value: ', c.value)\n", "print(' value type: ', type(c.value))\n", "# print(' value shape: ', c.value.shape)\n", "print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To actually run the code, use ```recorder.execute()```" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "inline = False, after recorder.execute():\n", " value: [230.]\n", " value type: \n", " value shape: (1,)\n", "\n" ] } ], "source": [ "recorder.execute()\n", "\n", "# The value of c is updated with the value of the expression\n", "print('inline = False, after recorder.execute():')\n", "print(' value: ', c.value)\n", "print(' value type: ', type(c.value))\n", "print(' value shape: ', c.shape)\n", "print()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "inline = False, after recorder.execute():\n", " value: [110.]\n", " value type: \n", " value shape: (1,)\n", "\n" ] } ], "source": [ "a.set_value(10.0)\n", "b.set_value(10.0)\n", "recorder.execute()\n", "\n", "# The value of c is updated with the value of the expression\n", "print('inline = False, after recorder.execute():')\n", "print(' value: ', c.value)\n", "print(' value type: ', type(c.value))\n", "print(' value shape: ', c.shape)\n", "print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Debugging mode\n", "With ```csdl.Recorder(debug = True)```, the construction of every variable is tracked. Call a variable's ```print_trace``` method to show where in your code that variable was created. " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import csdl_alpha as csdl\n", "recorder = csdl.Recorder(debug = True)\n", "recorder.start()\n", "\n", "a = csdl.Variable(name='a', value=5.0)\n", "b = csdl.Variable(name='b', value=15.0)\n", "c = a+b**2.0\n", "\n", "# uncomment when running\n", "# c.print_trace()\n", "\n", "recorder.stop()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Graph Visualization\n", "In order to visualize the graph itself, use ```Recorder.visualize_graph()```." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "import csdl_alpha as csdl\n", "recorder = csdl.Recorder(inline = True)\n", "recorder.start()\n", "\n", "a = csdl.Variable(name='a', value=5.0)\n", "b = csdl.Variable(name='b', value=15.0)\n", "b2 = b**2.0\n", "with csdl.namespace('sample_namespace'):\n", " c = a+b2\n", " c.add_name('c')\n", "\n", "recorder.visualize_graph('very_small_graph') # saves to current working directory\n", "\n", "recorder.stop()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The saved image:\n", "\n", "![alt text](very_small_graph.svg \"very_small_graph\")\n", "\n", "To see an example of ```Recorder.print_graph_structure()```, see the ```nonlinear_solver.ipynb``` example." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Save to CSV\n", "To view all variables, use ```csdl.inline_export(summary_csv=True)```" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Variable Min Max Mean Shape Graphs \n", "a 5.0 5.0 5.0 (1,) graph \n", "b 15.0 15.0 15.0 (1,) graph \n", "variable_0 2.0 2.0 2.0 (1,) graph \n", "variable_1 225.0 225.0 225.0 (1,) graph \n", "sample_namespace.c 230.0 230.0 230.0 (1,) graph \n" ] } ], "source": [ "import csdl_alpha as csdl\n", "recorder = csdl.Recorder(inline = True)\n", "recorder.start()\n", "\n", "a = csdl.Variable(name='a', value=5.0)\n", "b = csdl.Variable(name='b', value=15.0)\n", "b2 = b**2.0\n", "with csdl.namespace('sample_namespace'):\n", " c = a+b2\n", " c.add_name('c')\n", "\n", "csdl.save_all_variables()\n", "csdl.inline_export('output_csv_file', summary_csv=True, do_print=True)\n", "recorder.stop()" ] } ], "metadata": { "kernelspec": { "display_name": "csdl_a", "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.9.19" } }, "nbformat": 4, "nbformat_minor": 2 }