diff --git a/pyopencl/tools.py b/pyopencl/tools.py
index c2842f60572046cde403693c56a5ad180a578c97..ea0d66dbdfda9cfd7858d085a5291a02e403afe6 100644
--- a/pyopencl/tools.py
+++ b/pyopencl/tools.py
@@ -37,7 +37,9 @@ import re
 
 from pyopencl.compyte.dtypes import (  # noqa
         get_or_register_dtype, TypeNameNotKnown,
-        register_dtype, dtype_to_ctype)
+        register_dtype, dtype_to_ctype,
+        dtype_hashable as _dtype_hashable,
+        dtype_to_key as _dtype_to_key)
 
 
 def _register_types():
@@ -507,8 +509,15 @@ class _CDeclList:
 
         return result
 
+if _dtype_hashable:
+    _memoize_match_dtype_to_c_struct = memoize
+else:
+    import json as _json
+    _memoize_match_dtype_to_c_struct = memoize(
+        key=lambda device, name, dtype, context=None:
+        (device, name, _dtype_to_key(dtype), context))
 
-@memoize
+@_memoize_match_dtype_to_c_struct
 def match_dtype_to_c_struct(device, name, dtype, context=None):
     """Return a tuple `(dtype, c_decl)` such that the C struct declaration
     in `c_decl` and the structure :class:`numpy.dtype` instance `dtype`
@@ -656,8 +665,14 @@ def match_dtype_to_c_struct(device, name, dtype, context=None):
 
     return dtype, c_decl
 
+if _dtype_hashable:
+    _memoize_dtype_to_c_struct = memoize
+else:
+    import json as _json
+    _memoize_dtype_to_c_struct = memoize(
+        key=lambda device, dtype: (device, _dtype_to_key(dtype)))
 
-@memoize
+@_memoize_dtype_to_c_struct
 def dtype_to_c_struct(device, dtype):
     matched_dtype, c_decl = match_dtype_to_c_struct(
             device, dtype_to_ctype(dtype), dtype)