Home | History | Annotate | Download | only in xla
      1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
      2 
      3 Licensed under the Apache License, Version 2.0 (the "License");
      4 you may not use this file except in compliance with the License.
      5 You may obtain a copy of the License at
      6 
      7     http://www.apache.org/licenses/LICENSE-2.0
      8 
      9 Unless required by applicable law or agreed to in writing, software
     10 distributed under the License is distributed on an "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 See the License for the specific language governing permissions and
     13 limitations under the License.
     14 ==============================================================================*/
     15 
     16 #include "tensorflow/compiler/xla/array4d.h"
     17 
     18 #include <initializer_list>
     19 #include <numeric>
     20 
     21 #include "absl/types/span.h"
     22 #include "tensorflow/compiler/xla/test.h"
     23 
     24 namespace xla {
     25 namespace {
     26 
     27 // Given an Array4D and a 4-tuple index, computes the linear index into the
     28 // array idx represents.
     29 template <typename T>
     30 int64 Array4DLinearIndex(const Array4D<T>& arr, absl::Span<const int64> idx) {
     31   EXPECT_EQ(4, idx.size());
     32   return (idx[3] + idx[2] * arr.n4() + idx[1] * arr.n3() * arr.n4() +
     33           idx[0] * arr.n2() * arr.n3() * arr.n4());
     34 }
     35 
     36 TEST(Array4dTest, UninitializedDimsCtor) {
     37   Array4D<int> empty(2, 3, 4, 5);
     38   EXPECT_EQ(empty.n1(), 2);
     39   EXPECT_EQ(empty.n2(), 3);
     40   EXPECT_EQ(empty.n3(), 4);
     41   EXPECT_EQ(empty.n4(), 5);
     42   EXPECT_EQ(empty.num_elements(), 120);
     43 }
     44 
     45 TEST(Array4dTest, FillCtor) {
     46   Array4D<int> fullof7(2, 3, 4, 5, 7);
     47 
     48   EXPECT_EQ(fullof7.n1(), 2);
     49   EXPECT_EQ(fullof7.n2(), 3);
     50   EXPECT_EQ(fullof7.n3(), 4);
     51   EXPECT_EQ(fullof7.n4(), 5);
     52 
     53   fullof7.Each(
     54       [](absl::Span<const int64> idx, int* cell) { EXPECT_EQ(*cell, 7); });
     55 }
     56 
     57 TEST(Array4dTest, ContainerCtor) {
     58   // Fill an Array4D with a linear vector of [0..119] according to the default
     59   // row-major ordering.
     60   std::vector<int> filler(120);
     61   std::iota(filler.begin(), filler.end(), 0);
     62 
     63   Array4D<int> arr(2, 3, 4, 5, filler);
     64 
     65   EXPECT_EQ(arr.n1(), 2);
     66   EXPECT_EQ(arr.n2(), 3);
     67   EXPECT_EQ(arr.n3(), 4);
     68   EXPECT_EQ(arr.n4(), 5);
     69 
     70   arr.Each([&arr](absl::Span<const int64> idx, int* cell) {
     71     EXPECT_EQ(*cell, Array4DLinearIndex(arr, idx));
     72   });
     73 }
     74 
     75 TEST(Array3dTest, InitializerListCtor) {
     76   Array4D<int> arr = {{{{1}, {2}}, {{3}, {4}}, {{5}, {6}}, {{7}, {8}}},
     77                       {{{9}, {10}}, {{11}, {12}}, {{13}, {14}}, {{15}, {16}}},
     78                       {{{17}, {18}}, {{19}, {20}}, {{21}, {22}}, {{23}, {24}}}};
     79 
     80   EXPECT_EQ(arr.n1(), 3);
     81   EXPECT_EQ(arr.n2(), 4);
     82   EXPECT_EQ(arr.n3(), 2);
     83   EXPECT_EQ(arr.n4(), 1);
     84   EXPECT_EQ(arr.num_elements(), 24);
     85 
     86   EXPECT_EQ(arr(0, 0, 0, 0), 1);
     87   EXPECT_EQ(arr(0, 0, 1, 0), 2);
     88   EXPECT_EQ(arr(0, 1, 0, 0), 3);
     89   EXPECT_EQ(arr(0, 3, 1, 0), 8);
     90   EXPECT_EQ(arr(1, 0, 0, 0), 9);
     91   EXPECT_EQ(arr(1, 1, 1, 0), 12);
     92   EXPECT_EQ(arr(2, 0, 0, 0), 17);
     93   EXPECT_EQ(arr(2, 1, 1, 0), 20);
     94   EXPECT_EQ(arr(2, 2, 0, 0), 21);
     95   EXPECT_EQ(arr(2, 3, 1, 0), 24);
     96 }
     97 
     98 TEST(Array3dTest, InitializerListCtorHalf) {
     99   Array4D<Eigen::half> arr = {
    100       {{{1.0f}, {2.0f}}, {{3.0f}, {4.0f}}, {{5.0f}, {6.0f}}, {{7.0f}, {8.0f}}},
    101       {{{9.0f}, {10.0f}},
    102        {{11.0f}, {12.0f}},
    103        {{13.0f}, {14.0f}},
    104        {{15.0f}, {16.0f}}},
    105       {{{17.0f}, {18.0f}},
    106        {{19.0f}, {20.0f}},
    107        {{21.0f}, {22.0f}},
    108        {{23.0f}, {24.0f}}}};
    109 
    110   EXPECT_EQ(arr.n1(), 3);
    111   EXPECT_EQ(arr.n2(), 4);
    112   EXPECT_EQ(arr.n3(), 2);
    113   EXPECT_EQ(arr.n4(), 1);
    114   EXPECT_EQ(arr.num_elements(), 24);
    115 
    116   EXPECT_EQ(arr(0, 0, 0, 0), static_cast<Eigen::half>(1));
    117   EXPECT_EQ(arr(0, 0, 1, 0), static_cast<Eigen::half>(2));
    118   EXPECT_EQ(arr(0, 1, 0, 0), static_cast<Eigen::half>(3));
    119   EXPECT_EQ(arr(0, 3, 1, 0), static_cast<Eigen::half>(8));
    120   EXPECT_EQ(arr(1, 0, 0, 0), static_cast<Eigen::half>(9));
    121   EXPECT_EQ(arr(1, 1, 1, 0), static_cast<Eigen::half>(12));
    122   EXPECT_EQ(arr(2, 0, 0, 0), static_cast<Eigen::half>(17));
    123   EXPECT_EQ(arr(2, 1, 1, 0), static_cast<Eigen::half>(20));
    124   EXPECT_EQ(arr(2, 2, 0, 0), static_cast<Eigen::half>(21));
    125   EXPECT_EQ(arr(2, 3, 1, 0), static_cast<Eigen::half>(24));
    126 }
    127 
    128 TEST(Array4dTest, Fill) {
    129   Array4D<int> fullof7(2, 3, 4, 5, 7);
    130   fullof7.Each(
    131       [](absl::Span<const int64> idx, int* cell) { EXPECT_EQ(*cell, 7); });
    132 
    133   fullof7.Fill(11);
    134   fullof7.Each(
    135       [](absl::Span<const int64> idx, int* cell) { EXPECT_EQ(*cell, 11); });
    136 }
    137 
    138 TEST(Array4dTest, FillWithMultiples) {
    139   Array4D<float> arr(2, 3, 4, 5);
    140   arr.FillWithMultiples(2.0f);
    141 
    142   arr.Each([&arr](absl::Span<const int64> idx, float* cell) {
    143     EXPECT_EQ(*cell, 2.0f * Array4DLinearIndex(arr, idx));
    144   });
    145 }
    146 
    147 TEST(Array4dTest, FillRasterDimensionDepthOne) {
    148   Array4D<float> array(1, 1, 128, 128);
    149   Array2D<float> raster(128, 128);
    150   for (int row = 0; row < 128; ++row) {
    151     for (int col = 0; col < 128; ++col) {
    152       raster(row, col) = row * 1000.0 + col;
    153     }
    154   }
    155 
    156   array.FillWithYX(raster);
    157 
    158   VLOG(1) << array.ToString();
    159 
    160   EXPECT_FLOAT_EQ(raster(0, 0), array(0, 0, 0, 0));
    161   EXPECT_FLOAT_EQ(raster(0, 1), array(0, 0, 0, 1));
    162   EXPECT_FLOAT_EQ(raster(1, 0), array(0, 0, 1, 0));
    163   EXPECT_FLOAT_EQ(raster(1, 1), array(0, 0, 1, 1));
    164   EXPECT_FLOAT_EQ(raster(2, 0), array(0, 0, 2, 0));
    165   EXPECT_FLOAT_EQ(raster(127, 127), array(0, 0, 127, 127));
    166 
    167   EXPECT_FLOAT_EQ(0, array(0, 0, 0, 0));
    168   EXPECT_FLOAT_EQ(1, array(0, 0, 0, 1));
    169   EXPECT_FLOAT_EQ(2, array(0, 0, 0, 2));
    170 
    171   EXPECT_FLOAT_EQ(1001, array(0, 0, 1, 1));
    172   EXPECT_FLOAT_EQ(2001, array(0, 0, 2, 1));
    173   EXPECT_FLOAT_EQ(127000, array(0, 0, 127, 0));
    174   EXPECT_FLOAT_EQ(127127, array(0, 0, 127, 127));
    175 }
    176 
    177 TEST(Array4dTest, FillWithPzTestDepthOne) {
    178   Array2D<float> matrix(3, 2);
    179   std::initializer_list<std::initializer_list<float>> values = {
    180       {-3.f, -0.1f}, {0.f, -0.1f}, {3.f, 0.2f},
    181   };
    182   int rowno = 0;
    183   for (auto row : values) {
    184     int colno = 0;
    185     for (float f : row) {
    186       matrix(rowno, colno) = f;
    187       colno++;
    188     }
    189     rowno++;
    190   }
    191 
    192   Array4D<float> actual(3, 2, 1, 1);
    193   actual.FillWithPZ(matrix);
    194 
    195   EXPECT_FLOAT_EQ(-3, actual(0, 0, 0, 0));
    196   EXPECT_FLOAT_EQ(-0.1, actual(0, 1, 0, 0));
    197 
    198   EXPECT_FLOAT_EQ(0, actual(1, 0, 0, 0));
    199   EXPECT_FLOAT_EQ(-0.1, actual(1, 1, 0, 0));
    200 
    201   EXPECT_FLOAT_EQ(3, actual(2, 0, 0, 0));
    202   EXPECT_FLOAT_EQ(0.2, actual(2, 1, 0, 0));
    203 }
    204 
    205 }  // namespace
    206 }  // namespace xla
    207