Skip to content

Commit b406ca6

Browse files
stduhpfStéphane du Hamel
authored andcommitted
Tiling (vae/upscale): adaptative overlap
1 parent 8e2320e commit b406ca6

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

ggml_extend.hpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ __STATIC_INLINE__ void ggml_merge_tensor_2d(struct ggml_tensor* input,
396396
struct ggml_tensor* output,
397397
int x,
398398
int y,
399-
int overlap) {
399+
int overlap_x,
400+
int overlap_y) {
400401
int64_t width = input->ne[0];
401402
int64_t height = input->ne[1];
402403
int64_t channels = input->ne[2];
@@ -409,13 +410,13 @@ __STATIC_INLINE__ void ggml_merge_tensor_2d(struct ggml_tensor* input,
409410
for (int ix = 0; ix < width; ix++) {
410411
for (int k = 0; k < channels; k++) {
411412
float new_value = ggml_tensor_get_f32(input, ix, iy, k);
412-
if (overlap > 0) { // blend colors in overlapped area
413+
if (overlap_x > 0 && overlap_y > 0) { // blend colors in overlapped area
413414
float old_value = ggml_tensor_get_f32(output, x + ix, y + iy, k);
414415

415-
const float x_f_0 = (x > 0) ? ix / float(overlap) : 1;
416-
const float x_f_1 = (x < (img_width - width)) ? (width - ix) / float(overlap) : 1;
417-
const float y_f_0 = (y > 0) ? iy / float(overlap) : 1;
418-
const float y_f_1 = (y < (img_height - height)) ? (height - iy) / float(overlap) : 1;
416+
const float x_f_0 = (overlap_x > 0 && x > 0) ? ix / float(overlap_x) : 1;
417+
const float x_f_1 = (overlap_x > 0 && x < (img_width - width)) ? (width - ix) / float(overlap_x) : 1;
418+
const float y_f_0 = (overlap_y > 0 && y > 0) ? iy / float(overlap_y) : 1;
419+
const float y_f_1 = (overlap_y > 0 && y < (img_height - height)) ? (height - iy) / float(overlap_y) : 1;
419420

420421
const float x_f = std::min(std::min(x_f_0, x_f_1), 1.f);
421422
const float y_f = std::min(std::min(y_f_0, y_f_1), 1.f);
@@ -543,11 +544,21 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
543544
input_tile_size = tile_size * scale;
544545
output_tile_size = tile_size;
545546
}
547+
int num_tiles_x = (float)(input_width - input_tile_size * tile_overlap_factor) / (float)(input_tile_size * (1 - tile_overlap_factor));
548+
float tile_overlap_factor_x = (float)(input_tile_size * num_tiles_x - input_width) / (float)(input_tile_size * (num_tiles_x - 1));
549+
550+
int num_tiles_y = (float)(input_height - input_tile_size * tile_overlap_factor) / (float)(input_tile_size * (1 - tile_overlap_factor));
551+
float tile_overlap_factor_y = (float)(input_tile_size * num_tiles_y - input_height) / (float)(input_tile_size * (num_tiles_y - 1));
552+
553+
LOG_DEBUG("optimal overlap : %f, %f (targeting %f)", tile_overlap_factor_x, tile_overlap_factor_y, tile_overlap_factor);
546554

547555
GGML_ASSERT(input_width % 2 == 0 && input_height % 2 == 0 && output_width % 2 == 0 && output_height % 2 == 0); // should be multiple of 2
548556

549-
int tile_overlap = (int32_t)(input_tile_size * tile_overlap_factor);
550-
int non_tile_overlap = input_tile_size - tile_overlap;
557+
int tile_overlap_x = (int32_t)(input_tile_size * tile_overlap_factor_x);
558+
int non_tile_overlap_x = input_tile_size - tile_overlap_x;
559+
560+
int tile_overlap_y = (int32_t)(input_tile_size * tile_overlap_factor_y);
561+
int non_tile_overlap_y = input_tile_size - tile_overlap_y;
551562

552563
struct ggml_init_params params = {};
553564
params.mem_size += input_tile_size * input_tile_size * input->ne[2] * sizeof(float); // input chunk
@@ -569,18 +580,18 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
569580
ggml_tensor* input_tile = ggml_new_tensor_4d(tiles_ctx, GGML_TYPE_F32, input_tile_size, input_tile_size, input->ne[2], 1);
570581
ggml_tensor* output_tile = ggml_new_tensor_4d(tiles_ctx, GGML_TYPE_F32, output_tile_size, output_tile_size, output->ne[2], 1);
571582
on_processing(input_tile, NULL, true);
572-
int num_tiles = ceil((float)input_width / non_tile_overlap) * ceil((float)input_height / non_tile_overlap);
583+
int num_tiles = num_tiles_x * num_tiles_y;
573584
LOG_INFO("processing %i tiles", num_tiles);
574585
pretty_progress(1, num_tiles, 0.0f);
575586
int tile_count = 1;
576587
bool last_y = false, last_x = false;
577588
float last_time = 0.0f;
578-
for (int y = 0; y < input_height && !last_y; y += non_tile_overlap) {
589+
for (int y = 0; y < input_height && !last_y; y += non_tile_overlap_y) {
579590
if (y + input_tile_size >= input_height) {
580591
y = input_height - input_tile_size;
581592
last_y = true;
582593
}
583-
for (int x = 0; x < input_width && !last_x; x += non_tile_overlap) {
594+
for (int x = 0; x < input_width && !last_x; x += non_tile_overlap_x) {
584595
if (x + input_tile_size >= input_width) {
585596
x = input_width - input_tile_size;
586597
last_x = true;
@@ -589,9 +600,9 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
589600
ggml_split_tensor_2d(input, input_tile, x, y);
590601
on_processing(input_tile, output_tile, false);
591602
if (scaled_out) {
592-
ggml_merge_tensor_2d(output_tile, output, x * scale, y * scale, tile_overlap * scale);
603+
ggml_merge_tensor_2d(output_tile, output, x * scale, y * scale, tile_overlap_x * scale, tile_overlap_y * scale);
593604
} else {
594-
ggml_merge_tensor_2d(output_tile, output, x / scale, y / scale, tile_overlap / scale);
605+
ggml_merge_tensor_2d(output_tile, output, x / scale, y / scale, tile_overlap_x / scale, tile_overlap_y / scale);
595606
}
596607
int64_t t2 = ggml_time_ms();
597608
last_time = (t2 - t1) / 1000.0f;

0 commit comments

Comments
 (0)