group_conv3d.cpp 6.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/**
 * \file dnn/test/cuda/group_conv3d.cpp
 * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
 *
 * Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 */
#include "megdnn/oprs/nn.h"

#include "test/common/benchmarker.h"
#include "test/common/checker.h"
#include "test/common/convolution3d.h"
#include "test/cuda/fixture.h"

#include "src/cuda/utils.h"

namespace megdnn {
namespace test {

TEST_F(CUDA, GROUP_CONVOLUTION3D_FORWARD) {
    bool is_int_available = (cuda::current_device_prop().major >= 6);
    static_cast<void>(is_int_available);
    auto run = [&](size_t N, size_t IC, size_t ID, size_t IH, size_t IW,
                   size_t FD, size_t FH, size_t FW, size_t OC, size_t PD,
                   size_t PH, size_t PW, size_t SD, size_t SH, size_t SW,
                   size_t DD, size_t DH, size_t DW, size_t group) {
        {
            // float case
            Checker<Convolution3D> checker(handle_cuda());
            Convolution3D::Param param;
            param.sparse = Convolution3D::Param::Sparse::GROUP;
            param.pad_d = PD;
            param.pad_h = PH;
            param.pad_w = PW;
            param.stride_d = SD;
            param.stride_h = SH;
            param.stride_w = SW;
            param.dilate_d = DD;
            param.dilate_h = DH;
            param.dilate_w = DW;
            auto ICpg = IC / group;
            auto OCpg = OC / group;
            checker.set_param(param).exec(
                    {{N, IC, ID, IH, IW}, {group, OCpg, ICpg, FD, FH, FW}, {}});
        }
    };
    // normal case
    run(2, 64, 7, 7, 7, 1, 1, 1, 32, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2);
    run(1, 2, 2, 2, 2, 1, 1, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2);
    run(2, 64, 7, 7, 7, 3, 3, 3, 32, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2);
    // padded case
    run(2, 32, 7, 7, 7, 3, 3, 3, 64, 2, 2, 2, 1, 1, 1, 1, 1, 1, 4);
    // strided case
    run(2, 32, 7, 7, 7, 3, 3, 3, 64, 0, 0, 0, 2, 2, 2, 1, 1, 1, 8);
    // dilated case
#if CUDNN_MAJOR >= 6
    run(10, 4, 64, 64, 12, 3, 2, 2, 64, 0, 0, 0, 1, 1, 1, 3, 4, 2, 4);
#else
#endif
}

TEST_F(CUDA, GROUP_CONVOLUTION3D_FORWARD_1x1x1) {
    auto run = [&](size_t N, size_t IC, size_t ID, size_t IH, size_t IW,
                   size_t FD, size_t FH, size_t FW, size_t OC, size_t group) {
        Checker<Convolution3D> checker(handle_cuda());
#if CUDNN_MAJOR <= 6
        bool require_algo = true;
        checker.set_before_exec_callback(
                AlgoChecker<Convolution3DForward>{
                        "group_conv3d:1x1x1", &require_algo});
#endif
        Convolution3D::Param param;
        param.sparse = Convolution3D::Param::Sparse::GROUP;
        auto ICg = IC / group;
        auto OCg = OC / group;
        checker.set_param(param).exec(
                {{N, IC, ID, IH, IW}, {group, OCg, ICg, FD, FH, FW}, {}});
    };
    size_t ic = 192;
    for (size_t g = 2; g <= 4; g += 1) {
        for (size_t id = 4; id <= 16; id *= 2) {
            size_t iw = id, ih = id;
            run(2, ic, id, ih, iw, 1, 1, 1, ic / g, g);
            run(2, ic, id + 1, ih + 1, iw + 1, 1, 1, 1, ic / g, g);
        }
    }
}

TEST_F(CUDA, GROUP_CONVOLUTION3D_BACKWARD_DATA) {
    auto run = [&](size_t N, size_t IC, size_t ID, size_t IH, size_t IW,
                   size_t FD, size_t FH, size_t FW, size_t OC, size_t OD,
                   size_t OH, size_t OW, size_t PD, size_t PH, size_t PW,
                   size_t SD, size_t SH, size_t SW, size_t group) {
        Checker<Convolution3DBackwardData> checker(handle_cuda());
        Convolution3DBackwardData::Param param;
        param.sparse = Convolution3D::Param::Sparse::GROUP;
        param.pad_d = PD;
        param.pad_h = PH;
        param.pad_w = PW;
        param.stride_d = SD;
        param.stride_h = SH;
        param.stride_w = SW;
        auto ICg = IC / group;
        auto OCg = OC / group;
        checker.set_param(param).exec({{group, OCg, ICg, FD, FH, FW},
                                       {N, OC, OD, OH, OW},
                                       {N, IC, ID, IH, IW}});
    };    
    // bug case in prev ver 
    
    run(1, 2, 1, 1, 1,  1, 1, 1, 2,  1, 1, 3, 0, 0, 1, 1, 1, 1, 2); 
    run(1, 2, 1, 1, 1,  1, 1, 1, 2,  1, 1, 2, 0, 0, 1, 1, 1, 2, 2); 
    run(1, 2, 1, 1, 1,  1, 1, 1, 2,  1, 2, 1, 0, 1, 0, 1, 2, 1, 2); 
    run(1, 2, 1, 1, 1,  1, 1, 1, 2,  2, 1, 1, 1, 0, 0, 2, 1, 1, 2); 
    // normal case
    run(2, 64, 7, 7, 7, 3, 3, 3, 32, 5, 5, 5, 0, 0, 0, 1, 1, 1, 2);
    // padded case
    run(2, 32, 7, 7, 7, 3, 3, 3, 64, 7, 7, 7, 1, 1, 1, 1, 1, 1, 4);
    // strided case
    run(2, 32, 7, 7, 7, 3, 3, 3, 64, 3, 3, 3, 0, 0, 0, 2, 2, 2, 8);
    // bigger case
    run(2, 32, 64, 64, 64, 3, 3, 3, 32, 62, 62, 62, 0, 0, 0, 1, 1, 1, 4);
}

TEST_F(CUDA, GROUP_CONVOLUTION3D_BACKWARD_FILTER) {
    auto run = [&](size_t N, size_t IC, size_t ID, size_t IH, size_t IW,
                   size_t FD, size_t FH, size_t FW, size_t OC, size_t OD,
                   size_t OH, size_t OW, size_t PD, size_t PH, size_t PW,
                   size_t SD, size_t SH, size_t SW, size_t group) {
        Checker<Convolution3DBackwardFilter> checker(handle_cuda());
        Convolution3DBackwardFilter::Param param;
        param.sparse = Convolution3D::Param::Sparse::GROUP;
        param.pad_d = PD;
        param.pad_h = PH;
        param.pad_w = PW;
        param.stride_d = SD;
        param.stride_h = SH;
        param.stride_w = SW;
        auto ICg = IC / group;
        auto OCg = OC / group;
        checker.set_param(param).exec({{N, IC, ID, IH, IW},
                                       {N, OC, OD, OH, OW},
                                       {group, OCg, ICg, FD, FH, FW}});
    };
    // normal case
    run(2, 64, 7, 7, 7, 3, 3, 3, 32, 5, 5, 5, 0, 0, 0, 1, 1, 1, 2);
    // padded case
    run(2, 32, 7, 7, 7, 3, 3, 3, 64, 7, 7, 7, 1, 1, 1, 1, 1, 1, 4);
    // strided case
    run(2, 32, 7, 7, 7, 3, 3, 3, 64, 3, 3, 3, 0, 0, 0, 2, 2, 2, 8);
}

}  // namespace test
}  // namespace megdnn

// vim: syntax=cpp.doxygen