Basic syntax and variables
Case study: solving the Heat transfer problem
- have a square metallic plate with some initial temperature distribution (initial conditions)
- its border is in contact with a different temperature distribution (boundary conditions)
- want to simulate the evolution of the temperature across the plate
To solve the 2nd-order heat diffusion equation, we need to discretize it, i.e., to consider the plate as a grid of points, and to evaluate the temperature on each point at each iteration, according to the following finite difference equation:
Tnew[i,j] = 0.25 * (T[i-1,j] + T[i+1,j] + T[i,j-1] + T[i,j+1])
Tnew
= new temperature computed at the current iterationT
= temperature calculated at the past iteration (or the initial conditions at the first iteration)- the indices (i,j) indicate the grid point located at the i-th row and the j-th column
So, our objective is to:
- Write a code to implement the difference equation above. The code should:
- work for any given number of rows and columns in the grid,
- run for a given number of iterations, or until the difference between
Tnew
andT
is smaller than a given tolerance value, and - output the temperature at a desired position on the grid every given number of iterations.
- Use task parallelism to improve the performance of the code and run it on a single cluster node.
- Use data parallelism to improve the performance of the code and run it on multiple cluster nodes using hybrid parallelism.
Variables
A variable has three elements: a name, a type, and a value. When we store a value in a
variable for the first time, we say that we initialized it. Further changes to the value of a
variable are called assignments, in general, x=a
means that we assign the value a to the
variable x.
Variables in Chapel are declared with the var
or const
keywords. When a variable declared as const is
initialized, its value cannot be modified anymore during the execution of the program.
In Chapel, to declare a variable we must specify the type of the variable, or initialize it in place with some value. The common variable types in Chapel are:
- integer
int
, - floating point number
real
, - boolean
bool
, or - string
string
If a variable is declared without a type, Chapel will infer it from the given initial value, for example
(let’s store this in file baseSolver.chpl
)
const rows, cols = 100; // number of rows and columns in a matrix
const niter = 500; // number of iterations
const iout, jout = 50; // row and column to print
All these constant variables will be created as integers, and no other values can be assigned to these variables during the execution of the program.
On the other hand, if a variable is declared without an initial value, Chapel will initialize it with a default value depending on the declared type. The following variables will be created as real floating point numbers equal to 0.0.
var delta: real; // the greatest temperature difference from one iteration to next
var tmp: real; // for temporary results when computing the temperatures
Of course, we can use both, the initial value and the type, when declaring a varible as follows:
const tolerance: real = 0.0001; // temperature difference tolerance
var count: int = 0; // the iteration counter
const nout: int = 20; // the temperature at (iout,jout) will be printed every nout interations
Note that these two notations are different, but produce the same result in the end:
var a: real = 10; // we specify both the type and the value var a = 10: real; // we specify only the value (10 converted to real)
Let’s print out our configuration after we set all parameters:
writeln('Working with a matrix ', rows, 'x', cols, ' to ', niter, ' iterations or dT below ', tolerance);
Checking variable’s type
To check a variable’s type, use .type
query:
var x = 1e8:int;
type t = x.type;
writeln(t:string);
or in a single line:
writeln((1e8:int).type:string);
writeln((0.355 + 0.355i).type: string);