|
1 | | -# How to use isl via the C++ / Python interface |
| 1 | +Warning: This is a proposal, which does not document the current isl |
| 2 | + |
| 3 | +# How to use isl via the C++ and Python interface |
| 4 | + |
| 5 | +## Constructing an integer set or map (isl::set / isl::map) |
| 6 | + |
| 7 | +We create an integer set as follows. We first create a set of identifiers for |
| 8 | +each of the needed dimensions (`isl::id Id_N(ctx, "N"`). We then introduce |
| 9 | +initial expressions for all identifiers and required constants (`isl::pw_aff |
| 10 | +N(Id_N), Ten(ctx, 10)`). From these initial expressions the actual affine |
| 11 | +expressions are constructed (`isl::pw_aff LHS = Two.mul(M)`). Pairs of |
| 12 | +expressions are combined with the operators lt_set (<), le_set (<=), ge_set |
| 13 | +(>=), gt_set (>), eq_set (=), ne_set (!=) into a parameteric set of constraints |
| 14 | +(`isl::set PSet = LHS.le_set(RHS)`). Finally, a non-parameteric set is |
| 15 | +constructed from 1) a parameteric set specifying its constraints and 2) a list |
| 16 | +of identifiers that specify the parameter dimensions that should be promoted to |
| 17 | +set dimensions (`isl::set Set({Id_i, Id_j}, PSet)`). Similary, a map can be |
| 18 | +constructed by providing two lists of identifiers defining the input and output |
| 19 | +dimensions (`isl::map Map({Id_i}, {Id_j}, PSet)`) |
| 20 | + |
| 21 | +Example: |
| 22 | +*{ [N, M] -> { [i,j] : 2 * M + 3 * N <= 2 * i + j + 10 }* |
| 23 | + |
| 24 | + |
| 25 | +``` |
| 26 | +// Identifiers |
| 27 | +isl::id Id_N(ctx, "N"), Id_M(ctx, "M"), Id_i(ctx, "i"), Id_j(ctx, "j"); |
| 28 | +
|
| 29 | +// One (piece-wise) affine expression per identifier |
| 30 | +isl::pw_aff N(Id_N), M(Id_M), i(Id_i), j(Id_j); |
| 31 | +
|
| 32 | +// One (piece-wise) affine expression per constant |
| 33 | +isl::pw_aff Ten(ctx, 10), Two(ctx, 2), Three(ctx, 3); |
| 34 | +
|
| 35 | +// Build the left and right hand side of the expression |
| 36 | +isl::pw_aff LHS = Two.mul(M).add(Three.mul(N)); |
| 37 | +isl::pw_aff RHS = Two.mul(i).add(j).add(Ten); |
| 38 | +
|
| 39 | +// [N, M, i, j] -> { : 2 * M + 3 * N <= 2 * i + j + 10 } |
| 40 | +isl::set PSet = LHS.le_set(RHS); |
| 41 | +
|
| 42 | +// [N, M] -> { [i, j] : 2 * M + 3 * N <= 2 * i + j + 10 } |
| 43 | +isl::set Set({Id_i, Id_j}, PSet); |
| 44 | +
|
| 45 | +// [N, M] -> { [i] -> [j] : 2 * M + 3 * N <= 2 * i + j + 10 } |
| 46 | +isl::map Map({Id_i}, {Id_j}, PSet); |
| 47 | +``` |
| 48 | + |
| 49 | +- Comments |
| 50 | + |
| 51 | + - Why do we need to create identifiers twice? Can we just do? |
| 52 | + |
| 53 | +``` |
| 54 | +// One (piece-wise) affine expression per identifier |
| 55 | +isl::pw_aff N(ctx, "N"), M(ctx, "M"), i(ctx, i"), j(ctx, "j"); |
| 56 | +``` |
| 57 | + This likely won't work as there is no way to obtain ids for the identifiers. |
| 58 | + |
0 commit comments