int main(int argc, char *argv[]) { me.ev = mowgli_eventloop_create(); signals_init(); parse_commandline_options(argc, argv); me.config = mowgli_config_file_load(config_file); if(me.config == NULL) sigyn_fatal("Cannot load configuration file."); logger_init(me.config->entries); config_check(me.config); me.uplink.line = new_conn(me.uplink.hostname, me.uplink.port, me.uplink.ssl, read_irc, NULL); if (me.uplink.line == NULL) sigyn_fatal("Connection to uplink failed."); me.uplink.connected = true; loadmodules(me.config->entries); sigyn_introduce_client(me.client->nick, me.client->user, NULL); if (should_fork) daemonise(SYSCONFDIR "/sigyn.pid"); mowgli_eventloop_run(me.ev); sigyn_cleanup(); return EXIT_SUCCESS; }
int main(int argc, char* argv[]) { int my_rank; /* rank of process */ int num_process; /* number of processes */ int i, j, k; //for loop // MPI Initialization MPI_Status status ; /* return status for receive */ MPI_Status probe_status; /* return status for probe */ MPI_Request request; /* start up MPI */ MPI_Init(&argc, &argv); /* find out process rank */ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /* find out number of processes */ MPI_Comm_size(MPI_COMM_WORLD, &num_process); // Gensort generate input files named partition.ranknumber char gensort_fname[50]; char arg_bN[10]; char arg_NUMRECS[10]; char system_call[100]; sprintf(gensort_fname, "partition.%d", my_rank); sprintf(arg_bN, " -b%d", (my_rank*1000)); sprintf(arg_NUMRECS, " %d ", (1000)); // CAUTION!!! // CAUTION!!! // CAUTION!!! strcpy(system_call, "/Users/hawkwoodye/NetBeansProjects/gensort-1.4/gensort "); strcat(system_call, arg_bN); strcat(system_call, arg_NUMRECS); strcat(system_call, gensort_fname); system(system_call); // Parameters Set Up struct program_information prog_info; parse_commandline_options(argc, argv, &prog_info); // Process Input File Information struct stat stat_info; char file_path[52] = "./"; strcat(file_path, gensort_fname); strcpy(prog_info.input_file_name, file_path); if (stat(prog_info.input_file_name, &stat_info)) { printf("Rank %d %s ", my_rank, prog_info.input_file_name); print_usage_error_exit("Unable to stat input file!\n"); } prog_info.input_file_size = (size_t) stat_info.st_size; prog_info.number_of_process = num_process; prog_info.element_byte_size = 100; prog_info.element_key_size = 10; prog_info.element_count = (long) prog_info.input_file_size / prog_info.element_byte_size; printf("Rank %d Input File Name : %s\n", my_rank, prog_info.input_file_name); printf("Element Count : %ld\n", prog_info.element_count); //////////////////////////////////////////// // // // Our Sort Start // // // //////////////////////////////////////////// // !!! Pipeline First // !!! Pipeline First // !!! Pipeline First //////////////////////////////////////////// // // // STEP 1: Reading Disk -> Memory // // // //////////////////////////////////////////// FILE * file_ptr; struct element * records_per_buffer; long readbuffer_size; // in bytes // temporary set to the whole file will be changed to buffer size... // ... readbuffer_size = prog_info.input_file_size; // read buffer malloc records_per_buffer = (struct element *)malloc(readbuffer_size); file_ptr = fopen(prog_info.input_file_name, "rb"); // will add for loop for read one buffer each time // ... if(file_ptr == NULL) print_usage_error_exit("File open error!\n"); if(fseek(file_ptr, 0, SEEK_SET) != 0) print_usage_error_exit("Unable to seek input file!"); if(fread(records_per_buffer, 1, readbuffer_size, file_ptr) != readbuffer_size) { print_usage_error_exit("File reading error!\n"); } fclose(file_ptr); //////////////////////////////////////////// // // // STEP 2: Distribute (Communication) // // // //////////////////////////////////////////// // Each node count the first byte of each element and // decide which target node this element should be sent to // // Double Buffering will be added in // ... // // buffers for sending struct element * sending_buckets[num_process]; long buckets_index[num_process]; // buffer for receiving struct element * final_distributed_records; final_distributed_records = (struct element *)malloc(2 * prog_info.input_file_size); // bucket size in count of element, will be changed later, right now it is the total element count, which will not be reached long bucket_element_count; // Start Receiving Thread keep running until receive all~ long * final_index; final_index = (long*)malloc(sizeof(long)); *final_index = 0; struct parm_recv thread_recv_parm; thread_recv_parm._status = probe_status; thread_recv_parm._recv_buffer = final_distributed_records; thread_recv_parm._prog_info = prog_info; thread_recv_parm._final_index = final_index; thread_recv_parm._my_process = my_rank; pthread_t recv_thread; pthread_create(&recv_thread, NULL, background_probe_recv, (void*)&thread_recv_parm); bucket_element_count = prog_info.element_count ; for(i = 0; i < num_process; i++) { sending_buckets[i] = (struct element *)malloc(bucket_element_count * prog_info.element_byte_size ); buckets_index[i] = 0; } long count_of_dist_records = prog_info.element_count; struct element temp_record; char temp_key; int target_node; int probe_flag = 0; for(i = 0; i < prog_info.element_count; i++) { temp_record = records_per_buffer[i]; temp_key = temp_record.e[0]; target_node = (int)temp_key + 128; target_node = target_node / (256 / num_process); /* printf("Rank %d: key is %c or %d\n", my_rank, temp_key, target_node); if(target_node == num_process) { printf("!ERROR !\n"); break; } */ sending_buckets[target_node][buckets_index[target_node]] = temp_record; buckets_index[target_node]++; // when one bucket is full send it and memset to zero if(buckets_index[target_node] == bucket_element_count) { printf("Init start sending: %ld -> %d!!\n", buckets_index[target_node]*100, target_node); // MPI SEND MPI_Send(sending_buckets[target_node], (buckets_index[target_node] * 100), MPI_BYTE, target_node, target_node, MPI_COMM_WORLD); buckets_index[target_node] = 0; } } // last time send those unfilled buckects for(i = 0; i < num_process; i++) { if(buckets_index[i] != 0) { printf("Start sending: %ld -> %d!!\n", buckets_index[i]*100, i); //MPI SEND !!CAUTION!! only send (buckets_index[i] + 1) elements MPI_Send(sending_buckets[i], (buckets_index[i]) * 100, MPI_BYTE, i, i, MPI_COMM_WORLD); } } // call all process end for(i = 0; i < num_process; i++) { printf("%d send tag to %d!\n", my_rank, i); MPI_Send(&i, 0, MPI_BYTE, i, 255, MPI_COMM_WORLD); } //////////////////////////////////////////// // // // STEP 3: Sort and Write to file // // // //////////////////////////////////////////// //Barrier() MPI_Barrier(MPI_COMM_WORLD); // sort final_distributed_records quickSort(final_distributed_records, 0, (prog_info.element_count - 1) ); // write to disk FILE *outFile; char output_file_name[57]="./sorted_"; strcat(output_file_name, gensort_fname); // open the file we are writing to if(!(outFile = fopen(output_file_name, "wb"))) { print_usage_error_exit("File writing error!\n"); } // use fwrite to write binary data to the file fwrite(final_distributed_records, prog_info.input_file_size , 1, outFile); fclose(outFile); //////////////////////////////////////////// // // // STEP 4: Garbage Collection // // // //////////////////////////////////////////// pthread_join(recv_thread, NULL); free(final_distributed_records); free(final_index); for(i = 0; i < num_process; i++) { free(sending_buckets[i]); } free(records_per_buffer); // shut down MPI MPI_Finalize(); return (EXIT_SUCCESS); }