9#include <kernel/adjacency/base.hpp>
10#include <kernel/adjacency/adjactor.hpp>
13#include <kernel/util/omp_util.hpp>
48 static constexpr std::uint64_t
magic = 0x5052474A44413346ull;
94 Index num_nodes_domain,
95 Index num_nodes_image,
96 Index num_indices_image);
119 Index num_nodes_domain,
120 Index num_nodes_image,
121 Index num_indices_image,
122 const Index* domain_ptr,
123 const Index* image_idx);
140 Index num_nodes_image,
159 Index num_nodes_image,
174 template<
typename Adjactor_>
184 _render_as_is(adjactor);
191 _render_injectify(adjactor);
198 _render_transpose(adjactor);
204 _render_injectify_transpose(adjactor);
209 XABORTM(
"Invalid render_type parameter!");
227 template<
typename Adjactor1_,
typename Adjactor2_>
228 explicit Graph(
RenderType render_type,
const Adjactor1_& adjactor1,
const Adjactor2_& adjactor2) :
237 _render_as_is(adjactor1, adjactor2);
244 _render_injectify(adjactor1, adjactor2);
251 _render_transpose(adjactor1, adjactor2);
257 _render_injectify_transpose(adjactor1, adjactor2);
262 XABORTM(
"Invalid render_type parameter!");
298 explicit Graph(
const std::vector<char>& buffer);
335 ASSERTM(domain_node < get_num_nodes_domain(),
"Domain node index out of range");
426 template<
typename Adjactor_>
427 void _render_as_is(
const Adjactor_& adj)
429 typedef typename Adjactor_::ImageIterator AImIt;
434 Index num_indices_image = 0;
437 _domain_ptr.resize(adj.get_num_nodes_domain() + 1);
441 FEAT_PRAGMA_OMP(parallel
for schedule(dynamic, 1000))
442 for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
445 AImIt cur(adj.image_begin(i));
446 AImIt end(adj.image_end(i));
447 for(; cur != end; ++cur)
456 num_indices_image =
_domain_ptr[adj.get_num_nodes_domain()];
460 FEAT_PRAGMA_OMP(parallel
for schedule(dynamic, 1000))
461 for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
464 AImIt cur(adj.image_begin(i));
465 AImIt end(adj.image_end(i));
466 for(; cur != end; ++cur, ++k)
474 template<
typename Adjactor_>
475 void _render_injectify(
const Adjactor_& adj)
479 Index num_indices_image = 0;
482 _domain_ptr.resize(adj.get_num_nodes_domain() + 1);
485 FEAT_PRAGMA_OMP(parallel)
488 std::vector<char> vidx_mask(adj.get_num_nodes_image(), 0);
489 char* idx_mask = vidx_mask.data();
492 FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
493 for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
496 for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
498 if(idx_mask[*it] == 0)
505 for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
512 num_indices_image =
_domain_ptr[adj.get_num_nodes_domain()];
517 FEAT_PRAGMA_OMP(parallel)
519 std::vector<char> vidx_mask(adj.get_num_nodes_image(), 0);
520 char* idx_mask = vidx_mask.data();
521 FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
522 for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
525 for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
527 if(idx_mask[*it] == 0)
534 for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
541 template<
typename Adjactor_>
542 void _render_transpose(
const Adjactor_& adj)
544 typedef typename Adjactor_::ImageIterator AImIt;
548 Index num_indices_image = 0;
554 for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
556 AImIt cur(adj.image_begin(j));
557 AImIt end(adj.image_end(j));
558 for(; cur != end; ++cur)
566 num_indices_image =
_domain_ptr[adj.get_num_nodes_image()];
570 std::vector<Index*> vimg_ptr(adj.get_num_nodes_image(),
nullptr);
571 Index** image_ptr = vimg_ptr.data();
573 for(
Index i(0); i < adj.get_num_nodes_image(); ++i)
578 for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
580 AImIt cur(adj.image_begin(j));
581 AImIt end(adj.image_end(j));
582 for(; cur != end; ++cur)
584 Index*& idx = image_ptr[*cur];
592 template<
typename Adjactor_>
593 void _render_injectify_transpose(
const Adjactor_& adj)
597 Index num_indices_image = 0;
602 std::vector<char> vidx_mask(adj.get_num_nodes_image(), 0);
603 char* idx_mask = vidx_mask.data();
606 for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
608 for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
610 if(idx_mask[*it] == 0)
617 for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
622 std::vector<Index*> vimg_ptr(adj.get_num_nodes_image(),
nullptr);
623 Index** image_ptr = vimg_ptr.data();
628 for(
Index i(0); i < adj.get_num_nodes_image(); ++i)
634 for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
636 for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
638 if(idx_mask[*it] == 0)
640 Index*& idx = image_ptr[*it];
646 for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
656 const Adjactor1_& adj1,
657 const Adjactor2_& adj2)
660 XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(),
"Adjactor dimension mismatch!");
662 typedef typename Adjactor1_::ImageIterator AImIt1;
663 typedef typename Adjactor2_::ImageIterator AImIt2;
667 Index num_indices_image = 0;
670 _domain_ptr.resize(adj1.get_num_nodes_domain() + 1);
673 FEAT_PRAGMA_OMP(parallel
for schedule(dynamic, 1000))
674 for(
Index i = 0; i < adj1.get_num_nodes_domain(); ++i)
677 AImIt1 cur1(adj1.image_begin(i));
678 AImIt1 end1(adj1.image_end(i));
679 for(; cur1 != end1; ++cur1)
681 AImIt2 cur2(adj2.image_begin(*cur1));
682 AImIt2 end2(adj2.image_end(*cur1));
683 for(; cur2 != end2; ++cur2)
693 num_indices_image =
_domain_ptr[adj1.get_num_nodes_domain()];
698 FEAT_PRAGMA_OMP(parallel
for schedule(dynamic, 1000))
699 for(
Index i = 0; i < adj1.get_num_nodes_domain(); ++i)
702 AImIt1 cur1(adj1.image_begin(i));
703 AImIt1 end1(adj1.image_end(i));
704 for(; cur1 != end1; ++cur1)
706 AImIt2 cur2(adj2.image_begin(*cur1));
707 AImIt2 end2(adj2.image_end(*cur1));
708 for(; cur2 != end2; ++cur2, ++k)
720 void _render_injectify(
721 const Adjactor1_& adj1,
722 const Adjactor2_& adj2)
725 XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(),
"Adjactor dimension mismatch!");
729 Index num_indices_image = 0;
732 _domain_ptr.resize(adj1.get_num_nodes_domain() + 1);
734 FEAT_PRAGMA_OMP(parallel)
737 std::vector<char> vidx_mask(adj2.get_num_nodes_image(), 0);
738 char* idx_mask = vidx_mask.data();
741 FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
742 for(
Index i=0; i < adj1.get_num_nodes_domain(); ++i)
745 for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
747 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
749 if(idx_mask[*jt] == 0)
758 for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
759 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
766 num_indices_image =
_domain_ptr[adj1.get_num_nodes_domain()];
769 FEAT_PRAGMA_OMP(parallel)
771 std::vector<char> vidx_mask(adj2.get_num_nodes_image(), 0);
772 char* idx_mask = vidx_mask.data();
773 FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
774 for(
Index i = 0; i < adj1.get_num_nodes_domain(); ++i)
777 for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
779 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
781 if(idx_mask[*jt] == 0)
790 for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
791 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
801 void _render_transpose(
802 const Adjactor1_& adj1,
803 const Adjactor2_& adj2)
806 XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(),
"Adjactor dimension mismatch!");
808 typedef typename Adjactor1_::ImageIterator AImIt1;
809 typedef typename Adjactor2_::ImageIterator AImIt2;
813 Index num_indices_image = 0;
819 for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
821 AImIt1 cur1(adj1.image_begin(j));
822 AImIt1 end1(adj1.image_end(j));
823 for(; cur1 != end1; ++cur1)
825 AImIt2 cur2(adj2.image_begin(*cur1));
826 AImIt2 end2(adj2.image_end(*cur1));
827 for(; cur2 != end2; ++cur2)
836 num_indices_image =
_domain_ptr[adj2.get_num_nodes_image()];
840 std::vector<Index*> vimg_ptr(adj2.get_num_nodes_image(),
nullptr);
841 Index** image_ptr = vimg_ptr.data();
844 for(
Index i(0); i < adj2.get_num_nodes_image(); ++i)
849 for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
851 AImIt1 cur1(adj1.image_begin(j));
852 AImIt1 end1(adj1.image_end(j));
853 for(; cur1 != end1; ++cur1)
855 AImIt2 cur2(adj2.image_begin(*cur1));
856 AImIt2 end2(adj2.image_end(*cur1));
857 for(; cur2 != end2; ++cur2)
859 Index*& idx = image_ptr[*cur2];
871 void _render_injectify_transpose(
872 const Adjactor1_& adj1,
873 const Adjactor2_& adj2)
876 XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(),
"Adjactor dimension mismatch!");
880 Index num_indices_image = 0;
886 std::vector<char> vidx_mask(adj2.get_num_nodes_image(), 0);
887 char* idx_mask = vidx_mask.data();
890 for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
892 for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
894 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
896 if(idx_mask[*jt] == 0)
904 for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
905 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
911 num_indices_image =
_domain_ptr[adj2.get_num_nodes_image()];
914 std::vector<Index*> vimg_ptr(adj2.get_num_nodes_image(),
nullptr);
915 Index** image_ptr = vimg_ptr.data();
919 for(
Index i(0); i < adj2.get_num_nodes_image(); ++i)
925 for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
927 for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
929 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
931 if(idx_mask[*jt] == 0)
933 Index*& idx = image_ptr[*jt];
941 for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
942 for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
953 inline Index get_num_nodes_domain()
const
958 inline Index get_num_nodes_image()
const
#define XABORTM(msg)
Abortion macro definition with custom message.
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Adjacency Graph implementation.
Graph & operator=(Graph &&other)
move-assign operator
static constexpr std::uint64_t magic
magic number for Graph serialization
IndexVector _image_idx
Image node index Vector.
IndexVector _domain_ptr
Domain pointer Vector.
Graph clone() const
Clones this graph.
Graph()
Default constructor.
ImageIterator image_begin(Index domain_node) const
Returns an iterator for the first adjacent image node.
std::vector< Index > IndexVector
index vector type
Graph(RenderType render_type, const Adjactor1_ &adjactor1, const Adjactor2_ &adjactor2)
Composite-Render constructor.
Graph(RenderType render_type, const Adjactor_ &adjactor)
Render constructor.
const Index * get_domain_ptr() const
Returns the domain pointer array.
void sort_indices()
Sorts the image indices to non-descending order.
Index degree() const
Returns the degree of the graph.
Index * get_domain_ptr()
Returns the domain pointer array.
ImageIterator image_end(Index domain_node) const
Returns an iterator for the first position past the last adjacent image node.
Index * get_image_idx()
Returns the image node index array.
void permute_indices(const Adjacency::Permutation &inv_perm)
Permutes the image indices.
Index degree(Index domain_node) const
Returns the degree of a domain node.
IndexVector::const_iterator ImageIterator
ImageIterator for Graph class.
void clear()
Clears the graph.
virtual ~Graph()
virtual destructor
std::size_t bytes() const
Index _num_nodes_image
total number of image nodes
Index get_num_indices() const
Returns the total number indices.
const Index * get_image_idx() const
Returns the image node index array.
std::vector< char > serialize() const
Serializes the graph into a buffer.
RenderType
Render type enumeration.
@ injectify_sorted
Render-Injectified mode, sort image indices.
@ transpose
Render-Transpose mode.
@ injectify_transpose
Render-Injectified-Transpose mode.
@ injectify_transpose_sorted
Render-Injectified-Transpose mode, sort image indices.
@ injectify
Render-Injectified mode.
@ transpose_sorted
Render-Transpose mode, sort image indices.
@ as_is
Render-As-Is mode.
@ as_is_sorted
Render-As-Is mode, sort image indices.
void feat_omp_in_scan(std::size_t n, const T_ x[], T_ y[])
Computes an OpenMP-parallel inclusive scan a.k.a. a prefix sum of an array, i.e.
std::uint64_t Index
Index data type.