Last active
March 22, 2023 11:50
-
-
Save maltempi/f2d30e513ef7046f3c0455a5dc4be3e0 to your computer and use it in GitHub Desktop.
[MO436] ResNet18 using JAX, Flax, Onnx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "U5ChPfvrX9XQ" | |
}, | |
"source": [ | |
"# Project 4: Inference using ResNet18, Flax, JAX and Onnx\n", | |
"\n", | |
"--- \n", | |
"\n", | |
"**MO436 - Machine Learning under the hood** - IC Unicamp\n", | |
"\n", | |
"Written by [Thiago Maltempi](https://github.com/maltempi)\n", | |
"\n", | |
"July 2022\n", | |
"\n", | |
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/gist/maltempi/f2d30e513ef7046f3c0455a5dc4be3e0)", | |
"\n", | |
"--- \n", | |
"\n", | |
"This notebook contains a implementation of ResNet18 in Flax and its parameters is loaded a Onnx file. After that, we fiddle with Jax's transformers (`vmap` and `jit`) get some performance analysis.\n", | |
"\n", | |
"At least one GPU is required to run this notebook. All data displayed in result cells were ran on Google Colab with GPU.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "GqeXojX0YQEZ" | |
}, | |
"source": [ | |
"## Installing and importing dependencies for this notebook" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"id": "BBQ9aX95X5tF" | |
}, | |
"outputs": [], | |
"source": [ | |
"!pip install jax flax onnx matplotlib numpy scipy requests opencv-python -q" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"id": "xIJwiPtDYWS9" | |
}, | |
"outputs": [], | |
"source": [ | |
"# Python's\n", | |
"import sys\n", | |
"import os\n", | |
"from os.path import exists\n", | |
"from datetime import datetime\n", | |
"\n", | |
"# Flax stuff\n", | |
"import flax.linen as nn\n", | |
"import optax\n", | |
"from flax.training.train_state import TrainState\n", | |
"from flax.core import freeze, unfreeze\n", | |
"from jax import vmap, pmap, jit, make_jaxpr, device_put\n", | |
"\n", | |
"# Jax stuff\n", | |
"import jax.numpy as jnp\n", | |
"import jax.scipy as jsp\n", | |
"import jax\n", | |
"\n", | |
"# Other dependencies\n", | |
"import numpy as np\n", | |
"import scipy as sp\n", | |
"import matplotlib.pyplot as plt\n", | |
"import requests\n", | |
"import onnx\n", | |
"from onnx import numpy_helper\n", | |
"import cv2" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "G-fustKcvn7t" | |
}, | |
"source": [ | |
"## Defining settings, downloading dataset, labels etc\n", | |
"\n", | |
"Nothing really important, just preparing the environment." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"id": "Tc1Xe8oRZqT0" | |
}, | |
"outputs": [], | |
"source": [ | |
"onnx_model_path = './resnet18.onnx'\n", | |
"onnx_url = 'https://raw.githubusercontent.com/maltempi/MO436-work/main/models/resnet18/resnet18.onnx'\n", | |
"dataset_url = 'https://raw.githubusercontent.com/maltempi/MO436-work/main/datasets/imagenet'\n", | |
"labels_url = 'https://raw.githubusercontent.com/maltempi/MO436-work/main/datasets/imagenet/synset_words.txt'\n", | |
"\n", | |
"INPUT_IMAGE_HEIGHT = 224\n", | |
"INPUT_IMAGE_WIDTH = 224\n", | |
"INPUT_IMAGE_CHANNELS = 3\n", | |
"FLAX_IMAGE_SHAPE = (224,224,3) # HWC\n", | |
"FLAX_INPUT_SHAPE = (1,224,224,3) # NHWC\n", | |
"\n", | |
"def download(url, path):\n", | |
" if not exists(path):\n", | |
" print('Downloading', url, 'in', path)\n", | |
" res = requests.get(url)\n", | |
" with open(path, 'wb') as file:\n", | |
" file.write(res.content)\n", | |
"\n", | |
"\n", | |
"def download_onnx_model():\n", | |
" download(onnx_url, onnx_model_path)\n", | |
"\n", | |
"\n", | |
"def download_dataset(repository_url=dataset_url):\n", | |
" import os \n", | |
" _dir = './imgs'\n", | |
" os.makedirs(_dir, exist_ok=True)\n", | |
"\n", | |
" for i in range(1000):\n", | |
" filename=f'''val_{str(i+1).rjust(8, '0')}.png'''\n", | |
" path = f'{_dir}/{filename}'\n", | |
" url = f'''{repository_url}/{filename}'''\n", | |
" download(url, path)\n", | |
"\n", | |
"\n", | |
"def get_labels(url=labels_url, path='./labels.txt'):\n", | |
" download(labels_url, path)\n", | |
" with open(path, 'r') as f:\n", | |
" return [int(l.rstrip()) for l in f]\n", | |
"\n", | |
"download(f'{dataset_url}/val_00000097.png', './rabbit.png') # 188\n", | |
"download(f'{dataset_url}/val_00000211.png', './cat.png') # 95\n", | |
"download(f'{dataset_url}/val_00000217.png', './bird.png') # 392\n", | |
"\n", | |
"RABBIT_LABEL = '188'\n", | |
"CAT_LABEL = '95'\n", | |
"BIRD_LABEL = '392'\n", | |
"\n", | |
"download_dataset()\n", | |
"download_onnx_model()\n", | |
"labels = jnp.array(get_labels())\n", | |
"\n", | |
"def plot_speedup(t, baseline='numpy'):\n", | |
" '''\n", | |
" Compute speedup between two approaches.\n", | |
" Original code from: https://github.com/MO436-MC934/notebooks/blob/7b99a7676c58b38dd428a95bc73acc07b1282838/05-JAX/util/speedup.py\n", | |
" '''\n", | |
" def avg(lst):\n", | |
" return sum(lst) / len(lst)\n", | |
"\n", | |
" # Prepare data\n", | |
" base = avg(t[baseline].all_runs)\n", | |
" name = t.keys()\n", | |
" time = [base / avg(v.all_runs) for v in t.values()]\n", | |
" # Plot speedups as bar graph\n", | |
" plt.bar(name, time, width=0.8)\n", | |
" plt.ylabel(\"Speedup\")\n", | |
" # Write speedup on top of bars\n", | |
" for (i, n), t in zip(enumerate(name), time):\n", | |
" plt.text(i, t, f\"{t:.2f}x\", horizontalalignment='center', fontweight='bold')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "AFqqViGnYyEY" | |
}, | |
"source": [ | |
"## Implementing Resnet18 using Flax\n", | |
"\n", | |
"For the implementation of Resnet18, I opened the `onnx_model_path` into [NetronApp](https://netron.app) and followed the graph, node by node. Notice I added `name` parameter for every layer using same as in Onnx file, this will be useful for matching parameters' names.\n", | |
"\n", | |
"\n", | |
"### References for this section:\n", | |
"- [1] https://flax.readthedocs.io/en/latest/_autosummary/flax.linen.Conv.html\n", | |
"- [2] https://flax.readthedocs.io/en/latest/_autosummary/flax.linen.BatchNorm.html\n", | |
"- [3] https://flax.readthedocs.io/en/latest/_autosummary/flax.linen.relu.html\n", | |
"- [4] https://flax.readthedocs.io/en/latest/_autosummary/flax.linen.max_pool.html\n", | |
"- [5] https://github.com/KaimingHe/deep-residual-networks/issues/10#issuecomment-194037195\n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"id": "9lT0K0h5YwYW" | |
}, | |
"outputs": [], | |
"source": [ | |
"class ResNet18(nn.Module): \n", | |
" @nn.compact\n", | |
" def __call__(self, x):\n", | |
" momentum = 0.8999999761581421\n", | |
" epsilon = 0.000009999999747378752\n", | |
"\n", | |
" # why use_bias=false? See: [5]\n", | |
" use_bias = False\n", | |
"\n", | |
" x = nn.Conv(features=64, kernel_size=(7, 7), padding=(3,3), strides=2, use_bias=use_bias, name='resnetv15_conv0')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_batchnorm0')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.max_pool(x, window_shape=(3, 3), strides=(2, 2), padding=((1,1),(1,1)))\n", | |
"\n", | |
" # Stage 1\n", | |
" res = x\n", | |
" x = nn.Conv(features=64, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage1_conv0')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage1_batchnorm0')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=64, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage1_conv1')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage1_batchnorm1')(x)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
" res = x\n", | |
" x = nn.Conv(features=64, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage1_conv2')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage1_batchnorm2')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=64, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage1_conv3')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage1_batchnorm3')(x)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
"\n", | |
" # Stage 2\n", | |
" res = x\n", | |
" x = nn.Conv(features=128, kernel_size=(3, 3), padding=(1,1), strides=2, use_bias=use_bias, name='resnetv15_stage2_conv0')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage2_batchnorm0')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=128, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage2_conv1')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage2_batchnorm1')(x)\n", | |
" res = nn.Conv(features=128, kernel_size=(1, 1), padding=(0,0), strides=2, use_bias=use_bias, name='resnetv15_stage2_conv2')(res)\n", | |
" res = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage2_batchnorm2')(res)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
" res = x\n", | |
" x = nn.Conv(features=128, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage2_conv3')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage2_batchnorm3')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=128, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage2_conv4')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage2_batchnorm4')(x)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
" # Stage 3\n", | |
" res = x\n", | |
" x = nn.Conv(features=256, kernel_size=(3, 3), padding=(1,1), strides=2, use_bias=use_bias, name='resnetv15_stage3_conv0')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage3_batchnorm0')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=256, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage3_conv1')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage3_batchnorm1')(x)\n", | |
" res = nn.Conv(features=256, kernel_size=(1, 1), padding=(0,0), strides=2, use_bias=use_bias, name='resnetv15_stage3_conv2')(res)\n", | |
" res = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage3_batchnorm2')(res)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
" res = x\n", | |
" x = nn.Conv(features=256, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage3_conv3')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage3_batchnorm3')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=256, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage3_conv4')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage3_batchnorm4')(x)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
"\n", | |
" # Stage 4\n", | |
" res = x\n", | |
" x = nn.Conv(features=512, kernel_size=(3, 3), padding=(1,1), strides=2, use_bias=use_bias, name='resnetv15_stage4_conv0')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage4_batchnorm0')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=512, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage4_conv1')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage4_batchnorm1')(x)\n", | |
" res = nn.Conv(features=512, kernel_size=(1, 1), padding=(0,0), strides=2, use_bias=use_bias, name='resnetv15_stage4_conv2')(res)\n", | |
" res = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage4_batchnorm2')(res)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
" res = x\n", | |
" x = nn.Conv(features=512, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage4_conv3')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage4_batchnorm3')(x)\n", | |
" x = nn.relu(x)\n", | |
" x = nn.Conv(features=512, kernel_size=(3, 3), padding=(1,1), strides=1, use_bias=use_bias, name='resnetv15_stage4_conv4')(x)\n", | |
" x = nn.BatchNorm(use_running_average=True, momentum=momentum, epsilon=epsilon, dtype=jnp.float32, name='resnetv15_stage4_batchnorm4')(x)\n", | |
" x = nn.relu(x + res)\n", | |
"\n", | |
" # Global AVG pool\n", | |
" x = jnp.mean(x, axis=(1, 2))\n", | |
"\n", | |
" # Flatten\n", | |
" num_of_classes = 1000 # TODO: get this value from constructor or args\n", | |
" x = nn.Dense(num_of_classes, dtype=jnp.float32, name='resnetv15_dense0')(x)\n", | |
"\n", | |
" x = jnp.asarray(x, jnp.float32)\n", | |
"\n", | |
" return x" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "jwmAKMEKZl51" | |
}, | |
"source": [ | |
"# Taking a look in the model\n", | |
"Let's check what we have in the model. First, it is initializing the model and then we can take a look on `params`and `batch_stats`. Those dictionaries we need to fill with params broght from Onnx file.\n", | |
"\n", | |
"Notice in the below cell result we can see the tensor shapes expected by Flax. This will be useful on loading from Onnx." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "_isXLbsFZlSB", | |
"outputId": "de057b86-e16c-4955-83d3-a91727b83b5e" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Some examples of params:\n", | |
"resnetv15_conv0 \n", | |
" FrozenDict({\n", | |
" kernel: (7, 7, 3, 64),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_batchnorm0 \n", | |
" FrozenDict({\n", | |
" bias: (64,),\n", | |
" scale: (64,),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_stage1_conv0 \n", | |
" FrozenDict({\n", | |
" kernel: (3, 3, 64, 64),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_stage1_batchnorm0 \n", | |
" FrozenDict({\n", | |
" bias: (64,),\n", | |
" scale: (64,),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_dense0 \n", | |
" FrozenDict({\n", | |
" bias: (1000,),\n", | |
" kernel: (512, 1000),\n", | |
"}) \n", | |
"\n", | |
"Some examples of batch_stats:\n", | |
"resnetv15_batchnorm0 \n", | |
" FrozenDict({\n", | |
" mean: (64,),\n", | |
" var: (64,),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_stage1_batchnorm0 \n", | |
" FrozenDict({\n", | |
" mean: (64,),\n", | |
" var: (64,),\n", | |
"}) \n", | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"cnn = ResNet18()\n", | |
"rng = jax.random.PRNGKey(0)\n", | |
"rng, init_rng = jax.random.split(rng)\n", | |
"init = cnn.init(rng, jnp.ones(FLAX_INPUT_SHAPE))\n", | |
"\n", | |
"def print_param(dic, name):\n", | |
" print(name, '\\n', jax.tree_map(lambda x: x.shape, dic[name]), '\\n')\n", | |
"\n", | |
"# Uncomment this to check all params\n", | |
"#print(jax.tree_map(lambda x: x.shape, init['params']))\n", | |
"\n", | |
"print('Some examples of params:')\n", | |
"print_param(init['params'], 'resnetv15_conv0')\n", | |
"print_param(init['params'], 'resnetv15_batchnorm0')\n", | |
"print_param(init['params'], 'resnetv15_stage1_conv0')\n", | |
"print_param(init['params'], 'resnetv15_stage1_batchnorm0')\n", | |
"print_param(init['params'], 'resnetv15_dense0')\n", | |
"\n", | |
"print('Some examples of batch_stats:')\n", | |
"print_param(init['batch_stats'],'resnetv15_batchnorm0')\n", | |
"print_param(init['batch_stats'],'resnetv15_stage1_batchnorm0')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "VQ78Lg0AfNwP" | |
}, | |
"source": [ | |
"# Loading parameters from ONNX\n", | |
"With `onnx` library we can open the Onnx file and iterate through its graph. I'm parsing the names and matching with that names I added for every layer on Flax module definition.\n", | |
"\n", | |
"The trick here is pay attention on the tensor shapes used in Onnx file and what Flax actually expects. Convolutional layers from Onnx is using NCHW while Flax's expects NHWC. Also, for Fully Connected layers, Onnx brings in [outC, inC] while Flaxs uses [inC, outC]. We need to transpose it on the fly before push it to our params dictionary.\n", | |
"\n", | |
"Notice that some parameters names are different in Onnx and Flax, for example, `beta` in onnx is called `bias` in Flax.\n", | |
"\n", | |
"## References for this section:\n", | |
"- [1] https://flax.readthedocs.io/en/latest/howtos/convert_pytorch_to_flax.html" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"id": "FrsExnKhfMUp" | |
}, | |
"outputs": [], | |
"source": [ | |
"model = onnx.load(onnx_model_path)\n", | |
"params = {}\n", | |
"batch_stats = {}\n", | |
"\n", | |
"def initialize(d, key):\n", | |
" if not key in d.keys():\n", | |
" d[key] = {}\n", | |
" \n", | |
"for initializer in model.graph.initializer:\n", | |
" # Debug only\n", | |
" #print(f'- Tensor: {initializer.name!r:45} shape={initializer.dims}')\n", | |
"\n", | |
" if 'stage' in initializer.name:\n", | |
" key = '_'.join(initializer.name.split('_')[:3])\n", | |
" else:\n", | |
" key = '_'.join(initializer.name.split('_')[:2])\n", | |
"\n", | |
" # Debug only\n", | |
" #print('Loading', initializer.name, 'into', key)\n", | |
"\n", | |
" if '_mean' in initializer.name:\n", | |
" # BatchNorm uses _mean suffix (batch_stats)\n", | |
" initialize(batch_stats, key)\n", | |
" batch_stats[key]['mean'] = numpy_helper.to_array(initializer)\n", | |
"\n", | |
" elif '_var' in initializer.name:\n", | |
" # BatchNorm uses _var suffix (batch_stats)\n", | |
" initialize(batch_stats, key)\n", | |
" batch_stats[key]['var'] = numpy_helper.to_array(initializer)\n", | |
"\n", | |
" elif '_beta' in initializer.name:\n", | |
" # Batchnorm uses '_beta' suffix\n", | |
" initialize(params, key)\n", | |
" params[key]['bias'] = numpy_helper.to_array(initializer)\n", | |
" elif '_gamma' in initializer.name:\n", | |
" # Batchnorm uses _gamma suffix (batch_stats)\n", | |
" initialize(params, key)\n", | |
" params[key]['scale'] = numpy_helper.to_array(initializer)\n", | |
"\n", | |
" elif '_weight' in initializer.name:\n", | |
" # Conv uses _weight layer\n", | |
" initialize(params, key)\n", | |
"\n", | |
" weights = numpy_helper.to_array(initializer)\n", | |
"\n", | |
" if len(weights.shape) == 2:\n", | |
" weights = np.transpose(weights, (1, 0))\n", | |
" params[key]['kernel'] = weights\n", | |
" elif len(weights.shape) == 4:\n", | |
" weights = np.transpose(weights, (2, 3, 1, 0))\n", | |
" params[key]['kernel'] = weights\n", | |
" else:\n", | |
" print('WARNING: This should not happen...')\n", | |
"\n", | |
" elif '_bias' in initializer.name:\n", | |
" # Dense layer uses _bias suffix\n", | |
" initialize(params, key)\n", | |
" params[key]['bias'] = numpy_helper.to_array(initializer)\n", | |
" else:\n", | |
" print('WARNING: I dont know what I should do with this:', key, initializer.name)\n", | |
"\n", | |
"params = freeze(params)\n", | |
"batch_stats = freeze(batch_stats)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "rnPwahUmvPer" | |
}, | |
"source": [ | |
"Let's check if params and batch_stats looks like we got in the initialization above." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "Yn5TV9rDjT74", | |
"outputId": "d0b55f1c-9f12-4bf7-843f-1c934b9cf120" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Some examples of params:\n", | |
"resnetv15_conv0 \n", | |
" FrozenDict({\n", | |
" kernel: (7, 7, 3, 64),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_batchnorm0 \n", | |
" FrozenDict({\n", | |
" bias: (64,),\n", | |
" scale: (64,),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_stage1_conv0 \n", | |
" FrozenDict({\n", | |
" kernel: (3, 3, 64, 64),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_stage1_batchnorm0 \n", | |
" FrozenDict({\n", | |
" bias: (64,),\n", | |
" scale: (64,),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_dense0 \n", | |
" FrozenDict({\n", | |
" bias: (1000,),\n", | |
" kernel: (512, 1000),\n", | |
"}) \n", | |
"\n", | |
"Some examples of batch_stats:\n", | |
"resnetv15_batchnorm0 \n", | |
" FrozenDict({\n", | |
" mean: (64,),\n", | |
" var: (64,),\n", | |
"}) \n", | |
"\n", | |
"resnetv15_stage1_batchnorm0 \n", | |
" FrozenDict({\n", | |
" mean: (64,),\n", | |
" var: (64,),\n", | |
"}) \n", | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"print('Some examples of params:')\n", | |
"print_param(params, 'resnetv15_conv0')\n", | |
"print_param(params, 'resnetv15_batchnorm0')\n", | |
"print_param(params, 'resnetv15_stage1_conv0')\n", | |
"print_param(params, 'resnetv15_stage1_batchnorm0')\n", | |
"print_param(params, 'resnetv15_dense0')\n", | |
"\n", | |
"print('Some examples of batch_stats:')\n", | |
"print_param(batch_stats,'resnetv15_batchnorm0')\n", | |
"print_param(batch_stats,'resnetv15_stage1_batchnorm0')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "wZ8s9rc4wzVU" | |
}, | |
"source": [ | |
"# Pre-processing images\n", | |
"\n", | |
"Here I'm defining a function that opens an image, resizes to the right input dimension, and make some color adjustments, following [1].\n", | |
"\n", | |
"\n", | |
"## References for this section\n", | |
"- [1] https://github.com/MO436-MC934/work/blob/bb5ef4e747011d5d045b7373e35492b836aae27e/models/resnet18/main.cpp#L62 \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"id": "4I0XYsw6ndIv" | |
}, | |
"outputs": [], | |
"source": [ | |
"def get_image(path, show=False):\n", | |
" img = cv2.imread(path)\n", | |
"\n", | |
" img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n", | |
" img = cv2.resize(img, (INPUT_IMAGE_HEIGHT, INPUT_IMAGE_WIDTH))\n", | |
" \n", | |
" if show:\n", | |
" plt.imshow(img)\n", | |
" plt.show()\n", | |
"\n", | |
" mean=[0.485, 0.456, 0.406]\n", | |
" std=[0.229, 0.224, 0.225]\n", | |
"\n", | |
" img = img/255.0\n", | |
" img[:,:,0] = (img[:,:,0] - mean[0]) / std[0]\n", | |
" img[:,:,1] = (img[:,:,1] - mean[1]) / std[1]\n", | |
" img[:,:,2] = (img[:,:,2] - mean[2]) / std[2]\n", | |
"\n", | |
" return img" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "NS9MkTl_wifT" | |
}, | |
"source": [ | |
"# Testing inference...\n", | |
"\n", | |
"Just running a very basic inference and checking if the result is correct." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 286 | |
}, | |
"id": "C0HyBNeVniKh", | |
"outputId": "001ddb65-59da-4806-f196-b7a82ab00b8f" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
], | |
"image/png": "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\n" | |
}, | |
"metadata": { | |
"needs_background": "light" | |
} | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Correct value: 188; Predicted value: 188\n" | |
] | |
} | |
], | |
"source": [ | |
"def get_top1(activations):\n", | |
" '''\n", | |
" Get predicted labels... We don't care about performance here\n", | |
" '''\n", | |
" preds = []\n", | |
"\n", | |
" for activation in activations:\n", | |
" pred = jnp.argmax(activation)\n", | |
" preds.append(labels[pred])\n", | |
"\n", | |
" return preds\n", | |
"\n", | |
"def predict(input, params, batch_stats):\n", | |
" return ResNet18().apply({'params': params, 'batch_stats': batch_stats}, input)\n", | |
"\n", | |
"\n", | |
"def predict_single(image):\n", | |
" input = jnp.expand_dims(image, axis=0)\n", | |
" return ResNet18().apply({'params': params, 'batch_stats': batch_stats}, input)\n", | |
"\n", | |
"rabbit = get_image('./rabbit.png', show=True)\n", | |
"rabbit_pred_label = get_top1(predict_single(rabbit))[0]\n", | |
"print('Correct value: 188; Predicted value:', rabbit_pred_label)\n", | |
"assert 188 == rabbit_pred_label" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "BwYG04avTjn7" | |
}, | |
"source": [ | |
"# Performance time!\n", | |
"\n", | |
"The goal here will be predict 1000 images at once in Flax. So input shape will be `1000x224x224x3`. \n", | |
"\n", | |
"Jax runs our code in GPU in a very transparent way, so the first step will clearly define what is running on GPU and what is running on CPU.\n", | |
"\n", | |
"## References for this section:\n", | |
"- [1] https://jax.readthedocs.io/en/latest/notebooks/quickstart.html?highlight=vmap#jax-quickstart" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"predict_cpu = jit(predict, backend='cpu')\n", | |
"make_jaxpr(predict_cpu)(jnp.ones((1000, 224,224,3)), params, batch_stats)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "97NYg1jZhytz", | |
"outputId": "bc214383-cdde-4c83-9cd6-0ac2d11b98be" | |
}, | |
"execution_count": 10, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"{ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; a\u001b[35m:f32[1000,224,224,3]\u001b[39m b\u001b[35m:f32[64]\u001b[39m c\u001b[35m:f32[64]\u001b[39m d\u001b[35m:f32[7,7,3,64]\u001b[39m e\u001b[35m:f32[1000]\u001b[39m\n", | |
" f\u001b[35m:f32[512,1000]\u001b[39m g\u001b[35m:f32[64]\u001b[39m h\u001b[35m:f32[64]\u001b[39m i\u001b[35m:f32[64]\u001b[39m j\u001b[35m:f32[64]\u001b[39m k\u001b[35m:f32[64]\u001b[39m l\u001b[35m:f32[64]\u001b[39m m\u001b[35m:f32[64]\u001b[39m\n", | |
" n\u001b[35m:f32[64]\u001b[39m o\u001b[35m:f32[3,3,64,64]\u001b[39m p\u001b[35m:f32[3,3,64,64]\u001b[39m q\u001b[35m:f32[3,3,64,64]\u001b[39m r\u001b[35m:f32[3,3,64,64]\u001b[39m\n", | |
" s\u001b[35m:f32[128]\u001b[39m t\u001b[35m:f32[128]\u001b[39m u\u001b[35m:f32[128]\u001b[39m v\u001b[35m:f32[128]\u001b[39m w\u001b[35m:f32[128]\u001b[39m x\u001b[35m:f32[128]\u001b[39m y\u001b[35m:f32[128]\u001b[39m\n", | |
" z\u001b[35m:f32[128]\u001b[39m ba\u001b[35m:f32[128]\u001b[39m bb\u001b[35m:f32[128]\u001b[39m bc\u001b[35m:f32[3,3,64,128]\u001b[39m bd\u001b[35m:f32[3,3,128,128]\u001b[39m be\u001b[35m:f32[1,1,64,128]\u001b[39m\n", | |
" bf\u001b[35m:f32[3,3,128,128]\u001b[39m bg\u001b[35m:f32[3,3,128,128]\u001b[39m bh\u001b[35m:f32[256]\u001b[39m bi\u001b[35m:f32[256]\u001b[39m bj\u001b[35m:f32[256]\u001b[39m bk\u001b[35m:f32[256]\u001b[39m\n", | |
" bl\u001b[35m:f32[256]\u001b[39m bm\u001b[35m:f32[256]\u001b[39m bn\u001b[35m:f32[256]\u001b[39m bo\u001b[35m:f32[256]\u001b[39m bp\u001b[35m:f32[256]\u001b[39m bq\u001b[35m:f32[256]\u001b[39m br\u001b[35m:f32[3,3,128,256]\u001b[39m\n", | |
" bs\u001b[35m:f32[3,3,256,256]\u001b[39m bt\u001b[35m:f32[1,1,128,256]\u001b[39m bu\u001b[35m:f32[3,3,256,256]\u001b[39m bv\u001b[35m:f32[3,3,256,256]\u001b[39m\n", | |
" bw\u001b[35m:f32[512]\u001b[39m bx\u001b[35m:f32[512]\u001b[39m by\u001b[35m:f32[512]\u001b[39m bz\u001b[35m:f32[512]\u001b[39m ca\u001b[35m:f32[512]\u001b[39m cb\u001b[35m:f32[512]\u001b[39m cc\u001b[35m:f32[512]\u001b[39m\n", | |
" cd\u001b[35m:f32[512]\u001b[39m ce\u001b[35m:f32[512]\u001b[39m cf\u001b[35m:f32[512]\u001b[39m cg\u001b[35m:f32[3,3,256,512]\u001b[39m ch\u001b[35m:f32[3,3,512,512]\u001b[39m ci\u001b[35m:f32[1,1,256,512]\u001b[39m\n", | |
" cj\u001b[35m:f32[3,3,512,512]\u001b[39m ck\u001b[35m:f32[3,3,512,512]\u001b[39m cl\u001b[35m:f32[64]\u001b[39m cm\u001b[35m:f32[64]\u001b[39m cn\u001b[35m:f32[64]\u001b[39m co\u001b[35m:f32[64]\u001b[39m\n", | |
" cp\u001b[35m:f32[64]\u001b[39m cq\u001b[35m:f32[64]\u001b[39m cr\u001b[35m:f32[64]\u001b[39m cs\u001b[35m:f32[64]\u001b[39m ct\u001b[35m:f32[64]\u001b[39m cu\u001b[35m:f32[64]\u001b[39m cv\u001b[35m:f32[128]\u001b[39m\n", | |
" cw\u001b[35m:f32[128]\u001b[39m cx\u001b[35m:f32[128]\u001b[39m cy\u001b[35m:f32[128]\u001b[39m cz\u001b[35m:f32[128]\u001b[39m da\u001b[35m:f32[128]\u001b[39m db\u001b[35m:f32[128]\u001b[39m dc\u001b[35m:f32[128]\u001b[39m\n", | |
" dd\u001b[35m:f32[128]\u001b[39m de\u001b[35m:f32[128]\u001b[39m df\u001b[35m:f32[256]\u001b[39m dg\u001b[35m:f32[256]\u001b[39m dh\u001b[35m:f32[256]\u001b[39m di\u001b[35m:f32[256]\u001b[39m dj\u001b[35m:f32[256]\u001b[39m\n", | |
" dk\u001b[35m:f32[256]\u001b[39m dl\u001b[35m:f32[256]\u001b[39m dm\u001b[35m:f32[256]\u001b[39m dn\u001b[35m:f32[256]\u001b[39m do\u001b[35m:f32[256]\u001b[39m dp\u001b[35m:f32[512]\u001b[39m dq\u001b[35m:f32[512]\u001b[39m\n", | |
" dr\u001b[35m:f32[512]\u001b[39m ds\u001b[35m:f32[512]\u001b[39m dt\u001b[35m:f32[512]\u001b[39m du\u001b[35m:f32[512]\u001b[39m dv\u001b[35m:f32[512]\u001b[39m dw\u001b[35m:f32[512]\u001b[39m dx\u001b[35m:f32[512]\u001b[39m\n", | |
" dy\u001b[35m:f32[512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mdz\u001b[35m:f32[1000,1000]\u001b[39m = xla_call[\n", | |
" backend=cpu\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ea\u001b[35m:f32[1000,224,224,3]\u001b[39m eb\u001b[35m:f32[64]\u001b[39m ec\u001b[35m:f32[64]\u001b[39m ed\u001b[35m:f32[7,7,3,64]\u001b[39m\n", | |
" ee\u001b[35m:f32[1000]\u001b[39m ef\u001b[35m:f32[512,1000]\u001b[39m eg\u001b[35m:f32[64]\u001b[39m eh\u001b[35m:f32[64]\u001b[39m ei\u001b[35m:f32[64]\u001b[39m ej\u001b[35m:f32[64]\u001b[39m\n", | |
" ek\u001b[35m:f32[64]\u001b[39m el\u001b[35m:f32[64]\u001b[39m em\u001b[35m:f32[64]\u001b[39m en\u001b[35m:f32[64]\u001b[39m eo\u001b[35m:f32[3,3,64,64]\u001b[39m ep\u001b[35m:f32[3,3,64,64]\u001b[39m\n", | |
" eq\u001b[35m:f32[3,3,64,64]\u001b[39m er\u001b[35m:f32[3,3,64,64]\u001b[39m es\u001b[35m:f32[128]\u001b[39m et\u001b[35m:f32[128]\u001b[39m eu\u001b[35m:f32[128]\u001b[39m\n", | |
" ev\u001b[35m:f32[128]\u001b[39m ew\u001b[35m:f32[128]\u001b[39m ex\u001b[35m:f32[128]\u001b[39m ey\u001b[35m:f32[128]\u001b[39m ez\u001b[35m:f32[128]\u001b[39m fa\u001b[35m:f32[128]\u001b[39m\n", | |
" fb\u001b[35m:f32[128]\u001b[39m fc\u001b[35m:f32[3,3,64,128]\u001b[39m fd\u001b[35m:f32[3,3,128,128]\u001b[39m fe\u001b[35m:f32[1,1,64,128]\u001b[39m ff\u001b[35m:f32[3,3,128,128]\u001b[39m\n", | |
" fg\u001b[35m:f32[3,3,128,128]\u001b[39m fh\u001b[35m:f32[256]\u001b[39m fi\u001b[35m:f32[256]\u001b[39m fj\u001b[35m:f32[256]\u001b[39m fk\u001b[35m:f32[256]\u001b[39m fl\u001b[35m:f32[256]\u001b[39m\n", | |
" fm\u001b[35m:f32[256]\u001b[39m fn\u001b[35m:f32[256]\u001b[39m fo\u001b[35m:f32[256]\u001b[39m fp\u001b[35m:f32[256]\u001b[39m fq\u001b[35m:f32[256]\u001b[39m fr\u001b[35m:f32[3,3,128,256]\u001b[39m\n", | |
" fs\u001b[35m:f32[3,3,256,256]\u001b[39m ft\u001b[35m:f32[1,1,128,256]\u001b[39m fu\u001b[35m:f32[3,3,256,256]\u001b[39m fv\u001b[35m:f32[3,3,256,256]\u001b[39m\n", | |
" fw\u001b[35m:f32[512]\u001b[39m fx\u001b[35m:f32[512]\u001b[39m fy\u001b[35m:f32[512]\u001b[39m fz\u001b[35m:f32[512]\u001b[39m ga\u001b[35m:f32[512]\u001b[39m gb\u001b[35m:f32[512]\u001b[39m\n", | |
" gc\u001b[35m:f32[512]\u001b[39m gd\u001b[35m:f32[512]\u001b[39m ge\u001b[35m:f32[512]\u001b[39m gf\u001b[35m:f32[512]\u001b[39m gg\u001b[35m:f32[3,3,256,512]\u001b[39m gh\u001b[35m:f32[3,3,512,512]\u001b[39m\n", | |
" gi\u001b[35m:f32[1,1,256,512]\u001b[39m gj\u001b[35m:f32[3,3,512,512]\u001b[39m gk\u001b[35m:f32[3,3,512,512]\u001b[39m gl\u001b[35m:f32[64]\u001b[39m\n", | |
" gm\u001b[35m:f32[64]\u001b[39m gn\u001b[35m:f32[64]\u001b[39m go\u001b[35m:f32[64]\u001b[39m gp\u001b[35m:f32[64]\u001b[39m gq\u001b[35m:f32[64]\u001b[39m gr\u001b[35m:f32[64]\u001b[39m gs\u001b[35m:f32[64]\u001b[39m\n", | |
" gt\u001b[35m:f32[64]\u001b[39m gu\u001b[35m:f32[64]\u001b[39m gv\u001b[35m:f32[128]\u001b[39m gw\u001b[35m:f32[128]\u001b[39m gx\u001b[35m:f32[128]\u001b[39m gy\u001b[35m:f32[128]\u001b[39m gz\u001b[35m:f32[128]\u001b[39m\n", | |
" ha\u001b[35m:f32[128]\u001b[39m hb\u001b[35m:f32[128]\u001b[39m hc\u001b[35m:f32[128]\u001b[39m hd\u001b[35m:f32[128]\u001b[39m he\u001b[35m:f32[128]\u001b[39m hf\u001b[35m:f32[256]\u001b[39m\n", | |
" hg\u001b[35m:f32[256]\u001b[39m hh\u001b[35m:f32[256]\u001b[39m hi\u001b[35m:f32[256]\u001b[39m hj\u001b[35m:f32[256]\u001b[39m hk\u001b[35m:f32[256]\u001b[39m hl\u001b[35m:f32[256]\u001b[39m\n", | |
" hm\u001b[35m:f32[256]\u001b[39m hn\u001b[35m:f32[256]\u001b[39m ho\u001b[35m:f32[256]\u001b[39m hp\u001b[35m:f32[512]\u001b[39m hq\u001b[35m:f32[512]\u001b[39m hr\u001b[35m:f32[512]\u001b[39m\n", | |
" hs\u001b[35m:f32[512]\u001b[39m ht\u001b[35m:f32[512]\u001b[39m hu\u001b[35m:f32[512]\u001b[39m hv\u001b[35m:f32[512]\u001b[39m hw\u001b[35m:f32[512]\u001b[39m hx\u001b[35m:f32[512]\u001b[39m\n", | |
" hy\u001b[35m:f32[512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mhz\u001b[35m:f32[1000,112,112,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 224, 224, 3)\n", | |
" padding=((3, 3), (3, 3))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(7, 7, 3, 64)\n", | |
" window_strides=(2, 2)\n", | |
" ] ea ed\n", | |
" ia\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gl\n", | |
" ib\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gm\n", | |
" ic\u001b[35m:f32[1000,112,112,64]\u001b[39m = sub hz ia\n", | |
" id\u001b[35m:f32[1,1,1,64]\u001b[39m = add ib 9.999999747378752e-06\n", | |
" ie\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt id\n", | |
" if\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ec\n", | |
" ig\u001b[35m:f32[1,1,1,64]\u001b[39m = mul ie if\n", | |
" ih\u001b[35m:f32[1000,112,112,64]\u001b[39m = mul ic ig\n", | |
" ii\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] eb\n", | |
" ij\u001b[35m:f32[1000,112,112,64]\u001b[39m = add ih ii\n", | |
" ik\u001b[35m:f32[1000,112,112,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; il\u001b[35m:f32[1000,112,112,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mim\u001b[35m:f32[1000,112,112,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; in\u001b[35m:f32[1000,112,112,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mio\u001b[35m:f32[1000,112,112,64]\u001b[39m = max in 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(io,) }\n", | |
" name=relu\n", | |
" ] il\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(im,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10fa70>\n", | |
" num_consts=0\n", | |
" ] ij\n", | |
" ip\u001b[35m:f32[1000,56,56,64]\u001b[39m = reduce_window_max[\n", | |
" base_dilation=(1, 1, 1, 1)\n", | |
" padding=((0, 0), (1, 1), (1, 1), (0, 0))\n", | |
" window_dilation=(1, 1, 1, 1)\n", | |
" window_dimensions=(1, 3, 3, 1)\n", | |
" window_strides=(1, 2, 2, 1)\n", | |
" ] ik\n", | |
" iq\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] ip eo\n", | |
" ir\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gn\n", | |
" is\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] go\n", | |
" it\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub iq ir\n", | |
" iu\u001b[35m:f32[1,1,1,64]\u001b[39m = add is 9.999999747378752e-06\n", | |
" iv\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt iu\n", | |
" iw\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] eh\n", | |
" ix\u001b[35m:f32[1,1,1,64]\u001b[39m = mul iv iw\n", | |
" iy\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul it ix\n", | |
" iz\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] eg\n", | |
" ja\u001b[35m:f32[1000,56,56,64]\u001b[39m = add iy iz\n", | |
" jb\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jc\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjd\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; je\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjf\u001b[35m:f32[1000,56,56,64]\u001b[39m = max je 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jf,) }\n", | |
" name=relu\n", | |
" ] jc\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jd,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10f440>\n", | |
" num_consts=0\n", | |
" ] ja\n", | |
" jg\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] jb ep\n", | |
" jh\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gp\n", | |
" ji\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gq\n", | |
" jj\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub jg jh\n", | |
" jk\u001b[35m:f32[1,1,1,64]\u001b[39m = add ji 9.999999747378752e-06\n", | |
" jl\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt jk\n", | |
" jm\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ej\n", | |
" jn\u001b[35m:f32[1,1,1,64]\u001b[39m = mul jl jm\n", | |
" jo\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul jj jn\n", | |
" jp\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ei\n", | |
" jq\u001b[35m:f32[1000,56,56,64]\u001b[39m = add jo jp\n", | |
" jr\u001b[35m:f32[1000,56,56,64]\u001b[39m = add jq ip\n", | |
" js\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jt\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mju\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jv\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjw\u001b[35m:f32[1000,56,56,64]\u001b[39m = max jv 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jw,) }\n", | |
" name=relu\n", | |
" ] jt\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ju,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10fdd0>\n", | |
" num_consts=0\n", | |
" ] jr\n", | |
" jx\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] js eq\n", | |
" jy\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gr\n", | |
" jz\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gs\n", | |
" ka\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub jx jy\n", | |
" kb\u001b[35m:f32[1,1,1,64]\u001b[39m = add jz 9.999999747378752e-06\n", | |
" kc\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt kb\n", | |
" kd\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] el\n", | |
" ke\u001b[35m:f32[1,1,1,64]\u001b[39m = mul kc kd\n", | |
" kf\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul ka ke\n", | |
" kg\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ek\n", | |
" kh\u001b[35m:f32[1000,56,56,64]\u001b[39m = add kf kg\n", | |
" ki\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; kj\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mkk\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; kl\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mkm\u001b[35m:f32[1000,56,56,64]\u001b[39m = max kl 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(km,) }\n", | |
" name=relu\n", | |
" ] kj\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(kk,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10f710>\n", | |
" num_consts=0\n", | |
" ] kh\n", | |
" kn\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] ki er\n", | |
" ko\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gt\n", | |
" kp\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gu\n", | |
" kq\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub kn ko\n", | |
" kr\u001b[35m:f32[1,1,1,64]\u001b[39m = add kp 9.999999747378752e-06\n", | |
" ks\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt kr\n", | |
" kt\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] en\n", | |
" ku\u001b[35m:f32[1,1,1,64]\u001b[39m = mul ks kt\n", | |
" kv\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul kq ku\n", | |
" kw\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] em\n", | |
" kx\u001b[35m:f32[1000,56,56,64]\u001b[39m = add kv kw\n", | |
" ky\u001b[35m:f32[1000,56,56,64]\u001b[39m = add kx js\n", | |
" kz\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; la\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlb\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; lc\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mld\u001b[35m:f32[1000,56,56,64]\u001b[39m = max lc 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ld,) }\n", | |
" name=relu\n", | |
" ] la\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lb,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10f4d0>\n", | |
" num_consts=0\n", | |
" ] ky\n", | |
" le\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 128)\n", | |
" window_strides=(2, 2)\n", | |
" ] kz fc\n", | |
" lf\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gv\n", | |
" lg\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gw\n", | |
" lh\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub le lf\n", | |
" li\u001b[35m:f32[1,1,1,128]\u001b[39m = add lg 9.999999747378752e-06\n", | |
" lj\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt li\n", | |
" lk\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] et\n", | |
" ll\u001b[35m:f32[1,1,1,128]\u001b[39m = mul lj lk\n", | |
" lm\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul lh ll\n", | |
" ln\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] es\n", | |
" lo\u001b[35m:f32[1000,28,28,128]\u001b[39m = add lm ln\n", | |
" lp\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; lq\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlr\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ls\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlt\u001b[35m:f32[1000,28,28,128]\u001b[39m = max ls 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lt,) }\n", | |
" name=relu\n", | |
" ] lq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10fd40>\n", | |
" num_consts=0\n", | |
" ] lo\n", | |
" lu\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] lp fd\n", | |
" lv\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gx\n", | |
" lw\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gy\n", | |
" lx\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub lu lv\n", | |
" ly\u001b[35m:f32[1,1,1,128]\u001b[39m = add lw 9.999999747378752e-06\n", | |
" lz\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt ly\n", | |
" ma\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ev\n", | |
" mb\u001b[35m:f32[1,1,1,128]\u001b[39m = mul lz ma\n", | |
" mc\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul lx mb\n", | |
" md\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] eu\n", | |
" me\u001b[35m:f32[1000,28,28,128]\u001b[39m = add mc md\n", | |
" mf\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 64, 128)\n", | |
" window_strides=(2, 2)\n", | |
" ] kz fe\n", | |
" mg\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gz\n", | |
" mh\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ha\n", | |
" mi\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub mf mg\n", | |
" mj\u001b[35m:f32[1,1,1,128]\u001b[39m = add mh 9.999999747378752e-06\n", | |
" mk\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt mj\n", | |
" ml\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ex\n", | |
" mm\u001b[35m:f32[1,1,1,128]\u001b[39m = mul mk ml\n", | |
" mn\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul mi mm\n", | |
" mo\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ew\n", | |
" mp\u001b[35m:f32[1000,28,28,128]\u001b[39m = add mn mo\n", | |
" mq\u001b[35m:f32[1000,28,28,128]\u001b[39m = add me mp\n", | |
" mr\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ms\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmt\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; mu\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmv\u001b[35m:f32[1000,28,28,128]\u001b[39m = max mu 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(mv,) }\n", | |
" name=relu\n", | |
" ] ms\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(mt,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10f5f0>\n", | |
" num_consts=0\n", | |
" ] mq\n", | |
" mw\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] mr ff\n", | |
" mx\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] hb\n", | |
" my\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] hc\n", | |
" mz\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub mw mx\n", | |
" na\u001b[35m:f32[1,1,1,128]\u001b[39m = add my 9.999999747378752e-06\n", | |
" nb\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt na\n", | |
" nc\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ez\n", | |
" nd\u001b[35m:f32[1,1,1,128]\u001b[39m = mul nb nc\n", | |
" ne\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul mz nd\n", | |
" nf\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ey\n", | |
" ng\u001b[35m:f32[1000,28,28,128]\u001b[39m = add ne nf\n", | |
" nh\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ni\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mnj\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; nk\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mnl\u001b[35m:f32[1000,28,28,128]\u001b[39m = max nk 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(nl,) }\n", | |
" name=relu\n", | |
" ] ni\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(nj,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10f7a0>\n", | |
" num_consts=0\n", | |
" ] ng\n", | |
" nm\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] nh fg\n", | |
" nn\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] hd\n", | |
" no\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] he\n", | |
" np\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub nm nn\n", | |
" nq\u001b[35m:f32[1,1,1,128]\u001b[39m = add no 9.999999747378752e-06\n", | |
" nr\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt nq\n", | |
" ns\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] fb\n", | |
" nt\u001b[35m:f32[1,1,1,128]\u001b[39m = mul nr ns\n", | |
" nu\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul np nt\n", | |
" nv\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] fa\n", | |
" nw\u001b[35m:f32[1000,28,28,128]\u001b[39m = add nu nv\n", | |
" nx\u001b[35m:f32[1000,28,28,128]\u001b[39m = add nw mr\n", | |
" ny\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; nz\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moa\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ob\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moc\u001b[35m:f32[1000,28,28,128]\u001b[39m = max ob 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oc,) }\n", | |
" name=relu\n", | |
" ] nz\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oa,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10f8c0>\n", | |
" num_consts=0\n", | |
" ] nx\n", | |
" od\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 256)\n", | |
" window_strides=(2, 2)\n", | |
" ] ny fr\n", | |
" oe\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hf\n", | |
" of\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hg\n", | |
" og\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub od oe\n", | |
" oh\u001b[35m:f32[1,1,1,256]\u001b[39m = add of 9.999999747378752e-06\n", | |
" oi\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt oh\n", | |
" oj\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fi\n", | |
" ok\u001b[35m:f32[1,1,1,256]\u001b[39m = mul oi oj\n", | |
" ol\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul og ok\n", | |
" om\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fh\n", | |
" on\u001b[35m:f32[1000,14,14,256]\u001b[39m = add ol om\n", | |
" oo\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; op\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moq\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; or\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mos\u001b[35m:f32[1000,14,14,256]\u001b[39m = max or 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(os,) }\n", | |
" name=relu\n", | |
" ] op\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oq,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a10fcb0>\n", | |
" num_consts=0\n", | |
" ] on\n", | |
" ot\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] oo fs\n", | |
" ou\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hh\n", | |
" ov\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hi\n", | |
" ow\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub ot ou\n", | |
" ox\u001b[35m:f32[1,1,1,256]\u001b[39m = add ov 9.999999747378752e-06\n", | |
" oy\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt ox\n", | |
" oz\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fk\n", | |
" pa\u001b[35m:f32[1,1,1,256]\u001b[39m = mul oy oz\n", | |
" pb\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul ow pa\n", | |
" pc\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fj\n", | |
" pd\u001b[35m:f32[1000,14,14,256]\u001b[39m = add pb pc\n", | |
" pe\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 128, 256)\n", | |
" window_strides=(2, 2)\n", | |
" ] ny ft\n", | |
" pf\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hj\n", | |
" pg\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hk\n", | |
" ph\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub pe pf\n", | |
" pi\u001b[35m:f32[1,1,1,256]\u001b[39m = add pg 9.999999747378752e-06\n", | |
" pj\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt pi\n", | |
" pk\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fm\n", | |
" pl\u001b[35m:f32[1,1,1,256]\u001b[39m = mul pj pk\n", | |
" pm\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul ph pl\n", | |
" pn\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fl\n", | |
" po\u001b[35m:f32[1000,14,14,256]\u001b[39m = add pm pn\n", | |
" pp\u001b[35m:f32[1000,14,14,256]\u001b[39m = add pd po\n", | |
" pq\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; pr\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mps\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; pt\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mpu\u001b[35m:f32[1000,14,14,256]\u001b[39m = max pt 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(pu,) }\n", | |
" name=relu\n", | |
" ] pr\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ps,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0de440>\n", | |
" num_consts=0\n", | |
" ] pp\n", | |
" pv\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] pq fu\n", | |
" pw\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hl\n", | |
" px\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hm\n", | |
" py\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub pv pw\n", | |
" pz\u001b[35m:f32[1,1,1,256]\u001b[39m = add px 9.999999747378752e-06\n", | |
" qa\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt pz\n", | |
" qb\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fo\n", | |
" qc\u001b[35m:f32[1,1,1,256]\u001b[39m = mul qa qb\n", | |
" qd\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul py qc\n", | |
" qe\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fn\n", | |
" qf\u001b[35m:f32[1000,14,14,256]\u001b[39m = add qd qe\n", | |
" qg\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qh\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqi\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qj\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqk\u001b[35m:f32[1000,14,14,256]\u001b[39m = max qj 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qk,) }\n", | |
" name=relu\n", | |
" ] qh\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qi,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0ded40>\n", | |
" num_consts=0\n", | |
" ] qf\n", | |
" ql\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] qg fv\n", | |
" qm\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hn\n", | |
" qn\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] ho\n", | |
" qo\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub ql qm\n", | |
" qp\u001b[35m:f32[1,1,1,256]\u001b[39m = add qn 9.999999747378752e-06\n", | |
" qq\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt qp\n", | |
" qr\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fq\n", | |
" qs\u001b[35m:f32[1,1,1,256]\u001b[39m = mul qq qr\n", | |
" qt\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul qo qs\n", | |
" qu\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fp\n", | |
" qv\u001b[35m:f32[1000,14,14,256]\u001b[39m = add qt qu\n", | |
" qw\u001b[35m:f32[1000,14,14,256]\u001b[39m = add qv pq\n", | |
" qx\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qy\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqz\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ra\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mrb\u001b[35m:f32[1000,14,14,256]\u001b[39m = max ra 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(rb,) }\n", | |
" name=relu\n", | |
" ] qy\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qz,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0de050>\n", | |
" num_consts=0\n", | |
" ] qw\n", | |
" rc\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 512)\n", | |
" window_strides=(2, 2)\n", | |
" ] qx gg\n", | |
" rd\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hp\n", | |
" re\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hq\n", | |
" rf\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub rc rd\n", | |
" rg\u001b[35m:f32[1,1,1,512]\u001b[39m = add re 9.999999747378752e-06\n", | |
" rh\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt rg\n", | |
" ri\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fx\n", | |
" rj\u001b[35m:f32[1,1,1,512]\u001b[39m = mul rh ri\n", | |
" rk\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul rf rj\n", | |
" rl\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fw\n", | |
" rm\u001b[35m:f32[1000,7,7,512]\u001b[39m = add rk rl\n", | |
" rn\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ro\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mrp\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; rq\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mrr\u001b[35m:f32[1000,7,7,512]\u001b[39m = max rq 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(rr,) }\n", | |
" name=relu\n", | |
" ] ro\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(rp,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0de4d0>\n", | |
" num_consts=0\n", | |
" ] rm\n", | |
" rs\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] rn gh\n", | |
" rt\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hr\n", | |
" ru\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hs\n", | |
" rv\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub rs rt\n", | |
" rw\u001b[35m:f32[1,1,1,512]\u001b[39m = add ru 9.999999747378752e-06\n", | |
" rx\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt rw\n", | |
" ry\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fz\n", | |
" rz\u001b[35m:f32[1,1,1,512]\u001b[39m = mul rx ry\n", | |
" sa\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul rv rz\n", | |
" sb\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fy\n", | |
" sc\u001b[35m:f32[1000,7,7,512]\u001b[39m = add sa sb\n", | |
" sd\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 256, 512)\n", | |
" window_strides=(2, 2)\n", | |
" ] qx gi\n", | |
" se\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] ht\n", | |
" sf\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hu\n", | |
" sg\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub sd se\n", | |
" sh\u001b[35m:f32[1,1,1,512]\u001b[39m = add sf 9.999999747378752e-06\n", | |
" si\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt sh\n", | |
" sj\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gb\n", | |
" sk\u001b[35m:f32[1,1,1,512]\u001b[39m = mul si sj\n", | |
" sl\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul sg sk\n", | |
" sm\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] ga\n", | |
" sn\u001b[35m:f32[1000,7,7,512]\u001b[39m = add sl sm\n", | |
" so\u001b[35m:f32[1000,7,7,512]\u001b[39m = add sc sn\n", | |
" sp\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; sq\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22msr\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ss\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mst\u001b[35m:f32[1000,7,7,512]\u001b[39m = max ss 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(st,) }\n", | |
" name=relu\n", | |
" ] sq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(sr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0de7a0>\n", | |
" num_consts=0\n", | |
" ] so\n", | |
" su\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] sp gj\n", | |
" sv\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hv\n", | |
" sw\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hw\n", | |
" sx\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub su sv\n", | |
" sy\u001b[35m:f32[1,1,1,512]\u001b[39m = add sw 9.999999747378752e-06\n", | |
" sz\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt sy\n", | |
" ta\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gd\n", | |
" tb\u001b[35m:f32[1,1,1,512]\u001b[39m = mul sz ta\n", | |
" tc\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul sx tb\n", | |
" td\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gc\n", | |
" te\u001b[35m:f32[1000,7,7,512]\u001b[39m = add tc td\n", | |
" tf\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; tg\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mth\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ti\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mtj\u001b[35m:f32[1000,7,7,512]\u001b[39m = max ti 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(tj,) }\n", | |
" name=relu\n", | |
" ] tg\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(th,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0de200>\n", | |
" num_consts=0\n", | |
" ] te\n", | |
" tk\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] tf gk\n", | |
" tl\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hx\n", | |
" tm\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hy\n", | |
" tn\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub tk tl\n", | |
" to\u001b[35m:f32[1,1,1,512]\u001b[39m = add tm 9.999999747378752e-06\n", | |
" tp\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt to\n", | |
" tq\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gf\n", | |
" tr\u001b[35m:f32[1,1,1,512]\u001b[39m = mul tp tq\n", | |
" ts\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul tn tr\n", | |
" tt\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] ge\n", | |
" tu\u001b[35m:f32[1000,7,7,512]\u001b[39m = add ts tt\n", | |
" tv\u001b[35m:f32[1000,7,7,512]\u001b[39m = add tu sp\n", | |
" tw\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; tx\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mty\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; tz\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mua\u001b[35m:f32[1000,7,7,512]\u001b[39m = max tz 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ua,) }\n", | |
" name=relu\n", | |
" ] tx\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ty,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0de950>\n", | |
" num_consts=0\n", | |
" ] tv\n", | |
" ub\u001b[35m:f32[1000,512]\u001b[39m = reduce_sum[axes=(1, 2)] tw\n", | |
" uc\u001b[35m:f32[1000,512]\u001b[39m = div ub 49.0\n", | |
" ud\u001b[35m:f32[1000,1000]\u001b[39m = dot_general[\n", | |
" dimension_numbers=(((1,), (0,)), ((), ()))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" ] uc ef\n", | |
" ue\u001b[35m:f32[1,1000]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1000)] ee\n", | |
" uf\u001b[35m:f32[1000,1000]\u001b[39m = add ud ue\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(uf,) }\n", | |
" name=predict\n", | |
" ] a b c d e f g h i j k l m n o p q r s t u v w x y z ba bb bc bd be bf bg bh\n", | |
" bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb cc cd ce cf cg\n", | |
" ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz da db dc dd de df\n", | |
" dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(dz,) }" | |
] | |
}, | |
"metadata": {}, | |
"execution_count": 10 | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"predict_gpu = jit(predict, backend='gpu')\n", | |
"make_jaxpr(predict_gpu)(jnp.ones((1000, 224,224,3)), params, batch_stats)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "tH4sIjp3h_oE", | |
"outputId": "0b10eec5-182c-44ef-cfba-abed0d1aff88" | |
}, | |
"execution_count": 11, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"{ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; a\u001b[35m:f32[1000,224,224,3]\u001b[39m b\u001b[35m:f32[64]\u001b[39m c\u001b[35m:f32[64]\u001b[39m d\u001b[35m:f32[7,7,3,64]\u001b[39m e\u001b[35m:f32[1000]\u001b[39m\n", | |
" f\u001b[35m:f32[512,1000]\u001b[39m g\u001b[35m:f32[64]\u001b[39m h\u001b[35m:f32[64]\u001b[39m i\u001b[35m:f32[64]\u001b[39m j\u001b[35m:f32[64]\u001b[39m k\u001b[35m:f32[64]\u001b[39m l\u001b[35m:f32[64]\u001b[39m m\u001b[35m:f32[64]\u001b[39m\n", | |
" n\u001b[35m:f32[64]\u001b[39m o\u001b[35m:f32[3,3,64,64]\u001b[39m p\u001b[35m:f32[3,3,64,64]\u001b[39m q\u001b[35m:f32[3,3,64,64]\u001b[39m r\u001b[35m:f32[3,3,64,64]\u001b[39m\n", | |
" s\u001b[35m:f32[128]\u001b[39m t\u001b[35m:f32[128]\u001b[39m u\u001b[35m:f32[128]\u001b[39m v\u001b[35m:f32[128]\u001b[39m w\u001b[35m:f32[128]\u001b[39m x\u001b[35m:f32[128]\u001b[39m y\u001b[35m:f32[128]\u001b[39m\n", | |
" z\u001b[35m:f32[128]\u001b[39m ba\u001b[35m:f32[128]\u001b[39m bb\u001b[35m:f32[128]\u001b[39m bc\u001b[35m:f32[3,3,64,128]\u001b[39m bd\u001b[35m:f32[3,3,128,128]\u001b[39m be\u001b[35m:f32[1,1,64,128]\u001b[39m\n", | |
" bf\u001b[35m:f32[3,3,128,128]\u001b[39m bg\u001b[35m:f32[3,3,128,128]\u001b[39m bh\u001b[35m:f32[256]\u001b[39m bi\u001b[35m:f32[256]\u001b[39m bj\u001b[35m:f32[256]\u001b[39m bk\u001b[35m:f32[256]\u001b[39m\n", | |
" bl\u001b[35m:f32[256]\u001b[39m bm\u001b[35m:f32[256]\u001b[39m bn\u001b[35m:f32[256]\u001b[39m bo\u001b[35m:f32[256]\u001b[39m bp\u001b[35m:f32[256]\u001b[39m bq\u001b[35m:f32[256]\u001b[39m br\u001b[35m:f32[3,3,128,256]\u001b[39m\n", | |
" bs\u001b[35m:f32[3,3,256,256]\u001b[39m bt\u001b[35m:f32[1,1,128,256]\u001b[39m bu\u001b[35m:f32[3,3,256,256]\u001b[39m bv\u001b[35m:f32[3,3,256,256]\u001b[39m\n", | |
" bw\u001b[35m:f32[512]\u001b[39m bx\u001b[35m:f32[512]\u001b[39m by\u001b[35m:f32[512]\u001b[39m bz\u001b[35m:f32[512]\u001b[39m ca\u001b[35m:f32[512]\u001b[39m cb\u001b[35m:f32[512]\u001b[39m cc\u001b[35m:f32[512]\u001b[39m\n", | |
" cd\u001b[35m:f32[512]\u001b[39m ce\u001b[35m:f32[512]\u001b[39m cf\u001b[35m:f32[512]\u001b[39m cg\u001b[35m:f32[3,3,256,512]\u001b[39m ch\u001b[35m:f32[3,3,512,512]\u001b[39m ci\u001b[35m:f32[1,1,256,512]\u001b[39m\n", | |
" cj\u001b[35m:f32[3,3,512,512]\u001b[39m ck\u001b[35m:f32[3,3,512,512]\u001b[39m cl\u001b[35m:f32[64]\u001b[39m cm\u001b[35m:f32[64]\u001b[39m cn\u001b[35m:f32[64]\u001b[39m co\u001b[35m:f32[64]\u001b[39m\n", | |
" cp\u001b[35m:f32[64]\u001b[39m cq\u001b[35m:f32[64]\u001b[39m cr\u001b[35m:f32[64]\u001b[39m cs\u001b[35m:f32[64]\u001b[39m ct\u001b[35m:f32[64]\u001b[39m cu\u001b[35m:f32[64]\u001b[39m cv\u001b[35m:f32[128]\u001b[39m\n", | |
" cw\u001b[35m:f32[128]\u001b[39m cx\u001b[35m:f32[128]\u001b[39m cy\u001b[35m:f32[128]\u001b[39m cz\u001b[35m:f32[128]\u001b[39m da\u001b[35m:f32[128]\u001b[39m db\u001b[35m:f32[128]\u001b[39m dc\u001b[35m:f32[128]\u001b[39m\n", | |
" dd\u001b[35m:f32[128]\u001b[39m de\u001b[35m:f32[128]\u001b[39m df\u001b[35m:f32[256]\u001b[39m dg\u001b[35m:f32[256]\u001b[39m dh\u001b[35m:f32[256]\u001b[39m di\u001b[35m:f32[256]\u001b[39m dj\u001b[35m:f32[256]\u001b[39m\n", | |
" dk\u001b[35m:f32[256]\u001b[39m dl\u001b[35m:f32[256]\u001b[39m dm\u001b[35m:f32[256]\u001b[39m dn\u001b[35m:f32[256]\u001b[39m do\u001b[35m:f32[256]\u001b[39m dp\u001b[35m:f32[512]\u001b[39m dq\u001b[35m:f32[512]\u001b[39m\n", | |
" dr\u001b[35m:f32[512]\u001b[39m ds\u001b[35m:f32[512]\u001b[39m dt\u001b[35m:f32[512]\u001b[39m du\u001b[35m:f32[512]\u001b[39m dv\u001b[35m:f32[512]\u001b[39m dw\u001b[35m:f32[512]\u001b[39m dx\u001b[35m:f32[512]\u001b[39m\n", | |
" dy\u001b[35m:f32[512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mdz\u001b[35m:f32[1000,1000]\u001b[39m = xla_call[\n", | |
" backend=gpu\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ea\u001b[35m:f32[1000,224,224,3]\u001b[39m eb\u001b[35m:f32[64]\u001b[39m ec\u001b[35m:f32[64]\u001b[39m ed\u001b[35m:f32[7,7,3,64]\u001b[39m\n", | |
" ee\u001b[35m:f32[1000]\u001b[39m ef\u001b[35m:f32[512,1000]\u001b[39m eg\u001b[35m:f32[64]\u001b[39m eh\u001b[35m:f32[64]\u001b[39m ei\u001b[35m:f32[64]\u001b[39m ej\u001b[35m:f32[64]\u001b[39m\n", | |
" ek\u001b[35m:f32[64]\u001b[39m el\u001b[35m:f32[64]\u001b[39m em\u001b[35m:f32[64]\u001b[39m en\u001b[35m:f32[64]\u001b[39m eo\u001b[35m:f32[3,3,64,64]\u001b[39m ep\u001b[35m:f32[3,3,64,64]\u001b[39m\n", | |
" eq\u001b[35m:f32[3,3,64,64]\u001b[39m er\u001b[35m:f32[3,3,64,64]\u001b[39m es\u001b[35m:f32[128]\u001b[39m et\u001b[35m:f32[128]\u001b[39m eu\u001b[35m:f32[128]\u001b[39m\n", | |
" ev\u001b[35m:f32[128]\u001b[39m ew\u001b[35m:f32[128]\u001b[39m ex\u001b[35m:f32[128]\u001b[39m ey\u001b[35m:f32[128]\u001b[39m ez\u001b[35m:f32[128]\u001b[39m fa\u001b[35m:f32[128]\u001b[39m\n", | |
" fb\u001b[35m:f32[128]\u001b[39m fc\u001b[35m:f32[3,3,64,128]\u001b[39m fd\u001b[35m:f32[3,3,128,128]\u001b[39m fe\u001b[35m:f32[1,1,64,128]\u001b[39m ff\u001b[35m:f32[3,3,128,128]\u001b[39m\n", | |
" fg\u001b[35m:f32[3,3,128,128]\u001b[39m fh\u001b[35m:f32[256]\u001b[39m fi\u001b[35m:f32[256]\u001b[39m fj\u001b[35m:f32[256]\u001b[39m fk\u001b[35m:f32[256]\u001b[39m fl\u001b[35m:f32[256]\u001b[39m\n", | |
" fm\u001b[35m:f32[256]\u001b[39m fn\u001b[35m:f32[256]\u001b[39m fo\u001b[35m:f32[256]\u001b[39m fp\u001b[35m:f32[256]\u001b[39m fq\u001b[35m:f32[256]\u001b[39m fr\u001b[35m:f32[3,3,128,256]\u001b[39m\n", | |
" fs\u001b[35m:f32[3,3,256,256]\u001b[39m ft\u001b[35m:f32[1,1,128,256]\u001b[39m fu\u001b[35m:f32[3,3,256,256]\u001b[39m fv\u001b[35m:f32[3,3,256,256]\u001b[39m\n", | |
" fw\u001b[35m:f32[512]\u001b[39m fx\u001b[35m:f32[512]\u001b[39m fy\u001b[35m:f32[512]\u001b[39m fz\u001b[35m:f32[512]\u001b[39m ga\u001b[35m:f32[512]\u001b[39m gb\u001b[35m:f32[512]\u001b[39m\n", | |
" gc\u001b[35m:f32[512]\u001b[39m gd\u001b[35m:f32[512]\u001b[39m ge\u001b[35m:f32[512]\u001b[39m gf\u001b[35m:f32[512]\u001b[39m gg\u001b[35m:f32[3,3,256,512]\u001b[39m gh\u001b[35m:f32[3,3,512,512]\u001b[39m\n", | |
" gi\u001b[35m:f32[1,1,256,512]\u001b[39m gj\u001b[35m:f32[3,3,512,512]\u001b[39m gk\u001b[35m:f32[3,3,512,512]\u001b[39m gl\u001b[35m:f32[64]\u001b[39m\n", | |
" gm\u001b[35m:f32[64]\u001b[39m gn\u001b[35m:f32[64]\u001b[39m go\u001b[35m:f32[64]\u001b[39m gp\u001b[35m:f32[64]\u001b[39m gq\u001b[35m:f32[64]\u001b[39m gr\u001b[35m:f32[64]\u001b[39m gs\u001b[35m:f32[64]\u001b[39m\n", | |
" gt\u001b[35m:f32[64]\u001b[39m gu\u001b[35m:f32[64]\u001b[39m gv\u001b[35m:f32[128]\u001b[39m gw\u001b[35m:f32[128]\u001b[39m gx\u001b[35m:f32[128]\u001b[39m gy\u001b[35m:f32[128]\u001b[39m gz\u001b[35m:f32[128]\u001b[39m\n", | |
" ha\u001b[35m:f32[128]\u001b[39m hb\u001b[35m:f32[128]\u001b[39m hc\u001b[35m:f32[128]\u001b[39m hd\u001b[35m:f32[128]\u001b[39m he\u001b[35m:f32[128]\u001b[39m hf\u001b[35m:f32[256]\u001b[39m\n", | |
" hg\u001b[35m:f32[256]\u001b[39m hh\u001b[35m:f32[256]\u001b[39m hi\u001b[35m:f32[256]\u001b[39m hj\u001b[35m:f32[256]\u001b[39m hk\u001b[35m:f32[256]\u001b[39m hl\u001b[35m:f32[256]\u001b[39m\n", | |
" hm\u001b[35m:f32[256]\u001b[39m hn\u001b[35m:f32[256]\u001b[39m ho\u001b[35m:f32[256]\u001b[39m hp\u001b[35m:f32[512]\u001b[39m hq\u001b[35m:f32[512]\u001b[39m hr\u001b[35m:f32[512]\u001b[39m\n", | |
" hs\u001b[35m:f32[512]\u001b[39m ht\u001b[35m:f32[512]\u001b[39m hu\u001b[35m:f32[512]\u001b[39m hv\u001b[35m:f32[512]\u001b[39m hw\u001b[35m:f32[512]\u001b[39m hx\u001b[35m:f32[512]\u001b[39m\n", | |
" hy\u001b[35m:f32[512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mhz\u001b[35m:f32[1000,112,112,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 224, 224, 3)\n", | |
" padding=((3, 3), (3, 3))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(7, 7, 3, 64)\n", | |
" window_strides=(2, 2)\n", | |
" ] ea ed\n", | |
" ia\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gl\n", | |
" ib\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gm\n", | |
" ic\u001b[35m:f32[1000,112,112,64]\u001b[39m = sub hz ia\n", | |
" id\u001b[35m:f32[1,1,1,64]\u001b[39m = add ib 9.999999747378752e-06\n", | |
" ie\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt id\n", | |
" if\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ec\n", | |
" ig\u001b[35m:f32[1,1,1,64]\u001b[39m = mul ie if\n", | |
" ih\u001b[35m:f32[1000,112,112,64]\u001b[39m = mul ic ig\n", | |
" ii\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] eb\n", | |
" ij\u001b[35m:f32[1000,112,112,64]\u001b[39m = add ih ii\n", | |
" ik\u001b[35m:f32[1000,112,112,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; il\u001b[35m:f32[1000,112,112,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mim\u001b[35m:f32[1000,112,112,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; in\u001b[35m:f32[1000,112,112,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mio\u001b[35m:f32[1000,112,112,64]\u001b[39m = max in 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(io,) }\n", | |
" name=relu\n", | |
" ] il\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(im,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a2a84d0>\n", | |
" num_consts=0\n", | |
" ] ij\n", | |
" ip\u001b[35m:f32[1000,56,56,64]\u001b[39m = reduce_window_max[\n", | |
" base_dilation=(1, 1, 1, 1)\n", | |
" padding=((0, 0), (1, 1), (1, 1), (0, 0))\n", | |
" window_dilation=(1, 1, 1, 1)\n", | |
" window_dimensions=(1, 3, 3, 1)\n", | |
" window_strides=(1, 2, 2, 1)\n", | |
" ] ik\n", | |
" iq\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] ip eo\n", | |
" ir\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gn\n", | |
" is\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] go\n", | |
" it\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub iq ir\n", | |
" iu\u001b[35m:f32[1,1,1,64]\u001b[39m = add is 9.999999747378752e-06\n", | |
" iv\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt iu\n", | |
" iw\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] eh\n", | |
" ix\u001b[35m:f32[1,1,1,64]\u001b[39m = mul iv iw\n", | |
" iy\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul it ix\n", | |
" iz\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] eg\n", | |
" ja\u001b[35m:f32[1000,56,56,64]\u001b[39m = add iy iz\n", | |
" jb\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jc\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjd\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; je\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjf\u001b[35m:f32[1000,56,56,64]\u001b[39m = max je 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jf,) }\n", | |
" name=relu\n", | |
" ] jc\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jd,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0de290>\n", | |
" num_consts=0\n", | |
" ] ja\n", | |
" jg\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] jb ep\n", | |
" jh\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gp\n", | |
" ji\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gq\n", | |
" jj\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub jg jh\n", | |
" jk\u001b[35m:f32[1,1,1,64]\u001b[39m = add ji 9.999999747378752e-06\n", | |
" jl\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt jk\n", | |
" jm\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ej\n", | |
" jn\u001b[35m:f32[1,1,1,64]\u001b[39m = mul jl jm\n", | |
" jo\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul jj jn\n", | |
" jp\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ei\n", | |
" jq\u001b[35m:f32[1000,56,56,64]\u001b[39m = add jo jp\n", | |
" jr\u001b[35m:f32[1000,56,56,64]\u001b[39m = add jq ip\n", | |
" js\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jt\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mju\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jv\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjw\u001b[35m:f32[1000,56,56,64]\u001b[39m = max jv 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jw,) }\n", | |
" name=relu\n", | |
" ] jt\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ju,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0def80>\n", | |
" num_consts=0\n", | |
" ] jr\n", | |
" jx\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] js eq\n", | |
" jy\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gr\n", | |
" jz\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gs\n", | |
" ka\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub jx jy\n", | |
" kb\u001b[35m:f32[1,1,1,64]\u001b[39m = add jz 9.999999747378752e-06\n", | |
" kc\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt kb\n", | |
" kd\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] el\n", | |
" ke\u001b[35m:f32[1,1,1,64]\u001b[39m = mul kc kd\n", | |
" kf\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul ka ke\n", | |
" kg\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] ek\n", | |
" kh\u001b[35m:f32[1000,56,56,64]\u001b[39m = add kf kg\n", | |
" ki\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; kj\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mkk\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; kl\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mkm\u001b[35m:f32[1000,56,56,64]\u001b[39m = max kl 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(km,) }\n", | |
" name=relu\n", | |
" ] kj\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(kk,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a0dedd0>\n", | |
" num_consts=0\n", | |
" ] kh\n", | |
" kn\u001b[35m:f32[1000,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] ki er\n", | |
" ko\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gt\n", | |
" kp\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] gu\n", | |
" kq\u001b[35m:f32[1000,56,56,64]\u001b[39m = sub kn ko\n", | |
" kr\u001b[35m:f32[1,1,1,64]\u001b[39m = add kp 9.999999747378752e-06\n", | |
" ks\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt kr\n", | |
" kt\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] en\n", | |
" ku\u001b[35m:f32[1,1,1,64]\u001b[39m = mul ks kt\n", | |
" kv\u001b[35m:f32[1000,56,56,64]\u001b[39m = mul kq ku\n", | |
" kw\u001b[35m:f32[1,1,1,64]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 64)] em\n", | |
" kx\u001b[35m:f32[1000,56,56,64]\u001b[39m = add kv kw\n", | |
" ky\u001b[35m:f32[1000,56,56,64]\u001b[39m = add kx js\n", | |
" kz\u001b[35m:f32[1000,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; la\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlb\u001b[35m:f32[1000,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; lc\u001b[35m:f32[1000,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mld\u001b[35m:f32[1000,56,56,64]\u001b[39m = max lc 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ld,) }\n", | |
" name=relu\n", | |
" ] la\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lb,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e4d0>\n", | |
" num_consts=0\n", | |
" ] ky\n", | |
" le\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 128)\n", | |
" window_strides=(2, 2)\n", | |
" ] kz fc\n", | |
" lf\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gv\n", | |
" lg\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gw\n", | |
" lh\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub le lf\n", | |
" li\u001b[35m:f32[1,1,1,128]\u001b[39m = add lg 9.999999747378752e-06\n", | |
" lj\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt li\n", | |
" lk\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] et\n", | |
" ll\u001b[35m:f32[1,1,1,128]\u001b[39m = mul lj lk\n", | |
" lm\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul lh ll\n", | |
" ln\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] es\n", | |
" lo\u001b[35m:f32[1000,28,28,128]\u001b[39m = add lm ln\n", | |
" lp\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; lq\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlr\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ls\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlt\u001b[35m:f32[1000,28,28,128]\u001b[39m = max ls 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lt,) }\n", | |
" name=relu\n", | |
" ] lq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e7a0>\n", | |
" num_consts=0\n", | |
" ] lo\n", | |
" lu\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] lp fd\n", | |
" lv\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gx\n", | |
" lw\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gy\n", | |
" lx\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub lu lv\n", | |
" ly\u001b[35m:f32[1,1,1,128]\u001b[39m = add lw 9.999999747378752e-06\n", | |
" lz\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt ly\n", | |
" ma\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ev\n", | |
" mb\u001b[35m:f32[1,1,1,128]\u001b[39m = mul lz ma\n", | |
" mc\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul lx mb\n", | |
" md\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] eu\n", | |
" me\u001b[35m:f32[1000,28,28,128]\u001b[39m = add mc md\n", | |
" mf\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 56, 56, 64)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 64, 128)\n", | |
" window_strides=(2, 2)\n", | |
" ] kz fe\n", | |
" mg\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] gz\n", | |
" mh\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ha\n", | |
" mi\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub mf mg\n", | |
" mj\u001b[35m:f32[1,1,1,128]\u001b[39m = add mh 9.999999747378752e-06\n", | |
" mk\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt mj\n", | |
" ml\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ex\n", | |
" mm\u001b[35m:f32[1,1,1,128]\u001b[39m = mul mk ml\n", | |
" mn\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul mi mm\n", | |
" mo\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ew\n", | |
" mp\u001b[35m:f32[1000,28,28,128]\u001b[39m = add mn mo\n", | |
" mq\u001b[35m:f32[1000,28,28,128]\u001b[39m = add me mp\n", | |
" mr\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ms\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmt\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; mu\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmv\u001b[35m:f32[1000,28,28,128]\u001b[39m = max mu 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(mv,) }\n", | |
" name=relu\n", | |
" ] ms\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(mt,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e5f0>\n", | |
" num_consts=0\n", | |
" ] mq\n", | |
" mw\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] mr ff\n", | |
" mx\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] hb\n", | |
" my\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] hc\n", | |
" mz\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub mw mx\n", | |
" na\u001b[35m:f32[1,1,1,128]\u001b[39m = add my 9.999999747378752e-06\n", | |
" nb\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt na\n", | |
" nc\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ez\n", | |
" nd\u001b[35m:f32[1,1,1,128]\u001b[39m = mul nb nc\n", | |
" ne\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul mz nd\n", | |
" nf\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] ey\n", | |
" ng\u001b[35m:f32[1000,28,28,128]\u001b[39m = add ne nf\n", | |
" nh\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ni\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mnj\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; nk\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mnl\u001b[35m:f32[1000,28,28,128]\u001b[39m = max nk 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(nl,) }\n", | |
" name=relu\n", | |
" ] ni\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(nj,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e830>\n", | |
" num_consts=0\n", | |
" ] ng\n", | |
" nm\u001b[35m:f32[1000,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] nh fg\n", | |
" nn\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] hd\n", | |
" no\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] he\n", | |
" np\u001b[35m:f32[1000,28,28,128]\u001b[39m = sub nm nn\n", | |
" nq\u001b[35m:f32[1,1,1,128]\u001b[39m = add no 9.999999747378752e-06\n", | |
" nr\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt nq\n", | |
" ns\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] fb\n", | |
" nt\u001b[35m:f32[1,1,1,128]\u001b[39m = mul nr ns\n", | |
" nu\u001b[35m:f32[1000,28,28,128]\u001b[39m = mul np nt\n", | |
" nv\u001b[35m:f32[1,1,1,128]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 128)] fa\n", | |
" nw\u001b[35m:f32[1000,28,28,128]\u001b[39m = add nu nv\n", | |
" nx\u001b[35m:f32[1000,28,28,128]\u001b[39m = add nw mr\n", | |
" ny\u001b[35m:f32[1000,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; nz\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moa\u001b[35m:f32[1000,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ob\u001b[35m:f32[1000,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moc\u001b[35m:f32[1000,28,28,128]\u001b[39m = max ob 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oc,) }\n", | |
" name=relu\n", | |
" ] nz\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oa,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7ecb0>\n", | |
" num_consts=0\n", | |
" ] nx\n", | |
" od\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 256)\n", | |
" window_strides=(2, 2)\n", | |
" ] ny fr\n", | |
" oe\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hf\n", | |
" of\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hg\n", | |
" og\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub od oe\n", | |
" oh\u001b[35m:f32[1,1,1,256]\u001b[39m = add of 9.999999747378752e-06\n", | |
" oi\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt oh\n", | |
" oj\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fi\n", | |
" ok\u001b[35m:f32[1,1,1,256]\u001b[39m = mul oi oj\n", | |
" ol\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul og ok\n", | |
" om\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fh\n", | |
" on\u001b[35m:f32[1000,14,14,256]\u001b[39m = add ol om\n", | |
" oo\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; op\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moq\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; or\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mos\u001b[35m:f32[1000,14,14,256]\u001b[39m = max or 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(os,) }\n", | |
" name=relu\n", | |
" ] op\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oq,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e9e0>\n", | |
" num_consts=0\n", | |
" ] on\n", | |
" ot\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] oo fs\n", | |
" ou\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hh\n", | |
" ov\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hi\n", | |
" ow\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub ot ou\n", | |
" ox\u001b[35m:f32[1,1,1,256]\u001b[39m = add ov 9.999999747378752e-06\n", | |
" oy\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt ox\n", | |
" oz\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fk\n", | |
" pa\u001b[35m:f32[1,1,1,256]\u001b[39m = mul oy oz\n", | |
" pb\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul ow pa\n", | |
" pc\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fj\n", | |
" pd\u001b[35m:f32[1000,14,14,256]\u001b[39m = add pb pc\n", | |
" pe\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 28, 28, 128)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 128, 256)\n", | |
" window_strides=(2, 2)\n", | |
" ] ny ft\n", | |
" pf\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hj\n", | |
" pg\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hk\n", | |
" ph\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub pe pf\n", | |
" pi\u001b[35m:f32[1,1,1,256]\u001b[39m = add pg 9.999999747378752e-06\n", | |
" pj\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt pi\n", | |
" pk\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fm\n", | |
" pl\u001b[35m:f32[1,1,1,256]\u001b[39m = mul pj pk\n", | |
" pm\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul ph pl\n", | |
" pn\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fl\n", | |
" po\u001b[35m:f32[1000,14,14,256]\u001b[39m = add pm pn\n", | |
" pp\u001b[35m:f32[1000,14,14,256]\u001b[39m = add pd po\n", | |
" pq\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; pr\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mps\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; pt\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mpu\u001b[35m:f32[1000,14,14,256]\u001b[39m = max pt 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(pu,) }\n", | |
" name=relu\n", | |
" ] pr\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ps,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a1e7f80>\n", | |
" num_consts=0\n", | |
" ] pp\n", | |
" pv\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] pq fu\n", | |
" pw\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hl\n", | |
" px\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hm\n", | |
" py\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub pv pw\n", | |
" pz\u001b[35m:f32[1,1,1,256]\u001b[39m = add px 9.999999747378752e-06\n", | |
" qa\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt pz\n", | |
" qb\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fo\n", | |
" qc\u001b[35m:f32[1,1,1,256]\u001b[39m = mul qa qb\n", | |
" qd\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul py qc\n", | |
" qe\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fn\n", | |
" qf\u001b[35m:f32[1000,14,14,256]\u001b[39m = add qd qe\n", | |
" qg\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qh\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqi\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qj\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqk\u001b[35m:f32[1000,14,14,256]\u001b[39m = max qj 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qk,) }\n", | |
" name=relu\n", | |
" ] qh\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qi,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e710>\n", | |
" num_consts=0\n", | |
" ] qf\n", | |
" ql\u001b[35m:f32[1000,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] qg fv\n", | |
" qm\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] hn\n", | |
" qn\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] ho\n", | |
" qo\u001b[35m:f32[1000,14,14,256]\u001b[39m = sub ql qm\n", | |
" qp\u001b[35m:f32[1,1,1,256]\u001b[39m = add qn 9.999999747378752e-06\n", | |
" qq\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt qp\n", | |
" qr\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fq\n", | |
" qs\u001b[35m:f32[1,1,1,256]\u001b[39m = mul qq qr\n", | |
" qt\u001b[35m:f32[1000,14,14,256]\u001b[39m = mul qo qs\n", | |
" qu\u001b[35m:f32[1,1,1,256]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 256)] fp\n", | |
" qv\u001b[35m:f32[1000,14,14,256]\u001b[39m = add qt qu\n", | |
" qw\u001b[35m:f32[1000,14,14,256]\u001b[39m = add qv pq\n", | |
" qx\u001b[35m:f32[1000,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qy\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqz\u001b[35m:f32[1000,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ra\u001b[35m:f32[1000,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mrb\u001b[35m:f32[1000,14,14,256]\u001b[39m = max ra 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(rb,) }\n", | |
" name=relu\n", | |
" ] qy\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qz,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a1e73b0>\n", | |
" num_consts=0\n", | |
" ] qw\n", | |
" rc\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 512)\n", | |
" window_strides=(2, 2)\n", | |
" ] qx gg\n", | |
" rd\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hp\n", | |
" re\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hq\n", | |
" rf\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub rc rd\n", | |
" rg\u001b[35m:f32[1,1,1,512]\u001b[39m = add re 9.999999747378752e-06\n", | |
" rh\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt rg\n", | |
" ri\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fx\n", | |
" rj\u001b[35m:f32[1,1,1,512]\u001b[39m = mul rh ri\n", | |
" rk\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul rf rj\n", | |
" rl\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fw\n", | |
" rm\u001b[35m:f32[1000,7,7,512]\u001b[39m = add rk rl\n", | |
" rn\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ro\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mrp\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; rq\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mrr\u001b[35m:f32[1000,7,7,512]\u001b[39m = max rq 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(rr,) }\n", | |
" name=relu\n", | |
" ] ro\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(rp,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e170>\n", | |
" num_consts=0\n", | |
" ] rm\n", | |
" rs\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] rn gh\n", | |
" rt\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hr\n", | |
" ru\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hs\n", | |
" rv\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub rs rt\n", | |
" rw\u001b[35m:f32[1,1,1,512]\u001b[39m = add ru 9.999999747378752e-06\n", | |
" rx\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt rw\n", | |
" ry\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fz\n", | |
" rz\u001b[35m:f32[1,1,1,512]\u001b[39m = mul rx ry\n", | |
" sa\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul rv rz\n", | |
" sb\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] fy\n", | |
" sc\u001b[35m:f32[1000,7,7,512]\u001b[39m = add sa sb\n", | |
" sd\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 14, 14, 256)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 256, 512)\n", | |
" window_strides=(2, 2)\n", | |
" ] qx gi\n", | |
" se\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] ht\n", | |
" sf\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hu\n", | |
" sg\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub sd se\n", | |
" sh\u001b[35m:f32[1,1,1,512]\u001b[39m = add sf 9.999999747378752e-06\n", | |
" si\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt sh\n", | |
" sj\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gb\n", | |
" sk\u001b[35m:f32[1,1,1,512]\u001b[39m = mul si sj\n", | |
" sl\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul sg sk\n", | |
" sm\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] ga\n", | |
" sn\u001b[35m:f32[1000,7,7,512]\u001b[39m = add sl sm\n", | |
" so\u001b[35m:f32[1000,7,7,512]\u001b[39m = add sc sn\n", | |
" sp\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; sq\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22msr\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ss\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mst\u001b[35m:f32[1000,7,7,512]\u001b[39m = max ss 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(st,) }\n", | |
" name=relu\n", | |
" ] sq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(sr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1a8bf7e0e0>\n", | |
" num_consts=0\n", | |
" ] so\n", | |
" su\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] sp gj\n", | |
" sv\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hv\n", | |
" sw\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hw\n", | |
" sx\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub su sv\n", | |
" sy\u001b[35m:f32[1,1,1,512]\u001b[39m = add sw 9.999999747378752e-06\n", | |
" sz\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt sy\n", | |
" ta\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gd\n", | |
" tb\u001b[35m:f32[1,1,1,512]\u001b[39m = mul sz ta\n", | |
" tc\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul sx tb\n", | |
" td\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gc\n", | |
" te\u001b[35m:f32[1000,7,7,512]\u001b[39m = add tc td\n", | |
" tf\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; tg\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mth\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ti\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mtj\u001b[35m:f32[1000,7,7,512]\u001b[39m = max ti 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(tj,) }\n", | |
" name=relu\n", | |
" ] tg\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(th,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a1e75f0>\n", | |
" num_consts=0\n", | |
" ] te\n", | |
" tk\u001b[35m:f32[1000,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1000, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] tf gk\n", | |
" tl\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hx\n", | |
" tm\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] hy\n", | |
" tn\u001b[35m:f32[1000,7,7,512]\u001b[39m = sub tk tl\n", | |
" to\u001b[35m:f32[1,1,1,512]\u001b[39m = add tm 9.999999747378752e-06\n", | |
" tp\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt to\n", | |
" tq\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] gf\n", | |
" tr\u001b[35m:f32[1,1,1,512]\u001b[39m = mul tp tq\n", | |
" ts\u001b[35m:f32[1000,7,7,512]\u001b[39m = mul tn tr\n", | |
" tt\u001b[35m:f32[1,1,1,512]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1, 1, 512)] ge\n", | |
" tu\u001b[35m:f32[1000,7,7,512]\u001b[39m = add ts tt\n", | |
" tv\u001b[35m:f32[1000,7,7,512]\u001b[39m = add tu sp\n", | |
" tw\u001b[35m:f32[1000,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; tx\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mty\u001b[35m:f32[1000,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; tz\u001b[35m:f32[1000,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mua\u001b[35m:f32[1000,7,7,512]\u001b[39m = max tz 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ua,) }\n", | |
" name=relu\n", | |
" ] tx\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ty,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a1e7ef0>\n", | |
" num_consts=0\n", | |
" ] tv\n", | |
" ub\u001b[35m:f32[1000,512]\u001b[39m = reduce_sum[axes=(1, 2)] tw\n", | |
" uc\u001b[35m:f32[1000,512]\u001b[39m = div ub 49.0\n", | |
" ud\u001b[35m:f32[1000,1000]\u001b[39m = dot_general[\n", | |
" dimension_numbers=(((1,), (0,)), ((), ()))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" ] uc ef\n", | |
" ue\u001b[35m:f32[1,1000]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1000)] ee\n", | |
" uf\u001b[35m:f32[1000,1000]\u001b[39m = add ud ue\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(uf,) }\n", | |
" name=predict\n", | |
" ] a b c d e f g h i j k l m n o p q r s t u v w x y z ba bb bc bd be bf bg bh\n", | |
" bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb cc cd ce cf cg\n", | |
" ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz da db dc dd de df\n", | |
" dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(dz,) }" | |
] | |
}, | |
"metadata": {}, | |
"execution_count": 11 | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Let's load all images and copy them to GPU memory" | |
], | |
"metadata": { | |
"id": "H9ekpGpViINR" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": { | |
"id": "hIUOD0k4lot3" | |
}, | |
"outputs": [], | |
"source": [ | |
"all_images = []\n", | |
"for filename in sorted(os.listdir('./imgs')):\n", | |
" all_images.append(get_image(os.path.join('./imgs', filename)))\n", | |
"\n", | |
"all_images = jnp.array(all_images)\n", | |
"\n", | |
"all_images_dev = device_put(all_images)\n", | |
"params_dev = device_put(params)\n", | |
"batch_stats_dev = device_put(batch_stats)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Let's run some scenarios and check if we can have any speedup using GPU against CPU." | |
], | |
"metadata": { | |
"id": "7Z_aB8wRjGbO" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"First let's run it in CPU (if you are running this, it's a time to grab some coffee ;-))" | |
], | |
"metadata": { | |
"id": "TaClaYOcjRXB" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"cpu_time = %timeit -o -r 3 predict_cpu(all_images, params, batch_stats).block_until_ready()" | |
], | |
"metadata": { | |
"id": "jT3BDoVyjQbb" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Now let's try with GPU" | |
], | |
"metadata": { | |
"id": "_q_YjweopZwR" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"gpu_time = %timeit -o -r 3 predict_gpu(all_images_dev, params_dev, batch_stats_dev).block_until_ready()" | |
], | |
"metadata": { | |
"id": "uRW8_VQkfoPH" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "cttDh5qCW8nF" | |
}, | |
"outputs": [], | |
"source": [ | |
"plot_speedup({'cpu':cpu_time, 'gpu': gpu_time}, 'cpu')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Quite impressive eh?" | |
], | |
"metadata": { | |
"id": "dnRYqcNJs9K5" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Ok, but could we easily improve performance running on CPU?\n", | |
"\n", | |
"We can use `batching` with vmax. It splits the input in 1000 batches and run the input in a vectorized way." | |
], | |
"metadata": { | |
"id": "PkFQzuY-vuXC" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"predict_single_cpu = jit(predict_single, backend='cpu')\n", | |
"make_jaxpr(predict_single_cpu)(jnp.ones((224,224,3)))" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "miUJKs93gHop", | |
"outputId": "bed426f7-09c1-4125-f55a-93db51d5b214" | |
}, | |
"execution_count": 16, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"{ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22ma\u001b[35m:f32[7,7,3,64]\u001b[39m b\u001b[35m:f32[1,1,1,64]\u001b[39m c\u001b[35m:f32[1,1,1,64]\u001b[39m d\u001b[35m:f32[1,1,1,64]\u001b[39m e\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" f\u001b[35m:f32[3,3,64,64]\u001b[39m g\u001b[35m:f32[1,1,1,64]\u001b[39m h\u001b[35m:f32[1,1,1,64]\u001b[39m i\u001b[35m:f32[1,1,1,64]\u001b[39m j\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" k\u001b[35m:f32[3,3,64,64]\u001b[39m l\u001b[35m:f32[1,1,1,64]\u001b[39m m\u001b[35m:f32[1,1,1,64]\u001b[39m n\u001b[35m:f32[1,1,1,64]\u001b[39m o\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" p\u001b[35m:f32[3,3,64,64]\u001b[39m q\u001b[35m:f32[1,1,1,64]\u001b[39m r\u001b[35m:f32[1,1,1,64]\u001b[39m s\u001b[35m:f32[1,1,1,64]\u001b[39m t\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" u\u001b[35m:f32[3,3,64,64]\u001b[39m v\u001b[35m:f32[1,1,1,64]\u001b[39m w\u001b[35m:f32[1,1,1,64]\u001b[39m x\u001b[35m:f32[1,1,1,64]\u001b[39m y\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" z\u001b[35m:f32[3,3,64,128]\u001b[39m ba\u001b[35m:f32[1,1,1,128]\u001b[39m bb\u001b[35m:f32[1,1,1,128]\u001b[39m bc\u001b[35m:f32[1,1,1,128]\u001b[39m bd\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" be\u001b[35m:f32[3,3,128,128]\u001b[39m bf\u001b[35m:f32[1,1,1,128]\u001b[39m bg\u001b[35m:f32[1,1,1,128]\u001b[39m bh\u001b[35m:f32[1,1,1,128]\u001b[39m bi\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" bj\u001b[35m:f32[1,1,64,128]\u001b[39m bk\u001b[35m:f32[1,1,1,128]\u001b[39m bl\u001b[35m:f32[1,1,1,128]\u001b[39m bm\u001b[35m:f32[1,1,1,128]\u001b[39m bn\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" bo\u001b[35m:f32[3,3,128,128]\u001b[39m bp\u001b[35m:f32[1,1,1,128]\u001b[39m bq\u001b[35m:f32[1,1,1,128]\u001b[39m br\u001b[35m:f32[1,1,1,128]\u001b[39m bs\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" bt\u001b[35m:f32[3,3,128,128]\u001b[39m bu\u001b[35m:f32[1,1,1,128]\u001b[39m bv\u001b[35m:f32[1,1,1,128]\u001b[39m bw\u001b[35m:f32[1,1,1,128]\u001b[39m bx\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" by\u001b[35m:f32[3,3,128,256]\u001b[39m bz\u001b[35m:f32[1,1,1,256]\u001b[39m ca\u001b[35m:f32[1,1,1,256]\u001b[39m cb\u001b[35m:f32[1,1,1,256]\u001b[39m cc\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" cd\u001b[35m:f32[3,3,256,256]\u001b[39m ce\u001b[35m:f32[1,1,1,256]\u001b[39m cf\u001b[35m:f32[1,1,1,256]\u001b[39m cg\u001b[35m:f32[1,1,1,256]\u001b[39m ch\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" ci\u001b[35m:f32[1,1,128,256]\u001b[39m cj\u001b[35m:f32[1,1,1,256]\u001b[39m ck\u001b[35m:f32[1,1,1,256]\u001b[39m cl\u001b[35m:f32[1,1,1,256]\u001b[39m cm\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" cn\u001b[35m:f32[3,3,256,256]\u001b[39m co\u001b[35m:f32[1,1,1,256]\u001b[39m cp\u001b[35m:f32[1,1,1,256]\u001b[39m cq\u001b[35m:f32[1,1,1,256]\u001b[39m cr\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" cs\u001b[35m:f32[3,3,256,256]\u001b[39m ct\u001b[35m:f32[1,1,1,256]\u001b[39m cu\u001b[35m:f32[1,1,1,256]\u001b[39m cv\u001b[35m:f32[1,1,1,256]\u001b[39m cw\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" cx\u001b[35m:f32[3,3,256,512]\u001b[39m cy\u001b[35m:f32[1,1,1,512]\u001b[39m cz\u001b[35m:f32[1,1,1,512]\u001b[39m da\u001b[35m:f32[1,1,1,512]\u001b[39m db\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" dc\u001b[35m:f32[3,3,512,512]\u001b[39m dd\u001b[35m:f32[1,1,1,512]\u001b[39m de\u001b[35m:f32[1,1,1,512]\u001b[39m df\u001b[35m:f32[1,1,1,512]\u001b[39m dg\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" dh\u001b[35m:f32[1,1,256,512]\u001b[39m di\u001b[35m:f32[1,1,1,512]\u001b[39m dj\u001b[35m:f32[1,1,1,512]\u001b[39m dk\u001b[35m:f32[1,1,1,512]\u001b[39m dl\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" dm\u001b[35m:f32[3,3,512,512]\u001b[39m dn\u001b[35m:f32[1,1,1,512]\u001b[39m do\u001b[35m:f32[1,1,1,512]\u001b[39m dp\u001b[35m:f32[1,1,1,512]\u001b[39m dq\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" dr\u001b[35m:f32[3,3,512,512]\u001b[39m ds\u001b[35m:f32[1,1,1,512]\u001b[39m dt\u001b[35m:f32[1,1,1,512]\u001b[39m du\u001b[35m:f32[1,1,1,512]\u001b[39m dv\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" dw\u001b[35m:f32[512,1000]\u001b[39m dx\u001b[35m:f32[1000]\u001b[39m; dy\u001b[35m:f32[224,224,3]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mdz\u001b[35m:f32[1,1000]\u001b[39m = xla_call[\n", | |
" backend=cpu\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ea\u001b[35m:f32[7,7,3,64]\u001b[39m eb\u001b[35m:f32[1,1,1,64]\u001b[39m ec\u001b[35m:f32[1,1,1,64]\u001b[39m ed\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" ee\u001b[35m:f32[1,1,1,64]\u001b[39m ef\u001b[35m:f32[3,3,64,64]\u001b[39m eg\u001b[35m:f32[1,1,1,64]\u001b[39m eh\u001b[35m:f32[1,1,1,64]\u001b[39m ei\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" ej\u001b[35m:f32[1,1,1,64]\u001b[39m ek\u001b[35m:f32[3,3,64,64]\u001b[39m el\u001b[35m:f32[1,1,1,64]\u001b[39m em\u001b[35m:f32[1,1,1,64]\u001b[39m en\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" eo\u001b[35m:f32[1,1,1,64]\u001b[39m ep\u001b[35m:f32[3,3,64,64]\u001b[39m eq\u001b[35m:f32[1,1,1,64]\u001b[39m er\u001b[35m:f32[1,1,1,64]\u001b[39m es\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" et\u001b[35m:f32[1,1,1,64]\u001b[39m eu\u001b[35m:f32[3,3,64,64]\u001b[39m ev\u001b[35m:f32[1,1,1,64]\u001b[39m ew\u001b[35m:f32[1,1,1,64]\u001b[39m ex\u001b[35m:f32[1,1,1,64]\u001b[39m\n", | |
" ey\u001b[35m:f32[1,1,1,64]\u001b[39m ez\u001b[35m:f32[3,3,64,128]\u001b[39m fa\u001b[35m:f32[1,1,1,128]\u001b[39m fb\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" fc\u001b[35m:f32[1,1,1,128]\u001b[39m fd\u001b[35m:f32[1,1,1,128]\u001b[39m fe\u001b[35m:f32[3,3,128,128]\u001b[39m ff\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" fg\u001b[35m:f32[1,1,1,128]\u001b[39m fh\u001b[35m:f32[1,1,1,128]\u001b[39m fi\u001b[35m:f32[1,1,1,128]\u001b[39m fj\u001b[35m:f32[1,1,64,128]\u001b[39m\n", | |
" fk\u001b[35m:f32[1,1,1,128]\u001b[39m fl\u001b[35m:f32[1,1,1,128]\u001b[39m fm\u001b[35m:f32[1,1,1,128]\u001b[39m fn\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" fo\u001b[35m:f32[3,3,128,128]\u001b[39m fp\u001b[35m:f32[1,1,1,128]\u001b[39m fq\u001b[35m:f32[1,1,1,128]\u001b[39m fr\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" fs\u001b[35m:f32[1,1,1,128]\u001b[39m ft\u001b[35m:f32[3,3,128,128]\u001b[39m fu\u001b[35m:f32[1,1,1,128]\u001b[39m fv\u001b[35m:f32[1,1,1,128]\u001b[39m\n", | |
" fw\u001b[35m:f32[1,1,1,128]\u001b[39m fx\u001b[35m:f32[1,1,1,128]\u001b[39m fy\u001b[35m:f32[3,3,128,256]\u001b[39m fz\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" ga\u001b[35m:f32[1,1,1,256]\u001b[39m gb\u001b[35m:f32[1,1,1,256]\u001b[39m gc\u001b[35m:f32[1,1,1,256]\u001b[39m gd\u001b[35m:f32[3,3,256,256]\u001b[39m\n", | |
" ge\u001b[35m:f32[1,1,1,256]\u001b[39m gf\u001b[35m:f32[1,1,1,256]\u001b[39m gg\u001b[35m:f32[1,1,1,256]\u001b[39m gh\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" gi\u001b[35m:f32[1,1,128,256]\u001b[39m gj\u001b[35m:f32[1,1,1,256]\u001b[39m gk\u001b[35m:f32[1,1,1,256]\u001b[39m gl\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" gm\u001b[35m:f32[1,1,1,256]\u001b[39m gn\u001b[35m:f32[3,3,256,256]\u001b[39m go\u001b[35m:f32[1,1,1,256]\u001b[39m gp\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" gq\u001b[35m:f32[1,1,1,256]\u001b[39m gr\u001b[35m:f32[1,1,1,256]\u001b[39m gs\u001b[35m:f32[3,3,256,256]\u001b[39m gt\u001b[35m:f32[1,1,1,256]\u001b[39m\n", | |
" gu\u001b[35m:f32[1,1,1,256]\u001b[39m gv\u001b[35m:f32[1,1,1,256]\u001b[39m gw\u001b[35m:f32[1,1,1,256]\u001b[39m gx\u001b[35m:f32[3,3,256,512]\u001b[39m\n", | |
" gy\u001b[35m:f32[1,1,1,512]\u001b[39m gz\u001b[35m:f32[1,1,1,512]\u001b[39m ha\u001b[35m:f32[1,1,1,512]\u001b[39m hb\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" hc\u001b[35m:f32[3,3,512,512]\u001b[39m hd\u001b[35m:f32[1,1,1,512]\u001b[39m he\u001b[35m:f32[1,1,1,512]\u001b[39m hf\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" hg\u001b[35m:f32[1,1,1,512]\u001b[39m hh\u001b[35m:f32[1,1,256,512]\u001b[39m hi\u001b[35m:f32[1,1,1,512]\u001b[39m hj\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" hk\u001b[35m:f32[1,1,1,512]\u001b[39m hl\u001b[35m:f32[1,1,1,512]\u001b[39m hm\u001b[35m:f32[3,3,512,512]\u001b[39m hn\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" ho\u001b[35m:f32[1,1,1,512]\u001b[39m hp\u001b[35m:f32[1,1,1,512]\u001b[39m hq\u001b[35m:f32[1,1,1,512]\u001b[39m hr\u001b[35m:f32[3,3,512,512]\u001b[39m\n", | |
" hs\u001b[35m:f32[1,1,1,512]\u001b[39m ht\u001b[35m:f32[1,1,1,512]\u001b[39m hu\u001b[35m:f32[1,1,1,512]\u001b[39m hv\u001b[35m:f32[1,1,1,512]\u001b[39m\n", | |
" hw\u001b[35m:f32[512,1000]\u001b[39m hx\u001b[35m:f32[1000]\u001b[39m hy\u001b[35m:f32[224,224,3]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mhz\u001b[35m:f32[1,224,224,3]\u001b[39m = broadcast_in_dim[\n", | |
" broadcast_dimensions=(1, 2, 3)\n", | |
" shape=(1, 224, 224, 3)\n", | |
" ] hy\n", | |
" ia\u001b[35m:f32[1,112,112,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 224, 224, 3)\n", | |
" padding=((3, 3), (3, 3))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(7, 7, 3, 64)\n", | |
" window_strides=(2, 2)\n", | |
" ] hz ea\n", | |
" ib\u001b[35m:f32[1,112,112,64]\u001b[39m = sub ia eb\n", | |
" ic\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt ec\n", | |
" id\u001b[35m:f32[1,1,1,64]\u001b[39m = mul ic ed\n", | |
" ie\u001b[35m:f32[1,112,112,64]\u001b[39m = mul ib id\n", | |
" if\u001b[35m:f32[1,112,112,64]\u001b[39m = add ie ee\n", | |
" ig\u001b[35m:f32[1,112,112,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ih\u001b[35m:f32[1,112,112,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mii\u001b[35m:f32[1,112,112,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ij\u001b[35m:f32[1,112,112,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mik\u001b[35m:f32[1,112,112,64]\u001b[39m = max ij 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ik,) }\n", | |
" name=relu\n", | |
" ] ih\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ii,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9a148b00>\n", | |
" num_consts=0\n", | |
" ] if\n", | |
" il\u001b[35m:f32[1,56,56,64]\u001b[39m = reduce_window_max[\n", | |
" base_dilation=(1, 1, 1, 1)\n", | |
" padding=((0, 0), (1, 1), (1, 1), (0, 0))\n", | |
" window_dilation=(1, 1, 1, 1)\n", | |
" window_dimensions=(1, 3, 3, 1)\n", | |
" window_strides=(1, 2, 2, 1)\n", | |
" ] ig\n", | |
" im\u001b[35m:f32[1,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] il ef\n", | |
" in\u001b[35m:f32[1,56,56,64]\u001b[39m = sub im eg\n", | |
" io\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt eh\n", | |
" ip\u001b[35m:f32[1,1,1,64]\u001b[39m = mul io ei\n", | |
" iq\u001b[35m:f32[1,56,56,64]\u001b[39m = mul in ip\n", | |
" ir\u001b[35m:f32[1,56,56,64]\u001b[39m = add iq ej\n", | |
" is\u001b[35m:f32[1,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; it\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22miu\u001b[35m:f32[1,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; iv\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22miw\u001b[35m:f32[1,56,56,64]\u001b[39m = max iv 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(iw,) }\n", | |
" name=relu\n", | |
" ] it\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(iu,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9036fdd0>\n", | |
" num_consts=0\n", | |
" ] ir\n", | |
" ix\u001b[35m:f32[1,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] is ek\n", | |
" iy\u001b[35m:f32[1,56,56,64]\u001b[39m = sub ix el\n", | |
" iz\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt em\n", | |
" ja\u001b[35m:f32[1,1,1,64]\u001b[39m = mul iz en\n", | |
" jb\u001b[35m:f32[1,56,56,64]\u001b[39m = mul iy ja\n", | |
" jc\u001b[35m:f32[1,56,56,64]\u001b[39m = add jb eo\n", | |
" jd\u001b[35m:f32[1,56,56,64]\u001b[39m = add jc il\n", | |
" je\u001b[35m:f32[1,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jf\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjg\u001b[35m:f32[1,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jh\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mji\u001b[35m:f32[1,56,56,64]\u001b[39m = max jh 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ji,) }\n", | |
" name=relu\n", | |
" ] jf\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jg,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9036fc20>\n", | |
" num_consts=0\n", | |
" ] jd\n", | |
" jj\u001b[35m:f32[1,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] je ep\n", | |
" jk\u001b[35m:f32[1,56,56,64]\u001b[39m = sub jj eq\n", | |
" jl\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt er\n", | |
" jm\u001b[35m:f32[1,1,1,64]\u001b[39m = mul jl es\n", | |
" jn\u001b[35m:f32[1,56,56,64]\u001b[39m = mul jk jm\n", | |
" jo\u001b[35m:f32[1,56,56,64]\u001b[39m = add jn et\n", | |
" jp\u001b[35m:f32[1,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; jq\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjr\u001b[35m:f32[1,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; js\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mjt\u001b[35m:f32[1,56,56,64]\u001b[39m = max js 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jt,) }\n", | |
" name=relu\n", | |
" ] jq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(jr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9036fd40>\n", | |
" num_consts=0\n", | |
" ] jo\n", | |
" ju\u001b[35m:f32[1,56,56,64]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 64)\n", | |
" window_strides=(1, 1)\n", | |
" ] jp eu\n", | |
" jv\u001b[35m:f32[1,56,56,64]\u001b[39m = sub ju ev\n", | |
" jw\u001b[35m:f32[1,1,1,64]\u001b[39m = rsqrt ew\n", | |
" jx\u001b[35m:f32[1,1,1,64]\u001b[39m = mul jw ex\n", | |
" jy\u001b[35m:f32[1,56,56,64]\u001b[39m = mul jv jx\n", | |
" jz\u001b[35m:f32[1,56,56,64]\u001b[39m = add jy ey\n", | |
" ka\u001b[35m:f32[1,56,56,64]\u001b[39m = add jz je\n", | |
" kb\u001b[35m:f32[1,56,56,64]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; kc\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mkd\u001b[35m:f32[1,56,56,64]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ke\u001b[35m:f32[1,56,56,64]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mkf\u001b[35m:f32[1,56,56,64]\u001b[39m = max ke 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(kf,) }\n", | |
" name=relu\n", | |
" ] kc\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(kd,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e9036fe60>\n", | |
" num_consts=0\n", | |
" ] ka\n", | |
" kg\u001b[35m:f32[1,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 56, 56, 64)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 64, 128)\n", | |
" window_strides=(2, 2)\n", | |
" ] kb ez\n", | |
" kh\u001b[35m:f32[1,28,28,128]\u001b[39m = sub kg fa\n", | |
" ki\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt fb\n", | |
" kj\u001b[35m:f32[1,1,1,128]\u001b[39m = mul ki fc\n", | |
" kk\u001b[35m:f32[1,28,28,128]\u001b[39m = mul kh kj\n", | |
" kl\u001b[35m:f32[1,28,28,128]\u001b[39m = add kk fd\n", | |
" km\u001b[35m:f32[1,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; kn\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mko\u001b[35m:f32[1,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; kp\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mkq\u001b[35m:f32[1,28,28,128]\u001b[39m = max kp 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(kq,) }\n", | |
" name=relu\n", | |
" ] kn\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ko,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e903400e0>\n", | |
" num_consts=0\n", | |
" ] kl\n", | |
" kr\u001b[35m:f32[1,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] km fe\n", | |
" ks\u001b[35m:f32[1,28,28,128]\u001b[39m = sub kr ff\n", | |
" kt\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt fg\n", | |
" ku\u001b[35m:f32[1,1,1,128]\u001b[39m = mul kt fh\n", | |
" kv\u001b[35m:f32[1,28,28,128]\u001b[39m = mul ks ku\n", | |
" kw\u001b[35m:f32[1,28,28,128]\u001b[39m = add kv fi\n", | |
" kx\u001b[35m:f32[1,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 56, 56, 64)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 64, 128)\n", | |
" window_strides=(2, 2)\n", | |
" ] kb fj\n", | |
" ky\u001b[35m:f32[1,28,28,128]\u001b[39m = sub kx fk\n", | |
" kz\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt fl\n", | |
" la\u001b[35m:f32[1,1,1,128]\u001b[39m = mul kz fm\n", | |
" lb\u001b[35m:f32[1,28,28,128]\u001b[39m = mul ky la\n", | |
" lc\u001b[35m:f32[1,28,28,128]\u001b[39m = add lb fn\n", | |
" ld\u001b[35m:f32[1,28,28,128]\u001b[39m = add kw lc\n", | |
" le\u001b[35m:f32[1,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; lf\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlg\u001b[35m:f32[1,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; lh\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mli\u001b[35m:f32[1,28,28,128]\u001b[39m = max lh 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(li,) }\n", | |
" name=relu\n", | |
" ] lf\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lg,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340050>\n", | |
" num_consts=0\n", | |
" ] ld\n", | |
" lj\u001b[35m:f32[1,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] le fo\n", | |
" lk\u001b[35m:f32[1,28,28,128]\u001b[39m = sub lj fp\n", | |
" ll\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt fq\n", | |
" lm\u001b[35m:f32[1,1,1,128]\u001b[39m = mul ll fr\n", | |
" ln\u001b[35m:f32[1,28,28,128]\u001b[39m = mul lk lm\n", | |
" lo\u001b[35m:f32[1,28,28,128]\u001b[39m = add ln fs\n", | |
" lp\u001b[35m:f32[1,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; lq\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlr\u001b[35m:f32[1,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ls\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mlt\u001b[35m:f32[1,28,28,128]\u001b[39m = max ls 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lt,) }\n", | |
" name=relu\n", | |
" ] lq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(lr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340710>\n", | |
" num_consts=0\n", | |
" ] lo\n", | |
" lu\u001b[35m:f32[1,28,28,128]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 128)\n", | |
" window_strides=(1, 1)\n", | |
" ] lp ft\n", | |
" lv\u001b[35m:f32[1,28,28,128]\u001b[39m = sub lu fu\n", | |
" lw\u001b[35m:f32[1,1,1,128]\u001b[39m = rsqrt fv\n", | |
" lx\u001b[35m:f32[1,1,1,128]\u001b[39m = mul lw fw\n", | |
" ly\u001b[35m:f32[1,28,28,128]\u001b[39m = mul lv lx\n", | |
" lz\u001b[35m:f32[1,28,28,128]\u001b[39m = add ly fx\n", | |
" ma\u001b[35m:f32[1,28,28,128]\u001b[39m = add lz le\n", | |
" mb\u001b[35m:f32[1,28,28,128]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; mc\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmd\u001b[35m:f32[1,28,28,128]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; me\u001b[35m:f32[1,28,28,128]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmf\u001b[35m:f32[1,28,28,128]\u001b[39m = max me 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(mf,) }\n", | |
" name=relu\n", | |
" ] mc\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(md,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340560>\n", | |
" num_consts=0\n", | |
" ] ma\n", | |
" mg\u001b[35m:f32[1,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 28, 28, 128)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 128, 256)\n", | |
" window_strides=(2, 2)\n", | |
" ] mb fy\n", | |
" mh\u001b[35m:f32[1,14,14,256]\u001b[39m = sub mg fz\n", | |
" mi\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt ga\n", | |
" mj\u001b[35m:f32[1,1,1,256]\u001b[39m = mul mi gb\n", | |
" mk\u001b[35m:f32[1,14,14,256]\u001b[39m = mul mh mj\n", | |
" ml\u001b[35m:f32[1,14,14,256]\u001b[39m = add mk gc\n", | |
" mm\u001b[35m:f32[1,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; mn\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmo\u001b[35m:f32[1,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; mp\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mmq\u001b[35m:f32[1,14,14,256]\u001b[39m = max mp 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(mq,) }\n", | |
" name=relu\n", | |
" ] mn\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(mo,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340e60>\n", | |
" num_consts=0\n", | |
" ] ml\n", | |
" mr\u001b[35m:f32[1,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] mm gd\n", | |
" ms\u001b[35m:f32[1,14,14,256]\u001b[39m = sub mr ge\n", | |
" mt\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt gf\n", | |
" mu\u001b[35m:f32[1,1,1,256]\u001b[39m = mul mt gg\n", | |
" mv\u001b[35m:f32[1,14,14,256]\u001b[39m = mul ms mu\n", | |
" mw\u001b[35m:f32[1,14,14,256]\u001b[39m = add mv gh\n", | |
" mx\u001b[35m:f32[1,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 28, 28, 128)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 128, 256)\n", | |
" window_strides=(2, 2)\n", | |
" ] mb gi\n", | |
" my\u001b[35m:f32[1,14,14,256]\u001b[39m = sub mx gj\n", | |
" mz\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt gk\n", | |
" na\u001b[35m:f32[1,1,1,256]\u001b[39m = mul mz gl\n", | |
" nb\u001b[35m:f32[1,14,14,256]\u001b[39m = mul my na\n", | |
" nc\u001b[35m:f32[1,14,14,256]\u001b[39m = add nb gm\n", | |
" nd\u001b[35m:f32[1,14,14,256]\u001b[39m = add mw nc\n", | |
" ne\u001b[35m:f32[1,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; nf\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mng\u001b[35m:f32[1,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; nh\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mni\u001b[35m:f32[1,14,14,256]\u001b[39m = max nh 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ni,) }\n", | |
" name=relu\n", | |
" ] nf\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(ng,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340d40>\n", | |
" num_consts=0\n", | |
" ] nd\n", | |
" nj\u001b[35m:f32[1,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] ne gn\n", | |
" nk\u001b[35m:f32[1,14,14,256]\u001b[39m = sub nj go\n", | |
" nl\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt gp\n", | |
" nm\u001b[35m:f32[1,1,1,256]\u001b[39m = mul nl gq\n", | |
" nn\u001b[35m:f32[1,14,14,256]\u001b[39m = mul nk nm\n", | |
" no\u001b[35m:f32[1,14,14,256]\u001b[39m = add nn gr\n", | |
" np\u001b[35m:f32[1,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; nq\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mnr\u001b[35m:f32[1,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ns\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mnt\u001b[35m:f32[1,14,14,256]\u001b[39m = max ns 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(nt,) }\n", | |
" name=relu\n", | |
" ] nq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(nr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340950>\n", | |
" num_consts=0\n", | |
" ] no\n", | |
" nu\u001b[35m:f32[1,14,14,256]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 256)\n", | |
" window_strides=(1, 1)\n", | |
" ] np gs\n", | |
" nv\u001b[35m:f32[1,14,14,256]\u001b[39m = sub nu gt\n", | |
" nw\u001b[35m:f32[1,1,1,256]\u001b[39m = rsqrt gu\n", | |
" nx\u001b[35m:f32[1,1,1,256]\u001b[39m = mul nw gv\n", | |
" ny\u001b[35m:f32[1,14,14,256]\u001b[39m = mul nv nx\n", | |
" nz\u001b[35m:f32[1,14,14,256]\u001b[39m = add ny gw\n", | |
" oa\u001b[35m:f32[1,14,14,256]\u001b[39m = add nz ne\n", | |
" ob\u001b[35m:f32[1,14,14,256]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; oc\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mod\u001b[35m:f32[1,14,14,256]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; oe\u001b[35m:f32[1,14,14,256]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mof\u001b[35m:f32[1,14,14,256]\u001b[39m = max oe 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(of,) }\n", | |
" name=relu\n", | |
" ] oc\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(od,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e903407a0>\n", | |
" num_consts=0\n", | |
" ] oa\n", | |
" og\u001b[35m:f32[1,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 14, 14, 256)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 256, 512)\n", | |
" window_strides=(2, 2)\n", | |
" ] ob gx\n", | |
" oh\u001b[35m:f32[1,7,7,512]\u001b[39m = sub og gy\n", | |
" oi\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt gz\n", | |
" oj\u001b[35m:f32[1,1,1,512]\u001b[39m = mul oi ha\n", | |
" ok\u001b[35m:f32[1,7,7,512]\u001b[39m = mul oh oj\n", | |
" ol\u001b[35m:f32[1,7,7,512]\u001b[39m = add ok hb\n", | |
" om\u001b[35m:f32[1,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; on\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moo\u001b[35m:f32[1,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; op\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22moq\u001b[35m:f32[1,7,7,512]\u001b[39m = max op 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oq,) }\n", | |
" name=relu\n", | |
" ] on\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(oo,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340cb0>\n", | |
" num_consts=0\n", | |
" ] ol\n", | |
" or\u001b[35m:f32[1,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] om hc\n", | |
" os\u001b[35m:f32[1,7,7,512]\u001b[39m = sub or hd\n", | |
" ot\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt he\n", | |
" ou\u001b[35m:f32[1,1,1,512]\u001b[39m = mul ot hf\n", | |
" ov\u001b[35m:f32[1,7,7,512]\u001b[39m = mul os ou\n", | |
" ow\u001b[35m:f32[1,7,7,512]\u001b[39m = add ov hg\n", | |
" ox\u001b[35m:f32[1,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 14, 14, 256)\n", | |
" padding=((0, 0), (0, 0))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(1, 1, 256, 512)\n", | |
" window_strides=(2, 2)\n", | |
" ] ob hh\n", | |
" oy\u001b[35m:f32[1,7,7,512]\u001b[39m = sub ox hi\n", | |
" oz\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt hj\n", | |
" pa\u001b[35m:f32[1,1,1,512]\u001b[39m = mul oz hk\n", | |
" pb\u001b[35m:f32[1,7,7,512]\u001b[39m = mul oy pa\n", | |
" pc\u001b[35m:f32[1,7,7,512]\u001b[39m = add pb hl\n", | |
" pd\u001b[35m:f32[1,7,7,512]\u001b[39m = add ow pc\n", | |
" pe\u001b[35m:f32[1,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; pf\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mpg\u001b[35m:f32[1,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ph\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mpi\u001b[35m:f32[1,7,7,512]\u001b[39m = max ph 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(pi,) }\n", | |
" name=relu\n", | |
" ] pf\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(pg,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e903408c0>\n", | |
" num_consts=0\n", | |
" ] pd\n", | |
" pj\u001b[35m:f32[1,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] pe hm\n", | |
" pk\u001b[35m:f32[1,7,7,512]\u001b[39m = sub pj hn\n", | |
" pl\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt ho\n", | |
" pm\u001b[35m:f32[1,1,1,512]\u001b[39m = mul pl hp\n", | |
" pn\u001b[35m:f32[1,7,7,512]\u001b[39m = mul pk pm\n", | |
" po\u001b[35m:f32[1,7,7,512]\u001b[39m = add pn hq\n", | |
" pp\u001b[35m:f32[1,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; pq\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mpr\u001b[35m:f32[1,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; ps\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mpt\u001b[35m:f32[1,7,7,512]\u001b[39m = max ps 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(pt,) }\n", | |
" name=relu\n", | |
" ] pq\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(pr,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340830>\n", | |
" num_consts=0\n", | |
" ] po\n", | |
" pu\u001b[35m:f32[1,7,7,512]\u001b[39m = conv_general_dilated[\n", | |
" batch_group_count=1\n", | |
" dimension_numbers=ConvDimensionNumbers(lhs_spec=(0, 3, 1, 2), rhs_spec=(3, 2, 0, 1), out_spec=(0, 3, 1, 2))\n", | |
" feature_group_count=1\n", | |
" lhs_dilation=(1, 1)\n", | |
" lhs_shape=(1, 7, 7, 512)\n", | |
" padding=((1, 1), (1, 1))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" rhs_dilation=(1, 1)\n", | |
" rhs_shape=(3, 3, 512, 512)\n", | |
" window_strides=(1, 1)\n", | |
" ] pp hr\n", | |
" pv\u001b[35m:f32[1,7,7,512]\u001b[39m = sub pu hs\n", | |
" pw\u001b[35m:f32[1,1,1,512]\u001b[39m = rsqrt ht\n", | |
" px\u001b[35m:f32[1,1,1,512]\u001b[39m = mul pw hu\n", | |
" py\u001b[35m:f32[1,7,7,512]\u001b[39m = mul pv px\n", | |
" pz\u001b[35m:f32[1,7,7,512]\u001b[39m = add py hv\n", | |
" qa\u001b[35m:f32[1,7,7,512]\u001b[39m = add pz pe\n", | |
" qb\u001b[35m:f32[1,7,7,512]\u001b[39m = custom_jvp_call_jaxpr[\n", | |
" fun_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qc\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqd\u001b[35m:f32[1,7,7,512]\u001b[39m = xla_call[\n", | |
" call_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; qe\u001b[35m:f32[1,7,7,512]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n", | |
" \u001b[39m\u001b[22m\u001b[22mqf\u001b[35m:f32[1,7,7,512]\u001b[39m = max qe 0.0\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qf,) }\n", | |
" name=relu\n", | |
" ] qc\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qd,) }\n", | |
" jvp_jaxpr_thunk=<function _memoize.<locals>.memoized at 0x7f1e90340ef0>\n", | |
" num_consts=0\n", | |
" ] qa\n", | |
" qg\u001b[35m:f32[1,512]\u001b[39m = reduce_sum[axes=(1, 2)] qb\n", | |
" qh\u001b[35m:f32[1,512]\u001b[39m = div qg 49.0\n", | |
" qi\u001b[35m:f32[1,1000]\u001b[39m = dot_general[\n", | |
" dimension_numbers=(((1,), (0,)), ((), ()))\n", | |
" precision=None\n", | |
" preferred_element_type=None\n", | |
" ] qh hw\n", | |
" qj\u001b[35m:f32[1,1000]\u001b[39m = reshape[dimensions=None new_sizes=(1, 1000)] hx\n", | |
" qk\u001b[35m:f32[1,1000]\u001b[39m = add qi qj\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(qk,) }\n", | |
" name=predict_single\n", | |
" ] a b c d e f g h i j k l m n o p q r s t u v w x y z ba bb bc bd be bf bg bh\n", | |
" bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb cc cd ce cf cg\n", | |
" ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz da db dc dd de df\n", | |
" dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy\n", | |
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(dz,) }" | |
] | |
}, | |
"metadata": {}, | |
"execution_count": 16 | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"vmap_time = %timeit -o -r 3 vmap(predict_single_cpu)(all_images)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "Zem81xRnga9-", | |
"outputId": "af28a9ec-7a88-499c-bb35-025b04cc0e56" | |
}, | |
"execution_count": 17, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"1 loop, best of 3: 1min 23s per loop\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"plot_speedup({'cpu': cpu_time, 'vmap_cpu': vmap_time,}, 'cpu')" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 265 | |
}, | |
"id": "p4BWYWw90aKe", | |
"outputId": "b0646339-9e7e-4f3d-d18e-95c8729e6a59" | |
}, | |
"execution_count": 18, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
], | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAD4CAYAAADhNOGaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAASiElEQVR4nO3df7DddX3n8eeLxJAVRaYkWEgIN5TUSmvEcBctZVr80d3wozC7gIa2iuKQdVf8Mba70m2lDB1nKW5l6goodpEOHcCgDmYxirUqVoqW8FPADQ1Bm4QfgiBLBYLB9/5xDvZwuffmEPK9N7mf52Pmzj2f7+fz/Z73yXxzX+f743xOqgpJUrt2m+4CJEnTyyCQpMYZBJLUOINAkhpnEEhS42ZPdwHP17x582pkZGS6y5CkXcqNN974UFXNH69vlwuCkZER1q5dO91lSNIuJckPJurz1JAkNc4gkKTGGQS7uPe+9728/OUvJwnHHnvshOOuu+46li5dyu67786yZcu46aabft531VVXcdBBBzF37lyOPPJI7rnnnqkoXQ1xP925GQQzwIoVKybtf/LJJznhhBN47LHHOO+883jggQc48cQTefrpp7n//vtZsWIFe+65Jx/5yEe48cYbOeWUU6aocrXE/XQnVlW71M+hhx5aerZ77rmngDrmmGPG7f/85z9fQJ177rlVVfWhD32ogPrqV79aH/3oRwuoVatWVVXVW9/61gJq/fr1ddJJJ9Xs2bPrtttuq+uvv7522223OvXUU6fsdWlmcT+dXsDamuDv6i5315Cev2cOoRcsWADAwoULAdiwYcOkfRdccAHXXnstp512Gj/5yU9YsGAB55133lSXr0a4n06fzoIgycXAscAPq+rXxukP8JfA0cDjwNur6qax47Tj1SQzzg72zZs3jwsvvJATTjgBgGuuuYY999yz8/okcD+dSl1eI7gEWD5J/1HAkv7PSuDCDmtpzpYtW9iyZQsAixcvBmDTpk0AbN68GYADDzxw0j6A++677+fbvP/++6egcrXE/XQnMdE5ox3xA4wAt0/Q90ng5IH2OmDfbW3TawTPdvXVV9c555xTQC1durQ+9alP1V133VUHHHBA7bHHHlVV9cQTT9Q+++xTIyMjdcEFF9R+++1XIyMjtXXr1rr33ntrzpw5tWzZsvrY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\n" | |
}, | |
"metadata": { | |
"needs_background": "light" | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"It does not seem effective. Probably Flax already does that behind the scenes.\n", | |
"\n", | |
"Something important we still need to consider is if we would like to predict 1000 images in a naive python loop this would take **very** long. Do not believe me, take a look on this:" | |
], | |
"metadata": { | |
"id": "5WIO4iG0IQid" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"results = []\n", | |
"\n", | |
"def naive_py_loop(images):\n", | |
" for image in images:\n", | |
" predict_single(image)\n", | |
"\n", | |
"naive_python_loop_time = %timeit -o -r 3 naive_py_loop(all_images)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "gbPn4rUPJTIZ", | |
"outputId": "bda7df08-2a75-40dd-bb05-7b59f1fb977f" | |
}, | |
"execution_count": 19, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"1 loop, best of 3: 9min 33s per loop\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"plot_speedup({'naive_python_loop': naive_python_loop_time, 'vmap_cpu': vmap_time,}, 'naive_python_loop')" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 266 | |
}, | |
"id": "5NdqMf09Jtxm", | |
"outputId": "b530fe3b-429a-4bb5-a112-25c2a4a5bf95" | |
}, | |
"execution_count": 20, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
], | |
"image/png": "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\n" | |
}, | |
"metadata": { | |
"needs_background": "light" | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"So that means `vmap` makes predictions too much faster because of vectorization of the input.\n", | |
"\n", | |
"The most interesting thing in Jax is how it makes easy and transparent to use GPU or vectorization. \n", | |
"\n", | |
"It is also possible paralelize it in multiple devices with pmap, but unfortenetelly Colab has only one GPU in free tier so we won't be able to apply pmap." | |
], | |
"metadata": { | |
"id": "mOLXuZtVLIle" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Verifying accuracy\n", | |
"\n", | |
"We got same accuracy as expected in previous work. This means Flax implementation does not reduced accuracy." | |
], | |
"metadata": { | |
"id": "G0vzKPrUcSEY" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"ground_truth = [490,361,171,822,297,482,13,704,599,164,649,11,73,286,554,6,648,399,749,545,13,204,318,693,399,304,102,207,480,780,644,275,14,954,249,790,501,547,809,606,297,927,424,156,60,983,256,207,281,456,413,498,561,750,182,267,118,893,597,840,836,107,647,471,945,451,214,790,291,837,707,193,397,568,401,705,200,202,31,949,361,98,709,483,563,695,122,497,914,476,102,199,104,221,138,257,188,436,229,52,377,200,597,544,131,935,602,342,508,748,617,901,184,513,204,999,782,922,869,598,596,701,970,452,631,817,57,398,885,10,288,305,34,112,273,120,959,657,823,356,32,657,753,372,364,349,106,513,551,366,228,917,464,655,737,58,62,219,832,922,192,303,946,996,737,333,729,824,517,89,724,2,829,172,266,123,434,149,39,171,44,662,734,782,270,153,283,58,217,581,170,306,689,753,613,454,885,392,316,956,527,817,47,223,516,100,441,659,803,297,95,343,576,367,576,330,392,609,961,143,818,764,377,192,494,820,150,204,460,769,620,800,153,683,365,450,207,616,985,994,315,104,595,541,620,52,389,45,756,303,328,901,991,290,982,821,914,496,984,976,711,450,66,564,584,549,844,540,3,361,680,718,44,861,578,496,588,413,27,669,294,961,10,334,935,819,518,235,246,528,825,381,449,289,684,682,468,489,601,66,658,673,76,886,750,162,450,592,885,379,955,447,360,920,341,451,994,400,215,229,543,44,67,490,809,40,42,397,383,720,668,738,143,923,843,820,485,790,529,37,848,626,186,761,593,301,239,206,775,113,912,576,890,296,168,425,270,719,988,504,621,462,428,917,284,833,573,769,231,412,649,703,564,346,176,827,559,999,91,794,220,717,97,374,973,647,696,341,429,428,88,539,171,368,606,608,970,199,151,967,40,241,243,458,21,734,224,329,102,696,109,329,574,390,418,555,547,639,879,413,310,752,735,98,106,782,814,841,107,599,267,267,969,284,818,123,723,888,392,109,31,938,744,9,995,44,44,344,312,172,659,285,997,572,709,162,87,566,847,714,740,99,743,675,783,421,346,542,541,435,464,956,570,72,682,394,581,147,349,40,169,317,733,331,545,137,11,764,789,714,830,441,966,767,100,6,502,495,547,31,102,53,315,834,592,301,141,507,848,625,18,481,766,839,542,671,62,74,661,175,351,692,464,191,700,766,747,401,982,205,114,695,68,670,957,168,382,906,196,915,473,799,864,263,22,654,420,437,506,776,358,162,96,739,349,238,929,580,234,257,710,887,729,370,101,827,780,590,733,387,238,900,882,974,562,407,428,193,711,548,645,370,794,718,74,795,904,126,373,179,694,163,424,115,247,539,194,819,132,85,252,786,184,155,323,900,963,781,6,30,289,145,198,355,938,329,157,645,955,793,542,809,247,808,622,722,978,215,950,999,230,331,704,779,130,562,545,392,640,508,757,101,94,129,372,999,980,429,585,85,386,596,970,777,216,783,169,148,269,228,147,227,252,244,5,544,219,139,612,686,282,128,355,742,183,923,552,376,610,691,352,572,471,892,188,773,905,487,656,422,324,627,683,72,73,59,992,667,455,251,828,596,656,574,893,967,541,154,8,338,320,666,389,287,687,94,277,670,46,267,907,964,48,689,27,16,318,813,15,865,913,567,10,748,424,342,664,695,397,707,750,813,919,418,958,249,386,26,492,797,435,293,693,214,878,1,830,115,307,697,821,705,940,279,857,910,278,621,808,571,845,635,948,424,447,802,313,681,35,911,652,953,508,283,155,486,905,96,813,540,459,952,920,427,882,55,665,325,131,151,823,158,511,307,831,482,496,872,700,642,885,686,705,333,535,816,598,615,627,873,616,564,865,146,431,675,552,37,249,553,749,210,882,926,551,651,395,161,714,381,595,340,593,352,802,511,47,797,687,755,896,725,277,899,988,895,557,819,852,402,572,554,734,691,163,928,49,244,331,96,61,693,388,765,145,505,602,424,706,393,745,158,119,32,401,740,375,397,156,494,975,39,548,541,874,706,577,201,766,770,237,750,932,543,563,805,116,466,32,659,383,205,236,780,698,399,533,455,554,571,445,145,854,626,471,624,511,793,412,459,286,677,451,608,545,986,188,459,425,217,481,512,610,500,137,211,297,200,59,873,682,417,254,886,597,623,348,458,593,564,677,396,394,135,640,245,893,381,560,213,544,631,874,96,140,270,744,468,752,774,164,836,34,867,930,609,781,919,329,657,565,161,3,450,932,452,50,264,536,301]\n", | |
"glow_results = [490,590,171,822,298,493,13,970,599,87,649,11,73,286,554,6,450,397,749,545,13,189,318,693,399,304,102,18,489,897,644,275,212,954,249,790,495,547,809,629,296,927,424,123,60,659,256,132,267,809,639,498,561,750,40,267,69,893,856,840,836,144,647,471,945,451,214,790,291,968,278,193,397,568,401,710,200,202,31,949,361,98,709,654,274,695,166,497,914,476,102,75,104,221,138,257,188,436,229,52,377,200,597,544,131,848,602,343,508,845,617,320,184,570,132,999,782,512,548,598,689,701,970,455,328,794,57,397,885,10,288,556,34,64,273,183,370,657,823,49,32,657,753,372,364,992,117,513,551,367,228,917,464,655,737,136,62,219,832,922,211,317,946,996,737,333,729,824,517,89,724,2,829,172,266,109,434,15,39,171,186,662,734,985,270,153,283,58,217,939,140,306,689,753,613,454,885,392,316,956,527,854,47,804,978,100,441,659,803,966,95,343,576,367,576,330,392,609,961,143,818,764,377,125,494,756,150,253,460,769,620,280,153,683,365,655,207,616,712,994,315,104,595,356,620,52,389,45,756,677,328,779,991,290,982,821,914,496,984,125,786,498,66,564,584,549,844,540,172,359,680,718,185,861,742,496,975,413,63,669,294,961,10,334,817,373,518,235,246,529,759,555,449,289,684,596,473,489,601,66,656,771,85,886,879,162,450,592,885,530,955,443,360,271,702,451,232,400,215,754,543,44,67,490,809,40,154,397,383,720,726,738,143,923,843,820,486,790,914,37,848,626,186,761,534,300,239,206,775,189,904,576,890,296,168,425,270,366,988,14,621,462,428,723,284,833,573,769,246,412,649,710,564,346,176,827,291,999,210,562,220,717,97,374,306,647,550,341,426,428,88,539,171,368,606,608,807,989,151,967,40,241,243,458,21,734,224,331,102,696,109,329,826,390,418,555,547,639,573,413,310,752,735,98,49,977,304,841,107,599,267,285,939,284,818,123,248,943,392,109,33,819,744,9,995,44,44,344,312,141,659,285,997,572,709,473,87,566,943,714,740,99,743,675,811,421,346,251,347,435,464,956,570,72,682,394,581,147,349,182,169,317,733,329,545,137,11,863,789,714,830,441,966,767,100,6,502,495,547,31,205,53,378,834,592,301,179,507,236,622,18,481,829,839,542,297,1,74,791,175,351,685,471,191,700,949,747,401,982,108,114,695,68,771,957,168,382,906,196,915,473,891,873,263,22,654,420,437,987,776,358,162,96,739,349,238,890,580,234,257,524,887,729,379,918,755,780,21,733,387,238,900,882,974,562,407,428,446,711,708,328,370,794,698,74,795,904,77,776,179,694,209,426,114,247,289,214,958,132,30,252,786,50,155,331,900,963,776,6,30,289,91,198,349,938,329,157,645,312,793,251,809,247,808,622,722,857,215,259,999,230,329,704,779,130,562,545,392,640,508,757,195,94,81,372,999,980,429,585,30,389,721,970,788,216,783,169,148,283,228,116,227,252,564,5,313,377,176,612,933,279,128,355,742,183,923,553,509,610,248,352,572,464,892,188,773,905,487,656,422,324,627,683,72,73,59,992,790,454,251,916,596,656,705,893,967,558,154,8,338,320,302,389,287,990,94,255,670,46,267,934,964,23,689,27,16,318,813,149,949,913,548,10,748,424,342,664,695,397,707,750,813,306,418,547,249,386,210,492,598,422,293,693,214,878,1,830,114,307,721,821,705,940,282,857,943,278,644,808,571,845,635,948,439,447,275,313,681,35,790,652,781,661,283,184,486,905,96,813,540,491,758,920,427,882,174,665,325,59,60,974,154,511,705,831,482,496,848,700,745,885,686,944,333,535,701,598,614,627,873,619,684,949,146,431,675,228,37,249,553,898,210,882,926,551,575,395,18,714,381,595,340,865,352,938,908,47,963,687,755,896,725,277,299,988,517,557,674,852,402,572,289,734,691,163,928,49,244,974,150,61,693,388,765,59,831,602,424,706,393,745,158,119,32,401,740,654,397,158,494,975,39,548,540,874,710,729,12,580,770,237,790,932,543,563,805,116,466,42,659,384,205,826,989,698,399,533,507,554,571,445,145,839,626,471,606,523,793,412,459,286,677,490,608,545,986,188,957,425,654,481,659,610,500,137,51,296,90,59,873,682,417,220,654,965,623,348,14,814,564,677,396,394,135,640,221,495,381,560,75,858,632,905,96,140,589,859,476,662,774,164,540,34,867,930,609,781,919,329,657,565,161,3,450,932,452,50,250,539,302,]\n", | |
"activations = predict_gpu(all_images_dev, params_dev, batch_stats_dev).block_until_ready()\n", | |
"predictions = get_top1(activations)\n", | |
"\n" | |
], | |
"metadata": { | |
"id": "HCORIREWcReu" | |
}, | |
"execution_count": 21, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"print('Accuracy ---> ', sum(1 for x,y in zip(ground_truth, predictions) if x == y) / float(len(ground_truth)))\n", | |
"print('Accuracy comparing to results from MO436 projects 2 and 3 --> ', sum(1 for x,y in zip(glow_results, predictions) if x == y) / float(len(ground_truth)))" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "yAyTUypHdC-A", | |
"outputId": "298c1645-b078-49a0-9022-9cd566e392a9" | |
}, | |
"execution_count": 22, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Accuracy ---> 0.69\n", | |
"Accuracy comparing to results from MO436 projects 2 and 3 --> 1.0\n" | |
] | |
} | |
] | |
} | |
], | |
"metadata": { | |
"colab": { | |
"collapsed_sections": [], | |
"name": "Flax_Resnet18.ipynb", | |
"provenance": [] | |
}, | |
"gpuClass": "standard", | |
"kernelspec": { | |
"display_name": "Python 3", | |
"name": "python3" | |
}, | |
"language_info": { | |
"name": "python" | |
}, | |
"accelerator": "GPU" | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment