int main(int argc, char *argv[]) { #ifndef DEBUG int nproc; int rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nproc); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { FILE *fm = argc > 1 ? fopen(argv[1], "r") : fopen("matrixA.dat", "r"); FILE *fv = argc > 2 ? fopen(argv[2], "r") : fopen("vectorB.dat", "r"); int steps = argc > 3 ? atof(argv[3]) : 1; matrix a = create_matrix_from_file(fm); values b = create_vector_from_file(fv); double *x = initialize_x(a.n, 0.0); solve_parallel(&a, x, b.v, nproc, steps); print_vector(x, a.n); } else { matrix m = receive_matrix(); double *z = malloc(m.n*sizeof(*z)); values v; v.n = m.n; v.v = malloc(v.n*sizeof(*v.v)); while (1) { if (receive_vector(v) == exit_tag) break; range r = compute_range(v.n, nproc, rank); mul_matrix_row(&m, v.v, z, r.begin, r.end); MPI_Send(z+r.begin, r.end-r.begin, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD); } } MPI_Finalize(); #endif #ifdef DEBUG // test(); FILE *fm = argc > 1 ? fopen(argv[1], "r") : fopen("matrixA.dat", "r"); FILE *fv = argc > 2 ? fopen(argv[2], "r") : fopen("vectorB.dat", "r"); matrix m = create_matrix_from_file(fm); values vector = create_vector_from_file(fv); double *x = initialize_x(m.n, 0.0); solve(&m, x, vector.v); print_vector(x, m.n); #endif return 0; }
int main(int argc, char** argv) { if(argc != 2) { fprintf(stderr, "Usage: %s [numofthread]\n", argv[0]); exit(EXIT_FAILURE); } numofthread = atoi(argv[1]); if(numofthread < 1 || numofthread > 32 ) { fprintf(stderr, "Incorrect or to high num of threads!\n"); exit(EXIT_FAILURE); } fprintf(stdout, "Num of threads is %d.\n", numofthread); // Маска для сигналов struct sigaction cancel_act; memset(&cancel_act, 0, sizeof(cancel_act)); cancel_act.sa_handler = thread_cancel; sigfillset(&cancel_act.sa_mask); sigaction(SIGUSR1, &cancel_act, NULL); // Создаем тред слушающий broadcast pthread_t broadcast_thread; // Переменная которая сообщает треду следует ли отвечать на broadcast int isbusy = 1; // Запустим тред для прослушивания запросов if(pthread_create(&broadcast_thread, NULL, listen_broadcast, &isbusy)) { fprintf(stderr, "Can't create broadcast listen thread"); perror("Detail:"); exit(EXIT_FAILURE); } int listener; struct sockaddr_in addr; listener = socket(PF_INET, SOCK_STREAM, 0); if(listener < 0) { perror("Can't create listen socket"); exit(EXIT_FAILURE); } addr.sin_family = AF_INET; addr.sin_port = htons(RCVPORT); addr.sin_addr.s_addr = INADDR_ANY; int a = 1; // Добавляем опцию SO_REUSEADDR для случаев когда мы перезапускам сервер if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &a, sizeof(a)) < 0) { perror("Set listener socket options"); exit(EXIT_FAILURE); } // Биндим сокет if(bind(listener, (struct sockaddr*) &addr, sizeof(addr)) < 0) { perror("Can't bind listen socket"); exit(EXIT_FAILURE); } // Начинаем ждать соединения от клиентов if(listen(listener, 1) < 0) { perror("Error in listen socket"); exit(EXIT_FAILURE); } // Ожидаем соединений while(1) { fprintf(stdout, "\nWait new connection...\n\n"); int client; isbusy = 0; // Разрешаем отвечать клиентам на запросы struct sockaddr_in addrclient; socklen_t addrclientsize = sizeof(addrclient); client = accept(listener, (struct sockaddr*)&addrclient, &addrclientsize); if(client < 0) { perror("Client accepting"); } isbusy = 1; // Запрещаем отвечать на запросы task_data_t data; int read_bytes = recv(client, &data, sizeof(data), 0); if(read_bytes != sizeof(data)) { fprintf(stderr, "Invalid data from %s on port %d, reset peer\n", inet_ntoa(addrclient.sin_addr), ntohs(addrclient.sin_port)); close(client); isbusy = 0; } else { int matrix_size = data.dimension * sizeof(TYPE) * (data.dimension + 1); void *matrix_data = malloc(matrix_size); if (matrix_data == NULL) { perror("Cant' allocate memory.\n"); close(client); exit(EXIT_FAILURE); } fprintf(stdout, "New task from %s on port %d\nINFO: from: %d. amount: %d. dimension: %d.\n", inet_ntoa(addrclient.sin_addr), ntohs(addrclient.sin_port), data.from, data.amount, data.dimension); printf("Matrix size: %d\n", matrix_size); int total_read_bytes = 0; while (total_read_bytes < matrix_size) { read_bytes = recv(client, matrix_data + total_read_bytes, matrix_size, 0); printf(" recieved packet = %d\n", read_bytes); total_read_bytes += read_bytes; } printf("Total read bytes: %d\n", total_read_bytes); if (total_read_bytes != matrix_size) { fprintf(stderr, "Invalid matrix from %s on port %d, reset peer\n", inet_ntoa(addrclient.sin_addr), ntohs(addrclient.sin_port)); close(client); isbusy = 0; break; } if (isbusy) { TYPE **matrix = allocate_matrix(data.dimension); for (int i = 0; i <= data.dimension; ++i) { memcpy(matrix[i], matrix_data + i * (data.dimension * sizeof(TYPE)), data.dimension * sizeof(TYPE)); } //print_matrix(matrix, data.dimension); // ВЫЧИСЛИТЕЛЬНЫЕ ТРЕДЫ results = (long double *) malloc(sizeof(long double) * data.amount); bzero(results, sizeof(long double) * data.amount); printf("Begin to calculate ... "); if (!solve_parallel(matrix, data.dimension, data.from, data.amount, client)) { if(send(client, results, sizeof(long double) * data.amount, 0) < 0) { perror("Sending error"); } isbusy = 0; fprintf(stdout, "Calculation finished!\n"); } else { fprintf(stderr, "Client died!\n"); } free_matrix(matrix, data.dimension); free(results); } free(matrix_data); close(client); } } return (EXIT_SUCCESS); }
int main(int argc, char **argv) { int option, steps = 365, delta = 1, body_count; char *input = "init.dat", *output = "result.dat"; bool parallel = false, mpi = false, global_newton = false; long double start; long double px, py; imggen_info img_info; body *bodies = NULL; /* PBM default values */ img_info.gen_img = false; img_info.img_steps = 1000; img_info.img_prefix = "PBM"; img_info.offset = 2; img_info.width = 600; img_info.heigth = 600; /* Read cmdline params */ while ((option = getopt(argc,argv,"phs:d:f:o:i:x:gmn")) != -1) { switch(option) { case 'p': parallel = true; break; case 's': steps = atoi(optarg); break; case 'd': delta = atoi(optarg); break; case 'f': input = optarg; break; case 'o': output = optarg; break; case 'i': img_info.img_prefix = optarg; break; case 'x': img_info.img_steps = atoi(optarg); break; case 'g': img_info.gen_img = true; break; case 'm': mpi = true; break; case 'n': global_newton = true; break; default: printhelp(); return 1; } } /* Init MPI */ MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &mpi_processors); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_self); /* Validate params */ if (steps < 0 || delta < 1 || img_info.img_steps < 1) { m_printf("Wrong parameter value! Will exit!\n Steps: %i | Delta: %i | Input Filepath: %s", steps, delta, input); } bodies = readBodies(fopen(input,"r"), &body_count); if (bodies == NULL) { m_printf("Error while reading input file %s. Will exit now!\n", input); MPI_Finalize(); return 1; } /* Assert that all masses > 0 and any two particles do not share the same position */ if (!examineBodies(bodies, body_count, &img_info.max_x, &img_info.max_y)) { m_printf("Error while reading input file %s. Some value are not permitted!\n", input); printBodies(bodies, body_count); MPI_Finalize(); return 1; } totalImpulse(bodies, body_count, &px, &py); m_printf("Initial total impulse: px = %Le , py = %Le\n", px, py); MPI_Barrier(MPI_COMM_WORLD); start = seconds(); if (parallel) { m_printf("PARALLEL\n"); if (mpi) { m_printf("MPI+OMP\n"); if (global_newton) { m_printf("GLOBAL NEWTON\n"); solve_parallel_mpi_global_newton(bodies, body_count, steps, delta, img_info); } else { solve_parallel_mpi(bodies, body_count, steps, delta, img_info); } } else { m_printf("OMP\n"); solve_parallel(bodies, body_count, steps, delta, img_info); } } else { m_printf("SEQUENTIAL\n"); solve_sequential(bodies, body_count, steps, delta, img_info); } MPI_Barrier(MPI_COMM_WORLD); long double elapsed = seconds() - start; m_printf("Rate of interactions: %Lf\n", interactions(body_count, steps, elapsed)); m_printf("Elapsed time: %Lf\n", elapsed); totalImpulse(bodies, body_count, &px, &py); m_printf("Resulting total impulse: px = %Le , py = %Le\n", px, py); /* Write result to file */ FILE *f = fopen(output,"w"); if (f == NULL) { m_printf("Error while opening output file %s.\n", output); MPI_Finalize(); return 1; } writeBodies(f, bodies, body_count); MPI_Finalize(); return 0; }