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

Problem with linking to both FFTW3-3.dll and fmpich2.dll

pvds
Beginner
694 Views
I am developing a code that uses both FFTW for fast discrete Fourier transform calculations and MPICH2 for MPI implementation.

MPICH2 is installed in the default location (C:\Program Files\MPICH2). The .DLLs for FFTW3 (downloaded from www.fftw.org) are installed in the source directory. I have used lib ./def:libFFTW3-3.def to create the .lib and .exp files, which resides in the same directory.

If I try to execute

ifort -O3 -assume:byterecl -IC:\progra~1\mpich2\include -o program.exe source.f90 fmpich2.lib libfftw3-3.lib

I get unresolved externals during the linking phase:

unresolved external symbol _DFFTW_PLAN_DFT_2D referenced in funtion _MAIN__.J

with similar messages for other subroutine calls starting with _DFFTW_...

If I try to execute

ifort -O3 -assume:byterecl -assume:underscore -names:lowercase -IC:\progra~1\mpich2\include -o program.exe source.f90 fmpich2.lib libfftw3-3.lib

I get other unresolved externals during the linking phase:

unresolved externals symbol _mpi_init_ referenced in function _MAIN__.J

with similar messages for other subroutines calls starting with _mpi_.... (and no unresolved external symbols for the _dfftw_... subroutine calls).

When I inspect the exported symbols in fmpich2.dll (in windows/system32 directory) using Dependency Walker I find only function names in uppercase like MPI_INIT. When I do the same with the LIBFFTW3-3.dll i find the function names are present several times, e.g.,
DFFTW_PLAN_DFT_2D@28, dfftw_plan_dft_2d_, dfftw_plan_dft__. The number after @ various for the different subroutines.

As far as I understood, the defaults for ifort on Windows is that no underscore is appended and names are in upercase. Hence the linker was able to resolve the MPI_ ... subroutines with the first ifort command, but not the DFFTW_... routines. Apperently, the @xx appended to the subroutine names in upercase in LIBFFTW3-3.dll prevents the linker to resolve the routines. With the second ifort command, the linker
can resolve the dfftw_ routines but not the mpi_ routines because of the lower case and appended underscore.

How can I link to both libraries at the same time?

P.S. A non MPI version of the code using only FFTW3 compiles, links and runs fine with the options -assume:underscore and -names:lowercase.

Any help is appreciated.

Peter.
0 Kudos
11 Replies
TimP
Honored Contributor III
694 Views
Are you using a build of fftw intended for some other Fortran, such as Absoft? A better solution would be to use the one which comes with current ifort (MKL install option), or rebuild the public source yourself.
0 Kudos
pvds
Beginner
694 Views
I am using the DLLs made available via the offical FFTW website. As the function names in these DLLs are present in different forms, i assume that it is build to be used in combination with different compilers. I am just wondering why "@xx" is present in the uppercase symbol names as this appears to be the reason why the linker can not resolve the external DFFTW_... function names.

The code I am working on is to be released in the public domain and it would be usefull if users could just install FFTW using the DLLs from their website instead of having to rebuild FFTW.

Furthermore, my code can be compiled using different compilers (currently tested with ifort and gfortran) on various systems (linux, OS X, win XP and Vista) and currently uses only open source libraries. So I would like it not to be dependent on MKL.

Peter.
0 Kudos
Lorri_M_Intel
Employee
694 Views
Quoting - pvds
I am using the DLLs made available via the offical FFTW website. As the function names in these DLLs are present in different forms, i assume that it is build to be used in combination with different compilers. I am just wondering why "@xx" is present in the uppercase symbol names as this appears to be the reason why the linker can not resolve the external DFFTW_... function names.

The code I am working on is to be released in the public domain and it would be usefull if users could just install FFTW using the DLLs from their website instead of having to rebuild FFTW.

Furthermore, my code can be compiled using different compilers (currently tested with ifort and gfortran) on various systems (linux, OS X, win XP and Vista) and currently uses only open source libraries. So I would like it not to be dependent on MKL.

