CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
234 lines
6.3 KiB
C++
234 lines
6.3 KiB
C++
// Copyright Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <rocRoller/KernelArguments.hpp>
|
|
|
|
#include <rocRoller/DataTypes/DataTypes_Utils.hpp>
|
|
#include <rocRoller/Operations/CommandArgument_fwd.hpp>
|
|
|
|
#include <concepts>
|
|
#include <cstring>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <rocRoller/Utilities/Logging.hpp>
|
|
|
|
namespace rocRoller
|
|
{
|
|
|
|
struct AppendKernelArgumentsVisitor
|
|
{
|
|
KernelArguments* args;
|
|
std::string const& argName;
|
|
|
|
template <CCommandArgumentValue T>
|
|
void operator()(T const& value)
|
|
{
|
|
args->append(argName, value);
|
|
}
|
|
|
|
void call(CommandArgumentValue const& value)
|
|
{
|
|
std::visit(*this, value);
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
inline void KernelArguments::append(std::string const& argName, T value)
|
|
{
|
|
if constexpr(std::is_same_v<T, CommandArgumentValue>)
|
|
{
|
|
AppendKernelArgumentsVisitor visitor{this, argName};
|
|
visitor.call(value);
|
|
}
|
|
else
|
|
{
|
|
append(argName, value, true);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
inline void KernelArguments::appendUnbound(std::string const& argName)
|
|
{
|
|
append(argName, static_cast<T>(0), false);
|
|
}
|
|
|
|
template <typename T>
|
|
inline void KernelArguments::bind(std::string const& argName, T value)
|
|
{
|
|
if(!m_log)
|
|
{
|
|
throw std::runtime_error("Binding is not supported without logging.");
|
|
}
|
|
|
|
auto it = m_argRecords.find(argName);
|
|
if(it == m_argRecords.end())
|
|
{
|
|
throw std::runtime_error("Attempt to bind unknown argument " + argName);
|
|
}
|
|
|
|
auto& record = it->second;
|
|
|
|
if(std::get<ArgBound>(record))
|
|
{
|
|
throw std::runtime_error("Attempt to bind already bound argument " + argName);
|
|
}
|
|
|
|
if(sizeof(T) != std::get<ArgSize>(record))
|
|
{
|
|
throw std::runtime_error("Size mismatch in binding argument " + argName);
|
|
}
|
|
|
|
size_t offset = std::get<ArgOffset>(record);
|
|
|
|
if(offset % alignof(T) != 0)
|
|
{
|
|
throw std::runtime_error("Alignment error in argument " + argName + ": type mismatch?");
|
|
}
|
|
|
|
writeValue(offset, value);
|
|
|
|
std::get<ArgString>(record) = stringForValue(value, true);
|
|
std::get<ArgBound>(record) = true;
|
|
}
|
|
|
|
template <typename T>
|
|
inline std::string KernelArguments::stringForValue(T value, bool bound) const
|
|
{
|
|
if(!m_log)
|
|
return "";
|
|
|
|
if(!bound)
|
|
return "<unbound>";
|
|
|
|
std::ostringstream msg;
|
|
|
|
// Some pointer types (char, int8_t, uint8_t, etc) are interpreted
|
|
// as a string, we just want the pointer value.
|
|
if constexpr(std::is_pointer_v<T>)
|
|
{
|
|
msg << static_cast<void const*>(value);
|
|
}
|
|
else
|
|
{
|
|
msg << value;
|
|
}
|
|
return msg.str();
|
|
}
|
|
|
|
template <CScaleType T>
|
|
inline void KernelArguments::append(std::string const& argName, T value, bool bound)
|
|
{
|
|
auto constexpr PACKED_SCALE_ALIGN = alignof(typename PackedTypeOf<T>::type);
|
|
auto constexpr PACKED_SCALE_SIZE = sizeof(typename PackedTypeOf<T>::type);
|
|
|
|
alignTo(PACKED_SCALE_ALIGN);
|
|
size_t offset = m_data.size();
|
|
size_t argSize = PACKED_SCALE_SIZE;
|
|
|
|
if(m_log)
|
|
{
|
|
std::string valueString = stringForValue(value, bound);
|
|
appendRecord(argName, Arg(offset, argSize, bound, valueString));
|
|
}
|
|
|
|
m_data.insert(m_data.end(), argSize, 0);
|
|
writeValue(offset, value);
|
|
}
|
|
|
|
template <CScaleType T>
|
|
inline void KernelArguments::writeValue(size_t offset, T value)
|
|
{
|
|
auto constexpr PACKED_SCALE_SIZE = sizeof(typename PackedTypeOf<T>::type);
|
|
|
|
size_t argSize = PACKED_SCALE_SIZE;
|
|
AssertFatal(offset + argSize <= m_data.size(),
|
|
"Value exceeds allocated bounds.",
|
|
ShowValue(offset),
|
|
ShowValue(argSize),
|
|
ShowValue(m_data.size()));
|
|
|
|
std::memset(&m_data[offset], value.scale, argSize);
|
|
}
|
|
|
|
template <typename T>
|
|
inline void KernelArguments::append(std::string const& argName, T value, bool bound)
|
|
{
|
|
alignTo(alignof(T));
|
|
|
|
size_t offset = m_data.size();
|
|
size_t argSize = sizeof(T);
|
|
|
|
if(m_log)
|
|
{
|
|
std::string valueString = stringForValue(value, bound);
|
|
appendRecord(argName, Arg(offset, argSize, bound, valueString));
|
|
}
|
|
|
|
m_data.insert(m_data.end(), argSize, 0);
|
|
writeValue(offset, value);
|
|
}
|
|
|
|
template <typename T>
|
|
inline void KernelArguments::writeValue(size_t offset, T value)
|
|
{
|
|
AssertFatal(offset + sizeof(T) <= m_data.size(),
|
|
"Value exceeds allocated bounds.",
|
|
ShowValue(offset),
|
|
ShowValue(sizeof(T)),
|
|
ShowValue(m_data.size()));
|
|
|
|
std::memcpy(&m_data[offset], &value, sizeof(T));
|
|
}
|
|
|
|
inline void KernelArguments::alignTo(size_t alignment)
|
|
{
|
|
size_t extraElements = m_data.size() % alignment;
|
|
size_t padding = (alignment - extraElements) % alignment;
|
|
|
|
m_data.insert(m_data.end(), padding, 0);
|
|
}
|
|
|
|
inline void KernelArguments::appendRecord(std::string const& argName,
|
|
KernelArguments::Arg record)
|
|
{
|
|
auto it = m_argRecords.find(argName);
|
|
if(it != m_argRecords.end())
|
|
{
|
|
throw std::runtime_error("Duplicate argument name: " + argName);
|
|
}
|
|
|
|
m_argRecords[argName] = record;
|
|
m_names.push_back(argName);
|
|
}
|
|
|
|
template <typename T>
|
|
KernelArguments::const_iterator::operator T() const
|
|
{
|
|
if(sizeof(T) != m_value.second)
|
|
{
|
|
throw std::bad_cast();
|
|
}
|
|
return *reinterpret_cast<T*>(const_cast<void*>(m_value.first));
|
|
}
|
|
|
|
inline bool KernelArguments::log() const
|
|
{
|
|
return m_log;
|
|
}
|
|
|
|
inline std::vector<uint8_t> const& KernelArguments::dataVector() const
|
|
{
|
|
return m_data;
|
|
}
|
|
|
|
inline RuntimeArguments KernelArguments::runtimeArguments() const
|
|
{
|
|
return RuntimeArguments(m_data.data(), m_data.size());
|
|
}
|
|
}
|