- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
In both the same and opposite sense to my previous post (DftiCommitDescriptor fails under Intel-2024 ), Complex-Complex DFTs produce differing results depending on whether you statically or dynamically link the OneAPI library.
Here's my reproducer:
```
! cfft_reproducer.f90
program mkl_fft_example
! USE statements must come before IMPLICIT NONE
use MKL_DFTI
implicit none
type(DFTI_DESCRIPTOR), pointer :: handle
#ifdef MKLI8
integer, parameter :: IK = 8
#else
integer, parameter :: IK = 4
#endif
integer(kind=IK) :: i, status, DIM, LEN, STRIDES_IN(2), STRIDES_OUT(2)
real(kind=4) :: PI, fscale, bscale
real(kind=4) :: max_error
complex(kind=4), allocatable :: x(:), y(:)
DIM = 1
LEN = 16
STRIDES_IN = (/int(0,IK), int(1, IK)/)
STRIDES_OUT = (/int(0,IK), int(1, IK)/)
fscale = 1.0_4
bscale = 1.0_4 / real(LEN, 4)
PI = 3.14159265_4
! Create and set up FFT descriptor
status = DftiCreateDescriptor(handle, DFTI_SINGLE, DFTI_COMPLEX, DIM, LEN)
status = DftiSetValue(handle, DFTI_PLACEMENT, DFTI_INPLACE)
status = DftiSetValue(handle, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX)
status = DftiSetValue(handle, DFTI_INPUT_DISTANCE, LEN)
status = DftiSetValue(handle, DFTI_OUTPUT_DISTANCE, LEN)
status = DftiSetValue(handle, DFTI_INPUT_STRIDES, STRIDES_IN)
status = DftiSetValue(handle, DFTI_OUTPUT_STRIDES, STRIDES_OUT)
status = DftiSetValue(handle, DFTI_FORWARD_SCALE, bscale)
status = DftiSetValue(handle, DFTI_BACKWARD_SCALE, fscale)
status = DftiCommitDescriptor(handle)
if (status /= 0) then
print *, 'Error creating FFT descriptor'
stop
end if
allocate(x(LEN))
allocate(y(LEN))
! Initialize input signal: simple sinusoid
do i = 1, LEN
x(i) = cmplx(cos(2.0_4 * PI * (i-1) / LEN), &
sin(2.0_4 * PI * (i-1) / LEN), kind=4)
end do
! Save copy for comparison
y(:) = x(:)
! Print original signal
print *, 'Original signal:'
do i = 1, LEN
print '(I3,": (",F10.4,",",F10.4,")")', i, real(x(i)), aimag(x(i))
end do
! Forward transform
status = DftiComputeForward(handle, x)
! Inverse transform
status = DftiComputeBackward(handle, x)
print *, ''
print *, 'After inverse FFT (scaled):'
! Compute maximum error
max_error = 0.0_4
do i = 1, LEN
print '(I3,": (",F10.4,",",F10.4,")")', i, real(x(i)), aimag(x(i))
max_error = max(max_error, &
max(abs(real(x(i) - y(i))), abs(aimag(x(i) - y(i)))))
end do
print *, ''
print '("Maximum error: ",E12.4)', max_error
! Clean up
status = DftiFreeDescriptor(handle)
end program mkl_fft_example
```
Compiled with
```
Compiled with
```
TARGET = cfft_reproducer
SRC = cfft_reproducer.f90
INCLUDE_FLAGS = -I${MKLROOT}/include/intel64/ilp64
ifdef OLD
##### OLD STYLE #####
FCFLAGS = -qopenmp -Wl,--start-group \
${MKLROOT}/lib/intel64/libmkl_blas95_ilp64.a \
${MKLROOT}/lib/intel64/libmkl_lapack95_ilp64.a \
${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a \
${MKLROOT}/lib/intel64/libmkl_core.a \
${MKLROOT}/lib/intel64/libmkl_intel_thread.a \
-Wl,--end-group
else ifdef NEW
##### NEW STYLE #####
FCFLAGS = -qmkl
endif
$(TARGET): $(SRC)
${FC} -fpp -DMKLI8 $(INCLUDE_FLAGS) -o $(TARGET) $(SRC) $(FCFLAGS)
clean:
rm -f $(TARGET) *.o
```
If I do:
```
module load intel/intel-2021
export FC=ifort
make clean; make OLD=x; ./cfft_reproducer # compiles, runs successfully
make clean; make NEW=x; ./cfft_reproducer # compiles, produces incorrect result
```
However, if I do:
```
module load intel/intel-2024
export FC=ifx
make clean; make OLD=x; ./cfft_reproducer # compiles, runs successfully
If I do:
```
module load intel/intel-2021
export FC=ifort
make clean; make OLD=x; ./cfft_reproducer # compiles, runs successfully
make clean; make NEW=x; ./cfft_reproducer # compiles, produces incorrect result
```
However, if I do:
```
module load intel/intel-2024
export FC=ifx
make clean; make OLD=x; ./cfft_reproducer # compiles, runs successfully
make clean; make NEW=x; ./cfft_reproducer # compiles, produces incorrect result
```
```
By incorrect result, I mean it's skipping the first index (presumably the place where the Nyquist frequency is stored), with the remaining array matching the input.
If someone can please explain this behaviour, I'd appreciate it.
Note:
`module load intel/intel-2021` will point MKLROOT to `.../oneapi-2021.update.4/mkl/2021.4.0`
`module load intel/intel-2024` will point MKLROOT to `.../oneapi-2024.update.1/mkl/2024.1`
If someone can please explain this behaviour, I'd appreciate it.
Note:
`module load intel/intel-2021` will point MKLROOT to `.../oneapi-2021.update.4/mkl/2021.4.0`
`module load intel/intel-2024` will point MKLROOT to `.../oneapi-2024.update.1/mkl/2024.1`
Link Copied
0 Replies

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