Something like an end to end proof of concept
This commit is contained in:
parent
94d57491bd
commit
8c38c3955f
65
.github/workflows/ci.yml
vendored
65
.github/workflows/ci.yml
vendored
|
@ -16,12 +16,18 @@ jobs:
|
|||
name: Precheck for skipping redundant jobs
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
should_skip_mc: ${{ steps.skip_lang_check.outputs.should_skip }}
|
||||
should_skip_lang: ${{ steps.skip_lang_check.outputs.should_skip }}
|
||||
should_skip_components: ${{ steps.skip_components_check.outputs.should_skip }}
|
||||
should_skip_website: ${{ steps.skip_website_check.outputs.should_skip }}
|
||||
should_skip_vscodeext: ${{ steps.skip_vscodeext_check.outputs.should_skip }}
|
||||
should_skip_cli: ${{ steps.skip_cli_check.outputs.should_skip }}
|
||||
steps:
|
||||
- id: skip_mc_check
|
||||
name: Check if the changes are about mc files
|
||||
uses: fkirc/skip-duplicate-actions@v4.0.0
|
||||
with:
|
||||
paths: '["packages/mc/**"]'
|
||||
- id: skip_lang_check
|
||||
name: Check if the changes are about squiggle-lang src files
|
||||
uses: fkirc/skip-duplicate-actions@v4.0.0
|
||||
|
@ -48,6 +54,29 @@ jobs:
|
|||
with:
|
||||
paths: '["packages/cli/**"]'
|
||||
|
||||
mc-build:
|
||||
name: MC build
|
||||
runs-on: ubuntu-latest
|
||||
needs: pre_check
|
||||
if: ${{ needs.pre_check.outputs.should_skip_mc != 'true' }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: packages/mc
|
||||
steps:
|
||||
- name: Run yarn at monorepo level
|
||||
run: cd ../../ && yarn
|
||||
- name: Download wasm-bindgen
|
||||
uses: jetli/wasm-bindgen-action@v0.1.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Download wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Build
|
||||
run: wasm-pack build --target nodejs
|
||||
|
||||
lang-lint:
|
||||
name: Language lint
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -84,7 +113,17 @@ jobs:
|
|||
fetch-depth: 2
|
||||
- name: Install dependencies from monorepo level
|
||||
run: cd ../../ && yarn
|
||||
- name: Build rescript codebase
|
||||
- name: Download wasm-bindgen
|
||||
uses: jetli/wasm-bindgen-action@v0.1.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Download wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Build
|
||||
run: wasm-pack build --target nodejs
|
||||
- name: Build rescript codebase and typescript interface
|
||||
run: yarn build
|
||||
- name: Run rescript tests
|
||||
run: yarn test:rescript
|
||||
|
@ -127,7 +166,17 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies from monorepo level
|
||||
run: cd ../../ && yarn
|
||||
- name: Build rescript codebase in squiggle-lang
|
||||
- name: Download wasm-bindgen
|
||||
uses: jetli/wasm-bindgen-action@v0.1.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Download wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Build
|
||||
run: wasm-pack build --target nodejs
|
||||
- name: Build rescript codebase and typescript interface in squiggle-lang
|
||||
run: cd ../squiggle-lang && yarn build
|
||||
- name: Run webpack
|
||||
run: yarn bundle
|
||||
|
@ -164,7 +213,17 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies from monorepo level
|
||||
run: cd ../../ && yarn
|
||||
- name: Build rescript in squiggle-lang
|
||||
- name: Download wasm-bindgen
|
||||
uses: jetli/wasm-bindgen-action@v0.1.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Download wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: 'latest'
|
||||
- name: Build
|
||||
run: wasm-pack build --target nodejs
|
||||
- name: Build rescript and typescript in squiggle-lang
|
||||
run: cd ../squiggle-lang && yarn build
|
||||
- name: Build components
|
||||
run: cd ../components && yarn build
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
cargo2nix.overlays.default
|
||||
(final: prev: {
|
||||
# set the node version here
|
||||
nodejs = prev.nodejs-18_x;
|
||||
nodejs = prev.nodejs-16_x;
|
||||
# The override is the only way to get it into mkYarnModules
|
||||
})
|
||||
];
|
||||
|
|
|
@ -7,12 +7,15 @@ with pkgs; {
|
|||
cargo
|
||||
yarn
|
||||
nodejs
|
||||
nodePackages.ts-node
|
||||
rustup
|
||||
pkg-config
|
||||
libressl
|
||||
nixfmt
|
||||
rustfmt
|
||||
cargo2nix.outputs.packages.${pkgs.system}.default
|
||||
wasmtime
|
||||
binaryen
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ rec {
|
|||
THE_LD=$(patchelf --print-interpreter $(which mkdir))
|
||||
patchelf --set-interpreter $THE_LD bin/linux/ppx
|
||||
patchelf --set-interpreter $THE_LD bin/linux/bisect-ppx-report
|
||||
cp bin/linux/ppx ppx
|
||||
'';
|
||||
};
|
||||
gentype = {
|
||||
|
|
2
packages/mc/Cargo.lock
generated
2
packages/mc/Cargo.lock
generated
|
@ -449,7 +449,7 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "quri-squiggle-mc"
|
||||
name = "quri_squiggle_mc"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"cached",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# You must change these to your own details.
|
||||
[package]
|
||||
name = "quri-squiggle-mc"
|
||||
name = "quri_squiggle_mc"
|
||||
description = "Cached and parallel Monte Carlo simulations in WebAssembly"
|
||||
version = "0.0.1"
|
||||
authors = ["Quinn <quinn@quantifieduncertainty.org>"]
|
||||
|
@ -11,11 +11,11 @@ readme = "README.md"
|
|||
edition = "2018"
|
||||
|
||||
[package.metadata.wasm-pack.profile.dev]
|
||||
wasm-opt = false
|
||||
wasm-opt = true
|
||||
[package.metadata.wasm-pack.profile.profiling]
|
||||
wasm-opt = false
|
||||
wasm-opt = true
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = false
|
||||
wasm-opt = true
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
@ -33,7 +33,7 @@ default = ["wee_alloc"]
|
|||
[dependencies]
|
||||
# The `wasm-bindgen` crate provides the bare minimum functionality needed
|
||||
# to interact with JavaScript.
|
||||
wasm-bindgen = "0.2.45"
|
||||
wasm-bindgen = "0.2.82"
|
||||
|
||||
# The `web-sys` crate allows you to interact with the various browser APIs,
|
||||
# like the DOM.
|
||||
|
|
|
@ -6,6 +6,8 @@ Please run `yarn` at the monorepo level.
|
|||
|
||||
In this subrepo, please run `./cargo-refresh-nix.sh` every time `Cargo.toml`/`Cargo.lock` is modified, it requires nix with flakes.
|
||||
|
||||
Please view `/.github/workflows/ci.yml` for the most accurate story about how to build in concert with the rest of the packages in the monorepo.
|
||||
|
||||
## How to run in debug mode
|
||||
|
||||
```sh
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
import("../pkg/index.js").catch(console.error);
|
|
@ -4,15 +4,20 @@
|
|||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"build": "rimraf dist pkg && webpack",
|
||||
"start": "rimraf dist pkg && webpack-dev-server --open -d",
|
||||
"build:node": "wasm-pack build --target nodejs",
|
||||
"watch": "rimraf dist pkg && webpack --watch",
|
||||
"start": "rimraf dist pkg && webpack-dev-server --open",
|
||||
"test": "cargo test && wasm-pack test --headless"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wasm-tool/wasm-pack-plugin": "^1.1.0",
|
||||
"copy-webpack-plugin": "^5.0.3",
|
||||
"webpack": "^4.42.0",
|
||||
"webpack-cli": "^3.3.3",
|
||||
"webpack-dev-server": "^3.7.1",
|
||||
"rimraf": "^3.0.0"
|
||||
}
|
||||
"@wasm-tool/wasm-pack-plugin": "^1.6.0",
|
||||
"webpack": "^5.74.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.10.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"ts-loader": "^9.3.1",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"main": "./pkg/index.js",
|
||||
"types": "./pkg/index.d.ts"
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/** The math here was taken from https://github.com/jasondavies/science.js/blob/master/src/stats/SampleSetDist_Bandwidth.js
|
||||
*/
|
||||
use statistics::variance;
|
||||
// mod magic_numbers;
|
||||
// use kernel_density::ecdf::percentile;
|
||||
use crate::distribution::BandwidthParameters;
|
||||
use crate::distribution::e::a::floats::{lenf, min, percentile};
|
||||
mod e;
|
||||
use e::a::floats::{lenf, min, percentile};
|
||||
|
||||
fn iqr_percentile() -> f64 {
|
||||
return BandwidthParameters::default().iqr_percentile;
|
|
@ -1,10 +1,7 @@
|
|||
pub mod e;
|
||||
pub mod bandwidth;
|
||||
pub mod magic_numbers;
|
||||
pub mod monte_carlo;
|
||||
|
||||
pub use e::*;
|
||||
// pub use bandwidth;
|
||||
pub use magic_numbers::bandwidth::Parameters as BandwidthParameters;
|
||||
pub use magic_numbers::environment::Parameters as EnvironmentParameters;
|
||||
pub use monte_carlo::my_string;
|
||||
pub use monte_carlo::sampleN;
|
||||
|
|
|
@ -1,8 +1,36 @@
|
|||
use rand;
|
||||
use rand_distr::{Distribution, Normal};
|
||||
extern crate kernel_density;
|
||||
|
||||
pub fn my_string() -> String {
|
||||
let normal = Normal::new(2.0, 3.0).unwrap();
|
||||
let v = normal.sample(&mut rand::thread_rng());
|
||||
return format!("{} is from an N(2,3) distribution", v);
|
||||
use rand::Rng;
|
||||
use rand::thread_rng;
|
||||
// use kernel_density::kde;
|
||||
// use crate::distribution::bandwidth::{nrd0, nrd};
|
||||
|
||||
// TODO: impl a constructor such that xs.len() == ys.len().
|
||||
pub struct PdfCurve {
|
||||
xs: Vec<f64>,
|
||||
ys: Vec<f64>,
|
||||
}
|
||||
|
||||
// pub fn samples_to_continuous_pdf(samples: Vec<f64>, bandwidth: f64) -> PdfCurve {
|
||||
// let pdf = kde::normal(&samples, bandwidth);
|
||||
// return PdfCurve {
|
||||
// xs: samples,
|
||||
// ys: samples.map(|x| pdf.density(x)),
|
||||
// };
|
||||
// }
|
||||
|
||||
// pub fn getCurve(xs: Vec<f64>, n: u64) -> Vec<f64> {
|
||||
// let bandwidth = nrd(xs);
|
||||
// let curve = samples_to_continuous_pdf(samples, bandwidth);
|
||||
// return curve.ys;
|
||||
// }
|
||||
|
||||
|
||||
pub fn sampleN(xs: Vec<f32>, n: i32) -> Vec<f32> {
|
||||
let m = xs.len();
|
||||
let mut output = vec![];
|
||||
for _ in 0..n {
|
||||
output.push(xs[thread_rng().gen_range(0..m)])
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -11,20 +11,11 @@ use distribution::{monte_carlo, bandwidth};
|
|||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
// This is like the `main` function, except for JavaScript.
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main_js() -> Result<(), JsValue> {
|
||||
// This provides better error messages in debug mode.
|
||||
// It's disabled in release mode so it doesn't bloat up the file size.
|
||||
#[wasm_bindgen]
|
||||
pub fn sample_n(samples: Box<[f32]>, num_samples: i32) -> Vec<f32> {
|
||||
#[cfg(debug_assertions)]
|
||||
console_error_panic_hook::set_once();
|
||||
let samples_vec = Vec::from(samples);
|
||||
|
||||
console::log_1(&JsValue::from_str(&format!(
|
||||
"nrd(1,2,5): {}",
|
||||
bandwidth::nrd([1.0, 2.0, 5.0].to_vec())
|
||||
)));
|
||||
// Your code goes here!
|
||||
console::log_1(&JsValue::from_str(&monte_carlo::my_string()));
|
||||
|
||||
Ok(())
|
||||
monte_carlo::sampleN(samples_vec, num_samples)
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>My Rust + Webpack project!</title>
|
||||
<title>For developing squiggle-mc</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="index.js"></script>
|
||||
<h1>Testing the squiggle monte carlo module</h1>
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
2
packages/mc/ts/index.ts
Normal file
2
packages/mc/ts/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
import * as mc_rust_wasm from "../pkg";
|
||||
// console.log(mc_rust_wasm.sample_n([1,2,3,4,4,5,5,3,3,4,4,32,4,24,4,5,2,2], 1000))
|
11
packages/mc/tsconfig.json
Normal file
11
packages/mc/tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"noImplicitAny": true,
|
||||
"module": "es6",
|
||||
"target": "es5",
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node"
|
||||
}
|
||||
}
|
|
@ -3,26 +3,39 @@ const CopyPlugin = require("copy-webpack-plugin");
|
|||
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
|
||||
|
||||
const dist = path.resolve(__dirname, "dist");
|
||||
const static = path.resolve(__dirname, "static");
|
||||
|
||||
module.exports = {
|
||||
mode: "production",
|
||||
entry: {
|
||||
index: "./js/index.js"
|
||||
mode: "development",
|
||||
entry: "./ts/index.ts",
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: "ts-loader",
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
output: {
|
||||
path: dist,
|
||||
filename: "[name].js"
|
||||
},
|
||||
devServer: {
|
||||
contentBase: dist,
|
||||
filename: "[name].js",
|
||||
},
|
||||
plugins: [
|
||||
new CopyPlugin([
|
||||
path.resolve(__dirname, "static")
|
||||
]),
|
||||
|
||||
new WasmPackPlugin({
|
||||
crateDirectory: __dirname,
|
||||
}),
|
||||
]
|
||||
],
|
||||
resolve: {
|
||||
extensions: [".tsx", ".ts", ".js"]
|
||||
},
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
devServer: {
|
||||
static: {
|
||||
directory: static,
|
||||
watch: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -37,6 +37,6 @@
|
|||
"number": "+A-42-48-9-30-4"
|
||||
},
|
||||
"ppx-flags": [
|
||||
["../../node_modules/bisect_ppx/bin/linux/ppx", "--exclude-files", ".*_test\\.res$$"]
|
||||
["../../node_modules/bisect_ppx/ppx", "--exclude-files", ".*_test\\.res$$"]
|
||||
]
|
||||
}
|
||||
|
|
|
@ -11,4 +11,7 @@ module.exports = {
|
|||
".*Helpers.bs.js",
|
||||
".*Helpers.ts",
|
||||
],
|
||||
moduleNameMapper: {
|
||||
"@quri/squiggle-mc": "<rootDir>/../mc/pkg",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
"license": "MIT",
|
||||
"scripts": {
|
||||
"peggy": "peggy --cache",
|
||||
"build:mc-cached": "cd ../squiggle-mc-cached && yarn build and cd ../squiggle-lang",
|
||||
"build:mc": "cd ../mc && yarn build and cd ../squiggle-lang",
|
||||
"rescript": "rescript",
|
||||
"build": "yarn build:mc-cached && yarn build:peggy && yarn build:rescript && yarn build:typescript",
|
||||
"build": "yarn build:peggy && yarn build:rescript && yarn build:typescript",
|
||||
"build:peggy:helpers": "tsc --module commonjs --outDir src/rescript/Reducer/Reducer_Peggy/ src/rescript/Reducer/Reducer_Peggy/helpers.ts",
|
||||
"build:peggy": "yarn build:peggy:helpers && find . -type f -name *.peggy -exec yarn peggy {} \\;",
|
||||
"build:rescript": "rescript build -with-deps",
|
||||
|
|
|
@ -87,7 +87,7 @@ The former helps in cases where multiple distributions are correlated.
|
|||
However, if n > length(t), then there's no clear right answer, so we just randomly
|
||||
sample everything.
|
||||
*/
|
||||
let sampleN = (t: t, n) => {
|
||||
let sampleN' = (t: t, n) => {
|
||||
if n <= E.A.length(get(t)) {
|
||||
E.A.slice(get(t), ~offset=0, ~len=n)
|
||||
} else {
|
||||
|
@ -95,6 +95,8 @@ let sampleN = (t: t, n) => {
|
|||
}
|
||||
}
|
||||
|
||||
let sampleN = WasmInterface.sampleN
|
||||
|
||||
let _fromSampleResultArray = (samples: array<result<float, QuriSquiggleLang.Operation.Error.t>>) =>
|
||||
E.A.R.firstErrorOrOpen(samples)->E.R2.errMap(Error.fromOperationError) |> E.R2.bind(make)
|
||||
|
||||
|
|
2
packages/squiggle-lang/src/rescript/WasmInterface.res
Normal file
2
packages/squiggle-lang/src/rescript/WasmInterface.res
Normal file
|
@ -0,0 +1,2 @@
|
|||
@module external sampleN: (array<float>, int) => array<float> = "@quri/squiggle-mc/sample_n"
|
||||
let sampleN = sampleN
|
Loading…
Reference in New Issue
Block a user