From 91e845ef98eb2d7c60accad0308b21a76d958412 Mon Sep 17 00:00:00 2001 From: Bill Ladwig Date: Thu, 25 Jan 2018 16:21:04 -0700 Subject: [PATCH] Updated build scripts. Since the size of OpenMP constants differs from system to system, there is now a fortran program that will print the KIND sizes, and the ompgen.F90 file is generated by python using a string template. This only needs to be performed if using OpenMP. --- build_scripts/gnu_omp.sh | 6 +- build_scripts/win_mingw_omp.bat | 6 +- build_scripts/win_msvc_mingw_omp.bat | 6 +- conda_recipe/bld.bat | 6 +- conda_recipe/build.sh | 6 +- conda_recipe/meta.yaml | 5 +- doc/source/installation.rst | 10 +- fortran/build_help/omp_sizes.f90 | 14 + fortran/build_help/sizes | Bin 0 -> 8944 bytes fortran/build_help/sub_sizes.py | 40 ++ fortran/ompgen.F90 | 65 +-- fortran/ompgen.F90.template | 715 +++++++++++++++++++++++++++ 12 files changed, 813 insertions(+), 66 deletions(-) create mode 100644 fortran/build_help/omp_sizes.f90 create mode 100755 fortran/build_help/sizes create mode 100644 fortran/build_help/sub_sizes.py create mode 100644 fortran/ompgen.F90.template 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..75330f6 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..c2a91d1 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 c22a760..e8702a1 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -5,9 +5,8 @@ package: version: {{ version }} source: - fn: wrf-python-{{ version }}.tar.gz - url: https://github.com/NCAR/wrf-python/archive/{{ version }}.tar.gz - sha256: 9ca11366ed9a0d5e83e576ac80ce36be4748ba8a06752dac077277acec5e46d9 + git_url: https://github.com/NCAR/wrf-python + git_branch: develop package: name: wrf-python 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/sizes b/fortran/build_help/sizes new file mode 100755 index 0000000000000000000000000000000000000000..2be4af52a4e016614d156b72246e39da6c6c9c01 GIT binary patch literal 8944 zcmeHNU1(fI6rN3!G_C#F+ESvmuq{nV1vjZRnnH_-G<2h}rcEo-J`9`Po9ycTdG8JV z0U;t0LkaXjMJGx_fCKklp)BC$e<=@ucxMwEJ+5Hli$mJs)$WKg6W9XvR6eCWtC>Q z%r@kR(+vkw9vyn_XjnzrC&PV0^N39#9MP`DQrgBT+t-carSHLDAT}`|68R9dis>LP zrDaczTX(ync<-%q@pfnpkM|5ZG@c(H@npd$)eI9#QM@lT-iQVu&%EEICGq7f+bmWl zwL%mxx!#QrFp9_rDTEDyl(}lf@)H=vOKChWKJu+Wz(`w4qaY{DY}s%HQM{VQdrjMs z*HaTga#^mEI*ODB29FK~RInaG>%?0xfptP$Z@f}gO42%A9

U%{G_C^I*8%f^l&^ zy*XtRQkJs+g_ndq$pQn+=u^OjSL@pYUseQ_fDiD;{;Dy)B_`q%7f|^ zVmsbjz4z%h6@vcxx}H z!@d;C8kC+X%j_u?$9wXpOL_35Ehvn`*;37oyt(J%>(^FP|4Loo$@dJY6D!xOhVg3g zpyp92>c)6!my0;1pMDg|7`wY_Tg8A`%i0BcpPZ_?Q>p&K-Hc zu3E08cY8KbKP~&NB1H**j6fbcZP`XS{e)*jPqfQ~{3O7^?wDnmR!=FLKUtjYDHkh6 zyr22(!zy2lI+v4{?_S}A$LZqu@xC~f&6hFebZ^lAPIzNpJ277!sCQ|e>ma5$191l8 z48$2|mVslL*&CUcZ~cnj+{|3tWqjZ>voqay9A{ys7f)_f7iLmuO{>-pw77}L%&E@I z>_WYtHZD6)^~_w~+X`l(zRMR;bCY7*UQp7269P7Ias}To&j~-^aI#N3`NkK~$w!K9 zYmYkNC%=i4ijOqUFAAJoXBSWnUqtpv*U9@z8W;(!nmAeIBY95FD42yhKl6da-f-t+ zU)0H}=1x9PrfQ1jb-K1{C+B?;M>6d?`H59<;;~n0Hj>AEB+to31+!3p)ECjo7R9!i zN*YKPw`fh$^)pl=6MsTG`Q8`N$tQ|!TN`!4eM%E2Q$CV6l56Y&YRMOoJq-5iFVsu( z%B|$=OSdz#Q;V6i#}>~Hp?MV=Ta`iISExScnycT-#~ZgD=TkIb>~uYk5S^})dREl4 zrk>1?(`Dm1GPiXmk(V3N*d>yW=>8``P-1t;g8mR9zxZEx*G4I?ll+VM|^^Z2PD?Pn)xi5+*1 zzMax(@c0q?YI?k;>$24^I`D#UpdqZMg*jW>XDRYIana$Z~-397ztXZts#$-TG zCp;nXe*`VET#&{oBR6FmxTDWRev`rO$L2$r4aMmpgc aUb1fG(}Tl@q!dyImF`dP-rLK>gZ>3(b0{|e literal 0 HcmV?d00001 diff --git a/fortran/build_help/sub_sizes.py b/fortran/build_help/sub_sizes.py new file mode 100644 index 0000000..10aa3a3 --- /dev/null +++ b/fortran/build_help/sub_sizes.py @@ -0,0 +1,40 @@ +import subprocess +import os +from string import Template + +def main(): + + print ("Running sub_sizes") + result = subprocess.check_output(["./sizes"]) + + split_result = result.split() + + 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 60fb080..14fa7d4 100644 --- a/fortran/ompgen.F90 +++ b/fortran/ompgen.F90 @@ -1,70 +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. - ! linux on conda-forge uses 4, 4, 8 for some reason -#if defined(__GFORTRAN__) -#if (__SIZEOF_POINTER__ == 8) -#if defined(__linux__) - ! Will make this better in the future, for now on conda-forge, this - ! is what they're using - INTEGER, PARAMETER :: fomp_sched_kind = 4 - INTEGER, PARAMETER :: fomp_lock_kind = 4 - INTEGER, PARAMETER :: fomp_nest_lock_kind = 8 -#else - INTEGER, PARAMETER :: fomp_sched_kind = 4 - INTEGER, PARAMETER :: fomp_lock_kind = 8 - INTEGER, PARAMETER :: fomp_nest_lock_kind = 8 -#endif -#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 + +