static void rtsi_handleDataFunc(void *inSparseImageBuffer, IceTInt src) { if (inSparseImageBuffer == NULL) { /* Superfluous call from send to self. */ if (!rtsi_first) { icetRaiseError("Unexpected callback order" " in icetRenderTransferSparseImages.", ICET_SANITY_CHECK_FAIL); } } else { IceTSparseImage inSparseImage = icetSparseImageUnpackageFromReceive(inSparseImageBuffer); if (rtsi_first) { IceTSizeType num_pixels = icetSparseImageGetNumPixels(inSparseImage); icetSparseImageCopyPixels(inSparseImage, 0, num_pixels, rtsi_workingImage); } else { IceTInt rank; const IceTInt *process_orders; IceTSparseImage old_workingImage; icetGetIntegerv(ICET_RANK, &rank); process_orders = icetUnsafeStateGetInteger(ICET_PROCESS_ORDERS); if (process_orders[src] < process_orders[rank]) { icetCompressedCompressedComposite(inSparseImage, rtsi_workingImage, rtsi_availableImage); } else { icetCompressedCompressedComposite(rtsi_workingImage, inSparseImage, rtsi_availableImage); } old_workingImage = rtsi_workingImage; rtsi_workingImage = rtsi_availableImage; rtsi_availableImage = old_workingImage; } } rtsi_first = ICET_FALSE; }
static int TestSparseImageSplit(const IceTImage image) { #define NUM_PARTITIONS 7 IceTVoid *full_sparse_buffer; IceTSparseImage full_sparse; IceTVoid *sparse_partition_buffer[NUM_PARTITIONS]; IceTSparseImage sparse_partition[NUM_PARTITIONS]; IceTSizeType offsets[NUM_PARTITIONS]; IceTVoid *compare_sparse_buffer; IceTSparseImage compare_sparse; IceTSizeType width; IceTSizeType height; IceTSizeType num_partition_pixels; IceTInt partition; width = icetImageGetWidth(image); height = icetImageGetHeight(image); num_partition_pixels = icetSparseImageSplitPartitionNumPixels(width*height, NUM_PARTITIONS, NUM_PARTITIONS); full_sparse_buffer = malloc(icetSparseImageBufferSize(width, height)); full_sparse = icetSparseImageAssignBuffer(full_sparse_buffer,width,height); for (partition = 0; partition < NUM_PARTITIONS; partition++) { sparse_partition_buffer[partition] = malloc(icetSparseImageBufferSize(num_partition_pixels, 1)); sparse_partition[partition] = icetSparseImageAssignBuffer(sparse_partition_buffer[partition], num_partition_pixels, 1); } compare_sparse_buffer = malloc(icetSparseImageBufferSize(num_partition_pixels, 1)); compare_sparse = icetSparseImageAssignBuffer(compare_sparse_buffer, num_partition_pixels, 1); icetCompressImage(image, full_sparse); printf("Spliting image %d times\n", NUM_PARTITIONS); icetSparseImageSplit(full_sparse, 0, NUM_PARTITIONS, NUM_PARTITIONS, sparse_partition, offsets); for (partition = 0; partition < NUM_PARTITIONS; partition++) { IceTInt result; icetCompressSubImage(image, offsets[partition], icetSparseImageGetNumPixels( sparse_partition[partition]), compare_sparse); printf(" Comparing partition %d\n", partition); result = CompareSparseImages(compare_sparse, sparse_partition[partition]); if (result != TEST_PASSED) return result; } printf("Spliting image %d times with first partition in place.\n", NUM_PARTITIONS); sparse_partition[0] = full_sparse; icetSparseImageSplit(full_sparse, 0, NUM_PARTITIONS, NUM_PARTITIONS, sparse_partition, offsets); for (partition = 0; partition < NUM_PARTITIONS; partition++) { IceTInt result; icetCompressSubImage(image, offsets[partition], icetSparseImageGetNumPixels( sparse_partition[partition]), compare_sparse); printf(" Comparing partition %d\n", partition); result = CompareSparseImages(compare_sparse, sparse_partition[partition]); if (result != TEST_PASSED) return result; } free(full_sparse_buffer); for (partition = 0; partition < NUM_PARTITIONS; partition++) { free(sparse_partition_buffer[partition]); } free(compare_sparse_buffer); return TEST_PASSED; #undef NUM_PARTITIONS }
void icetSingleImageCollect(const IceTSparseImage input_image, IceTInt dest, IceTSizeType piece_offset, IceTImage result_image) { IceTSizeType *offsets; IceTSizeType *sizes; IceTInt rank; IceTInt numproc; IceTSizeType piece_size; IceTEnum color_format; IceTEnum depth_format; IceTSizeType color_size = 1; IceTSizeType depth_size = 1; #define DUMMY_BUFFER_SIZE ((IceTSizeType)(16*sizeof(IceTInt))) IceTByte dummy_buffer[DUMMY_BUFFER_SIZE]; rank = icetCommRank(); numproc = icetCommSize(); /* Collect partitions held by each process. */ piece_size = icetSparseImageGetNumPixels(input_image); if (rank == dest) { offsets = icetGetStateBuffer(ICET_IMAGE_COLLECT_OFFSET_BUF, sizeof(IceTSizeType)*numproc); sizes = icetGetStateBuffer(ICET_IMAGE_COLLECT_SIZE_BUF, sizeof(IceTSizeType)*numproc); } else { offsets = NULL; sizes = NULL; } /* Technically, these gathers are part of the collection process and should therefore be timed. However, unless the compositing is very well load balanced (and typically it is not), different processes will arrive here at different times. These gathers act something like a barrier that helps separate the time spent collecting final pixels from the time spent in transferring and compositing fragments. */ icetCommGather(&piece_offset, 1, ICET_SIZE_TYPE, offsets, dest); icetCommGather(&piece_size, 1, ICET_SIZE_TYPE, sizes, dest); #ifdef DEBUG if (rank == dest) { IceTVoid *data; IceTSizeType size; if (icetImageGetColorFormat(result_image) != ICET_IMAGE_COLOR_NONE) { data = icetImageGetColorVoid(result_image, &size); memset(data, 0xCD, icetImageGetNumPixels(result_image)*size); } if (icetImageGetDepthFormat(result_image) != ICET_IMAGE_DEPTH_NONE) { data = icetImageGetDepthVoid(result_image, &size); memset(data, 0xCD, icetImageGetNumPixels(result_image)*size); } } #endif if (piece_size > 0) { /* Decompress data into appropriate offset of result image. */ icetDecompressSubImageCorrectBackground(input_image, piece_offset, result_image); } else if (rank != dest) { /* If this function is called for multiple collections, it is likely that the local process will not have data for all collections. To prevent making the calling function allocate an image buffer when it is neither sending or receiving data, just allocate a dummy buffer to satisfy the following code. */ if (DUMMY_BUFFER_SIZE < icetImageBufferSize(0, 0)) { icetRaiseError("Oops. My dummy buffer is not big enough.", ICET_SANITY_CHECK_FAIL); return; } result_image = icetImageAssignBuffer(dummy_buffer, 0, 0); } else { /* Collecting data at empty process. We still want to use the provided result_image, but we have nothing of our own to put in it. Thus, do nothing. */ } /* Adjust image for output as some buffers, such as depth, might be dropped. */ icetImageAdjustForOutput(result_image); icetTimingCollectBegin(); color_format = icetImageGetColorFormat(result_image); depth_format = icetImageGetDepthFormat(result_image); if (color_format != ICET_IMAGE_COLOR_NONE) { /* Use IceTByte for byte-based pointer arithmetic. */ IceTByte *color_buffer = icetImageGetColorVoid(result_image, &color_size); int proc; if (rank == dest) { /* Adjust sizes and offsets to sizes of pixel colors. */ for (proc = 0; proc < numproc; proc++) { offsets[proc] *= color_size; sizes[proc] *= color_size; } icetCommGatherv(ICET_IN_PLACE_COLLECT, sizes[rank], ICET_BYTE, color_buffer, sizes, offsets, dest); } else { icetCommGatherv(color_buffer + piece_offset * color_size, piece_size * color_size, ICET_BYTE, NULL, NULL, NULL, dest); } } if (depth_format != ICET_IMAGE_DEPTH_NONE) { /* Use IceTByte for byte-based pointer arithmetic. */ IceTByte *depth_buffer = icetImageGetDepthVoid(result_image, &depth_size); int proc; if (rank == dest) { /* Adjust sizes and offsets to sizes of pixel depths. Also adjust for any adjustments made for color. */ if (color_size != depth_size) { for (proc = 0; proc < numproc; proc++) { offsets[proc] /= color_size; offsets[proc] *= depth_size; sizes[proc] /= color_size; sizes[proc] *= depth_size; } } icetCommGatherv(ICET_IN_PLACE_COLLECT, sizes[rank], ICET_BYTE, depth_buffer, sizes, offsets, dest); } else { icetCommGatherv(depth_buffer + piece_offset * depth_size, piece_size * depth_size, ICET_BYTE, NULL, NULL, NULL, dest); } } icetTimingCollectEnd(); }