{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Compile CoreML Models\n**Author**: [Joshua Z. Zhang](https://zhreshold.github.io/),             [Kazutaka Morita](https://github.com/kazum),             [Zhao Wu](https://github.com/FrozenGene)\n\nThis article is an introductory tutorial to deploy CoreML models with Relay.\n\nFor us to begin with, coremltools module is required to be installed.\n\nA quick solution is to install via pip\n\n```bash\npip install -U coremltools --user\n```\nor please refer to official site\nhttps://github.com/apple/coremltools\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import tvm\nfrom tvm import te\nimport tvm.relay as relay\nfrom tvm.contrib.download import download_testdata\nimport coremltools as cm\nimport numpy as np\nfrom PIL import Image"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Load pretrained CoreML model\nWe will download and load a pretrained mobilenet classification network\nprovided by apple in this example\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "model_url = \"https://docs-assets.developer.apple.com/coreml/models/MobileNet.mlmodel\"\nmodel_file = \"mobilenet.mlmodel\"\nmodel_path = download_testdata(model_url, model_file, module=\"coreml\")\n# Now you have mobilenet.mlmodel on disk\nmlmodel = cm.models.MLModel(model_path)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Load a test image\nA single cat dominates the examples!\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "img_url = \"https://github.com/dmlc/mxnet.js/blob/main/data/cat.png?raw=true\"\nimg_path = download_testdata(img_url, \"cat.png\", module=\"data\")\nimg = Image.open(img_path).resize((224, 224))\n# Mobilenet.mlmodel's input is BGR format\nimg_bgr = np.array(img)[:, :, ::-1]\nx = np.transpose(img_bgr, (2, 0, 1))[np.newaxis, :]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Compile the model on Relay\nWe should be familiar with the process right now.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "target = \"llvm\"\nshape_dict = {\"image\": x.shape}\n\n# Parse CoreML model and convert into Relay computation graph\nmod, params = relay.frontend.from_coreml(mlmodel, shape_dict)\n\nwith tvm.transform.PassContext(opt_level=3):\n    lib = relay.build(mod, target, params=params)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Execute on TVM\nThe process is no different from other example\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from tvm.contrib import graph_executor\n\ndev = tvm.cpu(0)\ndtype = \"float32\"\nm = graph_executor.GraphModule(lib[\"default\"](dev))\n# set inputs\nm.set_input(\"image\", tvm.nd.array(x.astype(dtype)))\n# execute\nm.run()\n# get outputs\ntvm_output = m.get_output(0)\ntop1 = np.argmax(tvm_output.numpy()[0])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Look up synset name\nLook up prediction top 1 index in 1000 class synset.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "synset_url = \"\".join(\n    [\n        \"https://gist.githubusercontent.com/zhreshold/\",\n        \"4d0b62f3d01426887599d4f7ede23ee5/raw/\",\n        \"596b27d23537e5a1b5751d2b0481ef172f58b539/\",\n        \"imagenet1000_clsid_to_human.txt\",\n    ]\n)\nsynset_name = \"imagenet1000_clsid_to_human.txt\"\nsynset_path = download_testdata(synset_url, synset_name, module=\"data\")\nwith open(synset_path) as f:\n    synset = eval(f.read())\n# You should see the following result: Top-1 id 282 class name tiger cat\nprint(\"Top-1 id\", top1, \"class name\", synset[top1])"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.5"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}