Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
ArrayRCP_MT_UnitTests_Decl.hpp
Go to the documentation of this file.
1/*
2// @HEADER
3// ***********************************************************************
4//
5// Teuchos: Common Tools Package
6// Copyright (2004) Sandia Corporation
7//
8// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9// license for use of this work by or on behalf of the U.S. Government.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39//
40// ***********************************************************************
41// @HEADER
42*/
43
44// These unit tests are used for both a Nightly version and a Basic version
45
47
48#include "Teuchos_ArrayRCP.hpp"
51#include <vector>
52#include <thread>
53
54namespace {
55
57using Teuchos::RCP;
58using Teuchos::rcp;
59using Teuchos::null;
61
62// thread method used by unit test mtArrayRCPMultipleReads below
63static void read_arrayrcp_in_thread(ArrayRCP<int> shared_arrayrcp,
64 int expectedValue, std::atomic<int> & countErrors) {
65 // spin lock all threads until released by the main thread
66 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
67 for( int n = 0; n < 1000; ++n) {
68 // test the iterators
69 for (ArrayRCP<int>::const_iterator iter = shared_arrayrcp.begin();
70 iter < shared_arrayrcp.end(); ++iter) {
71 // test reading a value
72 int readAValue = shared_arrayrcp[0];
73 // make sure the value is correct and log anything wrong
74 if (readAValue != expectedValue) {
75 ++countErrors;
76 }
77 // now check using the iterator
78 int readAValueByIterator = *iter;
79 // make sure the value is correct and log anything wrong
80 if (readAValueByIterator != expectedValue) {
81 ++countErrors;
82 }
83 }
84 }
85}
86
87// RCP Thread Safety Unit Test: mtArrayRCPMultipleReads
88//
89// Purpose:
90// Sanity Check: Validate that the class is working - this was not expected
91// to have any trouble once the RCP class was made thread and no issues
92// were found.
93//
94// Description:
95// Creates an ArrayRCP<int>, sets all the values to an arbitrary known value,
96// then shares it to several threads which all read the ArrayRCP
97// at the same time and validate the read works. This tests both using
98// the iterators to cycle through the array and the actually reading of the
99// elements.
100//
101// Solution to the Problem:
102// Sanity Check
103//
104// Demonstration of Problem:
105// Sanity Check
106TEUCHOS_UNIT_TEST( ArrayRCP, mtArrayRCPMultipleReads )
107{
108 const int numThreads = TEUCHOS_THREAD_SAFE_UNIT_TESTS_THREADS_USED;
109 const int numTests = NUM_TESTS_TO_RUN;
110 const int setValue = 67359487; // arbitrary
111 const int arraySize = 10; // arbitrary
112 std::atomic<int> countErrors(0); // atomic counter to log errors
113 try {
114 for (int testCycle = 0; testCycle < numTests; ++testCycle) {
115 std::vector<std::thread> threads;
116 // set up all threads to be spin locked
117 ThreadTestManager::s_bAllowThreadsToRun = false;
118 // create an ArrayRCP to share between the threads
119 ArrayRCP<int> shared_arrayrcp(arraySize, setValue); // some array
120 // Send the ArrayRCP to all the threads
121 for (int i = 0; i < numThreads; ++i) {
122 threads.push_back( std::thread(read_arrayrcp_in_thread,
123 shared_arrayrcp, setValue, std::ref(countErrors)));
124 }
125 // let the threads run
126 ThreadTestManager::s_bAllowThreadsToRun = true;
127 // join them
128 for (unsigned int i = 0; i < threads.size(); ++i) {
129 threads[i].join();
130 }
131 convenience_log_progress(testCycle, numTests); // this is just output
132 }
133 }
134 TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success);
135 TEST_EQUALITY(countErrors, 0);
136}
137
138// thread method used by unit test mtRCPofArrayRCPMultipleReads below
139// this variant reads an RCP<ArrayRCP<int>> instrad of an ArrayRCP<int>
140// Note the difference is the threads now directly access the same ArrayRCP<int>
141// object rather than copies of it.
142static void read_rcp_of_arrayrcp_in_thread(RCP<ArrayRCP<int>>
143 shared_rcp_of_arrayrcp, int expectedValue, std::atomic<int> & countErrors) {
144 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
145 for( int n = 0; n < 1000; ++n) {
146 for (ArrayRCP<int>::const_iterator iter = shared_rcp_of_arrayrcp->begin();
147 iter < shared_rcp_of_arrayrcp->end(); ++iter) {
148 // test reading a value
149 int readAValue = (*shared_rcp_of_arrayrcp)[0];
150 // make sure the value is correct and log anything wrong
151 if (readAValue != expectedValue) {
152 ++countErrors;
153 }
154 // now check using the iterator
155 int readAValueByIterator = *iter;
156 // make sure the value is correct and log anything wrong
157 if (readAValueByIterator != expectedValue) {
158 ++countErrors;
159 }
160 }
161 }
162}
163
164// RCP Thread Safety Unit Test: mtRCPofArrayRCPMultipleReads
165//
166// Purpose:
167// Sanity Check: Similar to prior mtArrayRCPMultipleReads test.
168//
169// Description:
170// Same as mtArrayRCPMultipleReads except we pass an RCP<Array<int>>
171// instead of an Array<int>
172//
173// Solution to the Problem:
174// Sanity Check
175//
176// Demonstration of Problem:
177// Sanity Check
178TEUCHOS_UNIT_TEST( ArrayRCP, mtRCPofArrayRCPMultipleReads )
179{
180 const int numThreads = TEUCHOS_THREAD_SAFE_UNIT_TESTS_THREADS_USED;
181 const int numTests = NUM_TESTS_TO_RUN;
182 const int setValue = 67359487; // arbitrary
183 const int arraySize = 10; // arbitrary
184 std::atomic<int> countErrors(0); // atomic counter to log errors
185 try {
186 for (int testCycle = 0; testCycle < numTests; ++testCycle) {
187 std::vector<std::thread> threads;
188 // set up all threads to be spin locked
189 ThreadTestManager::s_bAllowThreadsToRun = false;
190 // create an RCP<ArrayRCP> to share between the threads
191 RCP<ArrayRCP<int>> shared_rcp_of_arrayrcp =
192 rcp(new ArrayRCP<int>(arraySize, setValue)); // some array
193 // Send the RCP<ArrayRCP<int>> to all the threads
194 for (int i = 0; i < numThreads; ++i) {
195 threads.push_back( std::thread(read_rcp_of_arrayrcp_in_thread,
196 shared_rcp_of_arrayrcp, setValue, std::ref(countErrors)) );
197 }
198 // let the threads run
199 ThreadTestManager::s_bAllowThreadsToRun = true;
200 // join them
201 for (unsigned int i = 0; i < threads.size(); ++i) {
202 threads[i].join();
203 }
204 convenience_log_progress(testCycle, numTests); // this is just output
205 }
206 }
207 TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success);
208 TEST_EQUALITY(countErrors, 0);
209}
210
211} // end namespace
#define NUM_TESTS_TO_RUN
#define TEUCHOS_THREAD_SAFE_UNIT_TESTS_THREADS_USED
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions.
Unit testing support.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Reference-counted smart pointer for managing arrays.
Dangling reference error exception class.
Smart reference counting pointer class for automatic garbage collection.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.