diff --git a/Tests/EndToEndTests/TestCases/Concurrency/skynet_bulk.hylo b/Tests/EndToEndTests/TestCases/Concurrency/skynet_bulk.hylo new file mode 100644 index 000000000..34bc58f92 --- /dev/null +++ b/Tests/EndToEndTests/TestCases/Concurrency/skynet_bulk.hylo @@ -0,0 +1,42 @@ +//- compileToLLVM expecting: success + +fun skynet(num: Int, size: Int, div: Int) -> Int { + if size == 1 { + return num.copy() + } else { + var results = Array(count: div, initialized_with: fun (_ i: Int) { 0 }) + let sub_size = size / div + let p = mutable_pointer[to: &results] + spawn_(count: div, action: fun[sink let q = p.copy(), sink let n = num.copy(), sink let s = sub_size.copy(), sink let d = div.copy()] (index: Int) -> Void { + inout results = q.copy().unsafe[] + &results[index] = skynet(num: n + index * s, size: s, div: d) + }).await() + + return sum(results) + } +} + +fun sum(_ array: Array) -> Int { + var result = 0 + var i = 0 + while i != array.count() { + &result += array[i] + &i += 1 + } + return result +} + +@ffi("clock") +public fun clock() -> Int + +fun time_in_ms(_ clock_diff: Int) -> Int { + return clock_diff / 10_000 // TODO: constant dependent on the platform +} + +public fun main() { + let start = clock() + let result = skynet(num: 0, size: 1_000_000, div: 10); + let end = clock() + print(time_in_ms(end - start), terminator: " ms\n") + precondition(result == 499999500000, "invalid result") +} diff --git a/Tests/EndToEndTests/TestCases/Concurrency/skynet_strict.hylo b/Tests/EndToEndTests/TestCases/Concurrency/skynet_strict.hylo new file mode 100644 index 000000000..d71e6900b --- /dev/null +++ b/Tests/EndToEndTests/TestCases/Concurrency/skynet_strict.hylo @@ -0,0 +1,67 @@ +//- compileToLLVM expecting: success + +fun skynet(num: Int, size: Int, div: Int) -> Int { + if size == 1 { + return num.copy() + } else { + let sub_size = size / div + let f1 = spawn_(fun[sink let n = num.copy(), sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f2 = spawn_(fun[sink let n = num + sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f3 = spawn_(fun[sink let n = num + 2 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f4 = spawn_(fun[sink let n = num + 3 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f5 = spawn_(fun[sink let n = num + 4 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f6 = spawn_(fun[sink let n = num + 5 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f7 = spawn_(fun[sink let n = num + 6 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f8 = spawn_(fun[sink let n = num + 7 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f9 = spawn_(fun[sink let n = num + 8 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + let f10 = spawn_(fun[sink let n = num + 9 * sub_size, sink let s = sub_size.copy(), sink let d = div.copy()] () { + skynet(num: n, size: s, div: d) + }) + + var sum = 0 + sum += f1.await() + sum += f2.await() + sum += f3.await() + sum += f4.await() + sum += f5.await() + sum += f6.await() + sum += f7.await() + sum += f8.await() + sum += f9.await() + sum += f10.await() + return sum + } +} + +@ffi("clock") +public fun clock() -> Int + +fun time_in_ms(_ clock_diff: Int) -> Int { + return clock_diff / 10_000 // TODO: constant dependent on the platform +} + +public fun main() { + let start = clock() + let result = skynet(num: 0, size: 1_000_000, div: 10); + let end = clock() + print(time_in_ms(end - start), terminator: " ms\n") + precondition(result == 499999500000, "invalid result") +} diff --git a/Tests/EndToEndTests/TestCases/Concurrency/skynet_weak.hylo b/Tests/EndToEndTests/TestCases/Concurrency/skynet_weak.hylo new file mode 100644 index 000000000..40d0329cd --- /dev/null +++ b/Tests/EndToEndTests/TestCases/Concurrency/skynet_weak.hylo @@ -0,0 +1,53 @@ +//- compileToLLVM expecting: success + +fun skynet(num: Int, size: Int, div: Int) -> Int { + if size == 1 { + return num.copy() + } else { + let sub_size = size / div + var futures = Array>() + &futures.reserve_capacity(div) + var i = 0 + while i != div { + let cur_num = num + i * sub_size + let f = escaping_spawn_(fun[sink let n = cur_num.copy(), sink let s = sub_size.copy(), sink let d = div.copy()] () -> Int { + skynet(num: n, size: s, div: d) + }) + &futures.append(f) + &i += 1 + } + + var sum = 0 + var i2 = 0 + while i2 != div { + if inout f: EscapingFuture<{n: Int, s: Int, d: Int}> = &futures.pop_last() { + sum += &f.await() + } + &i2 += 1 + } + return sum + } +} + +public conformance EscapingFuture: SemiRegular { + + public fun infix== (_ other: Self) -> Bool { + return false + } + +} + +@ffi("clock") +public fun clock() -> Int + +fun time_in_ms(_ clock_diff: Int) -> Int { + return clock_diff / 10_000 // TODO: constant dependent on the platform +} + +public fun main() { + let start = clock() + let result = skynet(num: 0, size: 1_000_000, div: 10); + let end = clock() + print(time_in_ms(end - start), terminator: " ms\n") + precondition(result == 499999500000, "invalid result") +}