Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
elpa
elpa
Commits
a04d597a
Commit
a04d597a
authored
Apr 16, 2019
by
Andreas Marek
Browse files
Optional arguments in C
parent
8fc1df8a
Changes
11
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
a04d597a
...
...
@@ -48,7 +48,7 @@ static-build:
tags:
- avx
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
...
...
Makefile.am
View file @
a04d597a
...
...
@@ -455,6 +455,7 @@ nobase_nodist_elpa_include_HEADERS = \
elpa/elpa_version.h
\
elpa/elpa_constants.h
\
elpa/elpa_generated.h
\
elpa/elpa_generated_c_api.h
\
elpa/elpa_generated_legacy.h
dist_man_MANS
=
\
...
...
@@ -686,7 +687,8 @@ test_python.sh:
include
doxygen.am
CLEANFILES
=
\
elpa-generated.h
\
elpa_generated.h
\
elpa_generated_c_api.h
\
elpa1_test
*
\
elpa2_test
*
\
elpa2_real
*
\
...
...
@@ -718,16 +720,14 @@ clean-local:
-
rm
-rf
$(generated_headers)
distclean-local
:
-
rm
-rf
./m4
-
rm
-rf
./src
-
rm
-rf
./test
-
rm
-rf
./modules
-
rm
-rf
.fortran_dependencies
-
rm
config-f90.h
-
rm
-rf
./src/elpa2/kernels/.deps
-
rm
-rf
./src/.deps
-
rm
-rf
./test/.deps
-
rmdir
./src/elpa2/kernels/
-
rmdir
./src
-
rmdir
./test
-
rmdir
./m4
-
rmdir
modules/
-
rmdir
.fortran_dependencies/
-
rm
-rf
elpa/elpa_generated_c_api.h
EXTRA_DIST
=
\
elpa.spec
\
...
...
ci_test_scripts/generate_gitlab_ci_tests.py
View file @
a04d597a
...
...
@@ -319,7 +319,7 @@ print(" tags:")
print
(
" - avx"
)
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
\\\"
\
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 "
)
print
(
"
\n\n
"
)
...
...
configure.ac
View file @
a04d597a
...
...
@@ -68,6 +68,25 @@ if test x"${enable_legacy}" = x"yes"; then
AC_DEFINE([ENABLE_LEGACY], [1], [enable legacy interface])
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
m4_include([fdep/fortran_dependencies.m4])
...
...
@@ -1455,5 +1474,11 @@ if test x"$enable_kcomputer" = x"yes" ; then
echo "call: make -f ../generated_headers.am generated-headers top_srcdir=.."
echo "BEFORE triggering the build with make!"
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"
fi
elpa/elpa.h
View file @
a04d597a
...
...
@@ -14,6 +14,7 @@ typedef struct elpa_autotune_struct *elpa_autotune_t;
#include
<elpa/elpa_constants.h>
#include
<elpa/elpa_generated_c_api.h>
#include
<elpa/elpa_generated.h>
#include
<elpa/elpa_generic.h>
...
...
generated_headers.am
View file @
a04d597a
...
...
@@ -22,6 +22,22 @@ elpa/elpa_generated.h: $(top_srcdir)/src/elpa_impl.F90 \
$(top_srcdir)/src/elpa_api.F90 | elpa
@
rm
-f
$@
$(
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
elpa/elpa_generated_legacy.h
:
$(top_srcdir)/src/elpa_driver/legacy_interface/elpa_driver_c_interface.F90
\
...
...
src/elpa_api.F90
View file @
a04d597a
...
...
@@ -817,20 +817,49 @@ module elpa_api
api_version
=
api_version_set
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
!
!c> void elpa_uninit(int *error);
subroutine
elpa_uninit
(
error
)
bind
(
C
,
name
=
"elpa_uninit"
)
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!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
integer
,
optional
,
intent
(
out
)
::
error
integer
,
optional
,
intent
(
out
)
::
error
#else
integer
,
intent
(
out
)
::
error
integer
,
intent
(
out
)
::
error
#endif
#ifdef USE_FORTRAN2008
if
(
present
(
error
))
then
error
=
ELPA_OK
return
endif
#endif
if
(
present
(
error
))
error
=
ELPA_OK
end
subroutine
!> \brief helper function for error strings
!> Parameters
!> \param elpa_error integer: error code to querry
...
...
src/elpa_impl.F90
View file @
a04d597a
...
...
@@ -215,30 +215,93 @@ module elpa_impl
endif
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> *
!c> * \param none
!c> * \result elpa_t handle
!c> */
!c> elpa_t elpa_allocate(int *error);
function
elpa_impl_allocate_c
(
error
)
result
(
ptr
)
bind
(
C
,
name
=
"elpa_allocate"
)
integer
(
kind
=
c_int
)
::
error
type
(
c_ptr
)
::
ptr
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> elpa_t elpa_allocate2(int *error);
!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
::
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
obj
=>
elpa_impl_allocate
(
error
)
ptr
=
c_loc
(
obj
)
end
function
#else
!c_no> #ifndef OPTIONAL_C_ERROR_ARGUMENT
!c_no> elpa_t elpa_allocate(int *error);
!c_no> #endif
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_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
!c_o> #define NARGS_(_5, _4, _3, _2, _1, N, ...) N
!c_o> #define CONC(A, B) CONC_(A, B)
!c_o> #define CONC_(A, B) A##B
!c_o> #define elpa_deallocate(...) CONC(elpa_deallocate, NARGS(__VA_ARGS__))(__VA_ARGS__)
!c_o> #endif
#endif
!c> /*! \brief C interface for the implementation of the elpa_deallocate method
!c> *
!c> * \param elpa_t handle of ELPA object to be deallocated
!c> * \param int* error code
!c> * \result void
!c> */
!c> void elpa_deallocate(elpa_t handle, int *error);
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> void elpa_deallocate2(elpa_t handle, int *error);
!c_o> void elpa_deallocate1(elpa_t handle);
!c_o> #endif
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
!c_no> #ifndef OPTIONAL_C_ERROR_ARGUMENT
!c_no> void elpa_deallocate(elpa_t handle, int *error);
!c_no> #endif
subroutine
elpa_impl_deallocate_c
(
handle
,
error
)
bind
(
C
,
name
=
"elpa_deallocate"
)
type
(
c_ptr
),
value
::
handle
type
(
elpa_impl_t
),
pointer
::
self
...
...
@@ -249,6 +312,8 @@ module elpa_impl
deallocate
(
self
)
end
subroutine
#endif
!> \brief function to load all the parameters, which have been saved to a file
!> Parameters
!> \param self class(elpa_impl_t) the allocated ELPA object
...
...
@@ -387,13 +452,22 @@ module elpa_impl
#ifdef ENABLE_AUTOTUNING
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #define elpa_autotune_deallocate(...) CONC(elpa_autotune_deallocate, NARGS(__VA_ARGS__))(__VA_ARGS__)
!c_o> #endif
#endif
!c> /*! \brief C interface for the implementation of the elpa_autotune_deallocate method
!c> *
!c> * \param elpa_autotune_impl_t handle of ELPA autotune object to be deallocated
!c> * \result void
!c> */
!c> void elpa_autotune_deallocate(elpa_autotune_t handle, int *error);
subroutine
elpa_autotune_impl_deallocate_c
(
autotune_handle
)
bind
(
C
,
name
=
"elpa_autotune_deallocate"
)
#ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> #ifdef OPTIONAL_C_ERROR_ARGUMENT
!c_o> void elpa_autotune_deallocate2(elpa_autotune_t handle, int *error);
!c_o> void elpa_autotune_deallocate1(elpa_autotune_t handle);
!c_o> #endif
subroutine
elpa_autotune_impl_deallocate_c1
(
autotune_handle
)
bind
(
C
,
name
=
"elpa_autotune_deallocate1"
)
type
(
c_ptr
),
value
::
autotune_handle
type
(
elpa_autotune_impl_t
),
pointer
::
self
...
...
@@ -402,7 +476,32 @@ module elpa_impl
call
self
%
destroy
()
deallocate
(
self
)
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
!c_no> #ifndef OPTIONAL_C_ERROR_ARGUMENT
!c_no> void elpa_autotune_deallocate(elpa_autotune_t handle, int *error);
!c_no> #endif
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 /* ENABLE_AUTOTUNING */
!> \brief function to setup an ELPA object and to store the MPI communicators internally
!> Parameters
...
...
test/C/test.c
View file @
a04d597a
...
...
@@ -199,7 +199,7 @@ int main(int argc, char** argv) {
}
handle
=
elpa_allocate
(
&
error
);
assert_elpa_ok
(
error
);
//
assert_elpa_ok(error);
/* Set parameters */
elpa_set
(
handle
,
"na"
,
na
,
&
error
);
...
...
test/C/test_autotune.c
View file @
a04d597a
...
...
@@ -174,8 +174,12 @@ int main(int argc, char** argv) {
exit
(
1
);
}
#ifdef OPTIONAL_C_ERROR_ARGUMENT
handle
=
elpa_allocate
();
#else
handle
=
elpa_allocate
(
&
error
);
assert_elpa_ok
(
error
);
#endif
/* Set parameters */
elpa_set
(
handle
,
"na"
,
na
,
&
error
);
...
...
@@ -285,8 +289,13 @@ int main(int argc, char** argv) {
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_deallocate
(
handle
,
&
error
);
#endif
elpa_uninit
(
&
error
);
if
(
myid
==
0
)
{
...
...
test/C/test_multiple_objs.c
View file @
a04d597a
...
...
@@ -230,8 +230,12 @@ int main(int argc, char** argv) {
MPI_Barrier
(
MPI_COMM_WORLD
);
#endif
#ifdef OPTIONAL_C_ERROR_ARGUMENT
elpa_handle_2
=
elpa_allocate
();
#else
elpa_handle_2
=
elpa_allocate
(
&
error
);
assert_elpa_ok
(
error
);
#endif
set_basic_parameters
(
&
elpa_handle_2
,
na
,
nev
,
na_rows
,
na_cols
,
nblk
,
my_prow
,
my_pcol
);
/* Setup */
...
...
@@ -341,7 +345,11 @@ int main(int argc, char** argv) {
elpa_autotune_deallocate
(
autotune_handle
,
&
error
);
elpa_deallocate
(
elpa_handle_1
,
&
error
);
#ifdef OPTIONAL_C_ERROR_ARGUMENT
elpa_deallocate
(
elpa_handle_2
);
#else
elpa_deallocate
(
elpa_handle_2
,
&
error
);
#endif
elpa_uninit
(
&
error
);
if
(
myid
==
0
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment