Repository: kymatio/kymatio

Issue:
skcuda backend needs a NotImplementedError for 3d
Came up in discussion in #179
This issue is the short-term plan (0.1.0-alpha) whereas the actual implementation (#179) is tagged 0.2.0


Discussion:

Resolving patch:
diff --git a/kymatio/scattering3d/backend/__init__.py b/kymatio/scattering3d/backend/__init__.py
--- a/kymatio/scattering3d/backend/__init__.py
+++ b/kymatio/scattering3d/backend/__init__.py
@@ -62,8 +62,10 @@
 
 if BACKEND == 'torch':
     from .backend_torch import *
+elif BACKEND == 'skcuda':
+    from .backend_skcuda import *
 else:
-    # For now, raise and error
+    # For now, raise an error
     raise ValueError("Backend {} unknown".format(BACKEND))
 
 
diff --git a/kymatio/scattering3d/backend/backend_skcuda.py b/kymatio/scattering3d/backend/backend_skcuda.py
new file mode 100644
--- /dev/null
+++ b/kymatio/scattering3d/backend/backend_skcuda.py
@@ -0,0 +1,49 @@
+# The `skcuda` backend for Scattering3D is currently under development.
+# See issue #179.
+
+NAME = 'skcuda'
+
+
+skcuda_notimplementederror =\
+"""The \"skcuda\" backend for Scattering3D is currently under development.
+To perform 3D scattering, please set KYMATIO_BACKEND_3D=\"torch\"."""
+
+def to_complex(input):
+    raise NotImplementedError(skcuda_notimplementederror)
+
+
+def complex_modulus(input_array):
+    raise NotImplementedError(skcuda_notimplementederror)
+
+
+def fft(input, inverse=False):
+    """
+        fft of a 3d signal
+
+        Example
+        -------
+
+        Parameters
+        ----------
+        input : tensor
+            complex input for the FFT
+        inverse : bool
+            True for computing the inverse FFT.
+    """
+    raise NotImplementedError(skcuda_notimplementederror)
+
+
+def cdgmm3d(A, B):
+    """
+    Pointwise multiplication of complex tensors.
+
+    ----------
+    A: complex tensor
+    B: complex tensor of the same size as A
+
+    Returns
+    -------
+    output : tensor of the same size as A containing the result of the
+             elementwise complex multiplication of  A with B
+    """
+    raise NotImplementedError(skcuda_notimplementederror)
diff --git a/kymatio/scattering3d/scattering3d.py b/kymatio/scattering3d/scattering3d.py
--- a/kymatio/scattering3d/scattering3d.py
+++ b/kymatio/scattering3d/scattering3d.py
@@ -9,6 +9,9 @@
 from .backend import cdgmm3d, fft, complex_modulus, to_complex
 from .filter_bank import solid_harmonic_filter_bank, gaussian_filter_bank
 
+# TODO remove "import backend" below after implementing skcuda backend
+from kymatio.scattering3d import backend
+
 
 class Scattering3D(object):
     """3D Solid Harmonic scattering .
@@ -33,6 +36,8 @@ class Scattering3D(object):
 
     """
     def __init__(self, M, N, O, J, L, sigma_0):
+        if backend.NAME == "skcuda":
+            raise NotImplementedError(backend.skcuda_notimplementederror)
         super(Scattering3D, self).__init__()
         self.M = M
         self.N = N


Test patch:
diff --git a/kymatio/scattering3d/tests/test_scattering3d.py b/kymatio/scattering3d/tests/test_scattering3d.py
--- a/kymatio/scattering3d/tests/test_scattering3d.py
+++ b/kymatio/scattering3d/tests/test_scattering3d.py
@@ -1,6 +1,7 @@
 """ This script will test the submodules used by the scattering module"""
 import torch
 import os
+import warnings
 import numpy as np
 from kymatio import Scattering3D
 from kymatio.scattering3d import backend
@@ -26,6 +27,12 @@ def relative_difference(a, b):
 
 
 def test_FFT3d_central_freq_batch():
+    if backend.NAME == "skcuda":
+        warnings.warn(("The skcuda backend is not yet implemented for 3D "
+            "scattering, but that's ok (for now)."), RuntimeWarning,
+            stacklevel=2)
+        return
+
     # Checked the 0 frequency for the 3D FFT
     for device in devices:
         x = torch.zeros(1, 32, 32, 32, 2).float()
@@ -38,6 +45,12 @@ def test_FFT3d_central_freq_batch():
 
 
 def test_against_standard_computations():
+    if backend.NAME == "skcuda":
+        warnings.warn(("The skcuda backend is not yet implemented for 3D "
+            "scattering, but that's ok (for now)."), RuntimeWarning,
+            stacklevel=2)
+        return
+
     file_path = os.path.abspath(os.path.dirname(__file__))
     data = torch.load(os.path.join(file_path, 'test_data_3d.pt'))
     x = data['x']
@@ -89,6 +102,12 @@ def test_against_standard_computations():
         assert order_2_diff_cpu < 1e-6, "CPU : order 2 do not match, diff={}".format(order_2_diff_cpu)
 
 def test_solid_harmonic_scattering():
+    if backend.NAME == "skcuda":
+        warnings.warn(("The skcuda backend is not yet implemented for 3D "
+            "scattering, but that's ok (for now)."), RuntimeWarning,
+            stacklevel=2)
+        return
+
     # Compare value to analytical formula in the case of a single Gaussian
     centers = torch.FloatTensor(1, 1, 3).fill_(0)
     weights = torch.FloatTensor(1, 1).fill_(1)