Skip to content

Python simple cuda #685

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

MaximEremenko
Copy link

This pull request introduces a simplified Python interface for Type 3 NUFFTs (nonuniform-to-nonuniform) in 1D, 2D, and 3D within the cufinufft library. The new functions—nufft1d3, nufft2d3, and nufft3d3—allow users to perform Type 3 transforms with minimal setup, similar to the existing Type 1 and Type 2 interfaces.
Changes

  • Added nufft1d3, nufft2d3, and nufft3d3 to cufinufft/_simple.py, providing user-friendly access to Type 3 NUFFTs.
  • Updated cufinufft/init.py to include the new functions in the module’s public API.
  • Modified _invoke_plan to correctly handle Type 3 parameters (s, t, u) and plan creation for Type 3 transforms.

With this update, all NUFFT types (1, 2, and 3) now offer a consistent and simplified Python interface.

@DiamonDinoia DiamonDinoia requested a review from janden May 24, 2025 20:16
@DiamonDinoia
Copy link
Collaborator

This looks great.

I would ask @janden to review.

My suggestion it to extend https://github.com/flatironinstitute/finufft/blob/master/python/cufinufft/tests/test_simple.py with type3

@DiamonDinoia
Copy link
Collaborator

Hi @MaximEremenko,

I noticed the tests failing do you need help with it?

@MaximEremenko
Copy link
Author

MaximEremenko commented May 28, 2025

Hi @DiamonDinoia ,
I have version that can pass tests. Problem is here:
in function: verify_type3

ind = (int(0.1789 * n_target_pts),) and assert type3_rel_err < 100 * tol

Original CPU code looks a little different.

I made verify_type3 to ind = tuple(n-1 for n in n_tr + (int(0.1789 *n_pts),)) and it works but it looks like GPU version gives bigger error compare to CPU and general test case tuple(np.random.randint(0, n) for n in n_tr + (n_pts,)) does not work correctly.

@ahbarnett
Copy link
Collaborator

ahbarnett commented May 28, 2025 via email

@DiamonDinoia
Copy link
Collaborator

Hi @MaximEremenko,

Yes, let's leave something sensible that passes here.
@janden might want to change the tests to align to C++/matlab in a different PR.

@DiamonDinoia DiamonDinoia added this to the 2.5 milestone May 29, 2025
Copy link
Collaborator

@janden janden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together!

Some things to discuss here.

@@ -32,10 +41,13 @@ def _invoke_plan(dim, nufft_type, x, y, z, data, out, isign, eps,
n_modes = out.shape[-dim:]
if nufft_type == 2:
n_modes = data.shape[-dim:]

if nufft_type == 3:
plan = Plan(nufft_type, dim, n_trans = n_trans, eps=eps, isign=isign, dtype=dtype, **kwargs)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to specify the kwargs explicitly here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

**kwargs are defined the same way as for nufft_type 1 and 2, matching the invoke_guru CPU implementation:
if tp == 3:
plan = Plan(tp, dim, n_trans, eps, isign, pdtype, **kwargs)
else:
plan = Plan(tp, n_modes, n_trans, eps, isign, pdtype, **kwargs)
Explicit specification of parameters (e.g., n_trans=n_trans, eps=eps, isign=isign, dtype=dtype) is optional. I can modify it if necessary

@@ -332,7 +332,7 @@ def execute(self, data, out=None):

_data, data_shape = _ensure_array_shape(_data, "data", req_data_shape,
allow_reshape=True)
if self._type == 1:
if self._type in [1, 3]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

@@ -46,7 +58,7 @@ def _invoke_plan(dim, nufft_type, x, y, z, data, out, isign, eps,


def _get_ntrans(dim, nufft_type, data):
if nufft_type == 1:
if ((nufft_type == 1) | (nufft_type == 3)):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be preferable here to have if nufft_type == 1 or nufft_type == 3: or if nufft_type in [1, 3]: (see above). The | operator is a bitwise or.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to if nufft_type in [1, 3]. Thanks


target_coefs = to_cpu(target_coefs_gpu)

utils.verify_type3(source_pts, source_coefs, target_pts, target_coefs, tol)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline.

@@ -22,6 +22,9 @@ def _real_dtype(complex_dtype):

return real_dtype

def gen_coef_ind(n_pts, n_tr):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand why this is needed here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistent implementation with "def gen_coef_ind(n_pts, n_tr)" from python/finufft/tests/utils.py

@janden
Copy link
Collaborator

janden commented Jun 10, 2025

@janden might want to change the tests to align to C++/matlab in a different PR.

Agreed. Will make an issue.

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

Successfully merging this pull request may close these issues.

4 participants