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");
 
  420      template<
typename Adjactor_>
 
  421      void _render_as_is(
const Adjactor_& adj)
 
  423        typedef typename Adjactor_::ImageIterator AImIt;
 
  428        Index num_indices_image = 0;
 
  431        _domain_ptr.resize(adj.get_num_nodes_domain() + 1);
 
  435        FEAT_PRAGMA_OMP(parallel 
for schedule(dynamic, 1000))
 
  436        for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
 
  439          AImIt cur(adj.image_begin(i));
 
  440          AImIt end(adj.image_end(i));
 
  441          for(; cur != end; ++cur)
 
  450        num_indices_image = 
_domain_ptr[adj.get_num_nodes_domain()];
 
  454        FEAT_PRAGMA_OMP(parallel 
for schedule(dynamic, 1000))
 
  455        for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
 
  458          AImIt cur(adj.image_begin(i));
 
  459          AImIt end(adj.image_end(i));
 
  460          for(; cur != end; ++cur, ++k)
 
  468      template<
typename Adjactor_>
 
  469      void _render_injectify(
const Adjactor_& adj)
 
  473        Index num_indices_image = 0;
 
  476        _domain_ptr.resize(adj.get_num_nodes_domain() + 1);
 
  479        FEAT_PRAGMA_OMP(parallel)
 
  482          std::vector<char> vidx_mask(adj.get_num_nodes_image(), 0);
 
  483          char* idx_mask = vidx_mask.data();
 
  486          FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
 
  487          for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
 
  490            for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
 
  492              if(idx_mask[*it] == 0)
 
  499            for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
 
  506        num_indices_image = 
_domain_ptr[adj.get_num_nodes_domain()];
 
  511        FEAT_PRAGMA_OMP(parallel)
 
  513          std::vector<char> vidx_mask(adj.get_num_nodes_image(), 0);
 
  514          char* idx_mask = vidx_mask.data();
 
  515          FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
 
  516          for(
Index i = 0; i < adj.get_num_nodes_domain(); ++i)
 
  519            for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
 
  521              if(idx_mask[*it] == 0)
 
  528            for(
auto it = adj.image_begin(i); it != adj.image_end(i); ++it)
 
  535      template<
typename Adjactor_>
 
  536      void _render_transpose(
const Adjactor_& adj)
 
  538        typedef typename Adjactor_::ImageIterator AImIt;
 
  542        Index num_indices_image = 0;
 
  548        for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
 
  550          AImIt cur(adj.image_begin(j));
 
  551          AImIt end(adj.image_end(j));
 
  552          for(; cur != end; ++cur)
 
  560        num_indices_image = 
_domain_ptr[adj.get_num_nodes_image()];
 
  564        std::vector<Index*> vimg_ptr(adj.get_num_nodes_image(), 
nullptr);
 
  565        Index** image_ptr = vimg_ptr.data();
 
  567        for(
Index i(0); i < adj.get_num_nodes_image(); ++i)
 
  572        for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
 
  574          AImIt cur(adj.image_begin(j));
 
  575          AImIt end(adj.image_end(j));
 
  576          for(; cur != end; ++cur)
 
  578            Index*& idx = image_ptr[*cur];
 
  586      template<
typename Adjactor_>
 
  587      void _render_injectify_transpose(
const Adjactor_& adj)
 
  591        Index num_indices_image = 0;
 
  596        std::vector<char> vidx_mask(adj.get_num_nodes_image(), 0);
 
  597        char* idx_mask = vidx_mask.data();
 
  600        for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
 
  602          for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
 
  604            if(idx_mask[*it] == 0)
 
  611          for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
 
  616        std::vector<Index*> vimg_ptr(adj.get_num_nodes_image(), 
nullptr);
 
  617        Index** image_ptr = vimg_ptr.data();
 
  622        for(
Index i(0); i < adj.get_num_nodes_image(); ++i)
 
  628        for(
Index j(0); j < adj.get_num_nodes_domain(); ++j)
 
  630          for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
 
  632            if(idx_mask[*it] == 0)
 
  634              Index*& idx = image_ptr[*it];
 
  640          for(
auto it = adj.image_begin(j); it != adj.image_end(j); ++it)
 
  650        const Adjactor1_& adj1,
 
  651        const Adjactor2_& adj2)
 
  654        XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(), 
"Adjactor dimension mismatch!");
 
  656        typedef typename Adjactor1_::ImageIterator AImIt1;
 
  657        typedef typename Adjactor2_::ImageIterator AImIt2;
 
  661        Index num_indices_image = 0;
 
  664        _domain_ptr.resize(adj1.get_num_nodes_domain() + 1);
 
  667        FEAT_PRAGMA_OMP(parallel 
for schedule(dynamic, 1000))
 
  668        for(
Index i = 0; i < adj1.get_num_nodes_domain(); ++i)
 
  671          AImIt1 cur1(adj1.image_begin(i));
 
  672          AImIt1 end1(adj1.image_end(i));
 
  673          for(; cur1 != end1; ++cur1)
 
  675            AImIt2 cur2(adj2.image_begin(*cur1));
 
  676            AImIt2 end2(adj2.image_end(*cur1));
 
  677            for(; cur2 != end2; ++cur2)
 
  687        num_indices_image = 
_domain_ptr[adj1.get_num_nodes_domain()];
 
  692        FEAT_PRAGMA_OMP(parallel 
for schedule(dynamic, 1000))
 
  693        for(
Index i = 0; i < adj1.get_num_nodes_domain(); ++i)
 
  696          AImIt1 cur1(adj1.image_begin(i));
 
  697          AImIt1 end1(adj1.image_end(i));
 
  698          for(; cur1 != end1; ++cur1)
 
  700            AImIt2 cur2(adj2.image_begin(*cur1));
 
  701            AImIt2 end2(adj2.image_end(*cur1));
 
  702            for(; cur2 != end2; ++cur2, ++k)
 
  714      void _render_injectify(
 
  715        const Adjactor1_& adj1,
 
  716        const Adjactor2_& adj2)
 
  719        XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(), 
"Adjactor dimension mismatch!");
 
  723        Index num_indices_image = 0;
 
  726        _domain_ptr.resize(adj1.get_num_nodes_domain() + 1);
 
  728        FEAT_PRAGMA_OMP(parallel)
 
  731          std::vector<char> vidx_mask(adj2.get_num_nodes_image(), 0);
 
  732          char* idx_mask = vidx_mask.data();
 
  735          FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
 
  736          for(
Index i=0; i < adj1.get_num_nodes_domain(); ++i)
 
  739            for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
 
  741              for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  743                if(idx_mask[*jt] == 0)
 
  752            for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
 
  753              for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  760        num_indices_image = 
_domain_ptr[adj1.get_num_nodes_domain()];
 
  763        FEAT_PRAGMA_OMP(parallel)
 
  765          std::vector<char> vidx_mask(adj2.get_num_nodes_image(), 0);
 
  766          char* idx_mask = vidx_mask.data();
 
  767          FEAT_PRAGMA_OMP(
for schedule(dynamic, 1000))
 
  768          for(
Index i = 0; i < adj1.get_num_nodes_domain(); ++i)
 
  771            for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
 
  773              for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  775                if(idx_mask[*jt] == 0)
 
  784            for(
auto it = adj1.image_begin(i); it != adj1.image_end(i); ++it)
 
  785              for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  795      void _render_transpose(
 
  796        const Adjactor1_& adj1,
 
  797        const Adjactor2_& adj2)
 
  800        XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(), 
"Adjactor dimension mismatch!");
 
  802        typedef typename Adjactor1_::ImageIterator AImIt1;
 
  803        typedef typename Adjactor2_::ImageIterator AImIt2;
 
  807        Index num_indices_image = 0;
 
  813        for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
 
  815          AImIt1 cur1(adj1.image_begin(j));
 
  816          AImIt1 end1(adj1.image_end(j));
 
  817          for(; cur1 != end1; ++cur1)
 
  819            AImIt2 cur2(adj2.image_begin(*cur1));
 
  820            AImIt2 end2(adj2.image_end(*cur1));
 
  821            for(; cur2 != end2; ++cur2)
 
  830        num_indices_image = 
_domain_ptr[adj2.get_num_nodes_image()];
 
  834        std::vector<Index*> vimg_ptr(adj2.get_num_nodes_image(), 
nullptr);
 
  835        Index** image_ptr = vimg_ptr.data();
 
  838        for(
Index i(0); i < adj2.get_num_nodes_image(); ++i)
 
  843        for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
 
  845          AImIt1 cur1(adj1.image_begin(j));
 
  846          AImIt1 end1(adj1.image_end(j));
 
  847          for(; cur1 != end1; ++cur1)
 
  849            AImIt2 cur2(adj2.image_begin(*cur1));
 
  850            AImIt2 end2(adj2.image_end(*cur1));
 
  851            for(; cur2 != end2; ++cur2)
 
  853              Index*& idx = image_ptr[*cur2];
 
  865      void _render_injectify_transpose(
 
  866        const Adjactor1_& adj1,
 
  867        const Adjactor2_& adj2)
 
  870        XASSERTM(adj1.get_num_nodes_image() == adj2.get_num_nodes_domain(), 
"Adjactor dimension mismatch!");
 
  874        Index num_indices_image = 0;
 
  880        std::vector<char> vidx_mask(adj2.get_num_nodes_image(), 0);
 
  881        char* idx_mask = vidx_mask.data();
 
  884        for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
 
  886          for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
 
  888            for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  890              if(idx_mask[*jt] == 0)
 
  898          for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
 
  899            for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  905        num_indices_image = 
_domain_ptr[adj2.get_num_nodes_image()];
 
  908        std::vector<Index*> vimg_ptr(adj2.get_num_nodes_image(), 
nullptr);
 
  909        Index** image_ptr = vimg_ptr.data();
 
  913        for(
Index i(0); i < adj2.get_num_nodes_image(); ++i)
 
  919        for(
Index j(0); j < adj1.get_num_nodes_domain(); ++j)
 
  921          for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
 
  923            for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  925              if(idx_mask[*jt] == 0)
 
  927                Index*& idx = image_ptr[*jt];
 
  935          for(
auto it = adj1.image_begin(j); it != adj1.image_end(j); ++it)
 
  936            for(
auto jt = adj2.image_begin(*it); jt != adj2.image_end(*it); ++jt)
 
  947      inline Index get_num_nodes_domain()
 const 
  952      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
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.