Skip to content
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

1.14.6: Fortran 2003 test failures with Intel LLVM compilers #5305

Open
benmenadue opened this issue Feb 10, 2025 · 3 comments
Open

1.14.6: Fortran 2003 test failures with Intel LLVM compilers #5305

benmenadue opened this issue Feb 10, 2025 · 3 comments
Assignees
Labels
Component - Fortran Fortran wrappers

Comments

@benmenadue
Copy link

make test fails in fortranlib_test_F03 when compiled using the Intel LLVM 2024.2.1 compilers on Linux:

...
 ERROR: Wrong integer data is read back by H5Dread_f 
 ERROR: INCORRECT REAL VALIDATION 
 ERROR: Wrong real data is read back by H5Dread_f 
 Testing 1-D Array of Compound Datatypes Functionality                                 *FAILED*
...

(plus other similar failures).

The problem appears to be the test itself, in particular when it's reading the data back:

! Read dataset from disk
f_ptr = C_LOC(rdata(1,1))
CALL H5Dread_f(dataset, tid1, f_ptr, error, H5S_ALL_F, H5S_ALL_F, H5P_DEFAULT_F)
CALL check("H5Dread_f", error, total_error)

That takes the address of the first element, and from the compiler's perspective that's then the only element of that array that is ever referenced. As a result, I think that the compiler assumes that the rest of the elements are uninitialised (even though the C library wrote to them) and over-optimises the subsequent verification tests.

Even though the data is being written out and read back correctly, the compiler effectively assumes that it can't match. Unfortunately, I think this is a valid assumption by the compiler, given Fortran's aliasing rules, even if unexpectedly strict.

If I change it to C_LOC(rdata), i.e. the whole array rather than just the first element (even though they would likely evaluate to the same thing), so that the compiler sees the entire array being referenced, then it works correctly. Similar changes also work for the other components that fail in this test, and then every test passes.

(If this analysis is correct, the calls to C_LOC for wdata might also need to be updated to refer to the whole array instead of the first element. Otherwise the compiler could potentially move stores to other elements past the corresponding call to h5dwrite_f, since it would similarly think that call won't touch anything but the first element.)

@brtnfld
Copy link
Collaborator

brtnfld commented Feb 10, 2025

Could you provide a reference from the Fortran standard where C_LOC(data (1,1)) is not allowed? Some compilers complain about it when (1,1) is not provided. LLVM is the only compiler that I'm aware of that would interpret the standard in such a manner, as I'm unaware of the other compilers noting an extension of the standard to allow it. As far as I'm aware, the standard only addresses memory continuity, which that should not be an issue.

While C_LOC(data) might work in some cases, C_LOC(data(1,1)) emphasizes that you're working with the first element, which is the most reliable way to ensure compatibility with C's expectations, especially if the array is contiguous.

Also, Using C_LOC(data(1,1)) is more portable and predictable. It avoids potential issues, like this, related to different interpretations of C_LOC(data) by different compilers or C code that makes assumptions about array layout.

I think this is a compiler bug.

@brtnfld brtnfld self-assigned this Feb 10, 2025
@brtnfld brtnfld added the Component - Fortran Fortran wrappers label Feb 10, 2025
@benmenadue
Copy link
Author

Actually I think it's more the opposite: is there anything in the standard that allows the use of C_LOC(rdata(1,1)) to be used to refer to other elements of the array? I don't think sequence association kicks in here. That said, I'm pretty rusty on Fortran so I'll also ask over at Intel.

@brtnfld
Copy link
Collaborator

brtnfld commented Feb 10, 2025

There is not a specific place that says data(1,1) is valid. The reasoning is:

  • C_LOC is defined for interoperable arguments.
  • An array element (like data(1,1)) can be an interoperable argument (if the array itself and its element type are interoperable).
  • Therefore, C_LOC(data(1,1)) is valid.

The standard emphasizes that it's the storage location of x that's passed. For data(1,1), the storage location is the first element of the array. The standard focuses on what is allowed, not how implementations should achieve it. The compiler needs to adhere to the standards "what".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component - Fortran Fortran wrappers
Projects
None yet
Development

No branches or pull requests

2 participants