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 

Strange iostat value returned by open

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
johnbarnes



Joined: 28 May 2014
Posts: 11
Location: Oxfordshire, UK

PostPosted: Sat Jun 21, 2014 8:15 pm    Post subject: Strange iostat value returned by open Reply with quote

The open statement shown lives in some code which can be built into either a .exe or a DLL. The open behaves as expected when running the .exe and returns a iostat of 0 in normal circumstances (the file exists and is not open elsewhere).

open(32, file='file.bin', form='unformatted', access='transparent', status='old', iostat=ios)

Sometimes, when the code is running as a DLL (invoked by a C# .NET process), an iostat value of 1 comes back. This result is consistent in that if I run the test again the same iostat value is returned. It also seems spurious in that if I make a completely unrelated change to some other part of the code, the problem can go away, only to return again later when I make some other unrelated change to some other part of the code.

Apart from asking for ideas on how I can investigate this further, I do have two specific questions:

1. Is there a genuine set of circumstances in which this open can return an iostat value of 1? According to FTN95 help this code translates to "Floating point arithmetic over flow".

2. Are there some rules and guidelines I ought to be aware of in order to get a FORTRAN DLL involving I/O to work reliably when invoked by a .NET process?

Thanks,
John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Sun Jun 22, 2014 7:49 am    Post subject: Reply with quote

My first guess would be that an iostat of 1 means "Invalid function" but then I would not know how that might arise.

More likely there is a problem with garbage collection - i.e. memory is not being locked and you are getting a spurious error report. This would mean that DBK_LINK is not working as it should in this context.

If everything is working OK (despite this IOSTAT value) thenI would be tempted to carry on regardless. However, if you would like us to try to sort it out then we would need a short sample program that illustrates the issue.
Back to top
View user's profile Send private message AIM Address
johnbarnes



Joined: 28 May 2014
Posts: 11
Location: Oxfordshire, UK

PostPosted: Sun Jun 22, 2014 9:39 am    Post subject: Reply with quote

Thanks for your comments Paul.

Please expand on your comment about memory not being locked. I am not (knowingly) using multi-threading. I have made sure that all modules that declare data at the outer level have a save directive.

The overall setup is like this:

A 32-bit C# .exe dynamically loads a 32-bit C# .dll that provides a wrapper for entry points in the FORTRAN dll. This is all built with Visual Studio Express.

The FORTRAN dll is produced in Plato as a Win32 Release build with no non-default settings.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Sun Jun 22, 2014 9:55 am    Post subject: Reply with quote

I am suggesting that there might be a fault in DBK_LINK (the FTN95 linker for .NET). One of the things that DBK_LINK does is to lock memory for Fortran linking with C# etc. .NET has automatic garbage collect which means that, by default, objects are not fixed in memory. Traditionally Fortran uses a fixed memory system and DBK_LINK responds to this dilemma by locking the Fortran part.

It is also possible that your C# coding has not taken account of garbage collection. i.e that you have assumed objects (passed to Fortran) are always fixed in memory.
Back to top
View user's profile Send private message AIM Address
johnbarnes



Joined: 28 May 2014
Posts: 11
Location: Oxfordshire, UK

PostPosted: Sun Jun 22, 2014 4:52 pm    Post subject: Reply with quote

The only "objects" being passed across the interface are:

integer (passed both ways)
double (passed both ways)
string (only passed from C# to FORTRAN)
vector of double (passed both ways)

Unfortunately I have only seen the problem I have reported in the large body of code that is the real application. I have today seen a variant of the problem where instead of the unexpected result code from the binary file open there is a crash on the first open of a .txt file. I have also now built the dll using gFORTRAN and that works OK so far.

The number of interface calls made before the crash in the above two cases is quite limited. The interface code I am using on both the C# side a the FORTRAN side is not something I made up but has been used by others with Intel FORTRAN. What is the best way to make progress on this problem?

Thanks,
John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Sun Jun 22, 2014 7:25 pm    Post subject: Reply with quote

Your use of gFortran raises the question... when compiling with FTN95, are you using .NET (i.e. /CLR on the command line)?
Back to top
View user's profile Send private message AIM Address
johnbarnes



Joined: 28 May 2014
Posts: 11
Location: Oxfordshire, UK

PostPosted: Mon Jun 23, 2014 11:45 am    Post subject: Reply with quote

The project is set for Release Win32 builds in Plato, which is where I do all FTN95 builds. I think that means I am avoiding .NET on the FORTRAN side. That is a requirement for the project.

This is how one of the entry points is defined in the FORTRAN code:

subroutine XXXX_ENGINE_INITIALISE(args, success_code)
!DEC$ ATTRIBUTES DLLEXPORT :: XXXX_ENGINE_INITIALISE
!DEC$ ATTRIBUTES ALIAS:'_XXXX_ENGINE_INITIALISE' ::
XXXX_ENGINE_INITIALISE
character(*), intent(in) :: args
integer, intent(out) :: success_code ! 0: ok, -ive fatal error, +ive warning

The above is used with C# calling code like:

[DllImport(ExternalDll_C.Filename,
EntryPoint = "XXXX_ENGINE_INITIALISE",
ExactSpelling = false,
CallingConvention = CallingConvention.Cdecl)
]
internal static extern void XXXX_ENGINE_INITIALISE(
[MarshalAs(UnmanagedType.LPStr)] StringBuilder inString,
ref int successCode, // 0: ok, -ive fatal error, +ive warning
int inStringLength);
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Mon Jun 23, 2014 2:59 pm    Post subject: Reply with quote

I doubt if anyone has tried to do this before.

FTN95 has a .NET mode that is designed for running alongside other .NET assemblies. What you are attempting may well work at times but I cannot say that it is supported.

It is true that you can access a Win32 DLL from a .NET assembly but the assumption will be that the DLL does not have its own semi-permanent store (i.e. storage that is preserved between function calls). This is not the case for an FTN95 DLL because it accesses salflibc.dll (e.g. for IO).

I suggest that you try creating an FTN95 DLL in the form of a .NET assembly. This may be just a case of selecting .NET mode in Plato.
Back to top
View user's profile Send private message AIM Address
johnbarnes



Joined: 28 May 2014
Posts: 11
Location: Oxfordshire, UK

PostPosted: Thu Jun 26, 2014 10:00 am    Post subject: Reply with quote

Thanks for your comments.

Having found that my recent FTN95 Express install had made changes to PATH that resulted in use of an older version of both the compiler and library instead of the version 7.1 I thought I was using, and having fixed the PATH problem, the OPEN failure symptoms have gone away.

Since fixing the PATH problem, my experience is that invoking Win32 FTN95 in the manner described, works (at least to the extent that it does not fall over). I have tried both a simple setup involving one sub-process and a more complex case like this:

Controlling process in C#
Sub-process1 in C# calling FTN95 Win32 DLL
Sub-process2 in C# calling FTN95 Win32 DLL

The two sub-processes both make extensive use of FORTRAN I/O.

I note your reservations, and will try compiling the FORTRAN as .net.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
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