"projects/NeRF-Det/nerfdet/nerf_det3d_data_sample.py" did not exist on "8deeb6e203f80329f33759c9e5a2ef6cb07902d3"
run_gemm_example.inc 6.38 KB
Newer Older
1
// SPDX-License-Identifier: MIT
Illia Silin's avatar
Illia Silin committed
2
// Copyright (c) 2018-2023, Advanced Micro Devices, Inc. All rights reserved.
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

#pragma once

bool run_gemm(const ProblemSize& problem_size, const ExecutionConfig& config)
{
#if defined(BUILD_INT4_EXAMPLE) && defined(CK_EXPERIMENTAL_BIT_INT_EXTENSION_INT4)
    static_assert(sizeof(ck::int4_t) == sizeof(int8_t));
#endif

    using namespace ck::literals;

    auto& [M, N, K, StrideA, StrideB, StrideC] = problem_size;

    auto f_host_tensor_descriptor =
        [](std::size_t row, std::size_t col, std::size_t stride, auto layout) {
            if constexpr(std::is_same_v<decltype(layout), ck::tensor_layout::gemm::RowMajor>)
            {
                return HostTensorDescriptor({row, col}, {stride, 1_uz});
            }
            else
            {
                return HostTensorDescriptor({row, col}, {1_uz, stride});
            }
        };

    Tensor<ADataType> a_m_k(f_host_tensor_descriptor(M, K, StrideA, ALayout{}));
    Tensor<BDataType> b_k_n(f_host_tensor_descriptor(K, N, StrideB, BLayout{}));

    switch(config.init_method)
    {
Adam Osewski's avatar
Adam Osewski committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    case 0:
        ck::utils::FillConstant<ADataType>{1.f}(a_m_k);
        ck::utils::FillConstant<BDataType>{0.f}(b_k_n);

        // for (ck::index_t m = 0; m < M; ++m)
        // {
        //     for (ck::index_t k = 0; k < K; ++k)
        //     {
        //         a_m_k(m, k) = (m * M + k) % 5;
        //     }
        // }

        for(ck::index_t n = 0; n < N; ++n)
        {
            for(ck::index_t k = 0; k < K; ++k)
            {
                if(n == k)
                    b_k_n(k, n) = n * 2;
            }
        }

        break;
55
    case 1:
Adam Osewski's avatar
Adam Osewski committed
56
57
        ck::utils::FillUniformDistributionIntegerValue<ADataType>{-1.f, 3.f}(a_m_k);
        ck::utils::FillUniformDistributionIntegerValue<BDataType>{-1.f, 3.f}(b_k_n);
58
59
        break;
    default:
60
61
        ck::utils::FillUniformDistribution<ADataType>{-1.f, 1.f}(a_m_k);
        ck::utils::FillUniformDistribution<BDataType>{-1.f, 1.f}(b_k_n);
62
63
64
    }

    Tensor<CDataType> c_m_n_host_result(f_host_tensor_descriptor(M, N, StrideC, CLayout{}));
65
    Tensor<CDataType> c_m_n_device_result(f_host_tensor_descriptor(M, N, StrideC, CLayout{}));
66
67
68
69
70
71

    std::cout << "a_m_k: " << a_m_k.mDesc << std::endl;
    std::cout << "b_k_n: " << b_k_n.mDesc << std::endl;
    std::cout << "c_m_n: " << c_m_n_host_result.mDesc << std::endl;

#ifdef BUILD_INT4_EXAMPLE
72
73
74
75
76
    DeviceMem a_m_k_device_buf(sizeof(KernelADataType) * a_m_k.mDesc.GetElementSpaceSize());
    DeviceMem b_k_n_device_buf(sizeof(KernelBDataType) * b_k_n.mDesc.GetElementSpaceSize());
    DeviceMem c_m_n_device_buf(sizeof(KernelCDataType) *
                               c_m_n_device_result.mDesc.GetElementSpaceSize());

77
78
79
80
81
82
    const Tensor<KernelADataType> a_m_k_converted(a_m_k);
    const Tensor<KernelBDataType> b_k_n_converted(b_k_n);

    a_m_k_device_buf.ToDevice(a_m_k_converted.mData.data());
    b_k_n_device_buf.ToDevice(b_k_n_converted.mData.data());
#else
83
84
85
86
    DeviceMem a_m_k_device_buf(sizeof(ADataType) * a_m_k.mDesc.GetElementSpaceSize());
    DeviceMem b_k_n_device_buf(sizeof(BDataType) * b_k_n.mDesc.GetElementSpaceSize());
    DeviceMem c_m_n_device_buf(sizeof(CDataType) * c_m_n_device_result.mDesc.GetElementSpaceSize());

87
88
    a_m_k_device_buf.ToDevice(a_m_k.mData.data());
    b_k_n_device_buf.ToDevice(b_k_n.mData.data());
Adam Osewski's avatar
Adam Osewski committed
89
    c_m_n_device_buf.SetZero();
90
91
92
93
94
95
96
97
98
99
100
#endif

    auto a_element_op = AElementOp{};
    auto b_element_op = BElementOp{};
    auto c_element_op = CElementOp{};

    // do GEMM
    auto gemm     = DeviceGemmInstance{};
    auto invoker  = gemm.MakeInvoker();
    auto argument = gemm.MakeArgument(
#ifdef BUILD_INT4_EXAMPLE
101
102
103
        static_cast<KernelADataType*>(a_m_k_device_buf.GetDeviceBuffer()),
        static_cast<KernelBDataType*>(b_k_n_device_buf.GetDeviceBuffer()),
        static_cast<KernelCDataType*>(c_m_n_device_buf.GetDeviceBuffer()),
104
#else
105
106
107
        static_cast<ADataType*>(a_m_k_device_buf.GetDeviceBuffer()),
        static_cast<BDataType*>(b_k_n_device_buf.GetDeviceBuffer()),
        static_cast<CDataType*>(c_m_n_device_buf.GetDeviceBuffer()),
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
#endif
        M,
        N,
        K,
        StrideA,
        StrideB,
        StrideC,
        a_element_op,
        b_element_op,
        c_element_op);

    if(!gemm.IsSupportedArgument(argument))
    {
        std::cerr << gemm.GetTypeString() << " does not support this problem" << std::endl;

        return true;
    }

    float ave_time = invoker.Run(argument, StreamConfig{nullptr, config.time_kernel});

    std::size_t flop = 2_uz * M * N * K;
    std::size_t num_btype =
        sizeof(ADataType) * M * K + sizeof(BDataType) * K * N + sizeof(CDataType) * M * N;

    float tflops = static_cast<float>(flop) / 1.E9 / ave_time;

    float gb_per_sec = num_btype / 1.E6 / ave_time;

    std::cout << "Perf: " << ave_time << " ms, " << tflops << " TFlops, " << gb_per_sec << " GB/s, "
              << gemm.GetTypeString() << std::endl;

Adam Osewski's avatar
Adam Osewski committed
139
    bool result = true;
140
141
142
143
144
145
146
147
148
149
150
    if(config.do_verification)
    {
        auto ref_gemm    = ReferenceGemmInstance{};
        auto ref_invoker = ref_gemm.MakeInvoker();

        auto ref_argument = ref_gemm.MakeArgument(
            a_m_k, b_k_n, c_m_n_host_result, a_element_op, b_element_op, c_element_op);

        ref_invoker.Run(ref_argument);

#ifdef BUILD_INT4_EXAMPLE
151
152
153
154
155
        Tensor<CDataType> c_m_n_device_result_converted(c_m_n_host_result.mDesc);

        c_m_n_device_buf.FromDevice(c_m_n_device_result_converted.mData.data());

        c_m_n_device_result = c_m_n_device_result_converted.CopyAsType<CDataType>();
156

Adam Osewski's avatar
Adam Osewski committed
157
        result = result && ck::utils::check_err(c_m_n_device_result_converted, c_m_n_host_result);
158
#else
159
160
        c_m_n_device_buf.FromDevice(c_m_n_device_result.mData.data());

Adam Osewski's avatar
Adam Osewski committed
161
        result = result && ck::utils::check_err(c_m_n_device_result, c_m_n_host_result);
162
163
164
#endif
    }

Adam Osewski's avatar
Adam Osewski committed
165
166
167
168
169
170
171
172
173
174
175
    if(config.do_log)
    {
        LogRangeAsType<float>(std::cout << "a:\n", a_m_k.mData, ",", 32) << std::endl;
        LogRangeAsType<float>(std::cout << "b:\n", b_k_n.mData, ",", 32) << std::endl;
        LogRangeAsType<float>(std::cout << "c_host:\n", c_m_n_host_result.mData, ",", 32)
            << std::endl;
        LogRangeAsType<float>(std::cout << "c_device:\n", c_m_n_device_result.mData, ",", 32)
            << std::endl;
    }

    return result;
176
177
178
179
180
181
182
183
184
}

bool run_gemm_example(int argc, char* argv[])
{
    ProblemSize problem_size;
    ExecutionConfig config;

    return !parse_cmd_args(argc, argv, problem_size, config) || run_gemm(problem_size, config);
}