241 neighbor_lists_view_type neighbor_lists, epsilons_view_type epsilons,
242 const double uniform_radius = 0.0,
double max_search_radius = 0.0) {
246 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename trg_view_type::memory_space>::accessible==1) &&
247 "Target coordinates view passed to generate2DNeighborListsFromRadiusSearch should be accessible from the host.");
249 "Target coordinates view passed to generate2DNeighborListsFromRadiusSearch must have \
250 second dimension as large as _dim.");
251 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename neighbor_lists_view_type::memory_space>::accessible==1) &&
252 "Views passed to generate2DNeighborListsFromRadiusSearch should be accessible from the host.");
253 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename epsilons_view_type::memory_space>::accessible==1) &&
254 "Views passed to generate2DNeighborListsFromRadiusSearch should be accessible from the host.");
257 const int num_target_sites = trg_pts_view.extent(0);
265 && neighbor_lists.extent(1)>=1)
266 &&
"neighbor lists View does not have large enough dimensions");
270 &&
"epsilons View does not have the correct dimension");
272 typedef Kokkos::View<double*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
275 typedef Kokkos::View<size_t*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
279 int team_scratch_size = 0;
280 team_scratch_size += scratch_double_view::shmem_size(neighbor_lists.extent(1));
281 team_scratch_size += scratch_int_view::shmem_size(neighbor_lists.extent(1));
282 team_scratch_size += scratch_double_view::shmem_size(
_dim);
285 size_t max_num_neighbors = 0;
288 Kokkos::parallel_reduce(
"radius search",
host_team_policy(num_target_sites, Kokkos::AUTO)
289 .set_scratch_size(0 , Kokkos::PerTeam(team_scratch_size)),
290 KOKKOS_LAMBDA(
const host_member_type& teamMember,
size_t& t_max_num_neighbors) {
293 scratch_double_view neighbor_distances(teamMember.team_scratch(0 ), neighbor_lists.extent(1));
294 scratch_int_view neighbor_indices(teamMember.team_scratch(0 ), neighbor_lists.extent(1));
295 scratch_double_view this_target_coord(teamMember.team_scratch(0 ),
_dim);
297 size_t neighbors_found = 0;
299 const int i = teamMember.league_rank();
302 if (uniform_radius > 0) epsilons(i) = uniform_radius;
305 compadre_kernel_assert_release((epsilons(i)<=max_search_radius || max_search_radius==0) &&
"max_search_radius given (generally derived from the size of a halo region), and search radius needed would exceed this max_search_radius.");
307 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember, neighbor_lists.extent(1)), [&](
const int j) {
308 neighbor_indices(j) = 0;
309 neighbor_distances(j) = -1.0;
311 teamMember.team_barrier();
313 Kokkos::single(Kokkos::PerTeam(teamMember), [&] () {
317 for (
int j=0; j<
_dim; ++j) {
318 this_target_coord(j) = trg_pts_view(i,j);
321 nanoflann::SearchParams sp;
324 neighbors_found =
_tree_1d->template radiusSearchCustomCallback<Compadre::RadiusResultSet<double> >(this_target_coord.data(), rrs, sp) ;
325 }
else if (
_dim==2) {
326 neighbors_found =
_tree_2d->template radiusSearchCustomCallback<Compadre::RadiusResultSet<double> >(this_target_coord.data(), rrs, sp) ;
327 }
else if (
_dim==3) {
328 neighbors_found =
_tree_3d->template radiusSearchCustomCallback<Compadre::RadiusResultSet<double> >(this_target_coord.data(), rrs, sp) ;
331 t_max_num_neighbors = (neighbors_found > t_max_num_neighbors) ? neighbors_found : t_max_num_neighbors;
334 neighbor_lists(i,0) = neighbors_found;
338 teamMember.team_barrier();
341 int loop_bound = (neighbors_found < neighbor_lists.extent(1)-1) ? neighbors_found : neighbor_lists.extent(1)-1;
344 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember, loop_bound), [&](
const int j) {
346 neighbor_lists(i,j+1) =
static_cast<typename std::remove_pointer<typename std::remove_pointer<typename neighbor_lists_view_type::data_type>::type
>::type>(neighbor_indices(j));
348 teamMember.team_barrier();
351 }, Kokkos::Max<size_t>(max_num_neighbors) );
356 &&
"neighbor_lists does not contain enough columns for the maximum number of neighbors needing to be stored.");
358 return max_num_neighbors;
375 neighbor_lists_view_type neighbor_lists, neighbor_lists_view_type number_of_neighbors_list,
376 epsilons_view_type epsilons,
const double uniform_radius = 0.0,
double max_search_radius = 0.0) {
380 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename trg_view_type::memory_space>::accessible==1) &&
381 "Target coordinates view passed to generateCRNeighborListsFromRadiusSearch should be accessible from the host.");
383 "Target coordinates view passed to generateCRNeighborListsFromRadiusSearch must have \
384 second dimension as large as _dim.");
385 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename neighbor_lists_view_type::memory_space>::accessible==1) &&
386 "Views passed to generateCRNeighborListsFromRadiusSearch should be accessible from the host.");
387 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename epsilons_view_type::memory_space>::accessible==1) &&
388 "Views passed to generateCRNeighborListsFromRadiusSearch should be accessible from the host.");
391 const int num_target_sites = trg_pts_view.extent(0);
398 &&
"number_of_neighbors_list or neighbor lists View does not have large enough dimensions");
401 typedef Kokkos::View<
global_index_type*,
typename neighbor_lists_view_type::array_layout,
402 typename neighbor_lists_view_type::memory_space,
typename neighbor_lists_view_type::memory_traits> row_offsets_view_type;
403 row_offsets_view_type row_offsets;
404 int max_neighbor_list_row_storage_size = 1;
407 max_neighbor_list_row_storage_size = nla.getMaxNumNeighbors();
408 Kokkos::resize(row_offsets, num_target_sites);
410 Kokkos::parallel_for(Kokkos::RangePolicy<host_execution_space>(0,num_target_sites), [&](
const int i) {
411 row_offsets(i) = nla.getRowOffsetHost(i);
417 &&
"epsilons View does not have the correct dimension");
419 typedef Kokkos::View<double*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
422 typedef Kokkos::View<size_t*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
426 int team_scratch_size = 0;
427 team_scratch_size += scratch_double_view::shmem_size(max_neighbor_list_row_storage_size);
428 team_scratch_size += scratch_int_view::shmem_size(max_neighbor_list_row_storage_size);
429 team_scratch_size += scratch_double_view::shmem_size(
_dim);
433 Kokkos::parallel_for(
"radius search",
host_team_policy(num_target_sites, Kokkos::AUTO)
434 .set_scratch_size(0 , Kokkos::PerTeam(team_scratch_size)),
438 scratch_double_view neighbor_distances(teamMember.team_scratch(0 ), max_neighbor_list_row_storage_size);
439 scratch_int_view neighbor_indices(teamMember.team_scratch(0 ), max_neighbor_list_row_storage_size);
440 scratch_double_view this_target_coord(teamMember.team_scratch(0 ),
_dim);
442 size_t neighbors_found = 0;
444 const int i = teamMember.league_rank();
447 if (uniform_radius > 0) epsilons(i) = uniform_radius;
450 compadre_kernel_assert_release((epsilons(i)<=max_search_radius || max_search_radius==0) &&
"max_search_radius given (generally derived from the size of a halo region), and search radius needed would exceed this max_search_radius.");
452 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember, max_neighbor_list_row_storage_size), [&](
const int j) {
453 neighbor_indices(j) = 0;
454 neighbor_distances(j) = -1.0;
456 teamMember.team_barrier();
458 Kokkos::single(Kokkos::PerTeam(teamMember), [&] () {
462 for (
int j=0; j<
_dim; ++j) {
463 this_target_coord(j) = trg_pts_view(i,j);
466 nanoflann::SearchParams sp;
469 neighbors_found =
_tree_1d->template radiusSearchCustomCallback<Compadre::RadiusResultSet<double> >(this_target_coord.data(), rrs, sp) ;
470 }
else if (
_dim==2) {
471 neighbors_found =
_tree_2d->template radiusSearchCustomCallback<Compadre::RadiusResultSet<double> >(this_target_coord.data(), rrs, sp) ;
472 }
else if (
_dim==3) {
473 neighbors_found =
_tree_3d->template radiusSearchCustomCallback<Compadre::RadiusResultSet<double> >(this_target_coord.data(), rrs, sp) ;
478 if (is_dry_run || uniform_radius!=0.0) {
479 number_of_neighbors_list(i) = neighbors_found;
482 &&
"Number of neighbors found changed since dry-run.");
487 teamMember.team_barrier();
490 int loop_bound = neighbors_found;
493 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember, loop_bound), [&](
const int j) {
495 neighbor_lists(row_offsets(i)+j) =
static_cast<typename std::remove_pointer<typename std::remove_pointer<typename neighbor_lists_view_type::data_type>::type
>::type>(neighbor_indices(j));
497 teamMember.team_barrier();
503 return nla.getTotalNeighborsOverAllListsHost();
520 neighbor_lists_view_type neighbor_lists, epsilons_view_type epsilons,
521 const int neighbors_needed,
const double epsilon_multiplier = 1.6,
522 double max_search_radius = 0.0,
const bool verify_unisolvency =
true) {
526 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename trg_view_type::memory_space>::accessible==1) &&
527 "Target coordinates view passed to generate2DNeighborListsFromKNNSearch should be accessible from the host.");
529 "Target coordinates view passed to generate2DNeighborListsFromRadiusSearch must have \
530 second dimension as large as _dim.");
531 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename neighbor_lists_view_type::memory_space>::accessible==1) &&
532 "Views passed to generate2DNeighborListsFromKNNSearch should be accessible from the host.");
533 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename epsilons_view_type::memory_space>::accessible==1) &&
534 "Views passed to generate2DNeighborListsFromKNNSearch should be accessible from the host.");
537 const int num_target_sites = trg_pts_view.extent(0);
545 (neighbor_lists.extent(0)==(
size_t)num_target_sites
546 && neighbor_lists.extent(1)>=(
size_t)(neighbors_needed+1)))
547 &&
"neighbor lists View does not have large enough dimensions");
551 &&
"epsilons View does not have the correct dimension");
553 typedef Kokkos::View<double*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
556 typedef Kokkos::View<size_t*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
560 int team_scratch_size = 0;
561 team_scratch_size += scratch_double_view::shmem_size(neighbor_lists.extent(1));
562 team_scratch_size += scratch_int_view::shmem_size(neighbor_lists.extent(1));
563 team_scratch_size += scratch_double_view::shmem_size(
_dim);
566 size_t min_num_neighbors = 0;
574 Kokkos::parallel_reduce(
"knn search",
host_team_policy(num_target_sites, Kokkos::AUTO)
575 .set_scratch_size(0 , Kokkos::PerTeam(team_scratch_size)),
576 KOKKOS_LAMBDA(
const host_member_type& teamMember,
size_t& t_min_num_neighbors) {
579 scratch_double_view neighbor_distances(teamMember.team_scratch(0 ), neighbor_lists.extent(1));
580 scratch_int_view neighbor_indices(teamMember.team_scratch(0 ), neighbor_lists.extent(1));
581 scratch_double_view this_target_coord(teamMember.team_scratch(0 ),
_dim);
583 size_t neighbors_found = 0;
585 const int i = teamMember.league_rank();
587 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember, neighbor_lists.extent(1)), [=](
const int j) {
588 neighbor_indices(j) = 0;
589 neighbor_distances(j) = -1.0;
592 teamMember.team_barrier();
593 Kokkos::single(Kokkos::PerTeam(teamMember), [&] () {
597 for (
int j=0; j<
_dim; ++j) {
598 this_target_coord(j) = trg_pts_view(i,j);
602 neighbors_found =
_tree_1d->knnSearch(this_target_coord.data(), neighbors_needed,
603 neighbor_indices.data(), neighbor_distances.data()) ;
604 }
else if (
_dim==2) {
605 neighbors_found =
_tree_2d->knnSearch(this_target_coord.data(), neighbors_needed,
606 neighbor_indices.data(), neighbor_distances.data()) ;
607 }
else if (
_dim==3) {
608 neighbors_found =
_tree_3d->knnSearch(this_target_coord.data(), neighbors_needed,
609 neighbor_indices.data(), neighbor_distances.data()) ;
613 t_min_num_neighbors = (neighbors_found < t_min_num_neighbors) ? neighbors_found : t_min_num_neighbors;
616 epsilons(i) = (neighbor_distances(neighbors_found-1) > 0) ?
617 std::sqrt(neighbor_distances(neighbors_found-1))*epsilon_multiplier : 1e-14*epsilon_multiplier;
625 &&
"Neighbors found exceeded storage capacity in neighbor list.");
627 &&
"max_search_radius given (generally derived from the size of a halo region), \
628 and search radius needed would exceed this max_search_radius.");
631 }, Kokkos::Min<size_t>(min_num_neighbors) );
636 if (num_target_sites==0) min_num_neighbors = neighbors_needed;
638 if (verify_unisolvency) {
641 &&
"Neighbor search failed to find number of neighbors needed for unisolvency.");
646 epsilons, 0.0 , max_search_radius);
648 return max_num_neighbors;
665 neighbor_lists_view_type neighbor_lists, neighbor_lists_view_type number_of_neighbors_list,
666 epsilons_view_type epsilons,
const int neighbors_needed,
const double epsilon_multiplier = 1.6,
667 double max_search_radius = 0.0,
const bool verify_unisolvency =
true) {
671 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename trg_view_type::memory_space>::accessible==1) &&
672 "Target coordinates view passed to generateCRNeighborListsFromKNNSearch should be accessible from the host.");
674 "Target coordinates view passed to generateCRNeighborListsFromRadiusSearch must have \
675 second dimension as large as _dim.");
676 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename neighbor_lists_view_type::memory_space>::accessible==1) &&
677 "Views passed to generateCRNeighborListsFromKNNSearch should be accessible from the host.");
678 compadre_assert_release((Kokkos::SpaceAccessibility<host_execution_space, typename epsilons_view_type::memory_space>::accessible==1) &&
679 "Views passed to generateCRNeighborListsFromKNNSearch should be accessible from the host.");
682 const int num_target_sites = trg_pts_view.extent(0);
690 &&
"number_of_neighbors_list or neighbor lists View does not have large enough dimensions");
694 int max_neighbor_list_row_storage_size = neighbors_needed;
697 max_neighbor_list_row_storage_size = nla.getMaxNumNeighbors();
701 &&
"epsilons View does not have the correct dimension");
703 typedef Kokkos::View<double*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
706 typedef Kokkos::View<size_t*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
710 int team_scratch_size = 0;
711 team_scratch_size += scratch_double_view::shmem_size(max_neighbor_list_row_storage_size);
712 team_scratch_size += scratch_int_view::shmem_size(max_neighbor_list_row_storage_size);
713 team_scratch_size += scratch_double_view::shmem_size(
_dim);
716 size_t min_num_neighbors = 0;
724 Kokkos::parallel_reduce(
"knn search",
host_team_policy(num_target_sites, Kokkos::AUTO)
725 .set_scratch_size(0 , Kokkos::PerTeam(team_scratch_size)),
726 KOKKOS_LAMBDA(
const host_member_type& teamMember,
size_t& t_min_num_neighbors) {
729 scratch_double_view neighbor_distances(teamMember.team_scratch(0 ), max_neighbor_list_row_storage_size);
730 scratch_int_view neighbor_indices(teamMember.team_scratch(0 ), max_neighbor_list_row_storage_size);
731 scratch_double_view this_target_coord(teamMember.team_scratch(0 ),
_dim);
733 size_t neighbors_found = 0;
735 const int i = teamMember.league_rank();
737 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember, max_neighbor_list_row_storage_size), [=](
const int j) {
738 neighbor_indices(j) = 0;
739 neighbor_distances(j) = -1.0;
742 teamMember.team_barrier();
743 Kokkos::single(Kokkos::PerTeam(teamMember), [&] () {
747 for (
int j=0; j<
_dim; ++j) {
748 this_target_coord(j) = trg_pts_view(i,j);
752 neighbors_found =
_tree_1d->knnSearch(this_target_coord.data(), neighbors_needed,
753 neighbor_indices.data(), neighbor_distances.data()) ;
754 }
else if (
_dim==2) {
755 neighbors_found =
_tree_2d->knnSearch(this_target_coord.data(), neighbors_needed,
756 neighbor_indices.data(), neighbor_distances.data()) ;
757 }
else if (
_dim==3) {
758 neighbors_found =
_tree_3d->knnSearch(this_target_coord.data(), neighbors_needed,
759 neighbor_indices.data(), neighbor_distances.data()) ;
763 t_min_num_neighbors = (neighbors_found < t_min_num_neighbors) ? neighbors_found : t_min_num_neighbors;
766 epsilons(i) = (neighbor_distances(neighbors_found-1) > 0) ?
767 std::sqrt(neighbor_distances(neighbors_found-1))*epsilon_multiplier : 1e-14*epsilon_multiplier;
774 &&
"max_search_radius given (generally derived from the size of a halo region), \
775 and search radius needed would exceed this max_search_radius.");
778 }, Kokkos::Min<size_t>(min_num_neighbors) );
783 if (num_target_sites==0) min_num_neighbors = neighbors_needed;
785 if (verify_unisolvency) {
788 &&
"Neighbor search failed to find number of neighbors needed for unisolvency.");
793 number_of_neighbors_list, epsilons, 0.0 , max_search_radius);
796 return nla.getTotalNeighborsOverAllListsHost();