Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions e2e/assets/matrix_multiply_mo/dot_product.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
type Vec = [Int];

actor {
public func dot_product(a:Vec, b:Vec) : async Int {
Comment thread
chenyan-dfinity marked this conversation as resolved.
Outdated
assert (a.len() == b.len());
var res: Int = 0;
let len = a.len();
var i = 0;
while (i < len) {
res := res + a[i]*b[i];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add support for matrix operations/SIMD 😂

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Machine Learning!!!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

i += 1;
};
res
};
};
37 changes: 37 additions & 0 deletions e2e/assets/matrix_multiply_mo/matrix.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import A "mo:stdlib/array.mo";
import D "canister:dot_product";

type Matrix = [[Int]];

actor {
public 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<Int>(n_row, func (i:Nat) : Int = (m[i][j]));
});
};
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 transpose(b);
let res : [[var Int]] = A.tabulate<[var Int]>(n, func (_:Nat):[var Int] = A.init<Int>(k, 0));
var i = 0;
while (i < n) {
var j = 0;
while (j < k) {
res[i][j] := await D.dot_product(a[i], bt[j]);
j += 1;
};
i += 1;
};
A.tabulate<[Int]>(
n,
func (i:Nat) : [Int] { A.freeze<Int>(res[i]) });
};
};
3 changes: 3 additions & 0 deletions e2e/assets/matrix_multiply_mo/patch.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dfx config --new_canister dot_product
dfx config canisters/dot_product/main dot_product.mo
dfx config canisters/hello/main matrix.mo
10 changes: 10 additions & 0 deletions e2e/basic-project.bash
Original file line number Diff line number Diff line change
Expand Up @@ -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; }; })"
}
23 changes: 23 additions & 0 deletions src/dfx/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ pub fn construct() -> App<'static, 'static> {
.default_value("json")
.possible_values(&["json", "text"]),
Comment thread
chenyan-dfinity marked this conversation as resolved.
)
.arg(
Arg::with_name("new_canister")
.help(UserMessage::OptionFormat.to_str())
.long("new_canister")
.takes_value(true),
)
}

pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
Expand All @@ -28,6 +34,23 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
.as_ref()
.clone();

if let Some(name) = args.value_of("new_canister") {
let p = config.get_mut_json().pointer_mut("/canisters").unwrap();
Comment thread
chenyan-dfinity marked this conversation as resolved.
Outdated
let value: serde_json::Map<String, Value> = [(
"main".to_string(),
("src/".to_owned() + name + "/main.mo").into(),
)]
.iter()
.cloned()
.collect();
Comment thread
chenyan-dfinity marked this conversation as resolved.
Outdated

p.as_object_mut()
.unwrap()
Comment thread
chenyan-dfinity marked this conversation as resolved.
Outdated
.insert(name.to_string(), Value::from(value));
// TODO create the directory and file
Comment thread
chenyan-dfinity marked this conversation as resolved.
Outdated
return config.save();
}

let config_path = args.value_of("config_path").unwrap_or("");
let format = args.value_of("format").unwrap_or("json");

Expand Down