226 lines
7.5 KiB
C++
226 lines
7.5 KiB
C++
/* ******************************************************************************
|
|
*
|
|
*
|
|
* This program and the accompanying materials are made available under the
|
|
* terms of the Apache License, Version 2.0 which is available at
|
|
* https://www.apache.org/licenses/LICENSE-2.0.
|
|
*
|
|
* See the NOTICE file distributed with this work for additional
|
|
* information regarding copyright ownership.
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
******************************************************************************/
|
|
|
|
//
|
|
// @author Abdelrauf
|
|
//
|
|
|
|
#include "testlayers.h"
|
|
#include <helpers/LoopsCoordsHelper.h>
|
|
#include <type_traits>
|
|
using namespace sd;
|
|
|
|
class LoopCoordsHelper : public testing::Test {
|
|
public:
|
|
|
|
};
|
|
|
|
|
|
template<size_t Rank, size_t rankIndex = 0, bool Last_Index_Faster = true>
|
|
FORCEINLINE
|
|
typename std::enable_if<(Rank - 1 == rankIndex), bool>::type
|
|
eq_strides(CoordsState<Rank - 1>& cbs, const Nd4jLong* strides) {
|
|
return STRIDE(cbs, rankIndex) == strides[rankIndex];
|
|
}
|
|
|
|
template<size_t Rank, size_t rankIndex = 0>
|
|
FORCEINLINE
|
|
typename std::enable_if<(Rank - 1 != rankIndex), bool>::type
|
|
eq_strides(CoordsState<Rank - 1>& cbs, const Nd4jLong* strides) {
|
|
return STRIDE(cbs, rankIndex) == strides[rankIndex] && eq_strides<Rank, rankIndex + 1>(cbs, strides);
|
|
}
|
|
|
|
template<size_t Rank, size_t rankIndex = 0, bool Last_Index_Faster = true>
|
|
FORCEINLINE
|
|
typename std::enable_if<(Rank - 1 == rankIndex), bool>::type
|
|
eq_zip_strides(ZipCoordsState<Rank - 1>& cbs, const Nd4jLong* strides1, const Nd4jLong* strides2) {
|
|
return ZIP_STRIDE1(cbs, rankIndex) == strides1[rankIndex] && ZIP_STRIDE2(cbs, rankIndex) == strides2[rankIndex];
|
|
}
|
|
|
|
template<size_t Rank, size_t rankIndex = 0>
|
|
FORCEINLINE
|
|
typename std::enable_if<(Rank - 1 != rankIndex), bool>::type
|
|
eq_zip_strides(ZipCoordsState<Rank - 1>& cbs, const Nd4jLong* strides1, const Nd4jLong* strides2) {
|
|
return ZIP_STRIDE1(cbs, rankIndex) == strides1[rankIndex] && ZIP_STRIDE2(cbs, rankIndex) == strides2[rankIndex]
|
|
&& eq_zip_strides<Rank, rankIndex + 1>(cbs, strides1, strides2);
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(LoopCoordsHelper, Init_Tests) {
|
|
|
|
constexpr size_t test_Index = 131;
|
|
constexpr size_t Rank = 5;
|
|
|
|
Nd4jLong shape[Rank] = { 3, 5 ,7, 8, 9};
|
|
Nd4jLong multiply_st[] = { 2,3,3,5,6,7,9,3 };
|
|
Nd4jLong strides_c[Rank] ;
|
|
Nd4jLong strides_f[Rank];
|
|
|
|
Nd4jLong coords[Rank];
|
|
Nd4jLong coords_f[Rank];
|
|
|
|
strides_f[0] = multiply_st[0] * shape[0];
|
|
strides_c[Rank-1] = multiply_st[Rank-1] * shape[Rank-1];
|
|
|
|
for (int i = 1; i < Rank; i++) {
|
|
strides_f[i] = strides_f[i - 1] * multiply_st[i] * shape[i];
|
|
}
|
|
|
|
for (int i = Rank-2; i >=0; i--) {
|
|
strides_c[i] = strides_c[i+1] * multiply_st[i] * shape[i];
|
|
}
|
|
|
|
//init our base coords
|
|
index2coords_C(test_Index, Rank, shape, coords);
|
|
index2coords_F(test_Index, Rank, shape, coords_f);
|
|
|
|
|
|
size_t offset_calc = offset_from_coords(strides_c, coords, Rank);
|
|
size_t offset_calc_f = offset_from_coords(strides_f, coords_f, Rank);
|
|
|
|
CoordsState<Rank-1> cts;
|
|
CoordsState<Rank-1> cts_f;
|
|
|
|
ZipCoordsState<Rank-1> zcts;
|
|
ZipCoordsState<Rank-1> zcts_f;
|
|
|
|
size_t offset = init_coords<Rank>(cts, test_Index, shape, strides_c);
|
|
size_t offset_f = init_coords<Rank,0,false>(cts_f, test_Index, shape, strides_f);
|
|
|
|
zip_size_t zoffset = init_coords<Rank>(zcts, test_Index, shape, strides_c, strides_c);
|
|
zip_size_t zoffset_f = init_coords<Rank, 0, false>(zcts_f, test_Index, shape, strides_f, strides_f);
|
|
|
|
ASSERT_TRUE(eq_coords<Rank>(cts, coords));
|
|
ASSERT_TRUE(eq_coords<Rank>(cts_f, coords_f));
|
|
|
|
ASSERT_TRUE(eq_zip_coords<Rank>(zcts, coords));
|
|
ASSERT_TRUE(eq_zip_coords<Rank>(zcts_f, coords_f));
|
|
|
|
ASSERT_TRUE(eq_strides<Rank>(cts,strides_c));
|
|
ASSERT_TRUE(eq_strides<Rank>(cts_f,strides_f));
|
|
|
|
ASSERT_TRUE(eq_zip_strides<Rank>(zcts, strides_c, strides_c));
|
|
ASSERT_TRUE(eq_zip_strides<Rank>(zcts_f, strides_f, strides_f));
|
|
|
|
|
|
ASSERT_EQ(offset , offset_calc);
|
|
ASSERT_EQ(zoffset.first , offset_calc);
|
|
ASSERT_EQ(zoffset.second , offset_calc);
|
|
ASSERT_EQ(offset_f , offset_calc_f);
|
|
ASSERT_EQ(zoffset_f.first , offset_calc_f);
|
|
ASSERT_EQ(zoffset_f.second , offset_calc_f);
|
|
}
|
|
|
|
TEST_F(LoopCoordsHelper, Increment_Use_Tests) {
|
|
|
|
|
|
constexpr size_t Rank = 4;
|
|
|
|
Nd4jLong shape[Rank] = { 3, 5 ,7, 8 };
|
|
Nd4jLong multiply_st[] = { 2,3,3,5,6,7,9,3 };
|
|
Nd4jLong strides_c[Rank];
|
|
Nd4jLong strides_f[Rank];
|
|
|
|
Nd4jLong coords[Rank] = {};
|
|
Nd4jLong coords_f[Rank] = {};
|
|
Nd4jLong coords2[Rank] = {};
|
|
Nd4jLong coords2_f[Rank] = {};
|
|
Nd4jLong zcoords2[Rank] = {};
|
|
Nd4jLong zcoords2_f[Rank] = {};
|
|
|
|
strides_f[0] = multiply_st[0] * shape[0];
|
|
strides_c[Rank - 1] = multiply_st[Rank - 1] * shape[Rank - 1];
|
|
|
|
for (int i = 1; i < Rank; i++) {
|
|
strides_f[i] = strides_f[i - 1] * multiply_st[i] * shape[i];
|
|
}
|
|
|
|
for (int i = Rank - 2; i >= 0; i--) {
|
|
strides_c[i] = strides_c[i + 1] * multiply_st[i] * shape[i];
|
|
}
|
|
|
|
int total = 1;
|
|
for (int i = 0; i < Rank; i++) {
|
|
total *= shape[i];
|
|
}
|
|
|
|
CoordsState<Rank - 1> cts;
|
|
CoordsState<Rank - 1> cts_f;
|
|
|
|
ZipCoordsState<Rank - 1> zcts;
|
|
ZipCoordsState<Rank - 1> zcts_f;
|
|
|
|
size_t offset = init_coords<Rank>(cts, 0, shape, strides_c);
|
|
size_t offset_f = init_coords<Rank, 0, false>(cts_f, 0, shape, strides_f);
|
|
|
|
zip_size_t zoffset = init_coords<Rank>(zcts, 0, shape, strides_c, strides_c);
|
|
zip_size_t zoffset_f = init_coords<Rank, 0, false>(zcts_f, 0, shape, strides_f, strides_f);
|
|
|
|
size_t offset2 = 0;
|
|
size_t offset2_f = 0;
|
|
zip_size_t zoffset2 = {};
|
|
zip_size_t zoffset2_f = {};
|
|
|
|
for (int j = 0; j < total; j++) {
|
|
|
|
|
|
index2coords_C(j, Rank, shape, coords);
|
|
index2coords_F(j, Rank, shape, coords_f);
|
|
|
|
size_t offset_calc = offset_from_coords(strides_c, coords, Rank);
|
|
size_t offset_calc_f = offset_from_coords(strides_f, coords_f, Rank);
|
|
|
|
|
|
ASSERT_TRUE(eq_coords<Rank>(cts, coords));
|
|
ASSERT_TRUE(eq_coords<Rank>(cts_f, coords_f));
|
|
|
|
ASSERT_TRUE(eq_zip_coords<Rank>(zcts, coords));
|
|
ASSERT_TRUE(eq_zip_coords<Rank>(zcts_f, coords_f));
|
|
|
|
ASSERT_EQ(offset, offset_calc);
|
|
ASSERT_EQ(zoffset.first, offset_calc);
|
|
ASSERT_EQ(zoffset.second, offset_calc);
|
|
ASSERT_EQ(offset_f, offset_calc_f);
|
|
ASSERT_EQ(zoffset_f.first, offset_calc_f);
|
|
ASSERT_EQ(zoffset_f.second, offset_calc_f);
|
|
|
|
|
|
ASSERT_EQ(offset2, offset_calc);
|
|
ASSERT_EQ(zoffset2.first, offset_calc);
|
|
ASSERT_EQ(zoffset2.second, offset_calc);
|
|
ASSERT_EQ(offset2_f, offset_calc_f);
|
|
ASSERT_EQ(zoffset2_f.first, offset_calc_f);
|
|
ASSERT_EQ(zoffset2_f.second, offset_calc_f);
|
|
|
|
offset = inc_coords<Rank>(cts, offset);
|
|
offset_f = inc_coords<Rank,0,false>(cts_f, offset_f);
|
|
zoffset = inc_coords<Rank>(zcts, zoffset);
|
|
zoffset_f = inc_coords<Rank, 0, false>(zcts_f, zoffset_f);
|
|
|
|
offset2 = inc_coords(shape,strides_c, coords2, offset2, Rank);
|
|
offset2_f = inc_coords<false>(shape, strides_f, coords2_f, offset2_f, Rank);
|
|
zoffset2 = inc_coords(shape, strides_c, strides_c, zcoords2, zoffset2, Rank);
|
|
zoffset2_f = inc_coords<false>(shape, strides_f, strides_f, zcoords2_f, zoffset2_f, Rank);
|
|
|
|
}
|
|
|
|
}
|
|
|