Skip to content

Commit 9e22d15

Browse files
Krovatkinfacebook-github-bot
authored andcommitted
Enable tensorexpr cpp tests in CI. try #2 (pytorch#35454)
Summary: Pull Request resolved: pytorch#35454 Differential Revision: D20665160 Pulled By: Krovatkin fbshipit-source-id: e04cbe92b2ee5a3288f3c4e5c83533bfea85bf85
1 parent 930d218 commit 9e22d15

20 files changed

+779
-531
lines changed

test/cpp/jit/torch_python_test.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <c10/util/Exception.h>
22
#include <test/cpp/jit/tests.h>
3+
#include <test/cpp/tensorexpr/tests.h>
34

45
namespace torch {
56
namespace jit {
@@ -25,5 +26,17 @@ JIT_TEST_API void runJITCPPTests(bool runCuda) {
2526
testTorchSaveError();
2627
}
2728
#undef JIT_TEST
29+
30+
#define JIT_TEST(name) test##name();
31+
JIT_TEST_API void runTENSOREXPRCPPTests(bool runCuda) {
32+
TH_FORALL_TENSOREXPR_TESTS(JIT_TEST)
33+
if (runCuda) {
34+
#ifdef USE_CUDA
35+
TH_FORALL_TENSOREXPR_TESTS_CUDA(JIT_TEST)
36+
#endif
37+
}
38+
}
39+
#undef JIT_TEST
40+
2841
} // namespace jit
2942
} // namespace torch

test/cpp/tensorexpr/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ set(TENSOREXPR_TEST_ROOT ${TORCH_ROOT}/test/cpp/tensorexpr)
33
file(GLOB TENSOREXPR_TEST_SRCS ${TENSOREXPR_TEST_ROOT}/test_*.cpp)
44
set(TENSOREXPR_TEST_SRCS ${TENSOREXPR_TEST_SRCS} PARENT_SCOPE)
55

