diff --git a/doc/source/runtime.rst b/doc/source/runtime.rst
index 7bcd56285aee2c8f105f15bbde1d5952eb1a22c5..df7649846457d0f78738a7ee9b0e31a6d8ec8077 100644
--- a/doc/source/runtime.rst
+++ b/doc/source/runtime.rst
@@ -55,8 +55,10 @@ Constants
 Platforms, Devices and Contexts
 -------------------------------
 
-.. |comparable| replace:: Two instances of this class may be compared
-    using *"=="* and *"!="*.
+.. |comparable| replace:: Instances of this class are hashable, and two
+    instances of this class may be compared using *"=="* and *"!="*.
+    (Hashability was added in version 2011.2.)
+
 .. |buf-iface| replace:: must implement the Python buffer interface.
     (e.g. by being an :class:`numpy.ndarray`)
 .. |explain-waitfor| replace:: *wait_for*
diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp
index 0b0d0daca420f97501aa71a82f716e1bff4c3981..1a94c850dca1ae5bd97f446a97da45369da2cd66 100644
--- a/src/wrapper/wrap_cl.hpp
+++ b/src/wrapper/wrap_cl.hpp
@@ -239,8 +239,9 @@
     bool operator==(cls const &other) const \
     { return data() == other.data(); } \
     bool operator!=(cls const &other) const \
-    { return data() != other.data(); }
-
+    { return data() != other.data(); } \
+    long hash() const \
+    { return (long) (intptr_t) data(); }
 // }}}
 
 
diff --git a/src/wrapper/wrap_cl_part_1.cpp b/src/wrapper/wrap_cl_part_1.cpp
index 6e83c951dd1707b2dd4773e96e53b23f1ef07d5b..08f71f560570753fe440f4585d2162e504d9275c 100644
--- a/src/wrapper/wrap_cl_part_1.cpp
+++ b/src/wrapper/wrap_cl_part_1.cpp
@@ -24,6 +24,7 @@ void pyopencl_expose_part_1()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       ;
   }
 
@@ -37,6 +38,7 @@ void pyopencl_expose_part_1()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
 #if defined(cl_ext_device_fission) && defined(PYOPENCL_USE_DEVICE_FISSION)
       .DEF_SIMPLE_METHOD(create_sub_devices)
 #endif
@@ -61,6 +63,7 @@ void pyopencl_expose_part_1()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       ;
   }
 
@@ -82,6 +85,7 @@ void pyopencl_expose_part_1()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       ;
   }
 
@@ -96,6 +100,7 @@ void pyopencl_expose_part_1()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       ;
   }
 
@@ -129,6 +134,7 @@ void pyopencl_expose_part_1()
           (py::arg("shape"), py::arg("dtype"), py::arg("order")="C"))
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       ;
   }
   {
diff --git a/src/wrapper/wrap_cl_part_2.cpp b/src/wrapper/wrap_cl_part_2.cpp
index 95f298830f94afb15e11f5a5c5ade3494f1ca86d..210f9510de2b4167c6c5b7336e4ccb6f33225451 100644
--- a/src/wrapper/wrap_cl_part_2.cpp
+++ b/src/wrapper/wrap_cl_part_2.cpp
@@ -109,6 +109,7 @@ void pyopencl_expose_part_2()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       ;
   }
 
@@ -133,6 +134,7 @@ void pyopencl_expose_part_2()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       .def("all_kernels", create_kernels_in_program)
       ;
   }
@@ -149,6 +151,7 @@ void pyopencl_expose_part_2()
       .add_property("obj_ptr", &cls::obj_ptr)
       .def(py::self == py::self)
       .def(py::self != py::self)
+      .def("__hash__", &cls::hash)
       ;
   }