├── .gitignore ├── .hgignore ├── LICENSE.TXT ├── README.md ├── asmjs.html ├── asmjs ├── perf_all_together.js ├── perf_in_place.js ├── perf_typed_array.js ├── perf_use_asm.js ├── perf_util.js └── tests.js ├── btn_anchor.js ├── c.html ├── contents_ul.js ├── d.html ├── examples.js ├── examples_c.js ├── expl.js ├── expl ├── asmjs_complex_numbers_check.js ├── asmjs_complex_numbers_check_direct.js ├── asmjs_dftrealflat_check.js ├── asmjs_matmulrows_zip_342_check.js ├── dftreal_flatorize.js ├── flatasmjs_array_from_array.js ├── flatasmjs_array_from_matrix.js ├── flatasmjs_array_from_ndim.js ├── flatasmjs_array_from_scalar.js ├── flatasmjs_matrix_from_array.js ├── flatasmjs_matrix_from_matrix.js ├── flatasmjs_matrix_from_scalar.js ├── flatasmjs_ndim_from_ndim.js ├── flatasmjs_scalar_from_array.js ├── flatasmjs_scalar_from_matrix.js ├── flatasmjs_scalar_from_ndim.js ├── flatasmjs_scalar_from_scalar.js ├── flatasmjs_scalarint_from_scalardouble.js ├── matmulrows_loops.js ├── matmulrows_zip.js └── matmulrows_zip_flatorize.js ├── flatorize.js ├── flatorize_asmjs.js ├── flatorize_c.js ├── flatorize_d.js ├── flatorize_type_util.js ├── index.html ├── lib ├── README.md ├── flatmat.js ├── flatmat_speedtest.html ├── flatmat_speedtest.js ├── flatmat_speedtest_layout.js └── opinel.js ├── log.js ├── misc └── d_dynamic_loading │ ├── a_research.org │ ├── try_00 │ ├── dll.d │ ├── main.d │ ├── main_dmd.sh │ ├── main_ldc2.sh │ ├── output_main_dmd.txt │ └── output_main_ldc2.txt │ └── try_01_import │ ├── mymodule.d │ └── some_package │ ├── mymodule2.d │ └── mymodule3.d ├── modifsplitradix.js ├── prettify ├── lang-apollo.js ├── lang-css.js ├── lang-hs.js ├── lang-lisp.js ├── lang-lua.js ├── lang-ml.js ├── lang-proto.js ├── lang-scala.js ├── lang-sql.js ├── lang-vb.js ├── lang-vhdl.js ├── lang-wiki.js ├── lang-yaml.js ├── prettify.css └── prettify.js ├── simple_server.py ├── speed_test.js ├── style.css ├── test ├── README.md ├── common.py ├── speed_test_c_fftw │ ├── README.md │ ├── dftreal.html │ ├── dftreal0_all.sh │ ├── dftreal0_speed_test.py │ ├── dftreal1024.results.list.json │ ├── dftreal1024.results │ │ ├── i3_besserpc_ubuntu14.04.json │ │ ├── i5_t420s_ubuntu14.04.json │ │ └── i7_dell_ubuntu15.04.json │ ├── dftreal128.results.list.json │ ├── dftreal128.results │ │ ├── i3_besserpc_ubuntu14.04.json │ │ ├── i5_t420s_ubuntu14.04.json │ │ └── i7_dell_ubuntu15.04.json │ ├── dftreal16.results.list.json │ ├── dftreal16.results │ │ ├── i3_besserpc_ubuntu14.04.json │ │ ├── i5_t420s_ubuntu14.04.json │ │ └── i7_dell_ubuntu15.04.json │ ├── dftreal256.results.list.json │ ├── dftreal256.results │ │ ├── i3_besserpc_ubuntu14.04.json │ │ ├── i5_t420s_ubuntu14.04.json │ │ └── i7_dell_ubuntu15.04.json │ ├── dftreal32.results.list.json │ ├── dftreal32.results │ │ ├── i3_besserpc_ubuntu14.04.json │ │ ├── i5_t420s_ubuntu14.04.json │ │ └── i7_dell_ubuntu15.04.json │ ├── dftreal512.results.list.json │ ├── dftreal512.results │ │ ├── i3_besserpc_ubuntu14.04.json │ │ ├── i5_t420s_ubuntu14.04.json │ │ └── i7_dell_ubuntu15.04.json │ ├── dftreal64.results.list.json │ ├── dftreal64.results │ │ ├── i3_besserpc_ubuntu14.04.json │ │ ├── i5_t420s_ubuntu14.04.json │ │ └── i7_dell_ubuntu15.04.json │ ├── dftreal_n.js │ ├── dftreal_n_browser.yak.js │ ├── dftreal_n_contents.js │ ├── dftreal_n_impl_desc.array.js │ ├── dftreal_n_intro.yak.js │ ├── dftreal_n_results.yak.js │ ├── fft-newsplit-2007-johnson-frigo.pdf │ ├── fftw-3.3.4.tar.gz │ ├── fftw3real_32bit_compile.sh │ ├── fftw3real_32bit_main.c │ ├── fftw3real_32bit_measure_main.c │ ├── fftw3real_64bit_compile.sh │ ├── fftw3real_64bit_main.c │ ├── fftw3real_64bit_measure_main.c │ ├── fftw3real_aligned_malloc_macro.h │ ├── fftw3real_common.c │ ├── fftw3real_common.h │ ├── fftw3real_test_duration_macro.h │ ├── speed_test_dftreal_all.py │ ├── speed_test_dftreal_fftw3real.py │ ├── speed_test_dftreal_flatorize_asmjs_v8.py │ ├── speed_test_dftreal_flatorize_c.py │ ├── speed_test_dftreal_flatorize_d.py │ ├── speed_test_dftreal_flatorize_v8.py │ ├── speed_test_dftreal_naive_v8.py │ ├── yak.js │ ├── yak_test.html │ └── yak_test.yak.js ├── test_all.py ├── test_asmjs.py ├── test_c.py ├── test_c.srcdir │ ├── aligned_malloc_macro.h │ ├── common.c │ ├── common.h │ └── test_duration_macro.h ├── test_d.py └── test_d.srcdir │ ├── aligned_malloc_macro.h │ ├── common.d │ ├── common_decl.d │ └── test_duration_macro.h └── try ├── symbol_flatmatmul.html ├── symbol_flatmatmul.js ├── symbol_flatmatmul_inplace.html ├── symbol_flatmatmul_inplace.js ├── symbol_matmul.html └── symbol_matmul.js /.gitignore: -------------------------------------------------------------------------------- 1 | .hg 2 | *~ 3 | *.bin 4 | *.map 5 | *.o 6 | *.s 7 | *.so 8 | DIRECTIONS.org 9 | *.outdir 10 | *.pyc 11 | .*.sh 12 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | # use glob syntax. 2 | syntax: glob 3 | 4 | .git 5 | *.elc 6 | *.bin 7 | *.exe 8 | *.pyc 9 | *~ 10 | a.out 11 | *.js.ps 12 | 13 | DIRECTIONS.org 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | flatorize 2 | ========= 3 | 4 | Generate fast implementations of mathematical expressions. 5 | 6 | ## For the hurried 7 | 8 | Here is a [practical, editable use case](http://glat.info/hafi#o=7KjcK5K99varJF%5CJXJflatorizeQZnZnvarJfJXJF%5C('alpha5float9beta5float9gamma5float-4<5H3JfloatW'9 Well encapsulated code, but slow due to function call overhead. 40 | ``` 41 | 42 | ...and let `flatorize` transform the above into very fast JavaScript code: 43 | 44 | ``` 45 | // Generated "flatorized" code == factorized + flattened 46 | // 47 | // - factorized: avoid repeating computations. 48 | // - flattened: no function call. 49 | 50 | function anonymous(a, b) { 51 | /* function (a,b) { return symbol_matmulrows_zip_gen( a, b, 3, 4, 2 ); } */ 52 | var 53 | _0 = a[0] 54 | , _1 = _0[0] 55 | , _2 = _0[1] 56 | , _3 = _0[2] 57 | , _4 = _0[3] 58 | , _5 = a[1] 59 | , _6 = _5[0] 60 | , _7 = _5[1] 61 | , _8 = _5[2] 62 | , _9 = _5[3] 63 | , _a = a[2] 64 | , _b = _a[0] 65 | , _c = _a[1] 66 | , _d = _a[2] 67 | , _e = _a[3] 68 | , _f = b[0] 69 | , _g = _f[0] 70 | , _h = _f[1] 71 | , _i = b[1] 72 | , _j = _i[0] 73 | , _k = _i[1] 74 | , _l = b[2] 75 | , _m = _l[0] 76 | , _n = _l[1] 77 | , _o = b[3] 78 | , _p = _o[0] 79 | , _q = _o[1] 80 | ; 81 | return [ [ (_1 * _g) + (_2 * _j) + (_3 * _m) + (_4 * _p), (_1 * _h) + (_2 * _k) + (_3 * _n) + (_4 * _q) ], [ (_6 * _g) + (_7 * _j) + (_8 * _m) + (_9 * _p), (_6 * _h) + (_7 * _k) + (_8 * _n) + (_9 * _q) ], [ (_b * _g) + (_c * _j) + (_d * _m) + (_e * _p), (_b * _h) + (_c * _k) + (_d * _n) + (_e * _q) ] ]; 82 | 83 | } 84 | ``` 85 | 86 | Speedups exceed +1000% in many cases, including matrix multiplication and the Discrete Fourier Transform (full results). 87 | 88 | A [plugin](flatorize_asmjs.js) permits to generate even faster JavaScript code using `TypedArray`, in an `asm.js`-compatible way. For usage explanations, see the live [page](http://glat.info/flatorize/c.html). 89 | 90 | A [plugin](flatorize_c.js) permits to generate fast C code as well. For usage explanations, see the live [page](http://glat.info/flatorize/c.html). 91 | 92 | A [plugin](flatorize_d.js) permits to generate fast D code as well. For usage explanations, see the live [page](http://glat.info/flatorize/d.html). 93 | 94 | ## More 95 | 96 | For more details read the article: 97 | * download this repository and open [./index.html](index.html) 98 | * or visit the live [page](http://glat.info/flatorize) including [extensive speed tests on the Discrete Fourier Transform](http://glat.info/flatorize/test/speed_test_c_fftw/dftreal.html) 99 | * you can also run the [unit tests and speed tests](test) yourself 100 | 101 | See also the [slides](http://glat.info/bpjs2014/index.html) and [video](http://www.youtube.com/watch?v=FxNNSvNDbW8) from the Budapest 2014 nodebp/bpjs meetup. 102 | -------------------------------------------------------------------------------- /asmjs/perf_all_together.js: -------------------------------------------------------------------------------- 1 | /*global console document asmjs_perf_all_together genflatcode_asmjs_dftreal1024flat asmjs_remove_all_together_from_gen asmjs_perf_compare_gen_dft asmjs_perf_format_one_result dftreal1024flat_asmjsGen*/ 2 | 3 | function asmjs_perf_all_together() 4 | { 5 | // Make sure we have an implementation 6 | genflatcode_asmjs_dftreal1024flat(); 7 | 8 | // For a meaningful comparison we need to deactivate asm.js 9 | // because asm.js would compile the Typed Array version, 10 | // but not the normal array version. 11 | var flatorize = { 12 | fun : dftreal1024flat.getDirect() // Generated by `flatorize` 13 | , normal_array : true 14 | } 15 | 16 | , flatorize_asmjs = { 17 | gen : dftreal1024flat_asmjsGen 18 | } 19 | 20 | , result = asmjs_perf_compare_gen_dft( 21 | 1024 22 | , { flatorize : flatorize 23 | , flatorize_asmjs : flatorize_asmjs 24 | } 25 | ) 26 | ; 27 | 28 | console.log( 'asmjs_perf_all_together: result:', result ); 29 | 30 | var outnode = asmjs_perf_all_together.outnode; 31 | if (!outnode) 32 | { 33 | outnode = asmjs_perf_all_together.outnode = document.getElementById( 'asmjs_perf_all_together_output' ); 34 | outnode.innerHTML = ''; 35 | } 36 | 37 | outnode.innerHTML += asmjs_perf_format_one_result( 'flatorize ', result.flatorize ) + '\n' 38 | + asmjs_perf_format_one_result( 'flatorize.getAsmjsGen()', result.flatorize_asmjs ) + '\n' 39 | + '-> speedup: ' 40 | + asmjs_perf_prop_2_percent_string( result.flatorize_asmjs.speed_iter_per_sec / result.flatorize.speed_iter_per_sec ) + '\n' 41 | + '\n' 42 | ; 43 | } 44 | -------------------------------------------------------------------------------- /asmjs/perf_in_place.js: -------------------------------------------------------------------------------- 1 | /*global console document asmjs_perf_in_place genflatcode_asmjs_dftreal1024flat asmjs_remove_in_place_from_gen asmjs_perf_compare_gen_dft asmjs_perf_format_one_result dftreal1024flat_asmjsGen*/ 2 | 3 | function asmjs_perf_in_place() 4 | { 5 | // Make sure we have an implementation 6 | genflatcode_asmjs_dftreal1024flat(); 7 | 8 | // For a meaningful comparison we need to deactivate asm.js 9 | // because asm.js would compile the Typed Array version, 10 | // but not the normal array version. 11 | var with_new_output_array = { 12 | fun : dftreal1024flat.getDirect() // Generated by `flatorize` 13 | , normal_array : true 14 | } 15 | 16 | , with_in_place = { 17 | gen : asmjs_remove_typed_array_from_gen( asmjs_remove_use_asm_from_gen( dftreal1024flat_asmjsGen ) ) 18 | , normal_array : true 19 | } 20 | 21 | , result = asmjs_perf_compare_gen_dft( 22 | 1024 23 | , { with_new_output_array : with_new_output_array 24 | , with_in_place : with_in_place 25 | } 26 | ) 27 | ; 28 | 29 | console.log( 'asmjs_perf_in_place: result:', result ); 30 | 31 | var outnode = asmjs_perf_in_place.outnode; 32 | if (!outnode) 33 | { 34 | outnode = asmjs_perf_in_place.outnode = document.getElementById( 'asmjs_perf_in_place_output' ); 35 | outnode.innerHTML = ''; 36 | } 37 | 38 | outnode.innerHTML += asmjs_perf_format_one_result( 'with new output array', result.with_new_output_array ) + '\n' 39 | + asmjs_perf_format_one_result( 'with in-place array', result.with_in_place ) + '\n' 40 | + '-> speedup: ' 41 | + asmjs_perf_prop_2_percent_string( result.with_in_place.speed_iter_per_sec / result.with_new_output_array.speed_iter_per_sec ) + '\n' 42 | + '\n' 43 | ; 44 | } 45 | -------------------------------------------------------------------------------- /asmjs/perf_typed_array.js: -------------------------------------------------------------------------------- 1 | /*global console document asmjs_perf_typed_array genflatcode_asmjs_dftreal1024flat asmjs_remove_typed_array_from_gen asmjs_perf_compare_gen_dft asmjs_perf_format_one_result dftreal1024flat_asmjsGen*/ 2 | 3 | function asmjs_perf_typed_array() 4 | { 5 | // Make sure we have an implementation 6 | genflatcode_asmjs_dftreal1024flat(); 7 | 8 | // For a meaningful comparison we need to deactivate asm.js 9 | // because asm.js would compile the Typed Array version, 10 | // but not the normal array version. 11 | var without_asm_js_gen = asmjs_remove_use_asm_from_gen( dftreal1024flat_asmjsGen ) 12 | 13 | , with_typed_array = { gen : without_asm_js_gen } 14 | 15 | , with_normal_array = { gen : asmjs_remove_typed_array_from_gen( with_typed_array.gen ) 16 | , normal_array : true 17 | } 18 | , result = asmjs_perf_compare_gen_dft( 19 | 1024 20 | , { with_typed_array : with_typed_array 21 | , with_normal_array : with_normal_array 22 | } 23 | ) 24 | ; 25 | 26 | console.log( 'asmjs_perf_typed_array: result:', result ); 27 | 28 | var outnode = asmjs_perf_typed_array.outnode; 29 | if (!outnode) 30 | { 31 | outnode = asmjs_perf_typed_array.outnode = document.getElementById( 'asmjs_perf_typed_array_output' ); 32 | outnode.innerHTML = ''; 33 | } 34 | 35 | outnode.innerHTML += asmjs_perf_format_one_result( 'with normal array', result.with_normal_array ) + '\n' 36 | + asmjs_perf_format_one_result( 'with Typed Array', result.with_typed_array ) + '\n' 37 | + '-> speedup: ' 38 | + asmjs_perf_prop_2_percent_string( result.with_typed_array.speed_iter_per_sec / result.with_normal_array.speed_iter_per_sec ) + '\n' 39 | + '\n' 40 | ; 41 | } 42 | -------------------------------------------------------------------------------- /asmjs/perf_use_asm.js: -------------------------------------------------------------------------------- 1 | /*global console document asmjs_perf_use_asm genflatcode_asmjs_dftreal1024flat asmjs_remove_use_asm_from_gen asmjs_perf_compare_gen_dft asmjs_perf_format_one_result dftreal1024flat_asmjsGen*/ 2 | 3 | function asmjs_perf_use_asm() 4 | { 5 | // Make sure we have an implementation 6 | genflatcode_asmjs_dftreal1024flat(); 7 | 8 | var with_use_asm_gen = dftreal1024flat_asmjsGen 9 | , without_use_asm_gen = asmjs_remove_use_asm_from_gen( with_use_asm_gen ) 10 | , result = asmjs_perf_compare_gen_dft( 11 | 1024 12 | , { with_use_asm_gen : with_use_asm_gen 13 | , without_use_asm_gen : without_use_asm_gen 14 | } 15 | ) 16 | ; 17 | 18 | console.log( 'asmjs_perf_use_asm: result:', result ); 19 | 20 | var outnode = asmjs_perf_use_asm.outnode; 21 | if (!outnode) 22 | { 23 | outnode = asmjs_perf_use_asm.outnode = document.getElementById( 'asmjs_perf_use_asm_output' ); 24 | outnode.innerHTML = ''; 25 | } 26 | 27 | outnode.innerHTML += asmjs_perf_format_one_result( 'without "use asm"', result.without_use_asm_gen ) + '\n' 28 | + asmjs_perf_format_one_result( 'with "use asm"', result.with_use_asm_gen ) + '\n' 29 | + '-> speedup: ' 30 | + asmjs_perf_prop_2_percent_string( result.with_use_asm_gen.speed_iter_per_sec / result.without_use_asm_gen.speed_iter_per_sec ) + '\n' 31 | +'\n' 32 | ; 33 | } 34 | -------------------------------------------------------------------------------- /asmjs/perf_util.js: -------------------------------------------------------------------------------- 1 | /*global window ArrayBuffer console asmjs_perf_compare_gen_dft asmjs_remove_use_asm_from_gen asmjs_perf_format_one_result asmjs_perf_prop_2_percent_string asmjs_remove_typed_array_from_gen */ 2 | 3 | function asmjs_perf_format_one_result( /*string*/name, /*object*/r ) 4 | { 5 | (name || null).substring.call.a; 6 | return name + ': speed: ' + r.speed_iter_per_sec.toPrecision( 3 ) + ' iterations/second.'; 7 | } 8 | 9 | 10 | function asmjs_perf_prop_2_percent_string( x ) 11 | { 12 | var percent = 100 * (x - 1); 13 | return (percent > 0 ? '+' : '') + Math.round( percent ) + '%'; 14 | } 15 | 16 | 17 | function asmjs_perf_compare_gen_dft( /*integer*/dftsize, /*object*/candidates ) 18 | { 19 | (dftsize || null).toPrecision.call.a; 20 | 21 | console.log('asmjs_perf_compare_gen_dft: dftsize: ' + dftsize); 22 | 23 | var input = new Array(dftsize).join(',').split(',').map( Math.random ) 24 | , N = Math.round( 1e6 * 16 / dftsize ) 25 | , _emptyObj = {} 26 | , result = {} 27 | ; 28 | 29 | for (var name in candidates) { if (!(name in _emptyObj)) { // More flexible than hasOwnProperty 30 | 31 | var x = candidates[ name ] 32 | , cand = 'function' === typeof x ? { normal_array : false, gen : x } : x 33 | 34 | , duration_sec 35 | ; 36 | 37 | // Direct functional call (typical `flatorize` implementation.) 38 | 39 | if (cand.fun) 40 | { 41 | var start = Date.now(); 42 | 43 | for (var i = N; i--;) 44 | var output = cand.fun( input ); 45 | 46 | duration_sec = (Date.now() - start) / 1000; 47 | } 48 | else 49 | { 50 | // Implementation generator, typed array, in-place implementation 51 | // (typical `flatorize.getAsmjsGen()` implementation.) 52 | 53 | var use_typed_array = !cand.normal_array 54 | , gen = cand.gen 55 | 56 | , n2i = gen.array_name2info 57 | 58 | , buffer = use_typed_array ? new ArrayBuffer( gen.buffer_bytes ) : new Array( gen.count ) 59 | , compiled = gen( window, {}, buffer ) 60 | 61 | , info_arr = n2i.arr 62 | , info_freq = n2i.freq 63 | 64 | , input_view = use_typed_array && new gen.TypedArray( buffer, info_arr.begin_bytes, info_arr.n ) 65 | , output_view = use_typed_array && new gen.TypedArray( buffer, info_freq.begin_bytes, info_freq.n ) 66 | 67 | , impl = compiled[ 'dftreal' + dftsize + 'flat' ] 68 | ; 69 | 70 | if (input.length !== info_arr.n) 71 | null.bug; 72 | 73 | if (use_typed_array) 74 | input_view.set( input ); 75 | else 76 | buffer.splice.apply( buffer, [ info_arr.begin, info_arr.n ].concat( input ) ); 77 | 78 | var start = Date.now(); 79 | 80 | for (var i = N; i--;) 81 | impl(); 82 | 83 | duration_sec = (Date.now() - start) / 1000; 84 | } 85 | 86 | result[ name ] = { 87 | n_iter : N 88 | , duration_sec : duration_sec 89 | , speed_iter_per_sec : N / duration_sec 90 | }; 91 | }} 92 | 93 | return result; 94 | } 95 | 96 | 97 | 98 | function asmjs_remove_typed_array_from_gen( gen ) 99 | { 100 | var WTA = '_without_typed_array'; 101 | if (!gen[ WTA ]) 102 | { 103 | var gen_code = gen + '' 104 | , mo = /^\s*function\s+\w+?\(\s*([^\)]+)\s*\)\s*\{([\s\S]+)\}\s*$/.exec( gen_code ) 105 | , param = mo[ 1 ].replace( /\/\*.*?\*\//g, '' ) 106 | , body = mo[ 2 ] 107 | , new_body = body.replace( /new\s+stdlib\s*\.\s*\w+?Array\s*\((.*?)\)/g , '$1' ) 108 | ; 109 | if (body === new_body) 110 | throw new Error( 'Typed Array constructor call not found!' ); 111 | 112 | var new_gen = new Function( param, new_body ); 113 | 114 | // Copy the extra information like `array_name2info`, `TypedArray` etc. 115 | for (var propname in gen) { if (!(propname in new_gen)) { 116 | new_gen[ propname ] = gen[ propname ]; 117 | }} 118 | 119 | // Store in the cache 120 | 121 | gen[ WTA ] = new_gen; 122 | } 123 | return gen[ WTA ]; 124 | } 125 | 126 | 127 | function asmjs_remove_use_asm_from_gen( gen ) 128 | { 129 | var WUA = '_without_use_asm'; 130 | if (!gen[ WUA ]) 131 | { 132 | var gen_code = gen + '' 133 | , mo = /^\s*function\s+\w+?\(\s*([^\)]+)\s*\)\s*\{([\s\S]+)\}\s*$/.exec( gen_code ) 134 | , param = mo[ 1 ].replace( /\/\*.*?\*\//g, '' ) 135 | , body = mo[ 2 ] 136 | , new_body = body.replace( /(["'])use asm\1;?/g , '' ) 137 | ; 138 | if (body === new_body) 139 | throw new Error( '"use asm" not found!' ); 140 | 141 | var new_gen = new Function( param, new_body ); 142 | 143 | // Copy the extra information like `array_name2info`, `TypedArray` etc. 144 | for (var propname in gen) { if (!(propname in new_gen)) { 145 | new_gen[ propname ] = gen[ propname ]; 146 | }} 147 | 148 | // Store in the cache 149 | 150 | gen[ WUA ] = new_gen; 151 | } 152 | return gen[ WUA ]; 153 | } 154 | -------------------------------------------------------------------------------- /asmjs/tests.js: -------------------------------------------------------------------------------- 1 | /*global load generate_small_functions ...*/ 2 | 3 | if (typeof 'load' !== 'undefined') // For non-browser environment like V8 4 | { 5 | if (typeof log === 'undefined') var log = function () {}; 6 | if (typeof flatorize === 'undefined') load( 'flatorize.js' ); 7 | if (typeof generate_small_functions === 'undefined' ) load( 'examples.js' ); 8 | if (typeof flatorize.type_util === 'undefined' ) load( 'flatorize_type_util.js' ); 9 | if (typeof flatorize.getAsmjsGen === 'undefined' ) load( 'flatorize_asmjs.js' ); 10 | if (typeof dft_msr_exprgenF === 'undefined' ) load( 'modifsplitradix.js' ); 11 | 12 | if (typeof expl_run === 'undefined' ) load( 'expl.js' ); 13 | 14 | if (typeof expl_matmulrows_zip_flatorize === 'undefined') load( 'expl/matmulrows_zip_flatorize.js' ); 15 | if (typeof expl_dftreal_flatorize === 'undefined') load( 'expl/dftreal_flatorize.js' ); 16 | if (typeof asmjs_complex_numbers_check === 'undefined') load( 'expl/asmjs_complex_numbers_check.js' ); 17 | if (typeof asmjs_complex_numbers_check_direct === 'undefined') load( 'expl/asmjs_complex_numbers_check_direct.js' ); 18 | if (typeof asmjs_matmulrows_zip_342_check === 'undefined') load( 'expl/asmjs_matmulrows_zip_342_check.js' ); 19 | if (typeof asmjs_dftrealflat_check === 'undefined') load( 'expl/asmjs_dftrealflat_check.js' ); 20 | if (typeof expl_flatasmjs_scalar_from_scalar === 'undefined') load( 'expl/flatasmjs_scalar_from_scalar.js' ); 21 | if (typeof expl_flatasmjs_scalar_from_array === 'undefined') load( 'expl/flatasmjs_scalar_from_array.js' ); 22 | if (typeof expl_flatasmjs_scalar_from_matrix === 'undefined') load( 'expl/flatasmjs_scalar_from_matrix.js' ); 23 | if (typeof expl_flatasmjs_scalar_from_ndim === 'undefined') load( 'expl/flatasmjs_scalar_from_ndim.js' ); 24 | if (typeof expl_flatasmjs_array_from_scalar === 'undefined') load( 'expl/flatasmjs_array_from_scalar.js' ); 25 | if (typeof expl_flatasmjs_array_from_array === 'undefined') load( 'expl/flatasmjs_array_from_array.js' ); 26 | if (typeof expl_flatasmjs_array_from_matrix === 'undefined') load( 'expl/flatasmjs_array_from_matrix.js' ); 27 | if (typeof expl_flatasmjs_array_from_ndim === 'undefined') load( 'expl/flatasmjs_array_from_ndim.js' ); 28 | if (typeof expl_flatasmjs_matrix_from_scalar === 'undefined') load( 'expl/flatasmjs_matrix_from_scalar.js' ); 29 | if (typeof expl_flatasmjs_matrix_from_array === 'undefined') load( 'expl/flatasmjs_matrix_from_array.js' ); 30 | if (typeof expl_flatasmjs_matrix_from_matrix === 'undefined') load( 'expl/flatasmjs_matrix_from_matrix.js' ); 31 | if (typeof expl_flatasmjs_ndim_from_ndim === 'undefined') load( 'expl/flatasmjs_ndim_from_ndim.js' ); 32 | if (typeof expl_flatasmjs_scalarint_from_scalardouble === 'undefined') load( 'expl/flatasmjs_scalarint_from_scalardouble.js' ); 33 | } 34 | 35 | generate_small_functions(); 36 | 37 | (function () { 38 | 39 | asmjs_complex_numbers_check(); 40 | asmjs_complex_numbers_check_direct(); 41 | asmjs_matmulrows_zip_342_check(); 42 | 43 | asmjs_dftrealflat_check( 8 ); 44 | 45 | asmjs_dftrealflat_check( 16 ); 46 | 47 | // xxx still an issue with some gcc -> memory usage explodes 48 | if ('undefined' === typeof document && 'undefined' === typeof window) 49 | asmjs_dftrealflat_check( 1024 ); // Too slow - not in the browser 50 | 51 | 52 | var vsize = 10; 53 | 54 | passed.expl_flatasmjs_scalar_from_scalar = expl_run( expl_flatasmjs_scalar_from_scalar, { doc_silent : true, args : [ ] } ); 55 | 56 | passed.expl_flatasmjs_scalar_from_array = expl_run( expl_flatasmjs_scalar_from_array, { doc_silent : true, args : [ vsize ] } ); 57 | 58 | passed.expl_flatasmjs_scalar_from_matrix = expl_run( expl_flatasmjs_scalar_from_matrix, { doc_silent : true, args : [ vsize, vsize + 3 ] } ); 59 | 60 | passed.expl_flatasmjs_scalar_from_ndim_2 = expl_run( expl_flatasmjs_scalar_from_ndim, { doc_silent : true, args : [ [ vsize, vsize + 3 ] ] } ); 61 | 62 | passed.expl_flatasmjs_scalar_from_ndim_3 = expl_run( expl_flatasmjs_scalar_from_ndim, { doc_silent : true, args : [ [ 4, 5, 3 ] ] } ); 63 | 64 | passed.expl_flatasmjs_scalar_from_ndim_4 = expl_run( expl_flatasmjs_scalar_from_ndim, { doc_silent : true, args : [ [ 5, 4, 3, 2 ] ] } ); 65 | 66 | 67 | passed.expl_flatasmjs_array_from_scalar = expl_run( expl_flatasmjs_array_from_scalar, { doc_silent : true, args : [ vsize ] } ); 68 | 69 | passed.expl_flatasmjs_array_from_array = expl_run( expl_flatasmjs_array_from_array, { doc_silent : true, args : [ vsize ] } ); 70 | 71 | passed.expl_flatasmjs_array_from_matrix = expl_run( expl_flatasmjs_array_from_matrix, { doc_silent : true, args : [ vsize, vsize + 3 ] } ); 72 | 73 | passed.expl_flatasmjs_array_from_ndim_2 = expl_run( expl_flatasmjs_array_from_ndim, { doc_silent : true, args : [ [ vsize, vsize + 3 ] ] } ); 74 | 75 | passed.expl_flatasmjs_array_from_ndim_3 = expl_run( expl_flatasmjs_array_from_ndim, { doc_silent : true, args : [ [ 5, 4, 3 ] ] } ); 76 | 77 | passed.expl_flatasmjs_array_from_ndim_4 = expl_run( expl_flatasmjs_array_from_ndim, { doc_silent : true, args : [ [ 4, 5, 3, 2 ] ] } ); 78 | 79 | 80 | passed.expl_flatasmjs_matrix_from_scalar = expl_run( expl_flatasmjs_matrix_from_scalar, { doc_silent : true, args : [ vsize, vsize + 3 ] } ); 81 | 82 | passed.expl_flatasmjs_matrix_from_array = expl_run( expl_flatasmjs_matrix_from_array, { doc_silent : true, args : [ vsize ] } ); 83 | 84 | passed.expl_flatasmjs_matrix_from_matrix = expl_run( expl_flatasmjs_matrix_from_matrix, { doc_silent : true, args : [ vsize, vsize + 3 ] } ); 85 | 86 | passed.expl_flatasmjs_matrix_from_ndim_3 = expl_run( expl_flatasmjs_ndim_from_ndim, { doc_silent : true, args : [ [ 5, 4, 3 ], [ 6, 10 ] ] } ); 87 | 88 | passed.expl_flatasmjs_matrix_from_ndim_4 = expl_run( expl_flatasmjs_ndim_from_ndim, { doc_silent : true, args : [ [ 5, 4, 3, 2 ], [ 12, 10 ] ] } ); 89 | 90 | 91 | passed.expl_flatasmjs_ndim_3_from_array = expl_run( expl_flatasmjs_ndim_from_ndim, { doc_silent : true, args : [ [ 60 ], [ 5, 4, 3 ] ] } ); 92 | 93 | passed.expl_flatasmjs_ndim_3_from_matrix = expl_run( expl_flatasmjs_ndim_from_ndim, { doc_silent : true, args : [ [ 30, 2 ], [ 5, 4, 3 ] ] } ); 94 | 95 | passed.expl_flatasmjs_ndim_4_from_array = expl_run( expl_flatasmjs_ndim_from_ndim, { doc_silent : true, args : [ [ 120 ], [ 5, 4, 3, 2 ] ] } ); 96 | 97 | passed.expl_flatasmjs_ndim_4_from_matrix = expl_run( expl_flatasmjs_ndim_from_ndim, { doc_silent : true, args : [ [ 4, 30 ], [ 5, 4, 3, 2 ] ] } ); 98 | 99 | passed.expl_flatasmjs_ndim_4_from_ndim_3 = expl_run( expl_flatasmjs_ndim_from_ndim, { doc_silent : true, args : [ [ 5, 12, 2 ], [ 5, 4, 3, 2 ] ] } ); 100 | 101 | // Cast tests 102 | 103 | passed.expl_flatasmjs_scalarint_from_scalardouble = expl_run( expl_flatasmjs_scalarint_from_scalardouble, { doc_silent : true, args : [ ] } ); 104 | 105 | })(); 106 | -------------------------------------------------------------------------------- /btn_anchor.js: -------------------------------------------------------------------------------- 1 | [].forEach.call( document.getElementsByTagName( 'button' ), function (btn_node) { btn_node.removeAttribute( 'disabled' ); } ); 2 | window.ontouchstart = function () { Array.prototype.forEach.call( document.getElementsByClassName( "anchor" ), function (node) { node.className = node.className.replace( /\banchor\b/g, '' ); } ); }; 3 | -------------------------------------------------------------------------------- /contents_ul.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var d = document 4 | , gEBCN = 'getElementsByClassName' 5 | ; 6 | 7 | [].forEach.call( d[ gEBCN ]( 'contents-ul' ), fill_up_contents_ul ); 8 | 9 | function fill_up_contents_ul( ul ) 10 | { 11 | // Read from the DOM 12 | 13 | var arr = [].slice.call( d[ gEBCN ]( 'anchorable' ) ) 14 | , tn = arr.map( function (node) { return node.tagName.toUpperCase(); } ) 15 | , big = tn.reduce( function (a,b) { return a' + a.outerHTML + ''; 42 | } 43 | } 44 | 45 | })(); 46 | -------------------------------------------------------------------------------- /examples_c.js: -------------------------------------------------------------------------------- 1 | /* 2 | Tests for "./flatorize_c.js" 3 | 4 | Most tests are similar to those of ./examples.js 5 | 6 | The main difference is that: 7 | 8 | * in ./examples.js, we code arrays of complexes as arrays of arrays: 9 | [ [ re, im ], [ re, im ], ... ] 10 | 11 | * here, to prevent having to define a struct, we implement them as: 12 | [ re, im, re, im, ... ] 13 | 14 | * xxx later on we'll try a struct 15 | 16 | 17 | Copyright 2013 Guillaume Lathoud 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | Unless required by applicable law or agreed to in writing, software 26 | distributed under the License is distributed on an "AS IS" BASIS, 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | See the License for the specific language governing permissions and 29 | limitations under the License. 30 | 31 | A copy of the Apache License Version 2.0 as of February 20th, 2013 32 | can be found in the file ./LICENSE.TXT 33 | */ 34 | 35 | 36 | -------------------------------------------------------------------------------- /expl.js: -------------------------------------------------------------------------------- 1 | function augment_name_value_array_with_mapping( /*array of objects { name : ... , value : ... }*/nv_arr ) 2 | { 3 | nv_arr.forEach( augment_one ); 4 | return nv_arr; 5 | 6 | function augment_one( o ) 7 | { 8 | var name = o.name 9 | , value = o.value 10 | ; 11 | (name || null).substring.call.a; 12 | 13 | nv_arr[ name ] = value; 14 | } 15 | } 16 | 17 | function f2body( f ) 18 | { 19 | var fs = f+''; 20 | 21 | var mo_begin = /^(((?![\r\n])\s)*)\/\/#BEGIN_BODY\s*^/m.exec( fs ); 22 | if (mo_begin) 23 | { 24 | var n_indent = mo_begin[ 1 ].length 25 | , mo_end = /^(((?![\r\n])\s)*)\/\/#END_BODY\s*$/m.exec( fs ) 26 | ; 27 | return fs.substring( mo_begin.index + mo_begin[0].length, mo_end.index ) 28 | .replace( new RegExp( '(^|[\\r\\n])((?![\\r\\n])\\s){' + n_indent + ',' + n_indent + '}', 'g' ) , '$1' ) 29 | ; 30 | } 31 | 32 | return (f+'').replace(/^[^\{]*?\{([\s\S]*)\}[^\}]*$/, '$1' ) 33 | } 34 | 35 | function expl_run( f, /*?object?*/opt ) 36 | { 37 | var opt_args = opt && opt.args 38 | , doc_silent = opt && opt.doc_silent 39 | , PRECISION = 1e-9 40 | ; 41 | 42 | try { 43 | var r = f.apply( null, opt_args ) 44 | , s_expected = JSON.stringify( cut_precision( r.expected ) ) 45 | , s_obtained = JSON.stringify( cut_precision( r.obtained ) ) 46 | 47 | , ok = s_expected === s_obtained 48 | 49 | , html_expected = html_escape( s_expected ) 50 | , html_obtained = html_escape( s_obtained ) 51 | ; 52 | if (!doc_silent) 53 | document.write( f2body( f ) + '\n// ' + r.name + ': ' + html_obtained + (ok ? ' // Yes!' : ' // NOOOO!\n//\n// expected:\n// ' + r.name + ': ' + html_expected ) ); 54 | } catch (e) { 55 | if (doc_silent) 56 | throw e; 57 | else 58 | document.write( '--- expl_run: FAILED! ---\n\ne:\n\n' + e ); 59 | ok = false; 60 | } 61 | return ok; 62 | 63 | function cut_precision( x ) 64 | { 65 | var tof_x = typeof x; 66 | 67 | if ('number' === tof_x) 68 | return Math.round(x/PRECISION)*PRECISION; 69 | 70 | if ('object' === tof_x) 71 | { 72 | var ret = x instanceof Array ? [] : {}; 73 | for (var k in x) { if (!(k in ret)) { // More flexible than hasOwnProperty 74 | ret[ k ] = cut_precision( x[ k ] ); 75 | }} 76 | return ret; 77 | } 78 | 79 | return x; 80 | } 81 | 82 | function html_escape( s ) 83 | { 84 | return s 85 | .replace( /&/g, '&' ) 86 | .replace( //g, '>' ) 88 | .replace( /"/g, '"' ) 89 | .replace( /'/g, ''' ) 90 | ; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /expl/asmjs_complex_numbers_check.js: -------------------------------------------------------------------------------- 1 | /*global passed asmjs_complex_numbers_check f2_asmjsGen ArrayBuffer window Float32Array*/ 2 | 3 | var passed, passed_asmjsgen_info, f2_asmjsGen; 4 | function asmjs_complex_numbers_check() 5 | { 6 | var NAME = 'asmjs_complex_numbers_check'; 7 | 8 | (passed || (passed = {}))[ NAME ] = false; 9 | 10 | // "Complex numbers" example 11 | 12 | var info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 13 | cfg : { switcher: f2, name: "f2" } 14 | , input : augment_name_value_array_with_mapping( [ 15 | { name : "a", value : [1.2, -3.4] } 16 | , { name : "b", value : [0, 1] } 17 | , { name : "c", value : [-1, 9.99] } 18 | ] ) 19 | , output : augment_name_value_array_with_mapping( [ 20 | { 21 | name : 'd' 22 | , value : [ 23 | 1.2 - 2*(0 + -1) 24 | , -3.4 - 2*(1 + 9.99) 25 | ] 26 | } 27 | ] ) 28 | }; 29 | 30 | if (typeof f2_asmjsGen === 'undefined') 31 | f2_asmjsGen = flatorize.getAsmjsGen( info.cfg ); 32 | 33 | // --- Inputs and output 34 | var f2_buffer = new ArrayBuffer( f2_asmjsGen.buffer_bytes ); 35 | 36 | // --- Compile the asm.js code 37 | 38 | var f2_asmjsO = f2_asmjsGen( this, {}, f2_buffer ); 39 | 40 | // --- Example of use 41 | // Input views 42 | var n2i = f2_asmjsGen.array_name2info 43 | , TypedArray = f2_asmjsGen.TypedArray 44 | 45 | , a = new TypedArray( f2_buffer, n2i.a.begin_bytes, n2i.a.n ) 46 | , b = new TypedArray( f2_buffer, n2i.b.begin_bytes, n2i.b.n ) 47 | , c = new TypedArray( f2_buffer, n2i.c.begin_bytes, n2i.c.n ) 48 | // Output view 49 | , d = new TypedArray( f2_buffer, n2i.d.begin_bytes, n2i.d.n ) 50 | ; 51 | 52 | // Write input values 53 | a.set( info.input.a ); 54 | b.set( info.input.b ); 55 | c.set( info.input.c ); 56 | 57 | // Compute 58 | f2_asmjsO.f2(); 59 | 60 | 61 | // The result is accessible through `d` 62 | var error_v = [ 63 | d[ 0 ] - info.output.d[ 0 ] 64 | , d[ 1 ] - info.output.d[ 1 ] 65 | ] 66 | , error = Math.max.apply( Math, error_v.map( 67 | function (delta) { return Math.abs( delta ); } 68 | ) ) 69 | ; 70 | if (1e-4 < error) 71 | throw new Error( NAME + ' failed!' ); 72 | 73 | (passed || (passed = {}))[ NAME ] = true; 74 | } 75 | -------------------------------------------------------------------------------- /expl/asmjs_complex_numbers_check_direct.js: -------------------------------------------------------------------------------- 1 | /*global passed asmjs_complex_numbers_check_direct f2_asmjsGen_direct ArrayBuffer window Float32Array*/ 2 | 3 | var passed, passed_asmjsgen_info, f2_asmjsGen_direct; 4 | function asmjs_complex_numbers_check_direct() 5 | { 6 | var NAME = 'asmjs_complex_numbers_check_direct'; 7 | 8 | (passed || (passed = {}))[ NAME ] = false; 9 | 10 | // "Complex numbers" example 11 | 12 | var info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 13 | cfg : { 14 | name : 'f2' 15 | , varstr : 'a:[2 float],b:[2 float],c:[2 float]->d:[2 float]' 16 | , exprgen : f2.exprgen 17 | } 18 | , input : augment_name_value_array_with_mapping( [ 19 | { name : "a", value : [1.2, -3.4] } 20 | , { name : "b", value : [0, 1] } 21 | , { name : "c", value : [-1, 9.99] } 22 | ] ) 23 | , output : augment_name_value_array_with_mapping( [ 24 | { 25 | name : 'd' 26 | , value : [ 27 | 1.2 - 2*(0 + -1) 28 | , -3.4 - 2*(1 + 9.99) 29 | ] 30 | } 31 | ] ) 32 | }; 33 | 34 | if (typeof f2_asmjsGen_direct === 'undefined') 35 | f2_asmjsGen_direct = flatorize.getAsmjsGen( info.cfg ); 36 | 37 | // --- Inputs and output 38 | var f2_buffer = new ArrayBuffer( f2_asmjsGen_direct.buffer_bytes ); 39 | 40 | // --- Compile the asm.js code 41 | 42 | var f2_asmjsO = f2_asmjsGen_direct( this, {}, f2_buffer ); 43 | 44 | // --- Example of use 45 | // Input views 46 | var n2i = f2_asmjsGen_direct.array_name2info 47 | , TypedArray = f2_asmjsGen_direct.TypedArray 48 | 49 | , a = new TypedArray( f2_buffer, n2i.a.begin_bytes, n2i.a.n ) 50 | , b = new TypedArray( f2_buffer, n2i.b.begin_bytes, n2i.b.n ) 51 | , c = new TypedArray( f2_buffer, n2i.c.begin_bytes, n2i.c.n ) 52 | // Output view 53 | , d = new TypedArray( f2_buffer, n2i.d.begin_bytes, n2i.d.n ) 54 | ; 55 | 56 | // Write input values 57 | a.set( info.input.a ); 58 | b.set( info.input.b ); 59 | c.set( info.input.c ); 60 | 61 | // Compute 62 | f2_asmjsO.f2(); 63 | 64 | 65 | // The result is accessible through `d` 66 | var error_v = [ 67 | d[ 0 ] - info.output.d[ 0 ] 68 | , d[ 1 ] - info.output.d[ 1 ] 69 | ] 70 | , error = Math.max.apply( Math, error_v.map( 71 | function (delta) { return Math.abs( delta ); } 72 | ) ) 73 | ; 74 | if (1e-4 < error) 75 | throw new Error( NAME + ' failed!' ); 76 | 77 | (passed || (passed = {}))[ NAME ] = true; 78 | } 79 | -------------------------------------------------------------------------------- /expl/asmjs_dftrealflat_check.js: -------------------------------------------------------------------------------- 1 | /*global passed asmjs_complex_numbers_check matmulrows_zip_342_asmjsGen ArrayBuffer window Float32Array*/ 2 | 3 | var passed, passed_asmjsgen_info; 4 | function asmjs_dftrealflat_check( /*integer, e.g. 16 or 1024*/dftsize, /*?boolean?*/hermihalf, /*?object?*/opt ) 5 | { 6 | var precision = opt && opt.precision || 'double' 7 | , ERROR_MAX = precision === 'double' ? 1e-10 : precision === 'float' ? 1e-4 : null.unsupported_precision; 8 | ; 9 | 10 | var NAME = 'asmjs_dftreal' + dftsize + 'flat' + (hermihalf ? '_hermihalf' : '') + '_' + precision + '_check'; 11 | 12 | (passed || (passed = {}))[ NAME ] = false; 13 | 14 | // "DFT REAL" example 15 | 16 | var NAME_FLAT = 'dftreal' + dftsize + 'flat' + (hermihalf ? '_hermihalf' : '') + '_' + precision 17 | , NAME_ASMJSGEN = NAME_FLAT + '_asmjsGen' 18 | 19 | , dftrealflat = this[ NAME_FLAT ] 20 | , dftrealflat_asmjsGen = this[ NAME_ASMJSGEN ] 21 | ; 22 | if (typeof dftrealflat === 'undefined') 23 | { 24 | expl_dftreal_flatorize( dftsize, hermihalf, opt ); 25 | dftrealflat = expl_dftreal_flatorize[ NAME_FLAT ]; 26 | } 27 | 28 | var io = get_dftreal_sin_input_output_for_check( dftsize, hermihalf ); 29 | 30 | var info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 31 | cfg : { 32 | switcher: dftrealflat 33 | , name: NAME_FLAT 34 | } 35 | , input : augment_name_value_array_with_mapping( [ 36 | { 37 | name : "arr" 38 | , value : io.input 39 | } 40 | ] ) 41 | , output : augment_name_value_array_with_mapping( [ 42 | { 43 | name : 'freq' 44 | , value : io.expected 45 | } 46 | ] ) 47 | }; 48 | 49 | if (typeof dftrealflat_asmjsGen === 'undefined') 50 | { 51 | var dftrealflat_asmjsGen = flatorize.getAsmjsGen( 52 | info.cfg 53 | ); 54 | } 55 | 56 | // --- Inputs and output 57 | 58 | var dftrealflat_buffer = 59 | new ArrayBuffer( dftrealflat_asmjsGen.buffer_bytes ) 60 | ; 61 | 62 | // --- (independent) sanity check: naive, non-flatorized implementation 63 | 64 | var radix = Math.round( Math.log( dftsize ) / Math.log( 2 ) ) 65 | , naive_impl = dft_msr_naive_genF( radix, { real : true, hermihalf : hermihalf } ) 66 | , naive_freq = naive_impl( info.input.arr ) 67 | ; 68 | check_error( naive_freq, info.output.freq ); 69 | 70 | // --- Compile the asm.js code 71 | var dftrealflat_asmjsO = dftrealflat_asmjsGen( 72 | this, {}, dftrealflat_buffer 73 | ); 74 | 75 | // --- Example of use 76 | 77 | var n2i = dftrealflat_asmjsGen.array_name2info 78 | , TypedArray = dftrealflat_asmjsGen.TypedArray 79 | 80 | // Input views 81 | 82 | , arr = new TypedArray( 83 | dftrealflat_buffer, n2i.arr.begin_bytes, n2i.arr.n 84 | ) 85 | 86 | // Output view 87 | 88 | , freq = new TypedArray( 89 | dftrealflat_buffer, n2i.freq.begin_bytes, n2i.freq.n 90 | ) 91 | ; 92 | 93 | // Write input values 94 | 95 | arr.set( info.input.arr ); 96 | 97 | // Compute 98 | 99 | //#COMPUTE_BEGIN 100 | dftrealflat_asmjsO[ NAME_FLAT ](); 101 | //#COMPUTE_END 102 | 103 | // The result is accessible through `freq` 104 | 105 | check_error( freq, info.output.freq ); 106 | 107 | // Sanity check: original flatorized implementation 108 | 109 | var original_freq = dftrealflat( info.input.arr ); 110 | check_error( original_freq, info.output.freq ); 111 | 112 | // Finer check on a random vector: are the two implementation 113 | // consistent? (Don't worry, the original one is independently 114 | // proofed in ./index.html). 115 | 116 | var random_input = new Array( dftsize ).join(',').split(',').map( Math.random ) 117 | , original_output = dftrealflat( random_input ) 118 | ; 119 | arr.set( random_input ); 120 | dftrealflat_asmjsO[ NAME_FLAT ](); 121 | 122 | check_error( freq, original_output ); 123 | 124 | // 125 | 126 | (passed || (passed = {}))[ NAME ] = true; 127 | 128 | // --- Details 129 | 130 | function check_error( obtained, expected ) 131 | { 132 | var error_v = get_error( flattened( obtained ), flattened( expected ) ); 133 | 134 | if (error_v.some( isNaN )) 135 | throw new Error( NAME + ' failed! Got some NaN(s).' ); 136 | 137 | var error = Math.max.apply( Math, error_v.map( 138 | function (delta) { return Math.abs( delta ); } 139 | ) ) 140 | ; 141 | if (ERROR_MAX < error) 142 | throw new Error( NAME + ' failed! Observed error: ' + error ); 143 | } 144 | 145 | function get_error( obtained_flat, expected_flat ) 146 | { 147 | return expected_flat.map( function (number,i) { return number - obtained_flat[ i ]; } ); 148 | } 149 | 150 | 151 | function flattened( an_array ) 152 | { 153 | return [].reduce.call( 154 | an_array 155 | ,function (a,b) { return a.concat(b); } 156 | , [] 157 | ); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /expl/asmjs_matmulrows_zip_342_check.js: -------------------------------------------------------------------------------- 1 | /*global passed asmjs_complex_numbers_check matmulrows_zip_342_asmjsGen ArrayBuffer window Float32Array*/ 2 | 3 | var passed, passed_asmjsgen_info; 4 | function asmjs_matmulrows_zip_342_check() 5 | { 6 | var NAME = 'asmjs_matmulrows_zip_342_check'; 7 | 8 | (passed || (passed = {}))[ NAME ] = false; 9 | 10 | // "Matrix multiplication" example 11 | 12 | var matmulrows_zip_342 = this.matmulrows_zip_342 13 | , matmulrows_zip_342_asmjsGen = this.matmulrows_zip_342_asmjsGen 14 | ; 15 | if (typeof matmulrows_zip_342 === 'undefined') 16 | { 17 | expl_matmulrows_zip_flatorize(); 18 | matmulrows_zip_342 = expl_matmulrows_zip_flatorize.matmulrows_zip_342; 19 | } 20 | 21 | 22 | var info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 23 | cfg : { 24 | switcher: matmulrows_zip_342 25 | , name: "matmulrows_zip_342" 26 | } 27 | , input : augment_name_value_array_with_mapping( [ 28 | { 29 | name : 'a' 30 | , value : [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ] 31 | } 32 | , { 33 | name : 'b' 34 | , value : [ [13,14], [15,16], [17,18], [19,20] ] 35 | } 36 | 37 | ] ) 38 | , output : augment_name_value_array_with_mapping( [ 39 | { 40 | name : 'c' 41 | , value : [[170,180],[426,452],[682,724]] 42 | } 43 | ] ) 44 | }; 45 | 46 | 47 | if (typeof matmulrows_zip_342_asmjsGen === 'undefined') 48 | matmulrows_zip_342_asmjsGen = flatorize.getAsmjsGen( info.cfg ); 49 | 50 | 51 | // --- Inputs and output 52 | var matmulrows_zip_342_buffer = 53 | new ArrayBuffer( matmulrows_zip_342_asmjsGen.buffer_bytes ); 54 | 55 | // --- Compile the asm.js code 56 | var matmulrows_zip_342_asmjsO = matmulrows_zip_342_asmjsGen( 57 | this, {}, matmulrows_zip_342_buffer 58 | ); 59 | 60 | // --- Example of use 61 | 62 | var n2i = matmulrows_zip_342_asmjsGen.array_name2info 63 | , TypedArray = matmulrows_zip_342_asmjsGen.TypedArray 64 | 65 | // Input views 66 | 67 | , a = new TypedArray( matmulrows_zip_342_buffer, n2i.a.begin_bytes, n2i.a.n ) 68 | , b = new TypedArray( matmulrows_zip_342_buffer, n2i.b.begin_bytes, n2i.b.n ) 69 | 70 | // Output view 71 | 72 | , c = new TypedArray( matmulrows_zip_342_buffer, n2i.c.begin_bytes, n2i.c.n ) 73 | ; 74 | 75 | // Write input values 76 | 77 | set_rows( a, info.input.a ); 78 | set_rows( b, info.input.b ); 79 | 80 | // Compute 81 | 82 | matmulrows_zip_342_asmjsO.matmulrows_zip_342(); 83 | 84 | // The result is accessible through `c` 85 | 86 | var error_v = info.output.c 87 | .reduce( function (a,b) { return a.concat(b); }, [] ) 88 | .map( function (number,i) { return number - c[ i ]; } ) 89 | 90 | , error = Math.max.apply( Math, error_v.map( 91 | function (delta) { return Math.abs( delta ); } 92 | ) ) 93 | ; 94 | if (1e-10 < error) 95 | throw new Error( 'asmjs_matmulrows_zip_342_check failed!' ); 96 | 97 | (passed || (passed = {}))[ NAME ] = true; 98 | 99 | function set_rows( typedArray, rows ) 100 | { 101 | typedArray.set( rows.reduce( 102 | function (a,b) { return a.concat(b); } 103 | , [] 104 | ) ); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /expl/dftreal_flatorize.js: -------------------------------------------------------------------------------- 1 | if ('undefined' === typeof dft_msr_exprgenF && 'undefined' !== typeof load) 2 | load( 'modifsplitradix.js' ); 3 | 4 | function expl_dftreal_flatorize( /*integer, e.g. 16 or 1024*/dftsize, /*?boolean?*/hermihalf, /*?object?*/opt ) 5 | { 6 | var precision = opt && opt.precision || 'double'; 7 | 8 | // Give external access, for example to display source code. 9 | // Example of use: ../index.html 10 | 11 | var E = expl_dftreal_flatorize; 12 | 13 | //#BEGIN_BODY 14 | 15 | var power = Math.log( dftsize ) / Math.log( 2 ); 16 | if (power !== power | 0) 17 | throw new Error( 'dftsize must be a power of 2!' ); 18 | 19 | var dftrealflat = flatorize( 20 | // note the :[type] declarations, ignored by `flatorize` 21 | // but useful later in asm.js or C contexts 22 | 'arr:[' + dftsize + ' ' + precision + ']->freq:[' + (hermihalf ? 1 + (dftsize >> 1) : dftsize) + ' [2 ' + precision + ']]' 23 | , dft_msr_exprgenF( power, { real: true, hermihalf : !!hermihalf } ) 24 | ) 25 | ; 26 | 27 | // Does this work? 28 | 29 | var io = get_dftreal_sin_input_output_for_check( dftsize, hermihalf ) 30 | , sinfreq = dftrealflat( io.input ) 31 | ; 32 | 33 | //#END_BODY 34 | 35 | // More exports 36 | 37 | E[ 'dftreal' + dftsize + 'flat' + (hermihalf ? '_hermihalf' : '') + '_' + precision ] = dftrealflat; 38 | 39 | // For `expl_run` 40 | 41 | return { name : 'sinfreq', obtained : sinfreq, expected : io.expected, precision : precision }; 42 | } 43 | -------------------------------------------------------------------------------- /expl/flatasmjs_array_from_array.js: -------------------------------------------------------------------------------- 1 | /*global expl_array_from_array flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_array_from_array( /*integer*/size ) 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_array_from_array'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_array_from_array; 14 | 15 | //#BEGIN_BODY 16 | 17 | var flip = flatorize( 18 | // note the :[type] declarations, ignored by `flatorize` 19 | // but useful later in asm.js or C contexts 20 | 'arr:[' + size + ' double]->flipped:[' + size + ' double]' 21 | , function (arrname) 22 | { 23 | return symbol_array( arrname, size ).reverse(); 24 | } 25 | ) 26 | 27 | , input = empty_array( size ).map( function (tmp,i) { return i; } ) 28 | , expected = input.slice().reverse() 29 | 30 | , flip_asmjs_name = 'flip' + size + '_asmjs' 31 | 32 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 33 | cfg : { switcher : flip, name : flip_asmjs_name } 34 | , input : augment_name_value_array_with_mapping( [ 35 | { name : "arr", value : input } 36 | ] ) 37 | , output : augment_name_value_array_with_mapping( [ 38 | { name : 'flipped', value : expected } 39 | ] ) 40 | } 41 | 42 | , flip_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 43 | ; 44 | 45 | function symbol_array( arrname, size ) 46 | // arr := [ arr[0], arr[1], arr[2], ... ] 47 | { 48 | return empty_array( size ) 49 | .map( function ( tmp, i ) { return flatorize.part( arrname, i ); } ) 50 | ; 51 | } 52 | 53 | function empty_array( size ) 54 | { 55 | return new Array( size ).join( ',' ).split( ',' ); 56 | } 57 | 58 | // --- Do they work? 59 | 60 | // flatorized version 61 | 62 | var obtained = flip( input ); 63 | 64 | // flatorized+asm.js version 65 | 66 | var flip_asmjs_buffer = new ArrayBuffer( flip_asmjs_gen.buffer_bytes ) 67 | , flip_asmjs_O = flip_asmjs_gen( this, {}, flip_asmjs_buffer ) // compile 68 | , flip_asmjs = flip_asmjs_O[ flip_asmjs_name ] 69 | 70 | , n2i = flip_asmjs_gen.array_name2info 71 | , TypedArray = flip_asmjs_gen.TypedArray 72 | 73 | , flip_asmjs_input_arr = new TypedArray( flip_asmjs_buffer, n2i.arr.begin_bytes, n2i.arr.n ) 74 | , flip_asmjs_output_flipped = new TypedArray( flip_asmjs_buffer, n2i.flipped.begin_bytes, n2i.flipped.n ) 75 | ; 76 | 77 | flip_asmjs_input_arr.set( input ); 78 | 79 | flip_asmjs(); 80 | 81 | var obtained_asmjs = [].slice.apply( flip_asmjs_output_flipped ); 82 | 83 | //#END_BODY 84 | 85 | // More exports 86 | 87 | E[ 'flip' + size ] = flip; 88 | 89 | E[ flip_asmjs_name ] = flip_asmjs; 90 | 91 | // For `expl_run` 92 | 93 | return { name : 'flip' 94 | , obtained : { flatorize : obtained 95 | , flatorize_asmjs : obtained_asmjs 96 | } 97 | 98 | , expected : { flatorize : expected 99 | , flatorize_asmjs : expected 100 | } 101 | , input : input 102 | }; 103 | } 104 | -------------------------------------------------------------------------------- /expl/flatasmjs_array_from_matrix.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_array_from_matrix flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_array_from_matrix( /*integer*/nrow, /*integer*/ncol ) 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_array_from_matrix'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_array_from_matrix; 14 | 15 | //#BEGIN_BODY 16 | 17 | var diaglen = Math.min( nrow, ncol ) 18 | 19 | , diagflat_name = 'diagflat' + nrow + 'x' + ncol 20 | , diagflat = flatorize( 21 | // note the :[type] declarations, ignored by `flatorize` 22 | // but useful later in asm.js or C contexts 23 | 'mat:[' + nrow + ' [' + ncol + ' double]]->diag:[' + diaglen + ' double]' 24 | , function ( matname ) 25 | { 26 | return symbol_matrixrows( matname, nrow, ncol ) 27 | .slice( 0, diaglen ) 28 | .map( function ( row, i ) { return row[ i ]; } ) 29 | ; 30 | } 31 | ) 32 | 33 | , col_factor = Math.pow( 10, Math.ceil( Math.log( ncol ) / Math.log( 10 ) ) ) 34 | 35 | , input = new Array( nrow ).join(',').split(',').map( 36 | function ( tmp, irow ) { 37 | return new Array( ncol ).join( ',' ).split( ',' ).map( 38 | function ( tmp, icol ) { return irow + icol / col_factor; } 39 | ); 40 | } 41 | ) 42 | , expected = input.slice( 0, diaglen ).map( function (row,i) { return row[ i ]; } ) 43 | 44 | 45 | , diagflat_asmjs_name = diagflat_name + '_asmjs' 46 | 47 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 48 | cfg : { switcher : diagflat, name : diagflat_asmjs_name } 49 | , input : augment_name_value_array_with_mapping( [ 50 | { name : 'mat', value : input } 51 | ] ) 52 | , output : augment_name_value_array_with_mapping( [ 53 | { name : 'diag', value : expected } 54 | ] ) 55 | } 56 | 57 | 58 | , diagflat_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 59 | ; 60 | 61 | function symbol_matrixrows( name, nrow, ncol ) 62 | // m := [ [ m[0][0], m[0][1], m[0][2], ... ], 63 | // [ m[1][0], m[1][1], m[1][2], ... ], 64 | // ... 65 | // ] 66 | { 67 | return empty_array( nrow ).map( function ( tmp, r ) { 68 | 69 | return empty_array( ncol ).map( function ( tmp, c ) { 70 | 71 | return flatorize.part( flatorize.part( name, r ), c ); // e.g. m[r][c] 72 | }); 73 | }); 74 | } 75 | 76 | function empty_array( size ) 77 | { 78 | return new Array( size ).join( ',' ).split( ',' ); 79 | } 80 | 81 | // --- Do they work? 82 | 83 | // flatorized version 84 | 85 | var obtained = diagflat( input ); 86 | 87 | // flatorized+asm.js version 88 | 89 | var diagflat_asmjs_buffer = new ArrayBuffer( diagflat_asmjs_gen.buffer_bytes ) 90 | , diagflat_asmjs_O = diagflat_asmjs_gen( this, {}, diagflat_asmjs_buffer ) // compile 91 | , diagflat_asmjs = diagflat_asmjs_O[ diagflat_asmjs_name ] 92 | 93 | , n2i = diagflat_asmjs_gen.array_name2info 94 | , TypedArray = diagflat_asmjs_gen.TypedArray 95 | 96 | , diagflat_asmjs_input_mat = new TypedArray( diagflat_asmjs_buffer, n2i.mat.begin_bytes, n2i.mat.n ) 97 | , diagflat_asmjs_output_diag = new TypedArray( diagflat_asmjs_buffer, n2i.diag.begin_bytes, n2i.diag.n ) 98 | ; 99 | 100 | diagflat_asmjs_input_mat.set( input.reduce( function (a,b) { return a.concat(b); } ) ); 101 | 102 | diagflat_asmjs(); 103 | 104 | var obtained_asmjs = [].slice.apply( diagflat_asmjs_output_diag ); 105 | 106 | //#END_BODY 107 | 108 | // More exports 109 | 110 | E[ diagflat_name ] = diagflat; 111 | 112 | E[ diagflat_asmjs_name ] = diagflat_asmjs; 113 | 114 | // For `expl_run` 115 | 116 | return { name : 'diagflat' 117 | , obtained : { flatorize : obtained 118 | , flatorize_asmjs : obtained_asmjs 119 | } 120 | 121 | , expected : { flatorize : expected 122 | , flatorize_asmjs : expected 123 | } 124 | , input : input 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /expl/flatasmjs_array_from_ndim.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_array_from_ndim flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_array_from_ndim( /*array of integer*/dim ) 5 | // Maybe not the most meaningful use of flatorize, but a good unit 6 | // test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_array_from_ndim_' + dim.length; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_array_from_ndim; 14 | 15 | //#BEGIN_BODY 16 | 17 | var ndimdiaglen = Math.min.apply( Math, dim ) 18 | 19 | , ndimdiagflat_name = 'ndimdiagflat' + dim.join( 'x' ) 20 | , ndimdiagflat = flatorize( 21 | // note the :[type] declarations, ignored by `flatorize` 22 | // but useful later in asm.js or C contexts 23 | 'mat:' + dim2spec( dim, 'double' ) + '->ndimdiag:[' + ndimdiaglen + ' double]' 24 | , function ( matname ) 25 | { 26 | return !(ndimdiaglen > 0) 27 | ? [] 28 | : ndim_diag( 29 | symbol_ndim_matrix( matname, dim ) 30 | , dim 31 | , ndimdiaglen 32 | ) 33 | ; 34 | } 35 | ) 36 | 37 | , ndimdiagflat_asmjs_name = ndimdiagflat_name + '_asmjs' 38 | 39 | , input = random_ndim_matrix( dim ) 40 | , expected = new Array( ndimdiaglen ) 41 | ; 42 | for (var i = ndimdiaglen; i--;) 43 | { 44 | var tmp = input; 45 | for (var id = dim.length; id--;) 46 | tmp = tmp[ i ]; 47 | 48 | expected[ i ] = tmp; 49 | } 50 | 51 | var info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 52 | cfg : { switcher : ndimdiagflat, name : ndimdiagflat_asmjs_name } 53 | , input : augment_name_value_array_with_mapping( [ 54 | { name : 'mat', value : input } 55 | ] ) 56 | , output : augment_name_value_array_with_mapping( [ 57 | { name : 'ndimdiag', value : expected } 58 | ] ) 59 | } 60 | 61 | , ndimdiagflat_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 62 | ; 63 | 64 | function dim2spec( /*array of integer*/dim, /*string*/basic_type ) 65 | { 66 | (basic_type || null).substring.call.a; 67 | return dim.length > 0 68 | ? '[' + dim[ 0 ] + ' ' + dim2spec( dim.slice( 1 ), basic_type ) + ']' 69 | : basic_type 70 | ; 71 | } 72 | 73 | function ndim_diag( mat, dim, ndimdiaglen ) 74 | { 75 | (ndimdiaglen || null).toPrecision.call.a; 76 | return empty_array( ndimdiaglen ).map( one_term_of_the_diag ); 77 | 78 | function one_term_of_the_diag( tmp, i ) 79 | { 80 | return dim.reduce( function ( what, tmp ) { return what[ i ]; } 81 | , mat 82 | ); 83 | } 84 | } 85 | 86 | function symbol_ndim_matrix( /*string | object*/what, /*array of integer*/dim ) 87 | // 2-dimensional example: 88 | // 89 | // m := [ [ m[0][0], m[0][1], m[0][2], ... ], 90 | // [ m[1][0], m[1][1], m[1][2], ... ], 91 | // ... 92 | // ] 93 | { 94 | return !(dim.length > 0) 95 | 96 | ? what 97 | 98 | : empty_array( dim[ 0 ] ).map( function ( tmp, a ) { 99 | 100 | return symbol_ndim_matrix( flatorize.part( what, a ), dim.slice( 1 ) ); 101 | }) 102 | ; 103 | } 104 | 105 | function empty_array( size ) 106 | { 107 | return new Array( size ).join( ',' ).split( ',' ); 108 | } 109 | 110 | // --- Do they work? 111 | 112 | function random_ndim_matrix( dim ) 113 | { 114 | return !(dim.length > 0) 115 | ? Math.random() 116 | : empty_array( dim[ 0 ] ).map( 117 | function () { return random_ndim_matrix( dim.slice( 1 ) ); } 118 | ); 119 | } 120 | 121 | function flatten_values( /*array*/ndim_mat ) 122 | { 123 | return ndim_mat[ 0 ] instanceof Array 124 | ? ndim_mat.reduce( function ( a, b ) { return a.concat( flatten_values( b ) ); }, [] ) 125 | : ndim_mat 126 | ; 127 | } 128 | 129 | 130 | // flatorized version 131 | 132 | var obtained = ndimdiagflat( input ); 133 | 134 | // flatorized+asm.js version 135 | 136 | var ndimdiagflat_asmjs_buffer = new ArrayBuffer( ndimdiagflat_asmjs_gen.buffer_bytes ) 137 | , ndimdiagflat_asmjs_O = ndimdiagflat_asmjs_gen( this, {}, ndimdiagflat_asmjs_buffer ) // compile 138 | , ndimdiagflat_asmjs = ndimdiagflat_asmjs_O[ ndimdiagflat_asmjs_name ] 139 | 140 | , n2i = ndimdiagflat_asmjs_gen.array_name2info 141 | , TypedArray = ndimdiagflat_asmjs_gen.TypedArray 142 | 143 | , ndimdiagflat_asmjs_input_mat = new TypedArray( ndimdiagflat_asmjs_buffer, n2i.mat.begin_bytes, n2i.mat.n ) 144 | , ndimdiagflat_asmjs_output_ndimdiag = new TypedArray( ndimdiagflat_asmjs_buffer, n2i.ndimdiag.begin_bytes, n2i.ndimdiag.n ) 145 | ; 146 | 147 | ndimdiagflat_asmjs_input_mat.set( flatten_values( input ) ); 148 | 149 | ndimdiagflat_asmjs(); 150 | 151 | var obtained_asmjs = [].slice.apply( ndimdiagflat_asmjs_output_ndimdiag ); 152 | 153 | //#END_BODY 154 | 155 | // More exports 156 | 157 | E[ ndimdiagflat_name ] = ndimdiagflat; 158 | 159 | E[ ndimdiagflat_asmjs_name ] = ndimdiagflat_asmjs; 160 | 161 | // For `expl_run` 162 | 163 | return { name : 'ndimdiagflat' 164 | , obtained : { flatorize : obtained 165 | , flatorize_asmjs : obtained_asmjs 166 | } 167 | 168 | , expected : { flatorize : expected 169 | , flatorize_asmjs : expected 170 | } 171 | , input : input 172 | }; 173 | } 174 | -------------------------------------------------------------------------------- /expl/flatasmjs_array_from_scalar.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_array_from_scalar flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_array_from_scalar( /*integer*/size ) 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_array_from_scalar'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_array_from_scalar; 14 | 15 | //#BEGIN_BODY 16 | 17 | var count_a_few_name = 'count_a_few' + size 18 | , count_a_few = flatorize( 19 | // note the :[type] declarations, ignored by `flatorize` 20 | // but useful later in asm.js or C contexts 21 | 'n:int->v:[' + size + ' int]' 22 | , function ( n_name ) 23 | { 24 | return empty_array( size ) 25 | .map( function ( tmp, i ) { return flatorize.expr( n_name, '+', i ); } ) 26 | ; 27 | } 28 | ) 29 | 30 | , count_a_few_asmjs_name = count_a_few_name 31 | , count_a_few_asmjs_gen = flatorize.getAsmjsGen( { switcher : count_a_few, name : count_a_few_asmjs_name } ) 32 | 33 | 34 | , count_a_few_double_name = 'count_a_few_double' + size 35 | , count_a_few_double = flatorize( 36 | // note the :[type] declarations, ignored by `flatorize` 37 | // but useful later in asm.js or C contexts 38 | 'n:double->v:[' + size + ' double]' 39 | , function ( n_name ) 40 | { 41 | return empty_array( size ) 42 | .map( function ( tmp, i ) { return flatorize.expr( n_name, '+', i ); } ) 43 | ; 44 | } 45 | ) 46 | 47 | , input = 3 48 | , expected = empty_array( size ).map( function ( tmp, i ) { return input + i; } ) 49 | 50 | , input_double = 4.567 51 | , expected_double = empty_array( size ).map( function ( tmp, i ) { return input_double + i; } ) 52 | 53 | 54 | , count_a_few_double_asmjs_name = count_a_few_double_name 55 | 56 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 57 | 58 | cfg : { switcher : count_a_few_double, name : count_a_few_double_asmjs_name } 59 | , input : augment_name_value_array_with_mapping( [ 60 | { name : 'n', value : input_double } 61 | ] ) 62 | , output : augment_name_value_array_with_mapping( [ 63 | { name : 'v', value : expected_double } 64 | ] ) 65 | } 66 | 67 | 68 | , count_a_few_double_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 69 | 70 | ; 71 | 72 | function empty_array( size ) 73 | { 74 | return new Array( size ).join( ',' ).split( ',' ); 75 | } 76 | 77 | // --- Do they work? 78 | 79 | // flatorized version 80 | 81 | var obtained = count_a_few( input ) 82 | 83 | , obtained_double = count_a_few_double( input_double ) 84 | ; 85 | 86 | // flatorized+asm.js version 87 | 88 | var count_a_few_asmjs_buffer = new ArrayBuffer( count_a_few_asmjs_gen.buffer_bytes ) 89 | , count_a_few_asmjs_O = count_a_few_asmjs_gen( this, {}, count_a_few_asmjs_buffer ) // compile 90 | , count_a_few_asmjs = count_a_few_asmjs_O[ count_a_few_asmjs_name ] 91 | 92 | , n2i = count_a_few_asmjs_gen.array_name2info 93 | , TypedArray = count_a_few_asmjs_gen.TypedArray 94 | 95 | , count_a_few_asmjs_output_v = new TypedArray( count_a_few_asmjs_buffer, n2i.v.begin_bytes, n2i.v.n ) 96 | ; 97 | 98 | count_a_few_asmjs( input ); 99 | 100 | var obtained_asmjs = [].slice.apply( count_a_few_asmjs_output_v ); 101 | 102 | 103 | 104 | var count_a_few_double_asmjs_buffer = new ArrayBuffer( count_a_few_double_asmjs_gen.buffer_bytes ) 105 | , count_a_few_double_asmjs_O = count_a_few_double_asmjs_gen( this, {}, count_a_few_double_asmjs_buffer ) // compile 106 | , count_a_few_double_asmjs = count_a_few_double_asmjs_O[ count_a_few_double_asmjs_name ] 107 | 108 | , n2i = count_a_few_double_asmjs_gen.array_name2info 109 | , TypedArray = count_a_few_double_asmjs_gen.TypedArray 110 | 111 | , count_a_few_double_asmjs_output_v = new TypedArray( count_a_few_double_asmjs_buffer, n2i.v.begin_bytes, n2i.v.n ) 112 | ; 113 | 114 | count_a_few_double_asmjs( input_double ); 115 | 116 | var obtained_double_asmjs = [].slice.apply( count_a_few_double_asmjs_output_v ); 117 | 118 | //#END_BODY 119 | 120 | // More exports 121 | 122 | E[ count_a_few_name ] = count_a_few; 123 | 124 | E[ count_a_few_asmjs_name ] = count_a_few_asmjs; 125 | 126 | 127 | 128 | E[ count_a_few_double_name ] = count_a_few_double; 129 | 130 | E[ count_a_few_double_asmjs_name ] = count_a_few_double_asmjs; 131 | 132 | // For `expl_run` 133 | 134 | return { name : 'count_a_few' 135 | , obtained : { flatorize : [ obtained, obtained_double ] 136 | , flatorize_asmjs : [ obtained_asmjs, obtained_double_asmjs ] 137 | } 138 | 139 | , expected : { flatorize : [ expected, expected_double ] 140 | , flatorize_asmjs : [ expected, expected_double ] 141 | } 142 | , input : input 143 | }; 144 | } 145 | -------------------------------------------------------------------------------- /expl/flatasmjs_matrix_from_array.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_matrix_from_array flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_matrix_from_array( /*integer*/size ) 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_matrix_from_array'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_matrix_from_array; 14 | 15 | //#BEGIN_BODY 16 | 17 | var col_factor = Math.pow( 10, Math.ceil( Math.log( size ) / Math.log( 10 ) ) ) 18 | 19 | , v2m_name = 'v2m' 20 | , v2m = flatorize( 21 | // note the :[type] declarations, ignored by `flatorize` 22 | // but useful later in asm.js or C contexts 23 | 'arr:[' + size + ' double]->mat:[' + size + ' [' + size + ' double]]' 24 | , function ( arrname ) 25 | { 26 | return symbol_matmulrows_zip( 27 | transpose( 28 | /*matrix:*/ [ 29 | symbol_array( arrname, size ) 30 | .map( function ( x, i ) { return flatorize.expr( x, '*', i ) } ) 31 | ] 32 | ) 33 | , /*matrix:*/ [ 34 | symbol_array( arrname, size ) 35 | .map( function ( x, i ) { return flatorize.expr( x, '+', i / col_factor ); } ) 36 | ] 37 | ); 38 | } 39 | ) 40 | 41 | 42 | , input = empty_array( size ).map( Math.random ) 43 | 44 | , expected = empty_array( size ).map( 45 | function ( tmp, irow ) 46 | { 47 | return empty_array( size ).map( 48 | function ( tmp, icol ) 49 | { 50 | return (input[ irow ] * irow) * (input[ icol ] + icol / col_factor); 51 | } 52 | ); 53 | } 54 | ) 55 | 56 | , v2m_asmjs_name = v2m_name + '_asmjs' 57 | 58 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 59 | 60 | cfg : { switcher : v2m, name : v2m_asmjs_name } 61 | 62 | , input : augment_name_value_array_with_mapping( [ 63 | { name : 'arr', value : input } 64 | ] ) 65 | 66 | , output : augment_name_value_array_with_mapping( [ 67 | { name : 'mat', value : expected } 68 | ] ) 69 | } 70 | 71 | 72 | , v2m_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 73 | ; 74 | 75 | // --- Do they work? 76 | 77 | // flatorized version 78 | 79 | var obtained = v2m( input ); 80 | 81 | // flatorized+asm.js version 82 | 83 | var v2m_asmjs_buffer = new ArrayBuffer( v2m_asmjs_gen.buffer_bytes ) 84 | , v2m_asmjs_O = v2m_asmjs_gen( this, {}, v2m_asmjs_buffer ) // compile 85 | , v2m_asmjs = v2m_asmjs_O[ v2m_asmjs_name ] 86 | 87 | , n2i = v2m_asmjs_gen.array_name2info 88 | , TypedArray = v2m_asmjs_gen.TypedArray 89 | 90 | , v2m_asmjs_input_arr = new TypedArray( v2m_asmjs_buffer, n2i.arr.begin_bytes, n2i.arr.n ) 91 | , v2m_asmjs_output_mat = new TypedArray( v2m_asmjs_buffer, n2i.mat.begin_bytes, n2i.mat.n ) 92 | ; 93 | 94 | v2m_asmjs_input_arr.set( input ); 95 | 96 | v2m_asmjs(); 97 | 98 | var obtained_asmjs = [].slice.apply( v2m_asmjs_output_mat ); 99 | 100 | // --- Details 101 | 102 | function symbol_matmulrows_zip( a, b ) 103 | { 104 | return a.map( function (ra) { 105 | 106 | return transpose( b ).map( function (cb) { 107 | 108 | return symbol_sum( 109 | zip( ra, cb ) 110 | .map( function (xy) { 111 | return flatorize.expr( xy[ 0 ], '*', xy[ 1 ] ); 112 | } ) 113 | ); 114 | } ); 115 | } ); 116 | } 117 | 118 | function transpose( mat ) 119 | { 120 | return zip.apply( null, mat ); 121 | } 122 | 123 | function zip(/*...arguments...*/) 124 | { 125 | var arg = [].slice.apply( arguments ); 126 | if (!arg.length) 127 | return []; 128 | 129 | var n = arg[ 0 ].length 130 | , ret = new Array( n ) 131 | ; 132 | for (var i = 0; i < n; i++) 133 | ret[ i ] = arg.map( function (x) { return x[i]; } ); 134 | 135 | return ret; 136 | } 137 | 138 | function symbol_matrixrows( name, nrow, ncol ) 139 | // m := [ [ m[0][0], m[0][1], m[0][2], ... ], 140 | // [ m[1][0], m[1][1], m[1][2], ... ], 141 | // ... 142 | // ] 143 | { 144 | var ret = new Array( nrow ); 145 | for (var r = 0; r < nrow; r++) 146 | ret[ r ] = symbol_array( flatorize.part( name, r ), ncol ); // e.g. m[r] 147 | 148 | return ret; 149 | } 150 | 151 | function symbol_array( arrname, size ) 152 | // arr := [ arr[0], arr[1], arr[2], ... ] 153 | { 154 | return empty_array( size ) 155 | .map( function ( tmp, i ) { return flatorize.part( arrname, i ); } ) 156 | ; 157 | } 158 | 159 | function empty_array( size ) 160 | { 161 | return new Array( size ).join( ',' ).split( ',' ); 162 | } 163 | 164 | function symbol_sum( arr ) 165 | // sum( arr ) := arr[0] + arr[1] + ... 166 | { 167 | return flatorize.expr.apply( null, arr.reduce( symbol_sum_step, [] ) ); 168 | 169 | function symbol_sum_step( left, right ) 170 | { 171 | return left.length ? left.concat( [ '+', right ] ) : [ right ]; 172 | } 173 | } 174 | 175 | //#END_BODY 176 | 177 | // More exports 178 | 179 | E[ v2m_name ] = v2m; 180 | 181 | E[ v2m_asmjs_name ] = v2m_asmjs; 182 | 183 | // For `expl_run` 184 | 185 | return { name : 'v2m' 186 | , obtained : { flatorize : obtained 187 | , flatorize_asmjs : obtained_asmjs 188 | } 189 | 190 | , expected : { flatorize : expected 191 | , flatorize_asmjs : expected.reduce( function (a,b) { return a.concat(b); } ) 192 | } 193 | , input : input 194 | }; 195 | } 196 | -------------------------------------------------------------------------------- /expl/flatasmjs_matrix_from_matrix.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_matrix_from_matrix flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_matrix_from_matrix( /*integer*/nrow, /*integer*/ncol ) 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_matrix_from_matrix'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_matrix_from_matrix; 14 | 15 | //#BEGIN_BODY 16 | 17 | var transpose_name = 'transpose' 18 | , transpose = flatorize( 19 | // note the :[type] declarations, ignored by `flatorize` 20 | // but useful later in asm.js or C contexts 21 | 'mat:[' + nrow + ' [' + ncol + ' double]]->tmat:[' + ncol + ' [' + nrow + ' double]]' 22 | , function ( matname ) 23 | { 24 | return zip.apply( null, symbol_matrixrows( matname, nrow, ncol ) ); 25 | } 26 | ) 27 | 28 | 29 | , col_factor = Math.pow( 10, Math.ceil( Math.log( ncol ) / Math.log( 10 ) ) ) 30 | 31 | , input = empty_array( nrow ).map( 32 | function ( tmp, irow ) { 33 | return empty_array( ncol ).map( 34 | function ( tmp, icol ) { return irow + icol / col_factor; } 35 | ); 36 | } 37 | ) 38 | 39 | , expected = empty_array( ncol ).map( 40 | function ( tmp, icol ) { 41 | return empty_array( nrow ).map( 42 | function ( tmp, irow ) { return irow + icol / col_factor; } 43 | ); 44 | } 45 | ) 46 | 47 | 48 | , transpose_asmjs_name = transpose_name + '_asmjs' 49 | 50 | 51 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 52 | 53 | cfg : { switcher : transpose, name : transpose_asmjs_name } 54 | 55 | , input : augment_name_value_array_with_mapping( [ 56 | { name : 'mat', value : input } 57 | ] ) 58 | 59 | , output : augment_name_value_array_with_mapping( [ 60 | { name : 'tmat', value : expected } 61 | ] ) 62 | } 63 | 64 | 65 | , transpose_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 66 | ; 67 | 68 | function zip(/*...arguments...*/) 69 | { 70 | var arg = [].slice.apply( arguments ); 71 | if (!arg.length) 72 | return []; 73 | 74 | var n = arg[ 0 ].length 75 | , ret = new Array( n ) 76 | ; 77 | for (var i = 0; i < n; i++) 78 | ret[ i ] = arg.map( function (x) { return x[i]; } ); 79 | 80 | return ret; 81 | } 82 | 83 | function symbol_matrixrows( name, nrow, ncol ) 84 | // m := [ [ m[0][0], m[0][1], m[0][2], ... ], 85 | // [ m[1][0], m[1][1], m[1][2], ... ], 86 | // ... 87 | // ] 88 | { 89 | return empty_array( nrow ).map( function ( tmp, r ) { 90 | 91 | return empty_array( ncol ).map( function ( tmp, c ) { 92 | 93 | return flatorize.part( flatorize.part( name, r ), c ); // e.g. m[r][c] 94 | }); 95 | }); 96 | } 97 | 98 | function empty_array( size ) 99 | { 100 | return new Array( size ).join( ',' ).split( ',' ); 101 | } 102 | 103 | // --- Do they work? 104 | 105 | // flatorized version 106 | 107 | var obtained = transpose( input ); 108 | 109 | // flatorized+asm.js version 110 | 111 | var transpose_asmjs_buffer = new ArrayBuffer( transpose_asmjs_gen.buffer_bytes ) 112 | , transpose_asmjs_O = transpose_asmjs_gen( this, {}, transpose_asmjs_buffer ) // compile 113 | , transpose_asmjs = transpose_asmjs_O[ transpose_asmjs_name ] 114 | 115 | , n2i = transpose_asmjs_gen.array_name2info 116 | , TypedArray = transpose_asmjs_gen.TypedArray 117 | 118 | , transpose_asmjs_input_mat = new TypedArray( transpose_asmjs_buffer, n2i.mat.begin_bytes, n2i.mat.n ) 119 | , transpose_asmjs_output_tmat = new TypedArray( transpose_asmjs_buffer, n2i.tmat.begin_bytes, n2i.tmat.n ) 120 | ; 121 | 122 | transpose_asmjs_input_mat.set( input.reduce( function (a,b) { return a.concat(b); } ) ); 123 | 124 | transpose_asmjs(); 125 | 126 | var obtained_asmjs = [].slice.apply( transpose_asmjs_output_tmat ); 127 | 128 | //#END_BODY 129 | 130 | // More exports 131 | 132 | E[ transpose_name ] = transpose; 133 | 134 | E[ transpose_asmjs_name ] = transpose_asmjs; 135 | 136 | // For `expl_run` 137 | 138 | return { name : 'transpose' 139 | , obtained : { flatorize : obtained 140 | , flatorize_asmjs : obtained_asmjs 141 | } 142 | 143 | , expected : { flatorize : expected 144 | , flatorize_asmjs : expected.reduce( function (a,b) { return a.concat(b); } ) 145 | } 146 | , input : input 147 | }; 148 | } 149 | -------------------------------------------------------------------------------- /expl/flatasmjs_matrix_from_scalar.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_matrix_from_scalar flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_matrix_from_scalar( /*integer*/nrow, /*integer*/ncol ) 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_matrix_from_scalar'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_matrix_from_scalar; 14 | 15 | //#BEGIN_BODY 16 | 17 | var factor = Math.pow( 10, Math.ceil( Math.log( Math.max( nrow, ncol ) ) / Math.log( 10 ) ) ) 18 | 19 | , s2m_name = 's2m' 20 | , s2m = flatorize( 21 | // note the :[type] declarations, ignored by `flatorize` 22 | // but useful later in asm.js or C contexts 23 | 'x:double->mat:[' + nrow + ' [' + ncol + ' double]]' 24 | , function ( x_name ) 25 | { 26 | return empty_array( nrow ).map( 27 | function ( tmp, irow ) 28 | { 29 | return empty_array( ncol ).map( 30 | function ( tmp, icol ) 31 | { 32 | return flatorize.expr( 33 | x_name, '+', (irow + icol / factor) / factor 34 | ); 35 | } 36 | ); 37 | } 38 | ); 39 | } 40 | ) 41 | 42 | 43 | , input = 1234.56789 44 | 45 | , expected = empty_array( nrow ).map( 46 | function ( tmp, irow ) 47 | { 48 | return empty_array( ncol ).map( 49 | function ( tmp, icol ) 50 | { 51 | return input + (irow + icol / factor) / factor; 52 | } 53 | ); 54 | } 55 | ) 56 | 57 | 58 | , s2m_asmjs_name = s2m_name + '_asmjs' 59 | 60 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 61 | 62 | cfg : { switcher : s2m, name : s2m_asmjs_name } 63 | 64 | , input : augment_name_value_array_with_mapping( [ 65 | { name : 'x', value : input } 66 | ] ) 67 | 68 | , output : augment_name_value_array_with_mapping( [ 69 | { name : 'mat', value : expected } 70 | ] ) 71 | } 72 | 73 | 74 | 75 | 76 | , s2m_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 77 | ; 78 | 79 | function empty_array( size ) 80 | { 81 | return new Array( size ).join( ',' ).split( ',' ); 82 | } 83 | 84 | // --- Do they work? 85 | 86 | // flatorized version 87 | 88 | var obtained = s2m( input ); 89 | 90 | // flatorized+asm.js version 91 | 92 | var s2m_asmjs_buffer = new ArrayBuffer( s2m_asmjs_gen.buffer_bytes ) 93 | , s2m_asmjs_O = s2m_asmjs_gen( this, {}, s2m_asmjs_buffer ) // compile 94 | , s2m_asmjs = s2m_asmjs_O[ s2m_asmjs_name ] 95 | 96 | , n2i = s2m_asmjs_gen.array_name2info 97 | , TypedArray = s2m_asmjs_gen.TypedArray 98 | 99 | , s2m_asmjs_output_mat = new TypedArray( s2m_asmjs_buffer, n2i.mat.begin_bytes, n2i.mat.n ) 100 | ; 101 | 102 | s2m_asmjs( input ); 103 | 104 | var obtained_asmjs = [].slice.apply( s2m_asmjs_output_mat ); 105 | 106 | //#END_BODY 107 | 108 | // More exports 109 | 110 | E[ s2m_name ] = s2m; 111 | 112 | E[ s2m_asmjs_name ] = s2m_asmjs; 113 | 114 | // For `expl_run` 115 | 116 | return { name : 's2m' 117 | , obtained : { flatorize : obtained 118 | , flatorize_asmjs : obtained_asmjs 119 | } 120 | 121 | , expected : { flatorize : expected 122 | , flatorize_asmjs : expected.reduce( function (a,b) { return a.concat(b); } ) 123 | } 124 | , input : input 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /expl/flatasmjs_scalar_from_array.js: -------------------------------------------------------------------------------- 1 | /*global expl_scalar_from_array flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_scalar_from_array( /*integer*/size ) 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_scalar_from_array'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_scalar_from_array; 14 | 15 | //#BEGIN_BODY 16 | 17 | var sumflat = flatorize( 18 | // note the :[type] declarations, ignored by `flatorize` 19 | // but useful later in asm.js or C contexts 20 | 'arr:[' + size + ' double]->sum:double' 21 | , function (arrname) 22 | { 23 | return symbol_sum( symbol_array( arrname, size ) ); 24 | } 25 | ) 26 | 27 | , input = empty_array( size ).map( Math.random ) 28 | , expected = input.reduce( function (a,b) { return a+b; } ) 29 | 30 | , sumflat_asmjs_name = 'sumflat' + size + 'asmjs' 31 | 32 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 33 | 34 | cfg : { switcher : sumflat, name : sumflat_asmjs_name } 35 | 36 | , input : augment_name_value_array_with_mapping( [ 37 | { name : 'arr', value : input } 38 | ] ) 39 | 40 | , output : augment_name_value_array_with_mapping( [ 41 | { name : 'sum', value : expected } 42 | ] ) 43 | } 44 | 45 | , sumflat_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 46 | ; 47 | 48 | function symbol_array( arrname, size ) 49 | // arr := [ arr[0], arr[1], arr[2], ... ] 50 | { 51 | return empty_array( size ) 52 | .map( function ( tmp, i ) { return flatorize.part( arrname, i ); } ) 53 | ; 54 | } 55 | 56 | function empty_array( size ) 57 | { 58 | return new Array( size ).join( ',' ).split( ',' ); 59 | } 60 | 61 | function symbol_sum( arr ) 62 | // sum( arr ) := arr[0] + arr[1] + ... 63 | { 64 | return flatorize.expr.apply( 65 | null 66 | , arr.reduce( symbol_sum_step, [] ) 67 | ); 68 | 69 | function symbol_sum_step( left, right ) 70 | { 71 | return left.length ? left.concat( [ '+', right ] ) : [ right ]; 72 | } 73 | } 74 | 75 | // --- Do they work? 76 | 77 | // flatorized version 78 | 79 | var obtained = sumflat( input ); 80 | 81 | // flatorized+asm.js version 82 | 83 | var sumflat_asmjs_buffer = new ArrayBuffer( sumflat_asmjs_gen.buffer_bytes ) 84 | , sumflat_asmjs_O = sumflat_asmjs_gen( this, {}, sumflat_asmjs_buffer ) // compile 85 | , sumflat_asmjs = sumflat_asmjs_O[ sumflat_asmjs_name ] 86 | 87 | , n2i = sumflat_asmjs_gen.array_name2info 88 | , TypedArray = sumflat_asmjs_gen.TypedArray 89 | 90 | , sumflat_asmjs_input_arr = new TypedArray( sumflat_asmjs_buffer, n2i.arr.begin_bytes, n2i.arr.n ) 91 | ; 92 | 93 | sumflat_asmjs_input_arr.set( input ); 94 | 95 | var obtained_asmjs = sumflat_asmjs(); 96 | 97 | //#END_BODY 98 | 99 | // More exports 100 | 101 | E[ 'sumflat' + size ] = sumflat; 102 | 103 | E[ sumflat_asmjs_name ] = sumflat_asmjs; 104 | 105 | // For `expl_run` 106 | 107 | return { name : 'sumflat' 108 | , obtained : { flatorize : obtained 109 | , flatorize_asmjs : obtained_asmjs 110 | } 111 | 112 | , expected : { flatorize : expected 113 | , flatorize_asmjs : expected 114 | } 115 | , input : input 116 | }; 117 | } 118 | -------------------------------------------------------------------------------- /expl/flatasmjs_scalar_from_matrix.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_scalar_from_matrix flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_scalar_from_matrix( /*integer*/nrow, /*integer*/ncol ) 5 | // Probably not the most sumingful use(s) of flatorize (no fun call) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_scalar_from_matrix'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_scalar_from_matrix; 14 | 15 | //#BEGIN_BODY 16 | 17 | var matsumflat_name = 'matsumflat' + nrow + 'x' + ncol 18 | 19 | , matsumflat = flatorize( 20 | // note the :[type] declarations, ignored by `flatorize` 21 | // but useful later in asm.js or C contexts 22 | 'mat:[' + nrow + ' [' + ncol + ' double]]->sum:double' 23 | , function ( matname ) 24 | { 25 | return !(nrow > 0 && ncol > 0) 26 | ? 0 27 | : flatorize.expr.apply( 28 | null 29 | , symbol_sum( 30 | symbol_matrixrows( matname, nrow, ncol ) 31 | .map( symbol_sum ) 32 | ) 33 | ) 34 | ; 35 | } 36 | ) 37 | 38 | , input = empty_array( nrow ).map( 39 | function () { return empty_array( ncol ).map( Math.random ); } 40 | ) 41 | , expected = input.reduce( function (a,b) { return a+b.reduce( function (x,y) { return x+y; } ); } 42 | , 0 43 | ) 44 | 45 | , matsumflat_asmjs_name = matsumflat_name + 'asmjs' 46 | 47 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 48 | 49 | cfg : { switcher : matsumflat, name : matsumflat_asmjs_name } 50 | 51 | , input : augment_name_value_array_with_mapping( [ 52 | { name : 'mat', value : input } 53 | ] ) 54 | 55 | , output : augment_name_value_array_with_mapping( [ 56 | { name : 'sum', value : expected } 57 | ] ) 58 | } 59 | 60 | , matsumflat_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 61 | ; 62 | 63 | function symbol_matrixrows( name, nrow, ncol ) 64 | // m := [ [ m[0][0], m[0][1], m[0][2], ... ], 65 | // [ m[1][0], m[1][1], m[1][2], ... ], 66 | // ... 67 | // ] 68 | { 69 | return empty_array( nrow ).map( function ( tmp, r ) { 70 | 71 | return empty_array( ncol ).map( function ( tmp, c ) { 72 | 73 | return flatorize.part( flatorize.part( name, r ), c ); // e.g. m[r][c] 74 | }); 75 | }); 76 | } 77 | 78 | function symbol_sum( arr ) 79 | // sum( arr ) := arr[0] + arr[1] + ... 80 | { 81 | return flatorize.expr.apply( null, arr.reduce( symbol_sum_step, [] ) ); 82 | function symbol_sum_step( left, right ) 83 | { 84 | return left.length ? left.concat( [ '+', right ] ) : [ right ]; 85 | } 86 | } 87 | 88 | function empty_array( size ) 89 | { 90 | return new Array( size ).join( ',' ).split( ',' ); 91 | } 92 | 93 | // --- Do they work? 94 | 95 | // flatorized version 96 | 97 | var obtained = matsumflat( input ); 98 | 99 | // flatorized+asm.js version 100 | 101 | var matsumflat_asmjs_buffer = new ArrayBuffer( matsumflat_asmjs_gen.buffer_bytes ) 102 | , matsumflat_asmjs_O = matsumflat_asmjs_gen( this, {}, matsumflat_asmjs_buffer ) // compile 103 | , matsumflat_asmjs = matsumflat_asmjs_O[ matsumflat_asmjs_name ] 104 | 105 | , n2i = matsumflat_asmjs_gen.array_name2info 106 | , TypedArray = matsumflat_asmjs_gen.TypedArray 107 | 108 | , matsumflat_asmjs_input_arr = new TypedArray( matsumflat_asmjs_buffer, n2i.mat.begin_bytes, n2i.mat.n ) 109 | ; 110 | 111 | matsumflat_asmjs_input_arr.set( input.reduce( function (a,b) { return a.concat(b); } ) ); 112 | 113 | var obtained_asmjs = matsumflat_asmjs(); 114 | 115 | //#END_BODY 116 | 117 | // More exports 118 | 119 | E[ matsumflat_name ] = matsumflat; 120 | 121 | E[ matsumflat_asmjs_name ] = matsumflat_asmjs; 122 | 123 | // For `expl_run` 124 | 125 | return { name : 'matsumflat' 126 | , obtained : { flatorize : obtained 127 | , flatorize_asmjs : obtained_asmjs 128 | } 129 | 130 | , expected : { flatorize : expected 131 | , flatorize_asmjs : expected 132 | } 133 | , input : input 134 | }; 135 | } 136 | -------------------------------------------------------------------------------- /expl/flatasmjs_scalar_from_ndim.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_scalar_from_ndim flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_scalar_from_ndim( /*array of integer*/dim ) 5 | // Probably not the most sumingful use(s) of flatorize (no fun call) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_scalar_from_ndim_' + dim.length; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_scalar_from_ndim; 14 | 15 | //#BEGIN_BODY 16 | 17 | var ndimsumflat_name = 'ndimsumflat' + dim.join( 'x' ) 18 | 19 | , ndimsumflat = flatorize( 20 | // note the :[type] declarations, ignored by `flatorize` 21 | // but useful later in asm.js or C contexts 22 | 'mat:' + dim2spec( dim, 'double' ) + '->sum:double' 23 | , function ( matname ) 24 | { 25 | return dim.some( function ( d ) { return !(d > 0); } ) 26 | ? 0 27 | : flatorize.expr.apply( 28 | null 29 | , symbol_ndim_sum( 30 | symbol_ndim_matrix( matname, dim ) 31 | ) 32 | ) 33 | ; 34 | } 35 | ) 36 | 37 | , input = random_ndim_matrix( dim ) 38 | , expected = flatten_values( input ).reduce( function ( a, b ) { return a+b; }, 0 ) 39 | 40 | , ndimsumflat_asmjs_name = ndimsumflat_name + 'asmjs' 41 | 42 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 43 | 44 | cfg : { switcher : ndimsumflat, name : ndimsumflat_asmjs_name } 45 | 46 | , input : augment_name_value_array_with_mapping( [ 47 | { name : 'mat', value : input } 48 | ] ) 49 | 50 | , output : augment_name_value_array_with_mapping( [ 51 | { name : 'sum', value : expected } 52 | ] ) 53 | } 54 | 55 | , ndimsumflat_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 56 | ; 57 | 58 | function dim2spec( /*array of integer*/dim, /*string*/basic_type ) 59 | { 60 | (basic_type || null).substring.call.a; 61 | return dim.length > 0 62 | ? '[' + dim[ 0 ] + ' ' + dim2spec( dim.slice( 1 ), basic_type ) + ']' 63 | : basic_type 64 | ; 65 | } 66 | 67 | function symbol_ndim_sum( /*array or expression*/x ) 68 | { 69 | if (!(x instanceof Array) || flatorize.isExpr( x )) 70 | return x; 71 | 72 | return flatorize.expr.apply( null, x.reduce( symbol_ndim_sum_step, [] ) ); 73 | 74 | function symbol_ndim_sum_step( left, right ) 75 | { 76 | var sns_r = symbol_ndim_sum( right ); // Recursion to a lower dimension. 77 | return left.length ? left.concat( [ '+', sns_r ] ) : [ sns_r ]; 78 | } 79 | } 80 | 81 | function symbol_ndim_matrix( /*string | object*/what, /*array of integer*/dim ) 82 | // 2-dimensional example: 83 | // 84 | // m := [ [ m[0][0], m[0][1], m[0][2], ... ], 85 | // [ m[1][0], m[1][1], m[1][2], ... ], 86 | // ... 87 | // ] 88 | { 89 | return !(dim.length > 0) 90 | 91 | ? what 92 | 93 | : empty_array( dim[ 0 ] ).map( function ( tmp, a ) { 94 | 95 | return symbol_ndim_matrix( flatorize.part( what, a ), dim.slice( 1 ) ); 96 | }) 97 | ; 98 | } 99 | 100 | function empty_array( size ) 101 | { 102 | return new Array( size ).join( ',' ).split( ',' ); 103 | } 104 | 105 | // --- Do they work? 106 | 107 | function random_ndim_matrix( dim ) 108 | { 109 | return !(dim.length > 0) 110 | ? Math.random() 111 | : empty_array( dim[ 0 ] ).map( 112 | function () { return random_ndim_matrix( dim.slice( 1 ) ); } 113 | ); 114 | } 115 | 116 | function flatten_values( /*array*/ndim_mat ) 117 | { 118 | return ndim_mat[ 0 ] instanceof Array 119 | ? ndim_mat.reduce( function ( a, b ) { return a.concat( flatten_values( b ) ); }, [] ) 120 | : ndim_mat 121 | ; 122 | } 123 | 124 | // flatorized version 125 | 126 | var obtained = ndimsumflat( input ); 127 | 128 | // flatorized+asm.js version 129 | 130 | var ndimsumflat_asmjs_buffer = new ArrayBuffer( ndimsumflat_asmjs_gen.buffer_bytes ) 131 | , ndimsumflat_asmjs_O = ndimsumflat_asmjs_gen( this, {}, ndimsumflat_asmjs_buffer ) // compile 132 | , ndimsumflat_asmjs = ndimsumflat_asmjs_O[ ndimsumflat_asmjs_name ] 133 | 134 | , n2i = ndimsumflat_asmjs_gen.array_name2info 135 | , TypedArray = ndimsumflat_asmjs_gen.TypedArray 136 | 137 | , ndimsumflat_asmjs_input_arr = new TypedArray( ndimsumflat_asmjs_buffer, n2i.mat.begin_bytes, n2i.mat.n ) 138 | ; 139 | 140 | ndimsumflat_asmjs_input_arr.set( flatten_values( input ) ); 141 | 142 | var obtained_asmjs = ndimsumflat_asmjs(); 143 | 144 | //#END_BODY 145 | 146 | // More exports 147 | 148 | E[ ndimsumflat_name ] = ndimsumflat; 149 | 150 | E[ ndimsumflat_asmjs_name ] = ndimsumflat_asmjs; 151 | 152 | // For `expl_run` 153 | 154 | return { name : 'ndimsumflat' 155 | , obtained : { flatorize : obtained 156 | , flatorize_asmjs : obtained_asmjs 157 | } 158 | 159 | , expected : { flatorize : expected 160 | , flatorize_asmjs : expected 161 | } 162 | , input : input 163 | }; 164 | } 165 | -------------------------------------------------------------------------------- /expl/flatasmjs_scalar_from_scalar.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_scalar_from_scalar flatorize ArrayBuffer window passed_asmjsgen_info*/ 2 | 3 | var passed_asmjsgen_info; 4 | function expl_flatasmjs_scalar_from_scalar() 5 | // Probably not the most sumingful use(s) of flatorize (already flat) 6 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 7 | { 8 | var NAME = 'expl_flatasmjs_scalar_from_scalar'; 9 | 10 | // Give external access, for example to display source code. 11 | // Example of use: ../index.html 12 | 13 | var E = expl_flatasmjs_scalar_from_scalar; 14 | 15 | //#BEGIN_BODY 16 | 17 | var plusone_name = 'plusone' 18 | , plusone = flatorize( 19 | // note the :[type] declarations, ignored by `flatorize` 20 | // but useful later in asm.js or C contexts 21 | 'a:double->b:double' 22 | , function (a) 23 | { 24 | return flatorize.expr( a, '+', 1 ); 25 | } 26 | ) 27 | 28 | , input = 3 29 | , expected = input + 1 30 | 31 | , plusone_asmjs_name = plusone_name + '_asmjs' 32 | 33 | , info = (passed_asmjsgen_info || (passed_asmjsgen_info = {}))[ NAME ] = { 34 | 35 | cfg : { switcher : plusone, name : plusone_asmjs_name } 36 | 37 | , input : augment_name_value_array_with_mapping( [ 38 | { name : 'a', value : input } 39 | ] ) 40 | 41 | , output : augment_name_value_array_with_mapping( [ 42 | { name : 'b', value : expected } 43 | ] ) 44 | } 45 | 46 | , plusone_asmjs_gen = flatorize.getAsmjsGen( info.cfg ) 47 | ; 48 | 49 | // --- Do they work? 50 | 51 | // flatorized version 52 | 53 | var obtained = plusone( input ); 54 | 55 | // flatorized+asm.js version 56 | 57 | var plusone_asmjs_buffer = new ArrayBuffer( plusone_asmjs_gen.buffer_bytes ) 58 | , plusone_asmjs_O = plusone_asmjs_gen( this, {}, plusone_asmjs_buffer ) // compile 59 | , plusone_asmjs = plusone_asmjs_O[ plusone_asmjs_name ] 60 | ; 61 | 62 | var obtained_asmjs = plusone_asmjs( input ); 63 | 64 | //#END_BODY 65 | 66 | // More exports 67 | 68 | E[ plusone_name ] = plusone; 69 | 70 | E[ plusone_asmjs_name ] = plusone_asmjs; 71 | 72 | // For `expl_run` 73 | 74 | return { name : 'plusone' 75 | , obtained : { flatorize : obtained 76 | , flatorize_asmjs : obtained_asmjs 77 | } 78 | 79 | , expected : { flatorize : expected 80 | , flatorize_asmjs : expected 81 | } 82 | , input : input 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /expl/flatasmjs_scalarint_from_scalardouble.js: -------------------------------------------------------------------------------- 1 | /*global expl_flatasmjs_scalarint_from_scalardouble flatorize ArrayBuffer window*/ 2 | 3 | function expl_flatasmjs_scalarint_from_scalardouble() 4 | // Probably not the most sumingful use(s) of flatorize (already flat) 5 | // BUT useful as a unit test for both flatorize and flatorize+asm.js 6 | { 7 | // Give external access, for example to display source code. 8 | // Example of use: ../index.html 9 | 10 | var E = expl_flatasmjs_scalarint_from_scalardouble; 11 | 12 | //#BEGIN_BODY 13 | 14 | var plusone_name = 'plusone' 15 | , plusone = flatorize( 16 | // note the :[type] declarations, ignored by `flatorize` 17 | // but useful later in asm.js or C contexts 18 | 'a:double->b:int' 19 | , function (a) 20 | { 21 | return flatorize.expr( a, '+', 1.1 ); 22 | } 23 | ) 24 | ; 25 | 26 | try { 27 | var plusone_asmjs_name = plusone_name + '_asmjs' 28 | , plusone_asmjs_gen = flatorize.getAsmjsGen( { switcher : plusone, name : plusone_asmjs_name } ) 29 | ; 30 | } catch (e) { 31 | 32 | if (!(-1 < ('' + e).indexOf( 'Only one basic type permitted' ))) 33 | throw e; 34 | } 35 | 36 | // --- Do they work? 37 | 38 | var input = 3.456 39 | 40 | , expected = input + 1.1 // `flatorize` disregards the type declarations 41 | 42 | ; 43 | 44 | // flatorized version 45 | 46 | var obtained = plusone( input ); 47 | 48 | // flatorized+asm.js version: not allowed because of type mismatch 49 | 50 | //#END_BODY 51 | 52 | // More exports 53 | 54 | E[ plusone_name ] = plusone; 55 | 56 | // For `expl_run` 57 | 58 | return { name : 'plusone' 59 | , obtained : { flatorize : obtained 60 | } 61 | 62 | , expected : { flatorize : expected 63 | } 64 | , input : input 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /expl/matmulrows_loops.js: -------------------------------------------------------------------------------- 1 | function expl_matmulrows_loops() 2 | { 3 | // Give external access, for example to display source code. 4 | // Example of use: ../index.html 5 | 6 | var E = expl_matmulrows_loops; 7 | E.matmulrows_loops = matmulrows_loops; 8 | 9 | //#BEGIN_BODY 10 | function matmulrows_loops( a, b ) 11 | { 12 | var nrow = a.length 13 | , ncol = b[ 0 ].length 14 | , ret = new Array( nrow ) 15 | , nrow_b = b.length 16 | ; 17 | for (var ir = 0; ir < nrow; ir++) 18 | { 19 | var ra = a[ ir ] 20 | , rr = ret[ ir ] = new Array( ncol ) 21 | ; 22 | for (var ic = 0; ic < ncol; ic++) 23 | { 24 | var x = 0; 25 | for (var irb = 0; irb < nrow_b; irb++) 26 | { 27 | x += ra[ irb ] * b[ irb ][ ic ]; 28 | } 29 | rr[ ic ] = x; 30 | } 31 | } 32 | return ret; 33 | } 34 | 35 | // Does this work? 36 | 37 | var a = [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ] 38 | , b = [ [13,14], [15,16], [17,18], [19,20] ] 39 | , c = matmulrows_loops( a, b ) 40 | ; 41 | //#END_BODY 42 | 43 | // For `expl_run` 44 | 45 | return { name : 'c', obtained : c, expected : [[170,180],[426,452],[682,724]] }; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /expl/matmulrows_zip.js: -------------------------------------------------------------------------------- 1 | function expl_matmulrows_zip() 2 | { 3 | // Give external access, for example to display source code. 4 | // Example of use: ../index.html 5 | 6 | var E = expl_matmulrows_zip; 7 | E.matmulrows_zip = matmulrows_zip; 8 | E.zip = zip; 9 | E.sum = sum; 10 | 11 | //#BEGIN_BODY 12 | function matmulrows_zip( a, b ) 13 | { 14 | return a.map( function (ra) { 15 | return zip.apply( null, b ).map( function (cb) { 16 | return sum( 17 | zip( ra, cb ) 18 | .map( function (xy) { 19 | return xy[ 0 ] * xy[ 1 ]; 20 | } ) 21 | ); 22 | } ); 23 | } ); 24 | } 25 | 26 | // Tools 27 | 28 | function zip(/*...arguments...*/) 29 | { 30 | var arg = [].slice.apply( arguments ); 31 | if (!arg.length) 32 | return []; 33 | 34 | var n = arg[ 0 ].length 35 | , ret = new Array( n ) 36 | ; 37 | for (var i = 0; i < n; i++) 38 | ret[ i ] = arg.map( function (x) { return x[i]; } ); 39 | 40 | return ret; 41 | } 42 | 43 | function sum( a ) 44 | { 45 | return a.reduce( function (c,d) { return c + d; }, 0 ); 46 | } 47 | 48 | // Does this work? 49 | 50 | var a = [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ] 51 | , b = [ [13,14], [15,16], [17,18], [19,20] ] 52 | , c = matmulrows_zip( a, b ) 53 | ; 54 | //#END_BODY 55 | 56 | // For `expl_run` 57 | 58 | return { name : 'c', obtained : c, expected : [[170,180],[426,452],[682,724]] }; 59 | } 60 | -------------------------------------------------------------------------------- /expl/matmulrows_zip_flatorize.js: -------------------------------------------------------------------------------- 1 | function expl_matmulrows_zip_flatorize() 2 | { 3 | // Give external access, for example to display source code. 4 | // Example of use: ../index.html 5 | 6 | var E = expl_matmulrows_zip_flatorize; 7 | E.symbol_matmulrows_zip_gen = symbol_matmulrows_zip_gen; 8 | E.symbol_matmulrows_zip = symbol_matmulrows_zip; 9 | E.symbol_matrixrows = symbol_matrixrows; 10 | E.symbol_sum = symbol_sum; 11 | 12 | //#BEGIN_BODY 13 | var matmulrows_zip_342 = flatorize( 14 | // note the :[type] declarations, ignored by `flatorize` 15 | // but useful later in asm.js or C contexts 16 | 'a:[3 [4 double]],b:[4 [2 double]]->c:[3 [2 double]]' 17 | , function (a,b) { return symbol_matmulrows_zip_gen( a, b, 3, 4, 2 ); } 18 | ); 19 | 20 | // Wrapper 21 | 22 | function symbol_matmulrows_zip_gen( a, b, I, J, K ) 23 | { 24 | // Create matrices of symbolic expressions (NOT numbers) 25 | var sym_a = symbol_matrixrows( a, I, J ) 26 | , sym_b = symbol_matrixrows( b, J, K ) 27 | ; 28 | // Multiply the symbolic matrices 29 | return symbol_matmulrows_zip( sym_a, sym_b ); 30 | } 31 | 32 | // Core 33 | 34 | function symbol_matmulrows_zip( a, b ) 35 | { 36 | return a.map( function (ra) { 37 | return transpose( b ).map( function (cb) { 38 | return symbol_sum( 39 | zip( ra, cb ) 40 | .map( function (xy) { 41 | return flatorize.expr( xy[ 0 ], '*', xy[ 1 ] ); 42 | } ) 43 | ); 44 | } ); 45 | } ); 46 | } 47 | 48 | // Tools 49 | 50 | function symbol_matrixrows( name, nrow, ncol ) 51 | // m := [ [ m[0][0], m[0][1], m[0][2], ... ], 52 | // [ m[1][0], m[1][1], m[1][2], ... ], 53 | // ... 54 | // ] 55 | { 56 | return empty_array( nrow ).map( function ( tmp, r ) { 57 | 58 | return empty_array( ncol ).map( function ( tmp, c ) { 59 | 60 | return flatorize.part( flatorize.part( name, r ), c ); // e.g. m[r][c] 61 | }); 62 | }); 63 | } 64 | 65 | function empty_array( size ) 66 | { 67 | return new Array( size ).join( ',' ).split( ',' ); 68 | } 69 | 70 | function symbol_sum( arr ) 71 | // sum( arr ) := arr[0] + arr[1] + ... 72 | { 73 | return flatorize.expr.apply( null, arr.reduce( symbol_sum_step, [] ) ); 74 | function symbol_sum_step( left, right ) 75 | { 76 | return left.length ? left.concat( [ '+', right ] ) : [ right ]; 77 | } 78 | } 79 | 80 | // Does this work? 81 | 82 | var a = [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ] 83 | , b = [ [13,14], [15,16], [17,18], [19,20] ] 84 | , c = matmulrows_zip_342( a, b ) 85 | ; 86 | //#END_BODY 87 | 88 | // More tools 89 | 90 | function transpose( mat ) 91 | { 92 | return zip.apply( null, mat ); 93 | } 94 | 95 | function zip(/*...arguments...*/) 96 | { 97 | var arg = [].slice.apply( arguments ); 98 | if (!arg.length) 99 | return []; 100 | 101 | var n = arg[ 0 ].length 102 | , ret = new Array( n ) 103 | ; 104 | for (var i = 0; i < n; i++) 105 | ret[ i ] = arg.map( function (x) { return x[i]; } ); 106 | 107 | return ret; 108 | } 109 | 110 | // More exports 111 | 112 | E.matmulrows_zip_342 = matmulrows_zip_342; 113 | 114 | // For `expl_run` 115 | 116 | return { name : 'c', obtained : c, expected : [[170,180],[426,452],[682,724]] }; 117 | } 118 | -------------------------------------------------------------------------------- /flatorize.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glathoud/flatorize/79801c3cde0175c16178ff00e7474edcaf6a5d60/flatorize.js -------------------------------------------------------------------------------- /lib/README.md: -------------------------------------------------------------------------------- 1 | `flatmat.js`: a library of fast linear algebra functions for flat 2-D matrices, i.e. matrices stored as 1-D arrays of numbers. 2 | -------------------------------------------------------------------------------- /lib/flatmat_speedtest_layout.js: -------------------------------------------------------------------------------- 1 | function toggle_parent_shown( node ) 2 | { 3 | var pN = node.parentNode; 4 | pN.classList[ pN.classList.contains('shown')?'remove':'add' ]( 'shown' ); 5 | } 6 | 7 | (function () { 8 | 9 | var contents = [].slice.call( qSA( '.contents' ) ); 10 | 11 | [].forEach.call( qSA('section[id]'), setup_anchor ); 12 | 13 | var api = gEBI( 'api' ); 14 | if (api) 15 | { 16 | [ fm_id 17 | , fm_inv_of_ij 18 | , fm_mul_of_ijk 19 | , fm_mu_sigma_of_dim 20 | , fm_xvmxv_of_dim 21 | ] 22 | .forEach( api_describe_one ) 23 | ; 24 | } 25 | 26 | function setup_anchor( section_node ) 27 | { 28 | var id = gA( 'id', section_node ) 29 | , h = id && qS( 'h1,h2,h3', section_node ) 30 | ; 31 | if (id && h) 32 | { 33 | var s_html = h.innerHTML; 34 | 35 | aC( h 36 | , anchor_link_of_id( id ) 37 | ); 38 | 39 | contents.forEach( setup_one_line_in_contents ); 40 | } 41 | 42 | function setup_one_line_in_contents( ul ) 43 | { 44 | aC( ul 45 | , aC( cE( 'li' ) 46 | , sP( sA( cE( 'a' ), { href : '#' + id } ) 47 | , { innerHTML : s_html } 48 | ) 49 | ) 50 | ); 51 | } 52 | } 53 | 54 | function api_describe_one( f, i, noli ) 55 | { 56 | var src = ''+f; 57 | 58 | var mo = /^\s*function\s+((\S+?)\(.*?)$\s*\/\*\s*([\s\S]*?)\*\//m.exec( src ) 59 | , title = mo[ 1 ] 60 | , name = mo[ 2 ] 61 | , a_id = 'api_' + name 62 | 63 | , expl_f = name in fm_unittest && fm_unittest[ name ] 64 | 65 | , descr = '

