blob: b1552c40afef11e44f211fd46e800b86720d8c0d [file] [log] [blame]
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "vQTT2EYu4q_W"
},
"source": [
"##### Copyright 2020 Google LLC.\n",
"\n",
"Licensed under the Apache License, Version 2.0 (the \"License\");"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"colab": {},
"colab_type": "code",
"id": "BgQ7yyp84qDj"
},
"outputs": [],
"source": [
"#@title License header\n",
"# Copyright 2020 Google LLC\n",
"#\n",
"# 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": {
"colab_type": "text",
"id": "h5s6ncerSpc5"
},
"source": [
"# Defines a simple TF module, saves it and loads it in IREE.\n",
"\n",
"## Start kernel:\n",
"* [Install a TensorFlow2 nightly pip](https://www.tensorflow.org/install) (or bring your own)\n",
"* Enable IREE/TF integration by adding to your user.bazelrc: `build --define=iree_tensorflow=true`\n",
"* *Optional:* Prime the build: `bazel build bindings/python/pyiree`\n",
"* Start colab by running `python colab/start_colab_kernel.py` (see that file for initial setup instructions)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"colab": {},
"colab_type": "code",
"executionInfo": {
"elapsed": 6652,
"status": "ok",
"timestamp": 1598480165652,
"user": {
"displayName": "",
"photoUrl": "",
"userId": ""
},
"user_tz": 420
},
"id": "s2bScbYkP6VZ"
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"from pyiree.tf import compiler as ireec"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"colab": {},
"colab_type": "code",
"executionInfo": {
"elapsed": 623,
"status": "ok",
"timestamp": 1598480319071,
"user": {
"displayName": "",
"photoUrl": "",
"userId": ""
},
"user_tz": 420
},
"id": "6YGqN2uqP_7P"
},
"outputs": [],
"source": [
"class MyModule(tf.Module):\n",
"\n",
" def __init__(self):\n",
" self.v = tf.Variable([4], dtype=tf.float32)\n",
"\n",
" @tf.function(input_signature=[\n",
" tf.TensorSpec([4], tf.float32),\n",
" tf.TensorSpec([4], tf.float32)\n",
" ])\n",
" def add(self, a, b):\n",
" return tf.tanh(self.v * a + b)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"colab": {
"height": 326
},
"colab_type": "code",
"executionInfo": {
"elapsed": 954,
"status": "ok",
"timestamp": 1598480413200,
"user": {
"displayName": "",
"photoUrl": "",
"userId": ""
},
"user_tz": 420
},
"id": "r2H2BOpn2SpG",
"outputId": "9d6ad89a-d491-4dc4-f6b5-a26a8ef24fdb"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LOADED ASM: \n",
"\n",
"module attributes {tf.versions = {bad_consumers = [], min_consumer = 12 : i32, producer = 504 : i32}, tf_saved_model.semantics} {\n",
" \"tf_saved_model.global_tensor\"() {is_mutable, sym_name = \"__sm_node1__v\", tf_saved_model.exported_names = [\"v\"], type = tensor\u003c1xf32\u003e, value = dense\u003c4.000000e+00\u003e : tensor\u003c1xf32\u003e} : () -\u003e ()\n",
" func @__inference_add_160(%arg0: tensor\u003c4xf32\u003e {tf._user_specified_name = \"a\", tf_saved_model.index_path = [0]}, %arg1: tensor\u003c4xf32\u003e {tf._user_specified_name = \"b\", tf_saved_model.index_path = [1]}, %arg2: tensor\u003c!tf.resource\u003ctensor\u003c1xf32\u003e\u003e\u003e {tf_saved_model.bound_input = @__sm_node1__v}) -\u003e (tensor\u003c4xf32\u003e {tf_saved_model.index_path = []}) attributes {tf._input_shapes = [#tf.shape\u003c4\u003e, #tf.shape\u003c4\u003e, #tf.shape\u003c*\u003e], tf.signature.is_stateful, tf_saved_model.exported_names = [\"add\"]} {\n",
" %0 = \"tf.Cast\"(%arg2) {Truncate = false} : (tensor\u003c!tf.resource\u003ctensor\u003c1xf32\u003e\u003e\u003e) -\u003e tensor\u003c*x!tf.resource\u003e\n",
" %1 = tf_executor.graph {\n",
" %outputs, %control = tf_executor.island wraps \"tf.ReadVariableOp\"(%0) {device = \"\"} : (tensor\u003c*x!tf.resource\u003e) -\u003e tensor\u003c1xf32\u003e\n",
" %outputs_0, %control_1 = tf_executor.island wraps \"tf.Mul\"(%outputs, %arg0) {device = \"\"} : (tensor\u003c1xf32\u003e, tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %outputs_2, %control_3 = tf_executor.island wraps \"tf.AddV2\"(%outputs_0, %arg1) {device = \"\"} : (tensor\u003c4xf32\u003e, tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %outputs_4, %control_5 = tf_executor.island wraps \"tf.Tanh\"(%outputs_2) {device = \"\"} : (tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %outputs_6, %control_7 = tf_executor.island wraps \"tf.Identity\"(%outputs_4) {device = \"\"} : (tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" tf_executor.fetch %outputs_6 : tensor\u003c4xf32\u003e\n",
" }\n",
" return %1 : tensor\u003c4xf32\u003e\n",
" }\n",
"}\n"
]
}
],
"source": [
"#@title Compile to MLIR (mhlo).\n",
"compiler_module = ireec.tf_module_to_compiler_module(MyModule(),\n",
" pass_pipeline=())\n",
"print('LOADED ASM:', compiler_module.to_asm())"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"colab": {
"height": 258
},
"colab_type": "code",
"executionInfo": {
"elapsed": 82,
"status": "ok",
"timestamp": 1598480427027,
"user": {
"displayName": "",
"photoUrl": "",
"userId": ""
},
"user_tz": 420
},
"id": "S7IrzODx2RIF",
"outputId": "a96b729d-e64d-497e-bd0f-7c0e2fa31d4c"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LOWERED TF ASM: \n",
"\n",
"module attributes {tf.versions = {bad_consumers = [], min_consumer = 12 : i32, producer = 504 : i32}, tf_saved_model.semantics} {\n",
" \"tf_saved_model.global_tensor\"() {is_mutable, sym_name = \"__sm_node1__v\", tf_saved_model.exported_names = [\"v\"], type = tensor\u003c1xf32\u003e, value = dense\u003c4.000000e+00\u003e : tensor\u003c1xf32\u003e} : () -\u003e ()\n",
" func @__inference_add_160(%arg0: tensor\u003c4xf32\u003e {tf._user_specified_name = \"a\", tf_saved_model.index_path = [0]}, %arg1: tensor\u003c4xf32\u003e {tf._user_specified_name = \"b\", tf_saved_model.index_path = [1]}, %arg2: tensor\u003c!tf.resource\u003ctensor\u003c1xf32\u003e\u003e\u003e {tf_saved_model.bound_input = @__sm_node1__v}) -\u003e (tensor\u003c4xf32\u003e {tf_saved_model.index_path = []}) attributes {tf._input_shapes = [#tf.shape\u003c4\u003e, #tf.shape\u003c4\u003e, #tf.shape\u003c*\u003e], tf.signature.is_stateful, tf_saved_model.exported_names = [\"add\"]} {\n",
" %0 = \"tf.ReadVariableOp\"(%arg2) : (tensor\u003c!tf.resource\u003ctensor\u003c1xf32\u003e\u003e\u003e) -\u003e tensor\u003c1xf32\u003e\n",
" %1 = \"tf.Mul\"(%0, %arg0) {device = \"\"} : (tensor\u003c1xf32\u003e, tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %2 = \"tf.AddV2\"(%1, %arg1) {device = \"\"} : (tensor\u003c4xf32\u003e, tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %3 = \"tf.Tanh\"(%2) {device = \"\"} : (tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %4 = \"tf.Identity\"(%3) {device = \"\"} : (tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" return %4 : tensor\u003c4xf32\u003e\n",
" }\n",
"}\n"
]
}
],
"source": [
"#@title Canonicalize the TF import.\n",
"compiler_module.run_pass_pipeline([\n",
" \"tf-executor-graph-pruning\",\n",
" \"tf-standard-pipeline\",\n",
" \"canonicalize\",\n",
"])\n",
"print(\"LOWERED TF ASM:\", compiler_module.to_asm())"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"colab": {
"height": 445
},
"colab_type": "code",
"executionInfo": {
"elapsed": 47,
"status": "ok",
"timestamp": 1598480427942,
"user": {
"displayName": "",
"photoUrl": "",
"userId": ""
},
"user_tz": 420
},
"id": "BVmeZrRx2Uh9",
"outputId": "cfaa4c01-8f47-40ed-edbe-19f7cbf2c43c"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"XLA ASM: \n",
"\n",
"module attributes {tf.versions = {bad_consumers = [], min_consumer = 12 : i32, producer = 504 : i32}, tf_saved_model.semantics} {\n",
" \"tf_saved_model.global_tensor\"() {is_mutable, sym_name = \"__sm_node1__v\", tf_saved_model.exported_names = [\"v\"], type = tensor\u003c1xf32\u003e, value = dense\u003c4.000000e+00\u003e : tensor\u003c1xf32\u003e} : () -\u003e ()\n",
" func @__inference_add_160(%arg0: tensor\u003c4xf32\u003e {tf._user_specified_name = \"a\", tf_saved_model.index_path = [0]}, %arg1: tensor\u003c4xf32\u003e {tf._user_specified_name = \"b\", tf_saved_model.index_path = [1]}, %arg2: tensor\u003c!tf.resource\u003ctensor\u003c1xf32\u003e\u003e\u003e {tf_saved_model.bound_input = @__sm_node1__v}) -\u003e (tensor\u003c4xf32\u003e {tf_saved_model.index_path = []}) attributes {tf._input_shapes = [#tf.shape\u003c4\u003e, #tf.shape\u003c4\u003e, #tf.shape\u003c*\u003e], tf.signature.is_stateful, tf_saved_model.exported_names = [\"add\"]} {\n",
" %0 = \"tf.ReadVariableOp\"(%arg2) : (tensor\u003c!tf.resource\u003ctensor\u003c1xf32\u003e\u003e\u003e) -\u003e tensor\u003c1xf32\u003e\n",
" %1 = shape.shape_of %0 : tensor\u003c1xf32\u003e -\u003e tensor\u003c?xindex\u003e\n",
" %2 = shape.shape_of %arg0 : tensor\u003c4xf32\u003e -\u003e tensor\u003c?xindex\u003e\n",
" %3 = shape.cstr_broadcastable %1, %2 : tensor\u003c?xindex\u003e, tensor\u003c?xindex\u003e\n",
" %4 = shape.assuming %3 -\u003e (tensor\u003c4xf32\u003e) {\n",
" %7 = shape.const_shape [1] : tensor\u003c?xindex\u003e\n",
" %8 = shape.const_shape [4] : tensor\u003c?xindex\u003e\n",
" %9 = shape.const_shape [4] : tensor\u003c?xindex\u003e\n",
" %10 = tensor_cast %9 : tensor\u003c?xindex\u003e to tensor\u003c1xindex\u003e\n",
" %11 = \"mhlo.dynamic_broadcast_in_dim\"(%0, %10) {broadcast_dimensions = dense\u003c0\u003e : tensor\u003c1xi64\u003e} : (tensor\u003c1xf32\u003e, tensor\u003c1xindex\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %12 = \"mhlo.dynamic_broadcast_in_dim\"(%arg0, %10) {broadcast_dimensions = dense\u003c0\u003e : tensor\u003c1xi64\u003e} : (tensor\u003c4xf32\u003e, tensor\u003c1xindex\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" %13 = mhlo.multiply %11, %12 : tensor\u003c4xf32\u003e\n",
" shape.assuming_yield %13 : tensor\u003c4xf32\u003e\n",
" }\n",
" %5 = mhlo.add %4, %arg1 : tensor\u003c4xf32\u003e\n",
" %6 = \"mhlo.tanh\"(%5) : (tensor\u003c4xf32\u003e) -\u003e tensor\u003c4xf32\u003e\n",
" return %6 : tensor\u003c4xf32\u003e\n",
" }\n",
"}\n"
]
}
],
"source": [
"#@title Legalize to XLA (high-level).\n",
"compiler_module.run_pass_pipeline([\n",
" \"xla-legalize-tf{allow-partial-conversion=true}\",\n",
"])\n",
"print(\"XLA ASM:\", compiler_module.to_asm())"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"last_runtime": {
"build_target": "",
"kind": "local"
},
"name": "simple_tensorflow_module_import.ipynb",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}