From 8253205dea182f5674d01872fda5d737a614bfe8 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 13:29:15 -0400 Subject: [PATCH 1/9] BUGFIX/TEST: Fixing bug in rank. Added appropriate tests --- src/api/c/rank.cpp | 14 +++++--- test/rank.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 test/rank.cpp diff --git a/src/api/c/rank.cpp b/src/api/c/rank.cpp index c1eeb737d4..197d2c8974 100644 --- a/src/api/c/rank.cpp +++ b/src/api/c/rank.cpp @@ -17,6 +17,7 @@ #include #include #include +#include using af::dim4; using namespace detail; @@ -24,21 +25,24 @@ using namespace detail; template static inline uint rank(const af_array in, double tol) { + typedef typename af::dtype_traits::base_type BT; Array In = getArray(in); - Array r = createEmptyArray(dim4()); + Array R = createEmptyArray(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 q = createEmptyArray(dim4()); + Array r = createEmptyArray(dim4()); Array t = createEmptyArray(dim4()); qr(q, r, t, In); + + R = abs(r); } - Array val = createValueArray(r.dims(), scalar(tol)); - Array gt = logicOp(r, val, val.dims()); + Array val = createValueArray(R.dims(), scalar(tol)); + Array gt = logicOp(R, val, val.dims()); Array at = reduce(gt, 1); - return reduce_all(at); } diff --git a/test/rank.cpp b/test/rank.cpp new file mode 100644 index 0000000000..3ecf49784c --- /dev/null +++ b/test/rank.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using std::cout; +using std::endl; +using af::cfloat; +using af::cdouble; + +template +class Rank : public ::testing::Test +{ +}; + +typedef ::testing::Types TestTypes; +TYPED_TEST_CASE(Rank, TestTypes); + +template +void rankSmall() +{ + if (noDoubleTests()) 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 +void rankBig(const int num) +{ + if (noDoubleTests()) return; + af::dtype dt = (af::dtype)af::dtype_traits::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 +void rankLow(const int num) +{ + if (noDoubleTests()) return; + af::dtype dt = (af::dtype)af::dtype_traits::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(); +} + +TYPED_TEST(Rank, big) +{ + rankBig(1024); +} + +TYPED_TEST(Rank, low) +{ + rankBig(512); +} From e7d75bec1b275023fcf216b1b8ca3008b9c8645e Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 13:37:12 -0400 Subject: [PATCH 2/9] BUGFIX/TEST: Fixing not for C API. Added relevant tests. - Made sure the CPP API is calling C API --- src/api/c/unary.cpp | 2 +- src/api/cpp/array.cpp | 3 +-- test/math.cpp | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/api/c/unary.cpp b/src/api/c/unary.cpp index f1e86ffaba..2b8cc1d4b6 100644 --- a/src/api/c/unary.cpp +++ b/src/api/c/unary.cpp @@ -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; diff --git a/src/api/cpp/array.cpp b/src/api/cpp/array.cpp index 036db4930a..ba46f6385c 100644 --- a/src/api/cpp/array.cpp +++ b/src/api/cpp/array.cpp @@ -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); } diff --git a/test/math.cpp b/test/math.cpp index e5dbe76194..007054b7c3 100644 --- a/test/math.cpp +++ b/test/math.cpp @@ -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 *hb = b.host(); + + for(int i = 0; i < a.elements(); i++) { + ASSERT_EQ(ha[i] ^ hb[i], true); + } + + delete[] ha; + delete[] hb; +} From 1bde87148571ec6ccb0e229e0474923587b3e77b Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 13:55:40 -0400 Subject: [PATCH 3/9] BUGFIX: Fixing a bug in randn for CPU backend - The function was improperly creating identical arrays every time --- src/backend/cpu/random.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backend/cpu/random.cpp b/src/backend/cpu/random.cpp index 03fabb37d4..71de4ef825 100644 --- a/src/backend/cpu/random.cpp +++ b/src/backend/cpu/random.cpp @@ -86,11 +86,14 @@ Array randn(const af::dim4 &dims) if (my_seed != gen_seed) { gen = nrand(generator); + my_seed = gen_seed; } Array outArray = createEmptyArray(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; } From 05509c9399b6ae02d6a54d57b6c1feb564be8269 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 13:56:55 -0400 Subject: [PATCH 4/9] BUGFIX: Fixing setSeed for randu --- src/backend/cpu/random.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/cpu/random.cpp b/src/backend/cpu/random.cpp index 71de4ef825..4c91b96fb1 100644 --- a/src/backend/cpu/random.cpp +++ b/src/backend/cpu/random.cpp @@ -110,6 +110,7 @@ Array randu(const af::dim4 &dims) if (my_seed != gen_seed) { gen = urand(generator); + my_seed = gen_seed; } Array outArray = createEmptyArray(dims); @@ -155,6 +156,7 @@ Array randu(const af::dim4 &dims) if (my_seed != gen_seed) { gen = urand(generator); + my_seed = gen_seed; } Array outArray = createEmptyArray(dims); From b8cfd77440faa927d02945a915beefe20bcc7d5c Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 13:58:25 -0400 Subject: [PATCH 5/9] TEST: Updating and fixing the randu/randn tests --- test/random.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/random.cpp b/test/random.cpp index 5d4f46c255..fc5012e077 100644 --- a/test/random.cpp +++ b/test/random.cpp @@ -162,22 +162,29 @@ 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 h_in0(num); std::vector h_in1(num); std::vector h_in2(num); + std::vector 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]); } } @@ -188,7 +195,7 @@ TYPED_TEST(Random, setSeed) TYPED_TEST(Random_norm, setSeed) { - testSetSeed(456, 789, false); + testSetSeed(456, 789, true); } template From bd390834176581aab2e6924c417511ad29ac4f10 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 16:46:38 -0400 Subject: [PATCH 6/9] TEST: Updating random tests to properly reset seeds --- test/random.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/random.cpp b/test/random.cpp index fc5012e077..4ca5126b2a 100644 --- a/test/random.cpp +++ b/test/random.cpp @@ -151,6 +151,8 @@ void testSetSeed(const uintl seed0, const uintl seed1, bool is_norm = false) if (noDoubleTests()) return; + uintl orig_seed = af::getSeed(); + const int num = 1024 * 1024; af::dtype ty = (af::dtype)af::dtype_traits::af_type; @@ -186,6 +188,8 @@ void testSetSeed(const uintl seed0, const uintl seed1, bool is_norm = false) // 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) @@ -203,6 +207,8 @@ void testGetSeed(const uintl seed0, const uintl seed1) { if (noDoubleTests()) return; + uintl orig_seed = af::getSeed(); + const int num = 1024; af::dtype ty = (af::dtype)af::dtype_traits::af_type; @@ -217,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) From cd789110bf24df73defd3a34b1b5a051e24b409a Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 17:33:22 -0400 Subject: [PATCH 7/9] TEST: Fixing out of bounds access in fft tests --- test/fft.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fft.cpp b/test/fft.cpp index 8a25c1fe76..c2e5fcbe1f 100644 --- a/test/fft.cpp +++ b/test/fft.cpp @@ -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::af_type)); + dims.ndims(), dims.get(), (af_dtype) af::dtype_traits::af_type)); ASSERT_EQ(AF_ERR_SIZE, af_ifft2(&outArray, inArray, 0.01, 0, 0)); ASSERT_EQ(AF_SUCCESS, af_release_array(inArray)); @@ -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::af_type)); + dims.ndims(), dims.get(), (af_dtype) af::dtype_traits::af_type)); ASSERT_EQ(AF_ERR_SIZE, af_ifft3(&outArray, inArray, 0.01, 0, 0, 0)); ASSERT_EQ(AF_SUCCESS, af_release_array(inArray)); From 3fb199d0c90d33c566274d950bba0ea60e88c497 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 17:33:55 -0400 Subject: [PATCH 8/9] BUGFIX in randn for apple systems - A really ugly hack because the proper version fails on OSX for no reason --- src/backend/opencl/kernel/random.cl | 9 +++++++-- src/backend/opencl/kernel/random.hpp | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/backend/opencl/kernel/random.cl b/src/backend/opencl/kernel/random.cl index 5debf5259b..d6d0f1fa06 100644 --- a/src/backend/opencl/kernel/random.cl +++ b/src/backend/opencl/kernel/random.cl @@ -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); diff --git a/src/backend/opencl/kernel/random.hpp b/src/backend/opencl/kernel/random.hpp index a903e39a01..f951797e97 100644 --- a/src/backend/opencl/kernel/random.hpp +++ b/src/backend/opencl/kernel/random.hpp @@ -106,6 +106,10 @@ namespace opencl std::ostringstream options; options << " -D T=" << dtype_traits::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().name(); if (std::is_same::value) { From 214acf104779f04fd8e9bb39b7f351d3b125abd2 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 13 Jul 2015 17:35:28 -0400 Subject: [PATCH 9/9] Renaming rank test to rank_dense --- test/{rank.cpp => rank_dense.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{rank.cpp => rank_dense.cpp} (100%) diff --git a/test/rank.cpp b/test/rank_dense.cpp similarity index 100% rename from test/rank.cpp rename to test/rank_dense.cpp