[Beignet] [PATCH] Accelerate utest.

Zhigang Gong zhigang.gong at intel.com
Tue Dec 10 22:52:41 PST 2013


For some test cases which include more than one kernel, the current
implementation always build the program for a new sub test case.

That wastes a lot of time. This patch introduce a new macro
MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM which has an extra parameter
to specify whether to keep the previous program and avoid the extra
build. The normal usage is:

MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(fn1, true);
MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(fn2, true);
MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(fn3, true);
MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(fn4, true);
MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(fn5, false);

The scenario is that the above fn1-5 are included in the same kernel
file and we define the sub cases in the same cpp file. We already
have some examples of this usage in the compiler_abs.cpp, compiler_abs_diff.cpp
compiler_basic_arithmetic.cpp, compiler_vector_load_store.cpp, etc.

This patch reduces 2/3 of the utests execution time.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 utests/compiler_abs.cpp               |    9 +++--
 utests/compiler_abs_diff.cpp          |   15 +++++----
 utests/compiler_basic_arithmetic.cpp  |   40 ++++++++++++----------
 utests/compiler_global_constant.cpp   |    6 ++--
 utests/compiler_group_size.cpp        |    6 ++--
 utests/compiler_long_cmp.cpp          |    5 +++
 utests/compiler_long_convert.cpp      |    4 +--
 utests/compiler_step.cpp              |   10 ++++--
 utests/compiler_vector_load_store.cpp |   36 ++++++++++----------
 utests/utest.cpp                      |    7 ++--
 utests/utest.hpp                      |    9 ++++-
 utests/utest_helper.cpp               |   59 ++++++++++++++++++---------------
 utests/utest_helper.hpp               |    7 +++-
 13 files changed, 126 insertions(+), 87 deletions(-)

diff --git a/utests/compiler_abs.cpp b/utests/compiler_abs.cpp
index 9457b9b..3f477a8 100644
--- a/utests/compiler_abs.cpp
+++ b/utests/compiler_abs.cpp
@@ -166,13 +166,16 @@ template <typename T, typename U> static void compiler_abs_with_type(void)
     }
 }
 
