[v3] add utests option: -j which specifies the 'number' of jobs (multi-thread)

Submitted by Meng, Mengmeng on Oct. 20, 2015, 2:15 a.m.

Details

Message ID 1445307308-13053-1-git-send-email-mengmeng.meng@intel.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Meng, Mengmeng Oct. 20, 2015, 2:15 a.m.
It's out-of-order execution in multi-tread which value range should be [1 - CPU cores].
---
 utests/utest.cpp        | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 utests/utest.hpp        |  4 ++++
 utests/utest_helper.cpp | 12 +++++-----
 utests/utest_helper.hpp | 12 +++++-----
 utests/utest_run.cpp    | 14 +++++++++++-
 5 files changed, 89 insertions(+), 13 deletions(-)

Patch hide | download patch | download mbox

diff --git a/utests/utest.cpp b/utests/utest.cpp
index 0a03d8b..3dc5afd 100644
--- a/utests/utest.cpp
+++ b/utests/utest.cpp
@@ -31,6 +31,12 @@ 
 #include <cstring>
 #include <stdlib.h>
 #include <csignal>
+#include <algorithm>
+#include <random>
+#include <chrono>
+#include <iterator>
+#include <semaphore.h>
+#include <unistd.h>
 
 struct signalMap
 {
@@ -39,7 +45,9 @@  struct signalMap
 };
 
 using namespace std;
+sem_t tag;
 vector<UTest> *UTest::utestList = NULL;
+vector<int> v;
 // Initialize and declare statistics struct
 RStatistics UTest::retStatistics;
 
@@ -105,6 +113,30 @@  void catch_signal(void){
       perror("Could not set signal handler");
   }
 }
+void *multithread(void * arg)
+{
+  int SerialNumber;
+  //size_t PhtreadNumber = (size_t)arg;
+
+  while(! v.empty()){
+    sem_wait(&tag);
+
+    SerialNumber = v.back();
+    v.pop_back();
+
+    sem_post(&tag);
+
+    const  UTest &utest = (*UTest::utestList)[SerialNumber];
+   // printf("thread%lu  %d, utests.name is %s\n",PhtreadNumber, SerialNumber,utest.name);
+
+    UTest::do_run(utest);
+    cl_kernel_destroy(true);
+    cl_buffer_destroy();
+  }
+
+  return 0;
+}
+
 
 UTest::UTest(Function fn, const char *name, bool isBenchMark, bool haveIssue, bool needDestroyProgram)
        : fn(fn), name(name), isBenchMark(isBenchMark), haveIssue(haveIssue), needDestroyProgram(needDestroyProgram) {
@@ -148,6 +180,34 @@  void UTest::run(const char *name) {
   }
 }
 
+void UTest::runMultiThread(const char *number) {
+  if (number == NULL) return;
+  if (utestList == NULL) return;
+
+  unsigned long i, num;
+  sem_init(&tag, 0, 1);
+
+  num = atoi(number);
+
+  unsigned long max_num = sysconf(_SC_NPROCESSORS_ONLN);
+
+  if(num < 1 || num > max_num){
+    printf("the value range of multi-thread is [1 - %lu]",max_num);
+    return;
+  }
+
+  for(i = 0; i < utestList->size(); ++i) v.push_back (i);
+  unsigned seed = chrono::system_clock::now ().time_since_epoch ().count ();
+  shuffle (v.begin (), v.end (), std::default_random_engine (seed));
+
+  pthread_t pthread_arry[num];
+
+  for(i=0; i<num;i++) pthread_create(&pthread_arry[i], NULL, multithread, (void *)i);
+  for(i=0; i<num;i++) pthread_join(pthread_arry[i], NULL);
+
+  sem_destroy(&tag);
+}
+
 void UTest::runAll(void) {
   if (utestList == NULL) return;
 
diff --git a/utests/utest.hpp b/utests/utest.hpp
index 7ae8b87..cda7545 100644
--- a/utests/utest.hpp
+++ b/utests/utest.hpp
@@ -54,6 +54,8 @@  struct UTest
   Function fn;
   /*! Name of the test */
   const char *name;
+  /*! numbers of the jobs */
+  const char *number;
   /*! whether it is a bench mark. */
   bool isBenchMark;
   /*! Indicate whether current test cases has issue to be fixes */
@@ -64,6 +66,8 @@  struct UTest
   static std::vector<UTest> *utestList;
   /*! Run the test with the given name */
   static void run(const char *name);
+  /*! Run the test with the given name */
+  static void runMultiThread(const char *number);
   /*! Run all the tests without known issue*/
   static void runAllNoIssue(void);
   /*! Run all the benchmark. */
diff --git a/utests/utest_helper.cpp b/utests/utest_helper.cpp
index 664046c..1ded379 100644
--- a/utests/utest_helper.cpp
+++ b/utests/utest_helper.cpp
@@ -46,13 +46,13 @@  do { \
 cl_platform_id platform = NULL;
 cl_device_id device = NULL;
 cl_context ctx = NULL;
-cl_program program = NULL;
-cl_kernel kernel = NULL;
+__thread cl_program program = NULL;
+__thread cl_kernel kernel = NULL;
 cl_command_queue queue = NULL;
-cl_mem buf[MAX_BUFFER_N] = {};
-void *buf_data[MAX_BUFFER_N] = {};
-size_t globals[3] = {};
-size_t locals[3] = {};
+__thread cl_mem buf[MAX_BUFFER_N] = {};
+__thread void *buf_data[MAX_BUFFER_N] = {};
+__thread size_t globals[3] = {};
+__thread size_t locals[3] = {};
 float ULPSIZE_FAST_MATH = 10000.;
 
 #ifdef HAS_EGL
diff --git a/utests/utest_helper.hpp b/utests/utest_helper.hpp
index e6c8515..2008bdd 100644
--- a/utests/utest_helper.hpp
+++ b/utests/utest_helper.hpp
@@ -158,13 +158,13 @@  enum { MAX_BUFFER_N = 16 };
 extern cl_platform_id platform;
 extern cl_device_id device;
 extern cl_context ctx;
-extern cl_program program;
-extern cl_kernel kernel;
+extern __thread cl_program program;
+extern __thread cl_kernel kernel;
 extern cl_command_queue queue;
-extern cl_mem buf[MAX_BUFFER_N];
-extern void* buf_data[MAX_BUFFER_N];
-extern size_t globals[3];
-extern size_t locals[3];
+extern __thread cl_mem buf[MAX_BUFFER_N];
+extern __thread void* buf_data[MAX_BUFFER_N];
+extern __thread size_t globals[3];
+extern __thread size_t locals[3];
 extern float ULPSIZE_FAST_MATH;
 
 enum {
diff --git a/utests/utest_run.cpp b/utests/utest_run.cpp
index 3cc1b6c..576d381 100644
--- a/utests/utest_run.cpp
+++ b/utests/utest_run.cpp
@@ -28,9 +28,10 @@ 
 #include <iostream>
 #include <getopt.h>
 
-static const char *shortopts = "c:lanh";
+static const char *shortopts = "c:j:lanh";
 struct option longopts[] = {
 {"casename", required_argument, NULL, 'c'},
+{"jobs", required_argument, NULL, 'j'},
 {"list", no_argument, NULL, 'l'},
 {"all", no_argument, NULL, 'a'},
 {"allnoissue", no_argument, NULL, 'n'},
@@ -46,6 +47,7 @@  Usage:\n\
 \n\
   option:\n\
     -c <casename>: run sub-case named 'casename'\n\
+    -j <number>  : specifies the 'number' of jobs (multi-thread)\n\
     -l           : list all the available case name\n\
     -a           : run all test cases\n\
     -n           : run all test cases without known issue (default option)\n\
@@ -85,6 +87,16 @@  int main(int argc, char *argv[])
 
         break;
 
+      case 'j':
+        try {
+          UTest::runMultiThread(optarg);
+        }
+        catch (Exception e){
+          std::cout << "  " << e.what() << "    [SUCCESS]" << std::endl;
+        }
+
+        break;
+
       case 'l':
         UTest::listAllCases();
         break;

Comments

LTGM, pushed, thanks.

BTW: the patch miss Signed-off info, I add it by manual this time, you'd better add it in future.

> -----Original Message-----

> From: Beignet [mailto:beignet-bounces@lists.freedesktop.org] On Behalf Of

> Meng Mengmeng

> Sent: Tuesday, October 20, 2015 10:15

> To: beignet@lists.freedesktop.org

> Cc: Meng, Mengmeng

> Subject: [Beignet] [PATCH v3] add utests option: -j which specifies the

> 'number' of jobs (multi-thread)

> 

> It's out-of-order execution in multi-tread which value range should be [1 -

> CPU cores].

> ---

>  utests/utest.cpp        | 60

> +++++++++++++++++++++++++++++++++++++++++++++++++

>  utests/utest.hpp        |  4 ++++

>  utests/utest_helper.cpp | 12 +++++-----  utests/utest_helper.hpp | 12

> +++++-----

>  utests/utest_run.cpp    | 14 +++++++++++-

>  5 files changed, 89 insertions(+), 13 deletions(-)

> 

> diff --git a/utests/utest.cpp b/utests/utest.cpp index 0a03d8b..3dc5afd

> 100644

> --- a/utests/utest.cpp

> +++ b/utests/utest.cpp

> @@ -31,6 +31,12 @@

>  #include <cstring>

>  #include <stdlib.h>

>  #include <csignal>

> +#include <algorithm>

> +#include <random>

> +#include <chrono>

> +#include <iterator>

> +#include <semaphore.h>

> +#include <unistd.h>

> 

>  struct signalMap

>  {

> @@ -39,7 +45,9 @@ struct signalMap

>  };

> 

>  using namespace std;

> +sem_t tag;

>  vector<UTest> *UTest::utestList = NULL;

> +vector<int> v;

>  // Initialize and declare statistics struct  RStatistics UTest::retStatistics;

> 

> @@ -105,6 +113,30 @@ void catch_signal(void){

>        perror("Could not set signal handler");

>    }

>  }

> +void *multithread(void * arg)

> +{

> +  int SerialNumber;

> +  //size_t PhtreadNumber = (size_t)arg;

> +

> +  while(! v.empty()){

> +    sem_wait(&tag);

> +

> +    SerialNumber = v.back();

> +    v.pop_back();

> +

> +    sem_post(&tag);

> +

> +    const  UTest &utest = (*UTest::utestList)[SerialNumber];

> +   // printf("thread%lu  %d, utests.name is %s\n",PhtreadNumber,

> + SerialNumber,utest.name);

> +

> +    UTest::do_run(utest);

> +    cl_kernel_destroy(true);

> +    cl_buffer_destroy();

> +  }

> +

> +  return 0;

> +}

> +

> 

>  UTest::UTest(Function fn, const char *name, bool isBenchMark, bool

> haveIssue, bool needDestroyProgram)

>         : fn(fn), name(name), isBenchMark(isBenchMark), haveIssue(haveIssue),

> needDestroyProgram(needDestroyProgram) { @@ -148,6 +180,34 @@ void

> UTest::run(const char *name) {

>    }

>  }

> 

> +void UTest::runMultiThread(const char *number) {

> +  if (number == NULL) return;

> +  if (utestList == NULL) return;

> +

> +  unsigned long i, num;

> +  sem_init(&tag, 0, 1);

> +

> +  num = atoi(number);

> +

> +  unsigned long max_num = sysconf(_SC_NPROCESSORS_ONLN);

> +

> +  if(num < 1 || num > max_num){

> +    printf("the value range of multi-thread is [1 - %lu]",max_num);

> +    return;

> +  }

> +

> +  for(i = 0; i < utestList->size(); ++i) v.push_back (i);  unsigned

> + seed = chrono::system_clock::now ().time_since_epoch ().count ();

> + shuffle (v.begin (), v.end (), std::default_random_engine (seed));

> +

> +  pthread_t pthread_arry[num];

> +

> +  for(i=0; i<num;i++) pthread_create(&pthread_arry[i], NULL,

> + multithread, (void *)i);  for(i=0; i<num;i++)

> + pthread_join(pthread_arry[i], NULL);

> +

> +  sem_destroy(&tag);

> +}

> +

>  void UTest::runAll(void) {

>    if (utestList == NULL) return;

> 

> diff --git a/utests/utest.hpp b/utests/utest.hpp index 7ae8b87..cda7545

> 100644

> --- a/utests/utest.hpp

> +++ b/utests/utest.hpp

> @@ -54,6 +54,8 @@ struct UTest

>    Function fn;

>    /*! Name of the test */

>    const char *name;

> +  /*! numbers of the jobs */

> +  const char *number;

>    /*! whether it is a bench mark. */

>    bool isBenchMark;

>    /*! Indicate whether current test cases has issue to be fixes */ @@ -64,6

> +66,8 @@ struct UTest

>    static std::vector<UTest> *utestList;

>    /*! Run the test with the given name */

>    static void run(const char *name);

> +  /*! Run the test with the given name */  static void

> + runMultiThread(const char *number);

>    /*! Run all the tests without known issue*/

>    static void runAllNoIssue(void);

>    /*! Run all the benchmark. */

> diff --git a/utests/utest_helper.cpp b/utests/utest_helper.cpp index

> 664046c..1ded379 100644

> --- a/utests/utest_helper.cpp

> +++ b/utests/utest_helper.cpp

> @@ -46,13 +46,13 @@ do { \

>  cl_platform_id platform = NULL;

>  cl_device_id device = NULL;

>  cl_context ctx = NULL;

> -cl_program program = NULL;

> -cl_kernel kernel = NULL;

> +__thread cl_program program = NULL;

> +__thread cl_kernel kernel = NULL;

>  cl_command_queue queue = NULL;

> -cl_mem buf[MAX_BUFFER_N] = {};

> -void *buf_data[MAX_BUFFER_N] = {};

> -size_t globals[3] = {};

> -size_t locals[3] = {};

> +__thread cl_mem buf[MAX_BUFFER_N] = {}; __thread void

> +*buf_data[MAX_BUFFER_N] = {}; __thread size_t globals[3] = {}; __thread

> +size_t locals[3] = {};

>  float ULPSIZE_FAST_MATH = 10000.;

> 

>  #ifdef HAS_EGL

> diff --git a/utests/utest_helper.hpp b/utests/utest_helper.hpp index

> e6c8515..2008bdd 100644

> --- a/utests/utest_helper.hpp

> +++ b/utests/utest_helper.hpp

> @@ -158,13 +158,13 @@ enum { MAX_BUFFER_N = 16 };  extern

> cl_platform_id platform;  extern cl_device_id device;  extern cl_context ctx; -

> extern cl_program program; -extern cl_kernel kernel;

> +extern __thread cl_program program;

> +extern __thread cl_kernel kernel;

>  extern cl_command_queue queue;

> -extern cl_mem buf[MAX_BUFFER_N];

> -extern void* buf_data[MAX_BUFFER_N];

> -extern size_t globals[3];

> -extern size_t locals[3];

> +extern __thread cl_mem buf[MAX_BUFFER_N]; extern __thread void*

> +buf_data[MAX_BUFFER_N]; extern __thread size_t globals[3]; extern

> +__thread size_t locals[3];

>  extern float ULPSIZE_FAST_MATH;

> 

>  enum {

> diff --git a/utests/utest_run.cpp b/utests/utest_run.cpp index

> 3cc1b6c..576d381 100644

> --- a/utests/utest_run.cpp

> +++ b/utests/utest_run.cpp

> @@ -28,9 +28,10 @@

>  #include <iostream>

>  #include <getopt.h>

> 

> -static const char *shortopts = "c:lanh";

> +static const char *shortopts = "c:j:lanh";

>  struct option longopts[] = {

>  {"casename", required_argument, NULL, 'c'},

> +{"jobs", required_argument, NULL, 'j'},

>  {"list", no_argument, NULL, 'l'},

>  {"all", no_argument, NULL, 'a'},

>  {"allnoissue", no_argument, NULL, 'n'}, @@ -46,6 +47,7 @@ Usage:\n\  \n\

>    option:\n\

>      -c <casename>: run sub-case named 'casename'\n\

> +    -j <number>  : specifies the 'number' of jobs (multi-thread)\n\

>      -l           : list all the available case name\n\

>      -a           : run all test cases\n\

>      -n           : run all test cases without known issue (default option)\n\

> @@ -85,6 +87,16 @@ int main(int argc, char *argv[])

> 

>          break;

> 

> +      case 'j':

> +        try {

> +          UTest::runMultiThread(optarg);

> +        }

> +        catch (Exception e){

> +          std::cout << "  " << e.what() << "    [SUCCESS]" << std::endl;

> +        }

> +

> +        break;

> +

>        case 'l':

>          UTest::listAllCases();

>          break;

> --

> 1.9.1

> 

> _______________________________________________

> Beignet mailing list

> Beignet@lists.freedesktop.org

> http://lists.freedesktop.org/mailman/listinfo/beignet