diff --git a/cpp/benchmarks/CMakeLists.txt b/cpp/benchmarks/CMakeLists.txt index 4ccfa2464..712af5563 100644 --- a/cpp/benchmarks/CMakeLists.txt +++ b/cpp/benchmarks/CMakeLists.txt @@ -85,8 +85,8 @@ ConfigureBench(HAUSDORFF_BENCH ConfigureNVBench(DISTANCES_BENCH pairwise_linestring_distance.cu) +ConfigureNVBench(POINTS_IN_RANGE_BENCH + points_in_range.cu) + ConfigureNVBench(POINT_IN_POLYGON_BENCH point_in_polygon.cu) - -ConfigureNVBench(SPATIAL_WINDOW_BENCH - spatial_window.cu) diff --git a/cpp/benchmarks/spatial_window.cu b/cpp/benchmarks/points_in_range.cu similarity index 57% rename from cpp/benchmarks/spatial_window.cu rename to cpp/benchmarks/points_in_range.cu index 59cd5761e..5308f594d 100644 --- a/cpp/benchmarks/spatial_window.cu +++ b/cpp/benchmarks/points_in_range.cu @@ -19,8 +19,7 @@ #include #include -#include -#include +#include #include #include @@ -38,30 +37,30 @@ using namespace cuspatial; /** - * @brief Helper to generate random points within a rectangular window + * @brief Helper to generate random points within a range * * @p begin and @p end must be iterators to device-accessible memory * * @tparam PointsIter The type of the iterator to the output points container * @tparam T The floating point type for the coordinates - * @param begin The start of the range of points to generate - * @param end The end of the range of points to generate + * @param begin The start of the sequence of points to generate + * @param end The end of the sequence of points to generate * - * @param window_min the lower left window corner - * @param window_max the upper right window corner + * @param range the lower left range corner + * @param range the upper right range corner * */ template -void generate_points(PointsIter begin, PointsIter end, vec_2d window_min, vec_2d window_max) +void generate_points(PointsIter begin, PointsIter end, vec_2d range_min, vec_2d range_max) { auto engine_x = deterministic_engine(std::distance(begin, end)); auto engine_y = deterministic_engine(2 * std::distance(begin, end)); - auto x_dist = make_uniform_dist(window_min.x, window_max.x); - auto y_dist = make_uniform_dist(window_min.y, window_max.y); + auto x_dist = make_uniform_dist(range_min.x, range_max.x); + auto y_dist = make_uniform_dist(range_min.y, range_max.y); - auto x_gen = value_generator{window_min.x, window_max.x, engine_x, x_dist}; - auto y_gen = value_generator{window_min.y, window_max.y, engine_y, y_dist}; + auto x_gen = value_generator{range_min.x, range_max.x, engine_x, x_dist}; + auto y_gen = value_generator{range_min.y, range_max.y, engine_y, y_dist}; thrust::tabulate(rmm::exec_policy(), begin, end, [x_gen, y_gen] __device__(size_t n) mutable { return vec_2d{x_gen(n), y_gen(n)}; @@ -69,41 +68,40 @@ void generate_points(PointsIter begin, PointsIter end, vec_2d window_min, vec } template -void points_in_spatial_window_benchmark(nvbench::state& state, nvbench::type_list) +void points_in_range_benchmark(nvbench::state& state, nvbench::type_list) { // TODO: to be replaced by nvbench fixture once it's ready cuspatial::rmm_pool_raii rmm_pool; auto const num_points{state.get_int64("NumPoints")}; - auto window_min = vec_2d{-100, -100}; - auto window_max = vec_2d{100, 100}; + auto range_min = vec_2d{-100, -100}; + auto range_max = vec_2d{100, 100}; - auto range_min = vec_2d{-200, -200}; - auto range_max = vec_2d{200, 200}; + auto generate_min = vec_2d{-200, -200}; + auto generate_max = vec_2d{200, 200}; - auto d_x = rmm::device_uvector(num_points, rmm::cuda_stream_default); - auto d_y = rmm::device_uvector(num_points, rmm::cuda_stream_default); + auto points = rmm::device_uvector>(num_points, rmm::cuda_stream_default); - auto d_points = - cuspatial::make_zipped_vec_2d_output_iterator>(d_x.begin(), d_y.begin()); - - generate_points(d_points, d_points + num_points, range_min, range_max); - - auto xs = cudf::column(cudf::data_type{cudf::type_to_id()}, num_points, d_x.release()); - auto ys = cudf::column(cudf::data_type{cudf::type_to_id()}, num_points, d_y.release()); + generate_points(points.begin(), points.end(), generate_min, generate_max); CUSPATIAL_CUDA_TRY(cudaDeviceSynchronize()); state.add_element_count(num_points); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { - auto points_in = - points_in_spatial_window(window_min.x, window_max.x, window_min.y, window_max.y, xs, ys); + auto stream = rmm::cuda_stream_view(launch.get_stream()); + auto num_points_in = + cuspatial::count_points_in_range(range_min, range_max, points.begin(), points.end(), stream); + + auto result_points = rmm::device_uvector>(num_points_in, stream); + + cuspatial::copy_points_in_range( + range_min, range_max, points.begin(), points.end(), result_points.begin(), stream); }); } using floating_point_types = nvbench::type_list; -NVBENCH_BENCH_TYPES(points_in_spatial_window_benchmark, NVBENCH_TYPE_AXES(floating_point_types)) +NVBENCH_BENCH_TYPES(points_in_range_benchmark, NVBENCH_TYPE_AXES(floating_point_types)) .set_type_axes_names({"CoordsType"}) .add_int64_axis("NumPoints", {100'000, 1'000'000, 10'000'000, 100'000'000}); diff --git a/cpp/include/cuspatial/detail/utility/traits.hpp b/cpp/include/cuspatial/detail/utility/traits.hpp index f46e9bcfc..301d74a3e 100644 --- a/cpp/include/cuspatial/detail/utility/traits.hpp +++ b/cpp/include/cuspatial/detail/utility/traits.hpp @@ -23,7 +23,7 @@ namespace detail { /** * @internal - * @brief returns true if all types are the same. + * @brief returns true if all types Ts... are the same as T. */ template constexpr bool is_same() @@ -33,7 +33,17 @@ constexpr bool is_same() /** * @internal - * @brief returns true if all types are floating point types. + * @brief returns true if all types Ts... are convertible to U. + */ +template +constexpr bool is_convertible_to() +{ + return std::conjunction_v...>; +} + +/** + * @internal + * @brief returns true if all types Ts... are floating point types. */ template constexpr bool is_floating_point() diff --git a/cpp/include/cuspatial/experimental/detail/coordinate_transform.cuh b/cpp/include/cuspatial/experimental/detail/coordinate_transform.cuh index 4ec32883b..ae139db1e 100644 --- a/cpp/include/cuspatial/experimental/detail/coordinate_transform.cuh +++ b/cpp/include/cuspatial/experimental/detail/coordinate_transform.cuh @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include diff --git a/cpp/include/cuspatial/experimental/detail/points_in_range.cuh b/cpp/include/cuspatial/experimental/detail/points_in_range.cuh new file mode 100644 index 000000000..1e4ef2e8d --- /dev/null +++ b/cpp/include/cuspatial/experimental/detail/points_in_range.cuh @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://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. + */ + +#pragma once + +#include +#include +#include + +#include +#include + +#include + +namespace cuspatial { +namespace detail { + +// Functor to filter out points that are not inside the query range. Passed to thrust::copy_if +template +struct range_filter { + range_filter(vec_2d vertex_1, vec_2d vertex_2) + : v1{std::min(vertex_1.x, vertex_2.x), std::min(vertex_1.y, vertex_2.y)}, + v2{std::max(vertex_1.x, vertex_2.x), std::max(vertex_1.y, vertex_2.y)} + { + } + + __device__ inline bool operator()(vec_2d point) + { + return point.x > v1.x && point.x < v2.x && point.y > v1.y && point.y < v2.y; + } + + protected: + vec_2d v1; + vec_2d v2; +}; + +} // namespace detail + +template +typename thrust::iterator_traits::difference_type count_points_in_range( + vec_2d vertex_1, + vec_2d vertex_2, + InputIt points_first, + InputIt points_last, + rmm::cuda_stream_view stream) +{ + using Point = typename std::iterator_traits::value_type; + + static_assert(detail::is_convertible_to, Point>(), + "Input points must be convertible to cuspatial::vec_2d"); + + return thrust::count_if( + rmm::exec_policy(stream), points_first, points_last, detail::range_filter{vertex_1, vertex_2}); +} + +template +OutputIt copy_points_in_range(vec_2d vertex_1, + vec_2d vertex_2, + InputIt points_first, + InputIt points_last, + OutputIt output_points_first, + rmm::cuda_stream_view stream) +{ + using Point = typename std::iterator_traits::value_type; + + static_assert(detail::is_convertible_to, Point>(), + "Input points must be convertible to cuspatial::vec_2d"); + + static_assert(detail::is_same_floating_point(), + "Inputs and Range coordinates must have the same value type."); + + return thrust::copy_if(rmm::exec_policy(stream), + points_first, + points_last, + output_points_first, + detail::range_filter{vertex_1, vertex_2}); +} + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/experimental/points_in_range.cuh b/cpp/include/cuspatial/experimental/points_in_range.cuh new file mode 100644 index 000000000..a7acbaf62 --- /dev/null +++ b/cpp/include/cuspatial/experimental/points_in_range.cuh @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://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. + */ + +#pragma once + +#include + +#include + +#include + +namespace cuspatial { + +/** + * @brief Count of points (x,y) that fall within a query range. + * + * @ingroup spatial_relationship + * + * The query range is defined by a pair of opposite vertices within the coordinate system of the + * input points, `v1` and `v2`. A point (x, y) is in the range if `x` lies between `v1.x` and `v2.x` + * and `y` lies between `v1.y` and `v2.y`. A point is only counted if it is strictly within the + * interior of the query range. Points exactly on an edge or vertex of the range are not counted. + * + * The query range vertices and the input points are assumed to be defined in the same coordinate + * system. + * + * @param[in] vertex_1 Vertex of the query range quadrilateral + * @param[in] vertex_2 Vertex of the query range quadrilateral opposite `vertex_1` + * @param[in] points_first beginning of sequence of (x, y) coordinates of points to be queried + * @param[in] points_last end of sequence of (x, y) coordinates of points to be queried + * @param[in] stream The CUDA stream on which to perform computations + * + * @tparam InputIt Iterator to input points. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam T The underlying coordinate type. Must be a floating-point type. + * + * @pre All iterators must have the same `value_type`, with the same underlying floating-point + * coordinate type (e.g. `cuspatial::vec_2d`). + * + * @returns The number of input points that fall within the specified query range. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +typename thrust::iterator_traits::difference_type count_points_in_range( + vec_2d vertex_1, + vec_2d vertex_2, + InputIt points_first, + InputIt points_last, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Copies points (x,y) that fall within a query range. + * + * @ingroup spatial_relationship + * + * The query range is defined by a pair of opposite vertices of a quadrilateral within the + * coordinate system of the input points, `v1` and `v2`. A point (x, y) is in the range if `x` lies + * between `v1.x` and `v2.x` and `y` lies between `v1.y` and `v2.y`. A point is only counted if it + * is strictly within the interior of the query range. Points exactly on an edge or vertex of the + * range are not copied. + * + * The query range vertices and the input points are assumed to be defined in the same coordinate + * system. + * + * `output_points_first` must be an iterator to storage of sufficient size for the points that will + * be copied. cuspatial::count_points_in_range may be used to determine the size required. + * + * @param[in] vertex_1 Vertex of the query range quadrilateral + * @param[in] vertex_2 Vertex of the query range quadrilateral opposite `vertex_1` + * @param[in] points_first beginning of sequence of (x, y) coordinates of points to be queried + * @param[in] points_last end of sequence of (x, y) coordinates of points to be queried + * @param[out] output_points_first beginning of output range of (x, y) coordinates within the + * query range + * @param[in] stream The CUDA stream on which to perform computations and allocate memory. + * + * @tparam InputIt Iterator to input points. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam OutputIt Output iterator. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable. + * @tparam T The underlying coordinate type. Must be a floating-point type. + * + * @pre The range `[points_first, points_last)` may equal the range `[output_points_first, + * output_points_first + std::distance(points_first, points_last)), but the ranges may not + * partially overlap. + * @pre All iterators must have the same `value_type`, with the same underlying floating-point + * coordinate type (e.g. `cuspatial::vec_2d`). + * + * @returns Output iterator to the element past the last output point. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt copy_points_in_range(vec_2d vertex_1, + vec_2d vertex_2, + InputIt points_first, + InputIt points_last, + OutputIt output_points_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +} // namespace cuspatial + +#include diff --git a/cpp/include/cuspatial/spatial_window.hpp b/cpp/include/cuspatial/spatial_window.hpp index 7a783e48b..fb13466c2 100644 --- a/cpp/include/cuspatial/spatial_window.hpp +++ b/cpp/include/cuspatial/spatial_window.hpp @@ -37,6 +37,9 @@ namespace cuspatial { * Swaps `window_min_x` and `window_max_x` if `window_min_x > window_max_x`. * Swaps `window_min_y` and `window_max_y` if `window_min_y > window_max_y`. * + * The window coordinates and the (x, y) points to be tested are assumed to be defined in the same + * coordinate system. + * * @param[in] window_min_x lower x-coordinate of the query window * @param[in] window_max_x upper x-coordinate of the query window * @param[in] window_min_y lower y-coordinate of the query window diff --git a/cpp/src/spatial_window/spatial_window.cu b/cpp/src/spatial_window/spatial_window.cu index 869f9c295..3de5b0c59 100644 --- a/cpp/src/spatial_window/spatial_window.cu +++ b/cpp/src/spatial_window/spatial_window.cu @@ -15,11 +15,14 @@ */ #include +#include +#include -#include +#include #include #include -#include +#include +#include #include @@ -28,41 +31,6 @@ namespace { -// Functor to filter out points that are not inside the query window -// This is passed to cudf::detail::copy_if -template -struct spatial_window_filter { - spatial_window_filter(T window_min_x, - T window_max_x, - T window_min_y, - T window_max_y, - cudf::column_device_view const& x, - cudf::column_device_view const& y) - : min_x{std::min(window_min_x, window_max_x)}, // support mirrored rectangles - max_x{std::max(window_min_x, window_max_x)}, // where specified min > max - min_y{std::min(window_min_y, window_max_y)}, - max_y{std::max(window_min_y, window_max_y)}, - points_x{x}, - points_y{y} - { - } - - __device__ inline bool operator()(cudf::size_type i) - { - auto x = points_x.element(i); - auto y = points_y.element(i); - return x > min_x && x < max_x && y > min_y && y < max_y; - } - - protected: - T min_x; - T max_x; - T min_y; - T max_y; - cudf::column_device_view points_x; - cudf::column_device_view points_y; -}; - // Type-dispatch functor that creates the spatial window filter of the correct type. // Only floating point types are supported. struct spatial_window_dispatch { @@ -76,17 +44,32 @@ struct spatial_window_dispatch { rmm::cuda_stream_view stream, rmm::mr::device_memory_resource* mr) { - auto device_x = cudf::column_device_view::create(x, stream); - auto device_y = cudf::column_device_view::create(y, stream); - return cudf::detail::copy_if(cudf::table_view{{x, y}}, - spatial_window_filter{static_cast(window_min_x), - static_cast(window_max_x), - static_cast(window_min_y), - static_cast(window_max_y), - *device_x, - *device_y}, - stream, - mr); + auto points_begin = cuspatial::make_cartesian_2d_iterator(x.begin(), y.begin()); + + auto window_min = + cuspatial::vec_2d{static_cast(window_min_x), static_cast(window_min_y)}; + auto window_max = + cuspatial::vec_2d{static_cast(window_max_x), static_cast(window_max_y)}; + + auto output_size = cuspatial::count_points_in_range( + window_min, window_max, points_begin, points_begin + x.size(), stream); + + std::vector> cols{}; + cols.reserve(2); + auto mask_policy = cudf::mask_allocation_policy::NEVER; + cols.push_back(cudf::detail::allocate_like(x, output_size, mask_policy, stream, mr)); + cols.push_back(cudf::detail::allocate_like(y, output_size, mask_policy, stream, mr)); + + auto& output_x = cols[0]; + auto& output_y = cols[1]; + + auto output_zip = cuspatial::make_zipped_cartesian_2d_output_iterator( + output_x->mutable_view().begin(), output_y->mutable_view().begin()); + + cuspatial::copy_points_in_range( + window_min, window_max, points_begin, points_begin + x.size(), output_zip, stream); + + return std::make_unique(std::move(cols)); } template +#include +#include + +#include +#include +#include +#include + +#include + +#include + +template +using Vec = cuspatial::vec_2d; + +template +using VecVec = std::vector>; + +template +using DeviceVecVec = rmm::device_vector>; + +template +struct SpatialRangeTest : public testing::Test { + void spatial_range_test(Vec const& v1, + Vec const& v2, + DeviceVecVec const& points, + DeviceVecVec const& expected_points) + { + auto result_size = cuspatial::count_points_in_range(v1, v2, points.begin(), points.end()); + + EXPECT_EQ(result_size, expected_points.size()); + + auto result_points = DeviceVecVec(result_size); + cuspatial::copy_points_in_range(v1, v2, points.begin(), points.end(), result_points.begin()); + + EXPECT_EQ(expected_points, result_points); + } +}; + +using TestTypes = ::testing::Types; + +TYPED_TEST_CASE(SpatialRangeTest, TestTypes); + +TYPED_TEST(SpatialRangeTest, Empty) +{ + using T = TypeParam; + auto points = DeviceVecVec{}; + auto expected_points = DeviceVecVec{}; + + this->spatial_range_test(Vec{1.5, 1.5}, Vec{5.5, 5.5}, points, expected_points); +} + +TYPED_TEST(SpatialRangeTest, SimpleTest) +{ + using T = TypeParam; + auto points = DeviceVecVec(VecVec({{1.0, 0.0}, + {2.0, 1.0}, + {3.0, 2.0}, + {5.0, 3.0}, + {7.0, 1.0}, + {1.0, 3.0}, + {2.0, 5.0}, + {3.0, 6.0}, + {6.0, 5.0}, + {0.0, 4.0}, + {3.0, 7.0}, + {6.0, 4.0}})); + + auto expected_points = DeviceVecVec(VecVec({{3.0, 2.0}, {5.0, 3.0}, {2.0, 5.0}})); + + this->spatial_range_test(Vec{1.5, 1.5}, Vec{5.5, 5.5}, points, expected_points); +} + +// Test that ranges with min/max reversed still work +TYPED_TEST(SpatialRangeTest, ReversedRange) +{ + using T = TypeParam; + auto points = DeviceVecVec(VecVec({{1.0, 0.0}, + {2.0, 1.0}, + {3.0, 2.0}, + {5.0, 3.0}, + {7.0, 1.0}, + {1.0, 3.0}, + {2.0, 5.0}, + {3.0, 6.0}, + {6.0, 5.0}, + {0.0, 4.0}, + {3.0, 7.0}, + {6.0, 4.0}})); + + auto expected_points = DeviceVecVec(VecVec({{3.0, 2.0}, {5.0, 3.0}, {2.0, 5.0}})); + + this->spatial_range_test(Vec{5.5, 5.5}, Vec{1.5, 1.5}, points, expected_points); +} + +TYPED_TEST(SpatialRangeTest, AllPointsInRange) +{ + using T = TypeParam; + auto points = DeviceVecVec(VecVec({{1.0, 0.0}, + {2.0, 1.0}, + {3.0, 2.0}, + {5.0, 3.0}, + {7.0, 1.0}, + {1.0, 3.0}, + {2.0, 5.0}, + {3.0, 6.0}, + {6.0, 5.0}, + {0.0, 4.0}, + {3.0, 7.0}, + {6.0, 4.0}})); + + auto expected_points = DeviceVecVec(VecVec({{1.0, 0.0}, + {2.0, 1.0}, + {3.0, 2.0}, + {5.0, 3.0}, + {7.0, 1.0}, + {1.0, 3.0}, + {2.0, 5.0}, + {3.0, 6.0}, + {6.0, 5.0}, + {0.0, 4.0}, + {3.0, 7.0}, + {6.0, 4.0}})); + + this->spatial_range_test(Vec{-10.0, -10.0}, Vec{10.0, 10.0}, points, expected_points); +} + +TYPED_TEST(SpatialRangeTest, PointsOnOrNearEdges) +{ + using T = TypeParam; + + Vec v1 = {0.0, 0.0}; + Vec v2 = {1.0, 1.0}; + + auto eps = std::numeric_limits::epsilon(); + auto v_eps = Vec{eps, eps}; + + auto on_ll = v1; + auto on_ul = Vec{v1.x, v2.y}; + auto on_lr = Vec{v2.x, v1.y}; + auto on_ur = v2; + + auto on_left = Vec{v1.x, 0.5}; + auto on_right = Vec{v2.x, 0.5}; + auto on_bottom = Vec{0.5, v1.y}; + auto on_top = Vec{0.5, v2.y}; + + auto in_ll = on_ll + v_eps; + auto in_ul = on_ul + Vec{eps, -eps}; + auto in_lr = on_lr + Vec{-eps, eps}; + auto in_ur = on_ur - v_eps; + auto in_left = on_left + v_eps; + auto in_right = on_right - v_eps; + auto in_bottom = on_bottom + v_eps; + auto in_top = on_top - v_eps; + + auto out_ll = on_ll - v_eps; + auto out_ul = on_ul + Vec{-eps, eps}; + auto out_lr = on_lr + Vec{eps, -eps}; + auto out_ur = on_ur + v_eps; + auto out_left = on_left - v_eps; + auto out_right = on_right + v_eps; + auto out_bottom = on_bottom - v_eps; + auto out_top = on_top + v_eps; + + auto points = DeviceVecVec( + VecVec({on_ll, on_ul, on_lr, on_ur, on_left, on_right, on_bottom, on_top, + in_ll, in_ul, in_lr, in_ur, in_left, in_right, in_bottom, in_top, + out_ll, out_ul, out_lr, out_ur, out_left, out_right, out_bottom, out_top})); + + auto expected_points = + DeviceVecVec(VecVec({in_ll, in_ul, in_lr, in_ur, in_left, in_right, in_bottom, in_top})); + + this->spatial_range_test(v1, v2, points, expected_points); +} diff --git a/cpp/tests/spatial_window/spatial_window_test.cpp b/cpp/tests/spatial_window/spatial_window_test.cpp index 38ae15cef..c7aff236f 100644 --- a/cpp/tests/spatial_window/spatial_window_test.cpp +++ b/cpp/tests/spatial_window/spatial_window_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. + * Copyright (c) 2020-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,50 +30,11 @@ constexpr cudf::test::debug_output_level verbosity{cudf::test::debug_output_level::ALL_ERRORS}; template -struct SpatialWindowTest : public cudf::test::BaseFixture { +struct SpatialRangeTest : public cudf::test::BaseFixture { }; using TestTypes = cudf::test::Types; -TYPED_TEST_CASE(SpatialWindowTest, TestTypes); - -TYPED_TEST(SpatialWindowTest, SimpleTest) -{ - using T = TypeParam; - - auto points_x = cudf::test::fixed_width_column_wrapper( - {1.0, 2.0, 3.0, 5.0, 7.0, 1.0, 2.0, 3.0, 6.0, 0.0, 3.0, 6.0}); - auto points_y = cudf::test::fixed_width_column_wrapper( - {0.0, 1.0, 2.0, 3.0, 1.0, 3.0, 5.0, 6.0, 5.0, 4.0, 7.0, 4.0}); - - auto expected_points_x = cudf::test::fixed_width_column_wrapper({3.0, 5.0, 2.0}); - auto expected_points_y = cudf::test::fixed_width_column_wrapper({2.0, 3.0, 5.0}); - - auto result = cuspatial::points_in_spatial_window(1.5, 5.5, 1.5, 5.5, points_x, points_y); - - cudf::test::expect_columns_equivalent(result->get_column(0), expected_points_x, verbosity); - cudf::test::expect_columns_equivalent(result->get_column(1), expected_points_y, verbosity); -} - -// Test that windows with min/max reversed still work -TYPED_TEST(SpatialWindowTest, ReversedWindow) -{ - using T = TypeParam; - - auto points_x = cudf::test::fixed_width_column_wrapper( - {1.0, 2.0, 3.0, 5.0, 7.0, 1.0, 2.0, 3.0, 6.0, 0.0, 3.0, 6.0}); - auto points_y = cudf::test::fixed_width_column_wrapper( - {0.0, 1.0, 2.0, 3.0, 1.0, 3.0, 5.0, 6.0, 5.0, 4.0, 7.0, 4.0}); - - auto expected_points_x = cudf::test::fixed_width_column_wrapper({3.0, 5.0, 2.0}); - auto expected_points_y = cudf::test::fixed_width_column_wrapper({2.0, 3.0, 5.0}); - - auto result = cuspatial::points_in_spatial_window(5.5, 1.5, 5.5, 1.5, points_x, points_y); - - cudf::test::expect_columns_equivalent(result->get_column(0), expected_points_x, verbosity); - cudf::test::expect_columns_equivalent(result->get_column(1), expected_points_y, verbosity); -} - struct SpatialWindowErrorTest : public cudf::test::BaseFixture { };