Peter.

I downloaded the dlls too, and have been poking at them.

I suspect the @xxx names areintended to beCVF-compatible names. That is, CVF used a calling standard that was very close to the C __stdcall standard, with a few lively exceptions. Does that mean you should compile your application with /iface:cvf ? No, not only because you'll have the same problems with the MPI interfaces but because that is a big ugly hammer.

You are using two different packages with two different calling conventions. In order to do that, you will need to have explicit interfaces for one or the other.

I would recommend that you create interfaces for the fftw routines that you'll be calling, and use ALIAS to get the external name correct.

- Lorri






0 Kudos
pvds
Beginner
694 Views
Dear Lorri, thanks for the suggestions. I have been trying to figure this out the last couple of days. I have written a small test program to see how I should specify the interface to the FFTW routines:
program test
use fftw3
integer, parameter :: n=210
real, parameter :: pi=3.1416
double complex, pointer :: in(:), out(:)
! double complex :: in(n), out(n)
integer*8 plan

interface
subroutine dfftw_plan_dft_1d(plan, n, in, out, int1, int2)
!DEC$ ATTRIBUTES ALIAS:'_dfftw_plan_dft_1d_':: dfftw_plan_dft_1d
integer *8 plan
integer n, int1, int2
double complex in(:), out(:)
end subroutine dfftw_plan_dft_1d

subroutine dfftw_execute_dft(plan, in, out)
!DEC$ ATTRIBUTES ALIAS:'_dfftw_execute_dft_':: dfftw_execute_dft
integer *8 plan
double complex in(:), out(:)
end subroutine dfftw_execute_dft

subroutine dfftw_destroy_plan(plan)
!DEC$ ATTRIBUTES ALIAS:'_dfftw_destroy_plan_':: dfftw_destroy_plan
integer *8 plan
end subroutine dfftw_destroy_plan
end interface

allocate(in(N))
allocate(out(N))
in = (/ (sin(4*pi*i/n), i=1,n) /)
print *,"in="
print *, in
out = dcmplx(0.0d0,0.0d0)
call dfftw_plan_dft_1d(plan,N,in,out,FFTW_FORWARD,FFTW_ESTIMATE)
print *,"plan=",plan
print *,"executing plan"
call dfftw_execute_dft(plan, in, out)
print *,"dft is"
print *, out
call dfftw_destroy_plan(plan)
stop 'end program'
end program

Without the interface block I can compile this using

ifort fftw3.f90, test.f90 libfftw3-3.lib -assume:underscore -names:lowercase

Here fftw3.f90 is the source for a module file that contains all FFTW constant definitions. The resulting program runs fine and seems to give the expected results.
Next I included the interface block as given above and tried to get the names as they would appear with the compiler options -assume:underscore and -names:lowercase. The program compiles and links without error message using

ifort fftw3.f90 test.f90 libfftw3-3.lib

When I run the executable, it runs to the point where it prints " executing plan" to the screen and then aborts with

forrt1: severe (157): Program Exception - access violation.

The value printed out for the plan variable is the same when I use the command line options instead of the interface block.

If I use "C, ALIAS:" instead of "ALIAS:" in the ATTRIBUTES statement I already get an acces violation (same message) with the call to dfftw_plan_dft_1d. The same is true if I use "STDCALL, ALIAS:" instead of "ALIAS:" alone.

Do I have to include more !DEC$ options to have the same behaviour as the "-assume:underscore -name:lowercase" command line options? What may the cause of the access violation? Any help is appreciated.

Peter

0 Kudos
Lorri_M_Intel
Employee
694 Views
Quoting - pvds
Dear Lorri, thanks for the suggestions. I have been trying to figure this out the last couple of days. I have written a small test program to see how I should specify the interface to the FFTW routines:
program test
use fftw3
integer, parameter :: n=210
real, parameter :: pi=3.1416
double complex, pointer :: in(:), out(:)
! double complex :: in(n), out(n)
integer*8 plan

