Commit c0202255 authored by Xavier Thompson's avatar Xavier Thompson

Adapt and move tests/ into examples/

parent 8e04cf4f
Makefile.g++-11
\ No newline at end of file
CXX = clang++-14
CXXFLAGS = -g -O3 -flto -Werror -Wall -Wextra -std=c++20 -stdlib=libc++ -I../include
LDLIBS = -pthread
CXX=g++-11
CXXFLAGS=-g -O3 -fwhole-program -flto -Wall -Wextra -Werror -std=c++20 -fcoroutines -I../include
LDLIBS=-pthread
#include <typon/typon.hpp>
#include <typon/logger.hpp>
using namespace typon;
int fibo(int n) {
if (n < 2)
return n;
return fibo(n - 1) + fibo(n - 2);
}
Task<void> hello(int id) {
int n = fibo(20);
LOG("hello(%d), fibo(20) = %d", id, n);
co_return;
}
Join<void> parallel() {
for (int id = 0; id < 30; id++) {
co_await fork(hello(id));
LOG("resume after fork(hello(%d))", id);
}
LOG("sync()");
co_await Sync();
LOG("resume after sync()");
for (int id = 30; id < 60; id++) {
co_await fork(hello(id));
LOG("resume after fork(hello(%d))", id);
}
}
Root root() {
co_await parallel();
LOG("resume root after parallel()");
}
int main() {
root().call();
puts("done");
return 0;
}
#include <typon/typon.hpp>
#include <typon/logger.hpp>
#include <cstdio>
using namespace typon;
int fibo(int n) {
if (n < 2) {
return n;
}
return fibo(n - 1) + fibo(n - 2);
}
Task<void> hello(int id) {
int result = fibo(20);
LOG(" || hello(%2d), fibo(20) = %d", id, result);
co_return;
}
Task<void> fail() {
throw std::exception();
co_return;
}
Join<void> fail_join() {
co_await fork(fail());
}
Join<void> join_sync(int max) {
for (int id = 0; id < max; id++) {
co_await fork(hello(id));
}
try {
co_await fork(fail_join());
LOG(" ... fork(fail_join()) did not throw (stolen continuation)");
} catch(std::exception &) {
LOG(" ... fork(fail_join()) did throw, rethrowing");
throw;
}
LOG(" ... sync()");
try
{
co_await Sync();
LOG(" ... ERROR sync() did not throw");
} catch(std::exception &) {
LOG(" ... OK sync() did throw, rethrowing");
throw;
}
}
Join<void> join_no_sync(int max) {
for (int id = 0; id < max; id++) {
co_await fork(hello(id));
}
try {
co_await fork(fail_join());
LOG(" ... fork(fail_join()) did not throw (stolen continuation)");
} catch(std::exception &) {
LOG(" ... fork(fail_join()) did throw, rethrowing");
throw;
}
LOG(" ... join_no_sync(%d) is exiting normally", max);
}
Root root_sync(int max) {
try {
LOG(">>> join_sync(%d)", max);
co_await join_sync(max);
LOG("ERROR join_sync(%d) did not throw\n", max);
} catch(std::exception &) {
LOG("OK join_sync(%d) did throw\n", max);
}
}
Root root_no_sync(int max) {
try {
LOG(">>> join_no_sync(%d)", max);
co_await join_no_sync(max);
LOG("ERROR join_no_sync(%d) did not throw\n", max);
} catch(std::exception &) {
LOG("OK join_no_sync(%d) did throw\n", max);
}
}
int main() {
root_sync(0).call();
root_sync(20).call();
root_no_sync(0).call();
root_no_sync(20).call();
puts("done");
return 0;
}
#include <typon/typon.hpp>
#include <cstdio>
using namespace typon;
int fibo(int n) {
if (n < 2)
return n;
return fibo(n - 1) + fibo(n - 2);
}
Task<int> producer(int n) {
int value = fibo(n);
printf("[%u] producing %d\n", Scheduler::thread_id, value);
co_return value;
}
Task<void> consumer() {
printf("[%u] launching future\n", Scheduler::thread_id);
Future f = co_await future(producer(20));
printf("[%u] waiting on future\n", Scheduler::thread_id);
int value = co_await f.get();
printf("[%u] future yielded %d\n", Scheduler::thread_id, value);
}
Root root() {
co_await consumer();
}
int main() {
root().call();
puts("done");
return 0;
}
#include <typon/typon.hpp>
#include <cstdio>
using namespace typon;
int fibo(int n) {
if (n < 2)
return n;
return fibo(n - 1) + fibo(n - 2);
}
Task<int> producer(int n) {
int value = fibo(n);
printf("[%u] producing %d\n", Scheduler::thread_id, value);
co_return value;
}
Task<void> consumer() {
printf("[%u] launching future\n", Scheduler::thread_id);
Future f = co_await future(producer(40));
printf("[%u] leaking future\n", Scheduler::thread_id);
}
Root root() {
co_await consumer();
}
int main() {
root().call();
puts("done");
return 0;
}
#include <typon/task.hpp>
#include <cstdio>
using namespace typon;
Task<int> add(int a, int b) {
co_return a + b;
}
Task<int> loop(int n) {
int result = 0;
for (int i = 0; i < n; i++) {
result = result + co_await add(i, i+1);
}
co_return result;
}
int main() {
int result = loop(100000000).call();
printf("%d\n", result);
}
#include <typon/typon.hpp>
#include <cstdio>
using namespace typon;
int fibo(int n) {
if (n < 2) {
return n;
}
int a = fibo(n - 1);
int b = fibo(n - 2);
return a + b;
}
Join<int> parallel_fibo(int n) {
if (n < 2) {
co_return n;
}
if (n < 25)
{
int a = fibo(n - 1);
int b = fibo(n - 2);
co_return a + b;
}
auto a = co_await fork(parallel_fibo(n - 1));
auto b = co_await fork(parallel_fibo(n - 2));
co_await Sync();
co_return a.get() + b.get();
}
Root root() {
int result = co_await parallel_fibo(40);
printf("%d\n", result);
}
int main() {
root().call();
puts("done");
return 0;
}
#include <cstdio>
int fibo(int n) {
if (n < 2) {
return n;
}
int a = fibo(n - 1);
int b = fibo(n - 2);
return a + b;
}
int main() {
int result = fibo(40);
printf("%d\n", result);
puts("done");
return 0;
}
#include <typon/typon.hpp>
#include <cstdio>
using namespace typon;
Join<int> fibo(int n) {
if (n < 2) {
co_return n;
}
Forked a = co_await fork(fibo(n - 1));
Forked b = co_await fork(fibo(n - 2));
co_await Sync();
co_return a.get() + b.get();
}
Root root() {
int result = co_await fibo(40);
printf("%d\n", result);
}
int main() {
root().call();
puts("done");
return 0;
}
#include <typon/typon.hpp>
#include <cstdio>
using namespace typon;
Task<int> fibo(int n) {
if (n < 2) {
co_return n;
}
Future a = co_await future(fibo(n - 1));
Future b = co_await future(fibo(n - 2));
co_return co_await a.get() + co_await b.get();
}
Root root() {
int result = co_await fibo(40);
printf("%d\n", result);
}
int main() {
root().call();
puts("done");
return 0;
}
#include <typon/task.hpp>
#include <cstdio>
using namespace typon;
template <typename T>
Task<typename T::promise_type::value_type> call(T task)
{
co_return co_await std::move(task);
}
Task<int> fibo(int n) {
if (n < 2) {
co_return n;
}
int a = co_await call(fibo(n - 1));
int b = co_await call(fibo(n - 2));
co_return a + b;
}
int main() {
int result = fibo(40).call();
printf("%d\n", result);
}
#include <typon/typon.hpp>
#include <cstdio>
using namespace typon;
Task<int> fibo(int n) {
if (n < 2) {
co_return n;
}
int a = co_await fibo(n - 1);
int b = co_await fibo(n - 2);
co_return a + b;
}
int main() {
int result = fibo(40).call();
printf("%d\n", result);
}
#include <typon/typon.hpp>
#include <cstdio>
using namespace typon;
int fibo(int n) {
if (n < 2)
return n;
return fibo(n - 1) + fibo(n - 2);
}
Task<void> consume(Promise<int> & f) {
printf("[%u] waiting on promise\n", Scheduler::thread_id);
int value = co_await f;
printf("[%u] promise yielded %d\n", Scheduler::thread_id, value);
}
Task<void> produce(Promise<int> & f, int n) {
int value = fibo(n);
printf("[%u] producing %d\n", Scheduler::thread_id, value);
f.put(value);
co_return;
}
Join<void> parallel() {
Promise<int> f;
printf("[%u] fork(consume())\n", Scheduler::thread_id);
co_await fork(consume(f));
printf("[%u] fork(produce())\n", Scheduler::thread_id);
co_await fork(produce(f, 20));
}
Root root() {
co_await parallel();
}
int main() {
root().call();
puts("done");
return 0;
}
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <random>
#include <vector>
using u32 = std::uint_fast32_t;
u32 N = u32(1) << 26;
int main() {
std::vector<u32> v;
v.reserve(N);
for (u32 i = 0; i < N; i++) {
v.push_back(i);
}
std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});
printf("v[0] = %lu\n", v[0]);
puts("done");
}
#include <typon/typon.hpp>
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <random>
#include <vector>
using namespace typon;
long N = 1 << 26;
long C = N >> 8;
template <typename RandomIt>
Task<void> shuffle(RandomIt first, RandomIt last)
{
std::shuffle(first, last, std::mt19937{std::random_device{}()});
co_return;
}
template <typename RandomIt>
Join<void> parallel_shuffle(RandomIt first, RandomIt last)
{
auto it = first;
for (; it < last; it += C) {
co_await fork(shuffle(it, it + C));
}
if (it < last)
{
co_await fork(shuffle(it, last));
}
}
Root root() {
std::vector<long> v;
v.reserve(N);
for (long i = 0; i < N; i++) {
v.push_back(i);
}
co_await parallel_shuffle(v.begin(), v.end());
printf("v[0] = %lu\n", v[0]);
}
int main() {
root().call();
puts("done");
}
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <random>
#include <vector>
using u64 = std::uint_fast64_t;
u64 N = u64(1) << 26;
int R = 100;
u64 sum(u64 * array, u64 size)
{
u64 s = 0;
for (u64 i = 0; i < size; i++) {
s += array[i];
}
return s;
}
int main() {
std::vector<u64> v;
v.reserve(N);
for (u64 i = 0; i < N; i++) {
v.push_back(i);
}
u64 result = 0;
for (int i = 0; i < R; i++) {
result += sum(v.data(), v.size());
}
printf("sum = %lu\n", result);
puts("done");
}
#include <typon/typon.hpp>
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <random>
#include <vector>
using namespace typon;
using u64 = std::uint_fast64_t;
u64 N = u64(1) << 26;
int C = 256;
int R = 100;
Task<u64> sum(u64 * array, u64 size)
{
u64 s = 0;
for (u64 i = 0; i < size; i++) {
s += array[i];
}
co_return s;
}
Join<u64> parallel_sum(u64 * array, u64 size)
{
std::vector<Forked<u64>> v;
v.reserve(C - 1);
u64 start = 0;
u64 chunk = size / C;
for (int i = 0; i < C - 1; i++) {
v.push_back(co_await fork(sum(&(array[start]), chunk)));
start = start + chunk;
}
u64 s = co_await sum(&(array[start]), size - start);
co_await Sync();
for (auto & f : v) {
s += f.get();
}
co_return s;
}
Root root() {
std::vector<u64> v;
v.reserve(N);
for (u64 i = 0; i < N; i++) {
v.push_back(i);
}
u64 result = 0;
for (int i = 0; i < R; i++) {
result += co_await parallel_sum(v.data(), v.size());
}
printf("sum = %lu\n", result);
}
int main() {
root().call();
puts("done");
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment