Newer
Older
/***************************************************************************
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
-------------------
begin : Oct 25, 2010
copyright : (C) 2010 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/* See Copyright Notice in tnl/Copyright */
// NOTE: Vector = Array + VectorOperations, so we test Vector and VectorOperations at the same time
#pragma once
#ifdef HAVE_GTEST
#include <limits>
#include <TNL/Experimental/Arithmetics/Quad.h>
#include <TNL/Containers/Vector.h>
#include <TNL/Containers/VectorView.h>
#include "VectorTestSetup.h"
#include "gtest/gtest.h"
using namespace TNL;
using namespace TNL::Containers;
using namespace TNL::Containers::Algorithms;
using namespace TNL::Arithmetics;
// should be small enough to have fast tests, but larger than minGPUReductionDataSize
// and large enough to require multiple CUDA blocks for reduction
constexpr int VECTOR_TEST_SIZE = 5000;
TYPED_TEST( VectorTest, addVector )
{
using VectorType = typename TestFixture::VectorType;
using VectorOperations = typename TestFixture::VectorOperations;
using ViewType = typename TestFixture::ViewType;
const int size = VECTOR_TEST_SIZE;
VectorType x, y;
x.setSize( size );
y.setSize( size );
ViewType x_view( x ), y_view( y );
typename VectorType::HostType expected1, expected2;
expected1.setSize( size );
expected2.setSize( size );
for( int i = 0; i < size; i++ ) {
expected1[ i ] = 2.0 + 3.0 * i;
expected2[ i ] = 1.0 + 3.0 * i;
}
setConstantSequence( x, 1 );
setLinearSequence( y );
VectorOperations::addVector( x, y, 3.0, 2.0 );
EXPECT_EQ( x, expected1 );
setConstantSequence( x, 1 );
setLinearSequence( y );
x.addVector( y, 3.0, 1.0 );
EXPECT_EQ( x, expected2 );
setConstantSequence( x, 1 );
setLinearSequence( y );
x_view.addVector( y_view, 3.0, 1.0 );
EXPECT_EQ( x, expected2 );
// multiplication by floating-point scalars which produces integer values
setConstantSequence( x, 2 );
setConstantSequence( y, 4 );
x.addVector( y, 2.5, -1.5 );
EXPECT_EQ( x.min(), 7 );
EXPECT_EQ( x.max(), 7 );
}
TYPED_TEST( VectorTest, addVectors )
{
using VectorType = typename TestFixture::VectorType;
using VectorOperations = typename TestFixture::VectorOperations;
using ViewType = typename TestFixture::ViewType;
const int size = VECTOR_TEST_SIZE;
VectorType x, y, z;
x.setSize( size );
y.setSize( size );
z.setSize( size );
ViewType x_view( x ), y_view( y ), z_view( z );
typename VectorType::HostType expected1, expected2;
expected1.setSize( size );
expected2.setSize( size );
for( int i = 0; i < size; i++ ) {
expected1[ i ] = 1.0 + 3.0 * i + 2.0;
expected2[ i ] = 2.0 + 3.0 * i + 2.0;
}
setConstantSequence( x, 1 );
setLinearSequence( y );
setConstantSequence( z, 2 );
VectorOperations::addVectors( x, y, 3.0, z, 1.0, 1.0 );
EXPECT_EQ( x, expected1 );
setConstantSequence( x, 1 );
setLinearSequence( y );
setConstantSequence( z, 2 );
x.addVectors( y, 3.0, z, 1.0, 2.0 );
EXPECT_EQ( x, expected2 );
setConstantSequence( x, 1 );
setLinearSequence( y );
setConstantSequence( z, 2 );
x_view.addVectors( y_view, 3.0, z_view, 1.0, 2.0 );
EXPECT_EQ( x, expected2 );
// multiplication by floating-point scalars which produces integer values
setConstantSequence( x, 2 );
setConstantSequence( y, 4 );
setConstantSequence( z, 6 );
x.addVectors( y, 2.5, z, -1.5, -1.5 );
EXPECT_EQ( x.min(), -2 );
EXPECT_EQ( x.max(), -2 );
}
TYPED_TEST( VectorTest, prefixSum )
{
using VectorType = typename TestFixture::VectorType;
using VectorOperations = typename TestFixture::VectorOperations;
using ViewType = typename TestFixture::ViewType;
using RealType = typename VectorType::RealType;
using DeviceType = typename VectorType::DeviceType;
using IndexType = typename VectorType::IndexType;
v.computePrefixSum();
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), 0 );
setLinearSequence( v );
v.computePrefixSum();
for( int i = 1; i < size; i++ )
EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
setConstantSequence( v, 1 );
v_view.computePrefixSum();
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), i + 1 );
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
v_view.computePrefixSum();
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), 0 );
setLinearSequence( v );
v_view.computePrefixSum();
for( int i = 1; i < size; i++ )
EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
}
TYPED_TEST( VectorTest, exclusivePrefixSum )
{
using VectorType = typename TestFixture::VectorType;
using VectorOperations = typename TestFixture::VectorOperations;
using ViewType = typename TestFixture::ViewType;
const int size = VECTOR_TEST_SIZE;
VectorType v;
v.setSize( size );
ViewType v_view( v );
setConstantSequence( v, 1 );
v.computeExclusivePrefixSum();
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), i );
v.setValue( 0 );
v.computeExclusivePrefixSum();
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), 0 );
setLinearSequence( v );
v.computeExclusivePrefixSum();
for( int i = 1; i < size; i++ )
EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 );
setConstantSequence( v, 1 );
v_view.computeExclusivePrefixSum();
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), i );
v.setValue( 0 );
v_view.computeExclusivePrefixSum();
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), 0 );
setLinearSequence( v );
v_view.computeExclusivePrefixSum();
for( int i = 1; i < size; i++ )
EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 );
}
template< typename FlagsView >
void setupFlags( FlagsView& f )
{
auto f1 = [] __cuda_callable__ ( typename FlagsView::IndexType i ) { return ( i % 5 ) == 0; };
f.evaluate( f1 );
}
TYPED_TEST( VectorTest, segmentedPrefixSum )
{
using VectorType = typename TestFixture::VectorType;
using ViewType = typename TestFixture::ViewType;
using RealType = typename VectorType::RealType;
using DeviceType = typename VectorType::DeviceType;
using IndexType = typename VectorType::IndexType;
using FlagsArrayType = Array< bool, DeviceType, IndexType >;
using FlagsViewType = ArrayView< bool, DeviceType, IndexType >;
const int size = VECTOR_TEST_SIZE;
VectorType v( size );
ViewType v_view( v );
FlagsArrayType flags( size ), flags_copy( size );
FlagsViewType flags_view( flags );
//auto f1 = [] __cuda_callable__ ( IndexType i ) { return ( i % 5 ) == 0; };
//flags_view.evaluate( f1 );
setupFlags( flags_view );
v = 0;
v.computeSegmentedPrefixSum( flags_view );
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), 0 );
flags_view = flags_copy;
v = 1;
v.computeSegmentedPrefixSum( flags_view );
for( int i = 0; i < size; i++ )
EXPECT_EQ( v.getElement( i ), ( i % 5 ) + 1 );
flags_view = flags_copy;
v.computeSegmentedPrefixSum( flags_view );
for( int i = 1; i < size; i++ )
{
if( flags.getElement( i ) )
EXPECT_EQ( v.getElement( i ), i );
else
EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
}
flags_view = flags_copy;
v_view = 0;
v_view.computeSegmentedPrefixSum( flags_view );
for( int i = 0; i < size; i++ )
EXPECT_EQ( v_view.getElement( i ), 0 );
flags_view = flags_copy;
v_view = 1;
v_view.computeSegmentedPrefixSum( flags_view );
for( int i = 0; i < size; i++ )
EXPECT_EQ( v_view.getElement( i ), ( i % 5 ) + 1 );
flags_view = flags_copy;
//v_view.evaluate( [] __cuda_callable__ ( IndexType i ) { return i; } );
setLinearSequence( v );
v_view.computeSegmentedPrefixSum( flags_view );
for( int i = 1; i < size; i++ )
{
if( flags.getElement( i ) )
EXPECT_EQ( v_view.getElement( i ), i );
else
EXPECT_EQ( v_view.getElement( i ) - v_view.getElement( i - 1 ), i );
}
TYPED_TEST( VectorTest, abs )
{
using VectorType = typename TestFixture::VectorType;
using ViewType = typename TestFixture::ViewType;
const int size = VECTOR_TEST_SIZE;
VectorType _u( size ), _v( size );
ViewType u( _u ), v( _v );
for( int i = 0; i < size; i++ )
u.setElement( i, i );
v = -u;
}
#endif // HAVE_GTEST
#include "../GtestMissingError.h"
int main( int argc, char* argv[] )
{
//Test();
//return 0;
#ifdef HAVE_GTEST
::testing::InitGoogleTest( &argc, argv );
return RUN_ALL_TESTS();
#else
throw GtestMissingError();
#endif
}