@@ -556,7 +556,7 @@ TEST_F(OpConvCorrectnessTest, TransposedNonDefaultParams) {
556
556
Tensor input = tf.full ({2 , 6 , 4 , 5 }, 2.0 );
557
557
Tensor weight = tf.full ({6 , 1 , 2 , 2 }, 0.5 );
558
558
Tensor bias = tf.make ({3 }, {1 , 2 , 3 });
559
- Tensor out = tf.zeros ({2 , 3 , 3 , 6 });
559
+ Tensor out = tf.full ({2 , 3 , 3 , 6 }, 0.7 );
560
560
Tensor expected = tf.make (
561
561
{2 , 3 , 3 , 6 },
562
562
{1 , 1 , 1 , 1 , 1 , 1 , 1 , 3 , 3 , 1 , 3 , 3 , 1 , 3 , 3 , 1 , 3 , 3 , 2 , 2 , 2 , 2 ,
@@ -587,6 +587,118 @@ TEST_F(OpConvCorrectnessTest, TransposedNonDefaultParams) {
587
587
EXPECT_TENSOR_CLOSE (out, expected);
588
588
}
589
589
590
+ template <typename T>
591
+ std::vector<T> get_channels_last_data (const Tensor& t) {
592
+ const std::vector<int32_t > sizes (t.sizes ().begin (), t.sizes ().end ());
593
+ std::vector<T> contiguous_data (
594
+ t.const_data_ptr <T>(), t.const_data_ptr <T>() + t.numel ());
595
+ std::vector<T> channels_last_data (t.numel ());
596
+ int32_t N = sizes[0 ];
597
+ int32_t C = sizes[1 ];
598
+ int32_t H = sizes[2 ];
599
+ int32_t W = sizes[3 ];
600
+ for (int32_t n = 0 ; n < N; ++n) {
601
+ for (int32_t c = 0 ; c < C; ++c) {
602
+ for (int32_t h = 0 ; h < H; ++h) {
603
+ for (int32_t w = 0 ; w < W; ++w) {
604
+ // Calculate the index in the original blob
605
+ int32_t old_index = ((n * C + c) * H + h) * W + w;
606
+ // Calculate the index in the new blob
607
+ int32_t new_index = ((n * H + h) * W + w) * C + c;
608
+ // Copy the data
609
+ channels_last_data[new_index] = contiguous_data[old_index];
610
+ }
611
+ }
612
+ }
613
+ }
614
+ return channels_last_data;
615
+ }
616
+
617
+ TEST_F (OpConvCorrectnessTest, TransposedDefaultParamsChannelsLast) {
618
+ TensorFactory<ScalarType::Float> tf;
619
+
620
+ Tensor input = tf.full_channels_last ({2 , 4 , 3 , 2 }, 2.0 );
621
+ Tensor weight = tf.full_channels_last ({4 , 1 , 2 , 2 }, 0.5 );
622
+ optional<Tensor> bias;
623
+ Tensor out = tf.full_channels_last ({2 , 2 , 4 , 3 }, 0.7 );
624
+ Tensor expected =
625
+ tf.make ({2 , 2 , 4 , 3 }, {2 , 4 , 2 , 4 , 8 , 4 , 4 , 8 , 4 , 2 , 4 , 2 , 2 , 4 , 2 , 4 ,
626
+ 8 , 4 , 4 , 8 , 4 , 2 , 4 , 2 , 2 , 4 , 2 , 4 , 8 , 4 , 4 , 8 ,
627
+ 4 , 2 , 4 , 2 , 2 , 4 , 2 , 4 , 8 , 4 , 4 , 8 , 4 , 2 , 4 , 2 });
628
+
629
+ const std::vector<int32_t > sizes (
630
+ expected.sizes ().begin (), expected.sizes ().end ());
631
+ std::vector<float > channels_last_data =
632
+ get_channels_last_data<float >(expected);
633
+ Tensor expected_channels_last =
634
+ tf.make_channels_last (sizes, channels_last_data);
635
+
636
+ int64_t stride[1 ] = {1 };
637
+ int64_t padding[1 ] = {0 };
638
+ int64_t dilation[1 ] = {1 };
639
+ bool transposed = true ;
640
+ int64_t output_padding[1 ] = {0 };
641
+ int64_t groups = 2 ;
642
+
643
+ op_convolution_out (
644
+ input,
645
+ weight,
646
+ exec_aten::optional<Tensor>(bias),
647
+ exec_aten::ArrayRef<int64_t >{stride, 1 },
648
+ exec_aten::ArrayRef<int64_t >{padding, 1 },
649
+ exec_aten::ArrayRef<int64_t >{dilation, 1 },
650
+ transposed,
651
+ exec_aten::ArrayRef<int64_t >{output_padding, 1 },
652
+ groups,
653
+ out);
654
+
655
+ EXPECT_TENSOR_CLOSE (out, expected_channels_last);
656
+ }
657
+
658
+ TEST_F (OpConvCorrectnessTest, TransposedNonDefaultParamsChannelsLast) {
659
+ TensorFactory<ScalarType::Float> tf;
660
+
661
+ Tensor input = tf.full_channels_last ({2 , 6 , 4 , 5 }, 2.0 );
662
+ Tensor weight = tf.full_channels_last ({6 , 1 , 2 , 2 }, 0.5 );
663
+ Tensor bias = tf.make ({3 }, {1 , 2 , 3 });
664
+ Tensor out = tf.full_channels_last ({2 , 3 , 3 , 6 }, 0.7 );
665
+ Tensor expected = tf.make (
666
+ {2 , 3 , 3 , 6 },
667
+ {1 , 1 , 1 , 1 , 1 , 1 , 1 , 3 , 3 , 1 , 3 , 3 , 1 , 3 , 3 , 1 , 3 , 3 , 2 , 2 , 2 , 2 ,
668
+ 2 , 2 , 2 , 4 , 4 , 2 , 4 , 4 , 2 , 4 , 4 , 2 , 4 , 4 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 5 ,
669
+ 5 , 3 , 5 , 5 , 3 , 5 , 5 , 3 , 5 , 5 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 3 , 3 , 1 , 3 , 3 ,
670
+ 1 , 3 , 3 , 1 , 3 , 3 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 4 , 4 , 2 , 4 , 4 , 2 , 4 , 4 , 2 ,
671
+ 4 , 4 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 5 , 5 , 3 , 5 , 5 , 3 , 5 , 5 , 3 , 5 , 5 });
672
+
673
+ const std::vector<int32_t > sizes (
674
+ expected.sizes ().begin (), expected.sizes ().end ());
675
+ std::vector<float > channels_last_data =
676
+ get_channels_last_data<float >(expected);
677
+ Tensor expected_channels_last =
678
+ tf.make_channels_last (sizes, channels_last_data);
679
+
680
+ int64_t stride[1 ] = {3 };
681
+ int64_t padding[1 ] = {7 };
682
+ int64_t dilation[1 ] = {5 };
683
+ bool transposed = true ;
684
+ int64_t output_padding[1 ] = {2 };
685
+ int64_t groups = 3 ;
686
+
687
+ op_convolution_out (
688
+ input,
689
+ weight,
690
+ exec_aten::optional<Tensor>(bias),
691
+ exec_aten::ArrayRef<int64_t >{stride, 1 },
692
+ exec_aten::ArrayRef<int64_t >{padding, 1 },
693
+ exec_aten::ArrayRef<int64_t >{dilation, 1 },
694
+ transposed,
695
+ exec_aten::ArrayRef<int64_t >{output_padding, 1 },
696
+ groups,
697
+ out);
698
+
699
+ EXPECT_TENSOR_CLOSE (out, expected_channels_last);
700
+ }
701
+
590
702
TEST_F (OpConvCorrectnessTest, InvalidOutputPadding) {
591
703
TensorFactory<ScalarType::Float> tf;
592
704
0 commit comments