Files
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

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());
}
}