2 * Copyright (c) 2020 The Regents of the University of California
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer;
11 * redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution;
14 * neither the name of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <gtest/gtest.h>
36 #include "base/amo.hh"
39 multiply2Op(int *b
, int a
)
45 multiply3Op(int *b
, int a
, int c
)
51 addSubColumns(int *b
, const std::array
<int, 2>& a
, const std::array
<int, 2>& c
)
57 TEST(AmoTest
, AtomicOpMin
)
59 // test with ints and strings
60 int test_int_smaller
= 5;
61 int test_int_bigger
= 15;
62 std::string test_string_smaller
= "apple";
63 std::string test_string_bigger
= "cat";
65 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpMin
<int>(10);
66 TypedAtomicOpFunctor
<std::string
> *amo_op_string
=
67 new AtomicOpMin
<std::string
>("base");
68 amo_op_int
->execute(&test_int_smaller
);
69 amo_op_int
->execute(&test_int_bigger
);
70 amo_op_string
->execute(&test_string_smaller
);
71 amo_op_string
->execute(&test_string_bigger
);
73 EXPECT_EQ(test_int_smaller
, 5);
74 EXPECT_EQ(test_int_bigger
, 10);
75 EXPECT_EQ(test_string_smaller
, "apple");
76 EXPECT_EQ(test_string_bigger
, "base");
79 TEST(AmoTest
, AtomicOpMax
)
81 int test_int_smaller
= 5;
82 int test_int_bigger
= 15;
83 std::string test_string_smaller
= "apple";
84 std::string test_string_bigger
= "cat";
86 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpMax
<int>(10);
87 TypedAtomicOpFunctor
<std::string
> *amo_op_string
=
88 new AtomicOpMax
<std::string
>("base");
89 amo_op_int
->execute(&test_int_smaller
);
90 amo_op_int
->execute(&test_int_bigger
);
91 amo_op_string
->execute(&test_string_smaller
);
92 amo_op_string
->execute(&test_string_bigger
);
94 EXPECT_EQ(test_int_smaller
, 10);
95 EXPECT_EQ(test_int_bigger
, 15);
96 EXPECT_EQ(test_string_smaller
, "base");
97 EXPECT_EQ(test_string_bigger
, "cat");
100 TEST(AmoTest
, AtomicOpDec
)
103 char test_char
= 'c';
105 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpDec
<int>();
106 TypedAtomicOpFunctor
<char> *amo_op_char
= new AtomicOpDec
<char>();
107 amo_op_int
->execute(&test_int
);
108 amo_op_char
->execute(&test_char
);
110 EXPECT_EQ(test_int
, 9);
111 EXPECT_EQ(test_char
, 'b');
114 TEST(AmoTest
, AtomicOpInc
)
117 char test_char
= 'c';
119 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpInc
<int>();
120 TypedAtomicOpFunctor
<char> *amo_op_char
= new AtomicOpInc
<char>();
121 amo_op_int
->execute(&test_int
);
122 amo_op_char
->execute(&test_char
);
124 EXPECT_EQ(test_int
, 11);
125 EXPECT_EQ(test_char
, 'd');
128 TEST(AmoTest
, AtomicOpSub
)
131 char test_char
= 'c';
133 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpSub
<int>(2);
134 TypedAtomicOpFunctor
<char> *amo_op_char
= new AtomicOpSub
<char>('a');
135 amo_op_int
->execute(&test_int
);
136 amo_op_char
->execute(&test_char
);
138 EXPECT_EQ(test_int
, 8);
139 EXPECT_EQ(test_char
, 2);
142 TEST(AmoTest
, AtomicOpAdd
)
145 char test_char
= 'c';
147 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpAdd
<int>(2);
148 TypedAtomicOpFunctor
<char> *amo_op_char
= new AtomicOpAdd
<char>(2);
149 amo_op_int
->execute(&test_int
);
150 amo_op_char
->execute(&test_char
);
152 EXPECT_EQ(test_int
, 12);
153 EXPECT_EQ(test_char
, 'e');
156 TEST(AmoTest
, AtomicOpExch
)
159 char test_char
= 'c';
161 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpExch
<int>(2);
162 TypedAtomicOpFunctor
<char> *amo_op_char
= new AtomicOpExch
<char>('a');
163 amo_op_int
->execute(&test_int
);
164 amo_op_char
->execute(&test_char
);
166 EXPECT_EQ(test_int
, 2);
167 EXPECT_EQ(test_char
, 'a');
170 TEST(AmoTest
, AtomicOpXor
)
173 char test_char
= 'c';
175 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpXor
<int>(2);
176 TypedAtomicOpFunctor
<char> *amo_op_char
= new AtomicOpXor
<char>('a');
177 amo_op_int
->execute(&test_int
);
178 amo_op_char
->execute(&test_char
);
180 EXPECT_EQ(test_int
, 8); // 1010 ^ 0010 = 1000
181 EXPECT_EQ(test_char
, 2); // 99 ^ 97 = 2
184 TEST(AmoTest
, AtomicOpOr
)
187 bool test_bool
= true;
189 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpOr
<int>(2);
190 TypedAtomicOpFunctor
<bool> *amo_op_bool
= new AtomicOpOr
<bool>(false);
191 amo_op_int
->execute(&test_int
);
192 amo_op_bool
->execute(&test_bool
);
194 EXPECT_EQ(test_int
, 10);
195 EXPECT_EQ(test_bool
, true);
198 TEST(AmoTest
, AtomicOpAnd
)
201 char test_char
= 'c';
203 TypedAtomicOpFunctor
<int> *amo_op_int
= new AtomicOpAnd
<int>(6);
204 TypedAtomicOpFunctor
<char> *amo_op_char
= new AtomicOpAnd
<char>('a');
205 amo_op_int
->execute(&test_int
);
206 amo_op_char
->execute(&test_char
);
208 EXPECT_EQ(test_int
, 2);
209 EXPECT_EQ(test_char
, 'a');
212 TEST(AmoTest
, AtomicGeneric2Op
)
216 TypedAtomicOpFunctor
<int> *amo_op_int
=
217 new AtomicGeneric2Op
<int>(9, multiply2Op
);
218 amo_op_int
->execute(&test_int
);
220 EXPECT_EQ(test_int
, 81);
223 TEST(AmoTest
, AtomicGeneric3Op
)
227 TypedAtomicOpFunctor
<int> *amo_op_int
=
228 new AtomicGeneric3Op
<int>(4, 3, multiply3Op
);
229 amo_op_int
->execute(&test_int
);
231 EXPECT_EQ(test_int
, 24);
234 TEST(AmoTest
, AtomicGenericPair3Op
)
238 std::array
<int, 2> a
= {6, 3};
239 std::array
<int, 2> c
= {10, 8};
240 TypedAtomicOpFunctor
<int> *amo_op_int
=
241 new AtomicGenericPair3Op
<int>(a
, c
, addSubColumns
);
242 amo_op_int
->execute(&test_int
);
244 EXPECT_EQ(test_int
, 10);