Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Test / Source / Tests / Test_3x3transposeTimes.cpp
1 //
2 //  Test_3x3transposeTimes.cpp
3 //  BulletTest
4 //
5 //  Copyright (c) 2011 Apple Inc.
6 //
7
8
9 #include "LinearMath/btScalar.h"
10 #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
11
12
13 #include "Test_3x3transposeTimes.h"
14 #include "vector.h"
15 #include "Utils.h"
16 #include "main.h"
17 #include <math.h>
18 #include <string.h>
19
20 #include <LinearMath/btMatrix3x3.h>
21
22 #define LOOPCOUNT 1000
23 #define ARRAY_SIZE 128
24
25 static inline btSimdFloat4 rand_f4(void)
26 {
27     return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN );      // w channel NaN
28 }
29
30 static btMatrix3x3 TransposeTimesReference( const btMatrix3x3 &in, const btMatrix3x3 &m )
31 {
32     btVector3 m_el[3] = { in[0], in[1], in[2] };
33     btSimdFloat4 r0 = btAssign128(m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
34                             m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
35                             m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
36                             0.0f );
37     btSimdFloat4 r1 = btAssign128(   m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
38                             m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
39                             m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
40                             0.0f );
41     btSimdFloat4 r2 = btAssign128(   m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
42                             m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
43                             m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z(),
44                             0.0f );
45     return btMatrix3x3( r0, r1, r2 );
46 }
47
48 static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b )
49 {
50     if( a.getRow(0) != b.getRow(0) )
51         return 1;
52     if( a.getRow(1) != b.getRow(1) )
53         return 1;
54     if( a.getRow(2) != b.getRow(2) )
55         return 1;
56     return 0;
57 }
58
59 int Test_3x3transposeTimes(void)
60 {
61     // Init an array flanked by guard pages
62     btMatrix3x3 in1[ARRAY_SIZE];
63     btMatrix3x3 in2[ARRAY_SIZE];
64     btMatrix3x3 out[ARRAY_SIZE];
65     btMatrix3x3 out2[ARRAY_SIZE];
66     
67         float maxRelativeError = 0.f;
68     // Init the data
69     size_t i, j;
70     for( i = 0; i < ARRAY_SIZE; i++ )
71     {
72         in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );   
73         in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );   
74         
75         out[i] = TransposeTimesReference(in1[i], in2[i]);
76         out2[i] = in1[i].transposeTimes(in2[i]);
77         
78         if( out[i] != out2[i] )
79         {
80
81                         float relativeError = 0.f;
82
83                         for (int column=0;column<3;column++)
84                         for (int row=0;row<3;row++)
85                                 relativeError = btMax(relativeError,btFabs(out2[i][row][column] - out[i][row][column]) / out[i][row][column]);
86
87                         if (relativeError>1e-6)
88                         {
89                                 vlog( "failure @ %ld\n", i);
90                                 btVector3 m0, m1, m2;
91                                 m0 = out[i].getRow(0);
92                                 m1 = out[i].getRow(1);
93                                 m2 = out[i].getRow(2);
94             
95                                 vlog(   "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
96                                                 "\n          (%10.4f, %10.4f, %10.4f, %10.4f) "
97                                                 "\n          (%10.4f, %10.4f, %10.4f, %10.4f) \n",
98                                                 m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], 
99                                                 m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
100                                                 m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); 
101
102                                 m0 = out2[i].getRow(0);
103                                 m1 = out2[i].getRow(1);
104                                 m2 = out2[i].getRow(2);
105                                         
106                                 vlog(   "\ntested  = (%10.4f, %10.4f, %10.4f, %10.4f) "
107                                                 "\n          (%10.4f, %10.4f, %10.4f, %10.4f) " 
108                                                 "\n          (%10.4f, %10.4f, %10.4f, %10.4f) \n", 
109                                                 m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], 
110                                                 m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
111                                                 m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); 
112
113                                 return -1;
114                         } else
115                         {
116                                 if (relativeError>maxRelativeError)
117                                         maxRelativeError = relativeError;
118                         }
119         }
120     }
121     
122         if (maxRelativeError)
123         {
124                 printf("Warning: maxRelativeError = %e\n",maxRelativeError);
125         }
126     uint64_t scalarTime, vectorTime;
127     uint64_t startTime, bestTime, currentTime;
128     bestTime = -1LL;
129     scalarTime = 0;
130     for (j = 0; j < LOOPCOUNT; j++) {
131         startTime = ReadTicks();
132         for( i = 0; i < ARRAY_SIZE; i++ )
133             out[i] = TransposeTimesReference(in1[i], in2[i]);
134         currentTime = ReadTicks() - startTime;
135         scalarTime += currentTime;
136         if( currentTime < bestTime )
137             bestTime = currentTime;
138     }
139     if( 0 == gReportAverageTimes )
140         scalarTime = bestTime;        
141     else
142         scalarTime /= LOOPCOUNT;
143     
144     bestTime = -1LL;
145     vectorTime = 0;
146     for (j = 0; j < LOOPCOUNT; j++) {
147         startTime = ReadTicks();
148         for( i = 0; i < ARRAY_SIZE; i++ )
149             out[i] = in1[i].transposeTimes(in2[i]);
150         currentTime = ReadTicks() - startTime;
151         vectorTime += currentTime;
152         if( currentTime < bestTime )
153             bestTime = currentTime;
154     }
155     if( 0 == gReportAverageTimes )
156         vectorTime = bestTime;        
157     else
158         vectorTime /= LOOPCOUNT;
159     
160     vlog( "Timing:\n" );
161     vlog( "\t    scalar\t    vector\n" );
162     vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
163     
164     return 0;
165 }
166
167 #endif //BT_USE_SSE
168