#include <stdio.h>

#ifdef _OPENMP
    #include <omp.h>
#endif

void print_omp_info() {
    #pragma omp critical
    {
        printf("_OPENMP               = %i\n", _OPENMP);
        printf("omp_get_num_procs()   = %i\n", omp_get_num_procs());
        printf("omp_get_thread_num()  = %i\n", omp_get_thread_num());
        printf("omp_get_num_threads() = %i\n", omp_get_num_threads());
        printf("omp_get_max_threads() = %i\n", omp_get_max_threads());
        printf("omp_in_parallel()     = %s\n", (omp_in_parallel() ? "true" : "false"));
        printf("omp_get_dynamic()     = %s\n", (omp_get_dynamic() ? "true" : "false"));
        printf("omp_get_nested()      = %s\n", (omp_get_nested()  ? "true" : "false"));
    }
}

int main(int argc, char *argv[]) {
    #ifdef _OPENMP
        printf("call to print_omp_info in serial region\n");
        print_omp_info();

/*

call to print_omp_info in serial region
_OPENMP               = 201511
omp_get_num_procs()   = 4
omp_get_thread_num()  = 0
omp_get_num_threads() = 1
omp_get_max_threads() = 4
omp_in_parallel()     = false
omp_get_dynamic()     = false
omp_get_nested()      = false

*/
        printf("call to print_omp_info in parallel region\n");
        #pragma omp parallel
        print_omp_info();

/*

call to print_omp_info in parallel region
_OPENMP               = 201511
omp_get_num_procs()   = 4
omp_get_thread_num()  = 0
omp_get_num_threads() = 4
omp_get_max_threads() = 4
omp_in_parallel()     = true
omp_get_dynamic()     = false
omp_get_nested()      = false
_OPENMP               = 201511
omp_get_num_procs()   = 4
omp_get_thread_num()  = 3
omp_get_num_threads() = 4
omp_get_max_threads() = 4
omp_in_parallel()     = true
omp_get_dynamic()     = false
omp_get_nested()      = false
_OPENMP               = 201511
omp_get_num_procs()   = 4
omp_get_thread_num()  = 1
omp_get_num_threads() = 4
omp_get_max_threads() = 4
omp_in_parallel()     = true
omp_get_dynamic()     = false
omp_get_nested()      = false
_OPENMP               = 201511
omp_get_num_procs()   = 4
omp_get_thread_num()  = 2
omp_get_num_threads() = 4
omp_get_max_threads() = 4
omp_in_parallel()     = true
omp_get_dynamic()     = false
omp_get_nested()      = false

*/

        const int num_threads = 2;
        printf("omp_set_num_threads(%i)\n", num_threads);
        printf("call to print_omp_info in parallel region\n");
        omp_set_num_threads(num_threads);
        #pragma omp parallel
        print_omp_info();

/*

omp_set_num_threads(2)
call to print_omp_info in parallel region
_OPENMP               = 201511
omp_get_num_procs()   = 4
omp_get_thread_num()  = 1
omp_get_num_threads() = 2
omp_get_max_threads() = 2
omp_in_parallel()     = true
omp_get_dynamic()     = false
omp_get_nested()      = false
_OPENMP               = 201511
omp_get_num_procs()   = 4
omp_get_thread_num()  = 0
omp_get_num_threads() = 2
omp_get_max_threads() = 2
omp_in_parallel()     = true
omp_get_dynamic()     = false
omp_get_nested()      = false

*/
    #else
        printf("No OpenMP support.\n");
    #endif

    return 0;
}