diff options
| author | tylov <[email protected]> | 2023-07-21 00:37:28 +0200 |
|---|---|---|
| committer | tylov <[email protected]> | 2023-07-21 00:37:28 +0200 |
| commit | 2d67f4040f6eecd41f1b864b43c62823ed75aff0 (patch) | |
| tree | 084ce603dc4edfa1ccad3aabab5b671a817bc67e | |
| parent | 900295256d825fc323149cd223c49787f32a3696 (diff) | |
| download | STC-modified-2d67f4040f6eecd41f1b864b43c62823ed75aff0.tar.gz STC-modified-2d67f4040f6eecd41f1b864b43c62823ed75aff0.zip | |
Renamed badly abbreviated names in crand.h.
Moved coroutine.h from algo subfolder to stc.
Updated coroutine.h and docs.
26 files changed, 172 insertions, 125 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 1e1ae1aa..9189d7e8 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -392,8 +392,7 @@ cco_routine scope; Use `if-else-if` constructs instead. | | `cco_return;` | Return from coroutine (inside cco_routine) | | | Task objects: | | | | `cco_task_struct(Name, ...);` | Define a coroutine task struct | -| | `cco_await_task(task, ...);` | Await for task to finish or optionally yield a value | -| | `cco_block_task(task);` | Run blocking until task is finished (stackless) | +| | `cco_task_await(task, ...);` | Await for task to finish or optionally yield a value | | | Semaphores: | | | | `cco_sem` | Semaphore type | | `cco_sem` | `cco_sem_from(long value)` | Create semaphore | @@ -414,7 +413,9 @@ cco_routine scope; Use `if-else-if` constructs instead. | `void` | `cco_stop(co)` | Next call of coroutine finalizes | | `void` | `cco_reset(co)` | Reset state to initial (for reuse) | | `void` | `cco_block_on(cocall) { }` | Run blocking until cocall is finished | -| `void` | `cco_block_on(cocall, int *result) { }`| Run blocking until cocall is finished | +| `void` | `cco_block_on(cocall, int *result) {}`| Run blocking until cocall is finished | +| | `cco_task_block_on(task) {}` | Run blocking until task is finished | +| | `cco_task_block_on(task, rt, STACKSZ) {}`| Run blocking until task is finished | | | Time functions: | | | `double` | `cco_time(void)` | Return secs with usec prec. since Epoch | | | `cco_sleep(double sec)` | Sleep for seconds (msec or usec prec.) | diff --git a/docs/cpque_api.md b/docs/cpque_api.md index 4cde927b..247424b4 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -72,14 +72,14 @@ int main(void) { intptr_t N = 10000000; crand_t rng = crand_init(1234); - crand_unif_t dist = crand_unif_init(0, N * 10); + crand_uniform_t dist = crand_uniform_init(0, N * 10); // Define heap cpque_i heap = {0}; // Push ten million random numbers to priority queue. c_forrange (N) - cpque_i_push(&heap, crand_unif(&rng, &dist)); + cpque_i_push(&heap, crand_uniform(&rng, &dist)); // Add some negative ones. int nums[] = {-231, -32, -873, -4, -343}; diff --git a/docs/crandom_api.md b/docs/crandom_api.md index 22a4f4dd..88924784 100644 --- a/docs/crandom_api.md +++ b/docs/crandom_api.md @@ -1,30 +1,29 @@ # STC [crand](../include/stc/crand.h): Pseudo Random Number Generator  -This features a *64-bit PRNG* named **stc64**, and can generate bounded uniform and normal +This features a *64-bit PRNG* named **crand64**, and can generate bounded uniform and normal distributed random numbers. See [random](https://en.cppreference.com/w/cpp/header/random) for similar c++ functionality. ## Description -**stc64** is a novel, extremely fast PRNG by Tyge Løvset, suited for parallel usage. It features -Weyl-sequences as part of its state. It is inspired on *sfc64*, but has a different output function +**crand64** is a novel, very fast PRNG, suited for parallel usage. It features a +Weyl-sequence as part of its state. It is based on *sfc64*, but has a different output function and state size. -**sfc64** is the fastest among *pcg*, *xoshiro`**`*, and *lehmer*. It is equally fast as *sfc64* on -most platforms. *wyrand* is faster on platforms with fast 128-bit multiplication, and has 2^64 period -length (https://github.com/lemire/SwiftWyhash/issues/10). However, *wyrand* is not suited for massive -parallel usage due to its limited total minimal period length. +**sfc64** is the fastest among *pcg*, *xoshiro`**`*, and *lehmer*. It is equally fast or faster than +*sfc64* on most platforms. *wyrand* is faster on platforms with fast 128-bit multiplication, and has +2^64 period (https://github.com/lemire/SwiftWyhash/issues/10). *wyrand* is not suited for massive +parallel usage due to its limited minimal period. -**stc64** does not require multiplication or 128-bit integer operations. It has 320 bit state, -but updates only 256 bit per generated number. +**crand64** does not require multiplication or 128-bit integer operations. It has 320 bit state, +where 64-bits are constant per prng instance created. There is no *jump function*, but each odd number Weyl-increment (state[4]) starts a new -unique 2^64 *minimum* length period. For a single thread, a minimum period of 2^127 is generated -when the Weyl-increment is incremented by 2 every 2^64 output. +unique 2^64 *minimum* length period, i.e. virtually unlimitied number of unique threads. -**stc64** passes *PractRand* (tested up to 8TB output), Vigna's Hamming weight test, and simple +**crand64** passes *PractRand* (tested up to 8TB output), Vigna's Hamming weight test, and simple correlation tests, i.e. *n* interleaved streams with only one-bit differences in initial state. Also 32-bit and 16-bit versions passes PractRand up to their size limits. @@ -41,27 +40,27 @@ All crand definitions and prototypes are available by including a single header ## Methods ```c -void csrand(uint64_t seed); // seed global stc64 prng +void csrand(uint64_t seed); // seed global crand64 prng uint64_t crand(void); // global crand_u64(rng) double crandf(void); // global crand_f64(rng) -crand_t crand_init(uint64_t seed); // stc64_init(s) is deprecated +crand_t crand_init(uint64_t seed); uint64_t crand_u64(crand_t* rng); // range [0, 2^64 - 1] double crand_f64(crand_t* rng); // range [0.0, 1.0) -crand_unif_t crand_unif_init(int64_t low, int64_t high); // uniform-distribution -int64_t crand_unif(crand_t* rng, crand_unif_t* dist); // range [low, high] +crand_uniform_t crand_uniform_init(int64_t low, int64_t high); // uniform-distribution range +int64_t crand_uniform(crand_t* rng, crand_uniform_t* dist); -crand_norm_t crand_norm_init(double mean, double stddev); // normal-distribution -double crand_norm(crand_t* rng, crand_norm_t* dist); +crand_normal_t crand_normal_init(double mean, double stddev); // normal-gauss distribution +double crand_normal(crand_t* rng, crand_normal_t* dist); ``` ## Types | Name | Type definition | Used to represent... | |:-------------------|:------------------------------------------|:-----------------------------| | `crand_t` | `struct {uint64_t state[4];}` | The PRNG engine type | -| `crand_unif_t` | `struct {int64_t lower; uint64_t range;}` | Integer uniform distribution | -| `crand_norm_t` | `struct {double mean, stddev;}` | Normal distribution type | +| `crand_uniform_t` | `struct {int64_t lower; uint64_t range;}` | Integer uniform distribution | +| `crand_normal_t` | `struct {double mean, stddev;}` | Normal distribution type | ## Example ```c @@ -86,17 +85,17 @@ int main(void) // Setup random engine with normal distribution. uint64_t seed = time(NULL); crand_t rng = crand_init(seed); - crand_norm_t dist = crand_norm_init(Mean, StdDev); + crand_normal_t dist = crand_normal_init(Mean, StdDev); // Create histogram map - csmap_i mhist = csmap_i_init(); + csmap_i mhist = {0}; c_forrange (N) { - int index = (int)round(crand_norm(&rng, &dist)); + int index = (int)round(crand_normal(&rng, &dist)); csmap_i_emplace(&mhist, index, 0).ref->second += 1; } // Print the gaussian bar chart - cstr bar = cstr_init(); + cstr bar = {0}; c_foreach (i, csmap_i, mhist) { int n = (int)(i.ref->second * StdDev * Scale * 2.5 / N); if (n > 0) { diff --git a/include/stc/calgo.h b/include/stc/algorithm.h index 63ef97b9..cf3ab328 100644 --- a/include/stc/calgo.h +++ b/include/stc/algorithm.h @@ -4,6 +4,5 @@ #include "algo/raii.h" #include "algo/crange.h" #include "algo/filter.h" -#include "algo/coroutine.h" #endif diff --git a/include/stc/algo/coroutine.h b/include/stc/coroutine.h index 7c6989c3..f89d20af 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/coroutine.h @@ -24,7 +24,7 @@ #define STC_COROUTINE_INCLUDED /* #include <stdio.h> -#include <stc/algo/coroutine.h> +#include <stc/coroutine.h> struct iterpair { int max_x, max_y; @@ -56,7 +56,7 @@ int main(void) { return 0; } */ -#include "../ccommon.h" +#include "ccommon.h" enum { CCO_STATE_CLEANUP = -1, @@ -73,7 +73,7 @@ typedef enum { #define cco_done(co) ((co)->cco_state == CCO_STATE_DONE) #define cco_routine(co) \ - for (int *_state = &(co)->cco_state; *_state != CCO_STATE_DONE; *_state = CCO_STATE_DONE) \ + for (int* _state = &(co)->cco_state; *_state != CCO_STATE_DONE; *_state = CCO_STATE_DONE) \ _resume: switch (*_state) case 0: // thanks, @liigo! #define cco_yield() cco_yield_v(CCO_YIELD) @@ -138,7 +138,7 @@ struct cco_runtime; #define cco_task_struct(Name, ...) \ struct Name { \ - int (*cco_fn)(struct Name*, struct cco_runtime*); \ + int (*cco_func)(struct Name*, struct cco_runtime*); \ int cco_state, cco_expect; \ __VA_ARGS__ \ } @@ -146,31 +146,30 @@ struct cco_runtime; typedef cco_task_struct(cco_task, /**/) cco_task; typedef struct cco_runtime { - int result, top; - cco_task* stack[]; + int result, top; cco_task* stack[]; } cco_runtime; #define cco_cast_task(task) \ - ((cco_task *)(task) + 0*sizeof((task)->cco_fn(task, (cco_runtime*)0) + ((int*)0 == &(task)->cco_state))) + ((cco_task *)(task) + 0*sizeof((task)->cco_func(task, (cco_runtime*)0) + ((int*)0 == &(task)->cco_state))) #define cco_resume(task, rt) \ - (task)->cco_fn(task, rt) + (task)->cco_func(task, rt) -#define cco_block_task(...) c_MACRO_OVERLOAD(cco_block_task, __VA_ARGS__) -#define cco_block_task_1(task) cco_block_task_3(task, rt, 16) -#define cco_block_task_3(task, rt, STACKDEPTH) \ - for (struct { int result, top; cco_task* stack[STACKDEPTH]; } rt = {.stack={cco_cast_task(task)}}; \ - (((rt.result = cco_resume(rt.stack[rt.top], (cco_runtime*)&rt)) & rt.stack[rt.top]->cco_expect) || --rt.top >= 0); ) - -#define cco_await_task(...) c_MACRO_OVERLOAD(cco_await_task, __VA_ARGS__) -#define cco_await_task_2(task, rt) cco_await_task_3(task, rt, CCO_DONE) -#define cco_await_task_3(task, rt, resultbits) \ +#define cco_task_await(...) c_MACRO_OVERLOAD(cco_task_await, __VA_ARGS__) +#define cco_task_await_2(task, rt) cco_task_await_3(task, rt, CCO_DONE) +#define cco_task_await_3(task, rt, resultbits) \ do { \ cco_runtime* _rt = rt; \ - (_rt->stack[++_rt->top] = cco_cast_task(task))->cco_expect = ~(resultbits); \ + (_rt->stack[++_rt->top] = cco_cast_task(task))->cco_expect = (resultbits); \ cco_yield_v(CCO_AWAIT); \ } while (0) +#define cco_task_block_on(...) c_MACRO_OVERLOAD(cco_task_block_on, __VA_ARGS__) +#define cco_task_block_on_1(task) cco_task_block_on_3(task, _rt, 16) +#define cco_task_block_on_3(task, rt, STACKDEPTH) \ + for (struct { int result, top; cco_task* stack[STACKDEPTH]; } rt = {.stack={cco_cast_task(task)}}; \ + (((rt.result = cco_resume(rt.stack[rt.top], (cco_runtime*)&rt)) & ~rt.stack[rt.top]->cco_expect) || --rt.top >= 0); ) + /* * Semaphore */ diff --git a/include/stc/crand.h b/include/stc/crand.h index 0a6aa9e0..32722762 100644 --- a/include/stc/crand.h +++ b/include/stc/crand.h @@ -32,20 +32,20 @@ int main(void) { uint64_t seed = 123456789; crand_t rng = crand_init(seed); - crand_unif_t dist1 = crand_unif_init(1, 6); - crand_norm_t dist3 = crand_norm_init(1.0, 10.0); + crand_uniform_t dist1 = crand_uniform_init(1, 6); + crand_normal_t dist3 = crand_normal_init(1.0, 10.0); uint64_t i = crand_u64(&rng); - int64_t iu = crand_unif(&rng, &dist1); - double xn = crand_norm(&rng, &dist3); + int64_t iu = crand_uniform(&rng, &dist1); + double xn = crand_normal(&rng, &dist3); } */ #include <string.h> #include <math.h> typedef struct crand { uint64_t state[5]; } crand_t; -typedef struct crand_unif { int64_t lower; uint64_t range, threshold; } crand_unif_t; -typedef struct crand_norm { double mean, stddev, next; int has_next; } crand_norm_t; +typedef struct crand_uniform { int64_t lower; uint64_t range, threshold; } crand_uniform_t; +typedef struct crand_normal { double mean, stddev, next; int has_next; } crand_normal_t; /* PRNG crand_t. * Very fast PRNG suited for parallel usage with Weyl-sequence parameter. @@ -67,14 +67,14 @@ STC_API double crandf(void); STC_API crand_t crand_init(uint64_t seed); /* Unbiased bounded uniform distribution. range [low, high] */ -STC_API crand_unif_t crand_unif_init(int64_t low, int64_t high); -STC_API int64_t crand_unif(crand_t* rng, crand_unif_t* dist); +STC_API crand_uniform_t crand_uniform_init(int64_t low, int64_t high); +STC_API int64_t crand_uniform(crand_t* rng, crand_uniform_t* dist); /* Normal/gaussian distribution. */ -STC_INLINE crand_norm_t crand_norm_init(double mean, double stddev) - { crand_norm_t r = {mean, stddev, 0.0, 0}; return r; } +STC_INLINE crand_normal_t crand_normal_init(double mean, double stddev) + { crand_normal_t r = {mean, stddev, 0.0, 0}; return r; } -STC_API double crand_norm(crand_t* rng, crand_norm_t* dist); +STC_API double crand_normal(crand_t* rng, crand_normal_t* dist); /* Main crand_t prng */ STC_INLINE uint64_t crand_u64(crand_t* rng) { @@ -95,11 +95,10 @@ STC_INLINE double crand_f64(crand_t* rng) { /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) || defined(i_static) -/* Global random() */ -static crand_t crand_global = {{ - 0x26aa069ea2fb1a4d, 0x70c72c95cd592d04, - 0x504f333d3aa0b359, 0x9e3779b97f4a7c15, - 0x6a09e667a754166b +/* Global random seed */ +static crand_t crand_global = {{ // csrand(0) + 0x9e3779b97f4a7c15, 0x6f68261b57e7a770, + 0xe220a838bf5c9dde, 0x7c17d1800457b1ba, 0x1, }}; STC_DEF void csrand(uint64_t seed) @@ -116,20 +115,20 @@ STC_DEF crand_t crand_init(uint64_t seed) { s[0] = seed + 0x9e3779b97f4a7c15; s[1] = (s[0] ^ (s[0] >> 30))*0xbf58476d1ce4e5b9; s[2] = (s[1] ^ (s[1] >> 27))*0x94d049bb133111eb; - s[3] = (s[2] ^ (s[2] >> 31)); - s[4] = ((seed + 0x6aa069ea2fb1a4d) << 1) | 1; + s[3] = s[0] ^ s[2] ^ (s[2] >> 31); + s[4] = (seed << 1) | 1; return rng; } /* Init unbiased uniform uint RNG with bounds [low, high] */ -STC_DEF crand_unif_t crand_unif_init(int64_t low, int64_t high) { - crand_unif_t dist = {low, (uint64_t) (high - low + 1)}; +STC_DEF crand_uniform_t crand_uniform_init(int64_t low, int64_t high) { + crand_uniform_t dist = {low, (uint64_t) (high - low + 1)}; dist.threshold = (uint64_t)(0 - dist.range) % dist.range; return dist; } /* Int64 uniform distributed RNG, range [low, high]. */ -STC_DEF int64_t crand_unif(crand_t* rng, crand_unif_t* d) { +STC_DEF int64_t crand_uniform(crand_t* rng, crand_uniform_t* d) { uint64_t lo, hi; #ifdef c_umul128 do { c_umul128(crand_u64(rng), d->range, &lo, &hi); } while (lo < d->threshold); @@ -140,7 +139,7 @@ STC_DEF int64_t crand_unif(crand_t* rng, crand_unif_t* d) { } /* Normal distribution PRNG. Marsaglia polar method */ -STC_DEF double crand_norm(crand_t* rng, crand_norm_t* dist) { +STC_DEF double crand_normal(crand_t* rng, crand_normal_t* dist) { double u1, u2, s, m; if (dist->has_next++ & 1) return dist->next*dist->stddev + dist->mean; diff --git a/misc/examples/algorithms/forfilter.c b/misc/examples/algorithms/forfilter.c index f3c008b3..644b8459 100644 --- a/misc/examples/algorithms/forfilter.c +++ b/misc/examples/algorithms/forfilter.c @@ -3,8 +3,7 @@ #include <stc/cstr.h> #define i_implement #include <stc/csview.h> -#include <stc/algo/filter.h> -#include <stc/algo/crange.h> +#include <stc/algorithm.h> #define i_type IVec #define i_key int diff --git a/misc/examples/algorithms/forloops.c b/misc/examples/algorithms/forloops.c index 72d745f8..300eee18 100644 --- a/misc/examples/algorithms/forloops.c +++ b/misc/examples/algorithms/forloops.c @@ -1,5 +1,5 @@ #include <stdio.h> -#include <stc/algo/filter.h> +#include <stc/algorithm.h> #define i_type IVec #define i_key int diff --git a/misc/examples/algorithms/random.c b/misc/examples/algorithms/random.c index b7c0f277..ccd0711d 100644 --- a/misc/examples/algorithms/random.c +++ b/misc/examples/algorithms/random.c @@ -4,11 +4,11 @@ int main(void) { - const int N = 1000000000; + long long N = 1000000000; const uint64_t seed = (uint64_t)time(NULL), range = 1000000; crand_t rng = crand_init(seed); - int64_t sum; + long long sum; clock_t diff, before; printf("Compare speed of full and unbiased ranged random numbers...\n"); @@ -18,19 +18,19 @@ int main(void) sum += (uint32_t)crand_u64(&rng); } diff = clock() - before; - printf("full range\t\t: %f secs, %d, avg: %f\n", - (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); + printf("full range\t\t: %f secs, %lld, avg: %f\n", + (double)diff/CLOCKS_PER_SEC, N, (double)(sum/N)); - crand_unif_t dist1 = crand_unif_init(0, range); + crand_uniform_t dist1 = crand_uniform_init(0, range); rng = crand_init(seed); sum = 0; before = clock(); c_forrange (N) { - sum += crand_unif(&rng, &dist1); // unbiased + sum += crand_uniform(&rng, &dist1); // unbiased } diff = clock() - before; - printf("unbiased 0-%" PRIu64 "\t: %f secs, %d, avg: %f\n", - range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); + printf("unbiased 0-%" PRIu64 "\t: %f secs, %lld, avg: %f\n", + range, (double)diff/CLOCKS_PER_SEC, N, (double)(sum/N)); sum = 0; rng = crand_init(seed); @@ -39,7 +39,7 @@ int main(void) sum += (int64_t)(crand_u64(&rng) % (range + 1)); // biased } diff = clock() - before; - printf("biased 0-%" PRIu64 " \t: %f secs, %d, avg: %f\n", - range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); + printf("biased 0-%" PRIu64 " \t: %f secs, %lld, avg: %f\n", + range, (double)diff/CLOCKS_PER_SEC, N, (double)(sum/N)); } diff --git a/misc/examples/bitsets/prime.c b/misc/examples/bitsets/prime.c index cb3b095a..e5764d83 100644 --- a/misc/examples/bitsets/prime.c +++ b/misc/examples/bitsets/prime.c @@ -2,23 +2,23 @@ #include <math.h> #include <time.h> #include <stc/cbits.h> -#include <stc/algo/filter.h> -#include <stc/algo/crange.h> +#include <stc/algorithm.h> +typedef long long llong; -cbits sieveOfEratosthenes(int64_t n) +cbits sieveOfEratosthenes(llong n) { cbits bits = cbits_with_size(n/2 + 1, true); - int64_t q = (int64_t)sqrt((double) n) + 1; - for (int64_t i = 3; i < q; i += 2) { - int64_t j = i; + llong q = (llong)sqrt((double) n) + 1; + for (llong i = 3; i < q; i += 2) { + llong j = i; for (; j < n; j += 2) { if (cbits_test(&bits, j>>1)) { i = j; break; } } - for (int64_t j = i*i; j < n; j += i*2) + for (llong j = i*i; j < n; j += i*2) cbits_reset(&bits, j>>1); } return bits; @@ -26,12 +26,12 @@ cbits sieveOfEratosthenes(int64_t n) int main(void) { - int n = 1000000000; - printf("Computing prime numbers up to %d\n", n); + llong n = 100000000; + printf("Computing prime numbers up to %lld\n", n); clock_t t = clock(); cbits primes = sieveOfEratosthenes(n + 1); - int np = (int)cbits_count(&primes); + llong np = cbits_count(&primes); t = clock() - t; puts("Show all the primes in the range [2, 1000):"); @@ -50,7 +50,7 @@ int main(void) printf("%lld ", *i.ref); if (c_flt_getcount(i) % 10 == 0) puts(""); } - printf("Number of primes: %d, time: %.2f\n\n", np, (double)t/CLOCKS_PER_SEC); + printf("Number of primes: %lld, time: %.2f\n\n", np, (double)t/CLOCKS_PER_SEC); cbits_drop(&primes); } diff --git a/misc/examples/coroutines/cointerleave.c b/misc/examples/coroutines/cointerleave.c index 599ceaab..ea0d4dac 100644 --- a/misc/examples/coroutines/cointerleave.c +++ b/misc/examples/coroutines/cointerleave.c @@ -1,6 +1,6 @@ // https://www.youtube.com/watch?v=8sEe-4tig_A #include <stdio.h> -#include <stc/calgo.h> +#include <stc/coroutine.h> #define i_type IVec #define i_key int #include <stc/cvec.h> diff --git a/misc/examples/coroutines/coread.c b/misc/examples/coroutines/coread.c index a13f6be5..56248108 100644 --- a/misc/examples/coroutines/coread.c +++ b/misc/examples/coroutines/coread.c @@ -1,6 +1,6 @@ #define i_implement #include <stc/cstr.h> -#include <stc/algo/coroutine.h> +#include <stc/coroutine.h> #include <errno.h> // Read file line by line using coroutines: diff --git a/misc/examples/coroutines/coroutines.c b/misc/examples/coroutines/coroutines.c index b8dfaa13..de0fcda5 100644 --- a/misc/examples/coroutines/coroutines.c +++ b/misc/examples/coroutines/coroutines.c @@ -1,4 +1,4 @@ -#include <stc/algo/coroutine.h> +#include <stc/coroutine.h> #include <stdio.h> #include <stdint.h> diff --git a/misc/examples/coroutines/cotasks1.c b/misc/examples/coroutines/cotasks1.c index c87582f1..27999ccf 100644 --- a/misc/examples/coroutines/cotasks1.c +++ b/misc/examples/coroutines/cotasks1.c @@ -4,7 +4,7 @@ #include <stdio.h> #define i_static #include <stc/cstr.h> -#include <stc/algo/coroutine.h> +#include <stc/coroutine.h> struct next_value { int val; diff --git a/misc/examples/coroutines/cotasks2.c b/misc/examples/coroutines/cotasks2.c index 293583bc..9ca69bda 100644 --- a/misc/examples/coroutines/cotasks2.c +++ b/misc/examples/coroutines/cotasks2.c @@ -4,7 +4,7 @@ #include <stdio.h> #define i_static #include <stc/cstr.h> -#include <stc/algo/coroutine.h> +#include <stc/coroutine.h> cco_task_struct (next_value, int val; @@ -45,7 +45,7 @@ int produce_items(struct produce_items* p, cco_runtime* rt) while (true) { // await for next CCO_YIELD in next_value() - cco_await_task(&p->next, rt, CCO_YIELD); + cco_task_await(&p->next, rt, CCO_YIELD); cstr_printf(&p->str, "item %d", p->next.val); print_time(); printf("produced %s\n", cstr_str(&p->str)); @@ -71,7 +71,7 @@ int consume_items(struct consume_items* c, cco_runtime* rt) for (c->i = 1; c->i <= c->n; ++c->i) { printf("consume #%d\n", c->i); - cco_await_task(&c->produce, rt, CCO_YIELD); + cco_task_await(&c->produce, rt, CCO_YIELD); print_time(); printf("consumed %s\n", cstr_str(&c->produce.str)); } @@ -87,12 +87,12 @@ int main(void) { struct consume_items consume = { .n=5, - .cco_fn=consume_items, - .produce={.cco_fn=produce_items, .next={.cco_fn=next_value}}, + .cco_func=consume_items, + .produce={.cco_func=produce_items, .next={.cco_func=next_value}}, }; int count = 0; - cco_block_task(&consume) + cco_task_block_on(&consume) { ++count; //cco_sleep(0.001); diff --git a/misc/examples/coroutines/dining_philosophers.c b/misc/examples/coroutines/dining_philosophers.c index a5063a42..abe09204 100644 --- a/misc/examples/coroutines/dining_philosophers.c +++ b/misc/examples/coroutines/dining_philosophers.c @@ -2,7 +2,7 @@ #include <stdio.h> #include <time.h> #include <stc/crand.h> -#include <stc/algo/coroutine.h> +#include <stc/coroutine.h> // Define the number of philosophers and forks enum { diff --git a/misc/examples/coroutines/generator.c b/misc/examples/coroutines/generator.c index a15f9ba5..f9e59fea 100644 --- a/misc/examples/coroutines/generator.c +++ b/misc/examples/coroutines/generator.c @@ -1,7 +1,7 @@ // https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ -#include <stc/algo/coroutine.h> #include <stdio.h> +#include <stc/coroutine.h> typedef struct { int size; diff --git a/misc/examples/coroutines/scheduler.c b/misc/examples/coroutines/scheduler.c index 38defd0f..78461277 100644 --- a/misc/examples/coroutines/scheduler.c +++ b/misc/examples/coroutines/scheduler.c @@ -1,6 +1,6 @@ // https://www.youtube.com/watch?v=8sEe-4tig_A #include <stdio.h> -#include <stc/calgo.h> +#include <stc/coroutine.h> struct Task { int (*fn)(struct Task*); diff --git a/misc/examples/coroutines/triples.c b/misc/examples/coroutines/triples.c index 9f2fcc1e..fe1ca7c3 100644 --- a/misc/examples/coroutines/triples.c +++ b/misc/examples/coroutines/triples.c @@ -1,7 +1,7 @@ // https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ -#include <stc/algo/coroutine.h> #include <stdio.h> +#include <stc/coroutine.h> int gcd(int a, int b) { while (b) { diff --git a/misc/examples/linkedlists/list.c b/misc/examples/linkedlists/list.c index ad8bebb8..09591314 100644 --- a/misc/examples/linkedlists/list.c +++ b/misc/examples/linkedlists/list.c @@ -1,6 +1,6 @@ #include <stdio.h> #include <time.h> -#include <stc/algo/filter.h> +#include <stc/algorithm.h> #include <stc/crand.h> #define i_type DList diff --git a/misc/examples/make.sh b/misc/examples/make.sh index 7135ffdf..b362f275 100755 --- a/misc/examples/make.sh +++ b/misc/examples/make.sh @@ -38,8 +38,8 @@ fi if [ $run = 0 ] ; then for i in */*.c ; do - #out=$(basename $i .c).exe - out=$(dirname $i)/$(basename $i .c).exe + out=$(basename $i .c).exe + #out=$(dirname $i)/$(basename $i .c).exe echo $comp -I../../include $i $clibs $oflag$out $comp -I../../include $i $clibs $oflag$out done @@ -47,8 +47,8 @@ else for i in */*.c ; do echo $comp -I../../include $i $clibs $comp -I../../include $i $clibs - #out=$(basename $i .c).exe - out=$(dirname $i)/$(basename $i .c).exe + out=$(basename $i .c).exe + #out=$(dirname $i)/$(basename $i .c).exe if [ -f $out ]; then ./$out; fi done fi diff --git a/misc/examples/priorityqueues/priority.c b/misc/examples/priorityqueues/priority.c index bf2e188a..18684e73 100644 --- a/misc/examples/priorityqueues/priority.c +++ b/misc/examples/priorityqueues/priority.c @@ -11,21 +11,21 @@ int main(void) { intptr_t N = 10000000; crand_t rng = crand_init((uint64_t)time(NULL)); - crand_unif_t dist = crand_unif_init(0, N * 10); + crand_uniform_t dist = crand_uniform_init(0, N * 10); cpque_i heap = {0}; // Push ten million random numbers to priority queue printf("Push %" c_ZI " numbers\n", N); c_forrange (N) - cpque_i_push(&heap, crand_unif(&rng, &dist)); + cpque_i_push(&heap, crand_uniform(&rng, &dist)); // push some negative numbers too. c_forlist (i, int, {-231, -32, -873, -4, -343}) cpque_i_push(&heap, *i.ref); c_forrange (N) - cpque_i_push(&heap, crand_unif(&rng, &dist)); + cpque_i_push(&heap, crand_uniform(&rng, &dist)); puts("Extract the hundred smallest."); c_forrange (100) { diff --git a/misc/examples/queues/new_queue.c b/misc/examples/queues/new_queue.c index f3592df6..3904c50c 100644 --- a/misc/examples/queues/new_queue.c +++ b/misc/examples/queues/new_queue.c @@ -23,19 +23,19 @@ int point_cmp(const Point* a, const Point* b) { int main(void) { int n = 50000000; crand_t rng = crand_init((uint64_t)time(NULL)); - crand_unif_t dist = crand_unif_init(0, n); + crand_uniform_t dist = crand_uniform_init(0, n); IQ Q = {0}; // Push 50'000'000 random numbers onto the queue. c_forrange (n) - IQ_push(&Q, (int)crand_unif(&rng, &dist)); + IQ_push(&Q, (int)crand_uniform(&rng, &dist)); // Push or pop on the queue 50 million times printf("befor: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); c_forrange (n) { - int r = (int)crand_unif(&rng, &dist); + int r = (int)crand_uniform(&rng, &dist); if (r & 3) IQ_push(&Q, r); else diff --git a/misc/examples/queues/queue.c b/misc/examples/queues/queue.c index 56b5beb9..913524cc 100644 --- a/misc/examples/queues/queue.c +++ b/misc/examples/queues/queue.c @@ -7,20 +7,20 @@ int main(void) { int n = 100000000; - crand_unif_t dist; + crand_uniform_t dist; crand_t rng = crand_init(1234); - dist = crand_unif_init(0, n); + dist = crand_uniform_init(0, n); cqueue_i queue = {0}; // Push ten million random numbers onto the queue. c_forrange (n) - cqueue_i_push(&queue, (int)crand_unif(&rng, &dist)); + cqueue_i_push(&queue, (int)crand_uniform(&rng, &dist)); // Push or pop on the queue ten million times printf("%d\n", n); c_forrange (n) { // forrange uses initial n only. - int r = (int)crand_unif(&rng, &dist); + int r = (int)crand_uniform(&rng, &dist); if (r & 1) ++n, cqueue_i_push(&queue, r); else diff --git a/misc/examples/sortedmaps/gauss2.c b/misc/examples/sortedmaps/gauss2.c index 1ab8ade5..02ce4bc5 100644 --- a/misc/examples/sortedmaps/gauss2.c +++ b/misc/examples/sortedmaps/gauss2.c @@ -21,14 +21,14 @@ int main(void) printf("Mean %f, StdDev %f\n", Mean, StdDev); // Setup random engine with normal distribution. - crand_norm_t dist = crand_norm_init(Mean, StdDev); + crand_normal_t dist = crand_normal_init(Mean, StdDev); // Create and init histogram map with defered destruct csmap_int hist = {0}; cstr bar = {0}; c_forrange (N) { - int index = (int)round(crand_norm(&rng, &dist)); + int index = (int)round(crand_normal(&rng, &dist)); csmap_int_insert(&hist, index, 0).ref->second += 1; } diff --git a/misc/examples/spans/mdspan.c b/misc/examples/spans/mdspan.c new file mode 100644 index 00000000..4427299c --- /dev/null +++ b/misc/examples/spans/mdspan.c @@ -0,0 +1,51 @@ +#include <stdio.h> +#include <stc/cspan.h> +#include <stdlib.h> + +using_cspan3(DSpan, double); + +int main(void) { + const int nx=5, ny=4, nz=3; + double* data = c_new_n(double, nx*ny*nz); + + printf("\nMultidim span ms[5, 4, 3], fortran ordered"); + DSpan3 ms = cspan_md_order('F', data, nx, ny, nz); // Fortran, not 'C' + + int idx = 0; + c_forrange (i, ms.shape[0]) + c_forrange (j, ms.shape[1]) + c_forrange (k, ms.shape[2]) + *cspan_at(&ms, i, j, k) = ++idx; + + cspan_transpose(&ms); + + printf(", transposed:\n\n"); + c_forrange (i, ms.shape[0]) { + c_forrange (j, ms.shape[1]) { + c_forrange (k, ms.shape[2]) + printf(" %3g", *cspan_at(&ms, i, j, k)); + puts(""); + } + puts(""); + } + + DSpan2 sub; + + puts("Slicing:"); + printf("\nms[0, :, :] "); + sub = cspan_slice(DSpan2, &ms, {0}, {c_ALL}, {c_ALL}); + c_foreach (i, DSpan2, sub) printf(" %g", *i.ref); + puts(""); + + printf("\nms[:, 0, :] "); + sub = cspan_slice(DSpan2, &ms, {c_ALL}, {0}, {c_ALL}); + c_foreach (i, DSpan2, sub) printf(" %g", *i.ref); + puts(""); + + sub = cspan_slice(DSpan2, &ms, {c_ALL}, {c_ALL}, {0}); + printf("\nms[:, :, 0] "); + c_foreach (i, DSpan2, sub) printf(" %g", *i.ref); + puts(""); + + free(data); +} |
