-
Notifications
You must be signed in to change notification settings - Fork 184
How should stdlib handle single, double, quadruple precision types #25
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
Comments
My own preference that I have been using is 1. together with a., so 1a. |
I think the most important is to figure out which of 1. - 7. to use. One criteria is verbosity. These kinds are used all over the place every time you declare a real. So using a two character variable is the shortest, which leads to either 1., 6. or 7. The option 6. only works for a "default" real (whatever it is), and option 7. has three characters for quadruple precision. So the option 1. is the only option that allows to select any precision with just two characters. Using the terms single, double and quadruple are well established terms in Fortran, for example Lapack and other codes use the convention in the subroutine names as My next favorite would be 7., as it is two characters for single and double precision, and three characters for quadruple. After that probably 3. and then 2. The 7., 3. and 2. are less clear to read and write, because in Fortran when we talk about precision, most people use the terms single, double and quadruple. It takes time to convert the terms into numbers and to be honest I have to think a bit -- is double precision 8 bytes? How many bytes is quadruple precision? And in Fortran, we typically do not think in terms of how many bits or bytes variables occupy in memory, but rather we think in terms of precision of our numbers. So from this perspective, option 1. is more natural than options 7., 3. or 2. |
This should also consider integer (int32,int64,..). So, in your example, it would be 2-. |
I also like to use built-in type kinds from There have been concerns that the constants from |
Personally, I like options 1a and 1c. |
@milancurcic in that blog post you linked to, Steve Lionel is pretty clear that he recommends not to use the constants from iso_fortran_env. The safest is to define a module, where we define our our constants (option a.), we can call them More generally, tying double and quadruple precision to bytes is artificial. The same with real16 and bfloat16 (also 16bit, but different than real16). Rather, I recommend we provide our numerical code for single, double and quadruple precision (perhaps also half precision and/or bfloat16 later if those types become available) and that we control those kinds and declare them in some module. So option b. Regarding that it is already in the standard: we are designing a standard library. So we can use any of the options above I think if we determine that they are better than what is already in the standard. I think we'll not be able to resolve this quickly. But I do want to move forward. One compromise that would be ok with me right away is: 1b, that is:
and get rid of the |
This is one of things I was trying to address with issue #13. |
I'd suggest avoiding some of the simpler two-character names like One possible solution to management of kinds is to try and identify the available data types which have known hardware implementations, or at least have been defined in some sense (IEEE 754), and then name the kinds after these well-defined formats. The library would then map the kind to the type, and the user could invoke the type unambiguously. For example, descriptive names like This would seem to me to avoid the issues with This is not something that can be done in the language standard, since it strives to be hardware-agnostic, and a user without And if there's any types that I have missed ( |
@certik I am ok with your proposition. It would allow us to move forward in the different modules, while discussing what is the best solution for everyone, and maybe defining a |
@jvdp1 thank you. I'll update the PR #23. (Btw, we should probably call it @marshallward in order to move #23 forward, what do you suggest we do? What names should we use for the kind variables? It seems most people would be ok with
The |
If they're only used internally then there's no issue. I think I misunderstood the issue and had thought that the library would be providing types for users. Within the library there's no objection from me. |
Note: I am going to wait until the list at https://github.com/fortran-lang/stdlib/wiki/List-of-popular-open-source-Fortran-projects is reasonably complete, and then I'll update the information below. I'll use this comment to collect the usage in codes. I put the number of GitHub stars in parentheses. Codes that I know about off top of my head:
Codes found using this search query at GitHub (for some reason this query does not show any of the highly starred projects above...):
I then tried this query:
For some reason the GitHub queries do not return highly starred projects... So I started #28 to ensure the above analysis captures all the popular projects. |
@marshallward initially it would provide these types to users, but above we decided on a compromise that for now it would be internal to |
another factor to consider is that some compilers including GCC 9 can be buggy with quad-precision. Sometimes compile/link errors, sometimes runtime errors. I would consider making real128 be optionally included perhaps as a submodule for everyplace real128 might be a desired kind. The option to include could be manual or a build system check also consider for long term, growing momentum of half-precision float16 in general, including Fortran e.g. NAG. So having a modular approach to kinds may be useful and not burdensome. |
This is certainly a complicated issue. One of the wonderful things about Jin2For is it queries the kind parameter arrays provided by Because of these limitations in Jin2For, I'd prefer to see kinds supported that correspond to standardized floating point (and integer) formats with standardized ABIs like IEEE 754. This way they should exist across all compilers and be more interoperable with C and other languages. My inclination is to go with @certik's proposed 1-3 or 7 but use option c: I also note that care must be taken with approach "a", i.e., |
In my opinion option (c) using |
Hmm, I haven't considered this but I think it's a good point and I agree with it. If this would help non-Fortran projects to more easily interface Fortran stdlib (I think so), we should seriously consider this. |
Would it make sense to put the kinds variables (say |
If we are going to use
|
Let's not forget complex kinds! (and character kinds, but that warrants separate discussion) |
I totally agree. I would guess that most people are implicitly considering complex kinds when discussing reals because the available kinds for complex are the same as for reals, with the same properties (range, precision, epsilon, tiny, huge, etc.) As for character kinds, that's a trickier issue. |
I implemented this latest idea of a |
Proposed changes regarding links, meta-info and specs
When we declare a real variable in our API, we have to use some variable to represent the real kind. Available options for single, double and quadruple precision that people have used in codes:
real(sp)
,real(dp)
,real(qp)
real(real32)
,real(real64)
,real(real128)
real(r32)
,real(r64)
,real(r128)
real(float32)
,real(float64)
,real(float128)
real(f32)
,real(f64)
,real(f128)
real(wp)
(for default real)real(r4)
,real(r8)
,real(r16)
I will keep appending to this list if we find some code that uses different names.
Those variables must be defined somewhere. I will use the case 1. below, for other cases we simply substitute different names. The available options:
a.
stdlib_types
module that providessp
,dp
,qp
for single, double and quadruple precision as follows:The main idea behind this option is that there is a module in
stdlib
that provides the types and every other module uses it. The proposal #13 is similar to it. There are several options how the types are defined inside the module: one can definesp
anddp
usingselected_real_kind
also. Another alternative is to definesp
,dp
andqp
using iso_fortran_env as in b. to a. The modulestdlib_types
can be called differently also.b.
use iso_fortran_env, only: sp=>real32, dp=>real64, qp=>real128
(if the case 2. above is used, then one does not need to rename, so it simplifies to justuse iso_fortran_env, only: real32, real64, real128
). Unlike a., this option does not introduce a new module in stdlib. One simply usesiso_fortran_env
everywhere directly.c.
use iso_c_binding, only: sp=>c_float, dp=>c_double, qp=>c_float128
. Unlike a., this option does not introduce a new module in stdlib.I will keep this list updated if more options become available.
The text was updated successfully, but these errors were encountered: