Repository: ggerganov/llama.cpp
File: tests/test-backend-ops.cpp (C++)

Code before:
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {12, 12, 2, 32}, {3, 3, 2, 32}, 1, 1, 1, 1, 1, 1, true));
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {12, 12, 1, 1024}, {3, 3, 1, 1024}, 1, 1, 1, 1, 1, 1, true));
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {12, 12, 2, 1024}, {3, 3, 2, 1024}, 1, 1, 1, 1, 1, 1, true));
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {12, 12, 1, 2048}, {3, 3, 1, 2048}, 1, 1, 1, 1, 1, 1, true));
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {12, 12, 2, 2048}, {3, 3, 2, 2048}, 1, 1, 1, 1, 1, 1, true));
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {12, 12, 1, 2560}, {3, 3, 1, 2560}, 1, 1, 1, 1, 1, 1, true));
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {12, 12, 2, 2560}, {3, 3, 2, 2560}, 1, 1, 1, 1, 1, 1, true));
    test_cases.emplace_back(new test_im2col(GGML_TYPE_F32, GGML_TYPE_F16, GGML_TYPE_F16, {5, 5, 1, 32}, {3, 4, 1, 32}, 1, 1, 0, 0, 1, 1, true));

// Conv_2D test cases
#ifdef DETAILED_TESTS
    // Probably we do not have enough time to execute these in the pipeline.
    uint32_t iwh_idx  = 0;
    uint32_t kwh_idx  = 1;
    uint32_t Cout_idx = 2;
    uint32_t Cin_idx  = 3;
    uint32_t B_idx    = 4;

    std::vector<std::array<int, 5>> cases = {
  //{IWH, KWH, Cout, Cin, B}
  // K=CRS=NPQ=4096 conv_2d matmul performance
        {19,   4, 4096, 256, 16},
 // K=128, CRS=128, NPQ=4096
        { 19,  4, 128,  8,   16},
 // K=130, CRS=128, NPQ=4096
        { 19,  4, 130,  8,   16},
 // Edge case: K x CRS is small
        { 19,  2, 4,    4,   16},
 // A ConvNet's first layer
        { 224, 3, 8,    3,   1 },
 // A ConvNet's first layer with 2x2 convolution, and 1 channel
        { 224, 2, 8,    1,   1 },
 // A ConvNet's first layer with 2x2 convolution, and 1 channel, several images in the batch
        { 224, 2, 8,    1,   8 },
 // A middle layer of a ConvNet
        { 58,  3, 64,   32,  1 },
 // A middle layer of a ConvNet, several images in the batch
        { 58,  3, 64,   32,  8 },
 // A deep layer of a ConvNet, several images in the batch
        { 16,  3, 256,  128, 8 }
    };

    for (auto act_case : cases) {
        test_cases.emplace_back(new test_conv_2d(
            { act_case[iwh_idx], act_case[iwh_idx], act_case[Cin_idx], act_case[B_idx] },
            { act_case[kwh_idx], act_case[kwh_idx], act_case[Cin_idx], act_case[Cout_idx] }, 1, 1, 0, 0, 1, 1, false));
    }
#endif

    // CONV_2D:
    auto calc_conv_output_size = [](int64_t ins, int64_t ks, int s, int p, int d) -> int64_t {

Review comment (suggestion):
If we repeat the same test for different formats we typically loop through a ggml_type instead.

https://github.com/ggml-org/llama.cpp/blob/793c0d7f46384001738c337d7afa46b45ae32745/tests/test-backend-ops.cpp#L4989-L4996

Code after:
        {19,   4, 4096, 256, 16},
 // K=128, CRS=128, NPQ=4096
        { 19,  4, 128,  8,   16},
 // K=130, CRS=128, NPQ=4096
        { 19,  4, 130,  8,   16},
 // Edge case: K x CRS is small
        { 19,  2, 4,    4,   16},
 // A ConvNet's first layer
        { 224, 3, 8,    3,   1 },
 // A ConvNet's first layer with 2x2 convolution, and 1 channel
        { 224, 2, 8,    1,   1 },
 // A ConvNet's first layer with 2x2 convolution, and 1 channel, several images in the batch
        { 224, 2, 8,    1,   8 },
 // A middle layer of a ConvNet
        { 58,  3, 64,   32,  1 },
 // A middle layer of a ConvNet, several images in the batch
        { 58,  3, 64,   32,  8 },
 // A deep layer of a ConvNet, several images in the batch
        { 16,  3, 256,  128, 8 }
    };

    for (auto kernel_type : {GGML_TYPE_F32, GGML_TYPE_F16}) {
        for (auto act_case : cases) {
            test_cases.emplace_back(new test_conv_2d(
                { act_case[iwh_idx], act_case[iwh_idx], act_case[Cin_idx], act_case[B_idx] },
                { act_case[kwh_idx], act_case[kwh_idx], act_case[Cin_idx], act_case[Cout_idx] },
                kernel_type, 1, 1, 0, 0, 1, 1, false));
        }
    }
#endif

    // CONV_2D:
    auto calc_conv_output_size = [](int64_t ins, int64_t ks, int s, int p, int d) -> int64_t {
        return (ins + 2 * p - d * (ks - 1) - 1) / s + 1;
    };

    //uint32_t s0 = 3;
    uint32_t s1 = 5;
    uint32_t p0 = 5;
    //uint32_t p1 = 2;
    uint32_t d0 = 2;
    uint32_t d1 = 4;

    for (uint32_t s0 : { 1, 3 }) {
        for (uint32_t p1 : { 2, 5 }) {
            for (uint32_t Cin : { 1, 25 }) {
                for (uint32_t Cout : { 1, 12 }) {
                    for (uint32_t KH : { 1, 2, 3, 11 }) {
                        for (uint32_t KW : { 1, 2, 3, 11 }) {
                            for (uint32_t H : { 1, 133 }) {
                                for (uint32_t W : { 1, 141 }) {