diff --git a/e2e/assets/matrix_multiply_mo/dfx.json b/e2e/assets/matrix_multiply_mo/dfx.json new file mode 100644 index 0000000000..8fd273a7ad --- /dev/null +++ b/e2e/assets/matrix_multiply_mo/dfx.json @@ -0,0 +1,23 @@ +{ + "canisters": { + "dot_product": { + "main": "dot_product.mo" + }, + "hello": { + "main": "matrix.mo" + }, + "transpose": { + "main": "transpose.mo" + } + }, + "defaults": { + "build": { + "output": "canisters/" + }, + "start": { + "address": "127.0.0.1", + "port": 8000, + "serve_root": "canisters/hello/assets" + } + } +} diff --git a/e2e/assets/matrix_multiply_mo/dot_product.mo b/e2e/assets/matrix_multiply_mo/dot_product.mo new file mode 100644 index 0000000000..83a045bc53 --- /dev/null +++ b/e2e/assets/matrix_multiply_mo/dot_product.mo @@ -0,0 +1,20 @@ +type Vec = [Int]; + +actor { + var vec : Vec = []; + + public func init(a: Vec) : async () { + vec := a; + }; + public query func dot_product_with(b: Vec) : async Int { + assert (vec.len() == b.len()); + var res: Int = 0; + let len = vec.len(); + var i = 0; + while (i < len) { + res := res + vec[i]*b[i]; + i += 1; + }; + res + }; +}; diff --git a/e2e/assets/matrix_multiply_mo/matrix.mo b/e2e/assets/matrix_multiply_mo/matrix.mo new file mode 100644 index 0000000000..f5cd1285a5 --- /dev/null +++ b/e2e/assets/matrix_multiply_mo/matrix.mo @@ -0,0 +1,29 @@ +import A "mo:stdlib/array.mo"; +import D "canister:dot_product"; +import T "canister:transpose"; + +type Matrix = [[Int]]; + +actor { + public func multiply(a: Matrix, b: Matrix) : async Matrix { + assert (a.len() > 0 and b.len() > 0); + assert (a[0].len() == b.len()); + let n = a.len(); + let k = b[0].len(); + let bt = await T.transpose(b); + let res : [[var Int]] = A.tabulate<[var Int]>(n, func (_:Nat):[var Int] = A.init(k, 0)); + var i = 0; + while (i < n) { + await D.init(a[i]); + var j = 0; + while (j < k) { + res[i][j] := await D.dot_product_with(bt[j]); + j += 1; + }; + i += 1; + }; + A.tabulate<[Int]>( + n, + func (i:Nat) : [Int] { A.freeze(res[i]) }); + }; +}; diff --git a/e2e/assets/matrix_multiply_mo/patch.bash b/e2e/assets/matrix_multiply_mo/patch.bash new file mode 100644 index 0000000000..be830bd8c9 --- /dev/null +++ b/e2e/assets/matrix_multiply_mo/patch.bash @@ -0,0 +1 @@ +# nothing to do diff --git a/e2e/assets/matrix_multiply_mo/transpose.mo b/e2e/assets/matrix_multiply_mo/transpose.mo new file mode 100644 index 0000000000..0147020bd1 --- /dev/null +++ b/e2e/assets/matrix_multiply_mo/transpose.mo @@ -0,0 +1,16 @@ +import A "mo:stdlib/array.mo"; + +type Matrix = [[Int]]; + +actor { + public query func transpose(m: Matrix) : async Matrix { + assert (m.len() > 0); + let n_row = m.len(); + let n_col = m[0].len(); + A.tabulate<[Int]>( + n_col, + func (j:Nat) : [Int] { + A.tabulate(n_row, func (i:Nat) : Int = (m[i][j])); + }); + }; +}; diff --git a/e2e/basic-project.bash b/e2e/basic-project.bash index 8533ae62bd..2be9427ebd 100644 --- a/e2e/basic-project.bash +++ b/e2e/basic-project.bash @@ -133,3 +133,13 @@ teardown() { assert_command dfx canister call hello inc '(42,false,"testzZ",vec{1;2;3},opt record{head=42; tail=opt record{head=+43; tail=none}}, variant { cons=record{ 42; variant { cons=record{43; variant { nil }} } } })' assert_eq "(+43, true, \"uftu{[\", vec { 2; 3; 4; }, opt record { 1158359328 = +43; 1291237008 = opt record { 1158359328 = +44; 1291237008 = none; }; }, variant { 1103411697 = record { 0 = +43; 1 = variant { 1103411697 = record { 0 = +44; 1 = variant { 5493713 = null }; } }; } })" } + +@test "build + install + call -- matrix_multiply_mo" { + install_asset matrix_multiply_mo + dfx_start + dfx build + dfx canister install --all + + assert_command dfx canister call hello multiply '(vec{vec{1;2};vec{3;4};vec{5;6}},vec{vec{1;2;3};vec{4;5;6}})' + assert_eq "(vec { vec { +9; +12; +15; }; vec { +19; +26; +33; }; vec { +29; +40; +51; }; })" +}