Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/cc-cuda/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
const int repeat = atoi(argv[2]);

int* nodestatus = NULL;
Expand Down
1 change: 1 addition & 0 deletions src/cc-hip/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
const int repeat = atoi(argv[2]);

int* nodestatus = NULL;
Expand Down
1 change: 1 addition & 0 deletions src/cc-sycl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
const int repeat = atoi(argv[2]);

int* nodestatus = (int*) malloc (sizeof(int) * g.nodes);
Expand Down
1 change: 1 addition & 0 deletions src/gc-cuda/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
printf("input: %s\n", argv[1]);
printf("nodes: %d\n", g.nodes);
printf("edges: %d\n", g.edges);
Expand Down
1 change: 1 addition & 0 deletions src/gc-hip/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
printf("input: %s\n", argv[1]);
printf("nodes: %d\n", g.nodes);
printf("edges: %d\n", g.edges);
Expand Down
1 change: 1 addition & 0 deletions src/gc-omp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ int main(int argc, char* argv[])
const int repeat = atoi(argv[3]);

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
printf("input: %s\n", argv[1]);
printf("nodes: %d\n", g.nodes);
printf("edges: %d\n", g.edges);
Expand Down
1 change: 1 addition & 0 deletions src/gc-sycl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ int main(int argc, char *argv[]) {

printf("input: %s\n", argv[1]);
ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);

const int nodes = g.nodes;
const int edges = g.edges;
Expand Down
75 changes: 62 additions & 13 deletions src/mis-cuda/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ void freeECLgraph(ECLgraph &g)
ECLgraph readECLgraph(const char* const fname)
{
ECLgraph g;
int cnt;
size_t cnt;
size_t nodes1; // g.nodes + 1 computed in size_t to avoid overflowing int
int error_status = 0;
FILE* f = fopen(fname, "rb");
if (f == NULL) {
Expand All @@ -78,18 +79,19 @@ ECLgraph readECLgraph(const char* const fname)
exit(-1);
}

g.nindex = (int*)malloc((g.nodes + 1) * sizeof(g.nindex[0]));
g.nlist = (int*)malloc(g.edges * sizeof(g.nlist[0]));
g.eweight = (int*)malloc(g.edges * sizeof(g.eweight[0]));
nodes1 = (size_t)g.nodes + 1;
g.nindex = (int*)malloc(nodes1 * sizeof(g.nindex[0]));
g.nlist = (int*)malloc((size_t)g.edges * sizeof(g.nlist[0]));
g.eweight = (int*)malloc((size_t)g.edges * sizeof(g.eweight[0]));
if ((g.nindex == NULL) || (g.nlist == NULL) || (g.eweight == NULL)) {
fprintf(stderr, "ERROR: memory allocation failed\n\n");
error_status = 1;
goto release;
}

// check g.nindex
cnt = fread(g.nindex, sizeof(g.nindex[0]), g.nodes + 1, f);
if (cnt != g.nodes + 1) {
cnt = fread(g.nindex, sizeof(g.nindex[0]), nodes1, f);
if (cnt != nodes1) {
fprintf(stderr, "ERROR: failed to read neighbor index list\n\n");
error_status = 1;
goto release;
Expand All @@ -113,34 +115,33 @@ ECLgraph readECLgraph(const char* const fname)
}

// check g.nlist
cnt = fread(g.nlist, sizeof(g.nlist[0]), g.edges, f);
if (cnt != g.edges) {
cnt = fread(g.nlist, sizeof(g.nlist[0]), (size_t)g.edges, f);
if (cnt != (size_t)g.edges) {
fprintf(stderr, "ERROR: failed to read neighbor list\n\n");
error_status = 1;
goto release;
}
for (int v = 0; v < g.edges; v++) {
if (g.nlist[v] >= g.nodes) {
if ((g.nlist[v] < 0) || (g.nlist[v] >= g.nodes)) {
fprintf(stderr, "ERROR: value in neighbor list must be a valide node index\n");
error_status = 1;
goto release;
}
}

// check g.eweight (cnt = 0 is fine)
cnt = fread(g.eweight, sizeof(g.eweight[0]), g.edges, f);
cnt = fread(g.eweight, sizeof(g.eweight[0]), (size_t)g.edges, f);
if (cnt == 0) {
free(g.eweight);
g.eweight = NULL;
}
else if (cnt != g.edges) {
else if (cnt != (size_t)g.edges) {
error_status = 1;
fprintf(stderr, "ERROR: failed to read edge weights\n\n");
}

fclose(f);

release:
fclose(f);
if (error_status) {
freeECLgraph(g);
exit(-1);
Expand All @@ -149,4 +150,52 @@ ECLgraph readECLgraph(const char* const fname)
return g;
}


/* Algorithms such as ECL-MIS require a simple undirected graph: a node that is
its own neighbor, or an edge that is stored in only one of its two
directions, makes them spin forever waiting on a node that can never be
resolved. Graphs that are legitimately directed (used by, e.g.,
floydwarshall2) must not be passed to this check. */

void verifyUndirectedECLgraph(ECLgraph &g)
{
for (int v = 0; v < g.nodes; v++) {
for (int i = g.nindex[v]; i < g.nindex[v + 1]; i++) {
if (g.nlist[i] == v) {
fprintf(stderr, "ERROR: neighbor list must not contain self loops\n");
freeECLgraph(g);
exit(-1);
}
if ((i > g.nindex[v]) && (g.nlist[i - 1] >= g.nlist[i])) {
fprintf(stderr, "ERROR: neighbor list of each node must be sorted in increasing order\n");
freeECLgraph(g);
exit(-1);
}
}
}

// the sorted neighbor lists allow the reverse edge to be located by bisection
for (int v = 0; v < g.nodes; v++) {
for (int i = g.nindex[v]; i < g.nindex[v + 1]; i++) {
const int u = g.nlist[i];
int lo = g.nindex[u];
int hi = g.nindex[u + 1] - 1;
int found = 0;
while (lo <= hi) {
const int mid = lo + (hi - lo) / 2;
if (g.nlist[mid] == v) {
found = 1;
break;
}
if (g.nlist[mid] < v) lo = mid + 1; else hi = mid - 1;
}
if (!found) {
fprintf(stderr, "ERROR: graph must be undirected, edge %d -> %d is not matched by %d -> %d\n", v, u, u, v);
freeECLgraph(g);
exit(-1);
}
}
}
}

#endif
1 change: 1 addition & 0 deletions src/mis-cuda/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
printf("configuration: %d nodes and %d edges (%s)\n", g.nodes, g.edges, argv[1]);
printf("average degree: %.2f edges per node\n", 1.0 * g.edges / g.nodes);

Expand Down
1 change: 1 addition & 0 deletions src/mis-hip/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
printf("configuration: %d nodes and %d edges (%s)\n", g.nodes, g.edges, argv[1]);
printf("average degree: %.2f edges per node\n", 1.0 * g.edges / g.nodes);

Expand Down
1 change: 1 addition & 0 deletions src/mis-omp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
printf("configuration: %d nodes and %d edges (%s)\n", g.nodes, g.edges, argv[1]);
printf("average degree: %.2f edges per node\n", 1.0 * g.edges / g.nodes);

Expand Down
1 change: 1 addition & 0 deletions src/mis-sycl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ int main(int argc, char* argv[])
}

ECLgraph g = readECLgraph(argv[1]);
verifyUndirectedECLgraph(g);
printf("configuration: %d nodes and %d edges (%s)\n", g.nodes, g.edges, argv[1]);
printf("average degree: %.2f edges per node\n", 1.0 * g.edges / g.nodes);

Expand Down