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

Yang, Rong R rong.r.yang at intel.com
Sun Oct 18 22:35:42 PDT 2015


__thread is gcc feature, don't other compilers(clang and icc) support it? Or can you use thread_local? It is C++11 feature.

> -----Original Message-----
> From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of
> Meng Mengmeng
> Sent: Monday, October 19, 2015 11:20
> To: beignet at lists.freedesktop.org
> Cc: Meng, Mengmeng
> Subject: [Beignet] [PATCH v2] add utests option: -j which specifies the
> 'number' of jobs (multi-thread)
> 
> The multi-tread number should be [1 - CPU cores], then out-of-order
> execution for all utests lists.
> ---
>  utests/utest.cpp        | 60
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  utests/utest.hpp        |  4 ++++
>  utests/utest_helper.cpp |  8 +++----
>  utests/utest_helper.hpp |  8 +++----
>  utests/utest_run.cpp    | 14 +++++++++++-
>  5 files changed, 85 insertions(+), 9 deletions(-)
> 
> diff --git a/utests/utest.cpp b/utests/utest.cpp index 0a03d8b..806ba91
> 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);
> +
> +  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..4dcc6bb 100644
> --- a/utests/utest_helper.cpp
> +++ b/utests/utest_helper.cpp
> @@ -46,11 +46,11 @@ 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] = {};
> +__thread cl_mem buf[MAX_BUFFER_N] = {}; __thread void
> +*buf_data[MAX_BUFFER_N] = {};
>  size_t globals[3] = {};
>  size_t locals[3] = {};
>  float ULPSIZE_FAST_MATH = 10000.;
> diff --git a/utests/utest_helper.hpp b/utests/utest_helper.hpp index
> e6c8515..67dc98a 100644
> --- a/utests/utest_helper.hpp
> +++ b/utests/utest_helper.hpp
> @@ -158,11 +158,11 @@ 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 __thread cl_mem buf[MAX_BUFFER_N]; extern __thread void*
> +buf_data[MAX_BUFFER_N];
>  extern size_t globals[3];
>  extern size_t locals[3];
>  extern float ULPSIZE_FAST_MATH;
> 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list