forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Interesting EXP(X) problem Invalid Floating Point Operation
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
rrobe71907



Joined: 26 Sep 2014
Posts: 10
Location: Tamaqua PA

PostPosted: Fri Nov 07, 2014 10:33 pm    Post subject: Interesting EXP(X) problem Invalid Floating Point Operation Reply with quote

Have an interesting problem. Over the years, have done a lot of mixed language programming (main program written in one language calling a subroutine written in another; subroutines written in different languages calling each other) on a couple of different platforms.

Currently playing with D main programs calling FORTRAN subroutines.

when the following is used as real function in FORTRAN
main program (ENG0010.exe) the function runs fine
--------------------------

C Series Resistance Capacitance Circuit
C Resistance Capacitance Time
C T : Seconds
C R : Ohms
C C : Farads
REAL FUNCTION ERCT (T, R, C) RESULT (X)
REAL T, R, C, X
X = T / (R * C)
X = EXP(X)
RETURN
END FUNCTION ERCT


when used in a .dll (mathproc.dll) called by a D command line
program (dmath.exe, compiled with DMD dmath.d mathproc.lib),
function crashes at X = EXP(X) with
object.Error@(0): Invalid Floating Point Operation
in RegisterWaitForInputIdle
(I suspect that is a DMD v2.066.0 compiler specific message/error)

The FORTRAN main program:
PROGRAM ENG0010
IMPLICIT NONE

REAL E, T, R, C, L, I, ERCT, VCAP, V, TMP

C = 0.000018;
R = 8100.0;
E = 20.0;
T = 0.31;
TMP = ERCT (T, R, C)
PRINT '(a,F7.2)',' ERCT (T, R, C): ', TMP
V = VCAP (E, T, R, C)
PRINT '(a,F7.2)',' VCAP (E, T, R, C): ', V

END

The D main program:
import std.stdio;

// mathproc.dll subroutine declarations
extern (Pascal)
{
float ERCT (ref float, ref float, ref float);
float VCAP (ref float, ref float, ref float, ref float);
}

int main(string[] args)
{
float C, R, t, E, L, V, I, tmp;

C = 0.000018;
R = 8100.0;
E = 20.0;
t = 0.31;
tmp = ERCT (C,R,t);
printf (" ERCT (C,R,t): %f \n", tmp);
V = VCAP(C,R,t,E);
printf (" VCAP(C,R,t,E): %f \n", V);
return (0);
}

