<!DOCTYPE html>
<html>

<!--
Copyright 2022 The IREE Authors

Licensed under the Apache License v2.0 with LLVM Exceptions.
See https://llvm.org/LICENSE.txt for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

<head>
  <meta charset="utf-8" />
  <title>IREE WebGPU Sample</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="./IREE_Logo_Icon_Color.svg" type="image/svg+xml">

  <style>
    body {
      padding: 16px;
    }

    .drop-target {
      border: 3px solid #2244CC;
      background-color: #c0c0c0;
      color: #222222;
      width:  300px;
      height: 140px;
      margin: 20px;
      padding: 8px;
      display: flex;
      align-items: center;
      justify-content: center;
      user-select: none;
    }

    .drop-target p {
      pointer-events: none;
    }
  </style>

  <!-- https://getbootstrap.com/ for some webpage styling-->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

  <script src="./iree_api_webgpu.js"></script>
</head>

<body>
  <div class="container">
    <h1>IREE WebGPU Sample</h1>

    <p>
      This tool works similarly to
      <a href="https://github.com/iree-org/iree/blob/main/tools/iree-run-module-main.cc"><code>iree-run-module</code></a>
      (<a href="https://iree.dev/developers/general/developer-overview/#iree-run-module">docs</a>).
      <br>It loads a compiled IREE program then lets you call exported functions.
      <br><b>Note:</b> Some outputs are logged to the console.</p>
    </p>

    <h2>1. Load a program</h2>

    <div id="drop-zone" class="drop-target">
      <p style="margin:0px">Drag a compiled IREE program<br>(.vmfb file) here to load it</p>
    </div>
    <p>
      Currently loaded program:
      <b><span id="loaded-program-name" style="display: inline;">(None)</span></b>
    </p>

    <h2>2. Call functions on a loaded program</h2>

    <form>
      <p>
        <label for="function-name-input" class="form-label">Function name:</label>
        <input type="text" id="function-name-input" class="form-control"
               style="width:400px; font-family: monospace;" value="main"></input>
      </p>

      <p>
        <label for="function-arguments-input" class="form-label">Function arguments:</label>
        <br><span class="form-text">In the form <code>dim1xdim2xtype=val1,val2,...</code>, one per line</span>
        <textarea type="text" id="function-arguments-input" spellcheck="false" class="form-control"
                  style="min-width:400px; width:initial; min-height:100px; resize:both; font-family: monospace;"></textarea>
      </p>

      <button id="call-function" class="btn btn-primary" type="button"
              onclick="callFunctionWithFormInputs()" disabled>Call function</button>
      <button id="update-url" class="btn btn-secondary" type="button"
              onclick="updateUrlWithFormValues()">Update URL</button>
      <button id="update-url" class="btn btn-secondary" type="button"
              onclick="clearUrl()">Clear URL</button>
    </form>

    <p>
      <h4><label for="function-outputs" class="form-label">Function outputs:</label></h4>
      <textarea type="text" id="function-outputs" readonly spellcheck="false" class="form-control"
                style="min-width:400px; width:initial; height:100px; resize:both; font-family: monospace;"></textarea>
    </p>

    <p>Total time (including overheads):
      <code id="benchmark-time-js-output" style="font-family: monospace;"></code></p>
    <p>Invoke time:
      <code id="benchmark-time-invoke-output" style="font-family: monospace;"></code></p>
    <p>Readback time:
      <code id="benchmark-time-readback-output" style="font-family: monospace;"></code></p>

    <hr>
    <h2>Samples</h2>

    <p>
      Click to load a sample program, function, and arguments list.
      <br>These links will automatically update the URL.
    </p>

    <div class="container" style="width:fit-content; margin-left:0px">
      <div class="row" style="padding:4px">
        <div class="col-sm">
          simple_abs
          (<a href="https://github.com/iree-org/iree/blob/main/samples/models/simple_abs.mlir">source</a>)
        </div>
        <div class="col-sm-auto">
          <button class="btn btn-secondary" onclick="loadSample('simple_abs')">Load sample</button>
        </div>
      </div>
      <div class="row" style="padding:4px">
        <div class="col-sm">
          multiple_results
          (<a href="https://github.com/iree-org/iree/blob/webgpu/experimental/web/sample_webgpu/multiple_results.mlir">source</a>)
        </div>
        <div class="col-sm-auto">
          <button class="btn btn-secondary" onclick="loadSample('multiple_results')">Load sample</button>
        </div>
      </div>
      <div class="row" style="padding:4px">
        <div class="col-sm">
          fullyconnected
          (<a href="https://github.com/iree-org/iree/blob/main/tests/e2e/stablehlo_models/fullyconnected.mlir">source</a>)
        </div>
        <div class="col-sm-auto">
          <button class="btn btn-secondary" onclick="loadSample('fullyconnected')">Load sample</button>
        </div>
      </div>
      <div class="row" style="padding:4px">
        <div class="col-sm">
          mobilebert
          (<a href="https://tfhub.dev/iree/lite-model/mobilebert/fp32/1">source</a>)
        </div>
        <div class="col-sm-auto">
          <button class="btn btn-secondary" onclick="loadSample('mobilebert')">Load sample</button>
        </div>
      </div>
      <div class="row" style="padding:4px">
        <div class="col-sm">
          posenet
          (<a href="https://tfhub.dev/tensorflow/lite-model/posenet/mobilenet/float/075/1/default/1">source</a>)
        </div>
        <div class="col-sm-auto">
          <button class="btn btn-secondary" onclick="loadSample('posenet')">Load sample</button>
        </div>
      </div>
      <div class="row" style="padding:4px">
        <div class="col-sm">
          mobilessd
          (<a href="https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/mobile_ssd_v2_float_coco.tflite">source</a>)
        </div>
        <div class="col-sm-auto">
          <button class="btn btn-secondary" onclick="loadSample('mobilessd')">Load sample</button>
        </div>
      </div>
    </div>

    <hr>
    <h2>Compile your own program</h2>

    <p>
      Programs must be compiled for WebGPU to run on this page, using options
      to <code>iree-compile</code> such as:
    </p>

    <textarea type="text" readonly spellcheck="false"
    class="form-control" style="width:610px; height:90px; resize:none; font-family: monospace;">
