- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am now attempting to incorporate the useful feature of submodules in my projects. The feature works as expected when the compiler options are set to default values. However, when using /iface:cvf (a necessity in my application) and when multiple submodules in separate files refer to the same parent module, a number of link errors appear as shown below. Is CVF not allowed as a compilation option in this case?
Example
Parent module is M and stored in File 1. It invokes module subroutines A1 and A2 defined in submodule A stored in File 2. It also invokes module subroutines B1 and B2 defined in submodule B stored in File 3.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It will be easier for people to help you if you can post a small self-contained source file (or set of files), so that we can compile and link them to reproduce the issue. Of course, it may be that your description is sufficient, but it will take additional time to construct the source and it may be that there is some subtlety that gets lost that way.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sub-modules did not exist in Fortran 95 (which, with some extensions, is what CVF supported); so, it is debatable as to what /iface:cvf should do for procedures in sub-modules.
It may be that the routines that you "must" call using the CVF convention are all external procedures, in which case you can specify the CVF calling convention explicitly for only those procedures, using DEC$ directives as needed.
The problem statement should explain what kind of CVF compatibility is required -- are the routines in the modules to be called from code (in, say, VB/VBA) using CVF linkage, or the other way? What about module data -- is it to be accessible and shared? All these questions need to be settled since the problems are not over when an EXE/DLL is successfully built -- the EXE/DLL has to work correctly!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Normal procedures, when compiled with /iface:cvf, generate two entry points. One with the @n suffix for STDCALL and one without. The second is needed when you pass a procedure as an actual argument (and there is no explicit interface.) It would not astonish me if the Intel support for submodules failed to take this into account.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for all the informative responses. I must admit that although I am an experienced Fortran programmer for over 20 years, when I moved to Intel Fortran in 2005 or so, I did not understand the CVF option then and continue not to do so. Many of the legacy programs developed as far back as 1994 that I use to date do not compile without this option. I will describe these problems in a separate thread since I do want to resolve these issues. As a result, I am not able to explain explictly why CVF option is needed. I am posting the submodule example next.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following is a step-by-step account of the issues I am facing along with a description of the example problem:
1. Module M is a parent module. It references module subroutines A1 and A2 defined in a separate file as submodule (M) A. It also references module subroutines B1 and B2 defined in a separate file as submodule (M) B. This is a simple example that was set up to understand the submodule functionality. Finally, module M is called in a main program. These files are attached to this post.
2. Case 1: When the above project is set up in MSVS2017 with IVF 18.0.1.156 [IA-32], it works correctly with no issues with the four separate files (main.f90, module_M.f90, submodule_A.f90, submodule_B.f90) when the default settings are used i.e. Fortran -> External Procedures -> Calling Convention -> Default.
3. Case 2: When the calling convention is changed to CVF (/iface:cvf), the following errors appear:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does Case 2 fail in Debug build? IOW with IPO off
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
avinashs wrote:
The following is a step-by-step account of the issues I am facing along with a description of the example problem: ..
Hence, these errors seem to be related to the use of multiple files containing submodules and the CVF option enabled.
@avinashs,
You need to provide a reproducible case, what you have shown is insufficient - see below of a situation with your exact code but which works with Intel Fortran 18.0.1 as well as /IFACE:CVF option:
C:\Temp>type module_M.f90 module M interface module subroutine A1() end subroutine A1 module subroutine A2() end subroutine A2 module subroutine B1() end subroutine B1 module subroutine B2() end subroutine B2 end interface contains subroutine test() call A1() call A2() call B1() call B2() read * end subroutine subroutine P() print *, 'visit from parent' end subroutine P end module M C:\Temp>ifort /c /iface:cvf module_M.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R ) 64, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>ifort /c /iface:cvf submodule_A.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R ) 64, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>ifort /c /iface:cvf submodule_B.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R ) 64, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>ifort /c /iface:cvf main_submodule_test.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R ) 64, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>link /out:main.exe /subsystem:console main_submodule_test.obj module_M.o bj submodule_A.obj submodule_B.obj Microsoft (R) Incremental Linker Version 14.14.26433.0 Copyright (C) Microsoft Corporation. All rights reserved. C:\Temp>main.exe In A1 visit from parent In A2 visit from parent In B1 visit from parent In B2 visit from parent x C:\Temp>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan: Thanks for your prompt and informative response. I tried compiling from the command line as you have done and still get the errors. The same error occurs with MSVS2017. Could this be a compiler installation or version issue?
E:\Temp>ifort /c /iface:cvf module_M.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>ifort /c /iface:cvf submodule_A.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>ifort /c /iface:cvf submodule_B.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>ifort /c /iface:cvf main_submodule_test.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>link /out:main.exe *.obj Microsoft (R) Incremental Linker Version 14.15.26729.0 Copyright (C) Microsoft Corporation. All rights reserved. submodule_B.obj : error LNK2005: _M already defined in submodule_A.obj LINK : fatal error LNK1561: entry point must be defined E:\Temp>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
avinashs wrote:
.. I tried compiling from the command line as you have done and still get the errors ..
@avinashs,
Retry with the following:
- Delete ALL object (OBJ) files in your E:\temp folder,
- Ensure all your source (f90) files, especially submodule_B.f90 file, in your E:\temp folder are the same as what you have attached in Quote #6 above,
- Explicitly specify the files during the linker step instead of the wildcard spec: i.e., use the command <link /out:main.exe /subsystem:console main_submodule_test.obj module_M.obj submodule_A.obj submodule_B.obj>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan Tried all of the above but the same error persists.
E:\Temp>ifort /c /iface:cvf module_M.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>ifort /c /iface:cvf submodule_A.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>ifort /c /iface:cvf submodule_B.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>ifort /c /iface:cvf main_submodule_test.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. E:\Temp>link /out:main.exe /subsystem:console main_submodule_test.obj module_M.obj submodule_A.obj submodule_B.obj Microsoft (R) Incremental Linker Version 14.15.26729.0 Copyright (C) Microsoft Corporation. All rights reserved. submodule_B.obj : error LNK2005: _M already defined in submodule_A.obj main.exe : fatal error LNK1169: one or more multiply defined symbols found
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
avinashs wrote:
..Tried all of the above but the same error persists ..
Ok, I can reproduce the issue now, it happens with IA-32 (32-bit target). My earlier attempt was with Intel 64 (64-bit target) which works fine. if I recall correctly, /IFACE:CVF option also makes use of STDCALL calling convention on IA-32 and separately I remember running into issues with SUBMODULEs in Intel Fortran in connection with STDCALL convention. So it's possible these things are related (?).
You should submit a support request with Intel OSC (https://supporttickets.intel.com/?lang=en-US) on this issue; refer to this thread in it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan: Thanks for your efforts. I tried the IA-64 target and was able to get it to work. My next goal is to be able to move away from /iface:cvf completely since it seems to have a number of compatibility issues. ex. Intel MKL does not work with 64-bit targets when /iface:cvf option is active. Hence, I converted many projects back to 32-bit from 64-bit but now submodules are not working.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You used Intel 64, not IA-64. IA-64 is for Intel Itanium processors and this hasn't been supported in the compilers for several years now.
Please do report the problem to Intel using the link FortranFan mentioned.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
avinashs wrote:
.. My next goal is to be able to move away from /iface:cvf completely since it seems to have a number of compatibility issues. ex. Intel MKL does not work with 64-bit targets when /iface:cvf option is active. Hence, I converted many projects back to 32-bit from 64-bit but now submodules are not working.
Not sure how and why Intel MKL fails to work with 64-bit targets when /IFACE:CVF option is employed. You should try to put together a reproducer case with Intel MKL like you have done with SUBMODULEs and submit it to Intel support at least.
And yes, try to move away from IFACE:CVF if possible. Generally the need for this option is consistency and/or backward-compatibility of libraries with applications making use of them such as Microsoft's VBA (e.g, Excel spreadsheet environment). Under such circumstances, you can apply some of the principles of "design by contract" and mark the interfaces in own's code with the apps such as those in VBA with the required attributes using Intel compiler directives. With your sample code in Quote #6, should your subroutine TEST represent such an interface, mark it with !DIR$ ATTRIBUTES CVF and you might get your code to work like so:
C:\Temp>type module_M.f90 module M interface module subroutine A1() end subroutine A1 module subroutine A2() end subroutine A2 module subroutine B1() end subroutine B1 module subroutine B2() end subroutine B2 end interface contains subroutine test() !dir$ attributes cvf :: test !<-- Note the Intel compiler directive call A1() call A2() call B1() call B2() read * end subroutine subroutine P() print *, 'visit from parent' end subroutine P end module M C:\Temp>ifort /c /standard-semantics module_M.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>ifort /c /standard-semantics submodule_A.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>ifort /c /standard-semantics submodule_B.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>ifort /c /standard-semantics main_submodule_test.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.1.156 Build 20171018 Copyright (C) 1985-2017 Intel Corporation. All rights reserved. C:\Temp>link /out:main.exe /subsystem:console module_M.obj submodule_A.obj submo dule_B.obj main_submodule_test.obj Microsoft (R) Incremental Linker Version 14.14.26433.0 Copyright (C) Microsoft Corporation. All rights reserved. C:\Temp>main In A1 visit from parent In A2 visit from parent In B1 visit from parent In B2 visit from parent x C:\Temp>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan: As we agreed, it is best for me to move away from CVF now in 2018. I started with MS Fortran Compiler in 1995, then moved to DEC, then Compaq in 2000, then HP Compaq in 2002, then completely to Intel in 2005-2008. The /iface:cvf started with Intel and prior to that I never had to touch the compiler settings - all the codes worked straight out of the box with default settings with several compilers. In fact, the same codes worked on Unix with f77 and gcc compilers. Then with Intel, there were failures if /iface:cvf was not used, which I never understood. As you correctly point out, I will present examples to show the issues in separate threads.
With regard to Intel MKL + CVF + Intel 64 (thanks for the correction @Steve Lionel), this is a known issue: see for example
However, the option /iface:nomixed_str_len_arg option, which if not enabled causes MKL to fail in Intel 64, causes problems in all my other subroutines that accept character(len = *) arguments with the default setting. So it is not MKL per se but how the change of settings affects other subroutines.
I should definitely be more proactive and contribute these examples to the IVF forum, which has been so helpful since I joined in 2003.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
MKL used to supply a library variant compatible with CVF. That went away several years ago.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The entry point that the linker complains about (32-bit, with /iface:cvf) is a stub that may be needed in some cases of building applications that use submodules. The routine at that multiply-defined entry point (_M.) is, for the test codes that you provided, just one byte long, and contains a RET instruction. Furthermore, it is never called from any of the other routines. The "multiple definition" bug should be fixed but, in the interim, you may be able to get by with the linker /FORCE option (use with caution, test the EXE well before letting others use it).
I see no need for /iface:cvf in anything that you have described in this thread (other than to expose bugs in the compiler tools).

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page