diff --git a/episodes/01-intro.md b/episodes/01-intro.md index f2a74c7..a5402b1 100644 --- a/episodes/01-intro.md +++ b/episodes/01-intro.md @@ -35,7 +35,7 @@ Chapel source code must be written in text files with the extension **_.chpl_**. world"-type program to demonstrate how we write Chapel code! Using your favourite text editor, create the file `hello.chpl` with the following content: -```bash +```chpl writeln('If we can see this, everything works!'); ``` @@ -46,12 +46,14 @@ chpl --fast hello.chpl ``` The flag `--fast` indicates the compiler to optimise the binary to run as fast as possible in the given -architecture. The `-o` option tells Chapel what to call the final output program, in this case `hello.o`. +architecture. By default, the compiler will produce a program with the same name +as the source file. In our case, the program will be called `hello`. The `-o` +option can be used to change the name of the generated binary. To run the code, you execute it as you would any other program: ```bash -./hello.o +./hello ``` ```output If we can see this, everything works! @@ -82,7 +84,7 @@ and then inside that job compile and run the test code ```bash chpl --fast hello.chpl -./hello.o +./hello ``` For production jobs, you would compile the code and then submit a batch script to the queue: @@ -137,5 +139,5 @@ So, our objective is to: ::::::::::::::::::::::::::::::::::::: keypoints - "Chapel is a compiled language - any programs we make must be compiled with `chpl`." - "The `--fast` flag instructs the Chapel compiler to optimise our code." -- "The `-o` flag tells the compiler what to name our output (otherwise it gets named `a.out`)" +- "The `-o` flag tells the compiler what to name our output (otherwise it gets named after the source file)" :::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/episodes/02-variables.md b/episodes/02-variables.md index 2ebaf08..d7b6e79 100644 --- a/episodes/02-variables.md +++ b/episodes/02-variables.md @@ -31,7 +31,7 @@ In this example, our code is called `operators.chpl`. You can compile it with th ```bash chpl operators.chpl --fast -./operators.o +./operators ``` You should see output that looks something like the following: @@ -139,7 +139,7 @@ writeln("counter is ", counter, " and delta is ", delta); ``` ```bash chpl variables.chpl -./variables.o +./variables ``` ```output counter is 0 and delta is 0.0 @@ -154,7 +154,7 @@ writeln('The value of test is ', test, ' and its type is ', test.type:string); ``` ```bash chpl variables.chpl -./variables.o +./variables ``` ```output The value of test is 100 and its type is int(64) diff --git a/episodes/03-ranges-arrays.md b/episodes/03-ranges-arrays.md index 7bf2bd4..b9b96bd 100644 --- a/episodes/03-ranges-arrays.md +++ b/episodes/03-ranges-arrays.md @@ -27,7 +27,7 @@ for x in example_range do writeln(x); ```bash chpl ranges.chpl -./ranges.o +./ranges ``` ```output @@ -66,7 +66,7 @@ writeln('When set to a range: ', example_array); ```bash chpl ranges.chpl -./ranges.o +./ranges ``` ```output @@ -104,7 +104,7 @@ writeln(example_array); ```bash chpl ranges.chpl -./ranges.o +./ranges ``` ```output @@ -139,7 +139,7 @@ writeln(example_array); ```bash chpl ranges.chpl -./ranges.o +./ranges ``` ```output diff --git a/episodes/04-conditionals.md b/episodes/04-conditionals.md index 10cb10d..a138474 100644 --- a/episodes/04-conditionals.md +++ b/episodes/04-conditionals.md @@ -28,7 +28,7 @@ writeln(1 <= 2); ```bash chpl conditionals.chpl -./conditionals.o +./conditionals ``` ```output @@ -57,7 +57,7 @@ writeln(true || false); ```bash chpl conditionals.chpl -./conditionals.o +./conditionals ``` ```output @@ -77,12 +77,19 @@ true The general syntax of a while statement is: ```chpl -while condition do -{instructions} +// single-statement form +while condition do + instruction + +// multi-statement form +while condition +{ + instructions +} ``` The code flows as follows: first, the condition is evaluated, and then, if it is satisfied, all the -instructions within the curly brackets are executed one by one. This will be repeated over and over again +instructions within the curly brackets or `do` are executed one by one. This will be repeated over and over again until the condition does not hold anymore. The main loop in our simulation can be programmed using a while statement like this @@ -91,7 +98,7 @@ The main loop in our simulation can be programmed using a while statement like t //this is the main loop of the simulation var c = 0; delta = tolerance; -while (c < niter && delta >= tolerance) do +while (c < niter && delta >= tolerance) { c += 1; // actual simulation calculations will go here @@ -115,9 +122,16 @@ at the desired position. This is the type of control that an **_if statement_** is: ```chpl -if condition then -{instructions A} -else +// single-statement form +if condition then + instruction A +else + instruction B + +// multi-statement form +if condition +{instructions A} +else {instructions B} ``` @@ -148,6 +162,8 @@ const y = 50; // column number of the desired position const tolerance = 0.0001; // smallest difference in temperature that // would be accepted before stopping const outputFrequency: int = 20; // the temperature will be printed every outputFrequency iterations +var delta: real; // greatest difference in temperature from one iteration to another +var tmp: real; // for temporary results // this is our "plate" var temp: [0..rows+1, 0..cols+1] real = 25; @@ -158,7 +174,7 @@ writeln('Temperature at start is: ', temp[x, y]); //this is the main loop of the simulation var c = 0; delta = tolerance; -while (c < niter && delta >= tolerance) do +while (c < niter && delta >= tolerance) { c += 1; if (c % outputFrequency == 0) @@ -170,7 +186,7 @@ while (c < niter && delta >= tolerance) do ```bash chpl base_solution.chpl -./base_solution.o +./base_solution ``` ```output @@ -207,11 +223,11 @@ Of course the temperature is always 25.0 at any iteration other than the initial computation yet. ::::::::::::::::::::::::::::::::::::: keypoints -- "Use `if then {instructions A} else {instructions B}` syntax to execute one set of instructions +- "Use `if {instructions A} else {instructions B}` syntax to execute one set of instructions if the condition is satisfied, and the other set of instructions if the condition is not satisfied." -- This syntax can be simplified to `if then {instructions}` if we only want to execute the +- This syntax can be simplified to `if {instructions}` if we only want to execute the instructions within the curly brackets if the condition is satisfied. -- "Use `while do {instructions}` to repeatedly execute the instructions within the curly brackets +- "Use `while {instructions}` to repeatedly execute the instructions within the curly brackets while the condition is satisfied. The instructions will be executed over and over again until the condition does not hold anymore." :::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/episodes/05-loops.md b/episodes/05-loops.md index dd323f5..fac41ce 100644 --- a/episodes/05-loops.md +++ b/episodes/05-loops.md @@ -20,9 +20,14 @@ a given number of elements, the **_for-loop_** is what we want to use. The for-l syntax: ```chpl +// single-statement version for index in iterand do + instruction; + +// multi-statement version +for index in iterand {instructions} -``` +``` The *iterand* is a function or statement that expresses an iteration; it could be the range 1..15, for example. *index* is a variable that exists only in the context of the for-loop, and that will be taking the @@ -35,7 +40,7 @@ This `for` loop, for example ```chpl // calculate the new temperatures (temp_new) using the past temperatures (temp) -for i in 1..rows do +for i in 1..rows { // do this for every row } @@ -47,10 +52,10 @@ this: ```chpl // calculate the new temperatures (temp_new) using the past temperatures (temp) -for i in 1..rows do +for i in 1..rows { // do this for every row - for j in 1..cols do + for j in 1..cols { // and this for every column in the row i } @@ -62,10 +67,10 @@ follows: ```chpl // calculate the new temperatures (temp_new) using the past temperatures (temp) -for i in 1..rows do +for i in 1..rows { // do this for every row - for j in 1..cols do + for j in 1..cols { // and this for every column in the row i temp_new[i,j] = (temp[i-1,j] + temp[i+1,j] + temp[i,j-1] + temp[i,j+1]) / 4; @@ -78,6 +83,17 @@ Note that at the end of the outer `for` loop, when all the elements in `temp_new `temp` with the values of `temp_new`; this way everything is set up for the next iteration of the main `while` statement. +We're ready to execute our code, but the conditions we have initially set up +will not produce interesting output, because the plate has a temperature +value of `25` everywhere. We can change the boundaries to have temperature `0` +so that the middle will start cooling down. To do this, we should change the +declaration of `temp` to: + +```chpl +var temp: [0..rows+1, 0..cols+1] real = 0; // the whole plate starts at 0 +temp[1..rows,1..cols] = 25; // set the non-boundary coordinates to 25 +``` + Now let's compile and execute our code again: ```bash @@ -239,9 +255,9 @@ the job: ```chpl // update delta, the greatest difference between temp_new and temp delta=0; -for i in 1..rows do +for i in 1..rows { - for j in 1..cols do + for j in 1..cols { tmp = abs(temp_new[i,j]-temp[i,j]); if tmp > delta then delta = tmp; @@ -337,8 +353,8 @@ The greatest difference in temperatures between the last two iterations was: 0.0 ::::::::::::::::::::::::::::::::::::: keypoints - "You can organize loops with `for` and `while` statements. Use a `for` loop to run over every element of the - iterand, e.g. `for i in 1..rows do { ...}` will run over all integers from 1 to `rows`. Use a `while` + iterand, e.g. `for i in 1..rows { ...}` will run over all integers from 1 to `rows`. Use a `while` statement to repeatedly execute a code block until the condition does not hold anymore, e.g. `while (c < - niter && delta >= tolerance) do {...}` will repeatedly execute the commands in curly braces until one of the + niter && delta >= tolerance) {...}` will repeatedly execute the commands in curly braces until one of the two conditions turns false." :::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/episodes/06-procedures.md b/episodes/06-procedures.md index a6cc177..a9dd36f 100644 --- a/episodes/06-procedures.md +++ b/episodes/06-procedures.md @@ -65,8 +65,8 @@ procedure and is used to organize the calculations inside the procedure: ```chpl proc maxOf(x ...?k) { // take a tuple of one type with k elements - var maximum = x[1]; - for i in 2..k do maximum = if maximum < x[i] then x[i] else maximum; + var maximum = x[0]; + for i in 1.. ## Question > -> Why do we have `forall (i,j) in T.domain[1..n,1..n]` +> Why do we have `forall (i,j) in temp.domain[1..n,1..n]` > and not `forall (i,j) in mesh`? > > > ## Answer @@ -415,9 +416,10 @@ Here is the final version of the entire code: ```chpl use BlockDist; +use Math; config const n = 8; const mesh: domain(2) = {1..n,1..n}; -const largerMesh: domain(2) dmapped Block(boundingBox=mesh) = {0..n+1,0..n+1}; +const largerMesh: domain(2) dmapped new blockDist(boundingBox=mesh) = {0..n+1,0..n+1}; var temp, temp_new: [largerMesh] real; forall (i,j) in temp.domain[1..n,1..n] { var x = ((i:real)-0.5)/(n:real); @@ -518,7 +520,7 @@ We'll add the following to our code to write ASCII: ```chpl use IO; -var myFile = open("output.dat", iomode.cw); // open the file for writing +var myFile = open("output.dat", ioMode.cw); // open the file for writing var myWritingChannel = myFile.writer(); // create a writing channel starting at file offset 0 myWritingChannel.write(temp); // write the array myWritingChannel.close(); // close the channel