// SPDX-License-Identifier: MIT // Copyright (c) 2018-2022, Advanced Micro Devices, Inc. All rights reserved. #pragma once #include #include #include #include #include #include "ck/ck.hpp" #include "ck/tensor_operation/gpu/device/impl/device_softmax_impl.hpp" #include "ck/tensor_operation/gpu/element/element_wise_operation.hpp" #include "include/ck/utility/data_type.hpp" #include "profiler/include/profile_softmax_impl.hpp" namespace ck { template std::string serialize_range(const Range& range) { std::stringstream ss; for(auto& r : range) { ss << r << ", "; } std::string str = ss.str(); return std::string(str.begin(), str.end() - 2); } template class TestSoftmax : public ::testing::Test { protected: using InDataType = std::tuple_element_t<0, Tuple>; using AccDataType = std::tuple_element_t<1, Tuple>; using OutDataType = std::tuple_element_t<2, Tuple>; static constexpr index_t Rank = std::tuple_element_t<3, Tuple>{}.value; public: std::vector> in_lengths_ = {{2, 128, 1024}, {4, 16, 8448}, {128, 128, 64}}; std::vector> scales_ = {{2, 0}, {0, 2}, {2, 2}}; bool bench_ = false; // measure kernel performance bool verify_ = true; void SetUp() override { if constexpr(Rank == 4) { in_lengths_ = std::vector>{ {1, 2, 128, 1024}, {2, 4, 16, 8448}, {1, 128, 128, 64}}; } } void RunSingle(std::vector in_length, std::vector reduce_dims, AccDataType alpha, AccDataType beta) { int init_method = 1; // integer value initialization bool log = false; std::vector strides; // intenionally empty, to get packed layout. bool pass = ck::profiler::profile_softmax_impl( verify_, init_method, log, bench_, in_length, strides, reduce_dims, alpha, beta); EXPECT_TRUE(pass); } void Run(std::vector reduce_dims = {}) { if(reduce_dims.empty()) { reduce_dims.push_back(Rank - 1); } for(auto in_length : this->in_lengths_) { for(auto scale : this->scales_) { this->RunSingle(in_length, reduce_dims, scale[0], scale[1]); } } } }; template struct DeviceSoftmaxInstanceWrapper { using F16 = half_t; using F32 = float; using Pass = tensor_operation::element_wise::PassThrough; using InDataType = F16; using AccDataType = F32; using OutDataType = F16; using InElementOp = Pass; using AccElementOp = Pass; using DeviceSoftmaxInstance = tensor_operation::device::DeviceSoftmaxImpl; bool IsSupported(const std::vector in_lengths, const std::vector in_strides, const std::vector reduce_dims) const { auto softmax = DeviceSoftmaxInstance{}; auto argument = softmax.MakeArgument(in_lengths, in_strides, reduce_dims, 1, // alpha 1, // beta nullptr, // in_dev nullptr, // in_out Pass{}, // in elementwise op Pass{}); // acc elementwise op return softmax.IsSupportedArgument(argument); } }; } // namespace ck