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

Reusing DLLs built with CVF 66C in IVF 19.0.2.190

avinashs
New Contributor I
654 Views

I have some legacy DLLs built with CVF 6.6C from around 2010. There were no specific project settings as far as I recall to build the DLL i.e. the CVF project was run "straight-out-of-the-box" to create the DLL. My questions are:

1. Will the CVF6.6C DLLs be compatible with default debug settings of IVF 19.x? i.e. 
        nologo /debug:full /Od /warn:interfaces /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c
        
2. What would the IVF project settings have to be in order to make the DLL compatible? /iface:cvf seems to be a logical choice.

3. Around year 2001, CVF included the IMSL library. If a DLL created with CVF uses the IMSL library included with CVF, will it be self contained i.e. will some sort of IMSL lib be required for the DLL to run?

4. Conversely, what would the CVF6.6C settings have to be in order to make the DLLs compatible with the current default IVF settings in (1) above.
 
Any help would be greatly appreciated.

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
654 Views

CVF is owned by HP; Intel has no legal interest in it. Your license for CVF is still valid for CVF - it does not transfer to Intel Visual Fortran. The Intel product is derived (in part) from CVF sources, but that split happened 16+ years ago.

My advice would be to rebuild the DLL with Intel Fortran. We can help if you run into issues, but it should generally work if your code is correct. (The newer compiler may diagnose errors that CVF didn't catch.)

View solution in original post

0 Kudos
16 Replies
Steve_Lionel
Honored Contributor III
654 Views

Are you asking how to use a CVF-built DLL in your IVF project?  Adding the corresponding .lib (or generating a new one) is the first step. Yes, /iface:cvf will make it easier to call the DLL routines but I'd recommend instead an explicit interface for each routine, including !DEC$ ATTRIBUTES CVF for the routine.

You will need a copy of dforrt.dll on your system, unless the DLL was linked to the static libraries. You will not be able to share I/O units, or pass deferred-shape arrays or allocatables to the DLL.

CVF provided IMSL as a static library only, so if you built a DLL with IMSL it will have all the IMSL code included and you don't need to do anything special.

I see no purpose in rebuilding the DLL with CVF - you won't be able to avoid some interoperability issues as I noted above.

0 Kudos
avinashs
New Contributor I
654 Views

@SteveLionel - Thanks this is very helpful. I did not think of adding an interface with ATTRIBUTES CVF. The options are to reuse the old CVF dll as is in IVF or rebuild the CVF source code with IVF. We cannot rebuild with CVF because we no longer have a working copy.

On that note, what is the current status of CVF? Is it absorbed into IVF and is the old CVF license still valid?

 

0 Kudos
Steve_Lionel
Honored Contributor III
655 Views

CVF is owned by HP; Intel has no legal interest in it. Your license for CVF is still valid for CVF - it does not transfer to Intel Visual Fortran. The Intel product is derived (in part) from CVF sources, but that split happened 16+ years ago.

My advice would be to rebuild the DLL with Intel Fortran. We can help if you run into issues, but it should generally work if your code is correct. (The newer compiler may diagnose errors that CVF didn't catch.)

0 Kudos
avinashs
New Contributor I
654 Views

@SteveLionel: Thanks for the helpful suggestions.

(1) I set up a project in IVF 19.0.2.190 [IA-32] that uses a CVF6.6C dll with project settings in MSVS2017  /iface:cvf and Debug Multithreaded (/libs:static /threads /dbglibs). The dll works without error!

(2) An error occurs (exception thrown upon exit from dll) if the project settings are default conventions and Debug Multithread DLL (/libs:dll /threads /dbglibs) to accommodate our newer libraries and dlls. Very interestingly (to me), all the variables as seen in the locals window have their correct updated values upon exit from the subroutine in the CVF dll.

(3) The solution to (2) above is to rebuild the original source code in IVF 19.x with the default settings. However, the wrinkle here is that we no longer have IMSL so those routines would have to be replaced by alternatives.

(4) Alternative to (3) would be to build all the new routines in /iface:cvf. I have tried this and see no obstacles or difference in results.

(5) One of my earlier questions hence was "what project settings in building CVF dlls either on the command line or with !DEC ATTRIBUTES would be compatible with the current default calling convention and libraries (/libs:dll /threads /dbglibs) of 19.x"?

0 Kudos
Steve_Lionel
Honored Contributor III
654 Views

The error you describe sounds like stack corruption due to a mismatch in calling conventions. If building in CVF, which you say you don't have, you would want /iface:cref /nomixed_str_len_arg . 

You're correct that you would need IMSL to rebuild. /iface:cvf would seem to be a reasonable approach to make sure you didn't miss something.

0 Kudos
mecej4
Honored Contributor III
654 Views

Avinash, I do not understand your goals.

  1. You stated that you do not have CVF. It follows that you do not have the IMSL 4 that came with it. You have a CVF compiled DLL, however.
  2. From 1., it follows that if your code needs IMSL and the old DLL is not sufficient (or you wish to target x64) you need a version of IMSL that is compatible with Ifort. If you obtain such a version, all this talk about mixing calling conventions and using DIR$ directives is unnecessary.
  3. As an alternative to 2., you may use another numerical analysis library instead of IMSL.
  4. If you wish to use the old DLL with code compiled by Ifort, it would be wise to declare only the imported routines from the DLL as having ATTRIBUTES CVF.

Note that things get quite tricky if your code uses an IMSL routine that takes one or more callback routines as argument, such as NEQNF, and you have only the DLL that is CVF compatible. If this describes the situation, both the IMSL routine and the user-supplied callback routine have to be declared with ATTRIBUTES CVF when you compile with Ifort.

Which IMSL routines do you use?

0 Kudos
Steve_Lionel
Honored Contributor III
654 Views

Exposing the IMSL entry points from the CVF DLL would be a violation of the IMSL license terms, but that would be unusual. But indeed mecej4 identifies yet another interoperability issue that could be important.

But this does remind me that ANY sort of callback from the CVF DLL could be problematic. If the ifort-compiled executable passed a routine into the CVF DLL, expected to be called back, this would result in a calling standard mismatch. Again, /iface:cvf would paper over this.

0 Kudos
avinashs
New Contributor I
654 Views

Steve Lionel (Ret.) (Blackbelt) wrote:

The error you describe sounds like stack corruption due to a mismatch in calling conventions. If building in CVF, which you say you don't have, you would want /iface:cref /nomixed_str_len_arg . 

You're correct that you would need IMSL to rebuild. /iface:cvf would seem to be a reasonable approach to make sure you didn't miss something.

@SteveLionel - Thanks. The CVF settings are only for my education and to understand why certain DLLs cause crashes. Unfortunately, there isn't much in the Intel documentation so this forum is the only way to get this critical information.

Also, regarding CVF ... after migrating to Windows 7 in 2009, both CVF and VB6 could no longer be installed or run on our machines (some effort was done to use the "Windows XP" mode without much success). We had MSVS 2008 and IVF10 licenses at the time, which we upgrade every year since. So we have moved to IVF for Fortran and had to abandon VB6 since VB.net is completely different and incompatible. It seems now the best approach is also to abandon the old CVF dlls and rebuild everything in IVF.

One problem is that the IVF versions of the routines work in Excel VBA only if /iface:cvf is used for all the builds (and recently only in release mode). This is also something I figured out from the responses in a recent discussion in another thread started by @gib. Building with default convention as is done for the Intel sample code works for that example but causes crashes in our case.

At a minimum, once all the new dlls are built with IVF, I would like to compare results on runs with the old CVF dlls on our test problems to see that the differences are within acceptable limits (of the order of machine precision). At that point, we can eliminate the CVF dlls for good.

0 Kudos
FortranFan
Honored Contributor II
654 Views

avinashs wrote:

.. there isn't much in the Intel documentation so this forum is the only way to get this critical information. ..

@avinashs,

From what I've been noticing on this thread and other similar ones involving mixed language programming with legacy aspects (CVF/IVF ATTRIBUTES, etc.), Excel VBA, Microsoft .NET, etc., there is a LOT of outdated, disjointed, and in some cases erroneous information being fed back to OPs.  One just doesn't have the time to sort it all out, especially in threads such as this one where you ask very broad questions.

You will help yourself best by

  1. really digging through Intel documentation thoroughly if these matters are important enough for you,
  2. if you are proceeding with Intel Fortran, then employing as much as possible the Fortran standard facilities for enhanced interoperability with C and striving hard to minimize the use of !DIR$ ATTRIBUTES instances in code, restricting perhaps to STDCALL for compatibility with 32-bit Excel (toward this: always keep in Microsoft offers VBA and .NET compatibility with a companion C processor!),
  3. asking specific questions on the forum with small reproducers.

Attrib.png

0 Kudos
avinashs
New Contributor I
654 Views

mecej4 wrote:

Avinash, I do not understand your goals.

  1. You stated that you do not have CVF. It follows that you do not have the IMSL 4 that came with it. You have a CVF compiled DLL, however.
  2. From 1., it follows that if your code needs IMSL and the old DLL is not sufficient (or you wish to target x64) you need a version of IMSL that is compatible with Ifort. If you obtain such a version, all this talk about mixing calling conventions and using DIR$ directives is unnecessary.
  3. As an alternative to 2., you may use another numerical analysis library instead of IMSL.
  4. If you wish to use the old DLL with code compiled by Ifort, it would be wise to declare only the imported routines from the DLL as having ATTRIBUTES CVF.

Note that things get quite tricky if your code uses an IMSL routine that takes one or more callback routines as argument, such as NEQNF, and you have only the DLL that is CVF compatible. If this describes the situation, both the IMSL routine and the user-supplied callback routine have to be declared with ATTRIBUTES CVF when you compile with Ifort.

Which IMSL routines do you use?

@mecej4 - Thanks for your informative response. My responses to your points are:

1. As stated in my previous response #9, we were unable to install CVF in Windows 7. We had already purchased IVF a few years prior to 2009, but there was no option to buy IMSL bundled in as with Compaq. Further, the old IMSL did not work with IVF10 so were wary of not having to purchase multiple IMSL packages each time the compiler changed. We do have our old CVF dlls and the source code used to create them.

2. Yes - we could purchase IMSL again but do have all the alternative routines. We were mainly using linear algebra and BLAS routines since compiling LAPACK with IVF when the arguments passed were of character type caused a problem.

3. I have my own numerical analysis library for all numerical methods and hence the use of IVF by itself is completely possible since the source code can be compiled.

4. You are right in that the routines with incompatibility are those where a callback function is involved. Any routines without callback functions or those written in reverse communication mode for callback functions do not pose a problem.

0 Kudos
mecej4
Honored Contributor III
654 Views

If you have been using IMSL only for BLAS and Lapack routines, you can step over all the problems that you have described by simply using the MKL library that comes with Intel Fortran. For many simple cases, you can use MKL by using the /Qmkl compiler/linker option. There is no need to compile BLAS or Lapack from sources yourself, since MKL includes highly tuned, multithreaded, versions of the same routines, and implements multiple codepaths from which to choose the instruction set best suited for the CPU being used at run time.

It is possible, with a bit of trouble, to install and run CVF 6.6C on Windows 7, 8, 8.1 and 10 (32 and 64 bit OS). I have done this over the years. There have been several threads related to that on this forum: for example, https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/392549 . 

Here is an example of code that uses IMSL with a callback routine, with directives to enable calling the IMSL-4 libraries that came with CVF 6.6.

      module globl
!     Parameters in set of equations, not passed by IMSL to callback function.
      implicit none
      real a,b,c,d,g,h
      end module

      program xneqnf
      use globl
      IMPLICIT   NONE
!                                 Declare variables
      INTEGER    N, ITMAX
      PARAMETER  (N=3, ITMAX=20)
!
      INTEGER    K, ktr
      REAL       FNORM, X(N), XGUESS(N), errrel
      external fcn, neqnf
cdec$ attributes CVF :: fcn,neqnf
!
      DATA XGUESS/4.0, 4.0, 4.0/
!
!
!                                 Find the solution
      a = 1.0
      b = 27.0
      c = 2.0
      d = 10.0
      g = 2.0
      h = 7.0
      errrel = 1e-5
      do ktr = 1, 10
         write(*,77)a,b,c,d,g,h
   77 format(' Pars: ',4F12.4)
         CALL NEQNF (FCN, errrel, N, ITMAX, xguess, x, fnorm)
!                                 Output
         WRITE (*,99999) (X(K),K=1,N), FNORM
         a = a+0.02
         b = b + 0.3
         c = c -  0.02
         d = d + 0.1
         g = g - 0.01
         h = h + 0.03
         xguess = x
      end do
99999 FORMAT ('  The solution to the system is', /, '  X = (', 3F8.4,
     +       ')', /, '  with FNORM =', F8.4, //)
!
      END
!              User-defined subroutine, will be called from IMSL NEQNF
      SUBROUTINE FCN (X, F, N)
      use globl
      implicit none
cdec$ attributes CVF :: fcn
      INTEGER    N
      REAL       X(N), F(N)
!
      REAL       EXP, SIN
      INTRINSIC  EXP, SIN
!
      F(1) = X(1) + EXP(X(1)-a) + (X(2)+X(3))*(X(2)+X(3)) - b
      F(2) = EXP(X(2)-c)/X(1) + X(3)*X(3) - d
      F(3) = X(3) + SIN(X(2)-g) + X(2)*X(2) - h
      RETURN
      END

The same code can also be compiled with (i) CVF and IMSL 4, provided(*) "CVF" is changed to "DEFAULT" in the directives, and (ii) Ifort and IMSL 7 for Ifort, with the same changes to the directives, or with the directives removed. Note that Ifort no longer supports the /Qimsl option (it did up to at least 18.0.3).

(*) It is a bit ironic that CVF does not accept ATTRIBUTES CVF:

Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update C)
Copyright 2003 Compaq Computer Corp. All rights reserved.

xneqnfd.f
xneqnfd.f(51) : Error: Not a valid attribute for the DEC$ ATTRIBUTES directive.   [CVF]
cdec$ attributes cvf :: fcn

 

0 Kudos
Steve_Lionel
Honored Contributor III
654 Views

In CVF. ATTRIBUTES CVF is spelled "ATTRIBUTES DEFAULT".

0 Kudos
avinashs
New Contributor I
654 Views

mecej4 wrote:

Here is an example of code that uses IMSL with a callback routine, with directives to enable calling the IMSL-4 libraries that came with CVF 6.6.

      

The same code can also be compiled with (i) CVF and IMSL 4, provided(*) "CVF" is changed to "DEFAULT" in the directives, and (ii) Ifort and IMSL 7 for Ifort, with the same changes to the directives, or with the directives removed. Note that Ifort no longer supports the /Qimsl option (it did up to at least 18.0.3).

Interesting example. Just so I understand clearly ...

1. If you have CVF6.6 and IVF installed, then the above example is a way to link the older IMSL library that was a part of CVF6.6 with a code being run in IVF, with the major change being the declaration of both the IMSL routine and the external function with the !DEC$ ATTRIBUTES CVF directive.
2. The !DEC$ ATTRIBUTES CVF is also included in the function definition. A separate module is used to pass global data. If the function was defined in a "contains" section, could the !DEC$ ATTRIBUTES CVF still be used?
3. If the above method works, there is no need for a CVF dll anymore - you could rebuild a new dll from scratch with IVF.
4. Many of our codes now take advantage of modules, submodules and contains sections and I am still getting around to understanding the use of attributes in these features of Fortran codes.

Regarding MKL ... We do use MKL as much as possible. Just had a little problem in early days with character argument passing for some routines when built with /iface:cvf in 64-bit. On the other hand, building with IVF directly does not cause any problems in any configuration.

That being said, we have done several performance tests comparing Intel MKL with LAPACK libraries built from original source code in IVF, and don't see any performance difference. We also have to use LINPACK for some of the older routines.

0 Kudos
mecej4
Honored Contributor III
654 Views

Fortran 95 did not allow internal procedures to be used as actual arguments for dummy arguments of type procedure (subroutine/function). Some Fortran 95 compilers (including CVF) may have allowed such usage as an extension, but then you would have reduced portability of the code.

You have still not answered my question: which IMSL routines does your "CVF DLL" call? Have you found alternative subroutines for those calls?

0 Kudos
avinashs
New Contributor I
654 Views

mecej4 wrote:

Fortran 95 did not allow internal procedures to be used as actual arguments for dummy arguments of type procedure (subroutine/function). Some Fortran 95 compilers (including CVF) may have allowed such usage as an extension, but then you would have reduced portability of the code.

You have still not answered my question: which IMSL routines does your "CVF DLL" call? Have you found alternative subroutines for those calls?

Various routines of Chapter 1: Linear Systems and Chapter 2: Eigensystem Analysis. DDASPG from Chapter 5, DDLPRS and DSLPRS from Chapter 8. All of these are easily replaced with LINPACK, BLAS, LAPACK, ODEPACK etc., which is what we used in the 80's and 90's to begin with. One big issue that was recently resolved as a result of asking the question on this forum was that some of the older code compiled in CVF but not in IVF. The solution is to disable interface checking, which now removes the errors encountered in some of the legacy code.

0 Kudos
mecej4
Honored Contributor III
654 Views

Among the IMSL routines that you named, only DDASPG uses a callback function. Note that DASPG is now deprecated, and it is recommended that you use DAESL instead. Related to the IMSL DAESL is DASSL, which you can find at https://cse.cs.ucsb.edu/software .

avinashs wrote:
The solution is to disable interface checking, which now removes the errors encountered in some of the legacy code.

That may be a bit risky; please try to fix the interfaces.

0 Kudos
Reply