Fork me on GitHub

Exercise 3

Overview:

1. Still logged into the workshop cluster?

  1. If so, then continue to the next step. If not, then login as you did previously for Exercise 1.

2. Review / Compile / Run the orphan example code

This example computes a dot product in parallel, however it differs from previous examples because the parallel loop construct is orphaned - it is contained in a subroutine outside the lexical extent of the main program’s parallel region.

  1. After reviewing the source code, compile and run the program. For example:

    C:

    icc -openmp omp_orphan.c -o orphan 
    orphan | sort
    

    Fortran:

    ifort -openmp omp_orphan.f -o orphan
    orphan | sort
    
  2. Note the result…and the fact that this example will come back to haunt as omp_bug6 later.

3. Get environment information

  1. Starting from scratch, write a simple program that obtains information about your openMP environment. Alternately, you can modify the “hello” program to do this.

  2. Using the appropriate openMP routines/functions, have the master thread query and print the following:
    • The number of processors available
    • The number of threads being used
    • The maximum number of threads available
    • If you are in a parallel region
    • If dynamic threads are enabled
    • If nested parallelism is supported NOTE: Some compilers (IBM, GNU) implement some of the necessary Fortran functions as integer instead of logical as the standard specifies.
  3. If you need help, you can consult the omp_getEnvInfo.c or omp_getEnvInfo.f example file.

4. When things go wrong…

There are many things that can go wrong when developing OpenMP programs. The omp_bugX.X series of programs demonstrate just a few. See if you can figure out what the problem is with each case and then fix it.

Note: Please use the Intel (icc, ifort) compile commands for these exercises.

The buggy behavior will differ for each example. Some hints are provided below.

Hints (Click to expand!)
Code Behavior Hints/Notes
omp_bug1
omp_bug1fix
Fails compilation. Solution provided - must compile solution file. EXPLANATION: This example attempts to show the use of the combined PARALLEL for-DO directive. It fails because the loop does not come immediately after the directive. Corrections include removing all statements between the PARALLEL for-DO directive and the actual loop. Also, logic is added to preserve the ability to query the thread id and print it from inside the loop. Notice the use of the FIRSTPRIVATE clause to intialize the flag.
omp_bug2 Thread identifiers are wrong. Wrong answers. EXPLANATION: The bugs in this case are caused by neglecting to scope the TID and TOTAL variables as PRIVATE. By default, most OpenMP variables are scoped as SHARED. These variables need to be unique for each thread.
omp_bug3 Run-time error, hang. EXPLANATION: The run time error is caused by by the OMP BARRIER directive in the PRINT_RESULTS subroutine. By definition, an OMP BARRIER can not be nested outside the static extent of a SECTIONS directive. In this case it is orphaned outside the calling SECTIONS block.
omp_bug4
omp_bug4fix
Causes a segmentation fault. Solution provided - note that it is a script and will need to be "sourced". For example: "source omp_bug4fix". Be sure to examine the solution file to see what's going on - especially the last line, where you may need to change the name of the executable to match yours. EXPLANATION: OpenMP thread stack size is an implementation dependent resource. In this case, the array is too large to fit into the thread stack space and causes the segmentation fault.
omp_bug5
omp_bug5fix
Program hangs. Solution provided - must compile solution file. EXPLANATION: The problem in omp_bug5 is that the first thread acquires locka and then tries to get lockb before releasing locka. Meanwhile, the second thread has acquired lockb and then tries to get locka before releasing lockb. The solution overcomes the deadlock by using locks correctly.
omp_bug6 Failed compilation EXPLANATION: With orphaned directives, the correct scoping of variables is critical. The error occurs because the sum variable is scoped incorrectly. See the omp_orphan routine for one example of correct scoping. Note that there are other ways.

If you’re just finishing the tutorial and haven’t filled out our evaluation form yet, please do!