File: vector.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (126 lines) | stat: -rw-r--r-- 5,396 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * Copyright (c) 2014 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Code that's reused in vector tests.
 */

#ifndef _NATIVE_CLIENT_TESTS_SIMD_VECTOR_H
#define _NATIVE_CLIENT_TESTS_SIMD_VECTOR_H 1

#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <limits>
#include <pthread.h>
#include <random>
#include <type_traits>

#define CHECK(EXPR)                                                      \
  do {                                                                   \
    if (!(EXPR)) {                                                       \
      std::cerr << #EXPR " returned false at line " << __LINE__ << '\n'; \
      exit(1);                                                           \
    }                                                                    \
  } while (0)

#define NOINLINE __attribute__((noinline))

// X-Macro invoking ACTION(NUM_ELEMENTS, ELEMENT_TYPE, FORMAT_AS) for each
// supported vector type.
//
// TODO(jfb) Add uint64_t, double and wider vectors once supported.
#define FOR_EACH_VECTOR_TYPE(ACTION) \
  ACTION(16, uint8_t, uint32_t)      \
  ACTION(8, uint16_t, uint16_t)      \
  ACTION(4, uint32_t, uint32_t)      \
  ACTION(4, float, float)

// X-Macro for each state of the test.
#define FOR_EACH_STATE(ACTION) \
  ACTION(SETUP) ACTION(TEST) ACTION(CHECK) ACTION(CLEANUP)

struct Test {
  typedef void *(*Func)(void *);  // POSIX thread function signature.
#define CREATE_ENUM(S) S,
  enum State { FOR_EACH_STATE(CREATE_ENUM) DONE };
  Func functions[DONE];  // One function per state.
  enum { InBuf0, InBuf1, OutBuf, NumBufs };
  void *bufs[NumBufs];
  const char *name;
};
#define CREATE_STRING(S) #S,
static const char *states[] = {FOR_EACH_STATE(CREATE_STRING)};

#define DEFINE_FORMAT(N, T, FMT) \
  FMT format(T v) { return v; }
FOR_EACH_VECTOR_TYPE(DEFINE_FORMAT)

template <size_t NumElements, typename T>
NOINLINE void print_vector(const T *vec) {
  std::cout << '{';
  for (size_t i = 0; i != NumElements; ++i)
    std::cout << format(vec[i]) << (i == NumElements - 1 ? '}' : ',');
}

// Declare vector types of a particular number of elements and underlying type,
// aligned to the element width (*not* the vector's width).
//
// Attributes must be integer constants, work around that limitation and allow
// using the following type for vectors within generic code:
//
//   typedef typename VectorHelper<NumElements, T>::Vector VectorAligned;
template <size_t NumElements, typename T>
struct VectorHelper;
#define SPECIALIZE_VECTOR_HELPER(N, T, FMT)                              \
  template <>                                                            \
  struct VectorHelper<N, T> {                                            \
    typedef T VectorAligned __attribute__((vector_size(N * sizeof(T)))); \
    typedef T Unaligned                                                  \
        __attribute__((vector_size(N * sizeof(T)), aligned(1)));         \
    typedef T ElementAligned                                             \
        __attribute__((vector_size(N * sizeof(T)), aligned(sizeof(T)))); \
  };
FOR_EACH_VECTOR_TYPE(SPECIALIZE_VECTOR_HELPER)

// Fill an array with a pseudo-random sequence.
//
// Always generate the same pseudo-random sequence from one run to another (to
// preserve golden output file), but different sequence for each type being
// tested.
typedef std::minstd_rand Rng;
template <typename T>
NOINLINE void pseudoRandomInit(Rng *r, T *buf, size_t size) {
  for (size_t i = 0; i != size; ++i)
    buf[i] = std::is_floating_point<T>::value ? (*r)() / (T)(*r).max() : (*r)();
}

// Define main() and run all the tests in the TEST_ARRAY, which is defined as:
//   volatile Test TESTS_ARRAY[] = { ... };
#define DEFINE_MAIN(TESTS_ARRAY)                                           \
  int main(void) {                                                         \
    std::cout << std::dec << std::fixed                                    \
              << std::setprecision(std::numeric_limits<double>::digits10); \
                                                                           \
    for (int state = Test::SETUP; state != Test::DONE; ++state)            \
      for (size_t i = 0; i != sizeof(tests) / sizeof(tests[0]); ++i) {     \
        int err;                                                           \
        pthread_t tid;                                                     \
        volatile Test *test = &TESTS_ARRAY[i];                             \
        Test::Func f = test->functions[state];                             \
        std::cout << states[state] << ' ' << test->name << '\n';           \
                                                                           \
        err = pthread_create(&tid, NULL, f, (void *)test);                 \
        CHECK(err == 0);                                                   \
        err = pthread_join(tid, NULL);                                     \
        CHECK(err == 0);                                                   \
      }                                                                    \
                                                                           \
    return 0;                                                              \
  }

#endif