[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