This is a proposal to add some new constructs to CIVL-C. The goals are to make it easier to translate from source languages/APIs to CIVL-C and to enable optimizations in the model checker and possibly other static analysis tools. == New types == * `$range` : an ordered set of integers * `$domain(n)` : an ordered set of n-tuples of integers; an "n-dimensional" domain. n is at least 1. * `$domain`: union over all n>=1 of `$domain(n)`. For each n, `$domain(n)` is a subtype of `$domain`. it is exactly the same as the array types in CIVL-C. == New functions dealing with the types above == {{{ // range consisting of lo, lo+step, lo+2*step, ... // the sequence stops just before the first number // greater than hi. $range $range_regular(int lo, int hi, int step); // domain which is the Cartesian products of the given ranges. // this is a var-args function; the number of arguments determines // the dimension of the domain returned. The order is dictionary // order. $domain $domain_rectangular($range r1, ...); // returns the dimension of the domain int $domain_get_dim($domain d); }}} == New expressions == Some new expressions will make it easy to create new ranges and domains using range and domain literals. The range literal {{{ lo..hi }}} where `lo` and `hi` are expressions of integer type, represents the same range as `$range_regular(lo, hi, 1)`. The range literal {{{ lo..hi#step }}} where all three identifiers signify expressions of integer type, represents the same range as `$range_regular(lo, hi, step)`. The domain literal {{{ { r1, r2, ...} }}} where `r1`, `r2`, ..., are all expressions of range type, represents the domain `$domain_rectangular(r1, r2, ...)`. == New statements == {{{ $for (i1, i2, ... : dom) S }}} `i1`, `i2`, ... are variables of integer type. These are called the "index variables". `dom` is an expression of type `$domain`. The number of index variables must equal the dimension of `dom`. `S` is a statement. Semantics: loop over all elements of the domain and execute S for each such element. In the form above, the index variables must have been previously declared; alternatively, they can be declared inside the statement: {{{ $for (int i1, i2, ... : dom) S }}} Next, a parallel version of above: {{{ $parfor (i1, i2, ... : dom) S }}} Similar to `$for`, but instead of executing sequentially, a process (thread) is instantiated for each element of the domain and they all execute concurrently. There is an implicit barrier at the end of S and all the processes are waited on. == Example 1: OpenMP parallel construct == {{{ #pragma omp parallel { ... } }}} => {{{ int nthreads = 1+$choose_int(THREADS_MAX); $range thread_range = $range_regular(0, nthreads-1, 1); $domain(1) thread_dom = $domain_rectangular(thread_range); $parfor (int tid : thread_dom) { ... } }}} == Example 2: CUDA 3d grid == {{{ __kernel__ grid() { ... } grid<<>>(); }}} => {{{ grid(int idx, int idy, int idz) { ... } $range grid_range_x = $range_regular(0, nx-1, 1); $range grid_range_y = $range_regular(0, ny-1, 1); $range grid_range_z = $range_regular(0, nz-1, 1); $domain(3) block_dom = $domain_rectangular(grid_range_x, grid_range_y, grid_range_z); $parfor (int idx, idy, idz : block_dom) grid(idx, idy, idz); }}} == Optimization == The purpose of the `parfor` construct is to enable possible optimization in CIVL. The model checker, for example, when control reaches the `parfor` loop, may try to determine that any two iterations are non-interfering, i.e., any atomic statement from one iteration will commute with any atomic statement from a different iteration. In this case, it will just execute the loop sequentially without creating any new threads. == Worksharing == We could take this further and provide in CIVL-C "worksharing" constructs similar to those in OpenMP. Would this be a good idea?