6+
# this is used for running cpp tests from python as part of test_jit.TestJit.test_tensorexpr_cpp
7+
set(TENSOREXPR_TEST_SRCS_WITH_PADDED ${TENSOREXPR_TEST_SRCS} ${TENSOREXPR_TEST_ROOT}/padded_buffer.cpp)
8+
if(NOT USE_CUDA)
9+
list(REMOVE_ITEM TENSOREXPR_TEST_SRCS_WITH_PADDED ${TENSOREXPR_TEST_ROOT}/test_cuda.cpp)
10+
endif()
11+
if(NOT USE_LLVM)
12+
list(REMOVE_ITEM TENSOREXPR_TEST_SRCS_WITH_PADDED ${TENSOREXPR_TEST_ROOT}/test_llvm.cpp)
13+
endif()
14+
set(TENSOREXPR_TEST_SRCS_WITH_PADDED ${TENSOREXPR_TEST_SRCS_WITH_PADDED} PARENT_SCOPE)
15+
616
add_executable(test_tensorexpr
717
${TORCH_ROOT}/test/cpp/common/main.cpp
818
${TENSOREXPR_TEST_ROOT}/gtest.cpp

test/cpp/tensorexpr/gtest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ namespace jit {
99
TEST(TensorExprTest, name) { \
1010
test##name(); \
1111
}
12-
TH_FORALL_TESTS(TENSOREXPR_GTEST)
12+
TH_FORALL_TENSOREXPR_TESTS(TENSOREXPR_GTEST)
1313
#undef TENSOREXPR_GTEST
1414

1515
#ifdef TORCH_ENABLE_LLVM
1616
#define TENSOREXPR_GTEST_LLVM(name) \
1717
TEST(TensorExprTest, name##_LLVM) { \
1818
test##name(); \
1919
}
20-
TH_FORALL_TESTS_LLVM(TENSOREXPR_GTEST_LLVM)
20+
TH_FORALL_TENSOREXPR_TESTS_LLVM(TENSOREXPR_GTEST_LLVM)
2121
#undef TENSOREXPR_GTEST_LLVM
2222
#endif
2323

@@ -26,7 +26,7 @@ TH_FORALL_TESTS_LLVM(TENSOREXPR_GTEST_LLVM)
2626
TEST(TensorExprTest, name##_CUDA) { \
2727
test##name(); \
2828
}
29-
TH_FORALL_TESTS_CUDA(TENSOREXPR_GTEST_CUDA)
29+
TH_FORALL_TENSOREXPR_TESTS_CUDA(TENSOREXPR_GTEST_CUDA)
3030
#undef TENSOREXPR_GTEST_CUDA
3131
#endif
3232

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#pragma once
2+
3+
#include <cmath>
4+
// Copyright 2005, Google Inc.
5+
// All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are
9+
// met:
10+
//
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
14+
// copyright notice, this list of conditions and the following disclaimer
15+
// in the documentation and/or other materials provided with the
16+
// distribution.
17+
// * Neither the name of Google Inc. nor the names of its
18+
// contributors may be used to endorse or promote products derived from
19+
// this software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
//
33+
// The Google C++ Testing and Mocking Framework (Google Test)
34+
//
35+
// This header file declares functions and macros used internally by
36+
// Google Test. They are subject to change without notice.
37+
38+
using Bits = uint32_t;
39+
40+
// this avoids the "dereferencing type-punned pointer
41+
// will break strict-aliasing rules" error
42+
union Float {
43+
float float_;
44+
Bits bits_;
45+
};
46+
47+
// # of bits in a number.
48+
static const size_t kBitCount = 8*sizeof(Bits);
49+
// The mask for the sign bit.
50+
static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
51+
52+
// GOOGLETEST_CM0001 DO NOT DELETE
53+
54+
// Converts an integer from the sign-and-magnitude representation to
55+
// the biased representation. More precisely, let N be 2 to the
56+
// power of (kBitCount - 1), an integer x is represented by the
57+
// unsigned number x + N.
58+
//
59+
// For instance,
60+
//
61+
// -N + 1 (the most negative number representable using
62+
// sign-and-magnitude) is represented by 1;
63+
// 0 is represented by N; and
64+
// N - 1 (the biggest number representable using
65+
// sign-and-magnitude) is represented by 2N - 1.
66+
//
67+
// Read http://en.wikipedia.org/wiki/Signed_number_representations
68+
// for more details on signed number representations.
69+
static Bits SignAndMagnitudeToBiased(const Bits &sam) {
70+
if (kSignBitMask & sam) {
71+
// sam represents a negative number.
72+
return ~sam + 1;
73+
} else {
74+
// sam represents a positive number.
75+
return kSignBitMask | sam;
76+
}
77+
}
78+
79+
// Given two numbers in the sign-and-magnitude representation,
80+
// returns the distance between them as an unsigned number.
81+
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,
82+
const Bits &sam2) {
83+
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
84+
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
85+
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
86+
}
87+
88+
// How many ULP's (Units in the Last Place) we want to tolerate when
89+
// comparing two numbers. The larger the value, the more error we
90+
// allow. A 0 value means that two numbers must be exactly the same
91+
// to be considered equal.
92+
//
93+
// The maximum error of a single floating-point operation is 0.5
94+
// units in the last place. On Intel CPU's, all floating-point
95+
// calculations are done with 80-bit precision, while double has 64
96+
// bits. Therefore, 4 should be enough for ordinary use.
97+
//
98+
// See the following article for more details on ULP:
99+
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
100+
static const size_t kMaxUlps = 4;
101+
102+
// Returns true if and only if this number is at most kMaxUlps ULP's away
103+
// from rhs. In particular, this function:
104+
//
105+
// - returns false if either number is (or both are) NAN.
106+
// - treats really large numbers as almost equal to infinity.
107+
// - thinks +0.0 and -0.0 are 0 DLP's apart.
108+
inline bool AlmostEquals(float lhs, float rhs) {
109+
// The IEEE standard says that any comparison operation involving
110+
// a NAN must return false.
111+
if (std::isnan(lhs) || std::isnan(rhs))
112+
return false;
113+
114+
Float l = {lhs};
115+
Float r = {rhs};
116+
117+
return DistanceBetweenSignAndMagnitudeNumbers(l.bits_, r.bits_) <= kMaxUlps;
118+
}

test/cpp/tensorexpr/padded_buffer.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#include "test/cpp/tensorexpr/padded_buffer.h"
22

33
#include <sstream>
4-
5-
#include <gtest/gtest.h>
6-
74
#include <c10/util/Logging.h>
85

96
namespace torch {

test/cpp/tensorexpr/padded_buffer.h

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,20 @@ class PaddedBuffer : public PaddedBufferBase {
169169
// Verify the watermarks in the paddings are intact.
170170
void ValidateWatermark() const {
171171
for (int i = 0; i < kPaddingSize; i++) {
172-
EXPECT_EQ(data_[i], kPaddingValue)
173-
<< "left-side watermark broken: "
174-
<< "index: " << i << ", name: " << name();
175-
EXPECT_EQ(data_[i + total_size_ + kPaddingSize], kPaddingValue)
176-
<< "right-side watermark broken: "
177-
<< "index: " << i << ", name: " << name();
172+
ASSERT_EQ(
173+
data_[i],
174+
kPaddingValue,
175+
"left-side watermark broken: index: ",
176+
i,
177+
", name: ",
178+
name());
179+
ASSERT_EQ(
180+
data_[i + total_size_ + kPaddingSize],
181+
kPaddingValue,
182+
"right-side watermark broken: index: ",
183+
i,
184+
", name: ",
185+
name());
178186
}
179187
}
180188

@@ -183,9 +191,13 @@ class PaddedBuffer : public PaddedBufferBase {
183191
DCHECK(backup_data_.size() == data_.size())
184192
<< "Please make sure you have call Backup() before calling CheckBackup()";
185193
for (int i = 0; i < total_size_; i++) {
186-
EXPECT_EQ(data_[i + kPaddingSize], backup_data_[i + kPaddingSize])
187-
<< "mismatch against backup, "
188-
<< "index: " << i << ", name: " << name();
194+
ASSERT_EQ(
195+
data_[i + kPaddingSize],
196+
backup_data_[i + kPaddingSize],
197+
"mismatch against backup, index: ",
198+
i,
199+
", name: ",
200+
name());
189201
}
190202
}
191203

@@ -219,8 +231,8 @@ void ExpectAllEqual(const PaddedBuffer<T>& f1, const PaddedBuffer<T>& f2) {
219231
f1.ValidateWatermark();
220232
f2.ValidateWatermark();
221233
for (int i = 0; i < total_size; i++) {
222-
EXPECT_EQ(v1[kPaddingSize + i], v2[kPaddingSize + i])
223-
<< CompareErrorMsg(f1, f2, i);
234+
ASSERT_EQ(
235+
v1[kPaddingSize + i], v2[kPaddingSize + i], CompareErrorMsg(f1, f2, i));
224236
}
225237
}
226238

@@ -237,8 +249,11 @@ void ExpectAllNear(
237249
f1.ValidateWatermark();
238250
f2.ValidateWatermark();
239251
for (int i = 0; i < total_size; i++) {
240-
ASSERT_NEAR(v1[kPaddingSize + i], v2[kPaddingSize + i], abs_error);
241-
// << CompareErrorMsg(f1, f2, i);
252+
ASSERT_NEAR(
253+
v1[kPaddingSize + i],
254+
v2[kPaddingSize + i],
255+
abs_error,
256+
CompareErrorMsg(f1, f2, i));
242257
}
243258
}
244259

0 commit comments

Comments
 (0)