From 0cd7e0ca9480666078c750dff8febddc96fb72b7 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Sun, 16 Oct 2011 12:09:26 -0400
Subject: [PATCH] Emit better comments on why there are many warnings on a
 from-cache build on Intel.

---
 pyopencl/__init__.py           | 16 +++++++++++++---
 pyopencl/cache.py              |  5 +++--
 src/wrapper/wrap_cl.hpp        | 17 +++++++++++++----
 src/wrapper/wrap_cl_part_2.cpp |  7 +++++++
 4 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py
index f60f95fd..9bb014c2 100644
--- a/pyopencl/__init__.py
+++ b/pyopencl/__init__.py
@@ -141,18 +141,28 @@ def _add_functionality():
                         routine=lambda : routine))
 
         if err is not None:
-            # Python 3.2 outputs the whole tree of currently active exceptions
+            # Python 3.2 outputs the whole list of currently active exceptions
             # This serves to remove one (redundant) level from that nesting.
             raise err
 
         message = (75*"="+"\n").join(
-                "Build on %s succeeded, but said:\n\n%s" % (dev, log) 
+                "Build on %s succeeded, but said:\n\n%s" % (dev, log)
                 for dev, log in self._get_build_logs()
                 if log is not None and log.strip())
 
         if message:
+            if self.kind() == program_kind.UNKNOWN:
+                build_type = "Build"
+            elif self.kind() == program_kind.SOURCE:
+                build_type = "From-source build"
+            elif self.kind() == program_kind.BINARY:
+                build_type = "From-binary build"
+            else:
+                raise RuntimeError("unexpected kind of program")
+
             from warnings import warn
-            warn("Build succeeded, but resulted in non-empty logs:\n"+message)
+            warn("%s succeeded, but resulted in non-empty logs:\n%s"
+                    % (build_type, message))
 
         return self
 
diff --git a/pyopencl/cache.py b/pyopencl/cache.py
index 7719c3a8..f0f3988b 100644
--- a/pyopencl/cache.py
+++ b/pyopencl/cache.py
@@ -344,13 +344,14 @@ def _create_built_program_from_source_cached(ctx, src, options, devices, cache_d
             logs.append(log)
 
     message = (75*"="+"\n").join(
-            "Build on %s succeeded, but said:\n\n%s" % (dev, log) 
+            "Build on %s succeeded, but said:\n\n%s" % (dev, log)
             for dev, log in zip(devices, logs)
             if log is not None and log.strip())
 
     if message:
         from warnings import warn
-        warn("Build succeeded, but resulted in non-empty logs:\n"+message)
+        warn("Built kernel retrieved from cache. Original from-source build had warnings:\n"+message)
+
     # {{{ build on the build-needing devices, in one go
 
     result = None
diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp
index fd1f947b..78946cb8 100644
--- a/src/wrapper/wrap_cl.hpp
+++ b/src/wrapper/wrap_cl.hpp
@@ -2392,12 +2392,16 @@ namespace pyopencl
 
   class program : boost::noncopyable
   {
+    public:
+      enum program_kind_type { KND_UNKNOWN, KND_SOURCE, KND_BINARY };
+
     private:
       cl_program m_program;
+      program_kind_type m_program_kind;
 
     public:
-      program(cl_program prog, bool retain)
-        : m_program(prog)
+      program(cl_program prog, bool retain, program_kind_type progkind=KND_UNKNOWN)
+        : m_program(prog), m_program_kind(progkind)
       {
         if (retain)
           PYOPENCL_CALL_GUARDED(clRetainProgram, (prog));
@@ -2413,6 +2417,11 @@ namespace pyopencl
         return m_program;
       }
 
+      program_kind_type kind() const
+      {
+        return m_program_kind;
+      }
+
       npy_intp obj_ptr() const
       {
         return (npy_intp) data();
@@ -2560,7 +2569,7 @@ namespace pyopencl
 
     try
     {
-      return new program(result, false);
+      return new program(result, false, program::KND_SOURCE);
     }
     catch (...)
     {
@@ -2625,7 +2634,7 @@ namespace pyopencl
 
     try
     {
-      return new program(result, false);
+      return new program(result, false, program::KND_BINARY);
     }
     catch (...)
     {
diff --git a/src/wrapper/wrap_cl_part_2.cpp b/src/wrapper/wrap_cl_part_2.cpp
index 210f9510..c053e3df 100644
--- a/src/wrapper/wrap_cl_part_2.cpp
+++ b/src/wrapper/wrap_cl_part_2.cpp
@@ -118,6 +118,12 @@ void pyopencl_expose_part_2()
   // {{{ program
   {
     typedef program cls;
+    py::enum_<cls::program_kind_type>("program_kind")
+      .value("UNKNOWN", cls::KND_UNKNOWN)
+      .value("SOURCE", cls::KND_SOURCE)
+      .value("BINARY", cls::KND_BINARY)
+      ;
+
     py::class_<cls, boost::noncopyable>("_Program", py::no_init)
       .def("__init__", make_constructor(
             create_program_with_source,
@@ -127,6 +133,7 @@ void pyopencl_expose_part_2()
             create_program_with_binary,
             py::default_call_policies(),
             py::args("context", "devices", "binaries")))
+      .DEF_SIMPLE_METHOD(kind)
       .DEF_SIMPLE_METHOD(get_info)
       .DEF_SIMPLE_METHOD(get_build_info)
       .def("_build", &cls::build,
-- 
GitLab