Add Fortran API#174
Conversation
1832b49 to
59ab170
Compare
fcaf2e3 to
d2fbfbc
Compare
- provide C enums - add atom and molecule types - add basis set and shell definitions - add molecule grid and runtime environment - add load balancer to C API - add molecular weights for C API - add functional class wrapping ExchCXX - add xc integrator and matrix type - add references for functionals - add support for reading and writing from HDF5 in C
- remove matrix class - directly expose ReplicatedXCIntegrator API
|
Current version fails with OpenMPI due to missing f2c API in mpi_f08 module. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated 13 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ) | ||
| if(GAUXC_ENABLE_MPI) | ||
| target_link_libraries( gauxc PUBLIC MPI::MPI_Fortran ) | ||
| set( GAUXC_HAS_MPI_F08 TRUE CACHE BOOL "GauXC has MPI Fortran 2008 bindings" FORCE ) |
There was a problem hiding this comment.
This unconditionally forces GAUXC_HAS_MPI_F08=TRUE whenever MPI is enabled, which can break builds on MPI implementations that do not provide the mpi_f08 module (or do not support the nonstandard %mpi_val access used later). Instead of forcing this flag, detect F08 support (e.g., via CMake/FindMPI variables like MPI_Fortran_HAVE_F08_MODULE, or a try_compile that use mpi_f08) and only define GAUXC_HAS_MPI_F08 when it is actually available; otherwise keep the fallback path that uses use mpi.
| set( GAUXC_HAS_MPI_F08 TRUE CACHE BOOL "GauXC has MPI Fortran 2008 bindings" FORCE ) | |
| if(DEFINED MPI_Fortran_HAVE_F08_MODULE AND MPI_Fortran_HAVE_F08_MODULE) | |
| set( GAUXC_HAS_MPI_F08 TRUE CACHE BOOL "GauXC has MPI Fortran 2008 bindings" ) | |
| else() | |
| set( GAUXC_HAS_MPI_F08 FALSE CACHE BOOL "GauXC has MPI Fortran 2008 bindings" ) | |
| endif() |
| #ifdef GAUXC_HAS_MPI | ||
| call MPI_Init(mpi_ierr) | ||
| if (mpi_ierr /= MPI_SUCCESS) error stop 1 | ||
| #endif |
There was a problem hiding this comment.
The test runner always use mpi_f08 when GAUXC_HAS_MPI is set, but the rest of the codebase has conditional support for both mpi and mpi_f08. If GAUXC_HAS_MPI is true but mpi_f08 is not available, this test binary will not compile. Additionally, it calls MPI_Init/MPI_Finalize unconditionally; since MPI_Initialized/MPI_Finalized are already imported, it would be safer to guard initialization/finalization to avoid runtime errors in environments where MPI is already initialized or finalized.
| #ifdef GAUXC_HAS_MPI | ||
| call MPI_Finalize(mpi_ierr) | ||
| if (mpi_ierr /= MPI_SUCCESS) error stop 1 | ||
| #endif |
There was a problem hiding this comment.
The test runner always use mpi_f08 when GAUXC_HAS_MPI is set, but the rest of the codebase has conditional support for both mpi and mpi_f08. If GAUXC_HAS_MPI is true but mpi_f08 is not available, this test binary will not compile. Additionally, it calls MPI_Init/MPI_Finalize unconditionally; since MPI_Initialized/MPI_Finalized are already imported, it would be safer to guard initialization/finalization to avoid runtime errors in environments where MPI is already initialized or finalized.
| character(kind=c_char, len=:), allocatable :: msg | ||
| character(kind=c_char), pointer :: pmsg(:) | ||
|
|
||
| if (c_associated(status%message)) then | ||
| slen = strlen(status%message) | ||
| call c_f_pointer(status%message, pmsg, [slen]) | ||
| msg = transfer(pmsg(1:slen), "") | ||
| else | ||
| msg = "" |
There was a problem hiding this comment.
Using transfer(pmsg(1:slen), \"\") is not portable because the mold \"\" is default character kind, which may differ from c_char (and transfer does not perform kind conversion). This can produce incorrect results or fail on compilers where default character kind is not 1 byte. Prefer constructing msg using a c_char mold (e.g., allocate msg with character(kind=c_char,len=slen) and transfer with msg as the mold, or copy element-wise from pmsg).
| character(kind=c_char, len=:), allocatable :: msg | |
| character(kind=c_char), pointer :: pmsg(:) | |
| if (c_associated(status%message)) then | |
| slen = strlen(status%message) | |
| call c_f_pointer(status%message, pmsg, [slen]) | |
| msg = transfer(pmsg(1:slen), "") | |
| else | |
| msg = "" | |
| integer(c_int) :: i | |
| character(kind=c_char, len=:), allocatable :: msg | |
| character(kind=c_char), pointer :: pmsg(:) | |
| if (c_associated(status%message)) then | |
| slen = strlen(status%message) | |
| call c_f_pointer(status%message, pmsg, [slen]) | |
| allocate(character(kind=c_char, len=slen) :: msg) | |
| do i = 1, slen | |
| msg(i:i) = pmsg(i) | |
| end do | |
| else | |
| allocate(character(kind=c_char, len=0) :: msg) |
Closes #66