diff --git a/arraycontext/fake_numpy.py b/arraycontext/fake_numpy.py
index 0ca72bd93710364b577c455d6a0de6d14f8ac33e..a117fafff0d015d937e50459407909e8246671bb 100644
--- a/arraycontext/fake_numpy.py
+++ b/arraycontext/fake_numpy.py
@@ -182,6 +182,31 @@ class BaseFakeNumpyLinalgNamespace:
         if ord is None:
             ord = 2
 
+        from arraycontext.impl import _is_meshmode_dofarray, _is_pyopencl_array
+
+        if _is_pyopencl_array(ary):
+            if ary.ndim != 1:
+                from arraycontext.impl import _flatten_cl_array
+                # mimics numpy's norm computation
+                return self.norm(_flatten_cl_array(ary), ord=2)
+
+        if _is_meshmode_dofarray(ary):
+            from arraycontext.impl import _flatten_cl_array
+
+            from warnings import warn
+            warn("Taking an actx.np.linalg.norm of a DOFArray is deprecated. "
+                    "(DOFArrays use 2D arrays internally, and "
+                    "actx.np.linalg.norm should compute matrix norms of those.) "
+                    "This will stop working in 2022. "
+                    "Use meshmode.dof_array.flat_norm instead.",
+                    DeprecationWarning, stacklevel=2)
+
+            import numpy.linalg as la
+            return la.norm(
+                    [self.norm(_flatten_cl_array(subary), ord=ord)
+                        for _, subary in serialize_container(ary)],
+                    ord=ord)
+
         if is_array_container(ary):
             if ord == np.inf:
                 return max([self.norm(subary, ord=ord)
diff --git a/arraycontext/impl/__init__.py b/arraycontext/impl/__init__.py
index 6df8258599acbee87f9b031e86ae365dbb532cbb..093caeee3247d5d8e93fe1df3854de869718865e 100644
--- a/arraycontext/impl/__init__.py
+++ b/arraycontext/impl/__init__.py
@@ -1,3 +1,7 @@
+"""Various (undocumented) helper functions to avoid creating dependencies
+on other packages (such as pyopencl or meshmode).
+"""
+
 __copyright__ = """
 Copyright (C) 2020-1 University of Illinois Board of Trustees
 """
@@ -22,11 +26,39 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 """
 
+from typing import Any
 
-def _is_meshmode_dofarray(x):
+
+def _is_meshmode_dofarray(x: Any) -> bool:
     try:
         from meshmode.dof_array import DOFArray
     except ImportError:
         return False
     else:
         return isinstance(x, DOFArray)
+
+
+def _is_pyopencl_array(x: Any) -> bool:
+    try:
+        import pyopencl.array as cla
+    except ImportError:
+        return False
+    else:
+        return isinstance(x, cla.Array)
+
+
+def _flatten_cl_array(ary):
+    import pyopencl.array as cl
+    assert isinstance(ary, cl.Array)
+
+    if ary.size == 0:
+        # Work around https://github.com/inducer/pyopencl/pull/402
+        return ary._new_with_changes(
+                data=None, offset=0, shape=(0,), strides=(ary.dtype.itemsize,))
+    if ary.flags.f_contiguous:
+        return ary.reshape(-1, order="F")
+    elif ary.flags.c_contiguous:
+        return ary.reshape(-1, order="C")
+    else:
+        raise ValueError("cannot flatten array "
+                f"with strides {ary.strides} of {ary.dtype}")
diff --git a/arraycontext/impl/pyopencl.py b/arraycontext/impl/pyopencl.py
index 67374ca11ad66ca69cddcd2fc9b56447369a77e7..cf432eb0b72087cc089bf665d0c03dfb5a2925d7 100644
--- a/arraycontext/impl/pyopencl.py
+++ b/arraycontext/impl/pyopencl.py
@@ -40,7 +40,6 @@ from arraycontext.fake_numpy import \
         BaseFakeNumpyNamespace, BaseFakeNumpyLinalgNamespace
 from arraycontext.container.traversal import (rec_multimap_array_container,
                                               rec_map_array_container)
-from arraycontext.container import serialize_container
 from arraycontext.context import ArrayContext
 
 
@@ -169,62 +168,8 @@ class PyOpenCLFakeNumpyNamespace(BaseFakeNumpyNamespace):
 
 # {{{ fake np.linalg
 
-def _flatten_array(ary):
-    import pyopencl.array as cl
-    assert isinstance(ary, cl.Array)
-
-    if ary.size == 0:
-        # Work around https://github.com/inducer/pyopencl/pull/402
-        return ary._new_with_changes(
-                data=None, offset=0, shape=(0,), strides=(ary.dtype.itemsize,))
-    if ary.flags.f_contiguous:
-        return ary.reshape(-1, order="F")
-    elif ary.flags.c_contiguous:
-        return ary.reshape(-1, order="C")
-    else:
-        raise ValueError("cannot flatten array "
-                f"with strides {ary.strides} of {ary.dtype}")
-
-
 class _PyOpenCLFakeNumpyLinalgNamespace(BaseFakeNumpyLinalgNamespace):
-    def norm(self, ary, ord=None):
-        from numbers import Number
-        import pyopencl.array as cla
-
-        if isinstance(ary, Number):
-            return abs(ary)
-
-        if ord is None and isinstance(ary, cla.Array):
-            if ary.ndim == 1:
-                ord = 2
-            else:
-                # mimics numpy's norm computation
-                return self.norm(_flatten_array(ary), ord=2)
-
-        try:
-            from meshmode.dof_array import DOFArray
-        except ImportError:
-            pass
-        else:
-            if isinstance(ary, DOFArray):
-                if ord is None:
-                    ord = 2
-
-                from warnings import warn
-                warn("Taking an actx.np.linalg.norm of a DOFArray is deprecated. "
-                        "(DOFArrays use 2D arrays internally, and "
-                        "actx.np.linalg.norm should compute matrix norms of those.) "
-                        "This will stop working in 2022. "
-                        "Use meshmode.dof_array.flat_norm instead.",
-                        DeprecationWarning, stacklevel=2)
-
-                import numpy.linalg as la
-                return la.norm(
-                        [self.norm(_flatten_array(subary), ord=ord)
-                            for _, subary in serialize_container(ary)],
-                        ord=ord)
-
-        return super().norm(ary, ord)
+    pass
 
 # }}}