-#define ABS_TEST_TYPE(TYPE, UTYPE) \
+#define ABS_TEST_TYPE_1(TYPE, UTYPE, KEEP_PROGRAM) \
 	static void compiler_abs_##TYPE (void) \
         { \
            OCL_CALL (cl_kernel_init, "compiler_abs.cl", "compiler_abs_"#TYPE, SOURCE, NULL);  \
            compiler_abs_with_type<TYPE, UTYPE>(); \
         } \
-	MAKE_UTEST_FROM_FUNCTION(compiler_abs_##TYPE);
+	MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_abs_##TYPE, KEEP_PROGRAM);
+
+#define ABS_TEST_TYPE(TYPE, UTYPE) ABS_TEST_TYPE_1(TYPE, UTYPE, true)
+#define ABS_TEST_TYPE_END(TYPE, UTYPE) ABS_TEST_TYPE_1(TYPE, UTYPE, false)
 
 typedef unsigned char uchar;
 typedef unsigned short ushort;
@@ -248,4 +251,4 @@ ABS_TEST_TYPE(ushort2, ushort2)
 ABS_TEST_TYPE(ushort3, ushort3)
 ABS_TEST_TYPE(ushort4, ushort4)
 ABS_TEST_TYPE(ushort8, ushort8)
-ABS_TEST_TYPE(ushort16, ushort16)
+ABS_TEST_TYPE_END(ushort16, ushort16)
diff --git a/utests/compiler_abs_diff.cpp b/utests/compiler_abs_diff.cpp
index 71881b1..15a1f90 100644
--- a/utests/compiler_abs_diff.cpp
+++ b/utests/compiler_abs_diff.cpp
@@ -183,26 +183,29 @@ template <typename T, typename U> static void compiler_abs_diff_with_type(void)
 }
 
 
-#define ABS_TEST_DIFF_TYPE_2(TYPE, CLTYPE, UTYPE) \
+#define ABS_TEST_DIFF_TYPE_2(TYPE, CLTYPE, UTYPE, KEEP_PROGRAM) \
 	static void compiler_abs_diff_##CLTYPE (void) \
         { \
            OCL_CALL (cl_kernel_init, "compiler_abs_diff.cl", "compiler_abs_diff_"#CLTYPE, SOURCE, NULL);  \
            compiler_abs_diff_with_type<TYPE, UTYPE>(); \
         } \
-	MAKE_UTEST_FROM_FUNCTION(compiler_abs_diff_##CLTYPE);
+	MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_abs_diff_##CLTYPE, KEEP_PROGRAM);
+
+#define ABS_TEST_DIFF_TYPE(TYPE, UTYPE) ABS_TEST_DIFF_TYPE_2(TYPE, TYPE, UTYPE, true)
+
+#define ABS_TEST_DIFF_TYPE_END(TYPE, UTYPE) ABS_TEST_DIFF_TYPE_2(TYPE, TYPE, UTYPE, false)
 
-#define ABS_TEST_DIFF_TYPE(TYPE, UTYPE) ABS_TEST_DIFF_TYPE_2(TYPE, TYPE, UTYPE)
 
 typedef unsigned char uchar;
 typedef unsigned short ushort;
 typedef unsigned int uint;
 typedef uint64_t ulong64;
 ABS_TEST_DIFF_TYPE(int, uint)
-ABS_TEST_DIFF_TYPE_2(int64_t, long, ulong64)
+ABS_TEST_DIFF_TYPE_2(int64_t, long, ulong64, true)
 ABS_TEST_DIFF_TYPE(short, ushort)
 ABS_TEST_DIFF_TYPE(char, uchar)
 ABS_TEST_DIFF_TYPE(uint, uint)
-ABS_TEST_DIFF_TYPE_2(ulong64, ulong, ulong64)
+ABS_TEST_DIFF_TYPE_2(ulong64, ulong, ulong64, true)
 ABS_TEST_DIFF_TYPE(ushort, ushort)
 ABS_TEST_DIFF_TYPE(uchar, uchar)
 
@@ -289,4 +292,4 @@ ABS_TEST_DIFF_TYPE(ushort2, ushort2)
 ABS_TEST_DIFF_TYPE(ushort3, ushort3)
 ABS_TEST_DIFF_TYPE(ushort4, ushort4)
 ABS_TEST_DIFF_TYPE(ushort8, ushort8)
-ABS_TEST_DIFF_TYPE(ushort16, ushort16)
+ABS_TEST_DIFF_TYPE_END(ushort16, ushort16)
diff --git a/utests/compiler_basic_arithmetic.cpp b/utests/compiler_basic_arithmetic.cpp
index dcdd084..0e5ec41 100644
--- a/utests/compiler_basic_arithmetic.cpp
+++ b/utests/compiler_basic_arithmetic.cpp
@@ -61,52 +61,56 @@ std::cout <<"kernel name: " << kernel_name << std::endl;
   buf_data[0] = buf_data[1] = NULL;
 }
 
-#define DECL_TEST_SUB(type, alias) \
+#define DECL_TEST_SUB(type, alias, keep_program) \
 static void compiler_sub_ ##alias(void)\
 {\
   test_exec<type, TEST_OP_SUB>("compiler_sub_" # alias);\
 }\
-MAKE_UTEST_FROM_FUNCTION(compiler_sub_ ## alias)
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_sub_ ## alias, keep_program)
 
-#define DECL_TEST_ADD(type, alias) \
+#define DECL_TEST_ADD(type, alias, keep_program) \
 static void compiler_add_ ##alias(void)\
 {\
   test_exec<type, TEST_OP_ADD>("compiler_add_" # alias);\
 }\
-MAKE_UTEST_FROM_FUNCTION(compiler_add_ ## alias)
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_add_ ## alias, keep_program)
 
-#define DECL_TEST_MUL(type, alias) \
+#define DECL_TEST_MUL(type, alias, keep_program) \
 static void compiler_mul_ ##alias(void)\
 {\
   test_exec<type, TEST_OP_MUL>("compiler_mul_" # alias);\
 }\
-MAKE_UTEST_FROM_FUNCTION(compiler_mul_ ## alias)
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_mul_ ## alias, keep_program)
 
-#define DECL_TEST_DIV(type, alias) \
+#define DECL_TEST_DIV(type, alias, keep_program) \
 static void compiler_div_ ##alias(void)\
 {\
   test_exec<type, TEST_OP_DIV>("compiler_div_" # alias);\
 }\
-MAKE_UTEST_FROM_FUNCTION(compiler_div_ ## alias)
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_div_ ## alias, keep_program)
 
-#define DECL_TEST_REM(type, alias) \
+#define DECL_TEST_REM(type, alias, keep_program) \
 static void compiler_rem_ ##alias(void)\
 {\
   test_exec<type, TEST_OP_REM>("compiler_rem_" # alias);\
 }\
-MAKE_UTEST_FROM_FUNCTION(compiler_rem_ ## alias)
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_rem_ ## alias, keep_program)
 
-#define DECL_TEST_FOR_ALL_TYPE(op)\
-DECL_TEST_##op(int8_t, char) \
-DECL_TEST_##op(uint8_t, uchar) \
-DECL_TEST_##op(int16_t, short) \
-DECL_TEST_##op(uint16_t, ushort) \
-DECL_TEST_##op(int32_t, int) \
-DECL_TEST_##op(uint32_t, uint)
+#define _DECL_TEST_FOR_ALL_TYPE(op, keep_program) \
+DECL_TEST_##op(int8_t, char, true) \
+DECL_TEST_##op(uint8_t, uchar, true) \
+DECL_TEST_##op(int16_t, short, true) \
+DECL_TEST_##op(uint16_t, ushort, true) \
+DECL_TEST_##op(int32_t, int, true) \
+DECL_TEST_##op(uint32_t, uint, keep_program)
+
+#define DECL_TEST_FOR_ALL_TYPE(op) _DECL_TEST_FOR_ALL_TYPE(op, true)
+
+#define DECL_TEST_FOR_ALL_TYPE_END(op) _DECL_TEST_FOR_ALL_TYPE(op, false)
 
 DECL_TEST_FOR_ALL_TYPE(SUB)
 DECL_TEST_FOR_ALL_TYPE(ADD)
 DECL_TEST_FOR_ALL_TYPE(MUL)
 DECL_TEST_FOR_ALL_TYPE(DIV)
-DECL_TEST_FOR_ALL_TYPE(REM)
+DECL_TEST_FOR_ALL_TYPE_END(REM)
 #undef DECL_TEST_FOR_ALL_TYPE
diff --git a/utests/compiler_global_constant.cpp b/utests/compiler_global_constant.cpp
index a2d0172..88f9852 100644
--- a/utests/compiler_global_constant.cpp
+++ b/utests/compiler_global_constant.cpp
@@ -98,7 +98,7 @@ void compiler_global_constant3(void)
   OCL_UNMAP_BUFFER(0);
 }
 
-MAKE_UTEST_FROM_FUNCTION(compiler_global_constant);
-MAKE_UTEST_FROM_FUNCTION(compiler_global_constant1);
-MAKE_UTEST_FROM_FUNCTION(compiler_global_constant2);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_global_constant, true);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_global_constant1, true);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_global_constant2, true);
 MAKE_UTEST_FROM_FUNCTION(compiler_global_constant3);
diff --git a/utests/compiler_group_size.cpp b/utests/compiler_group_size.cpp
index 0c8881c..8ad83f0 100644
--- a/utests/compiler_group_size.cpp
+++ b/utests/compiler_group_size.cpp
@@ -134,8 +134,8 @@ void compiler_group_size4(void)
     OCL_UNMAP_BUFFER(1);
   }
 }
-MAKE_UTEST_FROM_FUNCTION(compiler_group_size1);
-MAKE_UTEST_FROM_FUNCTION(compiler_group_size2);
-MAKE_UTEST_FROM_FUNCTION(compiler_group_size3);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_group_size1, true);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_group_size2, true);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_group_size3, true);
 MAKE_UTEST_FROM_FUNCTION(compiler_group_size4);
 
diff --git a/utests/compiler_long_cmp.cpp b/utests/compiler_long_cmp.cpp
index 3775556..35d4c4f 100644
--- a/utests/compiler_long_cmp.cpp
+++ b/utests/compiler_long_cmp.cpp
@@ -47,6 +47,7 @@ void compiler_long_cmp(void)
     OCL_ASSERT(x == dest[i]);
   }
   OCL_UNMAP_BUFFER(2);
+  OCL_DESTROY_KERNEL_KEEP_PROGRAM(true);
 
   OCL_CREATE_KERNEL_FROM_FILE("compiler_long_cmp", "compiler_long_cmp_le");
   OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
@@ -60,6 +61,7 @@ void compiler_long_cmp(void)
     OCL_ASSERT(x == dest[i]);
   }
   OCL_UNMAP_BUFFER(2);
+  OCL_DESTROY_KERNEL_KEEP_PROGRAM(true);
 
   OCL_CREATE_KERNEL_FROM_FILE("compiler_long_cmp", "compiler_long_cmp_g");
   OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
@@ -73,6 +75,7 @@ void compiler_long_cmp(void)
     OCL_ASSERT(x == dest[i]);
   }
   OCL_UNMAP_BUFFER(2);
+  OCL_DESTROY_KERNEL_KEEP_PROGRAM(true);
 
   OCL_CREATE_KERNEL_FROM_FILE("compiler_long_cmp", "compiler_long_cmp_ge");
   OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
@@ -86,6 +89,7 @@ void compiler_long_cmp(void)
     OCL_ASSERT(x == dest[i]);
   }
   OCL_UNMAP_BUFFER(2);
+  OCL_DESTROY_KERNEL_KEEP_PROGRAM(true);
 
   OCL_CREATE_KERNEL_FROM_FILE("compiler_long_cmp", "compiler_long_cmp_eq");
   OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
@@ -99,6 +103,7 @@ void compiler_long_cmp(void)
     OCL_ASSERT(x == dest[i]);
   }
   OCL_UNMAP_BUFFER(2);
+  OCL_DESTROY_KERNEL_KEEP_PROGRAM(true);
 
   OCL_CREATE_KERNEL_FROM_FILE("compiler_long_cmp", "compiler_long_cmp_neq");
   OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
diff --git a/utests/compiler_long_convert.cpp b/utests/compiler_long_convert.cpp
index 827a45b..ada6926 100644
--- a/utests/compiler_long_convert.cpp
+++ b/utests/compiler_long_convert.cpp
@@ -65,7 +65,7 @@ void compiler_long_convert(void)
   OCL_UNMAP_BUFFER(5);
 }
 
