Commit 69b68de3 authored by Andreas Marek's avatar Andreas Marek

Error return codes for all API functions

parent eb62d23a
......@@ -13,16 +13,16 @@ use elpa
class(elpa_t), pointer :: elpa
.br
.RI "elpa => \fBelpa_allocate\fP ()"
.RI "elpa => \fBelpa_allocate\fP (error)"
.br
.RI " "
.br
.RI "With the definitions of the input and output variables:"
.br
.RI "class(elpa_t) :: \fBelpa\fP ! returns an instance of the ELPA object"
.RI "class(elpa_t) :: \fBelpa\fP ! returns an instance of the ELPA object"
.br
.RI "integer, optional :: \fBerror\fp ! a returned error code
.br
.SS C INTERFACE
#include <elpa/elpa.h>
......@@ -30,7 +30,7 @@ class(elpa_t), pointer :: elpa
elpa_t handle;
.br
.RI "\fBelpa_t\fP handle = \fBelpa_allocate\fP();"
.RI "\fBelpa_t\fP handle = \fBelpa_allocate\fP(\fBint\fP *error);"
.br
.RI " "
.br
......@@ -39,6 +39,10 @@ elpa_t handle;
.br
.br
.RI "elpa_t \fBhandle\fP; // returns an handle to the allocated ELPA object"
.br
.RI "int \fB*error\fP; // a returned error code
.br
.SH DESCRIPTION
Allocate an ELPA object. The function \fBelpa_init\fP(3) must be called once \fIBEFORE\fP \fBelpa_allocate\fP can be called.
......
......@@ -14,7 +14,7 @@ class(elpa_t), pointer :: elpa
class(elpa_autotune_t), pointer :: tune_state
.br
.RI "call\fBelpa%autotune_deallocate\fP (tune_state)"
.RI "call\fBelpa%autotune_deallocate\fP (tune_state, error)"
.br
.RI " "
.br
......@@ -23,6 +23,9 @@ class(elpa_autotune_t), pointer :: tune_state
.br
.RI "type(elpa_autotune_t) :: \fBtune_state\fP ! the ELPA autotuning object, created with \fBelpa_autotune_setup\fP(3)
.br
.RI "integer, optional :: \fBerror\fP ! the returned error code
.br
.br
.SS C INTERFACE
#include <elpa/elpa.h>
.br
......@@ -30,7 +33,7 @@ elpa_t handle;
elpa_autotune_t autotune_handle;
.br
.RI "void \fBelpa_autotune_deallocate\fP (\fBelpa_t\fP handle, \fBelpa_autotune_t\fP autotune_handle);"
.RI "void \fBelpa_autotune_deallocate\fP (\fBelpa_t\fP handle, \fBelpa_autotune_t\fP autotune_handle, \fBint\fP *error);"
.br
.RI " "
.br
......@@ -41,7 +44,10 @@ elpa_autotune_t autotune_handle;
.RI "elpa_t \fBhandle\fP; // the handle of an ELPA object, obtained before with \fBelpa_allocate\fP(3)"
.br
.RI "elpa_autotune_t \fBautotune_handle\fP; // the handle of an ELPA object, obtained before with \fBelpa_autotune_setup\fP(3)"
.br
.RI "int \fB*error\fP; // the returned error code"
.br
.br
.SH DESCRIPTION
Deallocates an ELPA autotuning instance. \fIPrior\fP to calling the elpa_autotune_deallocate method, an ELPA autotuning object must have been created. See \fBelpa_autotune_setup\fP(3)
.SH "SEE ALSO"
......
......@@ -13,16 +13,17 @@ use elpa
class(elpa_t), pointer :: elpa
.br
.RI "call \fBelpa_deallocate\fP (\fBclass(elpa_t)\fP elpa)"
.RI "call \fBelpa_deallocate\fP (\fBclass(elpa_t)\fP elpa, \fBinteger\fP error)"
.br
.RI " "
.br
.RI "With the definitions of the input and output variables:"
.br
.RI "class(elpa_t) :: \fBelpa\fP ! the pointer to the instance of the ELPA library which should be deallocated"
.RI "class(elpa_t) :: \fBelpa\fP ! the pointer to the instance of the ELPA library which should be deallocated"
.br
.RI "integer, optional :: \fBerror\fP ! the returned error code"
.br
.br
.SS C INTERFACE
#include <elpa/elpa.h>
......@@ -30,7 +31,7 @@ class(elpa_t), pointer :: elpa
elpa_t handle;
.br
.RI "\fBvoid\fP \fBelpa_deallocate\fP(\fBelpa_t\fP handle);"
.RI "\fBvoid\fP \fBelpa_deallocate\fP(\fBelpa_t\fP handle, \fBint\fP *error^);"
.br
.RI " "
.br
......@@ -39,7 +40,10 @@ elpa_t handle;
.br
.br
.RI "elpa_t \fBhandle\fP; // the handle to the ELPA instance which should be deallocated."
.br
.RI "int \fB*error\fP; // the returned error code"
.br
.br
.SH DESCRIPTION
Deallocate an ELPA object. The functions \fBelpa_init\fP(3) and \fBelpa_allocate\fP(3) must have been called \fIBEFORE\fP \fBelpa_deallocate\fP can be called.
.br
......
......@@ -13,14 +13,14 @@ use elpa
class(elpa_t), pointer :: elpa
.br
.RI "call \fBelpa_uninit\fP ()"
.RI "call \fBelpa_uninit\fP (error)"
.br
.RI " "
.br
.RI "With the definitions of the input and output variables:"
.br
.RI "No input or output is needed."
.RI "error integer, optional error code"
.br
.br
......@@ -31,7 +31,7 @@ class(elpa_t), pointer :: elpa
elpa_t handle;
.br
.RI "\fBvoid\fP \fBelpa_uninit\fP ();"
.RI "\fBvoid\fP \fBelpa_uninit\fP (int *error);"
.br
.RI " "
.br
......@@ -39,7 +39,7 @@ elpa_t handle;
.br
.br
.RI "No input or output is needed."
.RI "\fBint *\fP error : the error code"
.br
.SH DESCRIPTION
......
......@@ -163,7 +163,7 @@
!> call elpa%eigenvectors(a, ev, z, success)
!>
!> ! cleanup
!> call elpa_deallocate(e)
!> call elpa_deallocate(e, success)
!>
!> call elpa_uninit()
!> \endcode
......@@ -220,7 +220,7 @@
!> elpa_eigenvectors(handle, a, ev, z, &error);
!>
!> /* cleanup */
!> elpa_deallocate(handle);
!> elpa_deallocate(handle, &error);
!> elpa_uninit();
!> \endcode
!>
......@@ -287,10 +287,10 @@
!> call elpa%store("autotuned_object.txt", success)
!>
!> !deallocate autotune object
!> call elpa_autotune_deallocate(tune_state)
!> call elpa_autotune_deallocate(tune_state, success)
!>
!> ! cleanup
!> call elpa_deallocate(e)
!> call elpa_deallocate(e, success)
!>
!> call elpa_uninit()
!> \endcode
......@@ -313,11 +313,34 @@ module elpa
!> \brief function to allocate an ELPA instance
!> Parameters
!> \details
!> \params error integer, optional : error code
!> \result obj class(elpa_t), pointer : pointer to allocated object
function elpa_allocate() result(obj)
function elpa_allocate(error) result(obj)
use elpa_impl
class(elpa_t), pointer :: obj
obj => elpa_impl_allocate()
class(elpa_t), pointer :: obj
#ifdef USE_FORTRAN2008
integer, optional, intent(out) :: error
#else
integer, intent(out) :: error
#endif
integer :: error2
obj => elpa_impl_allocate(error2)
if (present(error)) then
error = error2
if (error .ne. ELPA_OK) then
write(*,*) "Cannot allocate the ELPA object!"
write(*,*) "This is a critical error!"
write(*,*) "ELPA not usable with this error"
endif
else
if (error2 .ne. ELPA_OK) then
write(*,*) "Cannot allocate the ELPA object!"
write(*,*) "This is a critical error, but you do not check the error codes!"
write(*,*) "ELPA not usable with this error"
stop
endif
endif
end function
......@@ -325,21 +348,91 @@ module elpa
!> Parameters
!> \details
!> \param obj class(elpa_t), pointer : pointer to the ELPA object to be destroyed and deallocated
subroutine elpa_deallocate(obj)
class(elpa_t), pointer :: obj
call obj%destroy()
deallocate(obj)
!> \param error integer, optional : error code
subroutine elpa_deallocate(obj, error)
class(elpa_t), pointer :: obj
#ifdef USE_FORTRAN2008
integer, optional, intent(out) :: error
#else
integer, intent(out) :: error
#endif
integer :: error2
call obj%destroy(error2)
if (present(error)) then
error = error2
if (error .ne. ELPA_OK) then
write(*,*) "Cannot destroy the ELPA object!"
write(*,*) "This is a critical error!"
write(*,*) "This might lead to a memory leak in your application!"
error = ELPA_ERROR_CRITICAL
return
endif
else
if (error2 .ne. ELPA_OK) then
write(*,*) "Cannot destroy the ELPA object!"
write(*,*) "This is a critical error!"
write(*,*) "This might lead to a memory leak in your application!"
write(*,*) "But you do not check the error codes!"
return
endif
endif
deallocate(obj, stat=error2)
if (error2 .ne. 0) then
write(*,*) "Cannot deallocate the ELPA object!"
write(*,*) "This is a critical error!"
write(*,*) "This might lead to a memory leak in your application!"
if (present(error)) then
error = ELPA_ERROR_CRITICAL
return
endif
endif
end subroutine
#ifdef ENABLE_AUTOTUNING
!> \brief function to deallocate an ELPA autotune instance
!> Parameters
!> \details
!> \param obj class(elpa_autotune_t), pointer : pointer to the autotune object to be destroyed and deallocated
subroutine elpa_autotune_deallocate(obj)
!> \param obj class(elpa_autotune_t), pointer : pointer to the autotune object to be destroyed and deallocated
!> \param error integer, optional : error code
subroutine elpa_autotune_deallocate(obj, error)
class(elpa_autotune_t), pointer :: obj
call obj%destroy()
deallocate(obj)
#ifdef USE_FORTRAN2008
integer, optional, intent(out) :: error
#else
integer, intent(out) :: error
#endif
integer :: error2
call obj%destroy(error2)
if (present(error)) then
error = error2
if (error2 .ne. ELPA_OK) then
write(*,*) "Cannot destroy the ELPA autotuning object!"
write(*,*) "This is a critical error!"
write(*,*) "This might lead to a memory leak in your application!"
error = ELPA_ERROR_CRITICAL
return
endif
else
if (error2 .ne. ELPA_OK) then
write(*,*) "Cannot destroy the ELPA autotuning object!"
write(*,*) "This is a critical error!"
write(*,*) "This might lead to a memory leak in your application!"
write(*,*) "But you do not check the error codes"
return
endif
endif
deallocate(obj, stat=error2)
if (error2 .ne. 0) then
write(*,*) "Cannot deallocate the ELPA autotuning object!"
write(*,*) "This is a critical error!"
write(*,*) "This might lead to a memory leak in your application!"
if (present(error)) then
error = ELPA_ERROR_CRITICAL
return
endif
endif
end subroutine
#endif
......
......@@ -96,10 +96,11 @@ function elpa_solve_evp_&
logical, intent(in), optional :: useGPU
logical :: success
integer(kind=c_int) :: successInternal
!integer(kind=c_int) :: successInternal
class(elpa_t), pointer :: e
call mpi_comm_rank(mpi_comm_rows,my_prow,mpierr)
call mpi_comm_rank(mpi_comm_cols,my_pcol,mpierr)
......@@ -110,51 +111,55 @@ function elpa_solve_evp_&
return
endif
e => elpa_allocate()
e => elpa_allocate(error)
if (error .ne. ELPA_OK) then
print *,"Problem calling internal elpa_allocate. Aborting ..."
stop
endif
call e%set("na", na,error)
call e%set("na", na, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("nev", nev,error)
call e%set("nev", nev, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("local_nrows", lda,error)
call e%set("local_nrows", lda, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("local_ncols", matrixCols,error)
call e%set("local_ncols", matrixCols, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("nblk", nblk,error)
call e%set("nblk", nblk, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("mpi_comm_parent", mpi_comm_all,error)
call e%set("mpi_comm_parent", mpi_comm_all, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("mpi_comm_rows", mpi_comm_rows,error)
call e%set("mpi_comm_rows", mpi_comm_rows, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("mpi_comm_cols", mpi_comm_cols,error)
call e%set("mpi_comm_cols", mpi_comm_cols, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
endif
call e%set("timings",1,error)
call e%set("timings",1, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..."
stop
......@@ -166,8 +171,8 @@ function elpa_solve_evp_&
return
endif
call e%set("solver", ELPA_SOLVER_1STAGE, successInternal)
if (successInternal .ne. ELPA_OK) then
call e%set("solver", ELPA_SOLVER_1STAGE, error)
if (error .ne. ELPA_OK) then
print *, "Cannot set ELPA 1stage solver"
success = .false.
return
......@@ -175,15 +180,15 @@ function elpa_solve_evp_&
if (present(useGPU)) then
if (useGPU) then
call e%set("gpu", 1, successInternal)
if (successInternal .ne. ELPA_OK) then
call e%set("gpu", 1, error)
if (error .ne. ELPA_OK) then
print *, "Cannot set gpu"
success = .false.
return
endif
else
call e%set("gpu", 0, successInternal)
if (successInternal .ne. ELPA_OK) then
call e%set("gpu", 0, error)
if (error .ne. ELPA_OK) then
print *, "Cannot set gpu"
success = .false.
return
......@@ -191,8 +196,8 @@ function elpa_solve_evp_&
endif
endif
call e%set("print_flops", 1,successInternal)
if (successInternal .ne. ELPA_OK) then
call e%set("print_flops", 1,error)
if (error .ne. ELPA_OK) then
print *, "Cannot set print_flops"
success = .false.
return
......@@ -204,7 +209,7 @@ function elpa_solve_evp_&
stop
endif
call e%eigenvectors(a(1:lda,1:matrixCols), ev, q(1:ldq,1:matrixCols), successInternal)
call e%eigenvectors(a(1:lda,1:matrixCols), ev, q(1:ldq,1:matrixCols), error)
time_evp_fwd = e%get_time("elpa_solve_evp_&
&MATH_DATATYPE&
......@@ -232,15 +237,23 @@ function elpa_solve_evp_&
if(my_prow==0 .and. my_pcol==0 .and. elpa_print_times) write(error_unit,*) 'Time trans_ev_real:',time_evp_back
endif
if (successInternal .ne. ELPA_OK) then
if (error .ne. ELPA_OK) then
print *, "Cannot solve with ELPA 1stage"
success = .false.
return
endif
call elpa_deallocate(e)
call elpa_deallocate(e, error)
if (error .ne. ELPA_OK) then
print *," Cannot deallocate the internal ELPA object! This might lead to a memory leak!"
! stop
endif
call elpa_uninit()
call elpa_uninit(error)
if (error .ne. ELPA_OK) then
print *," Cannot uninit the internal ELPA object! This might lead to a memory leak!"
! stop
endif
end function
......
......@@ -64,7 +64,7 @@
#endif
logical, intent(in) :: wantDebug
logical :: success
integer(kind=ik) :: successInternal, error
integer(kind=ik) :: error
class(elpa_t), pointer :: e
......@@ -82,7 +82,11 @@
return
endif
e => elpa_allocate()
e => elpa_allocate(error)
if (error .ne. ELPA_OK) then
print *,"Problem calling internal elpa_allocate. Aborting ..."
stop
endif
call e%set("na", na, error)
if (error .ne. ELPA_OK) then
......@@ -142,19 +146,27 @@
stop
endif
endif
call e%cholesky(a(1:lda,1:matrixCols), successInternal)
call e%cholesky(a(1:lda,1:matrixCols), error)
if (successInternal .ne. ELPA_OK) then
if (error .ne. ELPA_OK) then
print *, "Cannot run cholesky"
success = .false.
return
else
success =.true.
endif
call elpa_deallocate(e)
call elpa_uninit()
call elpa_deallocate(e, error)
if (error .ne. ELPA_OK) then
print *," Cannot deallocate the internal ELPA object! This might lead to a memory leak!"
! stop
endif
call elpa_uninit(error)
if (error .ne. ELPA_OK) then
print *," Cannot uninit the internal ELPA object! This might lead to a memory leak!"
! stop
endif
!call timer%stop("elpa_cholesky_&
!&MATH_DATATYPE&
!&_&
......
......@@ -88,7 +88,7 @@
logical, intent(in) :: wantDebug
logical :: success
integer(kind=iK) :: successInternal, error
integer(kind=iK) :: error
class(elpa_t), pointer :: e
!call timer%start("elpa_invert_trm_&
......@@ -105,7 +105,12 @@
return
endif
e => elpa_allocate()
e => elpa_allocate(error)
if (error .ne. ELPA_OK) then
print *,"Problem calling internal elpa_allocate. Aborting ..."
stop
endif
call e%set("na", na, error)
if (error .ne. ELPA_OK) then
......@@ -159,20 +164,29 @@
endif
endif
call e%invert_triangular(a(1:lda,1:matrixCols), successInternal)
call e%invert_triangular(a(1:lda,1:matrixCols), error)
if (successInternal .ne. ELPA_OK) then
if (error .ne. ELPA_OK) then
print *, "Cannot run invert_trm"
success = .false.
return
else
success =.true.
endif
call elpa_deallocate(e)
call elpa_uninit()
call elpa_deallocate(e, error)
if (error .ne. ELPA_OK) then
print *," Cannot deallocate the internal ELPA object! This might lead to a memory leak!"
! stop
endif
call elpa_uninit(error)
if (error .ne. ELPA_OK) then
print *," Cannot uninit the internal ELPA object! This might lead to a memory leak!"
! stop
endif
!call timer%stop("elpa_invert_trm_&
!call timer%stop("elpa_invert_trm_&
!&MATH_DATATYPE&
!&_&
!&PRECISION&
......
......@@ -95,7 +95,7 @@
! integer(kind=ik) :: istat
! character(200) :: errorMessage
logical :: success
integer(kind=ik) :: successInternal, error
integer(kind=ik) :: error
class(elpa_t), pointer :: e
!call timer%start("elpa_mult_at_b_&
......@@ -120,7 +120,11 @@
return
endif
e => elpa_allocate()
e => elpa_allocate(error)
if (error .ne. ELPA_OK) then
print *,"Problem calling internal elpa_allocate. Aborting ..."
stop
endif
call e%set("na", na, error)
if (error .ne. ELPA_OK) then
......@@ -167,16 +171,25 @@
call e%hermitian_multiply(uplo_a, uplo_c, ncb, a(1:lda,1:ldaCols), &
b(1:ldb,1:ldbCols), ldb, ldbCols, &
c(1:ldc,1:ldcCols), ldc, ldcCols, successInternal)
c(1:ldc,1:ldcCols), ldc, ldcCols, error)
if (successInternal .ne. ELPA_OK) then
if (error .ne. ELPA_OK) then
print *, "Cannot run multiply_a_b"
success = .false.
return
endif
call elpa_deallocate(e)
call elpa_uninit()
call elpa_deallocate(e, error)
if (error .ne. ELPA_OK) then
print *," Cannot deallocate the internal ELPA object! This might lead to a memory leak!"
! stop
endif
call elpa_uninit(error)
if (error .ne. ELPA_OK) then
print *," Cannot uninit the internal ELPA object! This might lead to a memory leak!"
! stop
endif
!call timer%stop("elpa_mult_at_b_&
!&MATH_DATATYPE&
......
......@@ -93,7 +93,11 @@
success = .false.
endif
obj => elpa_allocate()
obj => elpa_allocate(error)
if (error .ne. ELPA_OK) then
print *,"Problem calling internal elpa_allocate. Aborting ..."
stop
endif
call obj%set("na", na, error)
if (error .ne. ELPA_OK) then
......@@ -168,8 +172,17 @@
success = .true.
endif
call elpa_deallocate(obj)
call elpa_uninit()
call elpa_deallocate(obj, error)
if (error .ne. ELPA_OK) then
print *," Cannot deallocate the internal ELPA object! This might lead to a memory leak! "
!! stop
endif
call elpa_uninit(error)
if (error .ne. ELPA_OK) then
print *," Cannot uninit the internal ELPA object! This might lead to a memory leak!"
! stop
endif
!call timer%stop("elpa_solve_tridi_&
!&PRECISION&
......
......@@ -89,7 +89,7 @@
integer(kind=c_int) :: my_prow, my_pcol, mpierr
logical :: success
integer(kind=c_int) :: successInternal,error
integer(kind=c_int) :: error
class(elpa_t), pointer :: e
call mpi_comm_rank(mpi_comm_rows,my_prow,mpierr)
......@@ -102,51 +102,55 @@
return
endif
e => elpa_allocate()
e => elpa_allocate(error)
if (error .ne. ELPA_OK) then
print *,"Problem calling internal elpa_allocate. Aborting ..."
stop
endif
call e%set("na", na,error)
call e%set("na", na, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting..."
stop
endif
call e%set("nev", nev,error)
call e%set("nev", nev, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting..."
stop
endif
call e%set("local_nrows", lda,error)
call e%set("local_nrows", lda, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting..."
stop
endif
call e%set("local_ncols", matrixCols,error)
call e%set("local_ncols", matrixCols, error)
if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting..."
stop
endif
call e%set("nblk", nblk,error)
call e%set("nblk", nblk,