mirror of
https://github.com/ROCm/composable_kernel.git
synced 2026-05-19 04:19:36 +00:00
* Initial adding of generic reduction
* Initial adding of generic reduction ...
* Updates to make compiling done
* clang-format all files
* clang-format some files again
* Renaming in profiler/include/profile_reduce.hpp
* Updates and make BlockWise cases passed
* Updates and make ThreadWise and MultiBlockTwoCall cases passed
* Remove the support for MUL and NORM1 reduceOp from the profiler and the device instances
* Change to replace the dim0_max_vector_size/dim1_max_vector_size template argument in the device reduce classes
* format
* adding pooling
* added max and average pooling
* comment out cout and kernel timing
* Tiny simplification in profiler/reduce_profiler.cpp
* Add example for reduce_blockwise
* Tiny updates
* Change to pass the ElementWiseOp from device layer to kernel
* Fix the vectorDim and vectorSize in Device layer
* Enable vector load on both dim0 and dim1 for Threadwise method
* Tiny updates
* Change to let the user to pass the preUnaryOp and posUnaryOp
* Make pooling example work
* split device_reduce_instance into two libraries
* Tiny update
* Replace nanPropaOpt enum by boolean propagate_nan
* Simplification in DeviceReduce layer codes
* update build
* Change to clarify the difference between ck::half_t and half_float::half
* Renaming in all the reduction codes
* Add VectorSize as template parameter for device layer
* Add BetaIsZero as kernel template and as AccDataType for alpha
* print
* Small updates for pooling
* Updates for host_generic_reduction for reference
* Update to make AVG pooling pass
* Update to make MAX pooling with indices output pass
* fix
* add OutDst vector store to threadwise reduction and pooling
* tweak
* turn off check_indices that caused build issue
* refactor pooling
* clean up
* turn off check_indices for building issue for php-compiler
* add more tile size for odd C
* tweak conv for odd C
* update script
* clean up elementwise op
* add hack in reduction_operator.hpp to avoid compile error. To fix it, need to use element_wise_op in reduction op
* Add OutVectorSize as device and kernel tunable, also update to Elementwise Operations
* Move reduce operator mapping to host layer file reduction_operator_mapping.hpp from reduction_operator.hpp
* Change to the unary operators
* Move the definitions of unary operations to element_wise_operation.hpp
* re-org files
* Refine in device interfaces and multiblock kernels
* Split the reduction configurations into instances for specific methods
* Update in getTypeString() of device pool2d
* Renaming in host and kernel
* Tiny update in profiler/src/profiler.cpp
* Uncomment in device_operation/CMakeLists.txt to enable the building of all operations
* Make check_indices a templated function to remove some linking issue
* Renaming in the profiler reduce module
* Add support for double Reduction (but disable MultiblockAtomicAdd for double)
* Tiny correction of literal string
* Rename DevicePoolFwd to DevicePool2dFwd
* Split device_reduce_instance_xxx.cpp files according to the data types to speed up compiling
* Add comments for lists of configurations, lists of instances and references of add_reduce_instances_xxx
* Remove un-used header file gridwise_generic_reduction_wrapper_common.hpp
* Renaming and refining in the Reduction codes
* Tiny change in the unary operators
* Renaming symbols and files
* Renaming symbols in the kernels
* Move kernel kernel_set_buffer_value to separate file
* Add IndexDataType template parameter for kernels and use int32_t as index data type in device layer
* Tiny update in the kernels
* Remove definition of sqrtf()/isnan()/abs() for half_t due to some ADL issue
* Simplify a helper function in device layer
* Tiny adjustment in testing data initialization
* Renaming in kernel/device/host
* Add two testing scripts for reduction
* Refine the Unary operators in element_wise_operation.hpp
* Update in the reduce profiler module
* Update to the reduction testing scripts
* reduce compile parallelism
* change CI docker to rocm5.0
* remove unused variables
* fix build
Co-authored-by: Chao Liu <chao.liu2@amd.com>
[ROCm/composable_kernel commit: e17c0d8008]
292 lines
8.0 KiB
C++
292 lines
8.0 KiB
C++
/*******************************************************************************
|
|
*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2020 Advanced Micro Devices, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
*******************************************************************************/
|
|
#ifndef GUARD_HOST_REDUCE_UTIL_HPP
|
|
#define GUARD_HOST_REDUCE_UTIL_HPP
|
|
|
|
#include <half.hpp>
|
|
#include <limits>
|
|
#include <cmath>
|
|
#include <cassert>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
#include "reduction_enums.hpp"
|
|
|
|
namespace ck {
|
|
|
|
namespace host_reduce {
|
|
|
|
using ck::NanPropagation_t;
|
|
using ck::ReduceTensorOp_t;
|
|
|
|
template <typename T>
|
|
static inline bool float_equal_one(T);
|
|
|
|
static inline bool float_equal_one(float x) { return x == 1.0f; };
|
|
|
|
static inline bool float_equal_one(double x) { return x == 1.0; };
|
|
|
|
static inline bool float_equal_one(half_float::half x)
|
|
{
|
|
return x == static_cast<half_float::half>(1.0f);
|
|
};
|
|
|
|
template <typename T>
|
|
static inline bool float_equal_zero(T x);
|
|
|
|
static inline bool float_equal_zero(float x) { return x == 0.0f; };
|
|
|
|
static inline bool float_equal_zero(double x) { return x == 0.0; };
|
|
|
|
static inline bool float_equal_zero(half_float::half x)
|
|
{
|
|
return x == static_cast<half_float::half>(0.0f);
|
|
};
|
|
|
|
template <typename compType, ReduceTensorOp_t ReduceOpId>
|
|
__host__ static inline std::function<void(compType&)> PreUnaryOpFn(int)
|
|
{
|
|
using std::abs;
|
|
|
|
if constexpr(ReduceOpId == ReduceTensorOp_t::NORM1)
|
|
{
|
|
return ([&](compType& a_) { a_ = abs(a_); });
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::NORM2)
|
|
{
|
|
return ([&](compType& a_) { a_ = a_ * a_; });
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::AMAX)
|
|
{
|
|
return ([&](compType& a_) { a_ = abs(a_); });
|
|
}
|
|
else
|
|
{
|
|
// ReduceTensorOp_t::AVG:
|
|
// ReduceTensorOp_t::ADD:
|
|
// ReduceTensorOp_t::MUL:
|
|
// ReduceTensorOp_t::MIN:
|
|
// ReduceTensorOp_t::MAX:
|
|
return ([&](compType&) {});
|
|
};
|
|
};
|
|
|
|
template <typename compType, ReduceTensorOp_t ReduceOpId>
|
|
__host__ static inline std::function<void(compType&)> PosUnaryOpFn(int divider)
|
|
{
|
|
using std::sqrt;
|
|
|
|
if constexpr(ReduceOpId == ReduceTensorOp_t::NORM2)
|
|
{
|
|
return ([&](compType& a_) { a_ = sqrt(a_); });
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::AVG)
|
|
{
|
|
return ([&, divider](compType& a_) {
|
|
a_ = a_ / static_cast<compType>(static_cast<float>(divider));
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// ReduceTensorOp_t::ADD:
|
|
// ReduceTensorOp_t::NORM1:
|
|
// ReduceTensorOp_t::MUL:
|
|
// ReduceTensorOp_t::MIN:
|
|
// ReduceTensorOp_t::MAX:
|
|
// ReduceTensorOp_t::AMAX:
|
|
return ([&](compType&) {});
|
|
}
|
|
};
|
|
|
|
template <typename compType, ReduceTensorOp_t ReduceOpId>
|
|
__host__ static inline std::function<void(compType&, compType)> ReduceOpFn()
|
|
{
|
|
if constexpr(ReduceOpId == ReduceTensorOp_t::ADD || ReduceOpId == ReduceTensorOp_t::AVG ||
|
|
ReduceOpId == ReduceTensorOp_t::NORM1 || ReduceOpId == ReduceTensorOp_t::NORM2)
|
|
{
|
|
return ([&](compType& a_, compType b_) { a_ = a_ + b_; });
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::MUL)
|
|
{
|
|
return ([&](compType& a_, compType b_) { a_ = a_ * b_; });
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::MIN)
|
|
{
|
|
return ([&](compType& a_, compType b_) {
|
|
if(a_ > b_)
|
|
a_ = b_;
|
|
});
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::MAX || ReduceOpId == ReduceTensorOp_t::AMAX)
|
|
{
|
|
return ([&](compType& a_, compType b_) {
|
|
if(a_ < b_)
|
|
a_ = b_;
|
|
});
|
|
}
|
|
};
|
|
|
|
template <typename compType, ReduceTensorOp_t ReduceOpId>
|
|
__host__ static inline std::function<void(compType&, compType, bool& changed)> ReduceOpFn2()
|
|
{
|
|
if constexpr(ReduceOpId == ReduceTensorOp_t::MIN)
|
|
{
|
|
return ([&](compType& a_, compType b_, bool& changed) {
|
|
if(a_ > b_)
|
|
{
|
|
a_ = b_;
|
|
changed = true;
|
|
}
|
|
else
|
|
changed = false;
|
|
});
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::MAX || ReduceOpId == ReduceTensorOp_t::AMAX)
|
|
{
|
|
return ([&](compType& a_, compType b_, bool& changed) {
|
|
if(a_ < b_)
|
|
{
|
|
a_ = b_;
|
|
changed = true;
|
|
}
|
|
else
|
|
changed = false;
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// ReduceTensorOp_t::ADD:
|
|
// ReduceTensorOp_t::MUL:
|
|
// ReduceTensorOp_t::AVG:
|
|
// ReduceTensorOp_t::NORM1:
|
|
// ReduceTensorOp_t::NORM2:
|
|
return (std::function<void(compType&, compType, bool&)>{});
|
|
};
|
|
};
|
|
|
|
template <typename compType, ReduceTensorOp_t ReduceOpId>
|
|
__host__ static inline compType ReduceOpZeroVal()
|
|
{
|
|
if constexpr(ReduceOpId == ReduceTensorOp_t::MUL)
|
|
{
|
|
return (static_cast<compType>(1.0f));
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::MIN)
|
|
{
|
|
return (std::numeric_limits<compType>::max());
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::MAX)
|
|
{
|
|
return (std::numeric_limits<compType>::lowest());
|
|
}
|
|
else if constexpr(ReduceOpId == ReduceTensorOp_t::AMAX)
|
|
{
|
|
return (static_cast<compType>(0.0f));
|
|
}
|
|
else
|
|
{
|
|
// ReduceTensorOp_t::ADD
|
|
// ReduceTensorOp_t::AVG
|
|
// ReduceTensorOp_t::NORM1
|
|
// ReduceTensorOp_t::NORM2
|
|
return (static_cast<compType>(0.0f));
|
|
};
|
|
};
|
|
|
|
template <typename compType, bool PropagateNan>
|
|
__host__ static inline void binop_with_nan_check(std::function<void(compType&, compType)> opReduce,
|
|
compType& accuVal,
|
|
compType currVal)
|
|
{
|
|
using std::isnan;
|
|
|
|
if constexpr(!PropagateNan)
|
|
{
|
|
opReduce(accuVal, currVal);
|
|
}
|
|
else
|
|
{
|
|
if(isnan(currVal))
|
|
accuVal = currVal;
|
|
else
|
|
opReduce(accuVal, currVal);
|
|
};
|
|
};
|
|
|
|
template <typename compType, bool PropagateNan>
|
|
__host__ static inline void
|
|
binop_with_nan_check2(std::function<void(compType&, compType, bool&)> opReduce,
|
|
compType& accuVal,
|
|
compType currVal,
|
|
int& accuIndex,
|
|
int currIndex)
|
|
{
|
|
using std::isnan;
|
|
|
|
if constexpr(!PropagateNan)
|
|
{
|
|
bool changed;
|
|
|
|
opReduce(accuVal, currVal, changed);
|
|
|
|
if(changed)
|
|
accuIndex = currIndex;
|
|
}
|
|
else
|
|
{
|
|
if(isnan(currVal))
|
|
{
|
|
accuVal = currVal;
|
|
accuIndex = currIndex;
|
|
}
|
|
else
|
|
{
|
|
bool changed;
|
|
|
|
opReduce(accuVal, currVal, changed);
|
|
|
|
if(changed)
|
|
accuIndex = currIndex;
|
|
};
|
|
};
|
|
};
|
|
|
|
}; // namespace host_reduce
|
|
|
|
static inline std::vector<int> to_int_vector(const std::vector<size_t>& inData)
|
|
{
|
|
std::vector<int> outData;
|
|
|
|
for(auto elem : inData)
|
|
outData.push_back(static_cast<int>(elem));
|
|
|
|
return (outData);
|
|
};
|
|
|
|
}; // namespace ck
|
|
|
|
#endif
|