' + mo[ 3 ] 66 | .replace( /`([^`]+)`/g, '$1' ) 67 | .replace( /[\r\n]\s+[\r\n]/g, '

' ) 68 | + '

' 69 | + (!expl_f ? '' : 70 | '
' 71 | + '' 72 | + '
' + clean_body( expl_f ) + '
' 73 | + '
' 74 | ) 75 | + (i < noli.length - 1 ? '
' : '') 76 | ; 77 | 78 | aC( api 79 | , aC( sA( cE( 'dt' ) 80 | , { id : a_id } 81 | ) 82 | , sP( sA( cE( 'code' ) 83 | , { 'class': 'prettyprint lang-js' } 84 | ) 85 | , { innerHTML : title } 86 | ) 87 | , anchor_link_of_id( a_id ) 88 | ) 89 | , aC( cE( 'dd' ) 90 | , sP( cE( 'span' ) 91 | , { innerHTML : descr } 92 | ) 93 | ) 94 | ); 95 | } 96 | 97 | 98 | function anchor_link_of_id( id ) 99 | { 100 | return sA( aC( cE( 'span' ) 101 | , sP( sA( cE( 'a' ) 102 | , { href: '#' + id } 103 | ) 104 | , { 'innerHTML' : '#' } 105 | ) 106 | ) 107 | , { 'class' : 'anchor-link' } 108 | ); 109 | } 110 | 111 | function clean_body( f ) 112 | { 113 | var mo = /^[^\{]*\{([\s\S]*)\}\s*$/.exec( f ) 114 | , body = mo[ 1 ] 115 | , line_arr = body.match( /[\s\S]*?[\r\n]+/g ) 116 | , len_arr = line_arr.map( li => /^\s*$/.test( li ) ? +Infinity : /^\s+/.exec( li )[ 0 ].length ) 117 | , indent = Math.min.apply( Math, len_arr ) 118 | ; 119 | 120 | return line_arr.map( li => li.substring( indent ) ).join( '' ); 121 | } 122 | 123 | })(); 124 | -------------------------------------------------------------------------------- /log.js: -------------------------------------------------------------------------------- 1 | /* 2 | ECMAScript implementation of a few logging functions for both 3 | browsers and command-line engines (V8). 4 | 5 | 6 | Copyright 2013 Guillaume Lathoud 7 | 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | 20 | A copy of the Apache License Version 2.0 as of February 20th, 2013 21 | can be found in the file ./LICENSE.TXT 22 | */ 23 | 24 | function log(/*...arguments...*/) 25 | { 26 | // Browser environment 27 | if (typeof console !== 'undefined' && console.log) 28 | { 29 | try 30 | { 31 | console.log.apply( console, arguments ); 32 | } 33 | catch (e) 34 | { 35 | // Probably some IE browser 36 | console.log( Array.prototype.join.call( arguments, ' ' ) ) 37 | } 38 | } 39 | 40 | else 41 | { 42 | // Non-browser environment 43 | print.apply( null, arguments ); 44 | } 45 | } 46 | 47 | function time(name) 48 | { 49 | time[name] = new Date; // Using the fact that JavaScript functions are objects as well. 50 | } 51 | 52 | function timeEnd(name) 53 | { 54 | time[name] = new Date - time[name]; 55 | log(name, time[name] + 'ms'); 56 | } 57 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_00/dll.d: -------------------------------------------------------------------------------- 1 | import core.stdc.stdio; 2 | 3 | extern (C) int dll() 4 | { 5 | printf("dll()\n"); 6 | return 0; 7 | } 8 | 9 | shared static this() 10 | { 11 | printf("libdll.so shared static this\n"); 12 | } 13 | 14 | shared static ~this() 15 | { 16 | printf("libdll.so shared static ~this\n"); 17 | } 18 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_00/main.d: -------------------------------------------------------------------------------- 1 | import core.stdc.stdio; 2 | import core.stdc.stdlib; 3 | import core.sys.posix.dlfcn; 4 | 5 | // not needed: extern (C) int dll(); 6 | 7 | int main() 8 | { 9 | printf("+main()\n"); 10 | 11 | void* lh = dlopen("libdll.so", RTLD_LAZY); 12 | if (!lh) 13 | { 14 | fprintf(stderr, "dlopen error: %s\n", dlerror()); 15 | exit(1); 16 | } 17 | printf("libdll.so is loaded\n"); 18 | 19 | int function() fn = cast(int function())dlsym(lh, "dll"); 20 | char* error = dlerror(); 21 | if (error) 22 | { 23 | fprintf(stderr, "dlsym error: %s\n", error); 24 | exit(1); 25 | } 26 | printf("dll() function is found\n"); 27 | 28 | fn(); 29 | 30 | printf("unloading libdll.so\n"); 31 | dlclose(lh); 32 | 33 | printf("-main()\n"); 34 | return 0; 35 | } 36 | 37 | shared static this() { printf("main shared static this\n"); } 38 | 39 | shared static ~this() { printf("main shared static ~this\n"); } 40 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_00/main_dmd.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | COMPILO="dmd" 4 | PATH_WHERE_SHARED_LIB_IS="." 5 | 6 | rm *.map *.o *.so *.bin 2>>/dev/null 7 | 8 | cd "$PATH_WHERE_SHARED_LIB_IS" 9 | rm *.map *.o *.so *.bin 2>>/dev/null 10 | 11 | cd - 12 | 13 | $COMPILO -c dll.d -fPIC 14 | $COMPILO -oflibdll.so dll.o -shared -defaultlib=libphobos2.so -L-rpath="$PATH_WHERE_SHARED_LIB_IS" 15 | 16 | $COMPILO -c main.d 17 | $COMPILO -ofmain.bin main.o -L-ldl -defaultlib=libphobos2.so -L-rpath=".:$PATH_WHERE_SHARED_LIB_IS" -map 18 | 19 | ./main.bin 20 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_00/main_ldc2.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | LDC_DIR="~/other2/software/ldc" 4 | COMPILO="$LDC_DIR/bin/ldmd2" 5 | FULLNAME_SHARED_LIB="$LDC_DIR/lib/libphobos2-ldc-shared.so.2.0.80" 6 | 7 | rm *.map *.o *.so *.bin 2>>/dev/null 8 | 9 | cd "$PATH_WHERE_SHARED_LIB_IS" 10 | rm *.map *.o *.so *.bin 2>>/dev/null 11 | 12 | cd - 13 | 14 | $COMPILO -c dll.d -fPIC 15 | $COMPILO -oflibdll.so dll.o -shared -L-rpath="." -L"$FULLNAME_SHARED_LIB" 16 | 17 | $COMPILO -c main.d 18 | # $COMPILO -ofmain.bin main.o -L-ldl -L-rpath="." -L"$FULLNAME_SHARED_LIB" -map 19 | # Warning: command-line option '-map' not yet supported by LDC. 20 | $COMPILO -ofmain.bin main.o -L-ldl -L-rpath="." -L"$FULLNAME_SHARED_LIB" 21 | 22 | ./main.bin 23 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_00/output_main_dmd.txt: -------------------------------------------------------------------------------- 1 | /home/oa/d/glathoud/tmp/flatorize/misc/d_dynamic_loading/try_00 2 | main shared static this 3 | +main() 4 | libdll.so shared static this 5 | libdll.so is loaded 6 | dll() function is found 7 | dll() 8 | unloading libdll.so 9 | libdll.so shared static ~this 10 | -main() 11 | main shared static ~this 12 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_00/output_main_ldc2.txt: -------------------------------------------------------------------------------- 1 | /home/oa/d/glathoud/tmp/flatorize/misc/d_dynamic_loading/try_00 2 | main shared static this 3 | +main() 4 | libdll.so shared static this 5 | libdll.so is loaded 6 | dll() function is found 7 | dll() 8 | unloading libdll.so 9 | libdll.so shared static ~this 10 | -main() 11 | main shared static ~this 12 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_01_import/mymodule.d: -------------------------------------------------------------------------------- 1 | 2 | // rdmd -J. mymodule.d 3 | // rdmd -J. mymodule.d 4 | // rdmd --force -J. mymodule.d 5 | 6 | module mymodule; 7 | 8 | void main() 9 | { 10 | // from: 11 | // https://forum.dlang.org/thread/ifllo2$a45$1@digitalmars.com 12 | pragma(msg, import(.stringof[7..$] ~ ".d")); 13 | } 14 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_01_import/some_package/mymodule2.d: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | cd .. 4 | rdmd -J. some_package/mymodule2.d 5 | rdmd -J. some_package/mymodule2.d 6 | rdmd --force -J. some_package/mymodule2.d 7 | 8 | */ 9 | 10 | module some_package.mymodule; 11 | 12 | import std.string; 13 | 14 | void main() 15 | { 16 | // from: 17 | // https://forum.dlang.org/thread/ifllo2$a45$1@digitalmars.com 18 | pragma(msg, import(.stringof[7..$].replace(".","/") ~ ".d")); 19 | } 20 | -------------------------------------------------------------------------------- /misc/d_dynamic_loading/try_01_import/some_package/mymodule3.d: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | cd .. 4 | rdmd -J. some_package/mymodule3.d 5 | rdmd -J. some_package/mymodule3.d 6 | */ 7 | 8 | module some_package.mymodule; 9 | 10 | import std.string; 11 | 12 | void main() 13 | { 14 | // from: 15 | // https://forum.dlang.org/thread/ifllo2$a45$1@digitalmars.com 16 | immutable CODE = import(.stringof[7..$].replace(".","/") ~ ".d"); 17 | writeln( CODE ); 18 | } 19 | -------------------------------------------------------------------------------- /prettify/lang-apollo.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/, 2 | null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["apollo","agc","aea"]) -------------------------------------------------------------------------------- /prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[ \t\r\n\f]+/,null," \t\r\n\u000c"]],[["str",/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],["str",/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],["kwd",/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//], 2 | ["com",/^(?: