New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong fortran source creation floating point operations (not double) #3053
Comments
Do you mean constants, not variables? I'm not a Fortran programmer! As I understand it, I just did a bit of searching through Fortran documentation. It appears that the |
Yes. Only constants. Fortran interprets all
That is not true. ! Only one of the following 3
integer, parameter :: dp = 8
! Preferably it should be (this will make the kind specification determined for the architecture at compile time)
integer, parameter :: dp = kind(1.d0)
! or even
integer, parameter :: dp = selected_real_kind(15)
! Now all constants may be defined through:
real(dp), parameter :: pi = 3.141_dp This is the proper way to do it. I would highly suggest you don't use the explicit It is true that Note also that all
This is not true. All fortran compilers accept this standardized format. What you'll probably find are various named parameters Note, that all the same considerations apply to your |
Ok, thanks. If you want to submit a PR, it would be welcome! |
Sorry, I have no clue how to change your automatic build up :( Hope you'll get somebody to do it ;) |
Here's the code that generates the global constants: openmm/wrappers/generateWrappers.py Lines 903 to 912 in 7c2e599
The last line in that function just needs to be modified to write out the value in whatever is the correct way. |
Sorry, I don't have the time to delve into and debug in a new code. Hope you get the time eventually. |
The fix is in #3264. Could you take a look and verify that it looks correct? With this change, here is how the constants get defined. MODULE OpenMM_Types
implicit none
! Global Constants
real*8, parameter :: OpenMM_NmPerAngstrom = 0.1_8
real*8, parameter :: OpenMM_AngstromsPerNm = 10.0_8
real*8, parameter :: OpenMM_PsPerFs = 0.001_8
real*8, parameter :: OpenMM_FsPerPs = 1000.0_8
real*8, parameter :: OpenMM_KJPerKcal = 4.184_8
real*8, parameter :: OpenMM_KcalPerKJ = 1.0_8/4.184_8
real*8, parameter :: OpenMM_RadiansPerDegree = 3.1415926535897932385_8/180.0_8
real*8, parameter :: OpenMM_DegreesPerRadian = 180.0_8/3.1415926535897932385_8
real*8, parameter :: OpenMM_SigmaPerVdwRadius = 1.7817974362806786095_8
real*8, parameter :: OpenMM_VdwRadiusPerSigma = .56123102415468649070_8 |
Looks MUCH better! I would probably do something like this to have it portable: def writeGlobalConstants(self):
self.out.write(" ! Global Constants\n\n")
self.out.write(" integer, parameter :: dp = kind(1.d0)\n")
node = next((x for x in findNodes(self.doc.getroot(), "compounddef", kind="namespace") if x.findtext("compoundname") == "OpenMM"))
for section in findNodes(node, "sectiondef", kind="var"):
for memberNode in findNodes(section, "memberdef", kind="variable", mutable="no", prot="public", static="yes"):
vDef = convertOpenMMPrefix(getText("name", memberNode))
iDef = getText("initializer", memberNode)
if iDef.startswith("="):
iDef = iDef[1:]
self.out.write(" real(dp), parameter :: OpenMM_%s = %s\n" % (vDef, iDef)) and then with the fixes you have made, so everything is suffixed with |
Wouldn't that have the same problem as the original, that the constants get interpreted as single precision before being assigned to the double precision variable? |
Oh, I see. I missed the note about also adding The difference you're suggesting is to support platforms where double precision has a width different than 8 bytes? We don't support any such platforms. I worry that might create problems where the C++ compiler sets the width of double to 8 bytes, but the Fortran compiler sets it to something else. |
The value So this is about compiler compatibility. Some compilers may use |
Does that mean I should change all occurences of |
This page clarifies the situation a little, but not entirely. If I understand correctly, prior to Fortran 2008 there is no way to do what I described? According to https://www.charmm-gui.org/charmmdoc/developer.html, CHARMM is still on Fortran 77(!). Tinker is on Fortran 95. |
In principle yes. In practice it is, generally, not required. Sorry about the confusion created ;) Generally What is important is the My eyes just hurt at seeing Also note that since you are using modules you are using f90, so the kind specification is already enforced by convention. |
Got it, thanks. I just pushed the changes. Here's what the definition looks like now. MODULE OpenMM_Types
implicit none
! Global Constants
integer, parameter :: dp = kind(1.d0)
real*8, parameter :: OpenMM_NmPerAngstrom = 0.1_dp
real*8, parameter :: OpenMM_AngstromsPerNm = 10.0_dp
real*8, parameter :: OpenMM_PsPerFs = 0.001_dp
real*8, parameter :: OpenMM_FsPerPs = 1000.0_dp
real*8, parameter :: OpenMM_KJPerKcal = 4.184_dp
real*8, parameter :: OpenMM_KcalPerKJ = 1.0_dp/4.184_dp
real*8, parameter :: OpenMM_RadiansPerDegree = 3.1415926535897932385_dp/180.0_dp
real*8, parameter :: OpenMM_DegreesPerRadian = 180.0_dp/3.1415926535897932385_dp
real*8, parameter :: OpenMM_SigmaPerVdwRadius = 1.7817974362806786095_dp
real*8, parameter :: OpenMM_VdwRadiusPerSigma = .56123102415468649070_dp
Only the principle of not fixing something that isn't broken. No one has ever reported problems with |
Great, I am happy! ;) |
Thanks! I'll merge it as soon as the tests finish. |
I can see your fortran interface wrappers create faulty variables.
openmm/wrappers/generateWrappers.py
Line 881 in 3aa4bb8
I just built 7.4.2 and got this output:
This is really bad practice ;)
check this output:
the output will be something like this:
The same applies to your arithmetic operations, they are done in floating point precision (not double).
You really need all real variables to be suffixed with
_8
where you are using doubles.The text was updated successfully, but these errors were encountered: