int start_node( struct ChannelsConfigInterface *chan_if, int nodeid ){ BigArrayPtr sorted_array = NULL; const size_t data_size = sizeof(BigArrayItem)*ARRAY_ITEMS_COUNT; /*If can use bitonic sort*/ if ( test_sse41_CPU() ){ WRITE_LOG(LOG_ERR, "allocate bitonic sort memories\n"); /*we needed an extra buf to use with bitonic sort*/ BigArrayPtr extra_buf = NULL; /*allocated memory should be aligned*/ extra_buf = aligned_malloc(data_size, SSE2_ALIGNMENT); if ( !extra_buf ) { WRITE_LOG(LOG_ERR, "Can't allocate memories\n"); abort(); } sorted_array = aligned_malloc(data_size, SSE2_ALIGNMENT); if (!sorted_array) { WRITE_LOG(LOG_ERR, "Can't allocate memories\n"); abort(); } /*Read source data from STDIN*/ struct UserChannel *channel = chan_if->Channel(chan_if, EInputOutputNode, 1, EChannelModeRead ); const ssize_t readed = read( channel->fd, (void*)sorted_array, data_size); WRITE_FMT_LOG(LOG_ERR, "readed input file, expected size=%d, read size=%d\n", data_size, readed); assert(readed == data_size ); WRITE_LOG(LOG_DETAILED_UI, "Start bitonic sorting\n"); bitonic_sort_chunked((float*)sorted_array, ARRAY_ITEMS_COUNT, (float*)extra_buf, DEFAULT_CHUNK_SIZE); WRITE_LOG(LOG_DETAILED_UI, "Bitonic sorting complete\n"); aligned_free(extra_buf); } /*If can't use bitonic - then use c qsort*/ else{ WRITE_LOG(LOG_ERR, "qsort will used\n"); BigArrayPtr unsorted_array = NULL; unsorted_array = malloc( data_size ); if ( !unsorted_array ) { WRITE_LOG(LOG_ERR, "Can't allocate memories\n"); abort(); } if ( unsorted_array ){ /*Read source data from STDIN*/ const ssize_t readed = read( STDIN, (void*)unsorted_array, data_size); WRITE_FMT_LOG(LOG_ERR, "readed input file, expected size=%d, read size=%d\n", data_size, readed); assert(readed == data_size ); } WRITE_LOG(LOG_DETAILED_UI, "Start qsort sorting\n"); sorted_array = alloc_copy_array( unsorted_array, ARRAY_ITEMS_COUNT ); qsort( sorted_array, ARRAY_ITEMS_COUNT, sizeof(BigArrayItem), quicksort_BigArrayItem_comparator ); free(unsorted_array); } struct UserChannel *channel = chan_if->Channel( chan_if, EManagerNode, 1, EChannelModeWrite ); assert(channel); #if LOG_LEVEL == LOG_DEBUG channel->DebugPrint(channel, stderr); #endif /*send crc of sorted array to the manager node*/ uint32_t crc = array_crc( sorted_array, ARRAY_ITEMS_COUNT ); WRITE_FMT_LOG(LOG_DEBUG, "write crc=%u into fd=%d", crc, channel->fd); write_crc( channel->fd, crc ); /*send of crc complete*/ /*prepare histogram data, with step defined by BASE_HISTOGRAM_STEP*/ int histogram_len = 0; HistogramArrayPtr histogram_array = alloc_histogram_array_get_len( sorted_array, 0, ARRAY_ITEMS_COUNT, BASE_HISTOGRAM_STEP, &histogram_len ); WRITE_LOG(LOG_DEBUG, "histogram prepared, sending..."); struct Histogram single_histogram; single_histogram.src_nodeid = nodeid; single_histogram.array_len = histogram_len; single_histogram.array = histogram_array; /*send histogram to manager*/ channel = chan_if->Channel(chan_if, EManagerNode, 1, EChannelModeWrite); assert(channel); write_histogram( channel->fd, &single_histogram ); struct UserChannel *chanw = chan_if->Channel(chan_if, EManagerNode, 1, EChannelModeWrite); channel = chan_if->Channel(chan_if, EManagerNode, 1, EChannelModeRead); assert(channel); assert(chanw); /*read request for detailed histogram and send it to manager*/ read_requests_write_detailed_histograms( channel->fd, chanw->fd, nodeid, sorted_array, ARRAY_ITEMS_COUNT ); WRITE_LOG(LOG_UI, "\n!!!!!!!Histograms Sending complete!!!!!!.\n"); /* source nodes count not available because not has channels intended to communicate with source nodes * therefore will use dest nodes count because it's equal to source nodes count */ int *dst_nodes_list = NULL; int dst_nodes_count = chan_if->GetNodesListByType(chan_if, EDestinationNode, &dst_nodes_list ); int src_nodes_count = dst_nodes_count; WRITE_FMT_LOG( LOG_DEBUG, "src_nodes_count=%d\n", src_nodes_count ); /*read range request (data start, end, dest node id) from manager node*/ struct request_data_t req_data_array[src_nodes_count]; init_request_data_array( req_data_array, src_nodes_count); channel = chan_if->Channel( chan_if, EManagerNode, 1, EChannelModeRead ); assert(channel); read_range_request( channel->fd, req_data_array ); WRITE_FMT_LOG( LOG_UI, "qsort array len=%d\n", src_nodes_count); /*sort request data by dest node id to be deterministic*/ qsort( req_data_array, src_nodes_count, sizeof(struct request_data_t), quicksort_reqdata_by_destnodeid_comparator ); WRITE_LOG( LOG_UI, "qsort OK" ); /*send array data to the destination nodes, bounds for pieces of data was * received previously with range request */ for ( int i=0; i < src_nodes_count; i++ ){ int dst_nodeid = req_data_array[i].dst_nodeid; channel = chan_if->Channel( chan_if, EDestinationNode, dst_nodeid, EChannelModeWrite ); int dst_write_fd = channel->fd; WRITE_FMT_LOG(LOG_DEBUG, "write_sorted_ranges write fd=%d", dst_write_fd ); WRITE_FMT_LOG(LOG_DEBUG, "req_data_array[i].dst_nodeid=%d", req_data_array[i].dst_nodeid ); write_sorted_ranges( dst_write_fd, &req_data_array[i], sorted_array ); } WRITE_LOG(LOG_UI, "Sending Ranges Complete-OK"); if ( test_sse41_CPU() ) aligned_free(sorted_array); else free(sorted_array); return 0; }
BigArrayPtr alloc_sort( BigArrayPtr array, int array_len ){ BigArrayPtr sorted_array = alloc_copy_array( array, array_len ); qsort( sorted_array, array_len, sizeof(BigArrayItem), quicksort_BigArrayItem_comparator ); return sorted_array; }