Commit 9233720a authored by Andreas Marek's avatar Andreas Marek
Browse files

Merge branch 'fix_omp' into 'master_pre_stage'

Fix omp

See merge request !12
parents 57c4bada e867741a
...@@ -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
   
   
   
......
...@@ -40,6 +40,7 @@ libelpa@SUFFIX@_private_la_SOURCES = \ ...@@ -40,6 +40,7 @@ libelpa@SUFFIX@_private_la_SOURCES = \
src/helpers/mod_precision.F90 \ src/helpers/mod_precision.F90 \
src/helpers/mod_mpi.F90 \ src/helpers/mod_mpi.F90 \
src/helpers/mod_mpi_stubs.F90 \ src/helpers/mod_mpi_stubs.F90 \
src/helpers/mod_omp.F90 \
src/elpa_generated_fortran_interfaces.F90 \ src/elpa_generated_fortran_interfaces.F90 \
src/elpa2/mod_redist_band.F90 \ src/elpa2/mod_redist_band.F90 \
src/elpa2/mod_pack_unpack_cpu.F90 \ src/elpa2/mod_pack_unpack_cpu.F90 \
...@@ -454,6 +455,7 @@ nobase_nodist_elpa_include_HEADERS = \ ...@@ -454,6 +455,7 @@ nobase_nodist_elpa_include_HEADERS = \
elpa/elpa_version.h \ elpa/elpa_version.h \
elpa/elpa_constants.h \ elpa/elpa_constants.h \
elpa/elpa_generated.h \ elpa/elpa_generated.h \
elpa/elpa_generated_c_api.h \
elpa/elpa_generated_legacy.h elpa/elpa_generated_legacy.h
dist_man_MANS = \ dist_man_MANS = \
...@@ -685,7 +687,8 @@ test_python.sh: ...@@ -685,7 +687,8 @@ test_python.sh:
include doxygen.am include doxygen.am
CLEANFILES = \ CLEANFILES = \
elpa-generated.h \ elpa_generated.h \
elpa_generated_c_api.h \
elpa1_test* \ elpa1_test* \
elpa2_test*\ elpa2_test*\
elpa2_real* \ elpa2_real* \
...@@ -717,16 +720,14 @@ clean-local: ...@@ -717,16 +720,14 @@ clean-local:
-rm -rf $(generated_headers) -rm -rf $(generated_headers)
distclean-local: distclean-local:
-rm -rf ./m4
-rm -rf ./src
-rm -rf ./test
-rm -rf ./modules
-rm -rf .fortran_dependencies
-rm config-f90.h -rm config-f90.h
-rm -rf ./src/elpa2/kernels/.deps
-rm -rf ./src/.deps
-rm -rf ./test/.deps -rm -rf ./test/.deps
-rmdir ./src/elpa2/kernels/ -rm -rf elpa/elpa_generated_c_api.h
-rmdir ./src
-rmdir ./test
-rmdir ./m4
-rmdir modules/
-rmdir .fortran_dependencies/
EXTRA_DIST = \ EXTRA_DIST = \
elpa.spec \ elpa.spec \
......
...@@ -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])
...@@ -1454,5 +1472,11 @@ if test x"$enable_kcomputer" = x"yes" ; then ...@@ -1454,5 +1472,11 @@ if test x"$enable_kcomputer" = x"yes" ; then
echo "call: make -f ../generated_headers.am generated-headers top_srcdir=.." echo "call: make -f ../generated_headers.am generated-headers top_srcdir=.."
echo "BEFORE triggering the build with make!" echo "BEFORE triggering the build with make!"
else else
if test x"$optional_c_error_argument" = x"yes" ; then
echo "#define OPTIONAL_C_ERROR_ARGUMENT" > elpa/elpa_generated_c_api.h
else
echo "#undef OPTIONAL_C_ERROR_ARGUMENT" > elpa/elpa_generated_c_api.h
fi
make -f $srcdir/generated_headers.am generated-headers top_srcdir="$srcdir" CPP="$CPP" make -f $srcdir/generated_headers.am generated-headers top_srcdir="$srcdir" CPP="$CPP"
fi fi
...@@ -14,6 +14,7 @@ typedef struct elpa_autotune_struct *elpa_autotune_t; ...@@ -14,6 +14,7 @@ typedef struct elpa_autotune_struct *elpa_autotune_t;
#include <elpa/elpa_constants.h> #include <elpa/elpa_constants.h>
#include <elpa/elpa_generated_c_api.h>
#include <elpa/elpa_generated.h> #include <elpa/elpa_generated.h>
#include <elpa/elpa_generic.h> #include <elpa/elpa_generic.h>
......
...@@ -22,6 +22,22 @@ elpa/elpa_generated.h: $(top_srcdir)/src/elpa_impl.F90 \ ...@@ -22,6 +22,22 @@ elpa/elpa_generated.h: $(top_srcdir)/src/elpa_impl.F90 \
$(top_srcdir)/src/elpa_api.F90 | elpa $(top_srcdir)/src/elpa_api.F90 | elpa
@rm -f $@ @rm -f $@
$(call extract_interface,!c>) $(call extract_interface,!c>)
$(call extract_interface,!c_o>)
$(call extract_interface,!c_no>)
#if OPTIONAL_C_ERROR_ARGUMENT
#
#elpa/elpa_generated.h: $(top_srcdir)/src/elpa_impl.F90 \
# $(top_srcdir)/src/elpa_impl_math_template.F90 \
# $(top_srcdir)/src/elpa_api.F90 | elpa
# $(call extract_interface,!c_o>)
#
#else
#elpa/elpa_generated.h: $(top_srcdir)/src/elpa_impl.F90 \
# $(top_srcdir)/src/elpa_impl_math_template.F90 \
# $(top_srcdir)/src/elpa_api.F90 | elpa
# $(call extract_interface,!c_no>)
#endif
generated_headers += elpa/elpa_generated_legacy.h generated_headers += elpa/elpa_generated_legacy.h
elpa/elpa_generated_legacy.h: $(top_srcdir)/src/elpa_driver/legacy_interface/elpa_driver_c_interface.F90 \ elpa/elpa_generated_legacy.h: $(top_srcdir)/src/elpa_driver/legacy_interface/elpa_driver_c_interface.F90 \
......
...@@ -66,9 +66,8 @@ function elpa_solve_evp_& ...@@ -66,9 +66,8 @@ function elpa_solve_evp_&
use elpa_abstract_impl use elpa_abstract_impl
use elpa_mpi use elpa_mpi
use elpa1_compute use elpa1_compute
#ifdef WITH_OPENMP use elpa_omp
use omp_lib
#endif
implicit none implicit none
#include "../general/precision_kinds.F90" #include "../general/precision_kinds.F90"
class(elpa_abstract_impl_t), intent(inout) :: obj class(elpa_abstract_impl_t), intent(inout) :: obj
...@@ -122,7 +121,11 @@ function elpa_solve_evp_& ...@@ -122,7 +121,11 @@ function elpa_solve_evp_&
&") &")
#ifdef WITH_OPENMP #ifdef WITH_OPENMP
!nrThreads = omp_get_max_threads() ! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
omp_threads_caller = omp_get_max_threads()
! check the number of threads that ELPA should use internally
call obj%get("omp_threads",nrThreads,error) call obj%get("omp_threads",nrThreads,error)
call omp_set_num_threads(nrThreads) call omp_set_num_threads(nrThreads)
#else #else
...@@ -156,6 +159,13 @@ function elpa_solve_evp_& ...@@ -156,6 +159,13 @@ function elpa_solve_evp_&
if (.not.(obj%eigenvalues_only)) then if (.not.(obj%eigenvalues_only)) then
q(1,1) = ONE q(1,1) = ONE
endif endif
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
call obj%timer%stop("elpa_solve_evp_& call obj%timer%stop("elpa_solve_evp_&
&MATH_DATATYPE& &MATH_DATATYPE&
&_1stage_& &_1stage_&
...@@ -411,6 +421,13 @@ function elpa_solve_evp_& ...@@ -411,6 +421,13 @@ function elpa_solve_evp_&
endif endif
endif endif
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
call obj%timer%stop("elpa_solve_evp_& call obj%timer%stop("elpa_solve_evp_&
&MATH_DATATYPE& &MATH_DATATYPE&
&_1stage_& &_1stage_&
......
...@@ -102,9 +102,8 @@ call prmat(na,useGpu,a_mat,a_dev,lda,matrixCols,nblk,my_prow,my_pcol,np_rows,np_ ...@@ -102,9 +102,8 @@ call prmat(na,useGpu,a_mat,a_dev,lda,matrixCols,nblk,my_prow,my_pcol,np_rows,np_
use precision use precision
use elpa_abstract_impl use elpa_abstract_impl
use matrix_plot use matrix_plot
#ifdef WITH_OPENMP use elpa_omp
use omp_lib
#endif
implicit none implicit none
#include "../general/precision_kinds.F90" #include "../general/precision_kinds.F90"
class(elpa_abstract_impl_t), intent(inout) :: obj class(elpa_abstract_impl_t), intent(inout) :: obj
......
...@@ -48,9 +48,8 @@ ...@@ -48,9 +48,8 @@
use elpa_mpi use elpa_mpi
use precision use precision
use elpa_abstract_impl use elpa_abstract_impl
#ifdef WITH_OPENMP use elpa_omp
use omp_lib
#endif
implicit none implicit none
#include "../general/precision_kinds.F90" #include "../general/precision_kinds.F90"
class(elpa_abstract_impl_t), intent(inout) :: obj class(elpa_abstract_impl_t), intent(inout) :: obj
...@@ -80,7 +79,11 @@ ...@@ -80,7 +79,11 @@
&") &")
#ifdef WITH_OPENMP #ifdef WITH_OPENMP
!nrThreads=omp_get_max_threads() ! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
omp_threads_caller = omp_get_max_threads()
! check the number of threads that ELPA should use internally
call obj%get("omp_threads",nrThreads,error) call obj%get("omp_threads",nrThreads,error)
call omp_set_num_threads(nrThreads) call omp_set_num_threads(nrThreads)
#else #else
...@@ -333,6 +336,14 @@ ...@@ -333,6 +336,14 @@
a(l_row1:l_rows,l_col1) = 0 a(l_row1:l_rows,l_col1) = 0
endif endif
enddo enddo
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
call obj%timer%stop("elpa_cholesky_& call obj%timer%stop("elpa_cholesky_&
&MATH_DATATYPE& &MATH_DATATYPE&
&_& &_&
......
...@@ -63,9 +63,7 @@ ...@@ -63,9 +63,7 @@
&_impl &_impl
use precision use precision
use elpa_abstract_impl use elpa_abstract_impl
#ifdef WITH_OPENMP use elpa_omp
use omp_lib
#endif
implicit none implicit none
class(elpa_abstract_impl_t), intent(inout) :: obj class(elpa_abstract_impl_t), intent(inout) :: obj
...@@ -95,7 +93,12 @@ ...@@ -95,7 +93,12 @@
matrixCols = obj%local_ncols matrixCols = obj%local_ncols
#ifdef WITH_OPENMP #ifdef WITH_OPENMP
!nrThreads=omp_get_max_threads() ! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
omp_threads_caller = omp_get_max_threads()
! check the number of threads that ELPA should use internally
call obj%get("omp_threads",nrThreads,error) call obj%get("omp_threads",nrThreads,error)
#else #else
nrThreads=1 nrThreads=1
...@@ -130,6 +133,15 @@ ...@@ -130,6 +133,15 @@
mpi_comm_rows, mpi_comm_cols,.false., wantDebug, success, & mpi_comm_rows, mpi_comm_cols,.false., wantDebug, success, &
nrThreads) nrThreads)
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
call obj%timer%stop("elpa_solve_tridi_public_& call obj%timer%stop("elpa_solve_tridi_public_&
&MATH_DATATYPE& &MATH_DATATYPE&
&_& &_&
......
...@@ -62,9 +62,8 @@ ...@@ -62,9 +62,8 @@
&_impl &_impl
use elpa use elpa
use elpa_abstract_impl use elpa_abstract_impl
#ifdef WITH_OPENMP use elpa_omp
use omp_lib
#endif
implicit none implicit none
integer(kind=ik) :: na, nev, ldq, nblk, matrixCols, mpi_comm_rows, mpi_comm_cols integer(kind=ik) :: na, nev, ldq, nblk, matrixCols, mpi_comm_rows, mpi_comm_cols
real(kind=REAL_DATATYPE) :: d(na), e(na) real(kind=REAL_DATATYPE) :: d(na), e(na)
...@@ -148,6 +147,12 @@ ...@@ -148,6 +147,12 @@
endif endif
#ifdef WITH_OPENMP #ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
omp_threads_caller = omp_get_max_threads()
! check the number of threads that ELPA should use internally
nrThreads = omp_get_max_threads() nrThreads = omp_get_max_threads()
call obj%set("omp_threads", nrThreads, error) call obj%set("omp_threads", nrThreads, error)
#else #else
...@@ -167,6 +172,12 @@ ...@@ -167,6 +172,12 @@
if (error /= ELPA_OK) then if (error /= ELPA_OK) then
print *, "Cannot run solve_tridi" print *, "Cannot run solve_tridi"
success = .false. success = .false.
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
return return
else else
success = .true. success = .true.
...@@ -184,6 +195,13 @@ ...@@ -184,6 +195,13 @@
! stop ! stop
endif endif
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
!call timer%stop("elpa_solve_tridi_& !call timer%stop("elpa_solve_tridi_&
!&PRECISION& !&PRECISION&
!&_legacy_interface") !&_legacy_interface")
......
...@@ -63,9 +63,8 @@ ...@@ -63,9 +63,8 @@
use elpa_mpi use elpa_mpi
use cuda_functions use cuda_functions
use mod_check_for_gpu use mod_check_for_gpu
#ifdef WITH_OPENMP use elpa_omp
use omp_lib
#endif
use iso_c_binding use iso_c_binding
implicit none implicit none
#include "../general/precision_kinds.F90" #include "../general/precision_kinds.F90"
...@@ -150,7 +149,11 @@ ...@@ -150,7 +149,11 @@
#ifdef WITH_OPENMP #ifdef WITH_OPENMP
!nrThreads = omp_get_max_threads() ! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
omp_threads_caller = omp_get_max_threads()
! check the number of threads that ELPA should use internally
call obj%get("omp_threads",nrThreads,error) call obj%get("omp_threads",nrThreads,error)
call omp_set_num_threads(nrThreads) call omp_set_num_threads(nrThreads)
#else #else
...@@ -209,6 +212,14 @@ ...@@ -209,6 +212,14 @@
if (.not.(obj%eigenvalues_only)) then if (.not.(obj%eigenvalues_only)) then
q(1,1) = ONE q(1,1) = ONE
endif endif
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
call obj%timer%stop("elpa_solve_evp_& call obj%timer%stop("elpa_solve_evp_&
&MATH_DATATYPE& &MATH_DATATYPE&
&_2stage_& &_2stage_&
...@@ -779,6 +790,13 @@ ...@@ -779,6 +790,13 @@
endif endif
endif endif
! restore original OpenMP settings
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
! restore this at the end of ELPA 2
call omp_set_num_threads(omp_threads_caller)
#endif
call obj%timer%stop("elpa_solve_evp_& call obj%timer%stop("elpa_solve_evp_&
&MATH_DATATYPE& &MATH_DATATYPE&
&_2stage_& &_2stage_&
......
...@@ -817,20 +817,49 @@ module elpa_api ...@@ -817,20 +817,49 @@ module elpa_api
api_version = api_version_set api_version = api_version_set
end function end function
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #define elpa_uninit(...) CONC(elpa_uninit, NARGS(__VA_ARGS__))(__VA_ARGS__)
!c_o> #endif
#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_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> void elpa_uninit1(int *error);
!c_o> void elpa_uninit0();
!c_o> #endif
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
!c_no> #ifndef OPTIONAL_C_ERROR_ARGUMENT
!c_no> void elpa_uninit(int *error);
!c_no> #endif
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,93 @@ module elpa_impl ...@@ -215,30 +215,93 @@ module elpa_impl
endif endif
end function end function
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #define elpa_allocate(...) CONC(elpa_allocate, NARGS(__VA_ARGS__))(__VA_ARGS__)
!c_o> #endif
#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_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
integer(kind=c_int) :: error !c_o> elpa_t elpa_allocate2(int *error);
type(c_ptr) :: ptr !c_o> elpa_t elpa_allocate1();
!c_o> #endif
function elpa_impl_allocate_c1() result(ptr) bind(C, name="elpa_allocate1")
type(c_ptr) :: ptr
type(elpa_impl_t), pointer