Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce multipoint_range interface; Refactors point_distance API to support multipoint to multipoint distance. #731

Merged
merged 20 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from 11 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
18 changes: 9 additions & 9 deletions cpp/include/cuspatial/distance/point_distance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ namespace cuspatial {
* @ingroup distance
* @brief Compute pairwise point-to-point Cartesian distance
*
isVoid marked this conversation as resolved.
Show resolved Hide resolved
* @param points1_x Column of x-coordinates of the first point in each pair
* @param points1_y Column of y-coordinates of the first point in each pair
* @param points2_x Column of x-coordinates of the second point in each pair
* @param points2_y Column of y-coordinates of the second point in each pair
* @param stream The CUDA stream to use for device memory operations and kernel launches
* @param multipoints1_offset Index to the first point of each multipoint in points1_xy
* @param multipoints2_offset Index to the second point of each multipoint in points2_xy
* @param points1_xy Column of xy-coordinates of the first point in each pair
* @param points2_xy Column of xy-coordinates of the second point in each pair
* @return Column of distances between each pair of input points
*/

std::unique_ptr<cudf::column> pairwise_point_distance(
cudf::column_view const& points1_x,
cudf::column_view const& points1_y,
cudf::column_view const& points2_x,
cudf::column_view const& points2_y,
std::optional<cudf::device_span<cudf::size_type const>> multipoints1_offset,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints2_offset,
cudf::column_view const& points2_xy,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be clearer to have the point columns before their optional multipoint offset parameters.

Suggested change
std::optional<cudf::device_span<cudf::size_type const>> multipoints1_offset,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints2_offset,
cudf::column_view const& points2_xy,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints1_offset,
cudf::column_view const& points2_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints2_offset,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I didn't realize there are multiple APIs that follow this style. I would say leave it alone then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I forgot to revert this suggestion before I merge. Will address in #734

rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource());

} // namespace cuspatial
145 changes: 145 additions & 0 deletions cpp/include/cuspatial/experimental/array_view/multipoint_array.cuh
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* 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 <cuspatial/experimental/geometry_collection/multipoint.cuh>

#include <cuspatial/cuda_utils.hpp>
#include <cuspatial/traits.hpp>

