/*******************************************************
* Copyright (c) 2014, ArrayFire
* All rights reserved.
*
* This file is distributed under 3-clause BSD license.
* The complete license agreement can be obtained at:
* http://arrayfire.com/licenses/BSD-3-Clause
********************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using af::cdouble;
using af::cfloat;
using af::dim4;
using af::dtype_traits;
using std::cout;
using std::endl;
using std::ostream_iterator;
using std::string;
using std::vector;
template
void checkValues(const af_seq &seq, const T *data, const T *indexed_data,
OP compair_op) {
for (int i = 0, j = seq.begin; compair_op(j, (int)seq.end);
j += seq.step, i++) {
ASSERT_DOUBLE_EQ(real(data[j]), real(indexed_data[i]))
reverse_reverse_seq,
TEST_DIR "/index/ReverseReverse.test", 2);
}
TYPED_TEST(Indexing2D, ReverseStrided) {
DimCheck2D(this->reverse_strided_seq,
TEST_DIR "/index/ReverseStrided.test", 2);
}
TYPED_TEST(Indexing2D, ReverseStridedReverse) {
DimCheck2D(this->reverse_strided_reverse_seq,
TEST_DIR "/index/ReverseStridedReverse.test", 2);
}
TYPED_TEST(Indexing2D, StridedContinious) {
DimCheck2D(this->strided_continuous_seq,
TEST_DIR "/index/StridedContinious.test", 2);
}
TYPED_TEST(Indexing2D, StridedStrided) {
DimCheck2D(this->strided_strided_seq,
TEST_DIR "/index/StridedStrided.test", 2);
}
vector make_vec(af_seq first, af_seq second) {
vector out;
out.push_back(first);
out.push_back(second);
return out;
}
template
class Indexing : public ::testing::Test {
vector make_vec3(af_seq first, af_seq second, af_seq third) {
vector out;
out.push_back(first);
out.push_back(second);
out.push_back(third);
return out;
}
vector make_vec4(af_seq first, af_seq second, af_seq third,
af_seq fourth) {
vector out;
out.push_back(first);
out.push_back(second);
out.push_back(third);
out.push_back(fourth);
return out;
}
public:
virtual void SetUp() {
continuous3d_to_3d.push_back(
make_vec3(af_make_seq(0, 4, 1), af_make_seq(0, 6, 1), af_span));
continuous3d_to_3d.push_back(
make_vec3(af_make_seq(4, 8, 1), af_make_seq(4, 9, 1), af_span));
continuous3d_to_3d.push_back(
make_vec3(af_make_seq(6, 9, 1), af_make_seq(3, 8, 1), af_span));
continuous3d_to_2d.push_back(
make_vec3(af_span, af_make_seq(0, 6, 1), af_make_seq(0, 0, 1)));
continuous3d_to_2d.push_back(
make_vec3(af_span, af_make_seq(4, 9, 1), af_make_seq(1, 1, 1)));
continuous3d_to_2d.push_back(
make_vec3(af_span, af_make_seq(3, 8, 1), af_make_seq(0, 0, 1)));
continuous3d_to_1d.push_back(
make_vec3(af_span, af_make_seq(0, 0, 1), af_make_seq(0, 0, 1)));
continuous3d_to_1d.push_back(
make_vec3(af_span, af_make_seq(6, 6, 1), af_make_seq(1, 1, 1)));
continuous3d_to_1d.push_back(
make_vec3(af_span, af_make_seq(9, 9, 1), af_make_seq(0, 0, 1)));
continuous4d_to_4d.push_back(make_vec4(
af_make_seq(2, 6, 1), af_make_seq(2, 6, 1), af_span, af_span));
continuous4d_to_3d.push_back(make_vec4(af_make_seq(2, 6, 1),
af_make_seq(2, 6, 1), af_span,
af_make_seq(0, 0, 1)));
continuous4d_to_2d.push_back(
make_vec4(af_make_seq(2, 6, 1), af_make_seq(2, 6, 1),
af_make_seq(0, 0, 1), af_make_seq(0, 0, 1)));
continuous4d_to_1d.push_back(
make_vec4(af_make_seq(2, 6, 1), af_make_seq(2, 2, 1),
af_make_seq(0, 0, 1), af_make_seq(0, 0, 1)));
}
vector continuous3d_to_3d;
vector continuous3d_to_2d;
vector continuous3d_to_1d;
vector continuous4d_to_4d;
vector continuous4d_to_3d;
vector continuous4d_to_2d;
vector continuous4d_to_1d;
};
template
void DimCheckND(const vector &seqs, string TestFile,
size_t NDims) {
SUPPORTED_TYPE_CHECK(T);
// DimCheck2D function is generalized enough
// to check 3d and 4d indexing
DimCheck2D(seqs, TestFile, NDims);
}
TYPED_TEST_SUITE(Indexing, AllTypes);
TYPED_TEST(Indexing, 4D_to_4D) {
DimCheckND(this->continuous4d_to_4d,
TEST_DIR "/index/Continuous4Dto4D.test", 4);
}
TYPED_TEST(Indexing, 4D_to_3D) {
DimCheckND(this->continuous4d_to_3d,
TEST_DIR "/index/Continuous4Dto3D.test", 4);
}
TYPED_TEST(Indexing, 4D_to_2D) {
DimCheckND(this->continuous4d_to_2d,
TEST_DIR "/index/Continuous4Dto2D.test", 4);
}
TYPED_TEST(Indexing, 4D_to_1D) {
DimCheckND(this->continuous4d_to_1d,
TEST_DIR "/index/Continuous4Dto1D.test", 4);
}
TYPED_TEST(Indexing, 3D_to_3D) {
DimCheckND(this->continuous3d_to_3d,
TEST_DIR "/index/Continuous3Dto3D.test", 3);
}
TYPED_TEST(Indexing, 3D_to_2D) {
DimCheckND(this->continuous3d_to_2d,
TEST_DIR "/index/Continuous3Dto2D.test", 3);
}
TYPED_TEST(Indexing, 3D_to_1D) {
DimCheckND(this->continuous3d_to_1d,
TEST_DIR "/index/Continuous3Dto1D.test", 3);
}
TEST(Index, Docs_Util_C_API) {
// clang-format off
ASSERT_EQ(0, ([]() -> int {
//![ex_index_util_0]
af_index_t *indexers = 0;
af_err err = af_create_indexers(&indexers); // Memory is allocated on heap by the callee
// by default all the indexers span all the elements along
// the given dimension
// Create array
af_array a;
unsigned ndims = 2;
dim_t dim[] = {10, 10};
af_randu(&a, ndims, dim, f32);
// Create index array
af_array idx;
unsigned n = 1;
dim_t d[] = {5};
af_range(&idx, n, d, 0, s32);
af_print_array(a);
af_print_array(idx);
// create array indexer
err = af_set_array_indexer(indexers, idx, 1);
// index with indexers
af_array out;
err = af_index_gen(&out, a, 2, indexers); // number of indexers should be two since
// we have set only second af_index_t
if (err != AF_SUCCESS) {
printf("Failed in af_index_gen: %d\n", err);
return 1;
}
af_print_array(out);
af_release_array(out);
af_seq zeroIndices = af_make_seq(0.0, 9.0, 2.0);
err = af_set_seq_indexer(indexers, &zeroIndices, 0, false);
err = af_index_gen(&out, a, 2, indexers);
if (err != AF_SUCCESS) {
printf("Failed in af_index_gen: %d\n", err);
return 1;
}
af_print_array(out);
af_release_indexers(indexers);
af_release_array(a);
af_release_array(idx);
af_release_array(out);
return 0;
//![ex_index_util_0]
}()));
// clang-format on
}
//////////////////////////////// CPP ////////////////////////////////
using af::allTrue;
using af::array;
using af::constant;
using af::deviceGC;
using af::deviceMemInfo;
using af::end;
using af::freeHost;
using af::randu;
using af::range;
using af::reorder;
using af::seq;
using af::span;
using af::where;
TEST(Indexing2D, ColumnContiniousCPP) {
vector seqs;
seqs.push_back(make_vec(af_span, af_make_seq(0, 6, 1)));
// seqs.push_back(make_vec(span, af_make_seq( 4, 9, 1)));
// seqs.push_back(make_vec(span, af_make_seq( 3, 8, 1)));
vector numDims;
vector hData;
vector tests;
readTests(TEST_DIR "/index/ColumnContinious.test",
numDims, hData, tests);
dim4 dimensions = numDims[0];
array a(dimensions, &(hData[0].front()));
vector sub;
for (size_t i = 0; i < seqs.size(); i++) {
vector seq = seqs[i];
sub.push_back(a(seq[0], seq[1]));
}
for (size_t i = 0; i < seqs.size(); i++) {
dim_t elems = sub[i].elements();
float *ptr = new float[elems];
sub[i].host(ptr);
if (false == equal(ptr, ptr + tests[i].size(), tests[i].begin())) {
cout