diff --git a/build_scripts/chey_intel_mkl_omp.sh b/build_scripts/chey_intel_mkl_omp.sh new file mode 100644 index 0000000..ee40614 --- /dev/null +++ b/build_scripts/chey_intel_mkl_omp.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +cd ../fortran/build_help +ifort -o sizes -qopenmp omp_sizes.f90 +python sub_sizes.py + +cd .. +ifort ompgen.F90 -qopenmp -fpp -save-temps > /dev/null 2>&1 +mv ompgen.i90 omp.f90 +f2py *.f90 -m _wrffortran -h wrffortran.pyf --overwrite-signature +cd .. + +python setup.py clean --all +python setup.py config_fc --f90flags="-xHost -mkl -qopenmp" build_ext --rpath="/glade/u/apps/opt/intel/2017u1/compilers_and_libraries/linux/lib/intel64_lin:/glade/u/apps/opt/intel/2017u1/compilers_and_libraries/linux/mkl/lib/intel64_lin" --library-dirs="/glade/u/apps/opt/intel/2017u1/compilers_and_libraries/linux/lib/intel64_lin:/glade/u/apps/opt/intel/2017u1/compilers_and_libraries/linux/mkl/lib/intel64_lin" --libraries="mkl_intel_ilp64 mkl_intel_thread mkl_core iomp5 pthread m dl" build --compiler=intelem --fcompiler=intelem bdist_wheel + +#pip install . + diff --git a/chey_intel.py b/chey_intel.py new file mode 100644 index 0000000..78d194f --- /dev/null +++ b/chey_intel.py @@ -0,0 +1,219 @@ +# http://developer.intel.com/software/products/compilers/flin/ +from __future__ import division, absolute_import, print_function + +import sys + +from numpy.distutils.ccompiler import simple_version_match +from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file + +compilers = ['IntelFCompiler', 'IntelVisualFCompiler', + 'IntelItaniumFCompiler', 'IntelItaniumVisualFCompiler', + 'IntelEM64VisualFCompiler', 'IntelEM64TFCompiler'] + + +def intel_version_match(type): + # Match against the important stuff in the version string + return simple_version_match(start=r'Intel.*?Fortran.*?(?:%s).*?Version' % (type,)) + + +class BaseIntelFCompiler(FCompiler): + def update_executables(self): + f = dummy_fortran_file() + self.executables['version_cmd'] = ['', '-FI', '-V', '-c', + f + '.f', '-o', f + '.o'] + + def runtime_library_dir_option(self, dir): + return '-Wl,-rpath="%s"' % dir + + +class IntelFCompiler(BaseIntelFCompiler): + + compiler_type = 'intel' + compiler_aliases = ('ifort',) + description = 'Intel Fortran Compiler for 32-bit apps' + version_match = intel_version_match('32-bit|IA-32') + + possible_executables = ['ifort', 'ifc'] + + executables = { + 'version_cmd' : None, # set by update_executables + 'compiler_f77' : [None, "-72", "-w90", "-w95"], + 'compiler_f90' : [None], + 'compiler_fix' : [None, "-FI"], + 'linker_so' : ["", "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + pic_flags = ['-fPIC'] + module_dir_switch = '-module ' # Don't remove ending space! + module_include_switch = '-I' + + def get_flags_free(self): + return ['-FR'] + + def get_flags(self): + return ['-fPIC'] + + def get_flags_opt(self): # Scipy test failures with -O2 + v = self.get_version() + mpopt = '' + return ['-fp-model strict -O2'] + + def get_flags_arch(self): + return [] + + def get_flags_linker_so(self): + opt = FCompiler.get_flags_linker_so(self) + v = self.get_version() + if v and v >= '8.0': + opt.append('-nofor_main') + if sys.platform == 'darwin': + # Here, it's -dynamiclib + try: + idx = opt.index('-shared') + opt.remove('-shared') + except ValueError: + idx = 0 + opt[idx:idx] = ['-dynamiclib', '-Wl,-undefined,dynamic_lookup'] + return opt + + +class IntelItaniumFCompiler(IntelFCompiler): + compiler_type = 'intele' + compiler_aliases = () + description = 'Intel Fortran Compiler for Itanium apps' + + version_match = intel_version_match('Itanium|IA-64') + + possible_executables = ['ifort', 'efort', 'efc'] + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None, "-FI", "-w90", "-w95"], + 'compiler_fix' : [None, "-FI"], + 'compiler_f90' : [None], + 'linker_so' : ['', "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + +class IntelEM64TFCompiler(IntelFCompiler): + compiler_type = 'intelem' + compiler_aliases = () + description = 'Intel Fortran Compiler for 64-bit apps' + + version_match = intel_version_match('EM64T-based|Intel\\(R\\) 64|64|IA-64|64-bit') + + possible_executables = ['ifort', 'efort', 'efc'] + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None, "-FI"], + 'compiler_fix' : [None, "-FI"], + 'compiler_f90' : [None], + 'linker_so' : ['', "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags(self): + return ['-fPIC'] + + def get_flags_opt(self): # Scipy test failures with -O2 + v = self.get_version() + mpopt = '' + return ['-fp-model strict -O2'] + + def get_flags_arch(self): + return [''] + +# Is there no difference in the version string between the above compilers +# and the Visual compilers? + + +class IntelVisualFCompiler(BaseIntelFCompiler): + compiler_type = 'intelv' + description = 'Intel Visual Fortran Compiler for 32-bit apps' + version_match = intel_version_match('32-bit|IA-32') + + def update_executables(self): + f = dummy_fortran_file() + self.executables['version_cmd'] = ['', '/FI', '/c', + f + '.f', '/o', f + '.o'] + + ar_exe = 'lib.exe' + possible_executables = ['ifort', 'ifl'] + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None], + 'compiler_fix' : [None], + 'compiler_f90' : [None], + 'linker_so' : [None], + 'archiver' : [ar_exe, "/verbose", "/OUT:"], + 'ranlib' : None + } + + compile_switch = '/c ' + object_switch = '/Fo' # No space after /Fo! + library_switch = '/OUT:' # No space after /OUT:! + module_dir_switch = '/module:' # No space after /module: + module_include_switch = '/I' + + def get_flags(self): + opt = ['/nologo', '/MD', '/nbs', '/names:lowercase', '/assume:underscore'] + return opt + + def get_flags_free(self): + return [] + + def get_flags_debug(self): + return ['/4Yb', '/d2'] + + def get_flags_opt(self): + return ['/O1'] # Scipy test failures with /O2 + + def get_flags_arch(self): + return ["/arch:IA32", "/QaxSSE3"] + + def runtime_library_dir_option(self, dir): + raise NotImplementedError + + +class IntelItaniumVisualFCompiler(IntelVisualFCompiler): + compiler_type = 'intelev' + description = 'Intel Visual Fortran Compiler for Itanium apps' + + version_match = intel_version_match('Itanium') + + possible_executables = ['efl'] # XXX this is a wild guess + ar_exe = IntelVisualFCompiler.ar_exe + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None, "-FI", "-w90", "-w95"], + 'compiler_fix' : [None, "-FI", "-4L72", "-w"], + 'compiler_f90' : [None], + 'linker_so' : ['', "-shared"], + 'archiver' : [ar_exe, "/verbose", "/OUT:"], + 'ranlib' : None + } + + +class IntelEM64VisualFCompiler(IntelVisualFCompiler): + compiler_type = 'intelvem' + description = 'Intel Visual Fortran Compiler for 64-bit apps' + + version_match = simple_version_match(start=r'Intel\(R\).*?64,') + + def get_flags_arch(self): + return [''] + + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='intel').get_version()) diff --git a/conda_recipe/build.sh b/conda_recipe/build.sh index eefecaf..feace2b 100644 --- a/conda_recipe/build.sh +++ b/conda_recipe/build.sh @@ -1,12 +1,16 @@ #!/bin/bash cd fortran/build_help -gfortran -o sizes -fopenmp omp_sizes.f90 +if [ `uname` == Darwin ]; then + gfortran -o sizes -fopenmp omp_sizes.f90 -Wl,-rpath,${CONDA_PREFIX}/lib +else + gfortran -o sizes -fopenmp omp_sizes.f90 +fi python sub_sizes.py cd .. gfortran -E ompgen.F90 -fopenmp -cpp -o omp.f90 -f2py *.f90 -m _wrffortran -h wrffortran.pyf --overwrite-signature +f2py *.f90 -m _wrffortran -h wrffortran.pyf --overwrite-signature cd .. if [ `uname` == Darwin ]; then @@ -16,5 +20,3 @@ fi $PYTHON setup.py config_fc --f90flags="-mtune=generic -fopenmp" build_ext --libraries="gomp" build $PYTHON setup.py install --single-version-externally-managed --record=record.txt - - diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index d613f4c..1b83f52 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -6,7 +6,7 @@ package: source: git_url: https://github.com/NCAR/wrf-python - git_branch: release/1.1.0 + git_branch: develop build: number: 0 @@ -56,4 +56,4 @@ extra: - marylhaley - david-ian-brown - khallock - \ No newline at end of file + diff --git a/doc/source/new.rst b/doc/source/new.rst index e2ff9cc..c6f949d 100644 --- a/doc/source/new.rst +++ b/doc/source/new.rst @@ -4,6 +4,19 @@ What's New Releases ------------- +v1.1.1 +^^^^^^^^^^^^^^ + +- Release 1.1.1 +- Added script for building on Cheyenne with maxed out Intel settings, which + also required a patch for numpy.distutils. +- Fixed a few unicode characters hiding in a docstring that were causing + problems on Cheyenne, and also building the docs with Sphinx on Python 2.x. +- Fix issue with np.amax not working with xarray on Cheyenne, causing an error + with the mdbz product. +- Fix cape_2d private variable bug when running with multiple CPUs. + + v1.1.0 ^^^^^^^^^^^^^^ diff --git a/doc/source/tutorials/tutorial_03_2018.rst b/doc/source/tutorials/tutorial_03_2018.rst index 7fb0bb9..f453bbe 100644 --- a/doc/source/tutorials/tutorial_03_2018.rst +++ b/doc/source/tutorials/tutorial_03_2018.rst @@ -6,7 +6,7 @@ NCAR will be providing a four hour tutorial for wrf-python on Wednesday, March only 16 students, so registration is required. The tutorial will take place at NCAR's corporate training center in Boulder, -Colorado. +Colorado. `Corporate Technical Training Center `_ 3085 Center Green Drive, Building CG-2, Room #3024 @@ -15,12 +15,29 @@ Boulder, Colorado Overview -------------- +WRF-Python is a collection of diagnostic and interpolation routines for use +with output from the Weather Research and Forecasting (WRF-ARW) Model. The +package provides over 30 diagnostic calculations, +several interpolation routines, and utilities to help with plotting +via cartopy, basemap, or PyNGL. The functionality is similar to what is +provided by the NCL WRF package. + +.. note:: + + WRF-Python is NOT a tool for running the WRF-ARW model using Python. + This tutorial provides an introduction to wrf-python. The tutorial is beginner -friendly for new users of wrf-python, but this is not an introduction to the Python -programming language (see :ref:`prereq`). Due to limited seating, if you +friendly for new users of wrf-python, but this is NOT an introduction to the +Python programming language (see :ref:`prereq`). Due to limited seating, if you do not have any previous experience with Python, please do not register for this tutorial. +.. note:: + + For online training that provides an introduction to the Python + programming language itself, please see the + `Unidata Python Training Page `_. + Computers will be provided, but feel free to use your own laptop if you prefer. We will be covering how to install wrf-python via conda as part of the tutorial. @@ -47,7 +64,7 @@ Please register prior to February 21, 2018. The registration form is here: `Registration Form `_ -Registration consists of a brief survey, which will help give the instructors +Registration consists of a brief survey, which will help give the instructor a brief overview of your background and will help tailor the tutorial to your expectations. diff --git a/fortran/rip_cape.f90 b/fortran/rip_cape.f90 index c92be3f..5e9cdac 100644 --- a/fortran/rip_cape.f90 +++ b/fortran/rip_cape.f90 @@ -708,7 +708,7 @@ SUBROUTINE DCAPECALC2D(prs,tmk,qvp,ght,ter,sfp,cape,cin,& !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(tlcl, ethpari, & !$OMP zlcl, kk, ilcl, klcl, tmklift, tvenv, tvlift, ghtlift, & !$OMP facden, tmkenv, qvpenv, eslift, qvplift, buoy, benamin, & - !$OMP benaccum, zrel, kmax, dz, elfound, & + !$OMP benaccum, zrel, kmax, dz, elfound, gammam, cpm, e, & !$OMP kel, klfc, pavg, p2, p1, totthe, totqvp, totprs, & !$OMP i, j, k, kpar, kpar1, kpar2, qvppari, tmkpari, p, pup, pdn, th, & !$OMP pp1, pp2, ethmax, eth_temp, klev) SCHEDULE(runtime) diff --git a/setup.py b/setup.py index 41ec9e6..de39044 100755 --- a/setup.py +++ b/setup.py @@ -1,8 +1,26 @@ import os import sys import setuptools -import numpy.distutils.core - +import socket + +if not socket.gethostname().startswith("cheyenne"): + import numpy.distutils.core +else: + import chey_intel + import numpy.distutils.core + import numpy.distutils.fcompiler.intel + + numpy.distutils.fcompiler.intel.IntelFCompiler = chey_intel.IntelFCompiler + numpy.distutils.fcompiler.intel.IntelVisualFCompiler = ( + chey_intel.IntelVisualFCompiler) + numpy.distutils.fcompiler.intel.IntelItaniumFCompiler = ( + chey_intel.IntelItaniumFCompiler) + numpy.distutils.fcompiler.intel.IntelItaniumVisualFCompiler = ( + chey_intel.IntelItaniumVisualFCompiler) + numpy.distutils.fcompiler.intel.IntelEM64VisualFCompiler = ( + chey_intel.IntelEM64VisualFCompiler) + numpy.distutils.fcompiler.intel.IntelEM64TFCompiler = ( + chey_intel.IntelEM64TFCompiler) ext1 = numpy.distutils.core.Extension( name = "wrf._wrffortran", diff --git a/src/wrf/constants.py b/src/wrf/constants.py index 6a6dc90..cedc62a 100755 --- a/src/wrf/constants.py +++ b/src/wrf/constants.py @@ -76,7 +76,7 @@ else: # Add the integers based on python 2.x or 3.x def default_fill(dtype=None): dt = np.dtype(dtype) if dtype is not None else None - return _DEFAULT_FILL_MAP.get(dt, 0) + return _DEFAULT_FILL_MAP.get(dt, Constants.DEFAULT_FILL) diff --git a/src/wrf/extension.py b/src/wrf/extension.py index a3357a3..167d27c 100755 --- a/src/wrf/extension.py +++ b/src/wrf/extension.py @@ -1569,10 +1569,10 @@ def omp_get_wtime(): """Return elapsed wall clock time in seconds. The omp_get_wtime routine returns a value equal to the elapsed wall clock - time in seconds since some “time in the past”. The actual - “time in the past” is arbitrary, but it is guaranteed not to change during + time in seconds since some "time in the past". The actual + "time in the past" is arbitrary, but it is guaranteed not to change during the execution of the application program. The time returned is a - “per-thread time”, so it is not required to be globally consistent across + "per-thread time", so it is not required to be globally consistent across all threads participating in an application. Returns: diff --git a/src/wrf/g_dbz.py b/src/wrf/g_dbz.py index 4c0e71f..f16b6bb 100755 --- a/src/wrf/g_dbz.py +++ b/src/wrf/g_dbz.py @@ -6,7 +6,7 @@ import numpy as np #from .extension import computedbz,computetk from .extension import _dbz, _tk from .constants import Constants -from .util import extract_vars +from .util import extract_vars, to_np from .metadecorators import copy_and_set_metadata @@ -194,7 +194,7 @@ def get_max_dbz(wrfin, timeidx=0, method="cat", be a :class:`numpy.ndarray` object with no metadata. """ - return np.amax(get_dbz(wrfin, timeidx, method, squeeze, cache, meta, - _key, use_varint, use_liqskin), + return np.amax(to_np(get_dbz(wrfin, timeidx, method, squeeze, cache, meta, + _key, use_varint, use_liqskin)), axis=-3) diff --git a/src/wrf/version.py b/src/wrf/version.py index aebf1b8..c5762ad 100644 --- a/src/wrf/version.py +++ b/src/wrf/version.py @@ -1,2 +1,2 @@ -__version__ = "1.1.0" +__version__ = "1.1.1"