Blender
V4.3
source
blender
blenlib
tests
BLI_index_mask_expression_test.cc
Go to the documentation of this file.
1
/* SPDX-FileCopyrightText: 2024 Blender Authors
2
*
3
* SPDX-License-Identifier: Apache-2.0 */
4
5
#include "
BLI_array.hh
"
6
#include "
BLI_index_mask_expression.hh
"
7
#include "
BLI_rand.hh
"
8
#include "
BLI_set.hh
"
9
#include "
BLI_strict_flags.h
"
10
#include "
BLI_timeit.hh
"
11
12
#include "testing/testing.h"
13
14
namespace
blender::index_mask::tests
{
15
16
TEST
(index_mask_expression, Union)
17
{
18
IndexMaskMemory
memory;
19
const
IndexMask
mask_a =
IndexMask::from_initializers
({5,
IndexRange
(50, 100), 100'000}, memory);
20
const
IndexMask
mask_b =
IndexMask::from_initializers
({
IndexRange
(10, 10), 60, 200}, memory);
21
22
ExprBuilder
builder;
23
const
Expr
&expr = builder.merge({&mask_a, &mask_b});
24
const
IndexMask
union_mask =
evaluate_expression
(expr, memory);
25
26
EXPECT_EQ
(union_mask,
27
IndexMask::from_initializers
(
28
{5,
IndexRange
(10, 10),
IndexRange
(50, 100), 200, 100'000}, memory));
29
}
30
31
TEST
(index_mask_expression, UnionMulti)
32
{
33
IndexMaskMemory
memory;
34
const
IndexMask
mask_a =
IndexMask::from_initializers
({3, 5, 6, 8, 9}, memory);
35
const
IndexMask
mask_b =
IndexMask::from_initializers
({4, 6, 7, 12}, memory);
36
const
IndexMask
mask_c =
IndexMask::from_initializers
({0, 5}, memory);
37
const
IndexMask
mask_d =
IndexMask::from_initializers
({6, 7, 10}, memory);
38
39
ExprBuilder
builder;
40
const
Expr
&expr = builder.merge({&mask_a, &mask_b, &mask_c, &mask_d});
41
const
IndexMask
union_mask =
evaluate_expression
(expr, memory);
42
43
EXPECT_EQ
(union_mask,
IndexMask::from_initializers
({0, 3, 4, 5, 6, 7, 8, 9, 10, 12}, memory));
44
}
45
46
TEST
(index_mask_expression, IntersectMulti)
47
{
48
IndexMaskMemory
memory;
49
const
IndexMask
mask_a =
IndexMask::from_initializers
({3, 5, 6, 8, 9}, memory);
50
const
IndexMask
mask_b =
IndexMask::from_initializers
({2, 5, 6, 10}, memory);
51
const
IndexMask
mask_c =
IndexMask::from_initializers
({4, 5, 6}, memory);
52
const
IndexMask
mask_d =
IndexMask::from_initializers
({1, 5, 10}, memory);
53
54
ExprBuilder
builder;
55
const
Expr
&expr = builder.intersect({&mask_a, &mask_b, &mask_c, &mask_d});
56
const
IndexMask
intersect_mask =
evaluate_expression
(expr, memory);
57
58
EXPECT_EQ
(intersect_mask,
IndexMask::from_initializers
({5}, memory));
59
}
60
61
TEST
(index_mask_expression, DifferenceMulti)
62
{
63
IndexMaskMemory
memory;
64
const
IndexMask
mask_a =
IndexMask::from_initializers
({1, 2, 3, 5, 6, 7, 9, 10}, memory);
65
const
IndexMask
mask_b =
IndexMask::from_initializers
({2, 5, 6, 10}, memory);
66
const
IndexMask
mask_c =
IndexMask::from_initializers
({4, 5, 6}, memory);
67
const
IndexMask
mask_d =
IndexMask::from_initializers
({1, 5, 10}, memory);
68
69
ExprBuilder
builder;
70
const
Expr
&expr = builder.subtract(&mask_a, {&mask_b, &mask_c, &mask_d});
71
const
IndexMask
difference_mask =
evaluate_expression
(expr, memory);
72
73
EXPECT_EQ
(difference_mask,
IndexMask::from_initializers
({3, 7, 9}, memory));
74
}
75
76
TEST
(index_mask_expression,
Intersection
)
77
{
78
IndexMaskMemory
memory;
79
const
IndexMask
mask_a =
IndexMask::from_initializers
({5,
IndexRange
(50, 100), 100'000}, memory);
80
const
IndexMask
mask_b =
IndexMask::from_initializers
(
81
{5, 6,
IndexRange
(100, 100), 80000, 100'000}, memory);
82
83
ExprBuilder
builder;
84
const
Expr
&expr = builder.intersect({&mask_a, &mask_b});
85
const
IndexMask
intersection_mask =
evaluate_expression
(expr, memory);
86
87
EXPECT_EQ
(intersection_mask,
88
IndexMask::from_initializers
({5,
IndexRange
(100, 50), 100'000}, memory));
89
}
90
91
TEST
(index_mask_expression, Difference)
92
{
93
IndexMaskMemory
memory;
94
const
IndexMask
mask_a =
IndexMask::from_initializers
({5,
IndexRange
(50, 100), 100'000}, memory);
95
const
IndexMask
mask_b =
IndexMask::from_initializers
({5, 60,
IndexRange
(100, 20)}, memory);
96
97
ExprBuilder
builder;
98
const
Expr
&expr = builder.subtract(&mask_a, {&mask_b});
99
const
IndexMask
difference_mask =
evaluate_expression
(expr, memory);
100
101
EXPECT_EQ
(difference_mask,
102
IndexMask::from_initializers
(
103
{
IndexRange
(50, 10),
IndexRange
(61, 39),
IndexRange
(120, 30), 100'000}, memory));
104
}
105
106
TEST
(index_mask_expression, FizzBuzz)
107
{
108
IndexMaskMemory
memory;
109
const
IndexMask
mask_3 =
IndexMask::from_every_nth
(3, 11, 0, memory);
/* 0 - 30 */
110
const
IndexMask
mask_5 =
IndexMask::from_every_nth
(5, 11, 0, memory);
/* 0 - 50 */
111
112
{
113
ExprBuilder
builder;
114
const
Expr
&expr = builder.
merge
({&mask_3, &mask_5});
115
const
IndexMask
result =
evaluate_expression
(expr, memory);
116
EXPECT_EQ
(
117
result,
118
IndexMask::from_initializers
(
119
{0, 3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24, 25, 27, 30, 35, 40, 45, 50}, memory));
120
}
121
{
122
ExprBuilder
builder;
123
const
Expr
&expr = builder.
intersect
({&mask_3, &mask_5});
124
const
IndexMask
result =
evaluate_expression
(expr, memory);
125
EXPECT_EQ
(result,
IndexMask::from_initializers
({0, 15, 30}, memory));
126
}
127
{
128
ExprBuilder
builder;
129
const
Expr
&expr = builder.
subtract
(&mask_3, {&mask_5});
130
const
IndexMask
result =
evaluate_expression
(expr, memory);
131
EXPECT_EQ
(result,
IndexMask::from_initializers
({3, 6, 9, 12, 18, 21, 24, 27}, memory));
132
}
133
{
134
ExprBuilder
builder;
135
const
Expr
&expr = builder.
merge
(
136
{&builder.
intersect
({&mask_3, &mask_5}), &builder.
subtract
(&mask_3, {&mask_5})});
137
const
IndexMask
&result =
evaluate_expression
(expr, memory);
138
EXPECT_EQ
(result,
139
IndexMask::from_initializers
({0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30}, memory));
140
}
141
}
142
143
TEST
(index_mask_expression, UnionToFullRange)
144
{
145
IndexMaskMemory
memory;
146
const
IndexMask
mask_1 =
IndexMask::from_initializers
({2, 4, 5, 7}, memory);
147
const
IndexMask
mask_2 =
IndexMask::from_initializers
({6, 8}, memory);
148
const
IndexMask
mask_3 =
IndexMask::from_initializers
({1, 3}, memory);
149
150
ExprBuilder
builder;
151
const
Expr
&expr = builder.merge({&mask_1, &mask_2, &mask_3});
152
const
IndexMask
result =
evaluate_expression
(expr, memory);
153
EXPECT_TRUE(result.to_range().has_value());
154
EXPECT_EQ
(*result.to_range(),
IndexRange::from_begin_end_inclusive
(1, 8));
155
EXPECT_EQ
(result.segments_num(), 1);
156
}
157
158
TEST
(index_mask_expression, UnionIndividualIndices)
159
{
160
IndexMaskMemory
memory;
161
const
IndexMask
mask_1 =
IndexMask::from_initializers
({3}, memory);
162
const
IndexMask
mask_2 =
IndexMask::from_initializers
({6}, memory);
163
const
IndexMask
mask_3 =
IndexMask::from_initializers
({5}, memory);
164
165
ExprBuilder
builder;
166
const
Expr
&expr = builder.merge({&mask_1, &mask_2, &mask_3});
167
const
IndexMask
result =
evaluate_expression
(expr, memory);
168
EXPECT_EQ
(result,
IndexMask::from_initializers
({3, 5, 6}, memory));
169
EXPECT_EQ
(result.segments_num(), 1);
170
}
171
172
TEST
(index_mask_expression, UnionLargeRanges)
173
{
174
IndexMaskMemory
memory;
175
const
IndexMask
mask_a(
IndexRange
(0, 1'000'000));
176
const
IndexMask
mask_b(
IndexRange
(900'000, 1'100'000));
177
178
ExprBuilder
builder;
179
const
Expr
&expr = builder.
merge
({&mask_a, &mask_b});
180
const
IndexMask
result_mask =
evaluate_expression
(expr, memory);
181
182
EXPECT_EQ
(result_mask,
IndexMask
(
IndexRange
(0, 2'000'000)));
183
}
184
185
TEST
(index_mask_expression, SubtractSmall)
186
{
187
IndexMaskMemory
memory;
188
const
IndexMask
mask_a =
IndexMask::from_initializers
({3, 4, 5, 6, 7, 8, 9}, memory);
189
const
IndexMask
mask_b =
IndexMask::from_initializers
({5, 7}, memory);
190
const
IndexMask
mask_c =
IndexMask::from_initializers
({8}, memory);
191
192
ExprBuilder
builder;
193
const
Expr
&expr = builder.subtract(&mask_a, {&mask_b, &mask_c});
194
const
IndexMask
result =
evaluate_expression
(expr, memory);
195
196
EXPECT_EQ
(result,
IndexMask::from_initializers
({3, 4, 6, 9}, memory));
197
EXPECT_EQ
(result.segments_num(), 1);
198
}
199
200
TEST
(index_mask_expression, RangeTerms)
201
{
202
IndexMaskMemory
memory;
203
ExprBuilder
builder;
204
205
const
IndexRange
range_a =
IndexRange::from_begin_end
(30'000, 50'000);
206
const
IndexRange
range_b =
IndexRange::from_begin_end
(40'000, 100'000);
207
const
IndexRange
range_c =
IndexRange::from_begin_end
(45'000, 48'000);
208
209
const
Expr
&expr = builder.
subtract
(&builder.
merge
({range_a, range_b}), {range_c});
210
const
IndexMask
result_mask =
evaluate_expression
(expr, memory);
211
212
EXPECT_EQ
(result_mask,
213
IndexMask::from_initializers
({
IndexRange::from_begin_end
(30'000, 45'000),
214
IndexRange::from_begin_end
(48'000, 100'000)},
215
memory));
216
}
217
218
TEST
(index_mask_expression, SingleMask)
219
{
220
IndexMaskMemory
memory;
221
const
IndexMask
mask =
IndexMask::from_initializers
({5, 6, 8, 9}, memory);
222
223
ExprBuilder
builder;
224
const
Expr
&expr = builder.merge({&mask});
225
const
IndexMask
result =
evaluate_expression
(expr, memory);
226
227
EXPECT_EQ
(result, mask);
228
}
229
230
TEST
(index_mask_expression, SubtractSelf)
231
{
232
IndexMaskMemory
memory;
233
const
IndexMask
mask = IndexMask ::from_initializers({6, 8, 10, 100}, memory);
234
235
ExprBuilder
builder;
236
const
Expr
&expr = builder.subtract(&mask, {&mask});
237
const
IndexMask
result =
evaluate_expression
(expr, memory);
238
239
EXPECT_TRUE(result.is_empty());
240
}
241
242
/* Disable benchmark by default. */
243
#if 0
244
TEST
(index_mask_expression, Benchmark)
245
{
246
# ifdef NDEBUG
247
const
int64_t
iterations = 100;
248
# else
249
const
int64_t
iterations = 1;
250
# endif
251
252
for
([[maybe_unused]]
const
int64_t
_1 :
IndexRange
(5)) {
253
IndexMaskMemory
m;
254
const
IndexMask
a =
IndexMask::from_every_nth
(3, 1'000'000, 0, m);
255
const
IndexMask
b
=
IndexMask::from_every_nth
(100, 5'000, 0, m);
256
ExprBuilder
builder;
257
const
Expr
&expr = builder.
merge
({&a, &
b
});
258
259
SCOPED_TIMER
(
"benchmark"
);
260
for
([[maybe_unused]]
const
int64_t
_2 :
IndexRange
(iterations)) {
261
IndexMaskMemory
memory;
262
const
IndexMask
result =
evaluate_expression
(expr, memory);
263
UNUSED_VARS
(result);
264
}
265
}
266
}
267
#endif
268
269
}
// namespace blender::index_mask::tests
BLI_array.hh
EXPECT_EQ
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
BLI_index_mask_expression.hh
BLI_rand.hh
BLI_set.hh
BLI_strict_flags.h
BLI_timeit.hh
SCOPED_TIMER
#define SCOPED_TIMER(name)
Definition
BLI_timeit.hh:61
UNUSED_VARS
#define UNUSED_VARS(...)
Definition
BLI_utildefines.h:533
blender::IndexRange
Definition
BLI_index_range.hh:50
blender::IndexRange::from_begin_end
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
Definition
BLI_index_range.hh:74
blender::IndexRange::from_begin_end_inclusive
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
Definition
BLI_index_range.hh:79
blender::index_mask::ExprBuilder
Definition
BLI_index_mask_expression.hh:47
blender::index_mask::ExprBuilder::intersect
const IntersectionExpr & intersect(const Span< Term > terms)
Definition
index_mask_expression.cc:1331
blender::index_mask::ExprBuilder::merge
const UnionExpr & merge(const Span< Term > terms)
Definition
index_mask_expression.cc:1304
blender::index_mask::ExprBuilder::subtract
const DifferenceExpr & subtract(const Term &main_term, const Span< Term > subtract_terms)
Definition
index_mask_expression.cc:1317
blender::index_mask::IndexMaskMemory
Definition
BLI_index_mask.hh:108
blender::index_mask::IndexMask
Definition
BLI_index_mask.hh:184
blender::index_mask::IndexMask::from_every_nth
static IndexMask from_every_nth(int64_t n, int64_t indices_num, const int64_t initial_offset, IndexMaskMemory &memory)
Definition
index_mask.cc:1023
blender::index_mask::IndexMask::from_initializers
static IndexMask from_initializers(const Span< Initializer > initializers, IndexMaskMemory &memory)
Definition
index_mask.cc:672
b
local_group_size(16, 16) .push_constant(Type b
Definition
compositor_morphological_distance_info.hh:16
blender::index_mask::tests
Definition
BLI_index_mask_expression_test.cc:14
blender::index_mask::tests::TEST
TEST(index_mask_expression, Union)
Definition
BLI_index_mask_expression_test.cc:16
blender::index_mask::evaluate_expression
IndexMask evaluate_expression(const Expr &expression, IndexMaskMemory &memory)
Definition
index_mask_expression.cc:1287
int64_t
__int64 int64_t
Definition
stdint.h:89
Intersection
Definition
kernel/types.h:741
blender::index_mask::Expr
Definition
BLI_index_mask_expression.hh:17
Generated on Thu Feb 6 2025 07:36:39 for Blender by
doxygen
1.11.0