@@ -358,7 +358,8 @@ __STATIC_INLINE__ void ggml_merge_tensor_2d(struct ggml_tensor* input,
358358 struct ggml_tensor * output,
359359 int x,
360360 int y,
361- int overlap) {
361+ int overlap_x,
362+ int overlap_y) {
362363 int64_t width = input->ne [0 ];
363364 int64_t height = input->ne [1 ];
364365 int64_t channels = input->ne [2 ];
@@ -371,13 +372,13 @@ __STATIC_INLINE__ void ggml_merge_tensor_2d(struct ggml_tensor* input,
371372 for (int ix = 0 ; ix < width; ix++) {
372373 for (int k = 0 ; k < channels; k++) {
373374 float new_value = ggml_tensor_get_f32 (input, ix, iy, k);
374- if (overlap > 0 ) { // blend colors in overlapped area
375+ if (overlap_x > 0 && overlap_y > 0 ) { // blend colors in overlapped area
375376 float old_value = ggml_tensor_get_f32 (output, x + ix, y + iy, k);
376377
377- const float x_f_0 = (x > 0 ) ? ix / float (overlap ) : 1 ;
378- const float x_f_1 = (x < (img_width - width)) ? (width - ix) / float (overlap ) : 1 ;
379- const float y_f_0 = (y > 0 ) ? iy / float (overlap ) : 1 ;
380- const float y_f_1 = (y < (img_height - height)) ? (height - iy) / float (overlap ) : 1 ;
378+ const float x_f_0 = (overlap_x > 0 && x > 0 ) ? ix / float (overlap_x ) : 1 ;
379+ const float x_f_1 = (overlap_x > 0 && x < (img_width - width)) ? (width - ix) / float (overlap_x ) : 1 ;
380+ const float y_f_0 = (overlap_y > 0 && y > 0 ) ? iy / float (overlap_y ) : 1 ;
381+ const float y_f_1 = (overlap_y > 0 && y < (img_height - height)) ? (height - iy) / float (overlap_y ) : 1 ;
381382
382383 const float x_f = std::min (std::min (x_f_0, x_f_1), 1 .f );
383384 const float y_f = std::min (std::min (y_f_0, y_f_1), 1 .f );
@@ -505,11 +506,21 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
505506 input_tile_size = tile_size * scale;
506507 output_tile_size = tile_size;
507508 }
509+ int num_tiles_x = (float )(input_width - input_tile_size * tile_overlap_factor) / (float )(input_tile_size * (1 - tile_overlap_factor));
510+ float tile_overlap_factor_x = (float )(input_tile_size * num_tiles_x - input_width) / (float )(input_tile_size * (num_tiles_x - 1 ));
511+
512+ int num_tiles_y = (float )(input_height - input_tile_size * tile_overlap_factor) / (float )(input_tile_size * (1 - tile_overlap_factor));
513+ float tile_overlap_factor_y = (float )(input_tile_size * num_tiles_y - input_height) / (float )(input_tile_size * (num_tiles_y - 1 ));
514+
515+ LOG_DEBUG (" optimal overlap : %f, %f (targeting %f)" , tile_overlap_factor_x, tile_overlap_factor_y, tile_overlap_factor);
508516
509517 GGML_ASSERT (input_width % 2 == 0 && input_height % 2 == 0 && output_width % 2 == 0 && output_height % 2 == 0 ); // should be multiple of 2
510518
511- int tile_overlap = (int32_t )(input_tile_size * tile_overlap_factor);
512- int non_tile_overlap = input_tile_size - tile_overlap;
519+ int tile_overlap_x = (int32_t )(input_tile_size * tile_overlap_factor_x);
520+ int non_tile_overlap_x = input_tile_size - tile_overlap_x;
521+
522+ int tile_overlap_y = (int32_t )(input_tile_size * tile_overlap_factor_y);
523+ int non_tile_overlap_y = input_tile_size - tile_overlap_y;
513524
514525 struct ggml_init_params params = {};
515526 params.mem_size += input_tile_size * input_tile_size * input->ne [2 ] * sizeof (float ); // input chunk
@@ -531,18 +542,18 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
531542 ggml_tensor* input_tile = ggml_new_tensor_4d (tiles_ctx, GGML_TYPE_F32, input_tile_size, input_tile_size, input->ne [2 ], 1 );
532543 ggml_tensor* output_tile = ggml_new_tensor_4d (tiles_ctx, GGML_TYPE_F32, output_tile_size, output_tile_size, output->ne [2 ], 1 );
533544 on_processing (input_tile, NULL , true );
534- int num_tiles = ceil (( float )input_width / non_tile_overlap) * ceil (( float )input_height / non_tile_overlap) ;
545+ int num_tiles = num_tiles_x * num_tiles_y ;
535546 LOG_INFO (" processing %i tiles" , num_tiles);
536547 pretty_progress (1 , num_tiles, 0 .0f );
537548 int tile_count = 1 ;
538549 bool last_y = false , last_x = false ;
539550 float last_time = 0 .0f ;
540- for (int y = 0 ; y < input_height && !last_y; y += non_tile_overlap ) {
551+ for (int y = 0 ; y < input_height && !last_y; y += non_tile_overlap_y ) {
541552 if (y + input_tile_size >= input_height) {
542553 y = input_height - input_tile_size;
543554 last_y = true ;
544555 }
545- for (int x = 0 ; x < input_width && !last_x; x += non_tile_overlap ) {
556+ for (int x = 0 ; x < input_width && !last_x; x += non_tile_overlap_x ) {
546557 if (x + input_tile_size >= input_width) {
547558 x = input_width - input_tile_size;
548559 last_x = true ;
@@ -551,9 +562,9 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
551562 ggml_split_tensor_2d (input, input_tile, x, y);
552563 on_processing (input_tile, output_tile, false );
553564 if (scaled_out) {
554- ggml_merge_tensor_2d (output_tile, output, x * scale, y * scale, tile_overlap * scale);
565+ ggml_merge_tensor_2d (output_tile, output, x * scale, y * scale, tile_overlap_x * scale, tile_overlap_y * scale);
555566 } else {
556- ggml_merge_tensor_2d (output_tile, output, x / scale, y / scale, tile_overlap / scale);
567+ ggml_merge_tensor_2d (output_tile, output, x / scale, y / scale, tile_overlap_x / scale, tile_overlap_y / scale);
557568 }
558569 int64_t t2 = ggml_time_ms ();
559570 last_time = (t2 - t1) / 1000 .0f ;
0 commit comments