\pagebreak
\chapter{Internal Control Variables (ICVs)}
\label{chap:icv}

According to \$, an OpenMP implementation must act as if there are ICVs that control 
the behavior of the program.  This example illustrates two ICVs, \plc{nthreads-var} 
and \plc{max-active-levels-var}. The \plc{nthreads-var} ICV controls the 
number of threads requested for encountered parallel regions; there is one copy 
of this ICV per task. The \plc{max-active-levels-var} ICV controls the maximum 
number of nested active parallel regions; there is one copy of this ICV for the 
whole program.

In the following example, the \plc{nest-var}, \plc{max-active-levels-var}, 
\plc{dyn-var}, and \plc{nthreads-var} ICVs are modified through calls to 
the runtime library routines \code{omp\_set\_nested},\\ \code{omp\_set\_max\_active\_levels},\code{ 
omp\_set\_dynamic}, and \code{omp\_set\_num\_threads} respectively. These ICVs 
affect the operation of \code{parallel} regions. Each implicit task generated 
by a \code{parallel} region has its own copy of the \plc{nest-var, dyn-var}, 
and \plc{nthreads-var} ICVs.

In the following example, the new value of \plc{nthreads-var} applies only to 
the implicit tasks that execute the call to \code{omp\_set\_num\_threads}. There 
is one copy of the \plc{max-active-levels-var} ICV for the whole program and 
its value is the same for all tasks. This example assumes that nested parallelism 
is supported.

The outer \code{parallel} region creates a team of two threads; each of the threads 
will execute one of the two implicit tasks generated by the outer \code{parallel} 
region.

Each implicit task generated by the outer \code{parallel} region calls \code{omp\_set\_num\_threads(3)}, 
assigning the value 3 to its respective copy of \plc{nthreads-var}. Then each 
implicit task encounters an inner \code{parallel} region that creates a team 
of three threads; each of the threads will execute one of the three implicit tasks 
generated by that inner \code{parallel} region.

Since the outer \code{parallel} region is executed by 2 threads, and the inner 
by 3, there will be a total of 6 implicit tasks generated by the two inner \code{parallel} 
regions.

Each implicit task generated by an inner \code{parallel} region will execute 
the call to\\ \code{omp\_set\_num\_threads(4)}, assigning the value 4 to its respective 
copy of \plc{nthreads-var}.

The print statement in the outer \code{parallel} region is executed by only one 
of the threads in the team. So it will be executed only once.

The print statement in an inner \code{parallel} region is also executed by only 
one of the threads in the team. Since we have a total of two inner \code{parallel} 
regions, the print statement will be executed twice -- once per inner \code{parallel} 
region.

\cexample{icv}{1c}

\fexample{icv}{1f}

