- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'd actually like to ask about why I'm able to compile this example program. Obviously, this isn't an issue for the system I'm on right now, but I hope to not run into compiling issues when I'm working on a different system. The example program is very simple, it calls the LAPACK axillary function dzsum1. Here it is:
program dzsum1_test integer, parameter :: WP = selected_real_kind(15,307) complex(WP) :: a(5) real(WP) :: res real(WP) :: dzsum1 external :: dzsum1 a(1) = cmplx(1.d0,1.d0) a(2) = cmplx(1.d0,1.d0) res = dzsum1(5,a,1) write(*,*) res end program
Now, I can compile and run this program successfully with
ifort dzsum1_test.f90 -mkl
- Why does this work? Specifically, why don't I need to put
include "mkl.fi"
anywhere in my program? That is an include file for this function that's listed in the MKL Reference and I thought that I would need to make sure dzsum1 was declared in my file before I declared it as external. Whether I put the include line before or after the program statement, the compilation doesn't work. I'm assuming this has something to do with the behavior of "-mkl" but I can't find anything in the MKL user guide, MKL reference, or ifort man pages that talk about this switch doing anything except linking libraries, which I thought wasn't sufficient for an external declaration. - If it is in fact the "-mkl" switch that makes all this possible, is there a way to print out what it's doing?
Sorry for such a simple question, any help would be appreciated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The answer is quite simple. You used a straightforward F-77 style call, and the types and kinds of the subroutines just happened to be right -- they match the declarations in the source code of dzsum1, if you care to check at https://software.intel.com/en-us/node/521193. In such cases (we always write correct code, don't we?) the subroutine interface is not necessary, and the "implicit interface" is correct.
Now try changing the last argument from 1 to 1.0, and run the modified (and now incorrect) program with and without the interface file included.
The -mkl switch makes it easy for the compiler to search for files needed to compile and link source files that use MKL, and is not directly related to your question. You can try the -# flag, but the verbose output will probably not help you.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The answer is quite simple. You used a straightforward F-77 style call, and the types and kinds of the subroutines just happened to be right -- they match the declarations in the source code of dzsum1, if you care to check at https://software.intel.com/en-us/node/521193. In such cases (we always write correct code, don't we?) the subroutine interface is not necessary, and the "implicit interface" is correct.
Now try changing the last argument from 1 to 1.0, and run the modified (and now incorrect) program with and without the interface file included.
The -mkl switch makes it easy for the compiler to search for files needed to compile and link source files that use MKL, and is not directly related to your question. You can try the -# flag, but the verbose output will probably not help you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The include file 'mkl.fi' includes another eleven include files, so it takes the compiler a while to process all the interfaces. However, there is a simple fix for this. Create a three-line Fortran source file containing
module mymkl include 'mkl.fi' end module mymkl
and compile this file. A module file, 'mymkl.mod', will be generated. Place this module file in a place along the include/module search path.
That having been done, in your sources, wherever you would include mkl.fi, write "USE MYMKL" instead. Note that the USE statement should be placed before any declarations.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That is perfect. Thank you so much!
I remember using the same trick when I was using fftw, but the importance of it didn't hit me then. For anyone else reading this in the future, here is a (very) simple project setup with a makefile that will make this whole process streamlined. Simply type make to compile the project, the module will only be compiled if it needs to be. Type "make clean" to delete your program executable, and "make distclean" to delete your program executable along with the .mod file and module object file.
dzsum1_test.f90
program dzsum1_test use mymkl integer, parameter :: WP = selected_real_kind(15,307) complex(WP) :: a(5) real(WP) :: res a(1) = cmplx(1.d0,2.d0) a(2) = cmplx(1.d0,1.d0) res = dzsum1(5,a,1) write(*,*) res end program
mymkl.f90
module mymkl include 'mkl.fi' end module mymkl
Makefile
all: mymkl.mod ifort dzsum1_test.f90 -mkl mymkl.mod: ifort -c mymkl.f90 clean: rm a.out distclean: rm mymkl.mod mymkl.o a.out
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yikes! Thanks so much for the response. I'll be sure to use the interface file :) The compile takes much longer now though, I don't suppose there is a way to speed this up?(see edit below) I know that for many BLAS and LAPACK functions there is a precompiled fortran90 module that works well, but I don't think this includes anything for dzsum1.
I think I was thrown off by the dot_main example in the MKL reference guide, which seems like it could benefit from an interface file (either mkl.fi or mkl_blas.fi). I think I have a better grasp of what the interface file is for now -- if I'm understanding it correctly, it's not to provide the actual functions, but just information for the compiler about the arguments and return values of the function that's been linked in a library by "-mkl".
Thanks again!
Edit: It seems like this is the way to write the program in the original post that will compile the fastest and still have an interface file (much faster way in reply to this post). This include file is listed with the general LAPACK docs, but the larger include file is listed for the actual function.
program dzsum1_test include "mkl_lapack.fi" integer, parameter :: WP = selected_real_kind(15,307) complex(WP) :: a(5) real(WP) :: res a(1) = cmplx(1.d0,1.d0) a(2) = cmplx(1.d0,1.d0) res = dzsum1(5,a,1) write(*,*) res end program

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