Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/api/c/rank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,32 @@
#include <qr.hpp>
#include <reduce.hpp>
#include <logic.hpp>
#include <complex.hpp>

using af::dim4;
using namespace detail;

template<typename T>
static inline uint rank(const af_array in, double tol)
{
typedef typename af::dtype_traits<T>::base_type BT;
Array<T> In = getArray<T>(in);

Array<T> r = createEmptyArray<T>(dim4());
Array<BT> R = createEmptyArray<BT>(dim4());

// Scoping to get rid of q and t as they are not necessary
// Scoping to get rid of q, r and t as they are not necessary
{
Array<T> q = createEmptyArray<T>(dim4());
Array<T> r = createEmptyArray<T>(dim4());
Array<T> t = createEmptyArray<T>(dim4());
qr(q, r, t, In);

R = abs<BT, T>(r);
}

Array<T> val = createValueArray<T>(r.dims(), scalar<T>(tol));
Array<char> gt = logicOp<T, af_gt_t>(r, val, val.dims());
Array<BT> val = createValueArray<BT>(R.dims(), scalar<BT>(tol));
Array<char> gt = logicOp<BT, af_gt_t>(R, val, val.dims());
Array<char> at = reduce<af_or_t, char, char>(gt, 1);

return reduce_all<af_notzero_t, char, uint>(at);
}

Expand Down
2 changes: 1 addition & 1 deletion src/api/c/unary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ af_err af_not(af_array *out, const af_array in)
in_info.ndims(),
in_info.dims().get(), in_info.getType()));

AF_CHECK(af_neq(out, in, tmp, false));
AF_CHECK(af_eq(out, in, tmp, false));

AF_CHECK(af_release_array(tmp));
} CATCHALL;
Expand Down
3 changes: 1 addition & 2 deletions src/api/cpp/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,8 +919,7 @@ namespace af
{
af_array lhs = this->get();
af_array out;
array cst = constant(0, this->dims(), this->type());
AF_THROW(af_eq(&out, cst.get(), lhs, gforGet()));
AF_THROW(af_not(&out, lhs));
return array(out);
}

Expand Down
7 changes: 6 additions & 1 deletion src/backend/cpu/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,14 @@ Array<T> randn(const af::dim4 &dims)

if (my_seed != gen_seed) {
gen = nrand<T>(generator);
my_seed = gen_seed;
}

Array<T> outArray = createEmptyArray<T>(dims);
T *outPtr = outArray.get();
generate(outPtr, outPtr + outArray.elements(), gen);
for (int i = 0; i < (int)outArray.elements(); i++) {
outPtr[i] = gen();
}
return outArray;
}

Expand All @@ -107,6 +110,7 @@ Array<T> randu(const af::dim4 &dims)

if (my_seed != gen_seed) {
gen = urand<T>(generator);
my_seed = gen_seed;
}

Array<T> outArray = createEmptyArray<T>(dims);
Expand Down Expand Up @@ -152,6 +156,7 @@ Array<char> randu(const af::dim4 &dims)

if (my_seed != gen_seed) {
gen = urand<float>(generator);
my_seed = gen_seed;
}

Array<char> outArray = createEmptyArray<char>(dims);
Expand Down
9 changes: 7 additions & 2 deletions src/backend/opencl/kernel/random.cl
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,13 @@ void generate(T *one, T *two, threefry2_ctr_t *c, threefry2_key_t k)
T u1 = result(r.v[0]);
T u2 = result(r.v[1]);

T R = sqrt(-2*log(u1));
T Theta = 2 * PI_VAL * u2;
#if defined(IS_APPLE) // Because Apple is.. "special"
T R = sqrt((T)(-2.0) * log10(u1) * (T)log10_val);
#else
T R = sqrt((T)(-2.0) * log(u1));
#endif

T Theta = 2 * (T)PI_VAL * u2;

*one = R * sin(Theta);
*two = R * cos(Theta);
Expand Down
4 changes: 4 additions & 0 deletions src/backend/opencl/kernel/random.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ namespace opencl
std::ostringstream options;
options << " -D T=" << dtype_traits<T>::getName()
<< " -D repeat="<< REPEAT
#if defined(OS_MAC) // Because apple is "special"
<< " -D IS_APPLE"
<< " -D log10_val=" << std::log(10.0)
#endif
<< " -D " << random_name<T, isRandu>().name();

if (std::is_same<T, double>::value) {
Expand Down
4 changes: 2 additions & 2 deletions test/fft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ TEST(ifft2, Invalid_Array)

af::dim4 dims(100,1,1,1);
ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &(in.front()),
dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<cfloat>::af_type));
dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<float>::af_type));

ASSERT_EQ(AF_ERR_SIZE, af_ifft2(&outArray, inArray, 0.01, 0, 0));
ASSERT_EQ(AF_SUCCESS, af_release_array(inArray));
Expand All @@ -98,7 +98,7 @@ TEST(ifft3, Invalid_Array)

af::dim4 dims(10,10,1,1);
ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &(in.front()),
dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<cfloat>::af_type));
dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<float>::af_type));

ASSERT_EQ(AF_ERR_SIZE, af_ifft3(&outArray, inArray, 0.01, 0, 0, 0));
ASSERT_EQ(AF_SUCCESS, af_release_array(inArray));
Expand Down
15 changes: 15 additions & 0 deletions test/math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,18 @@ MATH_TESTS_DOUBLE(log2)
MATH_TESTS_LIMITS(double, double, abs, dbl_err, -10, 10)
MATH_TESTS_LIMITS(double, double, ceil, dbl_err, -10, 10)
MATH_TESTS_LIMITS(double, double, floor, dbl_err, -10, 10)

