ifort optimization O3 leads to inconsistency - optimization

I have a problem with my fortran code when using O3 optimization: The values calculated for the norm of an array changes with and without O3, and is incorrect with O3. The following shows a minimal example of my code
program main
use wavefunction
implicit none
integer(I4B) :: Na, Nb, Npes
complex(DPC), ALLOCATABLE, DIMENSION(:,:,:) :: phi
real(DP), ALLOCATABLE, DIMENSION(:) :: normPerPes1
real(DP) :: sigma
integer(I4B) :: i,j
Na=100
Nb=100
Npes=4
ALLOCATE(phi(Na,Nb,Npes), normPerPes1(Npes))
sigma=10
phi=(0.D0,0.D0)
do i=1,Na
do j=1,Nb
!gaussian on pes 1
phi(i,j,1)=1.D0/(sigma**2*2.D0*pi)*exp(-(dble(i-50)**2+dble(j-50)**2/(2.D0*sigma**2))
end do
end do
!total norm
write(*,*) norm(Na,Nb,Npes,phi)
!norm on each pes
CALL normPerPes(Na,Nb,Npes,phi,NormPerPes1)
write(*,*) NormPerPes1
end program main
which uses the following module
module wavefunction
use nrtype
implicit none
contains
function norm(Na,Nb,Npes, phi)
implicit none
INTEGER(I4B), INTENT(IN) :: Na, Nb, Npes
COMPLEX(DPC), INTENT(IN) :: phi(Na,Nb,Npes)
REAL(DP) :: norm
INTEGER(I4B) :: i,j, pesNr
norm=0.D0
do i=1,Na
do j=1,Nb
do pesNr=1, Npes
norm=norm+abs(phi(i,j,pesNr))**2
end do
end do
end do
end function norm
!----------------------------------------------------------
subroutine normPerPes(Na, Nb, Npes, phi, normPerPes1)
IMPLICIT none
REAL(DP) :: normPerPes1(Npes)
INTEGER(I4B), INTENT(IN) :: Na, Nb, Npes
COMPLEX(DPC), INTENT(IN) :: phi(Na,Nb,Npes)
INTEGER(I4B):: i,j,pesNr
normPerPes1=0.0d0
do i=1,Na
do j=1,Nb
do pesNr=1,Npes
normPerPes1(pesNr)=normPerPes1(pesNr)+abs(phi(i,j,pesNr))**2
end do
end do
end do
return
end subroutine normPerPes
!-----------------------------------------------------------
end module wavefunction
if I compile with the following Makefile
# compiler
FC = ifort
# flags
FFLAGS = # -O3
main: main.o nrtype.o wavefunction.o
main.o: main.f90 nrtype.o wavefunction.o
wavefunction.o: wavefunction.f90 nrtype.o
nrtype.o: nrtype.f90
%: %.o
$(FC) $(FFLAGS) -o dynamic $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FFLAGS) -c $<
clean:
rm -f *.o *.mod *_genmod.f90
I get the following correct output:
7.957747154568253E-004
7.957747154568242E-004 0.000000000000000E+000 0.000000000000000E+000
0.000000000000000E+000
However, if I use O3 then I obtain the following incorrect result
7.957747154568253E-004
1.989436788642788E-004 0.000000000000000E+000 0.000000000000000E+000
0.000000000000000E+000
This looks to me as there were something seriously fishy in my code, but I can't seem to find the problem. Thank you for your help!

As confirmed by Intel (see https://software.intel.com/en-us/forums/topic/516819), this is a problem of the compiler version used ( Composer XE 2013 SP1 initial release (pkg. 080) ).
They claim that upgrading to Update 2 or 3 helps - I was not able to try yet.
In the mean while a workaround is to forget about O3 and use O2 optimization.

Related

pandas installation failed with Error "ERROR: No matching distribution found for pandas" from setup.py

I'm tying to build a package which required pandas, numpy and scikit-learn as dependency. so i have added the dependencies in my setup.py as below.
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name='dest',
version='0.0.18',
author="Manikandan Jeyabal",
author_email="ManikandanJeyabal029#gmail.com",
description="Test Project creation",
long_description=long_description,
long_description_content_type="text/markdown",
packages=setuptools.find_packages(),
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
install_requires=[
"numpy <=1.17.4", "pandas", "scikit-learn >= 0.21.3, <= 0.22"
],
python_requires='>=3.7'
)
but unfortunately pandas installation failed with error for below cases
1) "pandas" -> ERROR: No matching distribution found for pandas
2) "pandas == 0.25.3" -> ERROR: No matching distribution found for pandas==0.25.3
3) "pandas >=0.25, <=1.0.0" -> ERROR: No matching distribution found for pandas>=0.25, <=1.0.0
Please help me to overcome this issue.
Regards,
MJ

