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

Error return codes for all API functions

parent eb62d23a
...@@ -13,7 +13,7 @@ use elpa ...@@ -13,7 +13,7 @@ use elpa
class(elpa_t), pointer :: elpa class(elpa_t), pointer :: elpa
.br .br
.RI "elpa => \fBelpa_allocate\fP ()" .RI "elpa => \fBelpa_allocate\fP (error)"
.br .br
.RI " " .RI " "
.br .br
...@@ -22,7 +22,7 @@ class(elpa_t), pointer :: elpa ...@@ -22,7 +22,7 @@ class(elpa_t), pointer :: elpa
.br .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 .br
.RI "integer, optional :: \fBerror\fp ! a returned error code
.br .br
.SS C INTERFACE .SS C INTERFACE
#include <elpa/elpa.h> #include <elpa/elpa.h>
...@@ -30,7 +30,7 @@ class(elpa_t), pointer :: elpa ...@@ -30,7 +30,7 @@ class(elpa_t), pointer :: elpa
elpa_t handle; elpa_t handle;
.br .br
.RI "\fBelpa_t\fP handle = \fBelpa_allocate\fP();" .RI "\fBelpa_t\fP handle = \fBelpa_allocate\fP(\fBint\fP *error);"
.br .br
.RI " " .RI " "
.br .br
...@@ -39,6 +39,10 @@ elpa_t handle; ...@@ -39,6 +39,10 @@ elpa_t handle;
.br .br
.br .br
.RI "elpa_t \fBhandle\fP; // returns an handle to the allocated ELPA object" .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 .SH DESCRIPTION
Allocate an ELPA object. The function \fBelpa_init\fP(3) must be called once \fIBEFORE\fP \fBelpa_allocate\fP can be called. 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 ...@@ -14,7 +14,7 @@ class(elpa_t), pointer :: elpa
class(elpa_autotune_t), pointer :: tune_state class(elpa_autotune_t), pointer :: tune_state
.br .br
.RI "call\fBelpa%autotune_deallocate\fP (tune_state)" .RI "call\fBelpa%autotune_deallocate\fP (tune_state, error)"
.br .br
.RI " " .RI " "
.br .br
...@@ -23,6 +23,9 @@ class(elpa_autotune_t), pointer :: tune_state ...@@ -23,6 +23,9 @@ class(elpa_autotune_t), pointer :: tune_state
.br .br
.RI "type(elpa_autotune_t) :: \fBtune_state\fP ! the ELPA autotuning object, created with \fBelpa_autotune_setup\fP(3) .RI "type(elpa_autotune_t) :: \fBtune_state\fP ! the ELPA autotuning object, created with \fBelpa_autotune_setup\fP(3)
.br .br
.RI "integer, optional :: \fBerror\fP ! the returned error code
.br
.br
.SS C INTERFACE .SS C INTERFACE
#include <elpa/elpa.h> #include <elpa/elpa.h>
.br .br
...@@ -30,7 +33,7 @@ elpa_t handle; ...@@ -30,7 +33,7 @@ elpa_t handle;
elpa_autotune_t autotune_handle; elpa_autotune_t autotune_handle;
.br .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 .br
.RI " " .RI " "
.br .br
...@@ -41,7 +44,10 @@ elpa_autotune_t autotune_handle; ...@@ -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)" .RI "elpa_t \fBhandle\fP; // the handle of an ELPA object, obtained before with \fBelpa_allocate\fP(3)"
.br .br
.RI "elpa_autotune_t \fBautotune_handle\fP; // the handle of an ELPA object, obtained before with \fBelpa_autotune_setup\fP(3)" .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 .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) 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" .SH "SEE ALSO"
......
...@@ -13,7 +13,7 @@ use elpa ...@@ -13,7 +13,7 @@ use elpa
class(elpa_t), pointer :: elpa class(elpa_t), pointer :: elpa
.br .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 .br
.RI " " .RI " "
.br .br
...@@ -22,7 +22,8 @@ class(elpa_t), pointer :: elpa ...@@ -22,7 +22,8 @@ class(elpa_t), pointer :: elpa
.br .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 .br
.RI "integer, optional :: \fBerror\fP ! the returned error code"
.br
.br .br
.SS C INTERFACE .SS C INTERFACE
#include <elpa/elpa.h> #include <elpa/elpa.h>
...@@ -30,7 +31,7 @@ class(elpa_t), pointer :: elpa ...@@ -30,7 +31,7 @@ class(elpa_t), pointer :: elpa
elpa_t handle; elpa_t handle;
.br .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 .br
.RI " " .RI " "
.br .br
...@@ -39,7 +40,10 @@ elpa_t handle; ...@@ -39,7 +40,10 @@ elpa_t handle;
.br .br
.br .br
.RI "elpa_t \fBhandle\fP; // the handle to the ELPA instance which should be deallocated." .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 .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. 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 .br
......
...@@ -13,14 +13,14 @@ use elpa ...@@ -13,14 +13,14 @@ use elpa
class(elpa_t), pointer :: elpa class(elpa_t), pointer :: elpa
.br .br
.RI "call \fBelpa_uninit\fP ()" .RI "call \fBelpa_uninit\fP (error)"
.br .br
.RI " " .RI " "
.br .br
.RI "With the definitions of the input and output variables:" .RI "With the definitions of the input and output variables:"
.br .br
.RI "No input or output is needed." .RI "error integer, optional error code"
.br .br
.br .br
...@@ -31,7 +31,7 @@ class(elpa_t), pointer :: elpa ...@@ -31,7 +31,7 @@ class(elpa_t), pointer :: elpa
elpa_t handle; elpa_t handle;
.br .br
.RI "\fBvoid\fP \fBelpa_uninit\fP ();" .RI "\fBvoid\fP \fBelpa_uninit\fP (int *error);"
.br .br
.RI " " .RI " "
.br .br
...@@ -39,7 +39,7 @@ elpa_t handle; ...@@ -39,7 +39,7 @@ elpa_t handle;
.br .br
.br .br
.RI "No input or output is needed." .RI "\fBint *\fP error : the error code"
.br .br
.SH DESCRIPTION .SH DESCRIPTION
......
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
!> call elpa%eigenvectors(a, ev, z, success) !> call elpa%eigenvectors(a, ev, z, success)
!> !>
!> ! cleanup !> ! cleanup
!> call elpa_deallocate(e) !> call elpa_deallocate(e, success)
!> !>
!> call elpa_uninit() !> call elpa_uninit()
!> \endcode !> \endcode
...@@ -220,7 +220,7 @@ ...@@ -220,7 +220,7 @@
!> elpa_eigenvectors(handle, a, ev, z, &error); !> elpa_eigenvectors(handle, a, ev, z, &error);
!> !>
!> /* cleanup */ !> /* cleanup */
!> elpa_deallocate(handle); !> elpa_deallocate(handle, &error);
!> elpa_uninit(); !> elpa_uninit();
!> \endcode !> \endcode
!> !>
...@@ -287,10 +287,10 @@ ...@@ -287,10 +287,10 @@
!> call elpa%store("autotuned_object.txt", success) !> call elpa%store("autotuned_object.txt", success)
!> !>
!> !deallocate autotune object !> !deallocate autotune object
!> call elpa_autotune_deallocate(tune_state) !> call elpa_autotune_deallocate(tune_state, success)
!> !>
!> ! cleanup !> ! cleanup
!> call elpa_deallocate(e) !> call elpa_deallocate(e, success)
!> !>
!> call elpa_uninit() !> call elpa_uninit()
!> \endcode !> \endcode
...@@ -313,11 +313,34 @@ module elpa ...@@ -313,11 +313,34 @@ module elpa
!> \brief function to allocate an ELPA instance !> \brief function to allocate an ELPA instance
!> Parameters !> Parameters
!> \details !> \details
!> \params error integer, optional : error code
!> \result obj class(elpa_t), pointer : pointer to allocated object !> \result obj class(elpa_t), pointer : pointer to allocated object
function elpa_allocate() result(obj) function elpa_allocate(error) result(obj)
use elpa_impl use elpa_impl
class(elpa_t), pointer :: obj class(elpa_t), pointer :: obj
obj => elpa_impl_allocate() #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 end function
...@@ -325,10 +348,45 @@ module elpa ...@@ -325,10 +348,45 @@ module elpa
!> Parameters !> Parameters
!> \details !> \details
!> \param obj class(elpa_t), pointer : pointer to the ELPA object to be destroyed and deallocated !> \param obj class(elpa_t), pointer : pointer to the ELPA object to be destroyed and deallocated
subroutine elpa_deallocate(obj) !> \param error integer, optional : error code
subroutine elpa_deallocate(obj, error)
class(elpa_t), pointer :: obj class(elpa_t), pointer :: obj
call obj%destroy() #ifdef USE_FORTRAN2008
deallocate(obj) 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 end subroutine
#ifdef ENABLE_AUTOTUNING #ifdef ENABLE_AUTOTUNING
...@@ -336,10 +394,45 @@ module elpa ...@@ -336,10 +394,45 @@ module elpa
!> Parameters !> Parameters
!> \details !> \details
!> \param obj class(elpa_autotune_t), pointer : pointer to the autotune object to be destroyed and deallocated !> \param obj class(elpa_autotune_t), pointer : pointer to the autotune object to be destroyed and deallocated
subroutine elpa_autotune_deallocate(obj) !> \param error integer, optional : error code
subroutine elpa_autotune_deallocate(obj, error)
class(elpa_autotune_t), pointer :: obj class(elpa_autotune_t), pointer :: obj
call obj%destroy() #ifdef USE_FORTRAN2008
deallocate(obj) 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 end subroutine
#endif #endif
......
...@@ -96,10 +96,11 @@ function elpa_solve_evp_& ...@@ -96,10 +96,11 @@ function elpa_solve_evp_&
logical, intent(in), optional :: useGPU logical, intent(in), optional :: useGPU
logical :: success logical :: success
integer(kind=c_int) :: successInternal !integer(kind=c_int) :: successInternal
class(elpa_t), pointer :: e class(elpa_t), pointer :: e
call mpi_comm_rank(mpi_comm_rows,my_prow,mpierr) call mpi_comm_rank(mpi_comm_rows,my_prow,mpierr)
call mpi_comm_rank(mpi_comm_cols,my_pcol,mpierr) call mpi_comm_rank(mpi_comm_cols,my_pcol,mpierr)
...@@ -110,51 +111,55 @@ function elpa_solve_evp_& ...@@ -110,51 +111,55 @@ function elpa_solve_evp_&
return return
endif 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 if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif endif
call e%set("nev", nev,error) call e%set("nev", nev, error)
if (error .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif endif
call e%set("local_nrows", lda,error) call e%set("local_nrows", lda, error)
if (error .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif endif
call e%set("local_ncols", matrixCols,error) call e%set("local_ncols", matrixCols, error)
if (error .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif endif
call e%set("nblk", nblk,error) call e%set("nblk", nblk, error)
if (error .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif 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 if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif 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 if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif 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 if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
endif endif
call e%set("timings",1,error) call e%set("timings",1, error)
if (error .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *,"Problem setting option. Aborting ..." print *,"Problem setting option. Aborting ..."
stop stop
...@@ -166,8 +171,8 @@ function elpa_solve_evp_& ...@@ -166,8 +171,8 @@ function elpa_solve_evp_&
return return
endif endif
call e%set("solver", ELPA_SOLVER_1STAGE, successInternal) call e%set("solver", ELPA_SOLVER_1STAGE, error)
if (successInternal .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *, "Cannot set ELPA 1stage solver" print *, "Cannot set ELPA 1stage solver"
success = .false. success = .false.
return return
...@@ -175,15 +180,15 @@ function elpa_solve_evp_& ...@@ -175,15 +180,15 @@ function elpa_solve_evp_&
if (present(useGPU)) then if (present(useGPU)) then
if (useGPU) then if (useGPU) then
call e%set("gpu", 1, successInternal) call e%set("gpu", 1, error)
if (successInternal .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *, "Cannot set gpu" print *, "Cannot set gpu"
success = .false. success = .false.
return return
endif endif
else else
call e%set("gpu", 0, successInternal) call e%set("gpu", 0, error)
if (successInternal .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *, "Cannot set gpu" print *, "Cannot set gpu"
success = .false. success = .false.
return return
...@@ -191,8 +196,8 @@ function elpa_solve_evp_& ...@@ -191,8 +196,8 @@ function elpa_solve_evp_&
endif endif
endif endif
call e%set("print_flops", 1,successInternal) call e%set("print_flops", 1,error)
if (successInternal .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *, "Cannot set print_flops" print *, "Cannot set print_flops"
success = .false. success = .false.
return return
...@@ -204,7 +209,7 @@ function elpa_solve_evp_& ...@@ -204,7 +209,7 @@ function elpa_solve_evp_&
stop stop
endif 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_& time_evp_fwd = e%get_time("elpa_solve_evp_&
&MATH_DATATYPE& &MATH_DATATYPE&
...@@ -232,15 +237,23 @@ function elpa_solve_evp_& ...@@ -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 if(my_prow==0 .and. my_pcol==0 .and. elpa_print_times) write(error_unit,*) 'Time trans_ev_real:',time_evp_back
endif endif
if (successInternal .ne. ELPA_OK) then if (error .ne. ELPA_OK) then
print *, "Cannot solve with ELPA 1stage" print *, "Cannot solve with ELPA 1stage"
success = .false. success = .false.
return return
endif 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 end function
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
#endif #endif
logical, intent(in) :: wantDebug logical, intent(in) :: wantDebug
logical :: success logical :: success
integer(kind=ik) :: successInternal, error integer(kind=ik) :: error
class(elpa_t), pointer :: e class(elpa_t), pointer :: e
...@@ -82,7 +82,11 @@ ...@@ -82,7 +82,11 @@
return return
endif 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 if (error .ne. ELPA_OK) then
...@@ -142,19 +146,27 @@ ...@@ -142,19 +146,27 @@
stop stop
endif endif
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" print *, "Cannot run cholesky"
success = .false. success = .false.
return return
else else
success =.true. success =.true.
endif 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_& !call timer%stop("elpa_cholesky_&
!&MATH_DATATYPE& !&MATH_DATATYPE&
!&_& !&_&
......
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
logical, intent(in) :: wantDebug logical, intent(in) :: wantDebug
logical :: success logical :: success
integer(kind=iK) :: successInternal, error integer(kind=iK) :: error
class(elpa_t), pointer :: e class(elpa_t), pointer :: e
!call timer%start("elpa_invert_trm_& !call timer%start("elpa_invert_trm_&
...@@ -105,7 +105,12 @@ ...@@ -105,7 +105,12 @@
return return
endif endif