<!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 Dynamic Web 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.js"></script>
</head>

<body>
  <div class="container">
    <h1>IREE Dynamic Web 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>

      <p>
        <label for="benchmark-iterations-input" class="form-label">
          Benchmark iterations (inner invoke call):</label>
        <input type="number" id="benchmark-iterations-input" class="form-control"
               style="width:400px; font-family: monospace;" value="1" min="1"></input>
      </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>Mean inference time (Wasm only):
      <code id="benchmark-time-wasm-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">
          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">
          collatz
          (<a href="https://github.com/iree-org/iree/blob/main/tests/e2e/stablehlo_models/collatz.mlir">source</a>)
        </div>
        <div class="col-sm-auto">
          <button class="btn btn-secondary" onclick="loadSample('collatz')">Load sample</button>
        </div>
      </div>
    </div>

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

    <p>
      Programs must be compiled for WebAssembly 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=llvm-cpu \
--iree-llvmcpu-target-triple=wasm32-unknown-emscripten \
--iree-llvmcpu-target-cpu-features=+atomics,+bulk-memory,+simd128 \</textarea>

  </div>

  <script>
    const initializePromise = ireeInitializeWorker();
    initializePromise.then(() => {
      console.log("IREE initialized, ready to load programs.");
    });

    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 benchmarkIterationsInput = document.getElementById("benchmark-iterations-input");
    const functionOutputsElement = document.getElementById("function-outputs");
    const timeJsOutputElement = document.getElementById("benchmark-time-js-output");
    const timeWasmOutputElement = document.getElementById("benchmark-time-wasm-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("iterations")) {
        benchmarkIterationsInput.value = searchParams.get("iterations");
      }

      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 iterations = benchmarkIterationsInput.value;
      const startJsTime = performance.now();

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

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

            const totalWasmTimeMs = resultObject['total_invoke_time_ms'];
            const meanWasmTimeMs = totalWasmTimeMs / iterations;
            timeWasmOutputElement.textContent = meanWasmTimeMs.toFixed(3) +
                "ms / iteration over " + iterations + " iteration(s)";
          })
          .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);
      searchParams.set("iterations", benchmarkIterationsInput.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 + ".vmfb");
      replaceUrlWithSearchParams(searchParams);

      if (sampleName === "simple_abs") {
        functionNameInput.value = "abs";
        functionArgumentsInput.value = "f32=-1.23";
      } 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 === "collatz") {
        functionNameInput.value = "collatz";
        functionArgumentsInput.value = "";
      }

      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>
