MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ sort_implementation()

Datum< Kakshya::RegionGroup > MayaFlux::Yantra::Granular::SortOp::sort_implementation ( const Datum< Kakshya::RegionGroup > &  input)
overrideprotected

Definition at line 617 of file GranularWorkflow.cpp.

619{
620 const auto feature_key = this->template get_parameter_or_default<std::string>("feature_key", std::string("feature"));
621 const bool ascending = this->template get_parameter_or_default<bool>("ascending", true);
622 const auto gpu_thresh = this->template get_parameter_or_default<uint32_t>("gpu_sort_threshold", 0U);
623 const auto n = static_cast<uint32_t>(input.data.regions.size());
624
625 Datum<Kakshya::RegionGroup> out = input;
626
627 if (n == 0)
628 return out;
629
630 if (gpu_thresh > 0 && n >= gpu_thresh) {
631 struct SortPC {
632 uint32_t element_count;
633 uint32_t pass_number;
634 uint32_t ascending;
635 };
636
637 std::vector<float> values(n);
638 for (uint32_t i = 0; i < n; ++i) {
639 auto attr = out.data.regions[i].get_attribute<double>(feature_key);
640 values[i] = attr ? static_cast<float>(*attr) : 0.0F;
641 }
642
643 std::vector<uint32_t> indices(n);
644 std::iota(indices.begin(), indices.end(), 0U);
645
646 auto executor = std::make_shared<ShaderExecutionContext<>>(
647 GpuShaderConfig {
648 .shader_path = "sort_by_attribute.comp",
649 .workgroup_size = { 256, 1, 1 },
650 .push_constant_size = sizeof(SortPC) });
651
652 executor->in_out(0, values, GpuBufferBinding::ElementType::FLOAT32)
653 .in_out(1, indices, GpuBufferBinding::ElementType::UINT32)
654 .set_output_size(1, n * sizeof(uint32_t));
655
656 const uint32_t n_passes = n * 2;
657 executor->set_multipass(n_passes,
658 [n, ascending](uint32_t pass, void* pc_data) {
659 const SortPC pc {
660 .element_count = n,
661 .pass_number = pass & 1U,
662 .ascending = ascending ? 1U : 0U,
663 };
664 std::memcpy(pc_data, &pc, sizeof(SortPC));
665 });
666
667 auto gpu_sorter = std::make_shared<GpuSorter<>>(executor);
668
669 Datum<std::vector<Kakshya::DataVariant>> sort_input {
670 { Kakshya::DataVariant(std::vector<double>(values.begin(), values.end())) }
671 };
672
673 auto result = gpu_sorter->apply_operation(sort_input);
674 const auto sorted_indices = ShaderExecutionContext<>::read_output<uint32_t>(result, 1);
675
676 std::vector<Kakshya::Region> reordered(n);
677 for (uint32_t i = 0; i < n; ++i)
678 reordered[i] = out.data.regions[sorted_indices[i]];
679
680 out.data.regions = std::move(reordered);
681 out.data.current_region_index = 0;
682 out.data.active_indices.clear();
683 return out;
684 }
685
686 out.data.sort_by_attribute(feature_key);
687
688 if (!ascending)
689 std::ranges::reverse(out.data.regions);
690
691 out.data.current_region_index = 0;
692 out.data.active_indices.clear();
693
694 return out;
695}
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
Definition NDData.hpp:76

References MayaFlux::Yantra::Datum< T >::data, MayaFlux::Yantra::GpuBufferBinding::FLOAT32, MayaFlux::Yantra::GpuShaderConfig::shader_path, and MayaFlux::Yantra::GpuBufferBinding::UINT32.