/* ****************************************************************************** * * * 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 #include using namespace sd; class LoopCoordsHelper : public testing::Test { public: }; template FORCEINLINE typename std::enable_if<(Rank - 1 == rankIndex), bool>::type eq_strides(CoordsState& cbs, const Nd4jLong* strides) { return STRIDE(cbs, rankIndex) == strides[rankIndex]; } template FORCEINLINE typename std::enable_if<(Rank - 1 != rankIndex), bool>::type eq_strides(CoordsState& cbs, const Nd4jLong* strides) { return STRIDE(cbs, rankIndex) == strides[rankIndex] && eq_strides(cbs, strides); } template FORCEINLINE typename std::enable_if<(Rank - 1 == rankIndex), bool>::type eq_zip_strides(ZipCoordsState& cbs, const Nd4jLong* strides1, const Nd4jLong* strides2) { return ZIP_STRIDE1(cbs, rankIndex) == strides1[rankIndex] && ZIP_STRIDE2(cbs, rankIndex) == strides2[rankIndex]; } template FORCEINLINE typename std::enable_if<(Rank - 1 != rankIndex), bool>::type eq_zip_strides(ZipCoordsState& cbs, const Nd4jLong* strides1, const Nd4jLong* strides2) { return ZIP_STRIDE1(cbs, rankIndex) == strides1[rankIndex] && ZIP_STRIDE2(cbs, rankIndex) == strides2[rankIndex] && eq_zip_strides(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 cts; CoordsState cts_f; ZipCoordsState zcts; ZipCoordsState zcts_f; size_t offset = init_coords(cts, test_Index, shape, strides_c); size_t offset_f = init_coords(cts_f, test_Index, shape, strides_f); zip_size_t zoffset = init_coords(zcts, test_Index, shape, strides_c, strides_c); zip_size_t zoffset_f = init_coords(zcts_f, test_Index, shape, strides_f, strides_f); ASSERT_TRUE(eq_coords(cts, coords)); ASSERT_TRUE(eq_coords(cts_f, coords_f)); ASSERT_TRUE(eq_zip_coords(zcts, coords)); ASSERT_TRUE(eq_zip_coords(zcts_f, coords_f)); ASSERT_TRUE(eq_strides(cts,strides_c)); ASSERT_TRUE(eq_strides(cts_f,strides_f)); ASSERT_TRUE(eq_zip_strides(zcts, strides_c, strides_c)); ASSERT_TRUE(eq_zip_strides(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 cts; CoordsState cts_f; ZipCoordsState zcts; ZipCoordsState zcts_f; size_t offset = init_coords(cts, 0, shape, strides_c); size_t offset_f = init_coords(cts_f, 0, shape, strides_f); zip_size_t zoffset = init_coords(zcts, 0, shape, strides_c, strides_c); zip_size_t zoffset_f = init_coords(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(cts, coords)); ASSERT_TRUE(eq_coords(cts_f, coords_f)); ASSERT_TRUE(eq_zip_coords(zcts, coords)); ASSERT_TRUE(eq_zip_coords(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(cts, offset); offset_f = inc_coords(cts_f, offset_f); zoffset = inc_coords(zcts, zoffset); zoffset_f = inc_coords(zcts_f, zoffset_f); offset2 = inc_coords(shape,strides_c, coords2, offset2, Rank); offset2_f = inc_coords(shape, strides_f, coords2_f, offset2_f, Rank); zoffset2 = inc_coords(shape, strides_c, strides_c, zcoords2, zoffset2, Rank); zoffset2_f = inc_coords(shape, strides_f, strides_f, zcoords2_f, zoffset2_f, Rank); } }