-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
157 lines (132 loc) · 5.69 KB
/
main.c
File metadata and controls
157 lines (132 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern void run_coordinator(int world_size);
extern void run_library(int rank, int N);
extern void run_client(int rank, int N);
void print_usage(const char* program_name) {
fprintf(stderr, "Usage: %s <N>\n", program_name);
fprintf(stderr, "\n");
fprintf(stderr, "Where N is the grid dimension for the library network.\n");
fprintf(stderr, "\n");
fprintf(stderr, "System requirements:\n");
fprintf(stderr, " - Total processes: 1 + N² + N³/2\n");
fprintf(stderr, " - Libraries: N² processes (N×N grid)\n");
fprintf(stderr, " - Clients: N³/2 processes (tree topology)\n");
fprintf(stderr, "\n");
fprintf(stderr, "Examples:\n");
fprintf(stderr, " N=2: mpirun -np 9 %s 2 (1 coord + 4 libs + 4 clients)\n", program_name);
fprintf(stderr, " N=3: mpirun -np 23 %s 3 (1 coord + 9 libs + 13 clients)\n", program_name);
fprintf(stderr, " N=4: mpirun -np 49 %s 4 (1 coord + 16 libs + 32 clients)\n", program_name);
fprintf(stderr, " N=5: mpirun -np 88 %s 5 (1 coord + 25 libs + 62 clients)\n", program_name);
}
void validate_system_configuration(int N, int actual_size) {
int expected_libraries = N * N;
int expected_clients = (N * N * N) / 2;
int expected_total = 1 + expected_libraries + expected_clients;
printf("=== SYSTEM CONFIGURATION VALIDATION ===\n");
printf("Grid dimension (N): %d\n", N);
printf("Expected processes:\n");
printf(" - Coordinator: 1\n");
printf(" - Libraries: %d (N² = %d²)\n", expected_libraries, N);
printf(" - Clients: %d (N³/2 = %d³/2)\n", expected_clients, N);
printf(" - Total: %d\n", expected_total);
printf("\n");
printf("Actual MPI world size: %d\n", actual_size);
if (actual_size == expected_total) {
printf("Configuration VALID - proceeding with execution\n");
} else {
printf("Configuration INVALID - size mismatch\n");
printf("Please adjust the number of MPI processes to %d\n", expected_total);
exit(1);
}
printf("==========================================\n\n");
}
void print_process_assignment(int rank, int N, const char* role) {
printf("Process %d: Assigned role = %s", rank, role);
if (strcmp(role, "LIBRARY") == 0) {
int lib_index = rank - 1;
int grid_x = lib_index % N;
int grid_y = lib_index / N;
printf(" at grid position (%d,%d)", grid_x, grid_y);
// Calculate assigned books
int first_book = lib_index * N;
int last_book = (lib_index + 1) * N - 1;
printf(", managing books %d-%d", first_book, last_book);
} else if (strcmp(role, "CLIENT") == 0) {
int client_index = rank - (N * N + 1);
int clients_per_library = N / 2;
int assigned_library = 1 + (client_index / clients_per_library);
printf(", belongs to library %d", assigned_library);
}
printf("\n");
}
int main(int argc, char* argv[]) {
// Validate command line arguments
if (argc != 2) {
print_usage(argv[0]);
return 1;
}
int N = atoi(argv[1]);
if (N <= 0 || N > 20) {
fprintf(stderr, "Error: N must be a positive integer between 1 and 20\n");
fprintf(stderr, " Larger values may cause resource exhaustion\n");
print_usage(argv[0]);
return 1;
}
// Check for reasonable N values to prevent resource exhaustion
int expected_total = 1 + N * N + (N * N * N) / 2;
if (expected_total > 1000) {
fprintf(stderr, "Warning: N=%d requires %d processes - this may be too large\n", N, expected_total);
fprintf(stderr, "Consider using smaller N values for testing\n");
}
// Initialize MPI
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_SINGLE, &provided);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Only coordinator validates and prints configuration
if (rank == 0) {
validate_system_configuration(N, size);
}
// Synchronize all processes before proceeding
MPI_Barrier(MPI_COMM_WORLD);
// Calculate process ranges
int first_library = 1;
int last_library = N * N;
int first_client = N * N + 1;
int last_client = N * N + (N * N * N) / 2;
// Assign and execute process roles
if (rank == 0) {
// Coordinator process
print_process_assignment(rank, N, "COORDINATOR");
run_coordinator(size);
} else if (rank >= first_library && rank <= last_library) {
// Library process
print_process_assignment(rank, N, "LIBRARY");
run_library(rank, N);
} else if (rank >= first_client && rank <= last_client) {
// Client process
print_process_assignment(rank, N, "CLIENT");
run_client(rank, N);
} else {
// Invalid rank - this shouldn't happen with proper configuration
fprintf(stderr, "ERROR: Process rank %d is outside valid ranges\n", rank);
fprintf(stderr, "Valid ranges: coordinator=0, libraries=[%d-%d], clients=[%d-%d]\n",
first_library, last_library, first_client, last_client);
MPI_Finalize();
return 1;
}
// Clean MPI shutdown
MPI_Finalize();
if (rank == 0) {
printf("=== SYSTEM SHUTDOWN COMPLETE ===\n");
printf("All processes terminated successfully.\n");
printf("Distributed library system execution finished.\n");
printf("=================================\n");
}
return 0;
}