Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New ForTrilinos.h and forerror module, prefixed ierr and serr #169

Merged
merged 4 commits into from
Dec 19, 2017

Conversation

aprokop
Copy link
Collaborator

@aprokop aprokop commented Dec 16, 2017

Compiles but setfaults.

@codecov-io
Copy link

codecov-io commented Dec 16, 2017

Codecov Report

Merging #169 into develop will decrease coverage by 0.08%.
The diff coverage is 74.32%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #169      +/-   ##
===========================================
- Coverage    38.21%   38.12%   -0.09%     
===========================================
  Files           31       33       +2     
  Lines        13454    13462       +8     
===========================================
- Hits          5141     5133       -8     
- Misses        8313     8329      +16
Impacted Files Coverage Δ
src/teuchos/src/forteuchos.f90 38.79% <ø> (ø) ⬆️
src/teuchos/src/forteuchosFORTRAN_wrap.cxx 41.82% <ø> (-0.73%) ⬇️
src/simple/test/test_simple_solver_handle.cpp 98.11% <ø> (ø) ⬆️
...rc/simple/test/test_simple_eigen_handle_preset.cpp 95.45% <ø> (ø) ⬆️
src/teuchos/test/test_teuchos_comm.f90 100% <ø> (ø) ⬆️
src/simple/src/fortrilinos.f90 57.25% <ø> (ø) ⬆️
src/simple/test/test_simple_eigen_handle.cpp 97.22% <ø> (ø) ⬆️
src/tpetra/src/fortpetra.f90 36.15% <ø> (ø) ⬆️
src/teuchos/test/test_teuchos_plist.f90 100% <ø> (ø) ⬆️
src/tpetra/tutorials/PowerMethod.f90 89.07% <0%> (-0.1%) ⬇️
... and 15 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d30922c...82810ec. Read the comment docs.

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 16, 2017

Rebased on top of develop.

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 16, 2017

I'm pretty OK with merging this as it is. The main goal of removing the global space pollution has been achieved.

It could be further improved, though, to simplify users life:

  • Add CHECK_IERR macro to ForTrilinos.h header.
    It has to be renamed to something prefixed first, though, check_trilinos_ierr or similar
  • The set/get functionality
    I'm still not sure if I see it's benefit.

