Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

IMSL error writing to console

durisinm
Novice
1,104 Views
I have an Excel VBA application that calls a VF DLL. Each subroutine in my DLL calls a particular IMSL routine. The subroutine that calls IMSL routine LINRG is failing with the message, "forrtl: severe (38): error during write, unit 6, file CONOUT$". Following that is a traceback listing through DFORRTD.DLL, PFRheometer.dll (my application), VBE6.DLL, OLEAUT32.dll, and VBE6.DLL. The values for Routine, Line, and Source in all of these lines are "Unknown" except for one of the routines, INVERTALPHADU, in PFRheometer.dll. That line lists the line number that makes the call to LINRG.

I'm guessing that LINRG is issuing some kind of error message to the console. I want to see it, but I'm not sure how to do that. I tried OPENing unit 6 with file='CONOUT$' before the call to LINRG, but that didn't change anything. I know that I've seen postings mentioning a Windows routine to provide a console in this forum or the old Compaq one, but I couldn't find any by searching.

Anybody got any suggestions on how to proceed?

I'm surprised that Visual Numerics would have the IMSL routines spitting out messages to the console. Returning error codes to the caller seems to be the better way to go. I don't remember seeing any mention of this when I looked through the IMSL documentation to find the routines I needed.

Mike
0 Kudos
11 Replies
james1
Beginner
1,105 Views
You can add a call to AllocConsole() to accept I/O directed to the console before that call. You can also add a PAUSE after the call to the offending routine as a "breakpoint" so you can read the message.

For example:

use kernel32
...
call AllocConsole()
...
call LINRG(...)
pause
...

James
0 Kudos
durisinm
Novice
1,105 Views
James,

Thank you. That worked. I didn't need the PAUSE statement because I'm working with a debug configuration, and the debugger stopped at the next statement and allowed me to see the message in the console window.

When I looked up the definition for AllocConsole in the VF online help, it was defined as BOOL AllocConsole(void). Is it always the case when the VC++ definition for a variable is (void) that you simply use the empty parentheses () in the equivalent VF call?

Mike
0 Kudos
Steven_L_Intel1
Employee
1,105 Views
(void) means no arguments, so just:

call AllocConsole

would work.

Steve
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,105 Views
Yes, C++ void means "nothing" (and if function result, means "subroutine"). But you shouldn't substitute function for a subroutine; James made a typo. Although you may not see apparent effect, I think that corrupts the stack in Fortran. Maybe I'm wrong, but it's better to be on the safe side.
0 Kudos
Intel_C_Intel
Employee
1,105 Views
Mike,

We use the NAG maths libraries and their intrinsic diagnostic output gives us no end of headaches. I've seen the exact error you quote! Because the code is so ancient (F77 and previous!), output defaults to unit 6. NAG has a couple of controlling routines that allow you to specify a) whether you want any output, and b) what LUN to write it to (i.e. to a sepcified file),. If you don't call those routines prior to your routine of interest, you're likely to end up with output being written to unit 6, and thence to crashing and burning.

The origins of all these major maths libraries seem a bit incestuous, so I wouldn't be surprised if IMSL works in a similar manner - look for routines that control the diagnostic output.
0 Kudos
Intel_C_Intel
Employee
1,105 Views
Look at ERSET for instance :)

Dan
0 Kudos
james1
Beginner
1,105 Views
General comment, I like to use empty parenthesis for consistency and readability for calls lacking formal parameters.

Jugoslav, you are incorrect about corrupting the stack. In this case the compiler simply doesn't use the call return register. Is there a reason you think CVF wouldn't handle this?

James
0 Kudos
Steven_L_Intel1
Employee
1,105 Views
You can corrupt the floating point stack if you call a function that returns a floating result in a way that the caller doesn't see the result, or if you call a function that DOESN'T return a floating result in a way that makes the caller think it does. There's no problem with functions that return integer results.

Steve
0 Kudos
durisinm
Novice
1,105 Views
Dan,

I looked up the ERSET routine, and it will allow me to suppress output from all of the IMSL routines. I'll use that once I solve my problem with using LINRG. Even though I can call FreeConsole to get rid of every console I create with AllocConsole, my application makes the console windows dance across the screen because it calls LINRG many times. Although somewhat entertaining, I doubt that it's what the users want to see, and creating and destroying all those windows has got to be taking extra time.

Mike
0 Kudos
Intel_C_Intel
Employee
1,105 Views
Mike,

One strategy we've used in the past is to turn off intrinsic diagnostics, but watch the error conditions from the maths routines, and create your own diagnostics that you can control and send where you want. This is a bit more work, but can be D-Lined so that it can be used to get the code working, but ultimatley has little effect on the speed.

Dan
0 Kudos
gkchang
Beginner
1,105 Views
My VB collegue won't allow me to "allocate a console" when my Fortran DLL (using IMSL calls) is fired by his VB app. The method Judd proposed cannot capture all reported errors for all IMSL function calls. Therefore, I use a wrapper for every IMSL function call using a simple mechanism as follows:

! open a file in case IMSL function may dump error info
   call file_open(cs_dumppath,cs_subname,io_unit)  

! set imsl routine to report all levels of errors
! print error message and do not stop if error ocurrs
   call erset(0,1,0)                               

! open a file and re-direct the imsl error output to this file
   call umach(-3,io_unit)                          

! call the IMSL 
   call IMSL_Function

! Get the IMSL error code & do proper handling
   imsl_errcode = iercd()   
 
   if (imsl_errcode /= 0) then         
       !extract error message from the error dump file
       !and report to global error log 
       call read_imslerr(io_unit) 
   end if


Any other idea?

-George
0 Kudos
Reply