-MAKE_UTEST_FROM_FUNCTION(compiler_long_convert);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_long_convert, true);
 
 // convert 64-bit integer to shorter integer
 void compiler_long_convert_2(void)
@@ -115,7 +115,7 @@ void compiler_long_convert_2(void)
   OCL_UNMAP_BUFFER(2);
 }
 
-MAKE_UTEST_FROM_FUNCTION(compiler_long_convert_2);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_long_convert_2, true);
 
 // convert 64-bit integer to 32-bit float
 void compiler_long_convert_to_float(void)
diff --git a/utests/compiler_step.cpp b/utests/compiler_step.cpp
index 3285dda..b022826 100644
--- a/utests/compiler_step.cpp
+++ b/utests/compiler_step.cpp
@@ -322,17 +322,21 @@ template <typename T> static void compiler_stepf_with_type(void)
     }
 }
 
-#define STEPF_TEST_TYPE(TYPE) \
+#define _STEPF_TEST_TYPE(TYPE, keep_program) \
 	static void compiler_stepf_##TYPE (void) \
         { \
            OCL_CALL (cl_kernel_init, "compiler_step.cl", "compiler_stepf_"#TYPE, SOURCE, NULL);  \
            compiler_stepf_with_type<TYPE>(); \
         } \
-	MAKE_UTEST_FROM_FUNCTION(compiler_stepf_##TYPE);
+	MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_stepf_##TYPE, keep_program);
+
+#define STEPF_TEST_TYPE(TYPE) _STEPF_TEST_TYPE(TYPE, true)
+#define STEPF_TEST_TYPE_END(TYPE) _STEPF_TEST_TYPE(TYPE, false)
+
 
 STEPF_TEST_TYPE(float)
 STEPF_TEST_TYPE(float2)
 STEPF_TEST_TYPE(float3)
 STEPF_TEST_TYPE(float4)
 STEPF_TEST_TYPE(float8)
-STEPF_TEST_TYPE(float16)
+STEPF_TEST_TYPE_END(float16)
diff --git a/utests/compiler_vector_load_store.cpp b/utests/compiler_vector_load_store.cpp
index f8a3dcb..b44abc7 100644
--- a/utests/compiler_vector_load_store.cpp
+++ b/utests/compiler_vector_load_store.cpp
@@ -37,27 +37,27 @@ static void compiler_vector_load_store(int elemNum, const char *kernelName)
   OCL_UNMAP_BUFFER(1);
 }
 
-#define compiler_vector_load_store(type, n, kernel_type) \
+#define compiler_vector_load_store(type, n, kernel_type, keep_program) \
 static void compiler_vector_ ##kernel_type ##n ##_load_store(void)\
 {\
   compiler_vector_load_store<type>(n, "test_" #kernel_type #n);\
 }\
-MAKE_UTEST_FROM_FUNCTION(compiler_vector_ ## kernel_type ##n ##_load_store);
+MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(compiler_vector_ ## kernel_type ##n ##_load_store, keep_program);
 
-#define test_all_vector(type, kernel_type) \
-  compiler_vector_load_store(type, 2, kernel_type) \
-  compiler_vector_load_store(type, 3, kernel_type) \
-  compiler_vector_load_store(type, 4, kernel_type) \
-  compiler_vector_load_store(type, 8, kernel_type) \
-  compiler_vector_load_store(type, 16, kernel_type)
+#define test_all_vector(type, kernel_type, keep_program) \
+  compiler_vector_load_store(type, 2, kernel_type, true) \
+  compiler_vector_load_store(type, 3, kernel_type, true) \
+  compiler_vector_load_store(type, 4, kernel_type, true) \
+  compiler_vector_load_store(type, 8, kernel_type, true) \
+  compiler_vector_load_store(type, 16, kernel_type, keep_program)
 
-test_all_vector(int8_t, char)
-test_all_vector(uint8_t, uchar)
-test_all_vector(int16_t, short)
-test_all_vector(uint16_t, ushort)
-test_all_vector(int32_t, int)
-test_all_vector(uint32_t, uint)
-test_all_vector(float, float)
-test_all_vector(double, double)
-test_all_vector(int64_t, long)
-test_all_vector(uint64_t, ulong)
+test_all_vector(int8_t, char, true)
+test_all_vector(uint8_t, uchar, true)
+test_all_vector(int16_t, short, true)
+test_all_vector(uint16_t, ushort, true)
+test_all_vector(int32_t, int, true)
+test_all_vector(uint32_t, uint, true)
+test_all_vector(float, float, true)
+test_all_vector(double, double, true)
+test_all_vector(int64_t, long, true)
+test_all_vector(uint64_t, ulong, false)
diff --git a/utests/utest.cpp b/utests/utest.cpp
index 18d10e8..88663cf 100644
--- a/utests/utest.cpp
+++ b/utests/utest.cpp
@@ -32,7 +32,8 @@ using namespace std;
 vector<UTest> *UTest::utestList = NULL;
 void releaseUTestList(void) { delete UTest::utestList; }
 
-UTest::UTest(Function fn, const char *name, bool haveIssue) : fn(fn), name(name), haveIssue(haveIssue) {
+UTest::UTest(Function fn, const char *name, bool haveIssue, bool needDestroyProgram)
+       : fn(fn), name(name), haveIssue(haveIssue), needDestroyProgram(needDestroyProgram) {
   if (utestList == NULL) {
     utestList = new vector<UTest>;
     atexit(releaseUTestList);
@@ -57,7 +58,7 @@ void UTest::run(const char *name) {
       std::cout << utest.name << ":" << std::endl;
       (utest.fn)();
       std::cout << std::endl;
-      cl_kernel_destroy();
+      cl_kernel_destroy(utest.needDestroyProgram);
       cl_buffer_destroy();
     }
   }
@@ -84,7 +85,7 @@ void UTest::runAllNoIssue(void) {
     std::cout << utest.name << ":" << std::endl;
     (utest.fn)();
     std::cout << std::endl;
-    cl_kernel_destroy();
+    cl_kernel_destroy(utest.needDestroyProgram);
     cl_buffer_destroy();
   }
 }
diff --git a/utests/utest.hpp b/utests/utest.hpp
index d3a6a6f..01d4a8c 100644
--- a/utests/utest.hpp
+++ b/utests/utest.hpp
@@ -39,13 +39,15 @@ struct UTest
   /*! Empty test */
   UTest(void);
   /*! Build a new unit test and append it to the unit test list */
-  UTest(Function fn, const char *name, bool haveIssue = false);
+  UTest(Function fn, const char *name, bool haveIssue = false, bool needDestroyProgram = true);
   /*! Function to execute */
   Function fn;
   /*! Name of the test */
   const char *name;
   /*! Indicate whether current test cases has issue to be fixes */
   bool haveIssue;
+  /*! Indicate whether destroy kernels/program. */
+  bool needDestroyProgram;
   /*! The tests that are registered */
   static std::vector<UTest> *utestList;
   /*! Run the test with the given name */
@@ -61,6 +63,11 @@ struct UTest
 /*! Register a new unit test */
 #define UTEST_REGISTER(FN) static const UTest __##FN##__(FN, #FN);
 
+#define MAKE_UTEST_FROM_FUNCTION_KEEP_PROGRAM(FN, KEEP_PROGRAM) \
+  static void __ANON__##FN##__(void) { UTEST_EXPECT_SUCCESS(FN()); } \
+  static const UTest __##FN##__(__ANON__##FN##__, #FN, false, !(KEEP_PROGRAM));
+
+
 /*! Turn a function into a unit test */
 #define MAKE_UTEST_FROM_FUNCTION(FN) \
   static void __ANON__##FN##__(void) { UTEST_EXPECT_SUCCESS(FN()); } \
diff --git a/utests/utest_helper.cpp b/utests/utest_helper.cpp
index 65af727..b264c1b 100644
--- a/utests/utest_helper.cpp
+++ b/utests/utest_helper.cpp
@@ -237,30 +237,32 @@ cl_kernel_init(const char *file_name, const char *kernel_name, int format, const
   cl_file_map_t *fm = NULL;
   char *ker_path = NULL;
   cl_int status = CL_SUCCESS;
+  static const char *prevFileName = NULL;
 
   /* Load the program and build it */
-  if (program)
-    clReleaseProgram(program);
-  ker_path = cl_do_kiss_path(file_name, device);
-  if (format == LLVM)
-    program = clCreateProgramWithLLVMIntel(ctx, 1, &device, ker_path, &status);
-  else if (format == SOURCE) {
-    cl_file_map_t *fm = cl_file_map_new();
-    FATAL_IF (cl_file_map_open(fm, ker_path) != CL_FILE_MAP_SUCCESS,
-              "Failed to open file \"%s\" with kernel \"%s\". Did you properly set OCL_KERNEL_PATH variable?",
-              file_name, kernel_name);
-    const char *src = cl_file_map_begin(fm);
-    const size_t sz = cl_file_map_size(fm);
-    program = clCreateProgramWithSource(ctx, 1, &src, &sz, &status);
-    cl_file_map_delete(fm);
-  } else
-    FATAL("Not able to create program from binary");
-
-  if (status != CL_SUCCESS) {
-    fprintf(stderr, "error calling clCreateProgramWithBinary\n");
-    goto error;
+  if (!program || (program && (!prevFileName || strcmp(prevFileName, file_name)))) {
+    if (program) clReleaseProgram(program);
+    ker_path = cl_do_kiss_path(file_name, device);
+    if (format == LLVM)
+      program = clCreateProgramWithLLVMIntel(ctx, 1, &device, ker_path, &status);
+    else if (format == SOURCE) {
+      cl_file_map_t *fm = cl_file_map_new();
+      FATAL_IF (cl_file_map_open(fm, ker_path) != CL_FILE_MAP_SUCCESS,
+                "Failed to open file \"%s\" with kernel \"%s\". Did you properly set OCL_KERNEL_PATH variable?",
+                file_name, kernel_name);
+      const char *src = cl_file_map_begin(fm);
+      const size_t sz = cl_file_map_size(fm);
+      program = clCreateProgramWithSource(ctx, 1, &src, &sz, &status);
+      cl_file_map_delete(fm);
+    } else
+      FATAL("Not able to create program from binary");
+
+    if (status != CL_SUCCESS) {
+      fprintf(stderr, "error calling clCreateProgramWithBinary\n");
+      goto error;
+    }
+    prevFileName = file_name;
   }
-
   /* OCL requires to build the program even if it is created from a binary */
   OCL_CALL (clBuildProgram, program, 1, &device, build_opt, NULL, NULL);
 
@@ -278,6 +280,7 @@ exit:
   cl_file_map_delete(fm);
   return status;
 error:
+  prevFileName = NULL;
   goto exit;
 }
 
@@ -413,12 +416,16 @@ error:
 }
 
 void
-cl_kernel_destroy(void)
+cl_kernel_destroy(bool needDestroyProgram)
 {
-  if (kernel) clReleaseKernel(kernel);
-  if (program) clReleaseProgram(program);
-  kernel = NULL;
-  program = NULL;
+  if (kernel) {
+    clReleaseKernel(kernel);
+    kernel = NULL;
+  }
+  if (needDestroyProgram && program) {
+    clReleaseProgram(program);
+    program = NULL;
+  }
 }
 
 void
diff --git a/utests/utest_helper.hpp b/utests/utest_helper.hpp
index 29a21d5..8da9dcb 100644
--- a/utests/utest_helper.hpp
+++ b/utests/utest_helper.hpp
@@ -65,6 +65,11 @@ extern EGLSurface  eglSurface;
     OCL_CALL (cl_kernel_init, NAME".cl", NAME, SOURCE, NULL); \
   } while (0)
 
+#define OCL_DESTROY_KERNEL_KEEP_PROGRAM(KEEP_PROGRAM) \
+  do { \
+    cl_kernel_destroy(!(KEEP_PROGRAM)); \
+  } while(0)
+
 #define OCL_CREATE_KERNEL_FROM_FILE(FILE_NAME, KERNEL_NAME) \
   do { \
     OCL_CALL(cl_kernel_init, FILE_NAME".cl", KERNEL_NAME, SOURCE, NULL); \
@@ -199,7 +204,7 @@ extern void cl_buffer_destroy(void);
 extern void cl_ocl_destroy(void);
 
 /* Release kernel and program */
-extern void cl_kernel_destroy(void);
+extern void cl_kernel_destroy(bool needDestroyProgram = true);
 
 /* Release everything allocated in cl_test_init */
 extern void cl_test_destroy(void);
-- 
1.7.9.5



More information about the Beignet mailing list