Updates will be applied on October 27th between 12pm - 12:45pm EDT (UTC-0400). Gitlab may be slow during the maintenance window.

Commit f5008166 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Split sizes based on final split size.

Changed icetSparseImageSplit and associated functions to base the size
of the splits based on the eventual number of splits done by the end
of the algorithm.  Each of these functions takes a new
eventual_num_partitions argument that is the number of times the
image will be split by the end of the algorithm.  If you partition
the image by factors of this number, you will get the same partition
sizes and order as if you partitioned by that number to begin with.
parent 4065bd3c
......@@ -1369,37 +1369,60 @@ void icetSparseImageCopyPixels(const IceTSparseImage in_image,
icetStateSetInteger(ICET_COMPRESS_TIME, compress_time);
}
static void icetSparseImageSplitChoosePartitions(IceTInt num_partitions,
IceTSizeType start_offset,
IceTSizeType size,
IceTSizeType *offsets)
{
if (num_partitions%2 == 1) {
IceTSizeType part_size = size/num_partitions;
IceTSizeType part_remainder = size%num_partitions;
IceTInt part_idx;
offsets[0] = start_offset;
for (part_idx = 0; part_idx < num_partitions-1; part_idx++) {
IceTSizeType this_part_size = part_size;
if (part_idx < part_remainder) { this_part_size++; }
offsets[part_idx+1] = offsets[part_idx] + this_part_size;
IceTSizeType icetSparseImageSplitPartitionNumPixels(
IceTSizeType input_num_pixels,
IceTInt num_partitions,
IceTInt eventual_num_partitions)
{
IceTInt sub_partitions = eventual_num_partitions/num_partitions;
#ifdef DEBUG
if (eventual_num_partitions%num_partitions != 0) {
icetRaiseError("num_partitions not a factor"
" of eventual_num_partitions.",
ICET_INVALID_VALUE);
}
#endif
return input_num_pixels/num_partitions + sub_partitions;
}
static void icetSparseImageSplitChoosePartitions(
IceTInt num_partitions,
IceTInt eventual_num_partitions,
IceTSizeType size,
IceTSizeType *offsets)
{
IceTSizeType remainder = size%eventual_num_partitions;
IceTInt sub_partitions = eventual_num_partitions/num_partitions;
IceTSizeType partition_lower_size = size/num_partitions;
IceTSizeType this_offset = 0;
IceTInt partition_idx;
#ifdef DEBUG
if (eventual_num_partitions%num_partitions != 0) {
icetRaiseError("num_partitions not a factor"
" of eventual_num_partitions.",
ICET_INVALID_VALUE);
}
#endif
for (partition_idx = 0; partition_idx < num_partitions; partition_idx++) {
offsets[partition_idx] = this_offset;
this_offset += partition_lower_size;
if (remainder > sub_partitions) {
this_offset += sub_partitions;
remainder -= sub_partitions;
} else {
this_offset += remainder;
remainder = 0;
}
} else {
IceTSizeType left_part_size = size/2 + size%2;
IceTSizeType right_part_size = size/2;
icetSparseImageSplitChoosePartitions(num_partitions/2,
start_offset,
left_part_size,
offsets);
icetSparseImageSplitChoosePartitions(num_partitions/2,
start_offset + left_part_size,
right_part_size,
offsets + num_partitions/2);
}
}
void icetSparseImageSplit(const IceTSparseImage in_image,
IceTInt num_partitions,
IceTInt eventual_num_partitions,
IceTSparseImage *out_images,
IceTSizeType *offsets)
{
......@@ -1438,7 +1461,7 @@ void icetSparseImageSplit(const IceTSparseImage in_image,
start_inactive = start_active = 0;
icetSparseImageSplitChoosePartitions(num_partitions,
0,
eventual_num_partitions,
total_num_pixels,
offsets);
......@@ -1494,13 +1517,6 @@ void icetSparseImageSplit(const IceTSparseImage in_image,
icetStateSetInteger(ICET_COMPRESS_TIME, compress_time);
}
IceTSizeType icetSparseImageSplitPartitionNumPixels(
IceTSizeType input_num_pixels,
IceTInt num_partitions)
{
return input_num_pixels/num_partitions + 1;
}
void icetClearImage(IceTImage image)
{
IceTInt region[4] = {0, 0, 0, 0};
......
......@@ -111,11 +111,13 @@ ICET_EXPORT void icetSparseImageCopyPixels(const IceTSparseImage in_image,
ICET_EXPORT void icetSparseImageSplit(const IceTSparseImage in_image,
IceTInt num_partitions,
IceTInt eventual_num_partitions,
IceTSparseImage *out_images,
IceTSizeType *offsets);
ICET_EXPORT IceTSizeType icetSparseImageSplitPartitionNumPixels(
IceTSizeType input_num_pixels,
IceTInt num_partitions);
IceTSizeType input_num_pixels,
IceTInt num_partitions,
IceTInt eventual_num_partitions);
ICET_EXPORT void icetClearImage(IceTImage image);
ICET_EXPORT void icetClearSparseImage(IceTSparseImage image);
......
......@@ -212,9 +212,11 @@ static void bswapSendFromUpperGroup(const IceTInt *lower_group,
IceTInt lower_group_size,
const IceTInt *upper_group,
IceTInt upper_group_size,
IceTInt largest_group_size,
IceTSparseImage working_image)
{
IceTInt num_pieces = lower_group_size/upper_group_size;
IceTInt eventual_num_pieces = largest_group_size/upper_group_size;
IceTSparseImage *image_partitions;
IceTSizeType *dummy_array;
IceTInt piece;
......@@ -229,7 +231,8 @@ static void bswapSendFromUpperGroup(const IceTInt *lower_group,
= icetSparseImageGetNumPixels(working_image);
IceTSizeType partition_num_pixels
= icetSparseImageSplitPartitionNumPixels(total_num_pixels,
num_pieces);
num_pieces,
eventual_num_pieces);
IceTSizeType buffer_size
= icetSparseImageBufferSize(partition_num_pixels, 1);
IceTByte *buffer; /* IceTByte for pointer arithmetic. */
......@@ -251,6 +254,7 @@ static void bswapSendFromUpperGroup(const IceTInt *lower_group,
icetSparseImageSplit(working_image,
num_pieces,
eventual_num_pieces,
image_partitions,
dummy_array);
}
......@@ -350,6 +354,13 @@ static void bswapComposePow2(const IceTInt *compose_group,
IceTSparseImage available_image;
*piece_offset = 0;
if (group_size < 2) {
*result_image = image_data;
if (spare_image) { *spare_image = icetSparseImageNull(); }
return;
}
group_rank = icetFindMyRankInGroup(compose_group, group_size);
/* Allocate available image. */
......@@ -357,7 +368,9 @@ static void bswapComposePow2(const IceTInt *compose_group,
IceTSizeType total_num_pixels
= icetSparseImageGetNumPixels(working_image);
IceTSizeType piece_num_pixels
= icetSparseImageSplitPartitionNumPixels(total_num_pixels, 2);
= icetSparseImageSplitPartitionNumPixels(total_num_pixels,
2,
group_size);
available_image
= icetGetStateBufferSparseImage(BSWAP_SPARE_WORKING_IMAGE_BUFFER,
piece_num_pixels, 1);
......@@ -382,13 +395,16 @@ static void bswapComposePow2(const IceTInt *compose_group,
IceTSizeType total_num_pixels
= icetSparseImageGetNumPixels(image_data);
IceTSizeType piece_num_pixels
= icetSparseImageSplitPartitionNumPixels(total_num_pixels, 2);
= icetSparseImageSplitPartitionNumPixels(total_num_pixels,
2,
group_size/bitmask);
outgoing_images[0] = image_data;
outgoing_images[1]
= icetGetStateBufferSparseImage(BSWAP_OUTGOING_IMAGES_BUFFER,
piece_num_pixels, 1);
icetSparseImageSplit(image_data,
2,
group_size/bitmask,
outgoing_images,
outgoing_offsets);
}
......@@ -476,6 +492,7 @@ static void bswapComposePow2(const IceTInt *compose_group,
* are selected for outputs. */
static void bswapComposeNoCombine(const IceTInt *compose_group,
IceTInt group_size,
IceTInt largest_group_size,
IceTSparseImage working_image,
IceTSparseImage *result_image,
IceTSizeType *piece_offset)
......@@ -487,13 +504,24 @@ static void bswapComposeNoCombine(const IceTInt *compose_group,
if (group_rank >= pow2size) {
IceTInt upper_group_rank = group_rank - pow2size;
/* Fix largest group size if necessary. */
if (largest_group_size == -1) {
largest_group_size = pow2size;
}
/* I am part of the extra stuff. Recurse to run bswap on my part. */
bswapComposeNoCombine(compose_group + pow2size, extra_proc,
working_image, result_image, piece_offset);
bswapComposeNoCombine(compose_group + pow2size,
extra_proc,
largest_group_size,
working_image,
result_image,
piece_offset);
/* Now I may have some image data to send to lower group. */
if (upper_group_rank < extra_pow2size) {
bswapSendFromUpperGroup(compose_group, pow2size,
compose_group + pow2size, extra_pow2size,
bswapSendFromUpperGroup(compose_group,
pow2size,
compose_group + pow2size,
extra_pow2size,
largest_group_size,
*result_image);
}
/* Report I have no image. */
......@@ -538,6 +566,7 @@ void icetBswapCompose(const IceTInt *compose_group,
/* Do actual bswap. */
bswapComposeNoCombine(compose_group,
group_size,
-1,
input_image,
result_image,
piece_offset);
......
......@@ -216,6 +216,8 @@ static void radixkGetPartitionIndices(int num_rounds,
k_array: vector of k values
current_round: current round number (0 to num_rounds - 1)
partition_index: image partition to collect (0 to k[current_round] - 1)
remainging_partitions: Number of pieces the image will be split into by
the end of the algorithm.
compose_group: array of world ranks representing the group of processes
participating in compositing (passed into icetRadixkCompose)
group_rank: Index in compose_group that represents me
......@@ -229,6 +231,7 @@ static void radixkGetPartitionIndices(int num_rounds,
static radixkPartnerInfo *radixkGetPartners(const int *k_array,
int current_round,
int partition_index,
int remaining_partitions,
const int *compose_group,
int group_rank,
IceTSizeType start_size)
......@@ -251,8 +254,10 @@ static radixkPartnerInfo *radixkGetPartners(const int *k_array,
}
/* Allocate arrays that can be used as send/receive buffers. */
partition_num_pixels = icetSparseImageSplitPartitionNumPixels(start_size,
current_k);
partition_num_pixels
= icetSparseImageSplitPartitionNumPixels(start_size,
current_k,
remaining_partitions);
sparse_image_size = icetSparseImageBufferSize(partition_num_pixels, 1);
recv_buf_pool = icetGetStateBuffer(RADIXK_RECEIVE_BUFFER,
sparse_image_size * current_k);
......@@ -298,6 +303,7 @@ static IceTCommRequest *radixkPostReceives(radixkPartnerInfo *partners,
int current_k,
int current_round,
int current_partition_index,
int remaining_partitions,
IceTSizeType start_size)
{
IceTCommRequest *receive_requests;
......@@ -312,8 +318,10 @@ static IceTCommRequest *radixkPostReceives(radixkPartnerInfo *partners,
receive_requests = icetGetStateBuffer(RADIXK_RECEIVE_REQUEST_BUFFER,
current_k * sizeof(IceTCommRequest));
partition_num_pixels = icetSparseImageSplitPartitionNumPixels(start_size,
current_k);
partition_num_pixels
= icetSparseImageSplitPartitionNumPixels(start_size,
current_k,
remaining_partitions);
sparse_image_size = icetSparseImageBufferSize(partition_num_pixels, 1);
tag = RADIXK_SWAP_IMAGE_TAG_START + current_round;
......@@ -346,6 +354,7 @@ static IceTCommRequest *radixkPostSends(radixkPartnerInfo *partners,
int current_k,
int current_round,
int current_partition_index,
int remaining_partitions,
IceTSizeType start_offset,
const IceTSparseImage image)
{
......@@ -368,7 +377,11 @@ static IceTCommRequest *radixkPostSends(radixkPartnerInfo *partners,
for (i = 0; i < current_k; i++) {
image_pieces[i] = partners[i].sendImage;
}
icetSparseImageSplit(image, current_k, image_pieces, piece_offsets);
icetSparseImageSplit(image,
current_k,
remaining_partitions,
image_pieces,
piece_offsets);
tag = RADIXK_SWAP_IMAGE_TAG_START + current_round;
......@@ -508,6 +521,7 @@ void icetRadixkCompose(const IceTInt *compose_group,
IceTSizeType my_offset;
int *partition_indices; /* My round vector [round0 pos, round1 pos, ...] */
int current_round;
int remaining_partitions;
IceTSparseImage working_image = input_image;
......@@ -553,6 +567,7 @@ void icetRadixkCompose(const IceTInt *compose_group,
calculate the current round's peer sizes based on our current size and
the k_array[i] info. */
my_offset = 0;
remaining_partitions = group_size;
for (current_round = 0; current_round < num_rounds; current_round++) {
IceTSizeType my_size = icetSparseImageGetNumPixels(working_image);
......@@ -561,6 +576,7 @@ void icetRadixkCompose(const IceTInt *compose_group,
radixkPartnerInfo *partners = radixkGetPartners(k_array,
current_round,
current_partition_index,
remaining_partitions,
compose_group,
group_rank,
my_size);
......@@ -571,12 +587,14 @@ void icetRadixkCompose(const IceTInt *compose_group,
current_k,
current_round,
current_partition_index,
remaining_partitions,
my_size);
send_requests = radixkPostSends(partners,
current_k,
current_round,
current_partition_index,
remaining_partitions,
my_offset,
working_image);
......@@ -589,6 +607,7 @@ void icetRadixkCompose(const IceTInt *compose_group,
icetCommWaitall(current_k, send_requests);
my_offset = partners[current_partition_index].offset;
remaining_partitions /= current_k;
} /* for all rounds */
*result_image = working_image;
......
......@@ -62,11 +62,11 @@ static IceTDouble g_opacity_lookup[OPACITY_LOOKUP_SIZE+1];
static void init_opacity_lookup(void)
{
IceTSizeType index;
IceTSizeType idx;
for (index = 0; index < OPACITY_LOOKUP_SIZE+1; index++) {
IceTDouble distance_times_tau = OPACITY_INDEX_2_DT(index);
g_opacity_lookup[index] = OPACITY_COMPUTE_VALUE(distance_times_tau);
for (idx = 0; idx < OPACITY_LOOKUP_SIZE+1; idx++) {
IceTDouble distance_times_tau = OPACITY_INDEX_2_DT(idx);
g_opacity_lookup[idx] = OPACITY_COMPUTE_VALUE(distance_times_tau);
}
}
......
......@@ -222,7 +222,9 @@ static int TestSparseImageSplit(const IceTImage image)
width = icetImageGetWidth(image);
height = icetImageGetHeight(image);
num_partition_pixels
= icetSparseImageSplitPartitionNumPixels(width*height, NUM_PARTITIONS);
= icetSparseImageSplitPartitionNumPixels(width*height,
NUM_PARTITIONS,
NUM_PARTITIONS);
full_sparse_buffer = malloc(icetSparseImageBufferSize(width, height));
full_sparse = icetSparseImageAssignBuffer(full_sparse_buffer,width,height);
......@@ -245,6 +247,7 @@ static int TestSparseImageSplit(const IceTImage image)
printf("Spliting image %d times\n", NUM_PARTITIONS);
icetSparseImageSplit(full_sparse,
NUM_PARTITIONS,
NUM_PARTITIONS,
sparse_partition,
offsets);
......@@ -265,6 +268,7 @@ static int TestSparseImageSplit(const IceTImage image)
NUM_PARTITIONS);
sparse_partition[0] = full_sparse;
icetSparseImageSplit(full_sparse,
NUM_PARTITIONS,
NUM_PARTITIONS,
sparse_partition,
offsets);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment