1 #ifndef __TEST_XY_FILTER_0B6AC4E9_AA51_4EF9_B255_90792DC07DB9_H__
2 #define __TEST_XY_FILTER_0B6AC4E9_AA51_4EF9_B255_90792DC07DB9_H__
4 #include <gtest/gtest.h>
10 void xy_filter_one_line_c(float *dst
, int width
, const float *filter
, int filter_width
);
11 void xy_filter_sse(float *dst
, int width
, int height
, int stride
, const float *filter
, int filter_width
);
12 void xy_filter_one_line_sse(float *dst
, int width
, const float *filter
, int filter_width
)
14 xy_filter_sse(dst
, width
, 1, ((width
*4)+15)&~15, filter
, filter_width
);
16 void xy_filter_one_line_sse_v6(float *dst
, int width
, const float *filter
, int filter_width
);
19 std::ostream
& GetBufString(std::ostream
& os
, T
* buf
, int len
)
21 for (int i
=0;i
<len
;i
++)
28 // Usable AlmostEqual function
30 bool AlmostEqual2sComplement(float A
, float B
, int maxUlps
)
33 // Make sure maxUlps is non-negative and small enough that the
35 // default NAN won't compare as equal to anything.
37 assert(maxUlps
> 0 && maxUlps
< 4 * 1024 * 1024);
41 // Make aInt lexicographically ordered as a twos-complement int
45 aInt
= 0x80000000 - aInt
;
47 // Make bInt lexicographically ordered as a twos-complement int
52 bInt
= 0x80000000 - bInt
;
54 int intDiff
= abs(aInt
- bInt
);
56 if (intDiff
<= maxUlps
)
63 class XyFilterTestData
66 static const int MAX_FILTER_LENGTH
= 256;
67 static const int MAX_DATA_BUFF_SIZE
= 512*512;
68 static const int MAX_BUFF_SIZE
= MAX_DATA_BUFF_SIZE
+ 2*MAX_FILTER_LENGTH
;
79 XyFilterTestData():buff_base(NULL
),filter_f(NULL
),data(NULL
)
81 buff_base
= (float*)xy_malloc(MAX_BUFF_SIZE
*sizeof(float));
82 data
= buff_base
+ MAX_FILTER_LENGTH
;
83 filter_f
= data
+ MAX_DATA_BUFF_SIZE
;
87 xy_free(buff_base
);buff_base
=NULL
;
90 const XyFilterTestData
& copy (const XyFilterTestData
& rhs
)
95 filter_width
= rhs
.filter_width
;
96 ex_filter_width
= rhs
.ex_filter_width
;
98 memcpy(buff_base
, rhs
.buff_base
, MAX_BUFF_SIZE
*sizeof(float));
101 bool operator== (const XyFilterTestData
& rhs
) const
103 for (int i
=0;i
<MAX_BUFF_SIZE
;i
++)
105 if (!AlmostEqual2sComplement(buff_base
[i
], rhs
.buff_base
[i
],8))
107 std::cerr
<<"Not almost equal at: "<<i
+buff_base
-data
108 <<" lhs:"<<buff_base
[i
]
109 <<" rhs:"<<rhs
.buff_base
[i
]
117 void FillRandData(int w
, int h
, int filter_width
)
121 this->filter_width
= filter_width
;
122 this->ex_filter_width
= ((filter_width
+3)&~3);
123 this->pitch
= ((w
+ex_filter_width
+3)&~3)*sizeof(float);
125 ASSERT(this->pitch
*this->h
<= MAX_DATA_BUFF_SIZE
);
127 for (int i
=0;i
<h
;i
++)
129 float *data2
= (float*)((PUINT8
)data
+ i
*pitch
);
130 for (int j
=0;j
<w
+filter_width
;j
++)
132 data2
[j
] = rand()&0xFF;
136 for (int i
=0;i
<filter_width
/2+1;i
++)
138 filter_f
[i
] = abs((rand()&0xFFFFF)+0xFFFFF);
141 for (int i
=filter_width
/2+1;i
<filter_width
;i
++)
143 filter_f
[i
] = filter_f
[filter_width
-i
-1];
146 for (int i
=0;i
<filter_width
;i
++)
150 for (int i
=filter_width
;i
<ex_filter_width
;i
++)
156 XyFilterTestData(const XyFilterTestData
&);
157 const XyFilterTestData
& operator= (const XyFilterTestData
& rhs
);
160 std::ostream
& operator<<( std::ostream
& os
, const XyFilterTestData
& data
)
162 os
<<"filter:"<<std::endl
;
163 GetBufString
<const float>(os
, data
.filter_f
, data
.filter_width
)<<" | ";
164 GetBufString
<const float>(os
, data
.filter_f
+data
.filter_width
, data
.ex_filter_width
- data
.filter_width
)<<std::endl
;
165 os
<<"data:"<<std::endl
;
166 GetBufString
<const float>(os
, data
.data
-data
.ex_filter_width
, data
.ex_filter_width
)<<" | ";
167 GetBufString
<const float>(os
, data
.data
, data
.w
-data
.ex_filter_width
)<<" | ";
168 GetBufString
<const float>(os
, data
.data
+data
.w
-data
.ex_filter_width
, data
.ex_filter_width
)<<std::endl
;
173 class XyFilterTest
: public ::testing::Test
176 XyFilterTestData data0
, data1
, data2
;
183 #define LOG_VAR(x) " "#x" "<<x<<" "
185 TEST_F(XyFilterTest
, c_vs_sse
)
188 for(int WIDTH
=4;WIDTH
<256;WIDTH
+=4)
189 for (int FILTER_WIDTH
=3;FILTER_WIDTH
<32;FILTER_WIDTH
++)
191 for(int i
=0;i
<LOOP_NUM
;i
++)
193 data0
.FillRandData(WIDTH
, 1, FILTER_WIDTH
);
196 xy_filter_one_line_c(data1
.data
, data1
.w
, data1
.filter_f
, data1
.ex_filter_width
);
197 xy_filter_one_line_sse_v6(data2
.data
, data2
.w
, data2
.filter_f
, data2
.ex_filter_width
);
198 ASSERT_EQ(true, data2
.operator==(data1
))
199 <<LOG_VAR(i
)<<LOG_VAR(WIDTH
)<<LOG_VAR(FILTER_WIDTH
)<<std::endl
208 TEST_F(XyFilterTest
, sse_vs_sse_v6
)
211 for(int WIDTH
=4;WIDTH
<256;WIDTH
+=4)
212 for (int FILTER_WIDTH
=3;FILTER_WIDTH
<32;FILTER_WIDTH
++)
214 for(int i
=0;i
<LOOP_NUM
;i
++)
216 data0
.FillRandData(WIDTH
, 1, FILTER_WIDTH
);
219 xy_filter_one_line_sse(data1
.data
, data1
.w
, data1
.filter_f
, data1
.ex_filter_width
);
220 xy_filter_one_line_sse_v6(data2
.data
, data2
.w
, data2
.filter_f
, data2
.ex_filter_width
);
221 ASSERT_EQ(true, data2
.operator==(data1
))
222 <<LOG_VAR(i
)<<LOG_VAR(WIDTH
)<<LOG_VAR(FILTER_WIDTH
)<<std::endl
230 #endif // __TEST_XY_FILTER_0B6AC4E9_AA51_4EF9_B255_90792DC07DB9_H__