[extern (Pascal) requires the parameters passed in reverse order; this was the only way I could get the D mains/FORTRAN .dll's compile/link cleanly]

Dependency Walker shows the ENG0010.exe version calls __FTN95INIT1_,
dmath.exe does not.


When dmath.exe profiled with Dependency Walker, received the following error:
Second chance exception 0xC0000090 (Float Invalid Operation) occurred in "SALFLIBC.DLL" at address 0x0053EB0A.

Have successfully called other float/REAL*4 FORTRAN functions from both
D command line and Windows programs; only time I have seen similar errors was when I should have used REAL*8 instead of REAL*4, so tried that correction; same result.

Can think of several possibilities:
1. I am blind and cannot see an obvious error
2. I need to call some sort of floating point initializer
or arithmetic trap; is it possible to call __FTN95INIT1_ (or its equivalent)
directly?
3. D calling FORTRAN function EXP(X) may have some minor
eccentricity/incompatibility.

Would someone like to admit my ignorance for me? Wink
Would not be surprised if I did something goofy. Wink

Thanks for reading this post.
_________________
Rodney Roberts
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sat Nov 08, 2014 9:08 am    Post subject: Reply with quote

I think that you may need to find a way to load salflibc.dll at the start.
Perhaps a call to LoadLibrary will do the trick. There is a similar comment in the instructions for using FTN95 with Visual Basic. See the knowledge base of this forum or ftn95.chm.
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Sat Nov 08, 2014 11:56 am    Post subject: Reply with quote

Try adding
call mask_underflow@()
somewhere at the start
Back to top
View user's profile Send private message
rrobe71907



Joined: 26 Sep 2014
Posts: 10
Location: Tamaqua PA

PostPosted: Sat Nov 08, 2014 8:19 pm    Post subject: Interesting EXP(X) problem Invalid Floating Point Operatio Reply with quote

Gentlemen:

Thanks, I will follow up on both your approaches and let you know the results.
_________________
Rodney Roberts
Back to top
View user's profile Send private message Visit poster's website
rrobe71907



Joined: 26 Sep 2014
Posts: 10
Location: Tamaqua PA

PostPosted: Mon Nov 10, 2014 11:11 pm    Post subject: Results of suggested fixes Reply with quote

The results of your suggestions:

added

LoadLibraryA ("C:\\Program Files\\Silverfrost\\FTN95 Express\\salflibc.dll");

(DMD's implementation of LoadLibrary; more info at dlang.org) to dmath.d, same error

just for grins, removed the above, added

C ------------------------------------------------
F_STDCALL INTEGER FUNCTION LIBMAIN(hInst,ul,lpR)
INTEGER hInst,ul,lpR,hLibModule,LoadLibrary
hLibModule = LoadLibrary
2 ("C:\Program Files\Silverfrost\FTN95 Express\salflibc.dll")
C CALL mask_underflow@()
C ***** Initialise global data here
LIBMAIN=1
RETURN
END FUNCTION LIBMAIN

to mathproc.dll; was necessary to explicitly call LIBMAIN from
D main program (had a PRINT statement in LIBMAIN so I would know if it was called).
This produced a slightly different error
object.Error@(0): Breakpoint
during the LIBMAIN call itself.

Even without the LoadLibraryA call or modified LibMain, Dependency Walker still reported successful loading of salflibc.dll during profiling.

Also, having the same problem with SINH(), COSH(), TANH() - these functions also raise e to some power; suspect that is the central issue here. For what it is worth, SQRT(), SIN(), COS(), ACOS(), ATAN(), LOG() (surprise!), MOD(), IAND(), IOR(), ISHFT() are working fine - before playing with LoadLibraryA() and LoadLibrary().

At any rate, I appreciated your help. I will have to keep digging to figure out what is going wrong.
_________________
Rodney Roberts
Back to top
View user's profile Send private message Visit poster's website
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Tue Nov 11, 2014 7:47 am    Post subject: Reply with quote

I had similar problems when the EXP approached area of denormal numbers.

What is there is still anyone's guess, but my observations were that EXP does not like approaching overflow and underflow areas. So please make sure that X in EXP(X) for real*4 numbers is safely less then 50-60 or -50 respectively. MASK_UNDERLOW@ helped me too. You may try also well documented trapping of exceptions (which has demo code in the Help) to find if it may expose the reason of such behavior

BTW, do you have any specific reason of using mixed language programming? If it was just for creating GUI then Clearwin+ is good enough for that (if not better then other options) with other advantages besides that you will not get that error
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Tue Nov 11, 2014 5:41 pm    Post subject: Reply with quote

Rodney Roberts: Are you using the Windows-32 DMD compiler and the FTN95 compiler in your work? If so, how do you surmount the following obstacle?

FTN95 emits COFF32 format object files but the Optlink linker used by DMD requires OMF format object files.

How do you construct a DMD-compatible import library from an FTN95-generated DLL?

As you can infer from a quote of Walter Bright, the father of D
Quote:
(Complaint: 1. DMD can only output OMF binaries
> 2. DMD cannot output 64bit code for Windows
> 3. DMD is not compatible with the MSVC linker or runtime)

Response: I intend to fix all of those, at least for 64 bit Windows, in the near term.)
things are easier in 64-bits. I built a DLL for your subroutine ERCT using IFORT-64, and the Windows DMD 64-bit compiler compiled and linked with the DLL quite nicely. I used this prototype in the D caller:
Code:
extern (C)
{
float ERCT (ref float, ref float, ref float);
}

Since IFort and DMD both use cdecl linkage, there is no need to reverse the order of arguments in the call in D:
Code:
tmp = ERCT (t,R,C);
Back to top
View user's profile Send private message
rrobe71907



Joined: 26 Sep 2014
Posts: 10
Location: Tamaqua PA

PostPosted: Tue Nov 11, 2014 10:41 pm    Post subject: to mecej4: Reply with quote

Yes, I am using the Windows-32 DMD Compiler. The key is DMC's implib utility. For example:

implib sttstcs.lib sttstcs.dll

will read sttstcs.dll and create a DMD/OMF compliant sttstcs.lib

I have tutorial links at
http://rrroberts.50webs.com/cobindex.htm#DCALLS (has links somewhere for downloading implib).

I had a harder time in DMD linking in a D dll than a FORTRAN dll!

Biggest reason I am doing this is to stay sharp technology wise, learn a new programming language, learn WINAPI calls (instead of a visual IDE); also there are a lot of libraries out there that the source code is not available freely and you would have to reinvent the wheel.

I am one of those displaced mid-50s technology pros. When I was a HP3000 systems analyst I realized that there is no such thing as one-size-fits-all programming languages. We had a legacy ERP system interfaced with an EDI system. I used whatever tool would do the job quickly and reliably.

I only heard about D a couple of months ago; thanks for the info about
IFORT-64, and the Windows DMD 64-bit - that I did not know about.
_________________
Rodney Roberts
Back to top
View user's profile Send private message Visit poster's website
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Wed Nov 12, 2014 12:23 pm    Post subject: Reply with quote

Thanks for the link to bup.zip. I knew about implib; it was part of Turbo/Borland C (that was two decades ago!), and I suspected that I might need to download the whole DMC package just to obtain implib, and was not keen to do so at the moment.

With implib, I can make the DMD-Fortran combination work with Intel Fortran (32 or 64 bit, the latter without IMPLIB, as I described earlier). It also works correctly when the DLL is built using CVF6.6C, using df /iface:cref /LD <fortran_file> /link /export:_ERCT=ERCT, followed by producing the import library and building the D caller using DMD.

With FTN95, there is a problem. I compiled the Fortran subroutine using slink /dll ofar.obj /export:_ERCT=ERCT. I am able to link the D main to the import library but the resulting EXE crashes with an invalid floating point operation exception. I tried calling the same DLL from a C main program. The program builds without errors when compiled with the Salford C compiler SCC using scc cmain.c /ANSI_C, and even works correctly when run. However, when the C caller is compiled using MS or Intel C, the EXE crashes.

Perhaps you or another reader will find it interesting to investigate why this fails, so here are the sources for the subroutine and the caller.
Code:
REAL FUNCTION ERCT (T, R, C)
IMPLICIT NONE
REAL T, R, C
ERCT = T / (R * C)
!write(*,*)ERCT
ERCT = EXP(ERCT)
RETURN
END FUNCTION ERCT

Code:
#include <stdio.h>
extern float ERCT (float*, float*, float*);

int main(){
float C, R, t, tmp;

C = 0.000018;
R = 8100.0;
t = 0.31;
tmp = ERCT (&t, &R, &C);
printf (" ERCT (t,R,C): %f \n", tmp);
return (0);
}
Back to top
View user's profile Send private message
rrobe71907



Joined: 26 Sep 2014
Posts: 10
Location: Tamaqua PA

PostPosted: Wed Nov 12, 2014 9:56 pm    Post subject: To DanRRight Reply with quote

Sorry I did not respond to your post yesterday, got cut short for time.

The input range to e**x functions (EXP, TANH) is in -2.13 to 2.36 range.
Just for grins, even replaced TANH with SINH/COSH. In the TANH() call,
made the passed argument REAL*8. Also tried placing call mask_underflow@()
in various locations.

Basically I am doing this to see if it can be done.
_________________
Rodney Roberts
Back to top
View user's profile Send private message Visit poster's website
rrobe71907



Joined: 26 Sep 2014
Posts: 10
Location: Tamaqua PA

PostPosted: Wed Nov 12, 2014 10:11 pm    Post subject: To Everyone Reply with quote

Forgot to mention I found an arithmetic error in the ERCT function - forgot a minus sign before T. Still no difference run/crash results - FORTRAN .exe still executes, D .exe still crashes and burns. The corrected version:

C Series Resistance Capacitance Circuit
C Resistance Capacitance Time
C T : Seconds
C R : Ohms
C C : Farads
REAL FUNCTION ERCT (T, R, C) RESULT (X)
REAL T, R, C, X
X = -T / (R * C)
X = EXP(X)
RETURN
END FUNCTION ERCT

----------------------------------------------
Just for grins, I will post D/FORTRAN EXP() problem to the D forum in the next day or two.

And found another problem in D/FORTRAN interfacing - COMPLEX real and imaginary parts swap positions when returned.

to mecej4:
Thanks for your insights - picked up a few things.
_________________
Rodney Roberts
Back to top
View user's profile Send private message Visit poster's website
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Thu Nov 13, 2014 12:03 am    Post subject: Reply with quote

Rodney: "..forgot a minus sign before T".

I noticed that, too, but figured that your clock probably ran anticlockwise. Laughing
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Thu Nov 13, 2014 12:28 am    Post subject: Reply with quote

Rodney,

That was very typical for someone stuck with multi-language programming... crashes, bugs, incompatibilities, compiler authors/companies appear and disappear with the speed of light...rarely you will end up with something solid.

Post your final circuit equations code here, will be good to learn from your experience.

I've made one years ago using just this compiler and nothing else. Here how its front looks. And even here since it uses external graphics library called Simpleplot (no control of source code. company is stone dead, authors are retired) we got tons of bugs you can read about in this forum



Last edited by DanRRight on Thu Nov 13, 2014 12:58 am; edited 8 times in total
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Nov 13, 2014 12:29 am    Post subject: Reply with quote

I would expect that the solution could be related to the use of STDCALL. Search ftn95.chm on STDCALL and this may provide a way of getting FTN95 to work.
I don't think that ISO_C_BINDING is available in FTN95.

Unfortunately this is a topic that I should know a lot more about, so I find this thread interesting.

John
Back to top
View user's profile Send private message
rrobe71907



Joined: 26 Sep 2014
Posts: 10
Location: Tamaqua PA

PostPosted: Thu Nov 13, 2014 10:12 pm    Post subject: Reply with quote

Everyone:
I will keep you informed of new developments on this issue (I will try to post in this topic) - with my luck I will find it when I stop looking for it.

DanRRight:
Your Circuit Equations is impressive! I must confess I am somewhere in between a craftsman, mechanic, and engineer - I can follow some from all three but not everything. Electronics is one of those subjects I can follow some of the basics of, but deep understanding eludes me. Every so often I try to learn a little more.
I was in Manufacturing(plastics) for a number of years, and the s/w tools I had to make to do with - I could tell some stories - as I am sure you can. What made it even more interesting was the EDI requirements of our automotive customers.

JohnCampbel:
The D extern(STD) {...} produced some sort of Symbol Undefined errors, finally found extern(Pascal) {...} worked, so that is what I went with. I have found programming can be like fine-tuning a Holly 4 barrel, stick with the recommendations, but sometimes you have to try something "outside of the box". Also, the F_STDCALL SUBROUTINE seemed not to produce any benefits.
This forum has turned into a good exchange of ideas, I picked up a few things as well - perhaps more than others.

mecej4:
You are trouble - we could be friends

Wink
_________________
Rodney Roberts
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group