Fortran DLL error when using a multivariable function

I am currently developping a fortran DLL and I have a problem about multi-variable functions. My final objective are to
call the DLL functions from VBA
debug the DLL using a fortran code calling the DLL functions
Here is my simplified case:
1. Fortran DLL code
module mod_thermo
implicit none
contains
function y1(x1) result(y) bind(c, name = "Y1")
use iso_c_binding, only : c_double
!GCC$ attributes dllexport, stdcall :: y1
real(c_double) :: x1
real(c_double) :: y
y = 2.d0 * x1
end function
function y2(x1, x2) result(y) bind(c, name = "Y2")
use iso_c_binding, only : c_double
!GCC$ attributes dllexport, stdcall :: y2
real(c_double) :: x1
real(c_double) :: x2
real(c_double) :: y
y = 2.d0 * x1 * x2
end function
end module
2. Fortran DLL compilation options with GCC
Compiler is GCC. Compilations options are:
-static (to avoid dependencies to other dll)
-Wl,--kill-at (VBA related)
-fno-underscoring (VBA related)
Output files are located in the project folder of the fortran code for future debug:
dll_thermo.dll
libdll_thermo.a
libdll_thermo.def
3. Fortran code for DLL testing (interfaces + program)
The DLL is linked to the code by liking library libdll_thermo.a
module mod_thermo
implicit none
interface
function y1(x1) result(y) bind(c,name="Y1")
use iso_c_binding, only : c_double
real(c_double) :: x1
real(c_double) :: y
end function
function y2(x1, x2) result(y) bind(c,name="Y2")
use iso_c_binding, only : c_double
real(c_double) :: x1
real(c_double) :: x2
real(c_double) :: y
end function
end interface
end module
program main
use mod_thermo
implicit none
write(*,*)"y1 calls:"
write(*,*)y1(1.d0) ! output ok
write(*,*)y1(2.d0) ! output ok
write(*,*)y1(3.d0) ! output ok
write(*,*)"y2 calls:"
write(*,*)y2(1.d0, 1.d0) ! output ok
write(*,*)y2(2.d0, 2.d0) ! output fails
write(*,*)y2(3.d0, 2.d0)
end program
4. Output and conclusion
My conclusion is that I do not perform the multivariable DLL function y2 call in a correct way. What would be your way to perform such calls ?
The problem came from the link to "libdll_thermo.a". Following tutorial from here, I found out that I should have linked "libdll_thermo.dll". Now it works.

Julia #eval world age missmatch

