diff --git a/wasm/imports.wat b/wasm/imports.wat index 6da1a0b53..ee2a3c277 100644 --- a/wasm/imports.wat +++ b/wasm/imports.wat @@ -6,9 +6,9 @@ (type $Gen_block (sub (array (mut (ref eq))))) + ;; (import "js_runtime" "print_string_mem" (func $print_string_mem (param i32) (param i32))) + (import "js_runtime" "print_string" (func $print_string (param (ref $String)))) - (import "js_runtime" "print_string_mem" - (func $print_string_mem (param i32) (param i32))) (import "js_runtime" "print_endline" (func $print_endline)) (import "js_runtime" "print_i32" (func $print_i32 (param i32))) @@ -18,9 +18,9 @@ (import "js_runtime" "flush" (func $flush)) (import "js_runtime" "atan2" (func $atan2 (param f64 f64) (result f64))) (import "js_runtime" "sin" (func $sin (param f64) (result f64))) + (import "js_runtime" "asin" (func $asin (param f64) (result f64))) (import "js_runtime" "cos" (func $cos (param f64) (result f64))) - - (import "js_runtime" "memory" (memory $mem 1)) + (import "js_runtime" "fmod" (func $fmod (param f64 f64) (result f64))) (import "runtime" "compare_ints" (func $compare_int (param (ref eq)) (param (ref eq)) (result (ref eq)))) @@ -28,6 +28,10 @@ (import "runtime" "string_eq" (func $string_eq (param $a (ref eq)) (param $b (ref eq)) (result (ref eq)))) + ;; (import "js_runtime" "memory" + (memory $mem 1) + ;; ) + (func (export "caml_int64_float_of_bits") (param $x (ref eq)) (result (ref $Float)) (struct.new $Float (f64.reinterpret_i64 @@ -83,6 +87,17 @@ call $cos ) + (func $C_asin (export "asin") (param f64) (result f64) + local.get 0 + call $asin + ) + + (func $C_fmod (export "fmod") (param f64 f64) (result f64) + local.get 1 + local.get 0 + call $fmod + ) + ;; ===== ;; Bytes ;; ===== @@ -668,11 +683,14 @@ ) + (; (func (export "print_string") (param $a (ref eq)) (result (ref eq)) (call $print_string_mem (i32.const 0) (call $copy_string (ref.cast (ref $String) (local.get $a)))) (ref.i31 (i32.const 0))) +;) + (func (export "print_endline") (param $a (ref eq)) (result (ref eq)) (call $print_endline) (ref.i31 (i32.const 0))) diff --git a/wasm/test/bench.sh b/wasm/test/bench.sh new file mode 100755 index 000000000..db68d5d5d --- /dev/null +++ b/wasm/test/bench.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +set -eu + +NODE="node-canary --stack-size=10000" + +ulimit -s 20000 + +#UNSAFE="-unsafe" +UNSAFE="" + +bench() { + echo "*** Running ${1}:" + + echo "" + + # clean-up + rm -rf *.assets *.wasm *.wat *.bc *.js || true 2> /dev/null + # compile native and wasocaml + ../../ocamlopt $UNSAFE -O3 ./${2}.ml > /dev/null + # optimize wasocaml code + wasm-opt --enable-gc --enable-reference-types --enable-multivalue --enable-tail-call --enable-nontrapping-float-to-int --traps-never-happen --skip-pass=inlining-optimizing a.out.wasm -o a.out.wasm -O3 + # compile bytecode + ocamlc $UNSAFE ./${2}.ml -o a.out.bc > /dev/null + # compile wsoo + wasm_of_ocaml compile --opt=3 ./a.out.bc -o a.wsoo.bc.js > /dev/null + # compile jsoo + js_of_ocaml compile --target-env=nodejs --opt=3 ./a.out.bc -o a.jsoo.bc.js + + # bench + hyperfine --runs 3 \ + -n "OCaml native" "./a.out" \ + -n "Wasocaml" "${NODE} ./main_node.mjs" \ + -n "Wsoo" "${NODE} ./a.wsoo.bc.js" \ + -n "Jsoo" "${NODE} ./a.jsoo.bc.js" \ + -n "Bytecode" "ocamlrun ./a.out.bc" # TODO: use ../../ocamlrun when it'll be produced + + echo "" +} + + +#bench "Almabench" "almabench" # global init must have correct type +#bench "Binary Trees" "binary_trees" # unreachable +#bench "Boyer" "boyer" # unreachable +#bench "Boyer no exceptions" "boyer_no_exc" # unreachable +#bench "Pfannkuchen" "fannkuch" # unreachable +#bench "Pfannkuchen 2" "fannkuch2" # missing "caml_string_notequal" and "caml_lessthan" +#bench "Fast Fourier Transform" "fft" # unreachable +#bench "Hamming" "hamming" # missing value let-rec +#bench "Nucleic" "nucleic" # unreachable +#bench "Ray-Trace" "raytrace" # global init must have correct type +#bench "Splay Tree" "splay" # unreachable + +bench "Knuth-Bendix" "kb" +bench "Knuth-Bendix (no exception)" "kb_no_exc" +bench "Soli" "soli" +bench "Fibonacci" "fib" +bench "Binary Decision Diagram" "bdd" +bench "Loop" "loop" +bench "Takc" "takc" +bench "Taku" "taku" +bench "Quicksort" "quicksort" diff --git a/wasm/test/main_node.mjs b/wasm/test/main_node.mjs index 04bfaa704..5042f821c 100644 --- a/wasm/test/main_node.mjs +++ b/wasm/test/main_node.mjs @@ -57,6 +57,8 @@ const bindings = { "memory": memory, "atan2": Math.atan2, "sin": Math.sin, + "asin": Math.asin, + "fmod": (x, y) => x % y, "cos": Math.cos, } diff --git a/wasm/test/test.sh b/wasm/test/test.sh index 492c9bf06..5690b3ead 100755 --- a/wasm/test/test.sh +++ b/wasm/test/test.sh @@ -1,7 +1,102 @@ #!/bin/sh -../../ocamlopt ./kb.ml -../../ocamlopt ./soli.ml -../../ocamlopt ./fib.ml -# wasm-opt --enable-gc --enable-reference-types --enable-exception-handling --enable-multivalue --enable-tail-call a.out.wasm -o a.out.wasm -O3 -python3 -m http.server 8000 --directory . +set -eu + +ULIMIT_STACK_SIZE=20000 +STACK_SIZE=10000 +NODE="node-canary --stack-size=${STACK_SIZE}" + +ulimit -s $ULIMIT_STACK_SIZE + +#UNSAFE="-unsafe" +UNSAFE="" + +bench_native() { + echo -n " OCaml native: " + ocamlopt $UNSAFE -O3 ./${2}.ml > /dev/null + ./a.out > output_${2}_ocaml_native.txt + echo "OK" +} + +bench_wasocaml_opt() { + echo -n " Wasocaml + wasm-opt (node): " + ../../ocamlopt $UNSAFE -O3 ./${2}.ml > /dev/null + wasm-opt --enable-gc --enable-reference-types --enable-multivalue --enable-tail-call --enable-nontrapping-float-to-int --traps-never-happen --skip-pass=inlining-optimizing a.out.wasm -o a.out.wasm -O3 + $NODE ./main_node.mjs > output_${2}_wasocaml_opt.txt + diff output_${2}_ocaml_native.txt output_${2}_wasocaml_opt.txt + echo "OK" +} + +bench_wasocaml() { + echo -n " Wasocaml (node): " + ../../ocamlopt $UNSAFE -O3 ./${2}.ml > /dev/null + $NODE ./main_node.mjs > output_${2}_wasocaml.txt + diff output_${2}_ocaml_native.txt output_${2}_wasocaml.txt + echo "OK" +} + +bench_wsoo() { + echo -n " wasm_of_ocaml (node): " + ocamlc $UNSAFE ./${2}.ml > /dev/null + rm -rf a.assets* a.js a.wat || true 2> /dev/null + wasm_of_ocaml compile --opt=3 ./a.out > /dev/null + $NODE ./a.js > output_${2}_wsoo.txt + diff output_${2}_ocaml_native.txt output_${2}_wsoo.txt + echo "OK" +} + +bench_jsoo() { + echo -n " js_of_ocaml (node): " + ocamlc $UNSAFE ./${2}.ml > /dev/null + rm -f a.js a.wat || true 2> /dev/null + js_of_ocaml compile --target-env=nodejs --opt=3 ./a.out + $NODE ./a.js > output_${2}_jsoo.txt + diff output_${2}_ocaml_native.txt output_${2}_jsoo.txt + echo "OK" +} + +bench_bytecode() { + echo -n " OCaml bytecode: " + ocamlc $UNSAFE ./${2}.ml > /dev/null + ocamlrun ./a.out > output_${2}_bytecode.txt + diff output_${2}_ocaml_native.txt output_${2}_bytecode.txt + echo "OK" +} + +bench() { + echo "*** Running ${1}:" + + echo "" + + bench_native "${1}" "${2}" + bench_wasocaml_opt "${1}" "${2}" + bench_wasocaml "${1}" "${2}" + bench_wsoo "${1}" "${2}" + bench_jsoo "${1}" "${2}" + bench_bytecode "${1}" "${2}" + + echo "" +} + + +#bench "Almabench" "almabench" # global init must have correct type +#bench "Binary Trees" "binary_trees" # unreachable +#bench "Boyer" "boyer" # unreachable +#bench "Boyer no exceptions" "boyer_no_exc" # unreachable +#bench "Pfannkuchen" "fannkuch" # unreachable +#bench "Pfannkuchen 2" "fannkuch2" # missing "caml_string_notequal" and "caml_lessthan" +#bench "Fast Fourier Transform" "fft" # unreachable +#bench "Hamming" "hamming" # missing value let-rec +#bench "Nucleic" "nucleic" # unreachable +#bench "Ray-Trace" "raytrace" # global init must have correct type +#bench "Splay Tree" "splay" # unreachable + +bench "Knuth-Bendix" "kb" +bench "Knuth-Bendix (no exception)" "kb_no_exc" +bench "Soli" "soli" +bench "Fibonacci" "fib" +bench "Binary Decision Diagram" "bdd" +bench "Loop" "loop" +bench "Takc" "takc" +bench "Taku" "taku" +bench "Quicksort" "quicksort" diff --git a/wasm/test/test_node.sh b/wasm/test/test_node.sh deleted file mode 100755 index d7057b950..000000000 --- a/wasm/test/test_node.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/sh - -set -eu - -alias time='/usr/bin/time -f"real %e user %U sys %S"' - -ULIMIT_STACK_SIZE=20000 -STACK_SIZE=10000 -NODE="node-canary --stack-size=${STACK_SIZE}" - -ulimit -s $ULIMIT_STACK_SIZE - -#UNSAFE="-unsafe" -UNSAFE="" - -bench_native() { - echo -n " OCaml native: " - ocamlopt $UNSAFE -O3 ./${2}.ml > /dev/null - time ./a.out > output_${2}_ocaml_native.txt -} - -bench_wasocaml_opt() { - echo -n " Wasocaml + wasm-opt (node): " - ../../ocamlopt $UNSAFE -O3 ./${2}.ml > /dev/null - wasm-opt --enable-gc --enable-reference-types --enable-multivalue --enable-tail-call --enable-nontrapping-float-to-int --traps-never-happen --skip-pass=inlining-optimizing a.out.wasm -o a.out.wasm -O3 - time $NODE ./main_node.mjs > output_${2}_wasocaml_opt.txt - diff output_${2}_ocaml_native.txt output_${2}_wasocaml_opt.txt -} - -bench_wasocaml() { - echo -n " Wasocaml (node): " - ../../ocamlopt $UNSAFE -O3 ./${2}.ml > /dev/null - time $NODE ./main_node.mjs > output_${2}_wasocaml.txt - diff output_${2}_ocaml_native.txt output_${2}_wasocaml.txt -} - -bench_wsoo() { - echo -n " wasm_of_ocaml (node): " - ocamlc $UNSAFE ./${2}.ml > /dev/null - rm -rf a.assets* a.js a.wat || true 2> /dev/null - wasm_of_ocaml compile --opt=3 ./a.out > /dev/null - time $NODE ./a.js > output_${2}_wsoo.txt - diff output_${2}_ocaml_native.txt output_${2}_wsoo.txt -} - -bench_jsoo() { - echo -n " js_of_ocaml (node): " - ocamlc $UNSAFE ./${2}.ml > /dev/null - rm -f a.js a.wat || true 2> /dev/null - js_of_ocaml compile --target-env=nodejs --opt=3 ./a.out - time $NODE ./a.js > output_${2}_jsoo.txt - diff output_${2}_ocaml_native.txt output_${2}_jsoo.txt -} - -bench_bytecode() { - echo -n " OCaml bytecode: " - ocamlc $UNSAFE ./${2}.ml > /dev/null - time ocamlrun ./a.out > output_${2}_bytecode.txt - diff output_${2}_ocaml_native.txt output_${2}_bytecode.txt -} - -bench() { - echo "*** Running ${1}:" - - echo "" - - bench_native "${1}" "${2}" - bench_wasocaml_opt "${1}" "${2}" - #bench_wasocaml "${1}" "${2}" - bench_wsoo "${1}" "${2}" - bench_jsoo "${1}" "${2}" - bench_bytecode "${1}" "${2}" - - echo "" -} - - -#bench "Almabench" "almabench" # global init must have correct type -#bench "Binary Trees" "binary_trees" # unreachable -#bench "Boyer" "boyer" # unreachable -#bench "Boyer no exceptions" "boyer_no_exc" # unreachable -#bench "Pfannkuchen" "fannkuch" # unreachable -#bench "Pfannkuchen 2" "fannkuch2" # missing "caml_string_notequal" and "caml_lessthan" -#bench "Fast Fourier Transform" "fft" # unreachable -#bench "Hamming" "hamming" # missing value let-rec -#bench "Nucleic" "nucleic" # unreachable -#bench "Ray-Trace" "raytrace" # global init must have correct type -#bench "Splay Tree" "splay" # unreachable - -bench "Knuth-Bendix" "kb" -bench "Knuth-Bendix (no exception)" "kb_no_exc" -bench "Soli" "soli" -bench "Fibonacci" "fib" -bench "Binary Decision Diagram" "bdd" -bench "Loop" "loop" -bench "Takc" "takc" -bench "Taku" "taku" -bench "Quicksort" "quicksort"