<commit_before>{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FYLyuStTYesc"
      },
      "source": [
        "##### Copyright 2020 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "PVm-iEoxYesf"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3MPf91rVYesq"
      },
      "source": [
        "# TensorFlow graph optimization with Grappler"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zmNCsZlgYesr"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://www.tensorflow.org/guide/graph_optimization\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/guide/graph_optimization.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/guide/graph_optimization.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a href=\"https://storage.googleapis.com/tensorflow_docs/docs/site/en/guide/graph_optimization.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l0qacLgyYess"
      },
      "source": [
        "## Overview\n",
        "\n",
        "TensorFlow uses both graph and eager executions to execute computations. A `tf.Graph` contains a set of `tf.Operation` objects (ops) which represent units of computation and `tf.Tensor` objects which represent the units of data that flow between ops.\n",
        "\n",
        "Grappler is the default graph optimization system in the TensorFlow runtime. Grappler applies optimizations in graph mode (within `tf.function`) to improve the performance of your TensorFlow computations through graph simplifications and other high-level optimizations such as inlining function bodies to enable inter-procedural optimizations. Optimizing the `tf.Graph` also reduces the device peak memory usage and improves hardware utilization by optimizing the mapping of graph nodes to compute resources. \n",
        "\n",
        "Use `tf.config.optimizer.set_experimental_options()` for finer control over your `tf.Graph` optimizations.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "A-zkJgR5Yesw"
      },
      "source": [
        "## Available graph optimizers\n",
        "\n",
        "Grappler performs graph optimizations through a top-level driver called the `MetaOptimizer`. The following graph optimizers are available with TensorFlow:  \n",
        "\n",
        "* *Constant folding optimizer -* Statically infers the value of tensors when possible by folding constant nodes in the graph and materializes the result using constants.\n",
        "* *Arithmetic optimizer -* Simplifies arithmetic operations by eliminating common subexpressions and simplifying arithmetic statements.  \n",
        "* *Layout optimizer -* Optimizes tensor layouts to execute data format dependent operations such as convolutions more efficiently.\n",
        "* *Remapper optimizer -* Remaps subgraphs onto more efficient implementations by replacing commonly occuring subgraphs with optimized fused monolithic kernels.\n",
        "* *Memory optimizer -* Analyzes the graph to inspect the peak memory usage for each operation and inserts CPU-GPU memory copy operations for swapping GPU memory to CPU to reduce the peak memory usage.\n",
        "* *Dependency optimizer -* Removes or rearranges control dependencies to shorten the critical path for a model step or enables other\n",
        "optimizations. Also removes nodes that are effectively no-ops such as Identity.\n",
        "* *Pruning optimizer -* Prunes nodes that have no effect on the output from the graph. It is usually run first to reduce the size of the graph and speed up processing in other Grappler passes.\n",
        "* *Function optimizer -* Optimizes the function library of a TensorFlow program and inlines function bodies to enable other inter-procedural optimizations.\n",
        "* *Shape optimizer -* Optimizes subgraphs that operate on shape and shape related information.\n",
        "* *Autoparallel optimizer -* Automatically parallelizes graphs by splitting along the batch dimension. This optimizer is turned OFF by default.\n",
        "* *Loop optimizer -* Optimizes the graph control flow by hoisting loop-invariant subgraphs out of loops and by removing redundant stack operations in loops. Also optimizes loops with statically known trip counts and removes statically known dead branches in conditionals.\n",
        "* *Scoped allocator optimizer -* Introduces scoped allocators to reduce data movement and to consolidate some operations.\n",
        "* *Pin to host optimizer -* Swaps small operations onto the CPU. This optimizer is turned OFF by default. \n",
        "* *Auto mixed precision optimizer -* Converts data types to float16 where applicable to improve performance. Currently applies only to GPUs.\n",
        "* *Debug stripper -* Strips nodes related to debugging operations such as `tf.debugging.Assert`, `tf.debugging.check_numerics`, and `tf.print` from the graph. This optimizer is turned OFF by default."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WZAUsxyWYess"
      },
      "source": [
        "## Setup\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "6BRIDzO6ypoY"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import timeit\n",
        "import traceback\n",
        "import contextlib\n",
        "\n",
        "\n",
        "import tensorflow as tf"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1O-XL1nxJX0X"
      },
      "source": [
        "Create a context manager to easily toggle optimizer states."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "uRuhVoAlYesz"
      },
      "outputs": [],
      "source": [
        "@contextlib.contextmanager\n",
        "def options(options):\n",
        "  old_opts = tf.config.optimizer.get_experimental_options()\n",
        "  tf.config.optimizer.set_experimental_options(options)\n",
        "  try:\n",
        "    yield\n",
        "  finally:\n",
        "    tf.config.optimizer.set_experimental_options(old_opts)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "E2o4kZtK0DoA"
      },
      "source": [
        "## Compare execution performance with and without Grappler\n",
        "\n",
        "TensorFlow 2 and beyond executes [eagerly](../eager.md) by default. Use `tf.function` to switch the default execution to Graph mode. Grappler runs automatically in the background to apply the graph optimizations above and improve execution performance. \n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3sh8RoLJ96IT"
      },
      "source": [
        "### Constant folding optimizer\n",
        "\n",
        "As a preliminary example, consider a function which performs operations on constants and returns an output."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "jOW_OSzMJEvN"
      },
      "outputs": [],
      "source": [
        "def test_function_1():\n",
        "  @tf.function\n",
        "  def simple_function(input_arg):\n",
        "    print('Tracing!')\n",
        "    a = tf.constant(np.random.randn(2000,2000), dtype = tf.float32)\n",
        "    c = a\n",
        "    for n in range(50):\n",
        "      c = c@a\n",
        "    return tf.reduce_mean(c+input_arg)\n",
        "\n",
        "  return simple_function"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tFVgUhhzLKIo"
      },
      "source": [
        "Turn off the constant folding optimizer and execute the function:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "KDMGsOHrJqKD"
      },
      "outputs": [],
      "source": [
        "with options({'constant_folding': False}):\n",
        "  print(tf.config.optimizer.get_experimental_options())\n",
        "  simple_function = test_function_1()\n",
        "  # Trace once\n",
        "  x = tf.constant(2.2)\n",
        "  simple_function(x)\n",
        "  print(\"Vanilla execution:\", timeit.timeit(lambda: simple_function(x), number = 1), \"s\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ykMXfo8qO41z"
      },
      "source": [
        "Enable the constant folding optimizer and execute the function again to observe a speed-up in function execution."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "73pc0gfFKY8l"
      },
      "outputs": [],
      "source": [
        "with options({'constant_folding': True}):\n",
        "  print(tf.config.optimizer.get_experimental_options())\n",
        "  simple_function = test_function_1()\n",
        "  # Trace once\n",
        "  x = tf.constant(2.2)\n",
        "  simple_function(x)\n",
        "  print(\"Constant folded execution:\", timeit.timeit(lambda: simple_function(x), number = 1), \"s\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "83w8rfcRVhWb"
      },
      "source": [
        "### Debug stripper optimizer\n",
        "\n",
        "Consider a simple function that checks the numeric value of its input argument and returns it. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "j2DvqEr8haut"
      },
      "outputs": [],
      "source": [
        "def test_function_2():\n",
        "  @tf.function\n",
        "  def simple_func(input_arg):\n",
        "    output = input_arg\n",
        "    tf.debugging.check_numerics(output, \"Bad!\")\n",
        "    return output\n",
        "  return simple_func"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ywKG3WRbpYB8"
      },
      "source": [
        "First, execute the function with the debug stripper optimizer turned off. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LsE-y6iQWSwH"
      },
      "outputs": [],
      "source": [
        "test_func = test_function_2()\n",
        "p1 = tf.constant(float('inf'))\n",
        "try:\n",
        "  test_func(p1)\n",
        "except tf.errors.InvalidArgumentError as e:\n",
        "  traceback.print_exc(limit=2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "URHpboM8xLN6"
      },
      "source": [
        "`tf.debugging.check_numerics` raises an invalid argument error because of the `Inf` argument to `test_func`."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CuPSha9YmJRo"
      },
      "source": [
        "Enable the debug stripper optimizer and execute the function again. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "UPJ7ygHnWP6B"
      },
      "outputs": [],
      "source": [
        "with options({'debug_stripper': True}):\n",
        "  test_func2 = test_function_2()\n",
        "  p1 = tf.constant(float('inf'))\n",
        "  try:\n",
        "    test_func2(p1)\n",
        "  except tf.errors.InvalidArgumentError as e:\n",
        "    traceback.print_exc(limit=2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nAsESNUB1QpI"
      },
      "source": [
        "The debug stripper optimizer strips the `tf.debug.check_numerics` node from the graph and executes the function without raising any errors. "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wHC6tR9GvFgW"
      },
      "source": [
        "## Summary\n",
        "\n",
        "The TensorFlow runtime uses Grappler to optimize graphs automatically before execution. Use `tf.config.optimizer.set_experimental_options` to enable or disable the various graph optimizers. \n",
        "\n",
        "For more information on Grappler, see <a href=\"http://web.stanford.edu/class/cs245/slides/TFGraphOptimizationsStanford.pdf\" class=\"external\">TensorFlow Graph Optimizations</a>."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "name": "graph_optimization.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}<commit_msg>Translate graph_optimization.ipynb via GitLocalize<commit_after>{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FYLyuStTYesc"
      },
      "source": [
        "##### Copyright 2020 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "PVm-iEoxYesf"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3MPf91rVYesq"
      },
      "source": [
        "# Grappler를 사용한 TensorFlow 그래프 최적화"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zmNCsZlgYesr"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td><a target=\"_blank\" href=\"https://www.tensorflow.org/guide/graph_optimization\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\">View on TensorFlow.org</a></td>\n",
        "  <td><a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/guide/graph_optimization.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\">Run in Google Colab</a></td>\n",
        "  <td><a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/guide/graph_optimization.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\">View source on GitHub</a></td>\n",
        "  <td><a href=\"https://storage.googleapis.com/tensorflow_docs/docs/site/en/guide/graph_optimization.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\">Download notebook</a></td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l0qacLgyYess"
      },
      "source": [
        "## 개요\n",
        "\n",
        "TensorFlow는 그래프와 Eager 실행을 모두 사용하여 계산을 실행합니다. `tf.Graph`에는 계산 단위를 나타내는 `tf.Operation` 객체(ops) 및 ops 간에 흐르는 데이터 단위를 나타내는 `tf.Tensor` 객체가 포함되어 있습니다.\n",
        "\n",
        "Grappler는 TensorFlow 런타임의 기본 그래프 최적화 시스템입니다. Grappler는 그래프 모드(`tf.function` 내)에서 최적화를 적용하여 그래프 단순화 및 함수 본문 인라인과 같은 기타 고급 최적화를 통해 TensorFlow 계산 성능을 향상하여 절차 간 최적화를 가능하게 합니다. `tf.Graph`를 최적화하면 리소스를 계산하기 위한 그래프 노드 매핑을 최적화하여 기기의 최대 메모리 사용량을 줄이고 하드웨어 사용률을 향상할 수 있습니다.\n",
        "\n",
        "`tf.Graph` 최적화를 더 세밀하게 제어하려면 `tf.config.optimizer.set_experimental_options()`를 사용하세요.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "A-zkJgR5Yesw"
      },
      "source": [
        "## 사용 가능한 그래프 옵티마이저\n",
        "\n",
        "Grappler는 `MetaOptimizer`라는 최상위 드라이버를 통해 그래프 최적화를 수행합니다. 다음 그래프 최적화 옵티마이저를 TensorFlow에서 사용할 수 있습니다.\n",
        "\n",
        "- *상수 폴딩 옵티마이저 -* 가능한 경우 그래프에서 상수 노드를 폴딩하여 텐서의 값을 정적으로 추론하고 상수를 사용하는 결과를 구체화합니다.\n",
        "- *산술 옵티마이저 -* 공통 하위 식을 제거하고 산술문을 단순화하여 산술 연산을 단순화합니다.\n",
        "- *레이아웃 옵티마이저 -* 텐서 레이아웃을 최적화하여 컨볼루션과 같이 데이터 형식에 종속적인 연산을 더 효율적으로 실행합니다.\n",
        "- *Remapper 옵티마이저 -* 공통으로 발생하는 하위 그래프를 최적화된 융합 모놀리식 커널로 대체하여 하위 그래프를 더 효율적인 구현으로 다시 매핑합니다.\n",
        "- *메모리 옵티마이저 -* 그래프를 분석하여 각 연산의 최대 메모리 사용량을 검사하고 GPU 메모리를 CPU로 교체하기 위한 CPU-GPU 메모리 복사 작업을 삽입하여 최대 메모리 사용량을 줄입니다.\n",
        "- *종속성 옵티마이저 -* 제어 종속성을 제거하거나 재배열하여 모델 단계의 중요 경로를 단축하거나 다른 최적화를 가능하게 합니다. 또한, Identity와 같이 효과적으로 no-ops인 노드를 제거합니다.\n",
        "- *잘라내기 옵티마이저 -* 그래프 출력에 영향을 미치지 않는 노드를 잘라냅니다. 일반적으로 그래프 크기를 줄이고 다른 Grappler 패스에서 처리 속도를 높이기 위해 먼저 실행됩니다.\n",
        "- *함수 옵티마이저 -*TensorFlow 프로그램의 함수 라이브러리를 최적화하고 함수 본문을 인라인 처리하여 다른 절차 간에 최적화를 가능하게 합니다.\n",
        "- *형상 옵티마이저 -* 형상 및 형상 관련 정보를 기반으로 작동하는 하위 그래프를 최적화합니다.\n",
        "- *자동 병렬 옵티마이저 -* 배치 차원을 따라 분할하여 그래프를 자동으로 병렬화합니다. 이 옵티마이저는 기본적으로 꺼져(OFF) 있습니다.\n",
        "- *루프 옵티마이저 -* 루프 고정 하위 그래프를 루프 밖으로 가져오고 루프에서 중복 스택 연산을 제거하여 그래프 제어 흐름을 최적화합니다. 또한, 정적으로 알려진 트립 카운트로 루프를 최적화하고 조건부에서 정적으로 알려진 데드 분기를 제거합니다.\n",
        "- *범위가 지정된 할당자 옵티마이저 -* 데이터 이동을 줄이고 일부 연산을 통합하기 위해 범위가 지정된 할당자를 소개합니다.\n",
        "- *호스트 옵티마이저로 고정 -* 작은 연산을 CPU로 전환합니다. 이 옵티마이저는 기본적으로 꺼져(OFF) 있습니다.\n",
        "- *자동 혼합 정밀 옵티마이저 -* 성능 향상을 위해 가능한 경우 데이터 유형을 float16으로 변환합니다. 현재 GPU에만 적용됩니다.\n",
        "- *디버그 스트리퍼 -* 그래프에서 `tf.debugging.Assert` , `tf.debugging.check_numerics` 및 `tf.print`와 같은 디버깅 연산과 관련된 노드를 제거합니다. 이 옵티마이저는 기본적으로 꺼져(OFF) 있습니다."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WZAUsxyWYess"
      },
      "source": [
        "## 설정\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "6BRIDzO6ypoY"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import timeit\n",
        "import traceback\n",
        "import contextlib\n",
        "\n",
        "\n",
        "import tensorflow as tf"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1O-XL1nxJX0X"
      },
      "source": [
        "옵티마이저 상태를 쉽게 전환할 수 있는 컨텍스트 관리자를 작성합니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "uRuhVoAlYesz"
      },
      "outputs": [],
      "source": [
        "@contextlib.contextmanager\n",
        "def options(options):\n",
        "  old_opts = tf.config.optimizer.get_experimental_options()\n",
        "  tf.config.optimizer.set_experimental_options(options)\n",
        "  try:\n",
        "    yield\n",
        "  finally:\n",
        "    tf.config.optimizer.set_experimental_options(old_opts)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "E2o4kZtK0DoA"
      },
      "source": [
        "## Grappler의 유무와 관계없이 실행 성능 비교하기\n",
        "\n",
        "TensorFlow 2 이상에서는 기본적으로 [즉시](../eager.md) 실행합니다. `tf.function`을 사용하여 기본 실행을 그래프 모드로 전환합니다. Grappler는 백그라운드에서 자동으로 실행되어 위의 그래프 최적화를 적용하고 실행 성능을 향상합니다.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3sh8RoLJ96IT"
      },
      "source": [
        "### 상수 폴딩 옵티마이저\n",
        "\n",
        "예비 예제로서, 상수에 대한 연산을 수행하고 출력을 반환하는 함수를 고려합니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "jOW_OSzMJEvN"
      },
      "outputs": [],
      "source": [
        "def test_function_1():\n",
        "  @tf.function\n",
        "  def simple_function(input_arg):\n",
        "    print('Tracing!')\n",
        "    a = tf.constant(np.random.randn(2000,2000), dtype = tf.float32)\n",
        "    c = a\n",
        "    for n in range(50):\n",
        "      c = c@a\n",
        "    return tf.reduce_mean(c+input_arg)\n",
        "\n",
        "  return simple_function"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tFVgUhhzLKIo"
      },
      "source": [
        "상수 폴딩 옵티마이저를 끄고 함수를 실행합니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "KDMGsOHrJqKD"
      },
      "outputs": [],
      "source": [
        "with options({'constant_folding': False}):\n",
        "  print(tf.config.optimizer.get_experimental_options())\n",
        "  simple_function = test_function_1()\n",
        "  # Trace once\n",
        "  x = tf.constant(2.2)\n",
        "  simple_function(x)\n",
        "  print(\"Vanilla execution:\", timeit.timeit(lambda: simple_function(x), number = 1), \"s\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ykMXfo8qO41z"
      },
      "source": [
        "상수 폴딩 옵티마이저를 활성화하고 함수를 다시 실행하여 함수 실행의 속도 향상을 관찰합니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "73pc0gfFKY8l"
      },
      "outputs": [],
      "source": [
        "with options({'constant_folding': True}):\n",
        "  print(tf.config.optimizer.get_experimental_options())\n",
        "  simple_function = test_function_1()\n",
        "  # Trace once\n",
        "  x = tf.constant(2.2)\n",
        "  simple_function(x)\n",
        "  print(\"Constant folded execution:\", timeit.timeit(lambda: simple_function(x), number = 1), \"s\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "83w8rfcRVhWb"
      },
      "source": [
        "### 디버그 스트리퍼 옵티마이저\n",
        "\n",
        "입력 인수의 숫자 값을 확인하여 반환하는 간단한 함수를 고려합니다. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "j2DvqEr8haut"
      },
      "outputs": [],
      "source": [
        "def test_function_2():\n",
        "  @tf.function\n",
        "  def simple_func(input_arg):\n",
        "    output = input_arg\n",
        "    tf.debugging.check_numerics(output, \"Bad!\")\n",
        "    return output\n",
        "  return simple_func"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ywKG3WRbpYB8"
      },
      "source": [
        "먼저, 디버그 스트리퍼 옵티마이저를 끈 상태에서 함수를 실행합니다. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LsE-y6iQWSwH"
      },
      "outputs": [],
      "source": [
        "test_func = test_function_2()\n",
        "p1 = tf.constant(float('inf'))\n",
        "try:\n",
        "  test_func(p1)\n",
        "except tf.errors.InvalidArgumentError as e:\n",
        "  traceback.print_exc(limit=2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "URHpboM8xLN6"
      },
      "source": [
        "`tf.debugging.check_numerics`는 `test_func`에 대한 `Inf` 인수로 인해 유효하지 않은 인수 오류를 발생시킵니다."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CuPSha9YmJRo"
      },
      "source": [
        "디버그 스트리퍼 옵티마이저를 활성화하고 함수를 다시 실행합니다. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "UPJ7ygHnWP6B"
      },
      "outputs": [],
      "source": [
        "with options({'debug_stripper': True}):\n",
        "  test_func2 = test_function_2()\n",
        "  p1 = tf.constant(float('inf'))\n",
        "  try:\n",
        "    test_func2(p1)\n",
        "  except tf.errors.InvalidArgumentError as e:\n",
        "    traceback.print_exc(limit=2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nAsESNUB1QpI"
      },
      "source": [
        "디버그 스트리퍼 옵티마이저는 그래프에서 `tf.debug.check_numerics` 노드를 제거하고 오류를 발생시키지 않고 함수를 실행합니다. "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wHC6tR9GvFgW"
      },
      "source": [
        "## 요약\n",
        "\n",
        "TensorFlow 런타임은 Grappler를 사용하여 실행 전에 그래프를 자동으로 최적화합니다. `tf.config.optimizer.set_experimental_options`를 사용하여 다양한 그래프 옵티마이저를 활성화하거나 비활성화하세요.\n",
        "\n",
        "Grappler에 대한 자세한 정보는 <a class=\"external\" href=\"http://web.stanford.edu/class/cs245/slides/TFGraphOptimizationsStanford.pdf\">TensorFlow 그래프 최적화</a>를 참조하세요."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "name": "graph_optimization.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
{'fraction_non_alphanumeric': 0.15163981259284653, 'fraction_numerical': 0.007465813430845999, 'mean_word_length': 2.0803707614689664, 'pattern_counts': {'":': 268, '<': 51, '<?xml version=': 0, '>': 51, 'https://': 18, 'lorem ipsum': 0, 'www.': 12, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '657411', 'n_tokens_mistral': 10254, 'n_tokens_neox': 11221, 'n_words': 2119}