interface
subroutine dfftw_plan_dft_1d(plan, n, in, out, int1, int2)
!DEC$ ATTRIBUTES ALIAS:'_dfftw_plan_dft_1d_':: dfftw_plan_dft_1d
integer *8 plan
integer n, int1, int2
double complex in(:), out(:)
end subroutine dfftw_plan_dft_1d

subroutine dfftw_execute_dft(plan, in, out)
!DEC$ ATTRIBUTES ALIAS:'_dfftw_execute_dft_':: dfftw_execute_dft
integer *8 plan
double complex in(:), out(:)
end subroutine dfftw_execute_dft

subroutine dfftw_destroy_plan(plan)
!DEC$ ATTRIBUTES ALIAS:'_dfftw_destroy_plan_':: dfftw_destroy_plan
integer *8 plan
end subroutine dfftw_destroy_plan
end interface

allocate(in(N))
allocate(out(N))
in = (/ (sin(4*pi*i/n), i=1,n) /)
print *,"in="
print *, in
out = dcmplx(0.0d0,0.0d0)
call dfftw_plan_dft_1d(plan,N,in,out,FFTW_FORWARD,FFTW_ESTIMATE)
print *,"plan=",plan
print *,"executing plan"
call dfftw_execute_dft(plan, in, out)
print *,"dft is"
print *, out
call dfftw_destroy_plan(plan)
stop 'end program'
end program

Without the interface block I can compile this using

ifort fftw3.f90, test.f90 libfftw3-3.lib -assume:underscore -names:lowercase

Here fftw3.f90 is the source for a module file that contains all FFTW constant definitions. The resulting program runs fine and seems to give the expected results.
Next I included the interface block as given above and tried to get the names as they would appear with the compiler options -assume:underscore and -names:lowercase. The program compiles and links without error message using

ifort fftw3.f90 test.f90 libfftw3-3.lib

When I run the executable, it runs to the point where it prints " executing plan" to the screen and then aborts with

forrt1: severe (157): Program Exception - access violation.

The value printed out for the plan variable is the same when I use the command line options instead of the interface block.

If I use "C, ALIAS:" instead of "ALIAS:" in the ATTRIBUTES statement I already get an acces violation (same message) with the call to dfftw_plan_dft_1d. The same is true if I use "STDCALL, ALIAS:" instead of "ALIAS:" alone.

Do I have to include more !DEC$ options to have the same behaviour as the "-assume:underscore -name:lowercase" command line options? What may the cause of the access violation? Any help is appreciated.

Peter


Hi Peter -

Try adding just the !DEC$ ALIAS statements, and not the rest of the interface (quickest thing to try is to comment out all but the ALIAS statements, in case they need to be put back)

If you program worked before by only changing the names, that should work.

If you want to keep your interface blocks (which is the better, long-term solution) the declaration for dfftw_plan_dft_1d should look like this:

subroutine dfftw_plan_dft_1d(plan, n, in, out, int1, int2)
!DEC$ ATTRIBUTES ALIAS:'_dfftw_plan_dft_1d_':: dfftw_plan_dft_1d
integer *8 plan
integer n, int1, int2
double complex in(*), out(*)
end subroutine dfftw_plan_dft_1d

The difference is that the arrays are defined as vectors (ie, f77-style), not assumed-shape. In the first case, the address of the array is passed; in the second case, an F90-descriptor is created and passed to the subroutine. The first case, the f77-style arrays, would be the default if you didn't specify any interface block.

Does this help?

- Lorri

0 Kudos
pvds
Beginner
694 Views
Dear Lorri, Thank you for your suggestion about the F77 style array specifications. This solved my problem. The code now compiles and runs, producing the same resutls as with the command line options.

One further question. I am currently compiling and running on win32, so I believe that the PLAN should be of type INTEGER*4 and not INTEGER*8. The latter is for 64 bits operating systems. My code will be run on WIN64 systems as well. I have tried in the test program above both INTEGER*4 and INTEGER*8 for the PLAN variable and both produce the same result with the ifort compiler. Do yoy think it is save to use the INTEGER*8 for both WIN32 and WIN64 systems, or should I check at compile time what operating system is used and make the appropriate substitution in the source code?

