Skip to content
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

Add symiirorder1 to cupyx.scipy.signal #7511

Merged
merged 8 commits into from
Apr 13, 2023
Merged

Conversation

andfoy
Copy link
Contributor

@andfoy andfoy commented Apr 5, 2023

See #7403

@takagi takagi self-assigned this Apr 6, 2023
@takagi takagi added cat:feature New features/APIs prio:medium labels Apr 6, 2023
@andfoy andfoy marked this pull request as ready for review April 7, 2023 22:54
@mergify
Copy link
Contributor

mergify bot commented Apr 10, 2023

This pull request is now in conflicts. Could you fix it @andfoy? 🙏

@takagi
Copy link
Member

takagi commented Apr 11, 2023

/test mini

@takagi takagi added this to the v13.0.0a1 milestone Apr 11, 2023
@mergify
Copy link
Contributor

mergify bot commented Apr 11, 2023

This pull request is now in conflicts. Could you fix it @andfoy? 🙏

@takagi
Copy link
Member

takagi commented Apr 13, 2023

/test mini

@takagi takagi enabled auto-merge April 13, 2023 04:34
@takagi takagi disabled auto-merge April 13, 2023 13:28
@takagi takagi merged commit d6252be into cupy:main Apr 13, 2023
4 checks passed
@takagi
Copy link
Member

takagi commented Apr 13, 2023

I merge this as the CI failures are not related. Thanks, @andfoy!

@andfoy andfoy deleted the add_symiirorder1 branch April 13, 2023 18:39
@andfoy
Copy link
Contributor Author

andfoy commented Apr 18, 2023

These are the benchmark results for symiirorder1 after PR #7522.

For larger input sizes, the GPU implementation achieves a ~3X improvement over SciPy.

Benchmark script
from itertools import product

import cupy as cp
import numpy as np
from cupy import testing
from cupyx.profiler import benchmark

from cupyx.scipy.signal import symiirorder1 as symiir1_gpu
from scipy.signal import symiirorder1 as symiir1_cpu

from tqdm import tqdm


input_sizes = [5, 10, 100, 1000, 5000, 10000, 50000, 100000, 200000, 500000,
               700000, 1_000_000, 2_000_000, 10_000_000]
modules = [(cp, symiir1_gpu, 'CuPy'), (np, symiir1_cpu, 'SciPy')]
# kwargs = [('order', [1, 2, 4, 6, 10])]
kwargs = [('precision', [1])]
# kwargs = [('extrapolate', [True])]
kwargs = list(product(*[list(product([x[0]], x[1])) for x in kwargs]))
measurement = {}


def gather_time(prof):
    cpu_time = prof.cpu_times.mean() * 1000
    gpu_time = prof.gpu_times.mean() * 1000
    return max(cpu_time, gpu_time)


def input_creation(xp, fn, size, precision=-1, **kwargs):
    size = size[0]
    x = testing.shaped_random((size,), xp, dtype=xp.float32)
    c0 = xp.asarray([2.0], dtype=xp.float32)
    z1 = xp.asarray([0.5], dtype=xp.float32)
    sig = (x, c0, z1, precision)
    return fn, sig


def closure(fn, sig):
    # try:
    return fn(*sig)
    # except ValueError:
    #     pass


for kwarg_comb in kwargs:
    kwarg_measurement = measurement.get(kwarg_comb, {})
    measurement[kwarg_comb] = kwarg_measurement
    kwarg_comb = dict(kwarg_comb)
    for size in tqdm(input_sizes):
        size_measurement = kwarg_measurement.get(size, {})
        kwarg_measurement[size] = size_measurement
        for xp, cls, _id in modules:
            b, x = input_creation(xp, cls, (size,), **kwarg_comb)
            prof = benchmark(closure, (b, x), n_repeat=100)
            size_measurement[_id] = gather_time(prof)


lines = []
for kwarg_comb in kwargs:
    kwarg_line = ', '.join([f'{x}={y}' for x, y in kwarg_comb])
    lines.append(f'### `{kwarg_line}`\n')
    lines.append('| Size | CuPy (ms) | SciPy (ms) | Speedup |')
    lines.append('|:----:|:---------:|:----------:|:-------:|')
    kwarg_measurement = measurement[kwarg_comb]
    for size in input_sizes:
        comp = f'{size}'
        size_measurement = kwarg_measurement[size]
        times = []
        for _, _, _id in modules:
            time = size_measurement[_id]
            times.append(time)
            time_info = f'{time:3f}'
            comp = f'{comp} | {time_info}'
        speedup = times[1] / times[0]
        comp = f'{comp} | {speedup:3f}'
        lines.append(f'| {comp} |')
    lines.append('\n')

print('\n'.join(lines))

precision=1

Size CuPy (ms) SciPy (ms) Speedup
5 2.344661 0.002708 0.001155
10 2.356515 0.002852 0.001210
100 2.360504 0.004143 0.001755
1000 2.421581 0.012302 0.005080
5000 2.387976 0.042065 0.017615
10000 2.418097 0.078274 0.032370
50000 2.394409 0.369082 0.154143
100000 2.417459 0.731418 0.302557
200000 2.501704 1.468732 0.587093
500000 2.781974 3.646715 1.310837
700000 2.806415 5.084350 1.811688
1000000 3.172863 7.267981 2.290670
2000000 5.308269 14.556299 2.742193
10000000 24.033003 85.798085 3.570011

@takagi
Copy link
Member

takagi commented Apr 18, 2023

Thanks, it's fine!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

2 participants