FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_graph.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
13 #include "hecmw_graph.h"
14 #include "hecmw_varray_int.h"
15 #include "hecmw_malloc.h"
16 #include "hecmw_config.h"
17 #include "hecmw_util.h"
18 #include <stdio.h>
19 #include <errno.h>
20 
21 /*********************************
22  * Prototype of static functions *
23  *********************************/
24 
27 static void clear(struct hecmw_graph *graph
28  );
29 
35 static int find_edge(const struct hecmw_graph *graph,
36  int vert1,
37  int vert2,
38  idx_t *idx
39  );
40 
46 static int add_edge_one_way(struct hecmw_graph *graph,
47  int vert1,
48  int vert2
49  );
50 
51 /**********************************
52  * Definition of public functions *
53  **********************************/
54 
55 int HECMW_graph_init(struct hecmw_graph *graph) {
56  graph->m_num_vertex = 0;
57  graph->m_num_edge = 0;
58  graph->is_ref = 0;
59  graph->m_edge_index =
60  (struct hecmw_varray_idx *)HECMW_malloc(sizeof(struct hecmw_varray_idx));
61  graph->m_edge_item =
62  (struct hecmw_varray_idx *)HECMW_malloc(sizeof(struct hecmw_varray_idx));
63  if (graph->m_edge_index == NULL || graph->m_edge_item == NULL) {
64  HECMW_set_error(errno, "");
65  return HECMW_ERROR;
66  }
69  return HECMW_SUCCESS;
70  return HECMW_ERROR;
71 }
72 
73 int HECMW_graph_init_with_arrays(struct hecmw_graph *graph, int num_vertex,
74  idx_t *edge_index, idx_t *edge_item) {
75  graph->m_num_vertex = num_vertex;
76  graph->m_num_edge = edge_index[num_vertex];
77  graph->m_edge_index =
78  (struct hecmw_varray_idx *)HECMW_malloc(sizeof(struct hecmw_varray_idx));
79  graph->m_edge_item =
80  (struct hecmw_varray_idx *)HECMW_malloc(sizeof(struct hecmw_varray_idx));
81  if (graph->m_edge_index == NULL || graph->m_edge_item == NULL) {
82  HECMW_set_error(errno, "");
83  return HECMW_ERROR;
84  }
85  graph->m_edge_index->n_val = num_vertex + 1;
86  graph->m_edge_index->max_val = num_vertex + 1;
87  graph->m_edge_index->vals = edge_index;
88 
89  graph->m_edge_item->n_val = graph->m_num_edge;
90  graph->m_edge_item->max_val = graph->m_num_edge;
91  graph->m_edge_item->vals = edge_item;
92 
93  graph->is_ref = 1;
94  return HECMW_SUCCESS;
95 }
96 
97 void HECMW_graph_finalize(struct hecmw_graph *graph) {
98  if (!graph->is_ref) {
101  }
102  HECMW_free(graph->m_edge_index);
103  HECMW_free(graph->m_edge_item);
104 }
105 
106 void HECMW_graph_setNumVertex(struct hecmw_graph *graph, int num_vertex) {
107  HECMW_assert(!graph->is_ref);
108 
109  graph->m_num_vertex = num_vertex;
110  HECMW_varray_idx_resize(graph->m_edge_index, num_vertex + 1);
111  HECMW_varray_idx_assign(graph->m_edge_index, 0, num_vertex + 1, 0);
112 }
113 
114 int HECMW_graph_addEdge(struct hecmw_graph *graph, int vert1, int vert2) {
115  HECMW_assert(!graph->is_ref);
116 
117  if (add_edge_one_way(graph, vert1, vert2) == HECMW_SUCCESS &&
118  add_edge_one_way(graph, vert2, vert1) == HECMW_SUCCESS)
119  return HECMW_SUCCESS;
120  return HECMW_ERROR;
121 }
122 
123 void HECMW_graph_print(const struct hecmw_graph *graph, FILE *fp) {
124  const idx_t *edge_index = HECMW_varray_idx_get_cv(graph->m_edge_index);
125  const idx_t *edge_item = HECMW_varray_idx_get_cv(graph->m_edge_item);
126  int i;
127  idx_t j;
128  idx_t idx_start, idx_end;
129 
130  fprintf(fp, "num_vertex = %d\n", graph->m_num_vertex);
131  fprintf(fp, "num_edge = %lld\n", (long long)graph->m_num_edge);
132 
133  for (i = 0; i < graph->m_num_vertex; i++) {
134  fprintf(fp, "%d: ", i);
135 
136  idx_start = edge_index[i];
137  idx_end = edge_index[i + 1];
138  for (j = idx_start; j < idx_end; j++) {
139  fprintf(fp, " %lld", (long long)edge_item[j]);
140  }
141  fprintf(fp, "\n");
142  }
143 }
144 
145 int HECMW_graph_getNumVertex(const struct hecmw_graph *graph) {
146  return graph->m_num_vertex;
147 }
148 
150  return graph->m_num_edge;
151 }
152 
153 const idx_t *HECMW_graph_getEdgeIndex(const struct hecmw_graph *graph) {
154  return HECMW_varray_idx_get_cv(graph->m_edge_index);
155 }
156 
157 const idx_t *HECMW_graph_getEdgeItem(const struct hecmw_graph *graph) {
158  return HECMW_varray_idx_get_cv(graph->m_edge_item);
159 }
160 
162  const struct hecmw_graph *refgraph, int num_part,
163  const int *parttab) {
164  const idx_t *ref_edge_index = HECMW_varray_idx_get_cv(refgraph->m_edge_index);
165  const idx_t *ref_edge_item = HECMW_varray_idx_get_cv(refgraph->m_edge_item);
166  int i, jj;
167  idx_t j;
168  int i_part, j_part;
169  idx_t start, end;
170  int retval;
171 
172  struct hecmw_varray_int *lists;
173  size_t n_edge;
174  idx_t *edge_index;
175  idx_t *edge_item;
176 
177  lists = (struct hecmw_varray_int *)HECMW_malloc(
178  sizeof(struct hecmw_varray_int) * num_part);
179  if (lists == NULL) {
180  HECMW_set_error(errno, "");
181  return HECMW_ERROR;
182  }
183  for (i = 0; i < num_part; i++) {
184  retval = HECMW_varray_int_init(lists + i);
185  if (retval != HECMW_SUCCESS) goto error;
186  }
187 
188  for (i = 0; i < HECMW_graph_getNumVertex(refgraph); i++) {
189  i_part = parttab[i];
190  start = ref_edge_index[i];
191  end = ref_edge_index[i + 1];
192  for (j = start; j < end; j++) {
193  jj = ref_edge_item[j];
194  j_part = parttab[jj];
195  if (i_part == j_part) continue;
196  retval = HECMW_varray_int_append(lists + i_part, j_part);
197  if (retval != HECMW_SUCCESS) goto error;
198  retval = HECMW_varray_int_append(lists + j_part, i_part);
199  if (retval != HECMW_SUCCESS) goto error;
200  }
201  }
202 
203  clear(graph);
204  HECMW_graph_setNumVertex(graph, num_part);
205  edge_index = HECMW_varray_idx_get_v(graph->m_edge_index);
206 
207  edge_index[0] = 0;
208  for (i = 0; i < num_part; i++) {
209  HECMW_varray_int_sort(lists + i);
210  HECMW_varray_int_uniq(lists + i);
211  n_edge = HECMW_varray_int_nval(lists + i);
212  edge_index[i + 1] = edge_index[i] + n_edge;
213  }
214  graph->m_num_edge = edge_index[num_part];
216  edge_item = HECMW_varray_idx_get_v(graph->m_edge_item);
217  for (i = 0; i < num_part; i++) {
218  start = edge_index[i];
219  n_edge = HECMW_varray_int_nval(lists + i);
220  for (j = 0; j < n_edge; j++) {
221  edge_item[start + j] = HECMW_varray_int_get(lists + i, j);
222  }
223  }
224 
225  for (i = 0; i < num_part; i++) {
226  HECMW_varray_int_finalize(lists + i);
227  }
228  HECMW_free(lists);
229  return HECMW_SUCCESS;
230 
231 error:
232  if (lists) {
233  for (i = 0; i < num_part; i++) {
234  HECMW_varray_int_finalize(lists + i);
235  }
236  HECMW_free(lists);
237  }
238  return HECMW_ERROR;
239 }
240 
241 /***********************************
242  * Definition of private functions *
243  ***********************************/
244 
245 void clear(struct hecmw_graph *graph) {
246  graph->m_num_vertex = 0;
247  graph->m_num_edge = 0;
250  graph->is_ref = 0;
251 }
252 
253 int find_edge(const struct hecmw_graph *graph, int vert1, int vert2,
254  idx_t *idx) {
255  const idx_t *edge_index = HECMW_varray_idx_get_cv(graph->m_edge_index);
256  const idx_t *edge_item = HECMW_varray_idx_get_cv(graph->m_edge_item);
257  idx_t idx_start, idx_end;
258  idx_t i;
259 
260  idx_start = edge_index[vert1];
261  idx_end = edge_index[vert1 + 1];
262  for (i = idx_start; i < idx_end; i++) {
263  if (edge_item[i] == vert2) {
264  if (idx) *idx = i;
265  return 1;
266  }
267  }
268  return 0;
269 }
270 
271 int add_edge_one_way(struct hecmw_graph *graph, int vert1, int vert2) {
272  idx_t *edge_index = HECMW_varray_idx_get_v(graph->m_edge_index);
273  idx_t idx;
274  int i;
275  int retval;
276 
277  HECMW_assert(!graph->is_ref);
278 
279  if (find_edge(graph, vert1, vert2, &idx)) {
280  return HECMW_SUCCESS;
281  }
282  /* insert vert2 into m_edge_item */
283  /* place to insert: m_edge_inidex[vert1 + 1] */
284  retval =
285  HECMW_varray_idx_insert(graph->m_edge_item, edge_index[vert1 + 1], vert2);
286  if (retval != HECMW_SUCCESS) {
287  return HECMW_ERROR;
288  }
289 
290  /* increment m_edge_index[vert1 + 1 .. n_num_vertex] */
291  for (i = vert1 + 1; i <= graph->m_num_vertex; i++) {
292  edge_index[i] += 1;
293  }
294  graph->m_num_edge++;
295  return HECMW_SUCCESS;
296 }
#define HECMW_ERROR
Definition: hecmw_config.h:68
#define HECMW_SUCCESS
Definition: hecmw_config.h:66
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:33
int HECMW_graph_degeneGraph(struct hecmw_graph *graph, const struct hecmw_graph *refgraph, int num_part, const int *parttab)
Definition: hecmw_graph.c:161
const idx_t * HECMW_graph_getEdgeItem(const struct hecmw_graph *graph)
Definition: hecmw_graph.c:157
idx_t HECMW_graph_getNumEdge(const struct hecmw_graph *graph)
Definition: hecmw_graph.c:149
const idx_t * HECMW_graph_getEdgeIndex(const struct hecmw_graph *graph)
Definition: hecmw_graph.c:153
int HECMW_graph_addEdge(struct hecmw_graph *graph, int vert1, int vert2)
Definition: hecmw_graph.c:114
int HECMW_graph_getNumVertex(const struct hecmw_graph *graph)
Definition: hecmw_graph.c:145
int HECMW_graph_init_with_arrays(struct hecmw_graph *graph, int num_vertex, idx_t *edge_index, idx_t *edge_item)
Definition: hecmw_graph.c:73
void HECMW_graph_print(const struct hecmw_graph *graph, FILE *fp)
Definition: hecmw_graph.c:123
void HECMW_graph_finalize(struct hecmw_graph *graph)
Definition: hecmw_graph.c:97
void HECMW_graph_setNumVertex(struct hecmw_graph *graph, int num_vertex)
Definition: hecmw_graph.c:106
int HECMW_graph_init(struct hecmw_graph *graph)
Definition: hecmw_graph.c:55
Graph utility.
#define NULL
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
void HECMW_varray_idx_finalize(struct hecmw_varray_idx *varray)
idx_t * HECMW_varray_idx_get_v(struct hecmw_varray_idx *varray)
int HECMW_varray_idx_assign(struct hecmw_varray_idx *varray, size_t begin, size_t end, idx_t val)
int HECMW_varray_idx_insert(struct hecmw_varray_idx *varray, size_t index, idx_t val)
int HECMW_varray_idx_resize(struct hecmw_varray_idx *varray, size_t len)
int HECMW_varray_idx_init(struct hecmw_varray_idx *varray)
const idx_t * HECMW_varray_idx_get_cv(const struct hecmw_varray_idx *varray)
long long idx_t
size_t HECMW_varray_int_nval(const struct hecmw_varray_int *varray)
size_t HECMW_varray_int_uniq(struct hecmw_varray_int *varray)
void HECMW_varray_int_sort(struct hecmw_varray_int *varray)
int HECMW_varray_int_get(const struct hecmw_varray_int *varray, size_t index)
int HECMW_varray_int_init(struct hecmw_varray_int *varray)
void HECMW_varray_int_finalize(struct hecmw_varray_int *varray)
int HECMW_varray_int_append(struct hecmw_varray_int *varray, int value)
int m_num_vertex
Definition: hecmw_graph.h:26
struct hecmw_varray_idx * m_edge_index
Definition: hecmw_graph.h:28
struct hecmw_varray_idx * m_edge_item
Definition: hecmw_graph.h:30
idx_t m_num_edge
Definition: hecmw_graph.h:27