Thanks for solving my problem.

Peter
0 Kudos
Les_Neilson
Valued Contributor II
694 Views
Quoting - pvds
One further question. I am currently compiling and running on win32, so I believe that the PLAN should be of type INTEGER*4 and not INTEGER*8. The latter is for 64 bits operating systems. My code will be run on WIN64 systems as well. I have tried in the test program above both INTEGER*4 and INTEGER*8 for the PLAN variable and both produce the same result with the ifort compiler. Do yoy think it is save to use the INTEGER*8 for both WIN32 and WIN64 systems, or should I check at compile time what operating system is used and make the appropriate substitution in the source code?

Thanks for solving my problem.

Peter

No INTEGER*8 is a language thing not an OS thing.
(INTEGER(KIND=8) is more Standard)
You can use INTEGER*8 wherever you need a large integer value.

If you need an integer that is the size of a "handle" then use INTEGER(HANDLE)

Les
0 Kudos
pvds
Beginner
694 Views
Quoting - Les Neilson

No INTEGER*8 is a language thing not an OS thing.
(INTEGER(KIND=8) is more Standard)
You can use INTEGER*8 wherever you need a large integer value.

If you need an integer that is the size of a "handle" then use INTEGER(HANDLE)

Les

This is true, however, what I meant to say is that on a 32 bit operating system pointers have a 4 byte size and on a 64 bit system they should be 8 bytes. I assumed that a 4 byte integer would hold a 32 bit pointer. Is this true?
I was also wondering about if I would define the plan variable as INTEGER(KIND=8) in the calling program what would happen if the subroutines in the FFTW librarry expect a size INTEGER(KIND=4) for the plan variable.

Peter
0 Kudos
Les_Neilson
Valued Contributor II
694 Views
Quoting - pvds

This is true, however, what I meant to say is that on a 32 bit operating system pointers have a 4 byte size and on a 64 bit system they should be 8 bytes. I assumed that a 4 byte integer would hold a 32 bit pointer. Is this true?
I was also wondering about if I would define the plan variable as INTEGER(KIND=8) in the calling program what would happen if the subroutines in the FFTW librarry expect a size INTEGER(KIND=4) for the plan variable.

Peter

Yes this is why you need to use something like INTEGER(KIND=INT_PTR_KIND()) for pointers and (HANDLE) for handles and so on.
On a 32-bit system it resolves to a 4-byte integer and on a 64-bit system to an 8-byte integer.
But you should only need to use these if you are really using address pointers or handles.

Yes youshould notpass an 8-byte integer to a subroutine expecting a 4-byte integer. But if your FFTW library uses 4-byte integer datathen your calling routines only need to use 4-byte integer data. Presumably the library does not need pointers.

Les
0 Kudos
mamey4
Beginner
694 Views
Hi,

although this is quite an old thread, I have a similar problem right now that I can't solve right now. I link a number of libraries to my project - if I do that without /assume:underscore, I get a whole lot of linker errors about unresolved symbols, whose names all start with an underscore (but don't end with one).

error LNK2001: unresolved symbol "_MPI_Allreduce". mkl_blacs_mpich2.lib(dgsum2d_.oo)

If I use /assume:underscore, however, all the imported symbols are fine, but I get linker errors in the object file of my program. The unresolved symbols here start and end with an underscore.

error LNK2001: unresolved symbol "_MPI_NULL_COPY_FN_". test.obj

From what I understood there are two calling conventions here. Is there a way to fix this problem without using other libraries?

Martin

0 Kudos
TimP
Honored Contributor III
694 Views
As you are linking against MKL built for Argonne MPICH2, you will need to assure that you are using a compatible version of that library. A post on the HPC forum, giving more specifics (version numbers for compiler, OS, MKL, MPICH) might turn up a more prompt expert response. I've heard that the current MPICH2 represents a significant improvement over previous versions, but don't know whether even the latest MKL has been tested with it.
0 Kudos
Reply