I'm trying to use the julia #eval functionality to only load the PyPlot package on demand. However I verry often run into world age missmatch.
Here is a minimal example where i try and plot on demand
function CreateMatrix(Ncount;Plot=true)
TheMatrix = fill(0.0,Ncount,Ncount)
if Plot
#eval using PyPlot
###"Plot the Matrix"
PyPlot.figure()
PyPlot.imshow(abs.(TheMatrix))
PyPlot.colorbar()
end
return TheMatrix
end
CreateMatrix(10;Plot=false)
CreateMatrix(10;Plot=true)
With the output
ERROR: LoadError: MethodError: no method matching figure()
The applicable method may be too new: running in world age 25063, while current world is 25079.
Closest candidates are:
figure(!Matched::Any...; kws...) at ~/.julia/packages/PyPlot/fZuOQ/src/PyPlot.jl:148 (method too new to be called from this world context.)
Stacktrace:
[1] #CreateMatrix#3(::Bool, ::Function, ::Int64) at myfile.jl:7
[2] (::getfield(Main, Symbol("#kw##CreateMatrix")))(::NamedTuple{(:Plot,),Tuple{Bool}}, ::typeof(CreateMatrix), ::Int64) at ./none:0
[3] top-level scope at none:0
[4] include at ./boot.jl:317 [inlined]
[5] include_relative(::Module, ::String) at ./loading.jl:1044
[6] include(::Module, ::String) at ./sysimg.jl:29
[7] exec_options(::Base.JLOptions) at ./client.jl:231
[8] _start() at ./client.jl:425
in expression starting at myfile.jl:16
Does anyone know how uses the #eval functionality properly?
EDIT
One of the comments suggested wrapping the plotting command and annotating with #noinline as below, but this does not work.
function CreateMatrix(Ncount;Plot=false)
TheMatrix = fill(0.0,Ncount,Ncount)
if Plot
#eval using PyPlot
###"Plot the Matrix"
ThePlotting(TheMatrix)
end
return TheMatrix
end
#noinline function ThePlotting(TheMatrix)
PyPlot.figure()
PyPlot.imshow(abs.(TheMatrix))
PyPlot.colorbar()
end
CreateMatrix(10;Plot=false)
CreateMatrix(10;Plot=true)
I'm running julia version 1.0.2
You can implement it like this:
function CreateMatrix(Ncount;Plot=true)
TheMatrix = fill(0.0,Ncount,Ncount)
if Plot
if isdefined(Main, :PyPlot)
println("PyPlot already loaded")
PyPlot.figure()
PyPlot.imshow(abs.(TheMatrix))
PyPlot.colorbar()
else
println("PyPlot loading PyPlot")
#eval using PyPlot
Base.invokelatest(PyPlot.figure)
Base.invokelatest(PyPlot.imshow, abs.(TheMatrix))
Base.invokelatest(PyPlot.colorbar)
end
end
return TheMatrix
end
I have used conditional to allow you to see which branch gets executed on repeated call to the function.
Initially I thought that when calling non-inlined function Julia allows world age change (but it turns out that it is strict).
Finally - in general it is probably safer not to write code like this but simply load the module in top-level scope (possibly conditionally).

Julia PyPlot can't create quadratic function

I'm trying to learn to plot things with Julia using PyPlot, and I tried to plot a quadratic function. It does not like how I'm squaring x. I tried using x**2 and x*x, and the compiler did not accept those either. What should I be using to square x?
Thanks
Code # line 7:
x1 = linspace(0,4*pi, 500); y1 = x^2
Error:
LoadError: MethodError: `*` has no method matching *(::LinSpace{Float64},
::LinSpace{Float64})
Closest candidates are:
*(::Any, ::Any, !Matched::Any, !Matched::Any...)
*{T}(!Matched::Bidiagonal{T}, ::AbstractArray{T,1})
*(!Matched::Number, ::AbstractArray{T,N})
...
in power_by_squaring at intfuncs.jl:80
in ^ at intfuncs.jl:108
in include_string at loading.jl:282
in include_string at C:\Users\User\.julia\v0.4\CodeTools\src\eval.jl:32
in anonymous at C:\Users\User\.julia\v0.4\Atom\src\eval.jl:84
in withpath at C:\Users\User\.julia\v0.4\Requires\src\require.jl:37
in withpath at C:\Users\User\.julia\v0.4\Atom\src\eval.jl:53
[inlined code] from C:\Users\User\.julia\v0.4\Atom\src\eval.jl:83
in anonymous at task.jl:58
while loading C:\Users\User\Desktop\Comp Sci\Class\plotTest, in expression
starting on line 7
To square every element of an array, use x.^2.
You are trying to square all of the elements of an array. This means you need to use the element-wise version x.^2.

Conversion of a python variable to a real*16 fortran one

I'm writing a code in Python that calls some subroutines written in Fortran. When the variables are defined in Fortran as:
real*8, intent(in) :: var1,var2
and, respectively in Python,
var1 = 1.0
var1 = 1.0
everything is fine. But if I define an extended real, that is:
real*16, intent(in) :: var1,var2
and in python use
import numpy as np
var1 = np.float16(2)
var2 = np.float16(2)
the variables take a strange number when passing them to the fortran routine. Can anyone see what I'm doing wrong?
This numpy-discussion thread from last year indicates that numpy's quadruple precision varies form machine to machine. My guess is that your bunk data comes from two different language's inconsistency as to what quad-precision means.
Note also that f2py really only understands <type>(kind=<precision>) where <type> is REAL/INTEGER/COMPLEX and <precision> is an integer 1, 2, 4, 8 (cf the FAQ).