Lift
Library of parallel computing primitives for GPUs and multi-core CPUs
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
harness.h
Go to the documentation of this file.
1 /*
2  * Lift
3  *
4  * Copyright (c) 2014-2015, NVIDIA CORPORATION
5  * Copyright (c) 2015-2016, Nuno Subtil <subtil@gmail.com>
6  * Copyright (c) 2015-2016, Roche Molecular Systems Inc.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * * Neither the name of the copyright holders nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #pragma once
33 
34 #include <string>
35 #include <vector>
36 
37 namespace lift {
38 
42 struct test
43 {
44  const std::string name; // short test name
45  const std::string description; // longer test description
46  const bool need_cuda; // true if the test requires CUDA to run
47 
48  bool test_passed; // set to true after run() if test passed
49 
50  test(std::string name, bool need_cuda)
51  : name(name),
52  description(""),
53  need_cuda(need_cuda),
54  test_passed(false)
55  { }
56 
57  test(std::string name, std::string description, bool need_cuda)
58  : name(name),
59  description(description),
60  need_cuda(need_cuda),
61  test_passed(false)
62  { }
63 
64  // setup routine, performs pre-test initialization (optional)
65  virtual void setup()
66  { }
67 
68  // the actual test routine
69  virtual void run() = 0;
70 
71  // teardown routine, performs post-test cleanup (optional)
72  virtual void teardown()
73  { }
74 };
75 
79 struct standalone_test : public test
80 {
81  typedef void (*callable) (void);
83 
85  : test(name, need_cuda), entrypoint(entrypoint)
86  { }
87 
88  standalone_test(callable entrypoint, std::string name, std::string description, bool need_cuda)
89  : test(name, description, need_cuda), entrypoint(entrypoint)
90  { }
91 
92  virtual void run(void)
93  {
94  entrypoint();
95  }
96 };
97 
98 // define a test object for a standalone function
99 #define TEST_FUN(test_name, entrypoint) \
100  standalone_test test_name(entrypoint, #test_name, false)
101 
102 // define a test object for a standalone function which requires CUDA to run
103 #define TEST_FUN_CUDA(test_name, entrypoint) \
104  standalone_test test_name(entrypoint, #test_name, true)
105 
106 // define a test object for a standalone function templated on the target system
107 // generates both host and device versions of the test
108 #define TEST_FUN_HD(test_name, entrypoint) \
109  standalone_test test_name##_host(entrypoint<host>, #test_name "_host", false); \
110  standalone_test test_name##_cuda(entrypoint<cuda>, #test_name "_cuda", true)
111 
112 // register a test object
113 #define TEST_REGISTER(test_name) \
114  test_list.push_back(&test_name)
115 
116 // register a pair of host/device test objects
117 #define TEST_REGISTER_HD(test_name) \
118  test_list.push_back(&test_name##_host); \
119  test_list.push_back(&test_name##_cuda)
120 
121 // the master test list
122 extern std::vector<test *> test_list;
123 // TLS pointer to the current test object being run
124 extern thread_local test *current_test;
125 
126 // check that expr is true, log and fail test if not
127 #define lift_check(expr) \
128  if (!(expr)) \
129  { \
130  printf("\n check failed at %s:%u: expression \"%s\"", __FILE__, __LINE__, #expr); \
131  fflush(stdout); \
132  current_test->test_passed = false; \
133  debug_check_failure(); \
134  }
135 
136 // mark a test failure
137 #define lift_fail() \
138  printf("\n test failed at %s:%u", __FILE__, __LINE__); \
139  fflush(stdout); \
140  current_test->test_passed = false; \
141  debug_check_failure()
142 
143 } // namespace lift
144 
145 // populate the master test list
146 extern void generate_test_list(void);
147 // debugging aid: empty function called whenever lift_check detects a failure
148 extern void debug_check_failure(void);
test(std::string name, std::string description, bool need_cuda)
Definition: harness.h:57
standalone_test(callable entrypoint, std::string name, bool need_cuda)
Definition: harness.h:84
void(* callable)(void)
Definition: harness.h:81
bool test_passed
Definition: harness.h:48
virtual void setup()
Definition: harness.h:65
standalone_test(callable entrypoint, std::string name, std::string description, bool need_cuda)
Definition: harness.h:88
virtual void run()=0
void debug_check_failure(void)
Definition: entrypoint.cu:51
The test object interface.
Definition: harness.h:42
callable entrypoint
Definition: harness.h:82
thread_local test * current_test
Definition: entrypoint.cu:41
virtual void run(void)
Definition: harness.h:92
const bool need_cuda
Definition: harness.h:46
Wrapper for standalone tests, which consist of a single function with no arguments and no return valu...
Definition: harness.h:79
const std::string name
Definition: harness.h:44
const std::string description
Definition: harness.h:45
std::vector< test * > test_list
Definition: entrypoint.cu:44
void generate_test_list(void)
virtual void teardown()
Definition: harness.h:72
test(std::string name, bool need_cuda)
Definition: harness.h:50