diff --git a/MANIFEST.in b/MANIFEST.in index 6654fc5..a9d60c7 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,6 +4,8 @@ include requirements.txt include fortran/*.f90 include fortran/*.pyf +include fortran/build_help/omp_sizes.f90 +include fortran/build_help/sub_sizes.py include build_scripts/*.sh include build_scripts/*.bat include setup.py diff --git a/build_scripts/gnu_omp.sh b/build_scripts/gnu_omp.sh index 09644ad..75310ad 100755 --- a/build_scripts/gnu_omp.sh +++ b/build_scripts/gnu_omp.sh @@ -1,6 +1,10 @@ #!/bin/bash -cd ../fortran +cd ../fortran/build_help +gfortran -o sizes -fopenmp omp_sizes.f90 +python sub_sizes.py + +cd .. gfortran -E ompgen.F90 -fopenmp -cpp -o omp.f90 f2py *.f90 -m _wrffortran -h wrffortran.pyf --overwrite-signature cd .. diff --git a/build_scripts/win_mingw_omp.bat b/build_scripts/win_mingw_omp.bat index b412e96..a5fa4c3 100644 --- a/build_scripts/win_mingw_omp.bat +++ b/build_scripts/win_mingw_omp.bat @@ -1,4 +1,8 @@ -cd ../fortran +cd ..\fortran\build_help +CALL gfortran -o sizes -fopenmp omp_sizes.f90 +CALL python sub_sizes.py + +cd .. CALL gfortran -E ompgen.F90 -cpp -fopenmp -o omp.f90 REM Wildcards not working on Windows for some reason CALLf2py -m _wrffortran -h wrffortran.pyf --overwrite-signature wrf_constants.f90 wrf_testfunc.f90 wrf_user.f90 rip_cape.f90 wrf_cloud_fracf.f90 wrf_fctt.f90 wrf_user_dbz.f90 wrf_relhl.f90 calc_uh.f90 wrf_user_latlon_routines.f90 wrf_pvo.f90 eqthecalc.f90 wrf_rip_phys_routines.f90 wrf_pw.f90 wrf_vinterp.f90 wrf_wind.f90 omp.f90 diff --git a/build_scripts/win_msvc_mingw_omp.bat b/build_scripts/win_msvc_mingw_omp.bat index 95a13a7..f4d1c5d 100644 --- a/build_scripts/win_msvc_mingw_omp.bat +++ b/build_scripts/win_msvc_mingw_omp.bat @@ -1,4 +1,8 @@ -cd ../fortran +cd ..\fortran\build_help +CALL gfortran -o sizes -fopenmp omp_sizes.f90 +CALL python sub_sizes.py + +cd .. CALL gfortran -E ompgen.F90 -cpp -fopenmp -o omp.f90 REM Wildcards not working on Windows for some reason CALL f2py -m _wrffortran -h wrffortran.pyf --overwrite-signature wrf_constants.f90 wrf_testfunc.f90 wrf_user.f90 rip_cape.f90 wrf_cloud_fracf.f90 wrf_fctt.f90 wrf_user_dbz.f90 wrf_relhl.f90 calc_uh.f90 wrf_user_latlon_routines.f90 wrf_pvo.f90 eqthecalc.f90 wrf_rip_phys_routines.f90 wrf_pw.f90 wrf_vinterp.f90 wrf_wind.f90 omp.f90 diff --git a/conda_recipe/bld.bat b/conda_recipe/bld.bat index d1bb7f0..d4a4a3f 100644 --- a/conda_recipe/bld.bat +++ b/conda_recipe/bld.bat @@ -1,4 +1,8 @@ -cd ./fortran +cd fortran\build_help +CALL gfortran -o sizes -fopenmp omp_sizes.f90 +CALL python sub_sizes.py + +cd .. CALL gfortran -E ompgen.F90 -cpp -fopenmp -o omp.f90 REM Wildcards not working on Windows for some reason CALL f2py -m _wrffortran -h wrffortran.pyf --overwrite-signature wrf_constants.f90 wrf_testfunc.f90 wrf_user.f90 rip_cape.f90 wrf_cloud_fracf.f90 wrf_fctt.f90 wrf_user_dbz.f90 wrf_relhl.f90 calc_uh.f90 wrf_user_latlon_routines.f90 wrf_pvo.f90 eqthecalc.f90 wrf_rip_phys_routines.f90 wrf_pw.f90 wrf_vinterp.f90 wrf_wind.f90 omp.f90 diff --git a/conda_recipe/build.sh b/conda_recipe/build.sh index ec01ebb..eefecaf 100644 --- a/conda_recipe/build.sh +++ b/conda_recipe/build.sh @@ -1,6 +1,10 @@ #!/bin/bash -cd ./fortran +cd fortran/build_help +gfortran -o sizes -fopenmp omp_sizes.f90 +python sub_sizes.py + +cd .. gfortran -E ompgen.F90 -fopenmp -cpp -o omp.f90 f2py *.f90 -m _wrffortran -h wrffortran.pyf --overwrite-signature cd .. diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index b912d3a..d613f4c 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -6,9 +6,8 @@ package: source: git_url: https://github.com/NCAR/wrf-python - git_branch: develop + git_branch: release/1.1.0 - build: number: 0 detect_binary_files_with_prefix: true @@ -17,14 +16,15 @@ requirements: build: - setuptools - python - - numpy 1.11.* # [unix] - - numpy 1.14.* # [win] + - numpy 1.11.* # [unix] + - numpy 1.14.* # [win] - wrapt - m2w64-toolchain # [win] - gcc # [unix] run: - setuptools - - numpy >=1.11 + - numpy >=1.11 # [unix] + - numpy >=1.14 # [win] - python - wrapt - m2w64-gcc-libs # [win] @@ -56,3 +56,4 @@ extra: - marylhaley - david-ian-brown - khallock + \ No newline at end of file diff --git a/conda_recipe/meta.yaml.develop b/conda_recipe/meta.yaml.develop index ee75ff1..9ab332b 100644 --- a/conda_recipe/meta.yaml.develop +++ b/conda_recipe/meta.yaml.develop @@ -8,7 +8,6 @@ source: git_url: https://github.com/NCAR/wrf-python git_branch: develop - build: number: 0 detect_binary_files_with_prefix: true @@ -16,15 +15,16 @@ build: requirements: build: - setuptools - - numpy 1.11.* # [unix] - - numpy 1.14.* # [win] + - python + - numpy 1.11.* # [unix] + - numpy 1.14.* # [win] - wrapt - m2w64-toolchain # [win] - - gcc # [unix] - - python + - gcc # [unix] run: - setuptools - - numpy >=1.11 + - numpy >=1.11 # [unix] + - numpy >=1.14 # [win] - python - wrapt - m2w64-gcc-libs # [win] @@ -55,4 +55,4 @@ extra: - bladwig1 - marylhaley - david-ian-brown - - khallock + - khallock \ No newline at end of file diff --git a/conda_recipe/meta.yaml.release b/conda_recipe/meta.yaml.release index 51c2ee0..f38235e 100644 --- a/conda_recipe/meta.yaml.release +++ b/conda_recipe/meta.yaml.release @@ -7,7 +7,7 @@ package: source: fn: wrf-python-{{ version }}.tar.gz url: https://github.com/NCAR/wrf-python/archive/{{ version }}.tar.gz - sha256: ea2202e1d8237c65b9d77a91f00da0f2e7a37ed6214ddd976872b619b9647b33 + sha256: 9ca11366ed9a0d5e83e576ac80ce36be4748ba8a06752dac077277acec5e46d9 build: number: 0 @@ -16,15 +16,16 @@ build: requirements: build: - setuptools - - numpy 1.11.* # [unix] - - numpy 1.14.* # [win] + - python + - numpy 1.11.* # [unix] + - numpy 1.14.* # [win] - wrapt - m2w64-toolchain # [win] - - gcc # [unix] - - python + - gcc # [unix] run: - setuptools - - numpy >=1.11 + - numpy >=1.11 # [unix] + - numpy >=1.14 # [win] - python - wrapt - m2w64-gcc-libs # [win] @@ -56,3 +57,4 @@ extra: - marylhaley - david-ian-brown - khallock + \ No newline at end of file diff --git a/doc/source/installation.rst b/doc/source/installation.rst index bd5cb18..4088af2 100644 --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -100,14 +100,20 @@ Below is a sample from a build script for GNU compiler with OpenMP enabled: .. code-block:: none - cd ../fortran + cd ../fortran/build_help + + gfortran -o sizes -fopenmp omp_sizes.f90 + + python sub_sizes.py + + cd .. gfortran -E ompgen.F90 -fopenmp -cpp -o omp.f90 f2py *.f90 -m _wrffortran -h wrffortran.pyf --overwrite-signature cd .. - + python setup.py clean --all python setup.py config_fc --f90flags="-mtune=generic -fopenmp" build_ext --libraries="gomp" build diff --git a/fortran/build_help/omp_sizes.f90 b/fortran/build_help/omp_sizes.f90 new file mode 100644 index 0000000..9e74a0b --- /dev/null +++ b/fortran/build_help/omp_sizes.f90 @@ -0,0 +1,14 @@ +PROGRAM sizes + + USE omp_lib + + PRINT *, "SIZES" + PRINT *, INT(OMP_SCHED_KIND, kind=OMP_SCHED_KIND) + PRINT *, INT(OMP_LOCK_KIND, kind=OMP_LOCK_KIND) + PRINT *, INT(OMP_NEST_LOCK_KIND, kind=OMP_NEST_LOCK_KIND) + PRINT *, INT(omp_sched_static, kind=OMP_SCHED_KIND) + PRINT *, INT(omp_sched_dynamic, kind=OMP_SCHED_KIND) + PRINT *, INT(omp_sched_guided, kind=OMP_SCHED_KIND) + PRINT *, INT(omp_sched_auto, kind=OMP_SCHED_KIND) + +END PROGRAM sizes diff --git a/fortran/build_help/sub_sizes.py b/fortran/build_help/sub_sizes.py new file mode 100644 index 0000000..4261977 --- /dev/null +++ b/fortran/build_help/sub_sizes.py @@ -0,0 +1,57 @@ +import subprocess +import os +from string import Template +import sys + +def main(): + + print ("Running sub_sizes") + try: + result = subprocess.check_output(["./sizes"]) + except: + result = subprocess.check_output(["sizes.exe"]) + + split_result = result.split() + + if sys.version_info >= (3, ): + if split_result[0].strip().decode() != "SIZES": + raise ValueError("First line is not SIZES") + + subs = {"FOMP_SCHED_KIND" : split_result[1].strip().decode(), + "FOMP_LOCK_KIND" : split_result[2].strip().decode(), + "FOMP_NEST_LOCK_KIND" : split_result[3].strip().decode(), + "FOMP_SCHED_STATIC" : split_result[4].strip().decode(), + "FOMP_SCHED_DYNAMIC" : split_result[5].strip().decode(), + "FOMP_SCHED_GUIDED" : split_result[6].strip().decode(), + "FOMP_SCHED_AUTO" : split_result[7].strip().decode() + } + else: + if split_result[0].strip() != "SIZES": + raise ValueError("First line is not SIZES") + + subs = {"FOMP_SCHED_KIND" : split_result[1].strip(), + "FOMP_LOCK_KIND" : split_result[2].strip(), + "FOMP_NEST_LOCK_KIND" : split_result[3].strip(), + "FOMP_SCHED_STATIC" : split_result[4].strip(), + "FOMP_SCHED_DYNAMIC" : split_result[5].strip(), + "FOMP_SCHED_GUIDED" : split_result[6].strip(), + "FOMP_SCHED_AUTO" : split_result[7].strip() + } + + + ompgen_temp_path = os.path.join("..", "ompgen.F90.template") + ompgen_out_path = os.path.join("..", "ompgen.F90") + + with open(ompgen_temp_path, "r") as ompgen_in: + ompgen_template = Template(ompgen_in.read()) + + ompgen_string = ompgen_template.substitute(subs) + + + with open(ompgen_out_path, "w") as ompgen_out: + ompgen_out.write(ompgen_string) + + + print ("End sub_sizes") +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/fortran/ompgen.F90 b/fortran/ompgen.F90 index 6ae48e1..14fa7d4 100644 --- a/fortran/ompgen.F90 +++ b/fortran/ompgen.F90 @@ -1,61 +1,23 @@ MODULE omp_constants #ifdef _OPENMP USE omp_lib - ! f2py can't figure this out without me making a map of these kinds to - ! c types, so we're going to have to hard code the kinds below. - !INTEGER, PARAMETER :: fomp_sched_kind = omp_sched_kind - !INTEGER, PARAMETER :: fomp_nest_lock_kind = omp_nest_lock_kind - !INTEGER, PARAMETER :: fomp_lock_kind = omp_lock_kind - - ! Note: Defining these specifically is the only way I can get f2py to - ! work without doing the same thing in a mapping file. The values below - ! are for GNU on 64bit. This may not be entirely correct for non-GNU - ! compilers. In particular, it will be the locks that segfault/crash if - ! this is wrong. -#if defined(__GFORTRAN__) -#if (__SIZEOF_POINTER__ == 8) - INTEGER, PARAMETER :: fomp_sched_kind = 4 - INTEGER, PARAMETER :: fomp_lock_kind = 8 - INTEGER, PARAMETER :: fomp_nest_lock_kind = 8 -#else - INTEGER, PARAMETER :: fomp_sched_kind = 4 - INTEGER, PARAMETER :: fomp_lock_kind = 4 - INTEGER, PARAMETER :: fomp_nest_lock_kind = 4 -#endif -#elif defined(__INTEL_COMPILER_BUILD_DATE) -#if defined(__x86_64__) || defined(_M_X64) - INTEGER, PARAMETER :: fomp_sched_kind = 4 - INTEGER, PARAMETER :: fomp_lock_kind = 8 - INTEGER, PARAMETER :: fomp_nest_lock_kind = 8 -#else - INTEGER, PARAMETER :: fomp_sched_kind = 4 - INTEGER, PARAMETER :: fomp_lock_kind = 4 - INTEGER, PARAMETER :: fomp_nest_lock_kind = 4 -#endif -#elif defined(__PGI) -#if defined(__x86_64__) + INTEGER, PARAMETER :: fomp_sched_kind = 4 INTEGER, PARAMETER :: fomp_lock_kind = 8 INTEGER, PARAMETER :: fomp_nest_lock_kind = 8 -#else - INTEGER, PARAMETER :: fomp_sched_kind = 4 - INTEGER, PARAMETER :: fomp_lock_kind = 4 - INTEGER, PARAMETER :: fomp_nest_lock_kind = 4 -#endif -#endif + INTEGER(KIND=4), PARAMETER :: fomp_sched_static = 1 + INTEGER(KIND=4), PARAMETER :: fomp_sched_dynamic = 2 + INTEGER(KIND=4), PARAMETER :: fomp_sched_guided = 3 + INTEGER(KIND=4), PARAMETER :: fomp_sched_auto = 4 - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_static = omp_sched_static - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_dynamic = omp_sched_dynamic - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_guided = omp_sched_guided - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_auto = omp_sched_auto #else INTEGER, PARAMETER :: fomp_sched_kind = 4 INTEGER, PARAMETER :: fomp_lock_kind = 4 INTEGER, PARAMETER :: fomp_nest_lock_kind = 8 - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_static = 1 - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_dynamic = 2 - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_guided = 3 - INTEGER(KIND=fomp_sched_kind), PARAMETER :: fomp_sched_auto = 4 + INTEGER(KIND=4), PARAMETER :: fomp_sched_static = 1 + INTEGER(KIND=4), PARAMETER :: fomp_sched_dynamic = 2 + INTEGER(KIND=4), PARAMETER :: fomp_sched_guided = 3 + INTEGER(KIND=4), PARAMETER :: fomp_sched_auto = 4 #endif END MODULE omp_constants diff --git a/fortran/ompgen.F90.template b/fortran/ompgen.F90.template new file mode 100644 index 0000000..00a50d5 --- /dev/null +++ b/fortran/ompgen.F90.template @@ -0,0 +1,715 @@ +MODULE omp_constants +#ifdef _OPENMP + USE omp_lib + + INTEGER, PARAMETER :: fomp_sched_kind = $FOMP_SCHED_KIND + INTEGER, PARAMETER :: fomp_lock_kind = $FOMP_LOCK_KIND + INTEGER, PARAMETER :: fomp_nest_lock_kind = $FOMP_NEST_LOCK_KIND + INTEGER(KIND=$FOMP_SCHED_KIND), PARAMETER :: fomp_sched_static = $FOMP_SCHED_STATIC + INTEGER(KIND=$FOMP_SCHED_KIND), PARAMETER :: fomp_sched_dynamic = $FOMP_SCHED_DYNAMIC + INTEGER(KIND=$FOMP_SCHED_KIND), PARAMETER :: fomp_sched_guided = $FOMP_SCHED_GUIDED + INTEGER(KIND=$FOMP_SCHED_KIND), PARAMETER :: fomp_sched_auto = $FOMP_SCHED_AUTO + +#else + INTEGER, PARAMETER :: fomp_sched_kind = 4 + INTEGER, PARAMETER :: fomp_lock_kind = 4 + INTEGER, PARAMETER :: fomp_nest_lock_kind = 8 + INTEGER(KIND=4), PARAMETER :: fomp_sched_static = 1 + INTEGER(KIND=4), PARAMETER :: fomp_sched_dynamic = 2 + INTEGER(KIND=4), PARAMETER :: fomp_sched_guided = 3 + INTEGER(KIND=4), PARAMETER :: fomp_sched_auto = 4 +#endif + +END MODULE omp_constants + + +FUNCTION fomp_enabled() + + IMPLICIT NONE + + !f2py threadsafe + + LOGICAL :: fomp_enabled + +#ifdef _OPENMP + fomp_enabled = .TRUE. +#else + fomp_enabled = .FALSE. +#endif + +END FUNCTION fomp_enabled + + +SUBROUTINE fomp_set_num_threads(num_threads) +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER, INTENT(IN) :: num_threads + +#ifdef _OPENMP + CALL omp_set_num_threads(num_threads) +#else + IF (.FALSE.) PRINT *, num_threads +#endif + + +END SUBROUTINE fomp_set_num_threads + + +FUNCTION fomp_get_num_threads() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_num_threads + +#ifdef _OPENMP + fomp_get_num_threads = omp_get_num_threads() +#else + fomp_get_num_threads = -1 +#endif + +END FUNCTION fomp_get_num_threads + + +FUNCTION fomp_get_max_threads() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_max_threads + +#ifdef _OPENMP + fomp_get_max_threads = omp_get_max_threads() +#else + fomp_get_max_threads = -1 +#endif + +END FUNCTION fomp_get_max_threads + + +FUNCTION fomp_get_thread_num() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_thread_num + +#ifdef _OPENMP + fomp_get_thread_num = omp_get_thread_num() +#else + fomp_get_thread_num = -1 +#endif + +END FUNCTION fomp_get_thread_num + + +FUNCTION fomp_get_num_procs() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_num_procs + +#ifdef _OPENMP + fomp_get_num_procs = omp_get_num_procs() +#else + fomp_get_num_procs = -1 +#endif + +END FUNCTION fomp_get_num_procs + + +FUNCTION fomp_in_parallel() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + LOGICAL :: fomp_in_parallel + +#ifdef _OPENMP + fomp_in_parallel = omp_in_parallel() +#else + fomp_in_parallel = .FALSE. +#endif + +END FUNCTION fomp_in_parallel + + +SUBROUTINE fomp_set_dynamic(dynamic_threads) +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + LOGICAL, INTENT(IN) :: dynamic_threads + +#ifdef _OPENMP + CALL omp_set_dynamic(dynamic_threads) +#else + IF (.FALSE.) PRINT *, dynamic_threads +#endif + +END SUBROUTINE fomp_set_dynamic + + +FUNCTION fomp_get_dynamic() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + LOGICAL :: fomp_get_dynamic + +#ifdef _OPENMP + fomp_get_dynamic = omp_get_dynamic() +#else + fomp_get_dynamic = .FALSE. +#endif + +END FUNCTION fomp_get_dynamic + + +SUBROUTINE fomp_set_nested(nested) +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + LOGICAL, INTENT(IN) :: nested + +#ifdef _OPENMP + CALL omp_set_nested(nested) +#else + IF (.FALSE.) PRINT *, nested +#endif + +END SUBROUTINE fomp_set_nested + + +FUNCTION fomp_get_nested() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + LOGICAL :: fomp_get_nested + +#ifdef _OPENMP + fomp_get_nested = omp_get_nested() +#else + fomp_get_nested = .FALSE. +#endif + +END FUNCTION fomp_get_nested + + +SUBROUTINE fomp_set_schedule(kind, modifier) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_sched_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_sched_kind), INTENT(IN) :: kind + INTEGER, INTENT(IN) :: modifier + +#ifdef _OPENMP + CALL omp_set_schedule(kind, modifier) +#else + IF (.FALSE.) PRINT *, kind, modifier +#endif + +END SUBROUTINE fomp_set_schedule + + +SUBROUTINE fomp_get_schedule(kind, modifier) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_sched_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_sched_kind), INTENT(OUT) :: kind + INTEGER, INTENT(OUT) :: modifier + +#ifdef _OPENMP + CALL omp_get_schedule(kind, modifier) +#else + kind = -1 + modifier = -1 +#endif + +END SUBROUTINE fomp_get_schedule + + +FUNCTION fomp_get_thread_limit() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_thread_limit + +#ifdef _OPENMP + fomp_get_thread_limit = omp_get_thread_limit() +#else + fomp_get_thread_limit = -1 +#endif + +END FUNCTION fomp_get_thread_limit + + +SUBROUTINE fomp_set_max_active_levels(max_levels) +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER, INTENT(IN) :: max_levels + +#ifdef _OPENMP + CALL omp_set_max_active_levels(max_levels) +#else + IF (.FALSE.) PRINT *, max_levels +#endif + +END SUBROUTINE fomp_set_max_active_levels + + +FUNCTION fomp_get_max_active_levels() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_max_active_levels + +#ifdef _OPENMP + fomp_get_max_active_levels = omp_get_max_active_levels() +#else + fomp_get_max_active_levels = -1 +#endif + +END FUNCTION fomp_get_max_active_levels + + +FUNCTION fomp_get_level() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_level + +#ifdef _OPENMP + fomp_get_level = omp_get_level() +#else + fomp_get_level = -1 +#endif + +END FUNCTION fomp_get_level + + +FUNCTION fomp_get_ancestor_thread_num(level) +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER, INTENT(IN) :: level + INTEGER :: fomp_get_ancestor_thread_num + +#ifdef _OPENMP + fomp_get_ancestor_thread_num = omp_get_ancestor_thread_num(level) +#else + IF (.FALSE.) PRINT *, level + fomp_get_ancestor_thread_num = -1 +#endif + +END FUNCTION fomp_get_ancestor_thread_num + + +FUNCTION fomp_get_team_size(level) +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER, INTENT(IN) :: level + INTEGER :: fomp_get_team_size + +#ifdef _OPENMP + fomp_get_team_size = omp_get_team_size(level) +#else + IF (.FALSE.) PRINT *, level + fomp_get_team_size = -1 +#endif + +END FUNCTION fomp_get_team_size + + +FUNCTION fomp_get_active_level() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER :: fomp_get_active_level + +#ifdef _OPENMP + fomp_get_active_level = omp_get_active_level() +#else + fomp_get_active_level = -1 +#endif + +END FUNCTION fomp_get_active_level + + +FUNCTION fomp_in_final() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + LOGICAL :: fomp_in_final + +#ifdef _OPENMP + fomp_in_final = omp_in_final() +#else + fomp_in_final = .FALSE. +#endif + +END FUNCTION fomp_in_final + + +SUBROUTINE fomp_init_lock(svar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_lock_kind), INTENT(OUT) :: svar + +#ifdef _OPENMP + CALL omp_init_lock(svar) +#else + svar = -1 +#endif + +END SUBROUTINE fomp_init_lock + + +SUBROUTINE fomp_init_nest_lock(nvar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_nest_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_nest_lock_kind), INTENT(OUT) :: nvar + +#ifdef _OPENMP + CALL omp_init_nest_lock(nvar) +#else + nvar = -1 +#endif + +END SUBROUTINE fomp_init_nest_lock + + +SUBROUTINE fomp_destroy_lock(svar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_lock_kind), INTENT(INOUT) :: svar + +#ifdef _OPENMP + CALL omp_destroy_lock(svar) +#else + IF (.FALSE.) PRINT *, svar +#endif + + +END SUBROUTINE fomp_destroy_lock + + +SUBROUTINE fomp_destroy_nest_lock(nvar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_nest_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_nest_lock_kind), INTENT(INOUT) :: nvar + +#ifdef _OPENMP + CALL omp_destroy_nest_lock(nvar) +#else + IF (.FALSE.) PRINT *, nvar +#endif + +END SUBROUTINE fomp_destroy_nest_lock + + +SUBROUTINE fomp_set_lock(svar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_lock_kind), INTENT(INOUT) :: svar + +#ifdef _OPENMP + CALL omp_set_lock(svar) +#else + IF (.FALSE.) PRINT *, svar +#endif + +END SUBROUTINE fomp_set_lock + + +SUBROUTINE fomp_set_nest_lock(nvar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_nest_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_nest_lock_kind), INTENT(INOUT) :: nvar + +#ifdef _OPENMP + CALL omp_set_nest_lock(nvar) +#else + IF (.FALSE.) PRINT *, nvar +#endif + +END SUBROUTINE fomp_set_nest_lock + + +SUBROUTINE fomp_unset_lock(svar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_lock_kind), INTENT(INOUT) :: svar + +#ifdef _OPENMP + CALL omp_unset_lock(svar) +#else + IF (.FALSE.) PRINT *, svar +#endif + +END SUBROUTINE fomp_unset_lock + + +SUBROUTINE fomp_unset_nest_lock(nvar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_nest_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_nest_lock_kind), INTENT(INOUT) :: nvar + +#ifdef _OPENMP + CALL omp_unset_nest_lock(nvar) +#else + IF (.FALSE.) PRINT *, nvar +#endif + +END SUBROUTINE fomp_unset_nest_lock + + +FUNCTION fomp_test_lock(svar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_lock_kind), INTENT(INOUT) :: svar + LOGICAL :: fomp_test_lock + +#ifdef _OPENMP + fomp_test_lock = omp_test_lock(svar) +#else + IF (.FALSE.) PRINT *, svar + fomp_test_lock = .FALSE. +#endif + + + +END FUNCTION fomp_test_lock + + +FUNCTION fomp_test_nest_lock(nvar) +#ifdef _OPENMP + USE omp_lib +#endif + USE omp_constants, ONLY : fomp_nest_lock_kind + + IMPLICIT NONE + + !f2py threadsafe + + INTEGER(KIND=fomp_nest_lock_kind), INTENT(INOUT) :: nvar + INTEGER :: fomp_test_nest_lock + +#ifdef _OPENMP + fomp_test_nest_lock = omp_test_nest_lock(nvar) +#else + IF (.FALSE.) PRINT *, nvar + fomp_test_nest_lock = -1 +#endif + + + +END FUNCTION fomp_test_nest_lock + + +FUNCTION fomp_get_wtime() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + REAL (KIND=8) :: fomp_get_wtime + +#ifdef _OPENMP + fomp_get_wtime = omp_get_wtime() +#else + fomp_get_wtime = -1 +#endif + + + +END FUNCTION fomp_get_wtime + + +FUNCTION fomp_get_wtick() +#ifdef _OPENMP + USE omp_lib +#endif + + IMPLICIT NONE + + !f2py threadsafe + + REAL (KIND=8) :: fomp_get_wtick + +#ifdef _OPENMP + fomp_get_wtick = omp_get_wtick() +#else + fomp_get_wtick = -1 +#endif + + + +END FUNCTION fomp_get_wtick + +