--iree-hal-target-backends=webgpu-spirv \
--iree-codegen-gpu-native-math-precision=true \
--iree-stream-resource-alias-mutable-bindings=true \</textarea>

  </div>

  <script>
    const initializePromise = ireeInitialize();
    initializePromise.then(() => {
      console.log("IREE initialized, ready to load programs.");
    }).catch((error) => {
      console.error("Failed to initialize IREE, error:");
      console.error(error);
    });

    let loadedProgram = null;
    const programNameElement = document.getElementById("loaded-program-name");
    const callFunctionButton = document.getElementById("call-function");
    const functionNameInput = document.getElementById("function-name-input");
    const functionArgumentsInput = document.getElementById("function-arguments-input");
    const functionOutputsElement = document.getElementById("function-outputs");
    const timeJsOutputElement = document.getElementById("benchmark-time-js-output");
    const timeInvokeOutputElement = document.getElementById("benchmark-time-invoke-output");
    const timeReadbackOutputElement = document.getElementById("benchmark-time-readback-output");

    async function finishLoadingProgram(newProgram, newProgramName) {
      if (loadedProgram !== null) {
        // Unload the previous program. We could keep a list of loaded programs
        // and let users select between them.
        await ireeUnloadProgram(loadedProgram);
      }

      await ireeInspectProgram(newProgram);

      loadedProgram = newProgram;
      programNameElement.innerText = newProgramName;
      callFunctionButton.disabled = false;
    }

    async function tryLoadFromUrlParams() {
      // Fetch IREE program from ?program=[file.vmfb] URL query parameter.
      const searchParams = new URLSearchParams(window.location.search);

      if (searchParams.has("function")) {
        functionNameInput.value = searchParams.get("function");
      }

      if (searchParams.has("arguments")) {
        functionArgumentsInput.value = searchParams.get("arguments");
      }

      if (searchParams.has("program")) {
        const programPath = searchParams.get("program");

        await initializePromise;
        const program = await ireeLoadProgram(programPath);

        // Set name to what is hopefully the file component of the path.
        finishLoadingProgram(program, programPath.split("/").pop());
      }
    }

    async function tryLoadFromBuffer(programDataBuffer, programName) {
      // Clear 'program' from the URL.
      const searchParams = new URLSearchParams(window.location.search);
      searchParams.delete("program");
      replaceUrlWithSearchParams(searchParams);

      await initializePromise;
      const program = await ireeLoadProgram(programDataBuffer);

      finishLoadingProgram(program, programName);
    }

    // ------------------------------------------------------------------------
    // Drag-and-drop to load from your local filesystem.
    const dropZone = document.getElementById("drop-zone");
    dropZone.addEventListener("drop", (dropEvent) => {
      dropEvent.preventDefault();
      dropEvent.target.style.border = "";

      // Assume exactly one file was dropped.
      const uploadedFile = dropEvent.dataTransfer.items[0].getAsFile();
      const fileReader = new FileReader();
      fileReader.onload = (fileLoadEvent) => {
        tryLoadFromBuffer(fileLoadEvent.target.result, uploadedFile.name)
          .catch((error) => {
            console.error("Error loading program from drop: '" + error + "'");
          });
      };
      fileReader.readAsArrayBuffer(uploadedFile);
    });
    dropZone.addEventListener("dragover", (event) => {
      event.preventDefault();
    });
    dropZone.addEventListener("dragenter", (event) => {
      if (event.target !== dropZone) return;
      event.target.style.border = "3px dotted red";
    });
    dropZone.addEventListener("dragleave", (event) => {
      if (event.target !== dropZone) return;
      event.target.style.border = "";
    });
    // ------------------------------------------------------------------------

    // ------------------------------------------------------------------------
    // Form inputs.
    function callFunctionWithFormInputs() {
      if (loadedProgram === null) {
        console.error("Can't call a function with no loaded program");
        return;
      }

      const functionName = functionNameInput.value;
      const inputs = functionArgumentsInput.value.split("\n");
      const startJsTime = performance.now();

      ireeCallFunction(loadedProgram, functionName, inputs)
          .then((resultObject) => {
            functionOutputsElement.value =
                resultObject['outputs'].replaceAll(";", "\n");

            const endJsTime = performance.now();
            const totalJsTime = endJsTime - startJsTime;
            timeJsOutputElement.textContent = totalJsTime.toFixed(3) + "ms";

            const invokeTimeMs = resultObject['invoke_time_ms'];
            timeInvokeOutputElement.textContent = invokeTimeMs + "ms";

            const readbackTimeMs = resultObject['readback_time_ms'];
            timeReadbackOutputElement.textContent = readbackTimeMs + "ms";
          })
          .catch((error) => {
            console.error("Function call error: '" + error + "'");
          });
    }

    function replaceUrlWithSearchParams(searchParams) {
      let newUrl = window.location.protocol + "//" + window.location.host +
          window.location.pathname;
      const searchString = searchParams.toString();
      if (searchString !== "") newUrl += "?" + searchParams;
      window.history.replaceState({path: newUrl}, "", newUrl);
    }

    function updateUrlWithFormValues() {
      const searchParams = new URLSearchParams(window.location.search);
      searchParams.set("function", functionNameInput.value);
      searchParams.set("arguments", functionArgumentsInput.value);
      replaceUrlWithSearchParams(searchParams);
    }

    function clearUrl() {
      const searchParams = new URLSearchParams(window.location.search);
      searchParams.delete("program");
      searchParams.delete("function");
      searchParams.delete("arguments");
      searchParams.delete("iterations");
      replaceUrlWithSearchParams(searchParams);
    }
    // ------------------------------------------------------------------------

    // ------------------------------------------------------------------------
    // Load samples programs / inputs.
    function loadSample(sampleName) {
      const searchParams = new URLSearchParams(window.location.search);
      searchParams.set("program", sampleName + "_webgpu.vmfb");
      replaceUrlWithSearchParams(searchParams);

      if (sampleName === "simple_abs") {
        functionNameInput.value = "abs";
        functionArgumentsInput.value = "f32=-1.23";
      } else if (sampleName === "multiple_results") {
        functionNameInput.value = "multiple_results";
        functionArgumentsInput.value = [
          "2xf32=-1.23,-1.45",
          "2xf32=-2.23,-2.45",
        ].join("\n");
      } else if (sampleName === "fullyconnected") {
        functionNameInput.value = "main";
        functionArgumentsInput.value = [
          "1x5xf32=1,-2,-3,4,-5",
          "1x5x3x1xf32=15,14,13,12,11,10,9,8,7,6,5,4,3,2,1",
        ].join("\n");
      } else if (sampleName === "mobilebert") {
        functionNameInput.value = "main";
        functionArgumentsInput.value = [
          "1x384xi32",
          "1x384xi32",
          "1x384xi32",
        ].join("\n");
      } else if (sampleName === "posenet") {
        functionNameInput.value = "main";
        functionArgumentsInput.value = "1x353x257x3xf32";
      } else if (sampleName === "mobilessd") {
        functionNameInput.value = "main";
        functionArgumentsInput.value = "1x320x320x3xf32";
      }

      updateUrlWithFormValues();

      tryLoadFromUrlParams().catch((error) => {
        console.error("Error loading sample program: '" + error + "'");
      });
    }
    // ------------------------------------------------------------------------

    window.addEventListener("load", () => {
      tryLoadFromUrlParams().catch((error) => {
        console.error("Error loading program from URL: '" + error + "'");
      });
    });
  </script>
</body>

</html>
