@@ -470,7 +470,10 @@ __STATIC_INLINE__ void ggml_merge_tensor_2d(struct ggml_tensor* input,
470470 struct ggml_tensor * output,
471471 int x,
472472 int y,
473- int overlap) {
473+ int overlap_x,
474+ int overlap_y,
475+ int x_skip = 0 ,
476+ int y_skip = 0 ) {
474477 int64_t width = input->ne [0 ];
475478 int64_t height = input->ne [1 ];
476479 int64_t channels = input->ne [2 ];
@@ -479,17 +482,17 @@ __STATIC_INLINE__ void ggml_merge_tensor_2d(struct ggml_tensor* input,
479482 int64_t img_height = output->ne [1 ];
480483
481484 GGML_ASSERT (input->type == GGML_TYPE_F32 && output->type == GGML_TYPE_F32);
482- for (int iy = 0 ; iy < height; iy++) {
483- for (int ix = 0 ; ix < width; ix++) {
485+ for (int iy = y_skip ; iy < height; iy++) {
486+ for (int ix = x_skip ; ix < width; ix++) {
484487 for (int k = 0 ; k < channels; k++) {
485488 float new_value = ggml_tensor_get_f32 (input, ix, iy, k);
486- if (overlap > 0 ) { // blend colors in overlapped area
489+ if (overlap_x > 0 || overlap_y > 0 ) { // blend colors in overlapped area
487490 float old_value = ggml_tensor_get_f32 (output, x + ix, y + iy, k);
488491
489- const float x_f_0 = (x > 0 ) ? ix / float (overlap ) : 1 ;
490- const float x_f_1 = (x < (img_width - width)) ? (width - ix) / float (overlap ) : 1 ;
491- const float y_f_0 = (y > 0 ) ? iy / float (overlap ) : 1 ;
492- const float y_f_1 = (y < (img_height - height)) ? (height - iy) / float (overlap ) : 1 ;
492+ const float x_f_0 = (overlap_x > 0 && x > 0 ) ? ( ix - x_skip) / float (overlap_x ) : 1 ;
493+ const float x_f_1 = (overlap_x > 0 && x < (img_width - width)) ? (width - ix) / float (overlap_x ) : 1 ;
494+ const float y_f_0 = (overlap_y > 0 && y > 0 ) ? ( iy - y_skip) / float (overlap_y ) : 1 ;
495+ const float y_f_1 = (overlap_y > 0 && y < (img_height - height)) ? (height - iy) / float (overlap_y ) : 1 ;
493496
494497 const float x_f = std::min (std::min (x_f_0, x_f_1), 1 .f );
495498 const float y_f = std::min (std::min (y_f_0, y_f_1), 1 .f );
@@ -602,21 +605,96 @@ __STATIC_INLINE__ void ggml_tensor_scale_output(struct ggml_tensor* src) {
602605
603606typedef std::function<void (ggml_tensor*, ggml_tensor*, bool )> on_tile_process;
604607
608+ __STATIC_INLINE__ void
609+ sd_tiling_calc_tiles (int &num_tiles_dim, float & tile_overlap_factor_dim, int small_dim, int tile_size, const float tile_overlap_factor) {
610+
611+ int tile_overlap = (tile_size * tile_overlap_factor);
612+ int non_tile_overlap = tile_size - tile_overlap;
613+
614+ num_tiles_dim = (small_dim - tile_overlap) / non_tile_overlap;
615+ int overshoot_dim = ((num_tiles_dim + 1 ) * non_tile_overlap + tile_overlap) % small_dim;
616+
617+ if ((overshoot_dim != non_tile_overlap) && (overshoot_dim <= num_tiles_dim * (tile_size / 2 - tile_overlap))) {
618+ // if tiles don't fit perfectly using the desired overlap
619+ // and there is enough room to squeeze an extra tile without overlap becoming >0.5
620+ num_tiles_dim++;
621+ }
622+
623+ tile_overlap_factor_dim = (float )(tile_size * num_tiles_dim - small_dim) / (float )(tile_size * (num_tiles_dim - 1 ));
624+ if (num_tiles_dim <= 2 ) {
625+ if (small_dim <= tile_size) {
626+ num_tiles_dim = 1 ;
627+ tile_overlap_factor_dim = 0 ;
628+ } else {
629+ num_tiles_dim = 2 ;
630+ tile_overlap_factor_dim = (2 * tile_size - small_dim) / (float )tile_size;
631+ }
632+ }
633+ }
634+
605635// Tiling
606- __STATIC_INLINE__ void sd_tiling (ggml_tensor* input, ggml_tensor* output, const int scale, const int tile_size, const float tile_overlap_factor, on_tile_process on_processing) {
636+ __STATIC_INLINE__ void sd_tiling_non_square (ggml_tensor* input, ggml_tensor* output, const int scale,
637+ const int p_tile_size_x, const int p_tile_size_y,
638+ const float tile_overlap_factor, on_tile_process on_processing) {
639+
607640 output = ggml_set_f32 (output, 0 );
641+
608642 int input_width = (int )input->ne [0 ];
609643 int input_height = (int )input->ne [1 ];
610644 int output_width = (int )output->ne [0 ];
611645 int output_height = (int )output->ne [1 ];
646+
647+ GGML_ASSERT (input_width / output_width == input_height / output_height && output_width / input_width == output_height / input_height);
648+ GGML_ASSERT (input_width / output_width == scale || output_width / input_width == scale);
649+
650+ int small_width = output_width;
651+ int small_height = output_height;
652+
653+ bool big_out = output_width > input_width;
654+ if (big_out) {
655+ // Ex: decode
656+ small_width = input_width;
657+ small_height = input_height;
658+ }
659+
660+ int num_tiles_x;
661+ float tile_overlap_factor_x;
662+ sd_tiling_calc_tiles (num_tiles_x, tile_overlap_factor_x, small_width, p_tile_size_x, tile_overlap_factor);
663+
664+ int num_tiles_y;
665+ float tile_overlap_factor_y;
666+ sd_tiling_calc_tiles (num_tiles_y, tile_overlap_factor_y, small_height, p_tile_size_y, tile_overlap_factor);
667+
668+ // LOG_DEBUG("num tiles : %d, %d ", num_tiles_x, num_tiles_y);
669+ // LOG_DEBUG("optimal overlap : %f, %f (targeting %f)", tile_overlap_factor_x, tile_overlap_factor_y, tile_overlap_factor);
670+
612671 GGML_ASSERT (input_width % 2 == 0 && input_height % 2 == 0 && output_width % 2 == 0 && output_height % 2 == 0 ); // should be multiple of 2
613672
614- int tile_overlap = (int32_t )(tile_size * tile_overlap_factor);
615- int non_tile_overlap = tile_size - tile_overlap;
673+ int tile_overlap_x = (int32_t )(p_tile_size_x * tile_overlap_factor_x);
674+ int non_tile_overlap_x = p_tile_size_x - tile_overlap_x;
675+
676+ int tile_overlap_y = (int32_t )(p_tile_size_y * tile_overlap_factor_y);
677+ int non_tile_overlap_y = p_tile_size_y - tile_overlap_y;
678+
679+ int tile_size_x = p_tile_size_x < small_width ? p_tile_size_x : small_width;
680+ int tile_size_y = p_tile_size_y < small_height ? p_tile_size_y : small_height;
681+
682+ int input_tile_size_x = tile_size_x;
683+ int input_tile_size_y = tile_size_y;
684+ int output_tile_size_x = tile_size_x;
685+ int output_tile_size_y = tile_size_y;
686+
687+ if (big_out) {
688+ output_tile_size_x *= scale;
689+ output_tile_size_y *= scale;
690+ } else {
691+ input_tile_size_x *= scale;
692+ input_tile_size_y *= scale;
693+ }
616694
617695 struct ggml_init_params params = {};
618- params.mem_size += tile_size * tile_size * input->ne [2 ] * sizeof (float ); // input chunk
619- params.mem_size += (tile_size * scale) * (tile_size * scale) * output->ne [2 ] * sizeof (float ); // output chunk
696+ params.mem_size += input_tile_size_x * input_tile_size_y * input->ne [2 ] * sizeof (float ); // input chunk
697+ params.mem_size += output_tile_size_x * output_tile_size_y * output->ne [2 ] * sizeof (float ); // output chunk
620698 params.mem_size += 3 * ggml_tensor_overhead ();
621699 params.mem_buffer = NULL ;
622700 params.no_alloc = false ;
@@ -631,29 +709,50 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
631709 }
632710
633711 // tiling
634- ggml_tensor* input_tile = ggml_new_tensor_4d (tiles_ctx, GGML_TYPE_F32, tile_size, tile_size, input->ne [2 ], 1 );
635- ggml_tensor* output_tile = ggml_new_tensor_4d (tiles_ctx, GGML_TYPE_F32, tile_size * scale, tile_size * scale, output->ne [2 ], 1 );
636- on_processing (input_tile, NULL , true );
637- int num_tiles = ceil ((float )input_width / non_tile_overlap) * ceil ((float )input_height / non_tile_overlap);
712+ ggml_tensor* input_tile = ggml_new_tensor_4d (tiles_ctx, GGML_TYPE_F32, input_tile_size_x, input_tile_size_y, input->ne [2 ], 1 );
713+ ggml_tensor* output_tile = ggml_new_tensor_4d (tiles_ctx, GGML_TYPE_F32, output_tile_size_x, output_tile_size_y, output->ne [2 ], 1 );
714+ int num_tiles = num_tiles_x * num_tiles_y;
638715 LOG_INFO (" processing %i tiles" , num_tiles);
639- pretty_progress (1 , num_tiles, 0 .0f );
716+ pretty_progress (0 , num_tiles, 0 .0f );
640717 int tile_count = 1 ;
641718 bool last_y = false , last_x = false ;
642719 float last_time = 0 .0f ;
643- for (int y = 0 ; y < input_height && !last_y; y += non_tile_overlap) {
644- if (y + tile_size >= input_height) {
645- y = input_height - tile_size;
720+ for (int y = 0 ; y < small_height && !last_y; y += non_tile_overlap_y) {
721+ int dy = 0 ;
722+ if (y + tile_size_y >= small_height) {
723+ int _y = y;
724+ y = small_height - tile_size_y;
725+ dy = _y - y;
726+ if (big_out) {
727+ dy *= scale;
728+ }
646729 last_y = true ;
647730 }
648- for (int x = 0 ; x < input_width && !last_x; x += non_tile_overlap) {
649- if (x + tile_size >= input_width) {
650- x = input_width - tile_size;
731+ for (int x = 0 ; x < small_width && !last_x; x += non_tile_overlap_x) {
732+ int dx = 0 ;
733+ if (x + tile_size_x >= small_width) {
734+ int _x = x;
735+ x = small_width - tile_size_x;
736+ dx = _x - x;
737+ if (big_out) {
738+ dx *= scale;
739+ }
651740 last_x = true ;
652741 }
742+
743+ int x_in = big_out ? x : scale * x;
744+ int y_in = big_out ? y : scale * y;
745+ int x_out = big_out ? x * scale : x;
746+ int y_out = big_out ? y * scale : y;
747+
748+ int overlap_x_out = big_out ? tile_overlap_x * scale : tile_overlap_x;
749+ int overlap_y_out = big_out ? tile_overlap_y * scale : tile_overlap_y;
750+
653751 int64_t t1 = ggml_time_ms ();
654- ggml_split_tensor_2d (input, input_tile, x, y );
752+ ggml_split_tensor_2d (input, input_tile, x_in, y_in );
655753 on_processing (input_tile, output_tile, false );
656- ggml_merge_tensor_2d (output_tile, output, x * scale, y * scale, tile_overlap * scale);
754+ ggml_merge_tensor_2d (output_tile, output, x_out, y_out, overlap_x_out, overlap_y_out, dx, dy);
755+
657756 int64_t t2 = ggml_time_ms ();
658757 last_time = (t2 - t1) / 1000 .0f ;
659758 pretty_progress (tile_count, num_tiles, last_time);
@@ -667,6 +766,11 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
667766 ggml_free (tiles_ctx);
668767}
669768
769+ __STATIC_INLINE__ void sd_tiling (ggml_tensor* input, ggml_tensor* output, const int scale,
770+ const int tile_size, const float tile_overlap_factor, on_tile_process on_processing) {
771+ sd_tiling_non_square (input, output, scale, tile_size, tile_size, tile_overlap_factor, on_processing);
772+ }
773+
670774__STATIC_INLINE__ struct ggml_tensor * ggml_group_norm_32 (struct ggml_context * ctx,
671775 struct ggml_tensor * a) {
672776 const float eps = 1e-6f ; // default eps parameter
0 commit comments