TEST(MathTests, Not)
{
af::array a = af::randu(5, 5, b8);
af::array b = !a;
char *ha = a.host<char>();
char *hb = b.host<char>();

for(int i = 0; i < a.elements(); i++) {
ASSERT_EQ(ha[i] ^ hb[i], true);
}

delete[] ha;
delete[] hb;
}
19 changes: 17 additions & 2 deletions test/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ void testSetSeed(const uintl seed0, const uintl seed1, bool is_norm = false)

if (noDoubleTests<T>()) return;

uintl orig_seed = af::getSeed();

const int num = 1024 * 1024;
af::dtype ty = (af::dtype)af::dtype_traits<T>::af_type;

Expand All @@ -162,23 +164,32 @@ void testSetSeed(const uintl seed0, const uintl seed1, bool is_norm = false)

af::setSeed(seed0);
af::array in2 = is_norm ? af::randn(num, ty) : af::randu(num, ty);
af::array in3 = is_norm ? af::randn(num, ty) : af::randu(num, ty);

std::vector<T> h_in0(num);
std::vector<T> h_in1(num);
std::vector<T> h_in2(num);
std::vector<T> h_in3(num);

in0.host((void *)&h_in0[0]);
in1.host((void *)&h_in1[0]);
in2.host((void *)&h_in2[0]);
in3.host((void *)&h_in3[0]);

for (int i = 0; i < num; i++) {
// Verify if same seed produces same arrays
ASSERT_EQ(h_in0[i], h_in2[i]);

// Verify different arrays don't clash at same location
// Verify different arrays created with different seeds differ
// b8 and u9 can clash because they generate a small set of values
if (ty != b8 && ty != u8) ASSERT_NE(h_in0[i], h_in1[i]);

// Verify different arrays created one after the other with same seed differ
// b8 and u9 can clash because they generate a small set of values
if (ty != b8 && ty != u8) ASSERT_NE(h_in2[i], h_in3[i]);
}

af::setSeed(orig_seed); // Reset the seed
}

TYPED_TEST(Random, setSeed)
Expand All @@ -188,14 +199,16 @@ TYPED_TEST(Random, setSeed)

TYPED_TEST(Random_norm, setSeed)
{
testSetSeed<TypeParam>(456, 789, false);
testSetSeed<TypeParam>(456, 789, true);
}

template<typename T>
void testGetSeed(const uintl seed0, const uintl seed1)
{
if (noDoubleTests<T>()) return;

uintl orig_seed = af::getSeed();

const int num = 1024;
af::dtype ty = (af::dtype)af::dtype_traits<T>::af_type;

Expand All @@ -210,6 +223,8 @@ void testGetSeed(const uintl seed0, const uintl seed1)
af::setSeed(seed0);
af::array in2 = af::randu(num, ty);
ASSERT_EQ(af::getSeed(), seed0);

af::setSeed(orig_seed); // Reset the seed
}

TYPED_TEST(Random, getSeed)
Expand Down
88 changes: 88 additions & 0 deletions test/rank_dense.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*******************************************************
* 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 <gtest/gtest.h>
#include <arrayfire.h>
#include <af/dim4.hpp>
#include <af/defines.h>
#include <af/traits.hpp>
#include <vector>
#include <iostream>
#include <complex>
#include <string>
#include <testHelpers.hpp>

using std::vector;
using std::string;
using std::cout;
using std::endl;
using af::cfloat;
using af::cdouble;

template<typename T>
class Rank : public ::testing::Test
{
};

typedef ::testing::Types<float, double, af::cfloat, af::cdouble> TestTypes;
TYPED_TEST_CASE(Rank, TestTypes);

template<typename T>
void rankSmall()
{
if (noDoubleTests<T>()) return;

T ha[] = {1, 4, 7, 2, 5, 8, 3, 6, 20};
af::array a(3, 3, ha);

ASSERT_EQ(3, (int)af::rank(a));
}

template<typename T>
void rankBig(const int num)
{
if (noDoubleTests<T>()) return;
af::dtype dt = (af::dtype)af::dtype_traits<T>::af_type;
af::array a = af::randu(num, num, dt);
ASSERT_EQ(num, (int)af::rank(a));

af::array b = af::randu(num, num/2, dt);
ASSERT_EQ(num/2, (int)af::rank(b));
ASSERT_EQ(num/2, (int)af::rank(transpose(b)));
}

template<typename T>
void rankLow(const int num)
{
if (noDoubleTests<T>()) return;
af::dtype dt = (af::dtype)af::dtype_traits<T>::af_type;

af::array a = af::randu(3 * num, num, dt);
af::array b = af::randu(3 * num, num, dt);
af::array c = a + 0.2 * b;
af::array in = join(1, a, b, c);

// The last third is just a linear combination of first and second thirds
ASSERT_EQ(2 * num, (int)af::rank(in));
}

TYPED_TEST(Rank, small)
{
rankSmall<TypeParam>();
}

TYPED_TEST(Rank, big)
{
rankBig<TypeParam>(1024);
}

TYPED_TEST(Rank, low)
{
rankBig<TypeParam>(512);
}