File: test_expressions.cpp

package info (click to toggle)
gridtools 2.3.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 29,480 kB
  • sloc: cpp: 228,792; python: 17,561; javascript: 9,164; ansic: 4,101; sh: 850; makefile: 231; f90: 201
file content (101 lines) | stat: -rw-r--r-- 3,573 bytes parent folder | download | duplicates (2)
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
/*
 * GridTools
 *
 * Copyright (c) 2014-2023, ETH Zurich
 * All rights reserved.
 *
 * Please, refer to the LICENSE file in the root directory.
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include <gtest/gtest.h>

#include <gridtools/stencil/cartesian.hpp>

namespace gridtools {
    namespace stencil {
        namespace cartesian {

            using namespace expressions;

            /*
             * Mocking accessor and iterate domain
             */
            template <class T>
            struct accessor_mock {
                T value;
            };

            template <class T>
            struct is_accessor<accessor_mock<T>> : std::true_type {};

            namespace {

                struct iterate_domain_mock {
                    // trivial evaluation of the accessor_mock
                    template <typename Accessor, typename std::enable_if<is_accessor<Accessor>::value, int>::type = 0>
                    GT_FUNCTION auto operator()(Accessor const &val) const {
                        return val.value;
                    }

                    // copy of the iterate_domain for expr
                    template <class Op, class... Args>
                    GT_FUNCTION auto operator()(expr<Op, Args...> const &arg) const {
                        return expressions::evaluation::value(*this, arg);
                    }
                };

                using val = accessor_mock<float>;

#define EXPRESSION_TEST(name, expr)                             \
    GT_FUNCTION float test_##name() {                           \
        auto result = iterate_domain_mock()(expr);              \
        static_assert(std::is_same_v<decltype(result), float>); \
        return result;                                          \
    }

                EXPRESSION_TEST(add_accessors, val{1} + val{2})
                EXPRESSION_TEST(sub_accessors, val{1} - val{2})
                EXPRESSION_TEST(negate_accessors, -val{1})
                EXPRESSION_TEST(plus_sign_accessors, +val{1})
                EXPRESSION_TEST(with_parenthesis_accessors, (val{1} + val{2}) * (val{1} - val{2}))

                /*
                 * User API tests
                 */
                TEST(test_expressions, add_accessors) {
                    EXPECT_FLOAT_EQ(test_add_accessors(), 3);
                    EXPECT_FLOAT_EQ(test_sub_accessors(), -1);
                    EXPECT_FLOAT_EQ(test_negate_accessors(), -1);
                    EXPECT_FLOAT_EQ(test_plus_sign_accessors(), 1);
                    EXPECT_FLOAT_EQ(test_with_parenthesis_accessors(), -3);
                }

                /*
                 * Library tests illustrating how expressions are evaluated (implementation details!)
                 */
                TEST(test_expressions, expr_plus_by_ctor) {
                    accessor_mock<double> a{1};
                    accessor_mock<double> b{2};

                    auto add = make_expr(plus_f{}, a, b);

                    iterate_domain_mock eval;

                    auto result = evaluation::value(eval, add);

                    ASSERT_DOUBLE_EQ(result, 3);
                }

                TEST(expression_unit_test, expr_plus_by_operator_overload) {
                    iterate_domain_mock iterate;

                    auto add = val{1} + val{2};

                    auto result = evaluation::value(iterate, add);

                    ASSERT_DOUBLE_EQ(result, 3);
                }
            } // namespace
        }     // namespace cartesian
    }         // namespace stencil
} // namespace gridtools