1+ /*
2+ Copyright 2024 Huawei Technologies Co., Ltd.
3+
4+ Licensed under the Apache License, Version 2.0 (the "License");
5+ you may not use this file except in compliance with the License.
6+ You may obtain a copy of the License at
7+
8+ http://www.apache.org/licenses/LICENSE-2.0
9+
10+ Unless required by applicable law or agreed to in writing, software
11+ distributed under the License is distributed on an "AS IS" BASIS,
12+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ See the License for the specific language governing permissions and
14+ limitations under the License.
15+
16+ @author Toni Boehnlein, Benjamin Lozes, Pal Andras Papp, Raphael S. Steiner
17+ */
18+ #pragma once
19+
20+ #include < vector>
21+ #include < stdexcept>
22+ #include " osp/concepts/computational_dag_concept.hpp"
23+
24+ namespace osp {
25+
26+ class hypergraph {
27+
28+ public:
29+
30+ hypergraph () = default ;
31+
32+ hypergraph (unsigned num_vertices_, unsigned num_hyperedges_)
33+ : Num_vertices(num_vertices_), Num_hyperedges(num_hyperedges_), vertex_weights(num_vertices_, 0 ),
34+ incident_hyperedges_to_vertex (num_vertices_), vertices_in_hyperedge(num_hyperedges_){}
35+
36+ hypergraph (const hypergraph &other) = default;
37+ hypergraph &operator =(const hypergraph &other) = default ;
38+
39+ virtual ~hypergraph () = default ;
40+
41+ inline unsigned num_vertices () const { return Num_vertices; }
42+ inline unsigned num_hyperedges () const { return Num_hyperedges; }
43+ inline unsigned num_pins () const { return Num_pins; }
44+
45+ void add_pin (unsigned vertex_idx, unsigned hyperedge_idx);
46+ void add_vertex (unsigned weight = 0 );
47+ void add_empty_hyperedge ();
48+ void add_hyperedge (const std::vector<unsigned >& pins);
49+ void set_vertex_weight (unsigned vertex_idx, int weight);
50+
51+ void clear ();
52+ void reset (unsigned num_vertices_, unsigned num_hyperedges_);
53+
54+ inline const std::vector<unsigned > &get_incident_hyperedges (unsigned vertex) const { return incident_hyperedges_to_vertex[vertex]; }
55+ inline const std::vector<unsigned > &get_vertices_in_hyperedge (unsigned hyperedge) const { return vertices_in_hyperedge[hyperedge]; }
56+
57+ template <typename Graph_t>
58+ void convert_from_cdag_as_dag (const Graph_t& dag);
59+
60+ template <typename Graph_t>
61+ void convert_from_cdag_as_hyperdag (const Graph_t& dag);
62+
63+ void read_spmv_from_matrixmarket ();
64+
65+ private:
66+ unsigned Num_vertices = 0 , Num_hyperedges = 0 , Num_pins = 0 ;
67+
68+ std::vector<int > vertex_weights;
69+
70+ std::vector<std::vector<unsigned >> incident_hyperedges_to_vertex;
71+ std::vector<std::vector<unsigned >> vertices_in_hyperedge;
72+ };
73+
74+ void hypergraph::add_pin (unsigned vertex_idx, unsigned hyperedge_idx)
75+ {
76+ if (vertex_idx >= Num_vertices)
77+ {
78+ throw std::invalid_argument (" Invalid Argument while adding pin: vertex index out of range." );
79+ }
80+ else if (hyperedge_idx >= Num_hyperedges)
81+ {
82+ throw std::invalid_argument (" Invalid Argument while adding pin: hyperedge index out of range." );
83+ }
84+ else {
85+ incident_hyperedges_to_vertex[vertex_idx].push_back (hyperedge_idx);
86+ vertices_in_hyperedge[hyperedge_idx].push_back (vertex_idx);
87+ ++Num_pins;
88+ }
89+ }
90+
91+ void hypergraph::add_vertex (unsigned weight = 0 )
92+ {
93+ vertex_weights.push_back (weight);
94+ incident_hyperedges_to_vertex.emplace_back ();
95+ ++Num_vertices;
96+ }
97+
98+ void hypergraph::add_empty_hyperedge ()
99+ {
100+ vertices_in_hyperedge.emplace_back ();
101+ ++Num_hyperedges;
102+ }
103+
104+ void hypergraph::add_hyperedge (const std::vector<unsigned >& pins)
105+ {
106+ vertices_in_hyperedge.emplace_back (pins);
107+ for (unsigned vertex : pins)
108+ incident_hyperedges_to_vertex[vertex].push_back (Num_hyperedges);
109+ ++Num_hyperedges;
110+ Num_pins += pins.size ();
111+ }
112+
113+ void hypergraph::set_vertex_weight (unsigned vertex_idx, int weight)
114+ {
115+ if (vertex_idx >= Num_vertices)
116+ throw std::invalid_argument (" Invalid Argument while setting vertex weight: vertex index out of range." );
117+ else
118+ vertex_weights[vertex_idx] = weight;
119+ }
120+
121+ void hypergraph::clear ()
122+ {
123+ Num_vertices = 0 ;
124+ Num_hyperedges = 0 ;
125+ Num_pins = 0 ;
126+
127+ vertex_weights.clear ();
128+ incident_hyperedges_to_vertex.clear ();
129+ vertices_in_hyperedge.clear ();
130+ }
131+
132+ void hypergraph::reset (unsigned num_vertices_, unsigned num_hyperedges_)
133+ {
134+ clear ();
135+
136+ Num_vertices = num_vertices_;
137+ Num_hyperedges = num_hyperedges_;
138+
139+ vertex_weights.resize (num_vertices_, 0 );
140+ incident_hyperedges_to_vertex.resize (num_vertices_);
141+ vertices_in_hyperedge.resize (num_hyperedges_);
142+ }
143+
144+ template <typename Graph_t>
145+ void convert_from_cdag_as_dag (const Graph_t& dag)
146+ {
147+ reset (dag.num_vertices (), dag.num_edges ());
148+ for (const auto &node : dag.vertices ())
149+ {
150+ set_vertex_weight (node, dag.vertex_work_weight (node));
151+ for (const auto &child : dag.children (node))
152+ add_hyperedge ({node, child});
153+ }
154+ }
155+
156+ template <typename Graph_t>
157+ void convert_from_cdag_as_hyperdag (const Graph_t& dag)
158+ {
159+ unsigned nr_of_non_sinks = 0 ;
160+ for (const auto &node : dag.vertices ())
161+ if (dag.out_degree (node) > 0 )
162+ ++ nr_of_non_sinks;
163+
164+ reset (dag.num_vertices (), nr_of_non_sinks);
165+ for (const auto &node : dag.vertices ())
166+ {
167+ set_vertex_weight (node, dag.vertex_work_weight (node));
168+ if (dag.out_degree (node) == 0 )
169+ continue ;
170+ std::vector<unsigned > new_hyperedge ({node});
171+ for (const auto &child : dag.children (node))
172+ new_hyperedge.push_back (child);
173+ add_hyperedge (new_hyperedge);
174+ }
175+ }
176+
177+ } // namespace osp
0 commit comments