NAG Library Manual, Mark 29
Interfaces:  FL   CL   CPP   AD 

NAG CL Interface Introduction
Example description
/* nag_omp_set_max_active_levels (x06ajc) Example Program.
 *
 * Copyright 2023 Numerical Algorithms Group.
 *
 * Mark 29.0, 2023.
 */
#include <stdio.h>
#include <nag.h>

int main(void)
{

  /* Scalars */
  Integer inner_num, inner_threads, max_active_levels, outer_threads, total,
    total_2, total_3, exit_status = 0;

  /* Nag Types */
  NagError fail;

  INIT_FAIL(fail);
  /* Initialise totals */
  total = 0;
  total_2 = 0;
  total_3 = 0;

  /* Set number of threads for inner and outer parallel regions */
  inner_threads = 7;
  outer_threads = 3;
  nag_omp_set_num_threads(outer_threads, &fail);

  /* Testing implementation default behaviour */

  printf("nag_omp_set_max_active_levels (x06ajc) Example Program Results\n");

#ifdef _OPENMP
#pragma omp parallel shared (inner_threads,total,inner_num,fail), default (none)
#endif
  {
#ifdef _OPENMP
#pragma omp master
#endif
    {
      printf("Implementation max active levels default: %11" NAG_IFMT "\n",
             nag_omp_get_max_active_levels());
      printf("    No. threads in 1st parallel region: %13" NAG_IFMT "\n",
             nag_omp_get_num_threads());
    }

#ifdef _OPENMP
#pragma omp barrier
#endif
    nag_omp_set_num_threads(inner_threads, &fail);

#ifdef _OPENMP
#pragma omp parallel shared (total,inner_num), default (none)
#endif
    {
      /* Get max number of threads inside second active parallel region */
      inner_num = nag_omp_get_num_threads();

#ifdef _OPENMP
#pragma omp atomic
#endif
        total++;
    }
#ifdef _OPENMP
#pragma omp master
#endif
    {
      printf("    No. threads in 2nd parallel region: %13" NAG_IFMT "\n",
             inner_num);
    }
  }

  printf("    Total threads: %34" NAG_IFMT "\n\n\n",total);

  /* Set max active parallel regions */
  max_active_levels = 2;
  nag_omp_set_max_active_levels(max_active_levels, &fail);

  if (fail.code != NE_NOERROR) {
    printf("Error from nag_omp_set_max_active_levels (x06ajc).\n%s\n",
           fail.message);
    fflush(stdout);
    exit_status = 1;
    goto END;
  }

  /* Set number of threads for inner and outer parallel regions */
  inner_threads = 7;
  outer_threads = 3;
  nag_omp_set_num_threads(outer_threads, &fail);

  /*      Testing with max active levels set to 2 */

#ifdef _OPENMP
#pragma omp parallel \
  shared (inner_threads,total_2,inner_num,fail,max_active_levels),\
  default (none)
#endif
  {
#ifdef _OPENMP
#pragma omp master
#endif
    {
      printf("    Max active levels set to: %23" NAG_IFMT "\n",
             max_active_levels);
      printf("    x06ak return value: %29" NAG_IFMT "\n",
             nag_omp_get_max_active_levels());
      printf("    No. threads in 1st parallel region: %13" NAG_IFMT "\n",
             nag_omp_get_num_threads());
    }

#ifdef _OPENMP
#pragma omp barrier
#endif
    nag_omp_set_num_threads(inner_threads, &fail);

#ifdef _OPENMP
#pragma omp parallel shared (total_2,inner_num), default (none)
#endif
    {
      /* Get max number of threads inside second active parallel region */
      inner_num = nag_omp_get_num_threads();

#ifdef _OPENMP
#pragma omp atomic
#endif
        total_2++;

    }
#ifdef _OPENMP
#pragma omp master
#endif
        {
          printf("    No. threads in 2nd parallel region: %13" NAG_IFMT "\n",
                 inner_num);
        }

  }

  printf("    Total threads: %34" NAG_IFMT "\n\n\n",total_2);

  /* Set max active parallel regions */
  max_active_levels = 1;
  nag_omp_set_max_active_levels(max_active_levels, &fail);

  if (fail.code != NE_NOERROR) {
    printf("Error from nag_omp_set_max_active_levels (x06ajc).\n%s\n",
           fail.message);
    fflush(stdout);
    exit_status = 1;
    goto END;
  }

  /*  Testing with max active levels set to 1 */
#ifdef _OPENMP
#pragma omp parallel \
  shared (inner_threads,total_3,inner_num,fail,max_active_levels), \
  default (none)
#endif
  {
#ifdef _OPENMP
#pragma omp master
#endif
    {
      printf("    Max active levels set to: %23" NAG_IFMT "\n",
             max_active_levels);
      printf("    x06ak return value: %29" NAG_IFMT "\n",
             nag_omp_get_max_active_levels());
      printf("    No. threads in 1st parallel region: %13" NAG_IFMT "\n",
             nag_omp_get_num_threads());
    }

#ifdef _OPENMP
#pragma omp barrier
#endif
    nag_omp_set_num_threads(inner_threads, &fail);
#ifdef _OPENMP
#pragma omp parallel shared (total_3,inner_num), default (none)
#endif
    {
      /* Get max number of threads inside second active parallel region */
      inner_num = nag_omp_get_num_threads();
#ifdef _OPENMP
#pragma omp atomic
#endif
        total_3++;
    }

#ifdef _OPENMP
#pragma omp master
#endif
    {
      printf("    No. threads in 2nd parallel region:");
    }
  }
  printf("%14" NAG_IFMT "\n", inner_num);
  printf("    Total threads: %34" NAG_IFMT "\n", total_3);

 END:
  return exit_status;
}