namespace cuspatial {
namespace array_view {
isVoid marked this conversation as resolved.
Show resolved Hide resolved

using namespace cuspatial::geometry_collection;
isVoid marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Host-Device view object of a multipoint array
isVoid marked this conversation as resolved.
Show resolved Hide resolved
* @ingroup array_view
*
* Conforms to GeoArrow's specification of multipoint:
* https://github.com/geopandas/geo-arrow-spec/blob/main/format.md
*
* @tparam GeometryIterator iterator type for the offset array. Must meet
* the requirements of [LegacyRandomAccessIterator][LinkLRAI].
* @tparam VecIterator iterator type for the point array. Must meet
* the requirements of [LegacyRandomAccessIterator][LinkLRAI].
*
* @note Though this object is host/device compatible,
* The underlying iterator should be device accessible if used in device kernel.
isVoid marked this conversation as resolved.
Show resolved Hide resolved
*
* [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
* "LegacyRandomAccessIterator"
*/
template <typename GeometryIterator, typename VecIterator>
class multipoint_array {
isVoid marked this conversation as resolved.
Show resolved Hide resolved
public:
using geometry_it_t = GeometryIterator;
using point_it_t = VecIterator;
using point_t = iterator_value_type<point_it_t>;
using element_t = iterator_vec_base_type<point_it_t>;

/**
* @brief Construct a new multipoint array object
*/
multipoint_array(GeometryIterator geometry_begin,
GeometryIterator geometry_end,
VecIterator points_begin,
VecIterator points_end);

/**
* @brief Returns the number of multipoints in the array.
*/
auto size();
isVoid marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Returns the iterator to the start of the multipoint array.
*/
auto multipoint_begin();

/**
* @brief Returns the iterator to the end of the multipoint array.
*/
auto multipoint_end();

/**
* @brief Returns the iterator to the start of the underlying point array.
*/
auto point_begin();

/**
* @brief Returns the iterator to the end of the underlying point array.
*/
auto point_end();

isVoid marked this conversation as resolved.
Show resolved Hide resolved
/**
* @brief Returns the `idx`th multipoint in the array.
*
* @tparam IndexType type of the index
* @param idx the index to the multipoint
* @return a multipoint object
*/
template <typename IndexType>
CUSPATIAL_HOST_DEVICE auto element(IndexType idx);
isVoid marked this conversation as resolved.
Show resolved Hide resolved

protected:
/// Iterator to the start of the index array of start positions to each multipoint.
GeometryIterator _geometry_begin;
/// Iterator to the past-the-end of the index array of start positions to each multipoint.
GeometryIterator _geometry_end;
/// Iterator to the start of the point array.
VecIterator _points_begin;
/// Iterator to the past-the-end position of the point array.
VecIterator _points_end;
isVoid marked this conversation as resolved.
Show resolved Hide resolved
};

/**
* @brief Create a view of multipoint array from array size and start iterators
* @ingroup array_view
*
* @tparam IndexType1 Index type of the size of the geometry array
* @tparam IndexType2 Index type of the size of the point array
* @tparam GeometryIterator iterator type for offset array. Must meet
* the requirements of [LegacyRandomAccessIterator][LinkLRAI].
* @tparam VecIterator iterator type for the point array. Must meet
* the requirements of [LegacyRandomAccessIterator][LinkLRAI].
*
* @note Iterators should be device-accessible if the view is intended to be
* used on device.
*
* @param num_multipoints Number of multipoints in the array
* @param geometry_begin Iterator to the start of the geometry offset array
* @param num_points Number of underlying points in the multipoint array
* @param point_begin Iterator to the start of the points array
* @return View object to multipoint array
* [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
* "LegacyRandomAccessIterator"
*/
template <typename IndexType1, typename IndexType2, typename GeometryIterator, typename VecIterator>
multipoint_array<GeometryIterator, VecIterator> make_multipoint_array(
isVoid marked this conversation as resolved.
Show resolved Hide resolved
IndexType1 num_multipoints,
GeometryIterator geometry_begin,
IndexType2 num_points,
VecIterator point_begin)
{
return multipoint_array<GeometryIterator, VecIterator>{
geometry_begin, geometry_begin + num_multipoints + 1, point_begin, point_begin + num_points};
}

} // namespace array_view
} // namespace cuspatial

#include <cuspatial/experimental/detail/array_view/multipoint_array.cuh>
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* 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 <thrust/binary_search.h>
#include <thrust/distance.h>
#include <thrust/iterator/transform_iterator.h>
#include <thrust/pair.h>

#include <cuspatial/cuda_utils.hpp>
#include <cuspatial/detail/iterator.hpp>
#include <cuspatial/experimental/geometry_collection/multipoint.cuh>
#include <cuspatial/traits.hpp>
#include <cuspatial/vec_2d.hpp>

namespace cuspatial {
namespace array_view {

using namespace cuspatial::geometry_collection;
using namespace cuspatial::detail;

namespace detail {
template <typename GeometryIterator, typename VecIterator>
struct to_multipoint_functor {
using difference_type = typename thrust::iterator_difference<GeometryIterator>::type;
GeometryIterator _geometry_begin;
isVoid marked this conversation as resolved.
Show resolved Hide resolved
VecIterator _points_begin;

to_multipoint_functor(GeometryIterator geometry_begin, VecIterator points_begin)
: _geometry_begin(geometry_begin), _points_begin(points_begin)
{
}

CUSPATIAL_HOST_DEVICE
auto operator()(difference_type const& i)
{
return multipoint<VecIterator>{_points_begin + _geometry_begin[i],
_points_begin + _geometry_begin[i + 1]};
}
};

} // namespace detail

template <typename GeometryIterator, typename VecIterator>
multipoint_array<GeometryIterator, VecIterator>::multipoint_array(GeometryIterator geometry_begin,
GeometryIterator geometry_end,
VecIterator points_begin,
VecIterator points_end)
: _geometry_begin(geometry_begin),
_geometry_end(geometry_end),
_points_begin(points_begin),
_points_end(points_end)
{
}

template <typename GeometryIterator, typename VecIterator>
auto multipoint_array<GeometryIterator, VecIterator>::size()
{
return thrust::distance(_geometry_begin, _geometry_end) - 1;
}

template <typename GeometryIterator, typename VecIterator>
auto multipoint_array<GeometryIterator, VecIterator>::multipoint_begin()
{
return cuspatial::detail::make_counting_transform_iterator(
0, detail::to_multipoint_functor(_geometry_begin, _points_begin));
}

template <typename GeometryIterator, typename VecIterator>
auto multipoint_array<GeometryIterator, VecIterator>::multipoint_end()
{
return multipoint_begin() + size();
}

template <typename GeometryIterator, typename VecIterator>
auto multipoint_array<GeometryIterator, VecIterator>::point_begin()
{
return _points_begin;
}

template <typename GeometryIterator, typename VecIterator>
auto multipoint_array<GeometryIterator, VecIterator>::point_end()
{
return _points_end;
}

template <typename GeometryIterator, typename VecIterator>
template <typename IndexType>
CUSPATIAL_HOST_DEVICE auto multipoint_array<GeometryIterator, VecIterator>::element(IndexType idx)
{
return multipoint{_points_begin + _geometry_begin[idx], _points_begin + _geometry_begin[idx + 1]};
isVoid marked this conversation as resolved.
Show resolved Hide resolved
}

} // namespace array_view
} // namespace cuspatial
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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 <cuspatial/cuda_utils.hpp>

namespace cuspatial {
namespace geometry_collection {

template <typename VecIterator>
CUSPATIAL_HOST_DEVICE multipoint<VecIterator>::multipoint(VecIterator begin, VecIterator end)
: points_begin(begin), points_end(end)
{
}

template <typename VecIterator>
CUSPATIAL_HOST_DEVICE auto multipoint<VecIterator>::point_begin() const
{
return points_begin;
}

template <typename VecIterator>
CUSPATIAL_HOST_DEVICE auto multipoint<VecIterator>::point_end() const
{
return points_end;
}

template <typename VecIterator>
CUSPATIAL_HOST_DEVICE auto multipoint<VecIterator>::begin() const
{
return point_begin();
}

template <typename VecIterator>
CUSPATIAL_HOST_DEVICE auto multipoint<VecIterator>::end() const
{
return point_end();
}

} // namespace geometry_collection
} // namespace cuspatial
Loading