@tjfulle Could move the CHECK_IERR out of FortranTestingUtilities.h and put it renamed version in ForTrilinos.h? I think this should not be too hard. You are also welcome to put in the set/get but it is strictly optional, and may cause more trouble than necessary (right now, forerror.f90 is SWIG-generated; if you put functions there, I'll need to figure out how to update forerror.i file to put stuff just in that file).

@aprokop aprokop changed the title [WIP] module for errors New ForTrilinos.h and forerror module, prefixed ierr and serr Dec 16, 2017
@tjfulle
Copy link
Collaborator

tjfulle commented Dec 16, 2017

Ya, I can move CHECK_ERROR in to the header. I didn’t much like it in the testing header anyway. What should it be named? FORTRILINOS_CHECKERR, CHECK_TRILINOS_ERROR, other?

Do you want to merge first and then I’ll make changes on top?

User code should mostly use the check error macro, so adding extra getter/setter is probably superfluous. And, I don’t want to modify the swig...

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 16, 2017

Ya, I can move CHECK_ERROR in to the header. I didn’t much like it in the testing header anyway. What should it be named? FORTRILINOS_CHECKERR, CHECK_TRILINOS_ERROR, other?

Don't know, all this sound pretty bad to me. But I can't find a better one. I guess CHECK_TRILINOS_ERROR. One thing here is that I don't actually know what this macro should do. We should not stop/terminate user's program, and we should not unconditionally output on the screen. Or at least, we should provide a user with a way to modify the behavior of this error check macro. So I'm not convinced if it should exposed unless it is heavily modified. In addition, it is using fortest which I don't want to install.

Do you want to merge first and then I’ll make changes on top?

Sure. But right now there is a hidden problem with this PR somewhere. Everything is fine and dandy building with gcc, but flang build fails for Tpetra tutorials with a linker error:

./../utils/src/libforerror.so.12.12.1: undefined reference to `fortrilinos_ierr' 

I really have trouble figuring out why.

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 17, 2017

The dependence of CHECK_IERR on fortest is minimal, and not needed.

To the other concern, I believe that if the macro is called, the code should stop and give an error message. If a user wants to query ierr independent of the macro, nothing is stopping them

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

Weird, compiling forerror.f90 in gcc gives

$ nm forerror.f90.o
0000000000000000 B fortrilinos_ierr    
0000000000000000 D fortrilinos_serr  

but in flang it gives

0000000000000000 T forerror_           
0000000000000000 D fortrilinos_serr 

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

Even more fun: removing initialization of fortrilinos_serr produces correct thing in flang:

0000000000000000 T forerror_           
0000000000000000 B fortrilinos_ierr 

So, somehow, initialization of fortrilinos_serr breaks stuff. Maybe I should update my flang installation. Furthermore, switching places of fortrilinos_ierr and fortrilinos_serr results in fortrilinos_ierr being present and fortrilinos_serr absent.

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

Just noticed that flang produces a warning which seems to indicate that maybe the code is wrong:

F90-W-0164-Overlapping data initializations of fortrilinos_ierr

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 17, 2017

Stupid thought, Do you get the same error if the variables are named ierr and serr?

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

The following patch seems to fix the issue:

diff --git a/src/utils/src/forerror.f90 b/src/utils/src/forerror.f90
index 7d698ea..5e29ef0 100644
--- a/src/utils/src/forerror.f90
+++ b/src/utils/src/forerror.f90
@@ -23,8 +23,8 @@ module forerror
  ! PARAMETERS
  integer(C_INT), parameter, public :: SWIG_FORTRAN_ERROR_STRLEN = 1024_C_INT
 
- integer(C_INT), bind(C) :: fortrilinos_ierr = 0
- character(kind=C_CHAR, len=1024), bind(C) :: fortrilinos_serr = ""
+ integer(C_INT), bind(C) :: fortrilinos_ierr
+ character(kind=C_CHAR, len=1024), bind(C) :: fortrilinos_serr
 
 
 end module
diff --git a/src/utils/src/forerrorFORTRAN_wrap.cxx b/src/utils/src/forerrorFORTRAN_wrap.cxx
index 2c45228..8a08fa4 100644
--- a/src/utils/src/forerrorFORTRAN_wrap.cxx
+++ b/src/utils/src/forerrorFORTRAN_wrap.cxx
@@ -217,8 +217,8 @@ template <typename T> T SwigValueInit() {
 
 
 extern "C" {
-extern int fortrilinos_ierr;
-extern char fortrilinos_serr[1024];
+int fortrilinos_ierr = 0;
+char fortrilinos_serr[1024] = "";
 }

@sethrj Thoughts?

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

@tjfulle No, but that also without the separate forerror module. I'm not sure why. It could be that it was still lying in the wait.

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

According to this:

The following notes or guidelines apply to interoperable global variables:

    - Within the scope of a program, you can bind only one Fortran variable to a C variable with external linkage.

It seems that we were trying to bind 2 Fortran variables to C variables with external linkage, and the compiler caught us doing the naughty.

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 17, 2017

What????? This is good reason to use many compilers before releasing a product...

Alternatively, can serr stay in the C side and be accessed as needed through a function? Code can query ierr and retrieve serr in the event that ierr/=0

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

Alternatively, can serr stay in the C side and be accessed as needed through a function? Code can query ierr and retrieve serr in the event that ierr/=0

I guess it could. I just don't want to spend too much time on this, and want to see what @sethrj says.

@sethrj
Copy link
Collaborator

sethrj commented Dec 17, 2017

@aprokop @tjfulle I still don't understand the motivation for these changes. I considered and tried multiple ways of handling this when developing the error handling. Do you want each module to have separate error variables? That would break the interface because a function in one module wouldn't know if an upstream module had thrown an unhandled exception on a previous call.

If the purpose is not to have ierr and serr in the global namespace, I thought that these variables were implicitly scoped by module (different modules can have the same variable name, right?) But if that isn't sufficient, if you look in <fortran/exception.i> you'll see that I anticipated people wanting to rename the flags: if you want to scope them as fortrilinos_ierr and fortrilinos_serr simply modify your forerror.i file to read:

#define SWIG_FORTRAN_ERROR_INT fortrilinos_ierr
#define SWIG_FORTRAN_ERROR_STR fortrilinos_serr
#define SWIG_FORTRAN_ERROR_STRLEN 1024
%include <exception.i>

and then alias the variables as needed downstream:

program test_foo
   use forerror, only : ierr => fortrilinos_ierr, serr => fortrilinos_serr
   ...

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 17, 2017

My motivation in bringing it up originally was to discuss whether the global error handling should be done independent of forteuchos. I definitely would hate to see different error handling in individual modules. I believe @aprokop discovered a bug in our implementation that interoperable C++/Fortran programs can share only one global variable and we were sharing two (serr and ierr)

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 17, 2017

@sethrj In #181 I put in the workarounds for ierr and serr treatment that were required to be able to compile with flang. That was for the original error treatment, without forerror module.

@sethrj
Copy link
Collaborator

sethrj commented Dec 18, 2017

OK @aprokop I've got a new version of SWIG that only binds the one value ierr and provides a function get_serr() that returns an allocatable string.

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 18, 2017

@tjfulle @sethrj I updated the PR, and it seems to work beautifully! @sethrj Your fixes did the thing and I no longer need to patch ForTrilinos to compile with flang.

I put the error module into forerror together with FORTRILINOS_CHECK_IERR macro. @tjfulle Do we need anything else in this PR?

@aprokop aprokop requested a review from tjfulle December 18, 2017 22:29
@tjfulle
Copy link
Collaborator

tjfulle commented Dec 19, 2017

@aprokop this looks much better!

There seems to be one inconsistency, but only for the tests. ForTrilinosTestUtilities.h seems to implicitly use ForTrilinos.h (by virtue of calling FORTRILINOS_CHECK_IERR), but it does not include it. You have included ForTrilinos.h in each test, but should it be included in ForTrilinosTestUtilities.h?

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 19, 2017

@tjfulle Good point! I'll fix that.

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 19, 2017

@aprokop also, to save space on macro length, the FORTRILINOS_TEST_IERR macro doesn't need to take the error message, it can call it itself from within and only if FORTRILINOS_IERR /= 0

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 19, 2017

@tjfulle FORTRILINOS_TEST_IERR?

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 19, 2017

Pushed the update. One thing that remains to be done is to actually test that we get a proper string of the exception. I am actually not sure.

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 19, 2017

@aprokop, ya, the macro TEST_IERR calls the subroutine fortrilinos_test_ierr (in fortest.f90). If fortest.f90 used forerror there is no need to explicitly pass ierr and friends.

Typing with thumbs, hopefully that made sense

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 19, 2017

If we’ve taken FORTRILINOS_SERRour of the interface to FORTRILINOS_TEST_IERR, should we also remove FORTRILINOS_IERR?

- Modify fortest_ierr to not pass ierr and serr;
- include ForTrilinos.h in FortranTestUtilities.h
@aprokop
Copy link
Collaborator Author

aprokop commented Dec 19, 2017

@tjfulle I think I did what you wanted me to, take a look. Independently, should we add printing of serr to other testing macros? Otherwise, you will get failures but it's going to be hard to figure out why. Are the macros supposed to work only with ierr or are they more general?

I also checked that indeed we can get and print proper Trilinos exception in Fortran. So I think we are good here.

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 19, 2017

@aprokop , it took me a minute to think of what you were saying, but if I understand, you are saying any test function that queries ierr and marks a test failed should include serr in the error message (in addition to the signature). If I understand correctly, then yes, I agree. The procedure write_error_stuff (on my phone, don’t remember the actual name) could be modified to print serr without touching anything else

@tjfulle
Copy link
Collaborator

tjfulle commented Dec 19, 2017

Actually, most of the other test macros just check for correctness and operate independent of ierr

@aprokop aprokop merged commit 3b9bb19 into trilinos:develop Dec 19, 2017
@aprokop aprokop deleted the ierr_fix branch December 19, 2017 02:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants