335 lines
8.4 KiB
C++
335 lines
8.4 KiB
C++
/*******************************************************************************
|
|
* Copyright (c) 2015-2018 Skymind, Inc.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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 raver119@gmail.com
|
|
//
|
|
|
|
#include <helpers/shape.h>
|
|
#include "testlayers.h"
|
|
#include <ops/declarable/headers/shape.h>
|
|
|
|
using namespace sd;
|
|
using namespace sd::graph;
|
|
|
|
class ShapeTests : public testing::Test {
|
|
public:
|
|
|
|
};
|
|
|
|
|
|
TEST_F(ShapeTests, Test_Basics_1) {
|
|
Nd4jLong shape[] = {2, 5, 3, 3, 1, 0, 1, 99};
|
|
|
|
ASSERT_EQ(2, shape::rank(shape));
|
|
ASSERT_EQ(1, shape::elementWiseStride(shape));
|
|
ASSERT_EQ(5, shape::sizeAt(shape, 0));
|
|
ASSERT_EQ(3, shape::sizeAt(shape, 1));
|
|
ASSERT_EQ('c', shape::order(shape));
|
|
}
|
|
|
|
|
|
TEST_F(ShapeTests, Test_Basics_2) {
|
|
Nd4jLong shape[] = {4, 2, 3, 4, 5, 60, 20, 5, 1, 0, -1, 102};
|
|
|
|
ASSERT_EQ(4, shape::rank(shape));
|
|
ASSERT_EQ(-1, shape::elementWiseStride(shape));
|
|
ASSERT_EQ(2, shape::sizeAt(shape, 0));
|
|
ASSERT_EQ(3, shape::sizeAt(shape, 1));
|
|
ASSERT_EQ(4, shape::sizeAt(shape, 2));
|
|
ASSERT_EQ(5, shape::sizeAt(shape, 3));
|
|
ASSERT_EQ('f', shape::order(shape));
|
|
}
|
|
|
|
|
|
TEST_F(ShapeTests, Test_tadLength_1) {
|
|
Nd4jLong shape[] = {4, 2, 3, 4, 5, 60, 20, 5, 1, 0, -1, 102};
|
|
int axis[] = {2, 3};
|
|
|
|
ASSERT_EQ(20, shape::tadLength(shape, axis, 2));
|
|
}
|
|
|
|
|
|
TEST_F(ShapeTests, Test_ShapeEquality_1) {
|
|
Nd4jLong shape[] = {4, 2, 3, 4, 5, 60, 20, 5, 1, 0, -1, 102};
|
|
Nd4jLong shape_GOOD[] = {4, 2, 3, 4, 5, 60, 20, 5, 1, 0, 1, 99};
|
|
Nd4jLong shape_BAD[] = {4, 3, 3, 4, 5, 60, 20, 5, 1, 0, -1, 102};
|
|
|
|
|
|
ASSERT_TRUE(shape::equalsSoft(shape, shape_GOOD));
|
|
ASSERT_FALSE(shape::equalsSoft(shape, shape_BAD));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_ShapeEquality_2) {
|
|
Nd4jLong shape[] = {4, 2, 3, 4, 5, 60, 20, 5, 1, 0, -1, 102};
|
|
Nd4jLong shape_GOOD[] = {4, 2, 3, 4, 5, 60, 20, 5, 1, 0, -1, 102};
|
|
Nd4jLong shape_BAD[] = {4, 2, 3, 4, 5, 60, 20, 5, 1, 0, -1, 99};
|
|
|
|
|
|
ASSERT_TRUE(shape::equalsStrict(shape, shape_GOOD));
|
|
ASSERT_FALSE(shape::equalsStrict(shape, shape_BAD));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Ind2SubC_1) {
|
|
Nd4jLong shape[] = {3, 5};
|
|
Nd4jLong c0[2];
|
|
shape::index2coords(0, 2, shape, c0);
|
|
|
|
ASSERT_EQ(0, c0[0]);
|
|
ASSERT_EQ(0, c0[1]);
|
|
|
|
Nd4jLong c1[2];
|
|
shape::index2coords(1, 2, shape, c1);
|
|
|
|
ASSERT_EQ(0, c1[0]);
|
|
ASSERT_EQ(1, c1[1]);
|
|
|
|
Nd4jLong c6[2];
|
|
shape::index2coords(5, 2, shape, c6);
|
|
|
|
ASSERT_EQ(1, c6[0]);
|
|
ASSERT_EQ(0, c6[1]);
|
|
}
|
|
|
|
|
|
TEST_F(ShapeTests, Test_ShapeDetector_1) {
|
|
Nd4jLong shape[] = {2, 5, 3, 3, 1, 0, 1, 99};
|
|
|
|
ASSERT_TRUE(shape::isMatrix(shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_ShapeDetector_2) {
|
|
Nd4jLong shape[] = {3, 2, 5, 3, 15, 3, 1, 0, 1, 99};
|
|
|
|
ASSERT_FALSE(shape::isMatrix(shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_ShapeDetector_3) {
|
|
Nd4jLong shape[] = {2, 1, 3, 3, 1, 0, 1, 99};
|
|
|
|
ASSERT_FALSE(shape::isColumnVector(shape));
|
|
ASSERT_TRUE(shape::isVector(shape));
|
|
ASSERT_TRUE(shape::isRowVector(shape));
|
|
ASSERT_FALSE(shape::isMatrix(shape));
|
|
}
|
|
|
|
|
|
TEST_F(ShapeTests, Test_ShapeDetector_4) {
|
|
Nd4jLong shape[] = {2, 3, 1, 1, 1, 0, 1, 99};
|
|
|
|
ASSERT_TRUE(shape::isColumnVector(shape));
|
|
ASSERT_TRUE(shape::isVector(shape));
|
|
ASSERT_FALSE(shape::isRowVector(shape));
|
|
ASSERT_FALSE(shape::isMatrix(shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_ShapeDetector_5) {
|
|
Nd4jLong shape[] = {2, 1, 1, 1, 1, 0, 1, 99};
|
|
|
|
ASSERT_TRUE(shape::isScalar(shape));
|
|
ASSERT_FALSE(shape::isMatrix(shape));
|
|
|
|
// edge case here. Technicaly it's still a vector with length of 1
|
|
ASSERT_TRUE(shape::isVector(shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_ShapeDetector_6) {
|
|
Nd4jLong shape[] = {2, 1, 1, 1, 1, 0, 1, 99};
|
|
|
|
ASSERT_EQ(8, shape::shapeInfoLength(shape));
|
|
ASSERT_EQ(64, shape::shapeInfoByteLength(shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_ShapeDetector_7) {
|
|
Nd4jLong shape[] = {3, 1, 1, 1, 1, 1, 1, 0, 1, 99};
|
|
|
|
ASSERT_EQ(10, shape::shapeInfoLength(shape));
|
|
ASSERT_EQ(80, shape::shapeInfoByteLength(shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Transpose_1) {
|
|
Nd4jLong shape[] = {3, 2, 5, 3, 15, 3, 1, 0, 1, 99};
|
|
Nd4jLong exp[] = {3, 3, 5, 2, 1, 3, 15, 0, 1, 102};
|
|
|
|
shape::transposeInplace(shape);
|
|
|
|
ASSERT_TRUE(shape::equalsStrict(exp, shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Transpose_2) {
|
|
Nd4jLong shape[] = {2, 5, 3, 3, 1, 0, 1, 99};
|
|
Nd4jLong exp[] = {2, 3, 5, 1, 3, 0, 1, 102};
|
|
|
|
shape::transposeInplace(shape);
|
|
|
|
ASSERT_TRUE(shape::equalsStrict(exp, shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Transpose_3) {
|
|
Nd4jLong shape[] = {2, 1, 3, 3, 1, 0, 1, 99};
|
|
Nd4jLong exp[] = {2, 3, 1, 1, 3, 0, 1, 102};
|
|
|
|
shape::transposeInplace(shape);
|
|
|
|
ASSERT_TRUE(shape::equalsStrict(exp, shape));
|
|
}
|
|
|
|
|
|
TEST_F(ShapeTests, Test_Transpose_4) {
|
|
Nd4jLong shape[] = {4, 2, 3, 4, 5, 5, 4, 3, 2, 0, 1, 99};
|
|
Nd4jLong exp[] = {4, 5, 4, 3, 2, 2, 3, 4, 5, 0, 1, 102};
|
|
|
|
shape::transposeInplace(shape);
|
|
|
|
ASSERT_TRUE(shape::equalsStrict(exp, shape));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Edge_1) {
|
|
auto x = NDArrayFactory::create<float>('f', {1, 4, 1, 4});
|
|
x.linspace(1);
|
|
|
|
x.reshapei('c', {4, 4});
|
|
|
|
//x.printShapeInfo("reshape0");
|
|
//x.printIndexedBuffer("x i");
|
|
//x.printBuffer("x r");
|
|
|
|
x.reshapei({4, 1, 1, 4});
|
|
|
|
//x.printShapeInfo("reshape1");
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Edge_2) {
|
|
auto x = NDArrayFactory::create<float>('c', {1, 4, 1, 3});
|
|
|
|
x.reshapei('c', {3, 4});
|
|
|
|
//x.printShapeInfo("reshape0");
|
|
|
|
x.reshapei({3, 1, 1, 4});
|
|
|
|
//x.printShapeInfo("reshape1");
|
|
}
|
|
|
|
|
|
TEST_F(ShapeTests, Test_Remove_Index_1) {
|
|
int array[] = {1, 2, 3};
|
|
int idx[] = {0};
|
|
int result[2];
|
|
shape::removeIndex(array, idx, 3, 1, result);
|
|
|
|
ASSERT_EQ(2, result[0]);
|
|
ASSERT_EQ(3, result[1]);
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Remove_Index_2) {
|
|
int array[] = {1, 2, 3};
|
|
int idx[] = {1};
|
|
int result[2];
|
|
shape::removeIndex(array, idx, 3, 1, result);
|
|
|
|
ASSERT_EQ(1, result[0]);
|
|
ASSERT_EQ(3, result[1]);
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Remove_Index_3) {
|
|
int array[] = {1, 2, 3};
|
|
int idx[] = {2};
|
|
int result[2];
|
|
shape::removeIndex(array, idx, 3, 1, result);
|
|
|
|
ASSERT_EQ(1, result[0]);
|
|
ASSERT_EQ(2, result[1]);
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Remove_Index_4) {
|
|
int array[] = {1, 2, 3};
|
|
int idx[] = {0, 2};
|
|
int result[1];
|
|
shape::removeIndex(array, idx, 3, 2, result);
|
|
|
|
ASSERT_EQ(2, result[0]);
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Remove_Index_5) {
|
|
int array[] = {1, 2, 3};
|
|
int idx[] = {1, 0};
|
|
int result[1];
|
|
shape::removeIndex(array, idx, 3, 2, result);
|
|
|
|
ASSERT_EQ(3, result[0]);
|
|
}
|
|
|
|
TEST_F(ShapeTests, Test_Remove_Index_6) {
|
|
int array[] = {1, 2, 3};
|
|
int idx[] = {1, 2};
|
|
int result[1];
|
|
shape::removeIndex(array, idx, 3, 2, result);
|
|
|
|
ASSERT_EQ(1, result[0]);
|
|
}
|
|
|
|
TEST_F(ShapeTests, Tests_Transpose_119_1) {
|
|
auto x = NDArrayFactory::create<float>('c', {3, 2});
|
|
auto y = NDArrayFactory::create<float>('c', {2}, {1.0f, 0.0f});
|
|
auto z = NDArrayFactory::create<float>('c', {2, 3});
|
|
|
|
x.linspace(1.f);
|
|
|
|
auto e = x.permute({1, 0});
|
|
e.streamline('c');
|
|
|
|
sd::ops::transpose op;
|
|
auto result = op.execute({&x, &y}, {&z}, {}, {}, {});
|
|
|
|
ASSERT_EQ(Status::OK(), result);
|
|
ASSERT_TRUE(e.isSameShape(z));
|
|
ASSERT_TRUE(e.equalsTo(z));
|
|
}
|
|
|
|
TEST_F(ShapeTests, Tests_Transpose_119_2) {
|
|
auto x = NDArrayFactory::create<float>('c', {3, 5});
|
|
x.linspace(1.f);
|
|
|
|
auto exp = x.transpose();
|
|
|
|
sd::ops::transpose op;
|
|
auto result = op.evaluate({&x});
|
|
ASSERT_EQ(Status::OK(), result->status());
|
|
|
|
auto z = result->at(0);
|
|
|
|
ASSERT_TRUE(exp.isSameShape(z));
|
|
ASSERT_TRUE(exp.equalsTo(z));
|
|
|
|
delete result;
|
|
}
|
|
|
|
TEST_F(ShapeTests, Tests_Transpose_119_3) {
|
|
auto x = NDArrayFactory::create<float>('c', {3, 5});
|
|
x.linspace(1.f);
|
|
|
|
auto z = NDArrayFactory::create<float>('c', {5, 3});
|
|
|
|
auto exp = x.transpose();
|
|
|
|
sd::ops::transpose op;
|
|
auto result = op.execute({&x}, {&z}, {}, {}, {});
|
|
ASSERT_EQ(Status::OK(), result);
|
|
|
|
ASSERT_TRUE(exp.isSameShape(z));
|
|
ASSERT_TRUE(exp.equalsTo(z));
|
|
} |