Skip to content

Commit 311b737

Browse files
authored
[API compatibility] support windows api (#76237)
* align_window_func_with_torch * adapt the parameters * add test * fix the cpu_only_paddle * add comment * fix the operate logic * add device process * optimize code
1 parent ca6936b commit 311b737

File tree

3 files changed

+472
-0
lines changed

3 files changed

+472
-0
lines changed

python/paddle/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@ def new_init(self, *args, **kwargs):
228228
is_autocast_enabled,
229229
)
230230
from .amp.auto_cast import autocast
231+
from .audio.functional.window import ( # noqa: F401
232+
bartlett_window,
233+
blackman_window,
234+
hamming_window,
235+
hann_window,
236+
kaiser_window,
237+
)
231238
from .autograd import (
232239
enable_grad,
233240
grad,

python/paddle/audio/functional/window.py

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from __future__ import annotations
1414

1515
import math
16+
import warnings
1617
from typing import TYPE_CHECKING
1718

1819
import numpy as np
@@ -21,9 +22,17 @@
2122

2223
if TYPE_CHECKING:
2324
from paddle import Tensor
25+
from paddle._typing import PlaceLike
2426

2527
from ..features.layers import _WindowLiteral
2628

29+
from paddle.base.framework import (
30+
_current_expected_place,
31+
_get_paddle_place,
32+
core,
33+
in_dynamic_or_pir_mode,
34+
)
35+
2736

2837
class WindowFunctionRegister:
2938
def __init__(self):
@@ -445,3 +454,287 @@ def get_window(
445454
params = (win_length, *args)
446455
kwargs = {'sym': sym}
447456
return winfunc(*params, dtype=dtype, **kwargs)
457+
458+
459+
def _apply_window_postprocess(
460+
w: Tensor,
461+
*,
462+
layout: str | None = None,
463+
device: PlaceLike | None = None,
464+
pin_memory: bool = False,
465+
requires_grad: bool = False,
466+
) -> Tensor:
467+
if layout is not None:
468+
warnings.warn("layout only supports 'strided' in Paddle; ignored")
469+
470+
if in_dynamic_or_pir_mode():
471+
device = (
472+
_get_paddle_place(device)
473+
if device is not None
474+
else _current_expected_place()
475+
)
476+
if (
477+
pin_memory
478+
and paddle.in_dynamic_mode()
479+
and device is not None
480+
and not isinstance(
481+
device, (core.CUDAPinnedPlace, core.XPUPinnedPlace)
482+
)
483+
):
484+
if isinstance(device, core.CUDAPlace) or (
485+
isinstance(device, core.Place) and device.is_gpu_place()
486+
):
487+
device = core.CUDAPinnedPlace()
488+
elif isinstance(device, core.XPUPlace) or (
489+
isinstance(device, core.Place) and device.is_xpu_place()
490+
):
491+
device = core.XPUPinnedPlace()
492+
else:
493+
raise RuntimeError(
494+
f"Pinning memory is not supported for {device}"
495+
)
496+
w = w.to(device=device)
497+
if pin_memory and paddle.in_dynamic_mode():
498+
w = w.pin_memory()
499+
if requires_grad is True:
500+
w.stop_gradient = False
501+
return w
502+
503+
504+
def hamming_window(
505+
window_length: int,
506+
periodic: bool = True,
507+
alpha: float = 0.54,
508+
beta: float = 0.46,
509+
*,
510+
dtype: str = 'float64',
511+
layout: str | None = None,
512+
device: PlaceLike | None = None,
513+
pin_memory: bool = False,
514+
requires_grad: bool = False,
515+
):
516+
"""
517+
Compute a generalized Hamming window.
518+
519+
Args:
520+
window_length (int): The size of the returned window. Must be positive.
521+
periodic (bool, optional): If True, returns a window for use as a periodic function; if False, returns a symmetric window. Defaults to True.
522+
alpha (float, optional): The coefficient α in the equation above. Defaults to 0.54.
523+
beta (float, optional): The coefficient β in the equation above. Defaults to 0.46.
524+
dtype (str, optional): The data type of the returned tensor. Defaults to 'float64'.
525+
layout (str, optional): Only included for API consistency with PyTorch; ignored in Paddle. Defaults to None.
526+
device(PlaceLike|None, optional): The desired device of returned tensor.
527+
if None, uses the current device for the default tensor type (see paddle.device.set_device()).
528+
device will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types. Default: None.
529+
pin_memory(bool, optional): If set, return tensor would be allocated in the pinned memory. Works only for CPU tensors. Default: False
530+
requires_grad(bool, optional): If autograd should record operations on the returned tensor. Default: False.
531+
532+
Returns:
533+
Tensor: A 1-D tensor of shape `(window_length,)` containing the Hamming window.
534+
535+
Examples:
536+
.. code-block:: python
537+
538+
>>> import paddle
539+
540+
>>> win = paddle.hamming_window(400, requires_grad=True)
541+
>>> win = paddle.hamming_window(256, alpha=0.5, beta=0.5)
542+
"""
543+
w0 = get_window('hamming', window_length, fftbins=periodic, dtype=dtype)
544+
alpha0, beta0 = 0.54, 0.46
545+
B = beta / beta0
546+
A = alpha - B * alpha0
547+
w = A + B * w0
548+
return _apply_window_postprocess(
549+
w,
550+
layout=layout,
551+
device=device,
552+
pin_memory=pin_memory,
553+
requires_grad=requires_grad,
554+
)
555+
556+
557+
def hann_window(
558+
window_length: int,
559+
periodic: bool = True,
560+
*,
561+
dtype: str = 'float64',
562+
layout: str | None = None,
563+
device: PlaceLike | None = None,
564+
pin_memory: bool = False,
565+
requires_grad: bool = False,
566+
):
567+
"""
568+
Compute a Hann window.
569+
570+
Args:
571+
window_length (int): The size of the returned window. Must be positive.
572+
periodic (bool, optional): If True, returns a window for use as a periodic function; if False, returns a symmetric window. Defaults to True.
573+
dtype (str, optional): The data type of the returned tensor. Defaults to 'float64'.
574+
layout (str, optional): Only included for API consistency with PyTorch; ignored in Paddle. Defaults to None.
575+
device(PlaceLike|None, optional): The desired device of returned tensor.
576+
if None, uses the current device for the default tensor type (see paddle.device.set_device()).
577+
device will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types. Default: None.
578+
pin_memory(bool, optional): If set, return tensor would be allocated in the pinned memory. Works only for CPU tensors. Default: False
579+
requires_grad(bool, optional): If autograd should record operations on the returned tensor. Default: False.
580+
581+
Returns:
582+
Tensor: A 1-D tensor of shape `(window_length,)` containing the Hann window.
583+
584+
Examples:
585+
.. code-block:: python
586+
587+
>>> import paddle
588+
589+
>>> win = paddle.hann_window(512)
590+
>>> win = paddle.hann_window(512, requires_grad=True)
591+
"""
592+
w = get_window('hann', window_length, fftbins=periodic, dtype=dtype)
593+
return _apply_window_postprocess(
594+
w,
595+
layout=layout,
596+
device=device,
597+
pin_memory=pin_memory,
598+
requires_grad=requires_grad,
599+
)
600+
601+
602+
def kaiser_window(
603+
window_length: int,
604+
periodic: bool = True,
605+
beta: float = 12.0,
606+
*,
607+
dtype: str = 'float64',
608+
layout: str | None = None,
609+
device: PlaceLike | None = None,
610+
pin_memory: bool = False,
611+
requires_grad: bool = False,
612+
):
613+
"""
614+
Compute a Kaiser window.
615+
616+
Args:
617+
window_length (int): The size of the returned window. Must be positive.
618+
periodic (bool, optional): If True, returns a window for use as a periodic function; if False, returns a symmetric window. Defaults to True.
619+
beta (float, optional): Shape parameter for the window. Defaults to 12.0.
620+
dtype (str, optional): The data type of the returned tensor. Defaults to 'float64'.
621+
layout (str, optional): Only included for API consistency with PyTorch; ignored in Paddle. Defaults to None.
622+
device(PlaceLike|None, optional): The desired device of returned tensor.
623+
if None, uses the current device for the default tensor type (see paddle.device.set_device()).
624+
device will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types. Default: None.
625+
pin_memory(bool, optional): If set, return tensor would be allocated in the pinned memory. Works only for CPU tensors. Default: False
626+
requires_grad(bool, optional): If autograd should record operations on the returned tensor. Default: False.
627+
628+
Returns:
629+
Tensor: A 1-D tensor of shape `(window_length,)` containing the Kaiser window.
630+
631+
Examples:
632+
.. code-block:: python
633+
634+
>>> import paddle
635+
636+
>>> win = paddle.kaiser_window(400, beta=8.6)
637+
>>> win = paddle.kaiser_window(400, requires_grad=True)
638+
"""
639+
w = get_window(
640+
('kaiser', beta), window_length, fftbins=periodic, dtype=dtype
641+
)
642+
return _apply_window_postprocess(
643+
w,
644+
layout=layout,
645+
device=device,
646+
pin_memory=pin_memory,
647+
requires_grad=requires_grad,
648+
)
649+
650+
651+
def blackman_window(
652+
window_length: int,
653+
periodic: bool = True,
654+
*,
655+
dtype: str = 'float64',
656+
layout: str | None = None,
657+
device: PlaceLike | None = None,
658+
pin_memory: bool = False,
659+
requires_grad: bool = False,
660+
):
661+
"""
662+
Compute a Blackman window.
663+
664+
Args:
665+
window_length (int): The size of the returned window. Must be positive.
666+
periodic (bool, optional): If True, returns a window for use as a periodic function; if False, returns a symmetric window. Defaults to True.
667+
dtype (str, optional): The data type of the returned tensor. Defaults to 'float64'.
668+
layout (str, optional): Only included for API consistency with PyTorch; ignored in Paddle. Defaults to None.
669+
device(PlaceLike|None, optional): The desired device of returned tensor.
670+
if None, uses the current device for the default tensor type (see paddle.device.set_device()).
671+
device will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types. Default: None.
672+
pin_memory(bool, optional): If set, return tensor would be allocated in the pinned memory. Works only for CPU tensors. Default: False
673+
requires_grad(bool, optional): If autograd should record operations on the returned tensor. Default: False.
674+
675+
Returns:
676+
Tensor: A 1-D tensor of shape `(window_length,)` containing the Blackman window.
677+
678+
Examples:
679+
.. code-block:: python
680+
681+
>>> import paddle
682+
683+
>>> win = paddle.blackman_window(256)
684+
>>> win = paddle.blackman_window(256, requires_grad=True)
685+
"""
686+
w = get_window('blackman', window_length, fftbins=periodic, dtype=dtype)
687+
return _apply_window_postprocess(
688+
w,
689+
layout=layout,
690+
device=device,
691+
pin_memory=pin_memory,
692+
requires_grad=requires_grad,
693+
)
694+
695+
696+
def bartlett_window(
697+
window_length: int,
698+
periodic: bool = True,
699+
*,
700+
dtype: str = 'float64',
701+
layout: str | None = None,
702+
device: PlaceLike | None = None,
703+
pin_memory: bool = False,
704+
requires_grad: bool = False,
705+
):
706+
"""
707+
Compute a Bartlett window.
708+
709+
Args:
710+
window_length (int): The size of the returned window. Must be positive.
711+
periodic (bool, optional): If True, returns a window for use as a periodic function; if False, returns a symmetric window. Defaults to True.
712+
dtype (str, optional): The data type of the returned tensor. Defaults to 'float64'.
713+
layout (str, optional): Only included for API consistency with PyTorch; ignored in Paddle. Defaults to None.
714+
device(PlaceLike|None, optional): The desired device of returned tensor.
715+
if None, uses the current device for the default tensor type (see paddle.device.set_device()).
716+
device will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types. Default: None.
717+
pin_memory(bool, optional): If set, return tensor would be allocated in the pinned memory. Works only for CPU tensors. Default: False
718+
requires_grad(bool, optional): If autograd should record operations on the returned tensor. Default: False.
719+
720+
Returns:
721+
Tensor: A 1-D tensor of shape `(window_length,)` containing the Bartlett window.
722+
723+
Examples:
724+
.. code-block:: python
725+
726+
>>> import paddle
727+
728+
>>> n_fft = 512
729+
>>> win = paddle.bartlett_window(n_fft)
730+
731+
>>> win = paddle.bartlett_window(n_fft, requires_grad=True)
732+
"""
733+
w = get_window('bartlett', window_length, fftbins=periodic, dtype=dtype)
734+
return _apply_window_postprocess(
735+
w,
736+
layout=layout,
737+
device=device,
738+
pin_memory=pin_memory,
739+
requires_grad=requires_grad,
740+
)

0 commit comments

Comments
 (0)