Skip to content

Commit

Permalink
adding web demo using web assembly support (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
flutter-painter authored and gyrdym committed Sep 7, 2024
1 parent 5694574 commit c6c5289
Show file tree
Hide file tree
Showing 16 changed files with 604 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 16.17.13
- Added Decision Tree web demo using Web Assembly

## 16.17.12
- update in README
- mention that web is possible
Expand Down
3 changes: 3 additions & 0 deletions example/wasm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://dart.dev/guides/libraries/private-files
# Created by `dart pub`
.dart_tool/
3 changes: 3 additions & 0 deletions example/wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 1.0.0

- Initial version.
27 changes: 27 additions & 0 deletions example/wasm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# wasm (dart)

A simple demo for [ml_algo](https://pub.dev/packages/ml_algo)
Decision tree example for predicting an iris' species based on its dimensions.
This simple js web demo uses Dart Web Assembly support

## building/running
- Serve the output, example

$ cd site
$ dart pub global activate dhttpd
$ dart pub global run dhttpd

- Open your brwoser at : http://localhost:8080/site/index.html

- type flower dimensions and run either using :
- a preloaded model (faster)
- training a (small) model on on the fly

![screenshot](screenshot.png)


- Compile with Wasm to a new site output directory:

mywebapp$ dart compile wasm web/main.dart -o site/test.wasm

For more details see documentation from https://dart.dev/web/wasm
30 changes: 30 additions & 0 deletions example/wasm/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file configures the static analysis results for your project (errors,
# warnings, and lints).
#
# This enables the 'recommended' set of lints from `package:lints`.
# This set helps identify many issues that may lead to problems when running
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
# style and format.
#
# If you want a smaller set of lints you can change this to specify
# 'package:lints/core.yaml'. These are just the most critical lints
# (the recommended set includes the core lints).
# The core lints are also what is used by pub.dev for scoring packages.

include: package:lints/recommended.yaml

# Uncomment the following section to specify additional rules.

# linter:
# rules:
# - camel_case_types

# analyzer:
# exclude:
# - path/to/excluded/files/**

# For more information about the core and recommended set of lints, see
# https://dart.dev/go/core-lints

# For additional information about configuring this file, see
# https://dart.dev/guides/language/analysis-options
19 changes: 19 additions & 0 deletions example/wasm/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: wasm
description: An absolute bare-bones web app.
version: 1.0.0
# repository: https://github.com/my_org/my_repo

environment:
sdk: ^3.5.0

# Add regular dependencies here.
dependencies:
web: ^0.5.1
ml_algo: ^16.17.11
ml_dataframe: ^1.6.0
ml_preprocessing: ^7.0.2

dev_dependencies:
build_runner: ^2.4.8
build_web_compilers: ^4.0.9
lints: ^4.0.0
Binary file added example/wasm/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 63 additions & 0 deletions example/wasm/site/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<title>Test ml dart wasm</title>
<link rel="preload" href="/test.wasm" as="fetch" crossorigin>
</head>
<body>
<h1>What iris is this ?</h1>
<h2>
<form onsubmit="return getValue('commands')">
SepalLengthCm: <input type="number" name="int1" id="int1"><br />
SepalWidthCm: <input type="number" name="int2" id="int2"><br />
PetalLengthCm: <input type="number" name="int3" id="int3"><br />
PetalWidthCm: <input type="number" name="int4" id="int4"><br />
<br>
</form>
<p></p>
<div id="decisionTreeLoaded_output">decisionTreeLoaded: Not run yet.</div>
<div id="decisionTreeFull">decisionTreeFull: Not run yet.</div>
</h2>
<script type="module">
const dartModulePromise = WebAssembly.compileStreaming(fetch('/test.wasm'));
const imports = {};
let dart2wasm_runtime = await import('/test.mjs');
let moduleInstance =
await dart2wasm_runtime.instantiate(dartModulePromise, imports);
dart2wasm_runtime.invoke(moduleInstance);
</script>
<script>
function testDecisionTreePreLoaded() {
let int1 = parseInt(document.getElementById('int1').value);
let int2 = parseInt(document.getElementById('int2').value);
let int3 = parseInt(document.getElementById('int3').value);
let int4 = parseInt(document.getElementById('int4').value);
console.log(`int1 ${int1}`);
if (isNaN(parseInt(int1)) || isNaN(parseInt(int2)) || isNaN(parseInt(int3)) || isNaN(parseInt(int4))) {
document.querySelector("#decisionTreeLoaded_output").innerHTML = "decisionTreeLoaded: " + "invalid";
} else {
const result = foo.decisionTreeLoaded(int1, int2, int3, int4);
document.querySelector("#decisionTreeLoaded_output").innerHTML = "decisionTreeLoaded: " + result;
}
}
async function testDecisionTreeFull() {
let int1 = parseInt(document.getElementById('int1').value);
let int2 = parseInt(document.getElementById('int2').value);
let int3 = parseInt(document.getElementById('int3').value);
let int4 = parseInt(document.getElementById('int4').value);
console.log(`int1 ${int1}`);
if (isNaN(parseInt(int1)) || isNaN(parseInt(int2)) || isNaN(parseInt(int3)) || isNaN(parseInt(int4))) {
document.querySelector("#decisionTreeFull").innerHTML = "decisionTreeFull: " + "invalid";
} else {
const result = foo.decisionTreeFull(int1, int2, int3, int4);
document.querySelector("#decisionTreeFull").innerHTML = "decisionTreeFull: " + result;
}
}
</script>
<div style="display: flex;justify-content: center;">
<button onclick="testDecisionTreePreLoaded()" style="margin-right: 10px;">test loading model </button>
<button onclick="testDecisionTreeFull()">test decision tree model</button>
</div>
</body>

</html>
21 changes: 21 additions & 0 deletions example/wasm/site/main.dart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(async function () {
let dart2wasm_runtime;
let moduleInstance;
try {
const dartModulePromise = WebAssembly.compileStreaming(fetch('main.wasm'));
const imports = {};
dart2wasm_runtime = await import('./main.mjs');
moduleInstance = await dart2wasm_runtime.instantiate(dartModulePromise, imports);
} catch (exception) {
console.error(`Failed to fetch and instantiate wasm module: ${exception}`);
console.error('See https://dart.dev/web/wasm for more information.');
}

if (moduleInstance) {
try {
await dart2wasm_runtime.invoke(moduleInstance);
} catch (exception) {
console.error(`Exception while invoking test: ${exception}`);
}
}
})();
14 changes: 14 additions & 0 deletions example/wasm/site/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
}

#output {
padding: 20px;
text-align: center;
}
Loading

0 comments on commit c6c5289

Please sign in to comment.