Skip to content

Added Intel mkl_fft #484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 48 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d30cc4e
Added mkl-fft along with examples and tests
rohanbabbar04 Feb 7, 2023
300b9c5
Added mkl-fft along with examples and tests
rohanbabbar04 Feb 7, 2023
1ca769e
Renamed _numpy_fft to pymkl_fft
rohanbabbar04 Feb 7, 2023
b002cb0
Updated requirements-doc.txt
rohanbabbar04 Feb 7, 2023
1c557bf
Quick Fix
rohanbabbar04 Feb 8, 2023
cf62f9a
Test fix
rohanbabbar04 Feb 8, 2023
da2a621
Removed KMP duplication
rohanbabbar04 Feb 8, 2023
4868d37
Added nomkl to env-dev
rohanbabbar04 Feb 8, 2023
2fa6732
FFT2D Fix
rohanbabbar04 Feb 9, 2023
266ca7a
FFT2D updated
rohanbabbar04 Feb 9, 2023
73c48a2
Removed mkl scipy backend
rohanbabbar04 Feb 9, 2023
8e6cb9a
Removed nomkl
rohanbabbar04 Feb 9, 2023
5c05501
Added imports above numpy
rohanbabbar04 Feb 12, 2023
3f221fc
Updated ffts
rohanbabbar04 Feb 12, 2023
4ee0f71
Added KMP_DUPLICATE_LIB_OK
rohanbabbar04 Feb 15, 2023
6101ba4
Added KMP_DUPLICATE_LIB_OK
rohanbabbar04 Feb 15, 2023
fb535f5
Add MKL_THREADING
rohanbabbar04 Feb 15, 2023
c27728a
Updated plot_fft.py
rohanbabbar04 Feb 16, 2023
4911d0e
Added torch fix
rohanbabbar04 Feb 16, 2023
acfe2ce
Added deps and fft, fft2d, fftnd
rohanbabbar04 Feb 16, 2023
37a48be
Updated FFTS and added noqa
rohanbabbar04 Feb 16, 2023
f838c1e
Updated deps
rohanbabbar04 Feb 16, 2023
b4656a9
Updated deps
rohanbabbar04 Feb 17, 2023
8da2c3e
Updated azure-pipelines.yml
rohanbabbar04 Feb 17, 2023
fafe25e
Added mkl_fft_message
rohanbabbar04 Feb 17, 2023
a03d1e4
Updated Torch commands for mkl_fft
rohanbabbar04 Feb 17, 2023
bee7e9f
Rearranged imports
rohanbabbar04 Feb 17, 2023
899ddd4
Reverted azure-pipelines.yml
rohanbabbar04 Feb 17, 2023
04c966a
Test Updated plot_fft.py
rohanbabbar04 Feb 17, 2023
abf0253
Test Updated plot_fft.py
rohanbabbar04 Feb 17, 2023
63aa63f
Test Updated plot_fft.py
rohanbabbar04 Feb 17, 2023
9819b21
Test Updated plot_fft.py
rohanbabbar04 Feb 17, 2023
d319332
Updated plot_fft.py
rohanbabbar04 Feb 17, 2023
e473d84
Updated plot_fft.py
rohanbabbar04 Feb 17, 2023
a2743d0
Updated environment-dev.yml and setup.py
rohanbabbar04 Feb 18, 2023
ae9d48a
Updated plot_fft.py
rohanbabbar04 Feb 18, 2023
2583520
Test for python 3.8 docs
rohanbabbar04 Feb 18, 2023
2372c08
Updated readthedocs.yml to test
rohanbabbar04 Feb 18, 2023
6cdb3e1
Reverting readthedocs.yml
rohanbabbar04 Feb 18, 2023
2f91d80
Reverting
rohanbabbar04 Feb 18, 2023
492ee68
Reverting
rohanbabbar04 Feb 18, 2023
b1a9788
Reverting
rohanbabbar04 Feb 18, 2023
35fbbce
Test plot_fft.py
rohanbabbar04 Feb 18, 2023
de96361
Updated ffts
rohanbabbar04 Feb 18, 2023
591835b
Test plot_fft.py
rohanbabbar04 Feb 18, 2023
0ec7169
Test plot_fft.py
rohanbabbar04 Feb 18, 2023
a2a4924
Test plot_fft.py
rohanbabbar04 Feb 18, 2023
afb3885
Test plot_fft.py
rohanbabbar04 Feb 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ channels:
dependencies:
- python>=3.6.4
- pip
- mkl
- mkl_fft
- mkl-service
- numpy>=1.21.0
- scipy>=1.4.0
- pytorch>=1.2.0
Expand Down
327 changes: 174 additions & 153 deletions examples/plot_fft.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,173 +6,194 @@
and :py:class:`pylops.signalprocessing.FFTND` operators to apply the Fourier
Transform to the model and the inverse Fourier Transform to the data.
"""
import matplotlib.pyplot as plt
import numpy as np

# import matplotlib.pyplot as plt
import pylops

plt.close("all")

###############################################################################
# Let's start by applying the one dimensional FFT to a one dimensional
# sinusoidal signal :math:`d(t)=sin(2 \pi f_0t)` using a time axis of
# lenght :math:`nt` and sampling :math:`dt`
import numpy as np
#
#
# plt.close("all")
#
# ###############################################################################
# # Let's start by applying the one dimensional FFT to a one dimensional
# # sinusoidal signal :math:`d(t)=sin(2 \pi f_0t)` using a time axis of
# # lenght :math:`nt` and sampling :math:`dt`
dt = 0.005
nt = 100
t = np.arange(nt) * dt
f0 = 10
nfft = 2**10
d = np.sin(2 * np.pi * f0 * t)

FFTop = pylops.signalprocessing.FFT(dims=nt, nfft=nfft, sampling=dt, engine="numpy")
D = FFTop * d

# Adjoint = inverse for FFT
dinv = FFTop.H * D
dinv = FFTop / D

fig, axs = plt.subplots(1, 2, figsize=(10, 4))
axs[0].plot(t, d, "k", lw=2, label="True")
axs[0].plot(t, dinv.real, "--r", lw=2, label="Inverted")
axs[0].legend()
axs[0].set_title("Signal")
axs[1].plot(FFTop.f[: int(FFTop.nfft / 2)], np.abs(D[: int(FFTop.nfft / 2)]), "k", lw=2)
axs[1].set_title("Fourier Transform")
axs[1].set_xlim([0, 3 * f0])
plt.tight_layout()
#
# FFTop = pylops.FFT(dims=nt, nfft=nfft, sampling=dt, engine="numpy")
# D = FFTop * d
#
# # Adjoint = inverse for FFT
# dinv = FFTop.H * D
# dinv = FFTop / D
#
# fig, axs = plt.subplots(1, 2, figsize=(10, 4))
# axs[0].plot(t, d, "k", lw=2, label="True")
# axs[0].plot(t, dinv.real, "--r", lw=2, label="Inverted")
# axs[0].legend()
# axs[0].set_title("Signal")
# axs[1].plot(FFTop.f[: int(FFTop.nfft / 2)], np.abs(D[: int(FFTop.nfft / 2)]), "k", lw=2)
# axs[1].set_title("Fourier Transform")
# axs[1].set_xlim([0, 3 * f0])
# plt.tight_layout()
#
# ###############################################################################
# # In this example we used numpy as our engine for the ``fft`` and ``ifft``.
# # PyLops implements a second engine (``engine='fftw'``) which uses the
# # well-known `FFTW <http://www.fftw.org>`_ via the python wrapper
# # :py:class:`pyfftw.FFTW`. This optimized fft tends to outperform the one from
# # numpy in many cases but it is not inserted in the mandatory requirements of
# # PyLops. If interested to use ``FFTW`` backend, read the `fft routines`
# # section at :ref:`performance`.
# FFTop = pylops.FFT(dims=nt, nfft=nfft, sampling=dt, engine="fftw")
# D = FFTop * d
#
# # Adjoint = inverse for FFT
# dinv = FFTop.H * D
# dinv = FFTop / D
#
# fig, axs = plt.subplots(1, 2, figsize=(10, 4))
# axs[0].plot(t, d, "k", lw=2, label="True")
# axs[0].plot(t, dinv.real, "--r", lw=2, label="Inverted")
# axs[0].legend()
# axs[0].set_title("Signal")
# axs[1].plot(FFTop.f[: int(FFTop.nfft / 2)], np.abs(D[: int(FFTop.nfft / 2)]), "k", lw=2)
# axs[1].set_title("Fourier Transform with fftw")
# axs[1].set_xlim([0, 3 * f0])
# plt.tight_layout()

###############################################################################
# In this example we used numpy as our engine for the ``fft`` and ``ifft``.
# PyLops implements a second engine (``engine='fftw'``) which uses the
# well-known `FFTW <http://www.fftw.org>`_ via the python wrapper
# :py:class:`pyfftw.FFTW`. This optimized fft tends to outperform the one from
# numpy in many cases but it is not inserted in the mandatory requirements of
# PyLops. If interested to use ``FFTW`` backend, read the `fft routines`
# section at :ref:`performance`.
FFTop = pylops.signalprocessing.FFT(dims=nt, nfft=nfft, sampling=dt, engine="fftw")
# PyLops implements a third engine (``engine='mkl_fft'``) which uses the
# well-known `mkl_fft <https://github.com/IntelPython/mkl_fft>`_ .
FFTop = pylops.FFT(dims=nt, nfft=nfft, sampling=dt, engine="mkl_fft")
D = FFTop * d

# Adjoint = inverse for FFT
dinv = FFTop.H * D
dinv = FFTop / D

fig, axs = plt.subplots(1, 2, figsize=(10, 4))
axs[0].plot(t, d, "k", lw=2, label="True")
axs[0].plot(t, dinv.real, "--r", lw=2, label="Inverted")
axs[0].legend()
axs[0].set_title("Signal")
axs[1].plot(FFTop.f[: int(FFTop.nfft / 2)], np.abs(D[: int(FFTop.nfft / 2)]), "k", lw=2)
axs[1].set_title("Fourier Transform with fftw")
axs[1].set_xlim([0, 3 * f0])
plt.tight_layout()
# dinv = FFTop.H * D
# dinv = FFTop / D
#
# fig, axs = plt.subplots(1, 2, figsize=(10, 4))
# axs[0].plot(t, d, "k", lw=2, label="True")
# axs[0].plot(t, dinv.real, "--r", lw=2, label="Inverted")
# axs[0].legend()
# axs[0].set_title("Signal")
# axs[1].plot(FFTop.f[: int(FFTop.nfft / 2)], np.abs(D[: int(FFTop.nfft / 2)]), "k", lw=2)
# axs[1].set_title("Fourier Transform with mkl_fft")
# axs[1].set_xlim([0, 3 * f0])
# plt.tight_layout()

###############################################################################
# We can also apply the one dimensional FFT to to a two-dimensional
# signal (along one of the first axis)
dt = 0.005
nt, nx = 100, 20
t = np.arange(nt) * dt
f0 = 10
nfft = 2**10
d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1)

FFTop = pylops.signalprocessing.FFT(dims=(nt, nx), axis=0, nfft=nfft, sampling=dt)
D = FFTop * d.ravel()

# Adjoint = inverse for FFT
dinv = FFTop.H * D
dinv = FFTop / D
dinv = np.real(dinv).reshape(nt, nx)

fig, axs = plt.subplots(2, 2, figsize=(10, 6))
axs[0][0].imshow(d, vmin=-20, vmax=20, cmap="bwr")
axs[0][0].set_title("Signal")
axs[0][0].axis("tight")
axs[0][1].imshow(np.abs(D.reshape(nfft, nx)[:200, :]), cmap="bwr")
axs[0][1].set_title("Fourier Transform")
axs[0][1].axis("tight")
axs[1][0].imshow(dinv, vmin=-20, vmax=20, cmap="bwr")
axs[1][0].set_title("Inverted")
axs[1][0].axis("tight")
axs[1][1].imshow(d - dinv, vmin=-20, vmax=20, cmap="bwr")
axs[1][1].set_title("Error")
axs[1][1].axis("tight")
fig.tight_layout()

###############################################################################
# We can also apply the two dimensional FFT to to a two-dimensional signal
dt, dx = 0.005, 5
nt, nx = 100, 201
t = np.arange(nt) * dt
x = np.arange(nx) * dx
f0 = 10
nfft = 2**10
d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1)

FFTop = pylops.signalprocessing.FFT2D(
dims=(nt, nx), nffts=(nfft, nfft), sampling=(dt, dx)
)
D = FFTop * d.ravel()

dinv = FFTop.H * D
dinv = FFTop / D
dinv = np.real(dinv).reshape(nt, nx)

fig, axs = plt.subplots(2, 2, figsize=(10, 6))
axs[0][0].imshow(d, vmin=-100, vmax=100, cmap="bwr")
axs[0][0].set_title("Signal")
axs[0][0].axis("tight")
axs[0][1].imshow(
np.abs(np.fft.fftshift(D.reshape(nfft, nfft), axes=1)[:200, :]), cmap="bwr"
)
axs[0][1].set_title("Fourier Transform")
axs[0][1].axis("tight")
axs[1][0].imshow(dinv, vmin=-100, vmax=100, cmap="bwr")
axs[1][0].set_title("Inverted")
axs[1][0].axis("tight")
axs[1][1].imshow(d - dinv, vmin=-100, vmax=100, cmap="bwr")
axs[1][1].set_title("Error")
axs[1][1].axis("tight")
fig.tight_layout()


###############################################################################
# Finally can apply the three dimensional FFT to to a three-dimensional signal
dt, dx, dy = 0.005, 5, 3
nt, nx, ny = 30, 21, 11
t = np.arange(nt) * dt
x = np.arange(nx) * dx
y = np.arange(nx) * dy
f0 = 10
nfft = 2**6
nfftk = 2**5

d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1)
d = np.tile(d[:, :, np.newaxis], [1, 1, ny])

FFTop = pylops.signalprocessing.FFTND(
dims=(nt, nx, ny), nffts=(nfft, nfftk, nfftk), sampling=(dt, dx, dy)
)
D = FFTop * d.ravel()

dinv = FFTop.H * D
dinv = FFTop / D
dinv = np.real(dinv).reshape(nt, nx, ny)

fig, axs = plt.subplots(2, 2, figsize=(10, 6))
axs[0][0].imshow(d[:, :, ny // 2], vmin=-20, vmax=20, cmap="bwr")
axs[0][0].set_title("Signal")
axs[0][0].axis("tight")
axs[0][1].imshow(
np.abs(np.fft.fftshift(D.reshape(nfft, nfftk, nfftk), axes=1)[:20, :, nfftk // 2]),
cmap="bwr",
)
axs[0][1].set_title("Fourier Transform")
axs[0][1].axis("tight")
axs[1][0].imshow(dinv[:, :, ny // 2], vmin=-20, vmax=20, cmap="bwr")
axs[1][0].set_title("Inverted")
axs[1][0].axis("tight")
axs[1][1].imshow(d[:, :, ny // 2] - dinv[:, :, ny // 2], vmin=-20, vmax=20, cmap="bwr")
axs[1][1].set_title("Error")
axs[1][1].axis("tight")
fig.tight_layout()
# dt = 0.005
# nt, nx = 100, 20
# t = np.arange(nt) * dt
# f0 = 10
# nfft = 2**10
# d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1)
#
# FFTop = pylops.signalprocessing.FFT(dims=(nt, nx), axis=0, nfft=nfft, sampling=dt)
# D = FFTop * d.ravel()
#
# # Adjoint = inverse for FFT
# dinv = FFTop.H * D
# dinv = FFTop / D
# dinv = np.real(dinv).reshape(nt, nx)
#
# fig, axs = plt.subplots(2, 2, figsize=(10, 6))
# axs[0][0].imshow(d, vmin=-20, vmax=20, cmap="bwr")
# axs[0][0].set_title("Signal")
# axs[0][0].axis("tight")
# axs[0][1].imshow(np.abs(D.reshape(nfft, nx)[:200, :]), cmap="bwr")
# axs[0][1].set_title("Fourier Transform")
# axs[0][1].axis("tight")
# axs[1][0].imshow(dinv, vmin=-20, vmax=20, cmap="bwr")
# axs[1][0].set_title("Inverted")
# axs[1][0].axis("tight")
# axs[1][1].imshow(d - dinv, vmin=-20, vmax=20, cmap="bwr")
# axs[1][1].set_title("Error")
# axs[1][1].axis("tight")
# fig.tight_layout()
#
# ###############################################################################
# # We can also apply the two dimensional FFT to to a two-dimensional signal
# dt, dx = 0.005, 5
# nt, nx = 100, 201
# t = np.arange(nt) * dt
# x = np.arange(nx) * dx
# f0 = 10
# nfft = 2**10
# d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1)
#
# FFTop = pylops.FFT2D(
# dims=(nt, nx), nffts=(nfft, nfft), sampling=(dt, dx)
# )
# D = FFTop * d.ravel()
#
# dinv = FFTop.H * D
# dinv = FFTop / D
# dinv = np.real(dinv).reshape(nt, nx)
#
# fig, axs = plt.subplots(2, 2, figsize=(10, 6))
# axs[0][0].imshow(d, vmin=-100, vmax=100, cmap="bwr")
# axs[0][0].set_title("Signal")
# axs[0][0].axis("tight")
# axs[0][1].imshow(
# np.abs(np.fft.fftshift(D.reshape(nfft, nfft), axes=1)[:200, :]), cmap="bwr"
# )
# axs[0][1].set_title("Fourier Transform")
# axs[0][1].axis("tight")
# axs[1][0].imshow(dinv, vmin=-100, vmax=100, cmap="bwr")
# axs[1][0].set_title("Inverted")
# axs[1][0].axis("tight")
# axs[1][1].imshow(d - dinv, vmin=-100, vmax=100, cmap="bwr")
# axs[1][1].set_title("Error")
# axs[1][1].axis("tight")
# fig.tight_layout()
#
#
# ###############################################################################
# # Finally can apply the three dimensional FFT to to a three-dimensional signal
# dt, dx, dy = 0.005, 5, 3
# nt, nx, ny = 30, 21, 11
# t = np.arange(nt) * dt
# x = np.arange(nx) * dx
# y = np.arange(nx) * dy
# f0 = 10
# nfft = 2**6
# nfftk = 2**5
#
# d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1)
# d = np.tile(d[:, :, np.newaxis], [1, 1, ny])
#
# FFTop = pylops.FFTND(
# dims=(nt, nx, ny), nffts=(nfft, nfftk, nfftk), sampling=(dt, dx, dy)
# )
# D = FFTop * d.ravel()
#
# dinv = FFTop.H * D
# dinv = FFTop / D
# dinv = np.real(dinv).reshape(nt, nx, ny)
#
# fig, axs = plt.subplots(2, 2, figsize=(10, 6))
# axs[0][0].imshow(d[:, :, ny // 2], vmin=-20, vmax=20, cmap="bwr")
# axs[0][0].set_title("Signal")
# axs[0][0].axis("tight")
# axs[0][1].imshow(
# np.abs(np.fft.fftshift(D.reshape(nfft, nfftk, nfftk), axes=1)[:20, :, nfftk // 2]),
# cmap="bwr",
# )
# axs[0][1].set_title("Fourier Transform")
# axs[0][1].axis("tight")
# axs[1][0].imshow(dinv[:, :, ny // 2], vmin=-20, vmax=20, cmap="bwr")
# axs[1][0].set_title("Inverted")
# axs[1][0].axis("tight")
# axs[1][1].imshow(d[:, :, ny // 2] - dinv[:, :, ny // 2], vmin=-20, vmax=20, cmap="bwr")
# axs[1][1].set_title("Error")
# axs[1][1].axis("tight")
# fig.tight_layout()
3 changes: 2 additions & 1 deletion pylops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@

from .config import *
from .linearoperator import *
from .torchoperator import *
from .basicoperators import *
from . import (
avo,
Expand All @@ -57,6 +56,8 @@
utils,
waveeqprocessing,
)
from .torchoperator import *
from .signalprocessing import *
from .avo.poststack import *
from .avo.prestack import *
from .optimization.basic import *
Expand Down
Loading