wiki:ConcurrencyExtensions

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<<<nx,ny,nz>>>();

=>

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?

Last modified 12 years ago Last modified on 06/10/14 14:22:11
Note: See TracWiki for help on using the wiki.