replace some c++ with c
This commit is contained in:
parent
d0d0f8140a
commit
d7d251bac5
2 changed files with 69 additions and 51 deletions
|
@ -7,6 +7,9 @@ CFLAGS += -O3 -g
|
||||||
clean:
|
clean:
|
||||||
rm -f lpa
|
rm -f lpa
|
||||||
|
|
||||||
|
lpac: lpa.cpp
|
||||||
|
mpicc $(CFLAGS) $(LDFLAGS) -o $@ $<
|
||||||
|
|
||||||
lpa: lpa.cpp
|
lpa: lpa.cpp
|
||||||
mpic++ $(CFLAGS) $(LDFLAGS) -o $@ $<
|
mpic++ $(CFLAGS) $(LDFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,14 @@ void pair_vector_init(struct pair_vector *);
|
||||||
void pair_vector_clear(struct pair_vector *);
|
void pair_vector_clear(struct pair_vector *);
|
||||||
void pair_vector_push(struct pair_vector *v, int fst, int snd);
|
void pair_vector_push(struct pair_vector *v, int fst, int snd);
|
||||||
|
|
||||||
|
pair compute_node_range(int p, int total_num_nodes, int each_num_nodes,
|
||||||
|
int process);
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
MPI::Init(argc, argv);
|
MPI_Init(&argc, &argv);
|
||||||
int rank = MPI::COMM_WORLD.Get_rank(), p = MPI::COMM_WORLD.Get_size();
|
int rank, p;
|
||||||
|
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
||||||
|
MPI_Comm_size(MPI_COMM_WORLD, &p);
|
||||||
|
|
||||||
MPI_Datatype IntPairType;
|
MPI_Datatype IntPairType;
|
||||||
init_pair_type(&IntPairType);
|
init_pair_type(&IntPairType);
|
||||||
|
@ -53,15 +58,15 @@ int main(int argc, char **argv) {
|
||||||
pair params;
|
pair params;
|
||||||
|
|
||||||
if (rank == 0) {
|
if (rank == 0) {
|
||||||
|
|
||||||
printf("Hello\n");
|
|
||||||
fp = fopen(argv[1], "r");
|
fp = fopen(argv[1], "r");
|
||||||
if ((read = getline(&line, &len, fp)) != -1)
|
|
||||||
|
// Read the first line
|
||||||
|
if (getline(&line, &len, fp) != -1)
|
||||||
sscanf(line, "%d %d", ¶ms.fst, ¶ms.snd);
|
sscanf(line, "%d %d", ¶ms.fst, ¶ms.snd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the params
|
// Send the params
|
||||||
MPI_Bcast(¶ms, 1, IntPairType, 0, MPI::COMM_WORLD);
|
MPI_Bcast(¶ms, 1, IntPairType, 0, MPI_COMM_WORLD);
|
||||||
int total_num_nodes = params.fst;
|
int total_num_nodes = params.fst;
|
||||||
int total_num_edges = params.snd;
|
int total_num_edges = params.snd;
|
||||||
int each_num_nodes = total_num_nodes / p;
|
int each_num_nodes = total_num_nodes / p;
|
||||||
|
@ -71,12 +76,12 @@ int main(int argc, char **argv) {
|
||||||
rank == p - 1 ? total_num_nodes - rank * each_num_nodes : each_num_nodes;
|
rank == p - 1 ? total_num_nodes - rank * each_num_nodes : each_num_nodes;
|
||||||
int my_nodes[num_my_nodes];
|
int my_nodes[num_my_nodes];
|
||||||
|
|
||||||
std::function<std::pair<int, int>(int)> node_range =
|
// std::function<std::pair<int, int>(int)> node_range =
|
||||||
[p, total_num_nodes, each_num_nodes](int process) {
|
// [p, total_num_nodes, each_num_nodes](int process) {
|
||||||
int start = process * each_num_nodes;
|
// int start = process * each_num_nodes;
|
||||||
int end = process == p - 1 ? total_num_nodes : start + each_num_nodes;
|
// int end = process == p - 1 ? total_num_nodes : start +
|
||||||
return std::make_pair(start, end);
|
// each_num_nodes; return std::make_pair(start, end);
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Read the edges
|
// Read the edges
|
||||||
int num_my_edges;
|
int num_my_edges;
|
||||||
|
@ -90,30 +95,33 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
// For the current process, what's the last node we're expecting to see?
|
// For the current process, what's the last node we're expecting to see?
|
||||||
int current_process = 0;
|
int current_process = 0;
|
||||||
std::pair<int, int> current_node_range = node_range(current_process);
|
pair current_node_range =
|
||||||
|
compute_node_range(p, total_num_nodes, each_num_nodes, current_process);
|
||||||
int edge_counter = 0;
|
int edge_counter = 0;
|
||||||
|
|
||||||
for (int i = 0; i < total_num_edges; ++i) {
|
for (int i = 0; i < total_num_edges; ++i) {
|
||||||
getline(&line, &len, fp);
|
if (getline(&line, &len, fp) == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
int fst, snd;
|
int fst, snd;
|
||||||
sscanf(line, "%d %d", &fst, &snd);
|
sscanf(line, "%d %d", &fst, &snd);
|
||||||
|
|
||||||
if (fst >= current_node_range.second) {
|
if (fst >= current_node_range.snd) {
|
||||||
if (current_process == 0) {
|
if (current_process == 0) {
|
||||||
num_my_edges = edge_counter;
|
num_my_edges = edge_counter;
|
||||||
my_edges = (pair *)calloc(num_my_edges, sizeof(pair));
|
my_edges = (pair *)calloc(num_my_edges, sizeof(pair));
|
||||||
memcpy(my_edges, all_edges.ptr, edge_counter * sizeof(pair));
|
memcpy(my_edges, all_edges.ptr, edge_counter * sizeof(pair));
|
||||||
} else {
|
} else {
|
||||||
MPI_Send(&edge_counter, 1, MPI_INT, current_process,
|
MPI_Send(&edge_counter, 1, MPI_INT, current_process,
|
||||||
TAG_SEND_NUM_EDGES, MPI::COMM_WORLD);
|
TAG_SEND_NUM_EDGES, MPI_COMM_WORLD);
|
||||||
MPI_Send(all_edges.ptr, edge_counter, IntPairType, current_process,
|
MPI_Send(all_edges.ptr, edge_counter, IntPairType, current_process,
|
||||||
TAG_SEND_EDGES, MPI::COMM_WORLD);
|
TAG_SEND_EDGES, MPI_COMM_WORLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're starting on the next process
|
// We're starting on the next process
|
||||||
current_process += 1;
|
current_process += 1;
|
||||||
current_node_range = node_range(current_process);
|
current_node_range = compute_node_range(
|
||||||
|
p, total_num_nodes, each_num_nodes, current_process);
|
||||||
edge_counter = 0;
|
edge_counter = 0;
|
||||||
pair_vector_clear(&all_edges);
|
pair_vector_clear(&all_edges);
|
||||||
}
|
}
|
||||||
|
@ -125,15 +133,17 @@ int main(int argc, char **argv) {
|
||||||
// We have to send the last one again here, since it didn't get caught in
|
// We have to send the last one again here, since it didn't get caught in
|
||||||
// the loop above
|
// the loop above
|
||||||
MPI_Send(&edge_counter, 1, MPI_INT, current_process, TAG_SEND_NUM_EDGES,
|
MPI_Send(&edge_counter, 1, MPI_INT, current_process, TAG_SEND_NUM_EDGES,
|
||||||
MPI::COMM_WORLD);
|
MPI_COMM_WORLD);
|
||||||
MPI_Send(all_edges.ptr, edge_counter, IntPairType, current_process,
|
MPI_Send(all_edges.ptr, edge_counter, IntPairType, current_process,
|
||||||
TAG_SEND_EDGES, MPI::COMM_WORLD);
|
TAG_SEND_EDGES, MPI_COMM_WORLD);
|
||||||
|
|
||||||
|
free(all_edges.ptr);
|
||||||
} else {
|
} else {
|
||||||
MPI_Recv(&num_my_edges, 1, MPI_INT, 0, TAG_SEND_NUM_EDGES, MPI::COMM_WORLD,
|
MPI_Recv(&num_my_edges, 1, MPI_INT, 0, TAG_SEND_NUM_EDGES, MPI_COMM_WORLD,
|
||||||
NULL);
|
NULL);
|
||||||
my_edges = (pair *)calloc(num_my_edges, sizeof(pair));
|
my_edges = (pair *)calloc(num_my_edges, sizeof(pair));
|
||||||
MPI_Recv(my_edges, num_my_edges, IntPairType, 0, TAG_SEND_EDGES,
|
MPI_Recv(my_edges, num_my_edges, IntPairType, 0, TAG_SEND_EDGES,
|
||||||
MPI::COMM_WORLD, NULL);
|
MPI_COMM_WORLD, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *buf = (char *)calloc(sizeof(char), 1000);
|
char *buf = (char *)calloc(sizeof(char), 1000);
|
||||||
|
@ -155,17 +165,18 @@ int main(int argc, char **argv) {
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
// STEP 2 TIMER STARTS HERE
|
// STEP 2 TIMER STARTS HERE
|
||||||
MPI::COMM_WORLD.Barrier();
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
double step_2_start_time = MPI::Wtime();
|
double step_2_start_time = MPI_Wtime();
|
||||||
|
|
||||||
// Each process analyzes the non-local edges that are contained in its portion
|
// Each process analyzes the non-local edges that are contained in its portion
|
||||||
// of the graph.
|
// of the graph.
|
||||||
#pragma region
|
#pragma region
|
||||||
std::map<int, int> node_label_assignment;
|
std::map<int, int> node_label_assignment;
|
||||||
std::pair<int, int> my_node_range = node_range(rank);
|
pair my_node_range =
|
||||||
|
compute_node_range(p, total_num_nodes, each_num_nodes, rank);
|
||||||
|
|
||||||
// Initial node assignment
|
// Initial node assignment
|
||||||
for (int i = my_node_range.first; i < my_node_range.second; ++i) {
|
for (int i = my_node_range.fst; i < my_node_range.snd; ++i) {
|
||||||
node_label_assignment[i] = i;
|
node_label_assignment[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,12 +188,12 @@ int main(int argc, char **argv) {
|
||||||
pair edge = my_edges[i];
|
pair edge = my_edges[i];
|
||||||
adj[edge.fst].insert(edge.snd);
|
adj[edge.fst].insert(edge.snd);
|
||||||
|
|
||||||
if (!(my_node_range.first <= edge.fst && edge.fst < my_node_range.second)) {
|
if (!(my_node_range.fst <= edge.fst && edge.fst < my_node_range.snd)) {
|
||||||
non_local_nodes.insert(edge.fst);
|
non_local_nodes.insert(edge.fst);
|
||||||
non_local_edges.insert(std::make_pair(edge.snd, edge.fst));
|
non_local_edges.insert(std::make_pair(edge.snd, edge.fst));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(my_node_range.first <= edge.snd && edge.snd < my_node_range.second)) {
|
if (!(my_node_range.fst <= edge.snd && edge.snd < my_node_range.snd)) {
|
||||||
non_local_nodes.insert(edge.snd);
|
non_local_nodes.insert(edge.snd);
|
||||||
non_local_edges.insert(std::make_pair(edge.fst, edge.snd));
|
non_local_edges.insert(std::make_pair(edge.fst, edge.snd));
|
||||||
}
|
}
|
||||||
|
@ -214,8 +225,8 @@ int main(int argc, char **argv) {
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
// STEP 5 TIMER STARTS HERE
|
// STEP 5 TIMER STARTS HERE
|
||||||
MPI::COMM_WORLD.Barrier();
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
double step_5_start_time = MPI::Wtime();
|
double step_5_start_time = MPI_Wtime();
|
||||||
|
|
||||||
// The processes perform the transfers of non-local labels and updates of
|
// The processes perform the transfers of non-local labels and updates of
|
||||||
// local labels until convergence.
|
// local labels until convergence.
|
||||||
|
@ -254,13 +265,9 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> recvbuf(recv_total, 0);
|
std::vector<int> recvbuf(recv_total, 0);
|
||||||
// std::cout << fmt::format("[{}] {} \t|| \t{}", rank,
|
MPI_Alltoallv(sendbuf.data(), send_counts.data(), send_displs.data(),
|
||||||
// fmt::join(send_counts, ", "),
|
MPI_INT, recvbuf.data(), recv_counts.data(),
|
||||||
// fmt::join(recv_counts, ", "))
|
recv_displs.data(), MPI_INT, MPI_COMM_WORLD);
|
||||||
// << std::endl;
|
|
||||||
MPI::COMM_WORLD.Alltoallv(sendbuf.data(), send_counts.data(),
|
|
||||||
send_displs.data(), MPI_INT, recvbuf.data(),
|
|
||||||
recv_counts.data(), recv_displs.data(), MPI_INT);
|
|
||||||
|
|
||||||
std::map<int, int> total_node_label_assignment(node_label_assignment);
|
std::map<int, int> total_node_label_assignment(node_label_assignment);
|
||||||
for (int i = 0; i < p; ++i) {
|
for (int i = 0; i < p; ++i) {
|
||||||
|
@ -274,7 +281,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
// For each local node, determine the minimum label out of its neighbors
|
// For each local node, determine the minimum label out of its neighbors
|
||||||
std::map<int, int> new_labels;
|
std::map<int, int> new_labels;
|
||||||
for (int i = my_node_range.first; i < my_node_range.second; ++i) {
|
for (int i = my_node_range.fst; i < my_node_range.snd; ++i) {
|
||||||
int current_value = total_node_label_assignment[i];
|
int current_value = total_node_label_assignment[i];
|
||||||
int min = current_value;
|
int min = current_value;
|
||||||
|
|
||||||
|
@ -313,8 +320,8 @@ int main(int argc, char **argv) {
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
// END TIMERS
|
// END TIMERS
|
||||||
MPI::COMM_WORLD.Barrier();
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
double end_time = MPI::Wtime();
|
double end_time = MPI_Wtime();
|
||||||
|
|
||||||
if (rank == 0) {
|
if (rank == 0) {
|
||||||
printf("2-5 Time: %0.04fs\n", end_time - step_2_start_time);
|
printf("2-5 Time: %0.04fs\n", end_time - step_2_start_time);
|
||||||
|
@ -329,19 +336,20 @@ int main(int argc, char **argv) {
|
||||||
std::map<int, int> label_count;
|
std::map<int, int> label_count;
|
||||||
int ctr = 0;
|
int ctr = 0;
|
||||||
for (int i = 0; i < p; ++i) {
|
for (int i = 0; i < p; ++i) {
|
||||||
std::pair<int, int> this_node_range = node_range(i);
|
pair this_node_range =
|
||||||
int count = this_node_range.second - this_node_range.first;
|
compute_node_range(p, total_num_nodes, each_num_nodes, i);
|
||||||
|
int count = this_node_range.snd - this_node_range.fst;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
for (int j = 0; j < count; ++j) {
|
for (int j = 0; j < count; ++j) {
|
||||||
all_assignments[this_node_range.first + j] =
|
all_assignments[this_node_range.fst + j] =
|
||||||
node_label_assignment[this_node_range.first + j];
|
node_label_assignment[this_node_range.fst + j];
|
||||||
label_count[all_assignments[this_node_range.first + j]]++;
|
label_count[all_assignments[this_node_range.fst + j]]++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MPI::COMM_WORLD.Recv(&all_assignments[this_node_range.first], count,
|
MPI::COMM_WORLD.Recv(&all_assignments[this_node_range.fst], count,
|
||||||
MPI::INT, i, TAG_SEND_FINAL_RESULT);
|
MPI_INT, i, TAG_SEND_FINAL_RESULT);
|
||||||
for (int j = 0; j < count; ++j) {
|
for (int j = 0; j < count; ++j) {
|
||||||
label_count[all_assignments[this_node_range.first + j]]++;
|
label_count[all_assignments[this_node_range.fst + j]]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,15 +357,15 @@ int main(int argc, char **argv) {
|
||||||
std::cout << "Done! " << label_count.size() << std::endl;
|
std::cout << "Done! " << label_count.size() << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::vector<int> flat_assignments;
|
std::vector<int> flat_assignments;
|
||||||
for (int i = my_node_range.first; i < my_node_range.second; ++i) {
|
for (int i = my_node_range.fst; i < my_node_range.snd; ++i) {
|
||||||
flat_assignments.push_back(node_label_assignment[i]);
|
flat_assignments.push_back(node_label_assignment[i]);
|
||||||
}
|
}
|
||||||
MPI::COMM_WORLD.Send(flat_assignments.data(), flat_assignments.size(),
|
MPI::COMM_WORLD.Send(flat_assignments.data(), flat_assignments.size(),
|
||||||
MPI::INT, 0, TAG_SEND_FINAL_RESULT);
|
MPI_INT, 0, TAG_SEND_FINAL_RESULT);
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
MPI::Finalize();
|
MPI_Finalize();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,4 +405,11 @@ void pair_vector_push(struct pair_vector *v, int fst, int snd) {
|
||||||
v->ptr[v->len].fst = fst;
|
v->ptr[v->len].fst = fst;
|
||||||
v->ptr[v->len].snd = snd;
|
v->ptr[v->len].snd = snd;
|
||||||
v->len++;
|
v->len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pair compute_node_range(int p, int total_num_nodes, int each_num_nodes,
|
||||||
|
int process) {
|
||||||
|
int start = process * each_num_nodes;
|
||||||
|
int end = process == p - 1 ? total_num_nodes : start + each_num_nodes;
|
||||||
|
return {.fst = start, .snd = end};
|
||||||
}
|
}
|
Loading…
Reference in a new issue