Commit c3a093a6 authored by Andreas Marek's avatar Andreas Marek

Optional arguments in C

parent 8fc1df8a
...@@ -48,7 +48,7 @@ static-build: ...@@ -48,7 +48,7 @@ static-build:
tags: tags:
- avx - avx
script: script:
- ./ci_test_scripts/run_ci_tests.sh -c " CFLAGS=\"-O3 -mavx\" FCFLAGS=\"-O3 -axAVX\" SCALAPACK_LDFLAGS=\"$MKL_INTEL_SCALAPACK_LDFLAGS_NO_MPI_NO_OMP\" SCALAPACK_FCFLAGS=\"$MKL_INTEL_SCALAPACK_FCFLAGS_NO_MPI_NO_OMP\" --with-mpi=no FC=ifort --enable-shared=no --enable-static=yes --disable-avx2 || { cat config.log; exit 1; } " -j 8 -t 2 -m 150 -n 50 -b 16 -s $SKIP_STEP -i $INTERACTIVE_RUN -S $SLURM - ./ci_test_scripts/run_ci_tests.sh -c " CFLAGS=\"-O3 -mavx\" FCFLAGS=\"-O3 -axAVX\" SCALAPACK_LDFLAGS=\"$MKL_INTEL_SCALAPACK_LDFLAGS_NO_MPI_NO_OMP\" SCALAPACK_FCFLAGS=\"$MKL_INTEL_SCALAPACK_FCFLAGS_NO_MPI_NO_OMP\" --with-mpi=no FC=ifort --enable-shared=no --enable-static=yes --disable-avx2 --enable-optional-argument-in-C-API || { cat config.log; exit 1; } " -j 8 -t 2 -m 150 -n 50 -b 16 -s $SKIP_STEP -i $INTERACTIVE_RUN -S $SLURM
......
...@@ -319,7 +319,7 @@ print(" tags:") ...@@ -319,7 +319,7 @@ print(" tags:")
print(" - avx") print(" - avx")
print(" script:") print(" script:")
print(" - ./ci_test_scripts/run_ci_tests.sh -c \" CFLAGS=\\\"-O3 -mavx\\\" FCFLAGS=\\\"-O3 -axAVX\\\" SCALAPACK_LDFLAGS=\\\"$MKL_INTEL_SCALAPACK_LDFLAGS_NO_MPI_NO_OMP\\\" \ print(" - ./ci_test_scripts/run_ci_tests.sh -c \" CFLAGS=\\\"-O3 -mavx\\\" FCFLAGS=\\\"-O3 -axAVX\\\" SCALAPACK_LDFLAGS=\\\"$MKL_INTEL_SCALAPACK_LDFLAGS_NO_MPI_NO_OMP\\\" \
SCALAPACK_FCFLAGS=\\\"$MKL_INTEL_SCALAPACK_FCFLAGS_NO_MPI_NO_OMP\\\" --with-mpi=no FC=ifort --enable-shared=no --enable-static=yes --disable-avx2 || { cat config.log; exit 1; } \" -j 8 \ SCALAPACK_FCFLAGS=\\\"$MKL_INTEL_SCALAPACK_FCFLAGS_NO_MPI_NO_OMP\\\" --with-mpi=no FC=ifort --enable-shared=no --enable-static=yes --disable-avx2 --enable-optional-argument-in-C-API || { cat config.log; exit 1; } \" -j 8 \
-t 2 -m 150 -n 50 -b 16 -s $SKIP_STEP -i $INTERACTIVE_RUN -S $SLURM ") -t 2 -m 150 -n 50 -b 16 -s $SKIP_STEP -i $INTERACTIVE_RUN -S $SLURM ")
print("\n\n") print("\n\n")
......
...@@ -68,6 +68,24 @@ if test x"${enable_legacy}" = x"yes"; then ...@@ -68,6 +68,24 @@ if test x"${enable_legacy}" = x"yes"; then
AC_DEFINE([ENABLE_LEGACY], [1], [enable legacy interface]) AC_DEFINE([ENABLE_LEGACY], [1], [enable legacy interface])
fi fi
AC_MSG_CHECKING(whether in C interface the error argument should be optional)
AC_ARG_ENABLE([optional-argument-in-C-API],
AS_HELP_STRING([--enable-optional-argument-in-C-API],
[do not build C API with error argument as optional, default no]),
[
if test x"$enableval" = x"yes"; then
optional_c_error_argument=yes
else
optional_c_error_argument=no
fi
],
[optional_c_error_argument=no])
AC_MSG_RESULT([${optional_c_error_argument}])
AM_CONDITIONAL([OPTIONAL_C_ERROR_ARGUMENT],[test x"$enable_legacy" = x"yes"])
if test x"${optional_c_error_argument}" = x"yes"; then
AC_DEFINE([OPTIONAL_C_ERROR_ARGUMENT], [1], [enable error argument in C-API to be optional])
fi
# gnu-make fortran module dependencies # gnu-make fortran module dependencies
m4_include([fdep/fortran_dependencies.m4]) m4_include([fdep/fortran_dependencies.m4])
......
...@@ -817,20 +817,42 @@ module elpa_api ...@@ -817,20 +817,42 @@ module elpa_api
api_version = api_version_set api_version = api_version_set
end function end function
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c> #define elpa_uninit(...) CONC(elpa_uninit, NARGS(__VA_ARGS__))(__VA_ARGS__)
#endif
!> \brief subroutine to uninit the ELPA library. Does nothing at the moment. Might do sth. later !> \brief subroutine to uninit the ELPA library. Does nothing at the moment. Might do sth. later
! !
!c> void elpa_uninit(int *error); #ifdef OPTIONAL_C_ERROR_ARGUMENT
subroutine elpa_uninit(error) bind(C, name="elpa_uninit") !c> void elpa_uninit1(int *error);
!c> void elpa_uninit0();
subroutine elpa_uninit_c1(error) bind(C, name="elpa_uninit1")
integer(kind=c_int) :: error
call elpa_uninit(error)
end subroutine
subroutine elpa_uninit_c0() bind(C, name="elpa_uninit0")
call elpa_uninit()
end subroutine
#else
subroutine elpa_uninit_c(error) bind(C, name="elpa_uninit")
integer(kind=c_int) :: error
call elpa_uninit(error)
end subroutine
#endif
subroutine elpa_uninit(error)
#ifdef USE_FORTRAN2008 #ifdef USE_FORTRAN2008
integer, optional, intent(out) :: error integer, optional, intent(out) :: error
#else #else
integer, intent(out) :: error integer, intent(out) :: error
#endif
#ifdef USE_FORTRAN2008
if (present(error)) then
error = ELPA_OK
return
endif
#endif #endif
if (present(error)) error = ELPA_OK
end subroutine end subroutine
!> \brief helper function for error strings !> \brief helper function for error strings
!> Parameters !> Parameters
!> \param elpa_error integer: error code to querry !> \param elpa_error integer: error code to querry
......
...@@ -215,30 +215,79 @@ module elpa_impl ...@@ -215,30 +215,79 @@ module elpa_impl
endif endif
end function end function
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c> #define elpa_allocate(...) CONC(elpa_allocate, NARGS(__VA_ARGS__))(__VA_ARGS__)
#endif
!c> /*! \brief C interface for the implementation of the elpa_allocate method !c> /*! \brief C interface for the implementation of the elpa_allocate method
!c> * !c> *
!c> * \param none !c> * \param none
!c> * \result elpa_t handle !c> * \result elpa_t handle
!c> */ !c> */
!c> elpa_t elpa_allocate(int *error); #ifdef OPTIONAL_C_ERROR_ARGUMENT
function elpa_impl_allocate_c(error) result(ptr) bind(C, name="elpa_allocate") !c> elpa_t elpa_allocate2(int *error);
integer(kind=c_int) :: error !c> elpa_t elpa_allocate1();
type(c_ptr) :: ptr function elpa_impl_allocate_c1() result(ptr) bind(C, name="elpa_allocate1")
type(c_ptr) :: ptr
type(elpa_impl_t), pointer :: obj
obj => elpa_impl_allocate()
ptr = c_loc(obj)
end function
function elpa_impl_allocate_c2(error) result(ptr) bind(C, name="elpa_allocate2")
integer(kind=c_int) :: error
type(c_ptr) :: ptr
type(elpa_impl_t), pointer :: obj type(elpa_impl_t), pointer :: obj
obj => elpa_impl_allocate(error) obj => elpa_impl_allocate(error)
ptr = c_loc(obj) ptr = c_loc(obj)
end function end function
#else
function elpa_impl_allocate_c(error) result(ptr) bind(C, name="elpa_allocate")
integer(kind=c_int) :: error
type(c_ptr) :: ptr
type(elpa_impl_t), pointer :: obj
obj => elpa_impl_allocate(error)
ptr = c_loc(obj)
end function
#endif
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c> #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
!c> #define NARGS_(_5, _4, _3, _2, _1, N, ...) N
!c> #define CONC(A, B) CONC_(A, B)
!c> #define CONC_(A, B) A##B
!c> #define elpa_deallocate(...) CONC(elpa_deallocate, NARGS(__VA_ARGS__))(__VA_ARGS__)
#endif
!c> /*! \brief C interface for the implementation of the elpa_deallocate method !c> /*! \brief C interface for the implementation of the elpa_deallocate method
!c> * !c> *
!c> * \param elpa_t handle of ELPA object to be deallocated !c> * \param elpa_t handle of ELPA object to be deallocated
!c> * \param int* error code !c> * \param int* error code
!c> * \result void !c> * \result void
!c> */ !c> */
!c> void elpa_deallocate(elpa_t handle, int *error); #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c> void elpa_deallocate2(elpa_t handle, int *error);
!c> void elpa_deallocate1(elpa_t handle);
subroutine elpa_impl_deallocate_c2(handle, error) bind(C, name="elpa_deallocate2")
type(c_ptr), value :: handle
type(elpa_impl_t), pointer :: self
integer(kind=c_int) :: error
call c_f_pointer(handle, self)
call self%destroy(error)
deallocate(self)
end subroutine
subroutine elpa_impl_deallocate_c1(handle) bind(C, name="elpa_deallocate1")
type(c_ptr), value :: handle
type(elpa_impl_t), pointer :: self
call c_f_pointer(handle, self)
call self%destroy()
deallocate(self)
end subroutine
#else
subroutine elpa_impl_deallocate_c(handle, error) bind(C, name="elpa_deallocate") subroutine elpa_impl_deallocate_c(handle, error) bind(C, name="elpa_deallocate")
type(c_ptr), value :: handle type(c_ptr), value :: handle
type(elpa_impl_t), pointer :: self type(elpa_impl_t), pointer :: self
...@@ -249,6 +298,8 @@ module elpa_impl ...@@ -249,6 +298,8 @@ module elpa_impl
deallocate(self) deallocate(self)
end subroutine end subroutine
#endif
!> \brief function to load all the parameters, which have been saved to a file !> \brief function to load all the parameters, which have been saved to a file
!> Parameters !> Parameters
!> \param self class(elpa_impl_t) the allocated ELPA object !> \param self class(elpa_impl_t) the allocated ELPA object
...@@ -387,13 +438,18 @@ module elpa_impl ...@@ -387,13 +438,18 @@ module elpa_impl
#ifdef ENABLE_AUTOTUNING #ifdef ENABLE_AUTOTUNING
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c> #define elpa_autotune_deallocate(...) CONC(elpa_autotune_deallocate, NARGS(__VA_ARGS__))(__VA_ARGS__)
#endif
!c> /*! \brief C interface for the implementation of the elpa_autotune_deallocate method !c> /*! \brief C interface for the implementation of the elpa_autotune_deallocate method
!c> * !c> *
!c> * \param elpa_autotune_impl_t handle of ELPA autotune object to be deallocated !c> * \param elpa_autotune_impl_t handle of ELPA autotune object to be deallocated
!c> * \result void !c> * \result void
!c> */ !c> */
!c> void elpa_autotune_deallocate(elpa_autotune_t handle, int *error); #ifdef OPTIONAL_C_ERROR_ARGUMENT
subroutine elpa_autotune_impl_deallocate_c( autotune_handle) bind(C, name="elpa_autotune_deallocate") !c> void elpa_autotune_deallocate2(elpa_autotune_t handle, int *error);
!c> void elpa_autotune_deallocate1(elpa_autotune_t handle);
subroutine elpa_autotune_impl_deallocate_c1( autotune_handle) bind(C, name="elpa_autotune_deallocate1")
type(c_ptr), value :: autotune_handle type(c_ptr), value :: autotune_handle
type(elpa_autotune_impl_t), pointer :: self type(elpa_autotune_impl_t), pointer :: self
...@@ -402,7 +458,29 @@ module elpa_impl ...@@ -402,7 +458,29 @@ module elpa_impl
call self%destroy() call self%destroy()
deallocate(self) deallocate(self)
end subroutine end subroutine
subroutine elpa_autotune_impl_deallocate_c2( autotune_handle, error) bind(C, name="elpa_autotune_deallocate2")
type(c_ptr), value :: autotune_handle
type(elpa_autotune_impl_t), pointer :: self
integer(kind=c_int) :: error
call c_f_pointer(autotune_handle, self)
call self%destroy(error)
deallocate(self)
end subroutine
#else
subroutine elpa_autotune_impl_deallocate( autotune_handle, error) bind(C, name="elpa_autotune_deallocate")
type(c_ptr), value :: autotune_handle
type(elpa_autotune_impl_t), pointer :: self
integer(kind=c_int) :: error
call c_f_pointer(autotune_handle, self)
call self%destroy(error)
deallocate(self)
end subroutine
#endif #endif
#endif /* ENABLE_AUTOTUNING */
!> \brief function to setup an ELPA object and to store the MPI communicators internally !> \brief function to setup an ELPA object and to store the MPI communicators internally
!> Parameters !> Parameters
......
...@@ -174,7 +174,11 @@ int main(int argc, char** argv) { ...@@ -174,7 +174,11 @@ int main(int argc, char** argv) {
exit(1); exit(1);
} }
#ifdef OPTIONAL_C_ERROR_ARGUMENT
handle = elpa_allocate();
#else
handle = elpa_allocate(&error); handle = elpa_allocate(&error);
#endif
assert_elpa_ok(error); assert_elpa_ok(error);
/* Set parameters */ /* Set parameters */
...@@ -285,8 +289,13 @@ int main(int argc, char** argv) { ...@@ -285,8 +289,13 @@ int main(int argc, char** argv) {
elpa_autotune_print_best(handle, autotune_handle, &error); elpa_autotune_print_best(handle, autotune_handle, &error);
} }
#ifdef OPTIONAL_C_ERROR_ARGUMENT
elpa_autotune_deallocate(autotune_handle);
elpa_deallocate(handle);
#else
elpa_autotune_deallocate(autotune_handle, &error); elpa_autotune_deallocate(autotune_handle, &error);
elpa_deallocate(handle, &error); elpa_deallocate(handle, &error);
#endif
elpa_uninit(&error); elpa_uninit(&error);
if (myid == 0) { if (myid == 0) {
......
...@@ -230,7 +230,11 @@ int main(int argc, char** argv) { ...@@ -230,7 +230,11 @@ int main(int argc, char** argv) {
MPI_Barrier(MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);
#endif #endif
#ifdef OPTIONAL_C_ERROR_ARGUMENT
elpa_handle_2 = elpa_allocate();
#else
elpa_handle_2 = elpa_allocate(&error); elpa_handle_2 = elpa_allocate(&error);
#endif
assert_elpa_ok(error); assert_elpa_ok(error);
set_basic_parameters(&elpa_handle_2, na, nev, na_rows, na_cols, nblk, my_prow, my_pcol); set_basic_parameters(&elpa_handle_2, na, nev, na_rows, na_cols, nblk, my_prow, my_pcol);
...@@ -341,7 +345,11 @@ int main(int argc, char** argv) { ...@@ -341,7 +345,11 @@ int main(int argc, char** argv) {
elpa_autotune_deallocate(autotune_handle, &error); elpa_autotune_deallocate(autotune_handle, &error);
elpa_deallocate(elpa_handle_1, &error); elpa_deallocate(elpa_handle_1, &error);
#ifdef OPTIONAL_C_ERROR_ARGUMENT
elpa_deallocate(elpa_handle_2);
#else
elpa_deallocate(elpa_handle_2, &error); elpa_deallocate(elpa_handle_2, &error);
#endif
elpa_uninit(&error); elpa_uninit(&error);
if (myid == 0) { if (myid == 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment