Repository: numpy/numpy

Issue:
Intel 18 Beta Compiler: -openmp not allowed
All,

I grabbed the Intel 2018 Beta distribution today and went about building the earth system model I work on. In doing so, all our f2py build steps failed because of a change Intel has made. Namely, `-openmp` is no longer a valid option and only `-qopenmp` is allowed.

This affects numpy in `numpy/distutils/intelccompiler.py` and `numpy/distutils/fcompiler/intel.py` where there are hard-coded `-openmp` in option strings. I tried adding `--f90flags=-qopenmp`, but it seemed to just _add_ that flag to the default set and since `-openmp` was there, bang!

It might best to add something like:
```
          v = self.get_version()
          if v and v >= '15.0':
              opt.append('-qopenmp')
          else
              opt.append('-openmp')
```
a la `get_flags_linker_so` since there are always people using old versions of Intel compilers. Intel has been accepting and promoting `-qopenmp` since the Intel 15 days at least, so there's been 3 years of warmup.

I am currently not able to test any changes at present as on the cluster I'm working on (where I have Intel 18 installed) I don't have write access to the Python distribution I can use. I've asked the maintainer for help fixing this locally, but I thought numpy themselves should be made aware.


Discussion:
Thanks for the report. Let us know the results of your experimentation.
@charris this is kind of important, so I added the 1.13.0 release. 
@mathomp4 Any chance that you can get the proposed fix tested soon?

@cgohlke Can you help?
@charris The admin came back yesterday from vacation and I had him hand-change the `-openmp` to `-qopenmp` in `numpy/distutils/intelccompiler.py` and `numpy/distutils/fcompiler/intel.py`. After that change, everything worked well.

I didn't ask him to try the optioned variant mainly because every Intel compiler we use and support--Intel 15 and higher--all support `-qopenmp` so it would have been more work during his stressful day back! 

I'll try and corner him again, but since I can say `-qopenmp` works, it's just python if you want to make a versioned version.

ETA: Also, if you do do a versioned version, you may as well make `-qopenmp` the "else" case. No Intel compiler in the future should use `-openmp`. (Next up: NAG compiler + numpy!)
Hmm, looks like  `-qopenmp` was added in 15.0, which came out in July 2014. That is probably near enough in time that we need to support both options. @rgommers Thoughts?
On Python 2.7 for Windows, Intel <=14.0 is required for compatibility with Visual Studio 2008.
@cgohlke Thanks for the info.
> On Python 2.7 for Windows, Intel <=14.0 is required for compatibility with Visual Studio 2008.

Ouch. Really? On the OS on our cluster, Intel Fortran 14 might work, but anything before that just starts failing in random ways. I've pretty much required 15+. Good catch @cgohlke 
> Ouch. Really?

According to https://software.intel.com/en-us/intel-parallel-studio-xe-compilers-required-microsoft-visual-studio VS2008 support was dropped in compiler 15.0:
```
Intel® Parallel Studio XE 2015 Initial release through update 3 (compiler 15.0) VS2010, VS2012, VS2013 (includes VS2010 Shell)
Intel® Composer XE 2013 SP1 Update 1 or later (compiler 14.0.1) - VS2008, VS2010, VS2012, VS2013 (includes VS2010 Shell)
```
Hmm, we don't use any of the openmp flags for windows. @cgohlke Should we?
> Hmm, we don't use any of the openmp flags for windows.

That's right. No need to worry about Windows then. 

Resolving patch:
diff --git a/numpy/distutils/fcompiler/intel.py b/numpy/distutils/fcompiler/intel.py
--- a/numpy/distutils/fcompiler/intel.py
+++ b/numpy/distutils/fcompiler/intel.py
@@ -56,7 +56,9 @@ def get_flags(self):
         return ['-fPIC']
 
     def get_flags_opt(self):  # Scipy test failures with -O2
-        return ['-xhost -openmp -fp-model strict -O1']
+        v = self.get_version()
+        mpopt = 'openmp' if v and int(v.split('.')[0]) < 15 else 'qopenmp'
+        return ['-xhost -fp-model strict -O1 -{}'.format(mpopt)]
 
     def get_flags_arch(self):
         return []
@@ -120,7 +122,9 @@ def get_flags(self):
         return ['-fPIC']
 
     def get_flags_opt(self):  # Scipy test failures with -O2
-        return ['-openmp -fp-model strict -O1']
+        v = self.get_version()
+        mpopt = 'openmp' if v and int(v.split('.')[0]) < 15 else 'qopenmp'
+        return ['-fp-model strict -O1 -{}'.format(mpopt)]
 
     def get_flags_arch(self):
         return ['']
diff --git a/numpy/distutils/intelccompiler.py b/numpy/distutils/intelccompiler.py
--- a/numpy/distutils/intelccompiler.py
+++ b/numpy/distutils/intelccompiler.py
@@ -17,9 +17,13 @@ class IntelCCompiler(UnixCCompiler):
 
     def __init__(self, verbose=0, dry_run=0, force=0):
         UnixCCompiler.__init__(self, verbose, dry_run, force)
+
+        v = self.get_version()
+        mpopt = 'openmp' if v and int(v.split('.')[0]) < 15 else 'qopenmp'
         self.cc_exe = ('icc -fPIC -fp-model strict -O3 '
-                       '-fomit-frame-pointer -openmp')
+                       '-fomit-frame-pointer -{}').format(mpopt)
         compiler = self.cc_exe
+
         if platform.system() == 'Darwin':
             shared_flag = '-Wl,-undefined,dynamic_lookup'
         else:
@@ -53,9 +57,13 @@ class IntelEM64TCCompiler(UnixCCompiler):
 
     def __init__(self, verbose=0, dry_run=0, force=0):
         UnixCCompiler.__init__(self, verbose, dry_run, force)
+
+        v = self.get_version()
+        mpopt = 'openmp' if v and int(v.split('.')[0]) < 15 else 'qopenmp'
         self.cc_exe = ('icc -m64 -fPIC -fp-model strict -O3 '
-                       '-fomit-frame-pointer -openmp')
+                       '-fomit-frame-pointer -{}').format(mpopt)
         compiler = self.cc_exe
+
         if platform.system() == 'Darwin':
             shared_flag = '-Wl,-undefined,dynamic_lookup'
         else:


Test patch: