Files
TheRock/rocm-libraries/shared/rocroller/lib/include/rocRoller/Serialization/llvm/YAML.hpp
T
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

434 lines
13 KiB
C++

// Copyright Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#pragma once
#ifdef ROCROLLER_USE_LLVM
#include <rocRoller/Serialization/Base.hpp>
#include <rocRoller/Serialization/HasTraits.hpp>
#include <rocRoller/Utilities/Concepts.hpp>
#include <rocRoller/Utilities/Error.hpp>
#include <llvm/ObjectYAML/YAML.h>
#include <cstddef>
namespace llvm
{
namespace yaml
{
/**
* Map the `rocRoller::Serialization` traits classes into `llvm::yaml` traits classes.
*/
namespace sn = rocRoller::Serialization;
/**
* The LLVM documentation tells you to put a member:
*
* static const bool flow = true;
*
* in order to designate a type to be serialized with the flow style (i.e. to use brackets instead of whitespace)
*
* What it doesn't clarify is that the value of the bool is not important, so:
*
* static const bool flow = false;
*
* will *also* mark a type as using the flow style. The only way to not use flow style is to not have a
* member named `flow`. This presents a challenge when trying to specify a traits class that may or may not
* use flow style based on a template parameter.
*
* In the rocRoller::Serialization traits classes, having a `flow` member with a value of `false` will work to
* specify the non-flow style.
*
* The following `FlowBase` can be used as a base class for `llvm::yaml` traits classes and contains a flow
* member only for types that evaluate to `true`. This uses a series of concepts declared in HasTraits.hpp
*/
template <typename T>
struct FlowBase
{
};
template <sn::CHasFlow T>
struct FlowBase<T>
{
static const bool flow = true;
};
template <typename T>
requires(sn::has_SequenceTraits<T, IO>::value) struct SequenceTraits<T>
: public FlowBase<sn::SequenceTraits<T, IO>>
{
static size_t size(IO& io, T& seq)
{
return sn::SequenceTraits<T, IO>::size(io, seq);
}
static auto& element(IO& io, T& seq, size_t index)
{
return sn::SequenceTraits<T, IO>::element(io, seq, index);
}
};
template <typename T>
requires(sn::has_EnumTraits<T, IO>::value) struct ScalarEnumerationTraits<T>
{
static void enumeration(IO& io, T& value)
{
sn::EnumTraits<T, IO>::enumeration(io, value);
}
};
template <typename T, typename Context>
requires(sn::has_MappingTraits<T, IO>::value) struct MappingContextTraits<T, Context>
{
static void mapping(IO& io, T& obj, Context& ctx)
{
sn::MappingTraits<T, IO, Context>::mapping(io, obj, ctx);
}
};
template <typename T, typename Context>
concept HasContextMappingTraits = requires(IO& io, T& obj, Context& ctx)
{
{MappingContextTraits<T, Context>::mapping(io, obj, ctx)};
};
template <typename T>
requires(sn::has_EmptyMappingTraits<T, IO>::value) struct MappingTraits<T>
: public FlowBase<sn::MappingTraits<T, IO, EmptyContext>>
{
static void mapping(IO& io, T& obj)
{
sn::MappingTraits<T, IO, EmptyContext>::mapping(io, obj);
}
};
template <typename T>
concept HasEmptyMappingTraits = requires(IO& io, T& obj)
{
{MappingTraits<T>::mapping(io, obj)};
};
template <typename T>
requires(sn::has_CustomMappingTraits<T, IO>::value) struct CustomMappingTraits<T>
{
using Impl = sn::CustomMappingTraits<T, IO>;
static void inputOne(IO& io, StringRef key, T& value)
{
Impl::inputOne(io, key.str(), value);
}
static void output(IO& io, T& value)
{
Impl::output(io, value);
}
};
template <typename T>
struct Hide
{
T& value;
Hide(T& value)
: value(value)
{
}
T& operator*()
{
return value;
}
};
} // namespace yaml
} // namespace llvm
namespace rocRoller
{
namespace Serialization
{
template <>
struct IOTraits<llvm::yaml::IO>
{
using IO = llvm::yaml::IO;
template <typename T>
static void mapRequired(IO& io, const char* key, T& obj)
{
io.mapRequired(key, obj);
}
template <typename T>
static void mapRequired(IO& io, const char* key, T const& obj)
{
AssertFatal(outputting(io));
T tmp = obj;
io.mapRequired(key, tmp);
}
template <typename T, typename Context>
static void mapRequired(IO& io, const char* key, T& obj, Context& ctx)
{
io.mapRequired(key, obj, ctx);
}
template <typename T>
static void mapOptional(IO& io, const char* key, T& obj)
{
io.mapOptional(key, obj);
}
template <typename T, typename Context>
static void mapOptional(IO& io, const char* key, T& obj, Context& ctx)
{
io.mapOptional(key, obj, ctx);
}
static bool outputting(IO& io)
{
return io.outputting();
}
static void setError(IO& io, std::string const& msg)
{
throw std::runtime_error(msg);
}
static void setContext(IO& io, void* ctx)
{
io.setContext(ctx);
}
static void* getContext(IO& io)
{
return io.getContext();
}
template <typename T>
static void enumCase(IO& io, T& member, const char* key, T value)
{
io.enumCase(member, key, value);
}
};
} // namespace Serialization
} // namespace rocRoller
namespace llvm
{
namespace yaml
{
LLVM_YAML_STRONG_TYPEDEF(size_t, FooType);
using mysize_t
= std::conditional<std::is_same<size_t, uint64_t>::value, FooType, size_t>::type;
template <>
struct ScalarTraits<mysize_t>
{
static void output(const mysize_t& value, void* ctx, raw_ostream& stream)
{
uint64_t tmp = value;
ScalarTraits<uint64_t>::output(tmp, ctx, stream);
}
static StringRef input(StringRef str, void* ctx, mysize_t& value)
{
uint64_t tmp;
auto rv = ScalarTraits<uint64_t>::input(str, ctx, tmp);
value = tmp;
return rv;
}
static bool mustQuote(StringRef)
{
return false;
}
};
template <typename T>
struct MappingTraits<Hide<T>>
{
static void mapping(IO& io, Hide<T>& value)
{
sn::MappingTraits<T, IO>::mapping(io, *value);
}
static const bool flow = sn::MappingTraits<T, IO>::flow;
};
template <typename T>
struct SequenceTraits<Hide<T>>
{
using Impl = sn::SequenceTraits<T, IO>;
using Value = typename Impl::Value;
static size_t size(IO& io, Hide<T>& t)
{
return Impl::size(io, *t);
}
static Value& element(IO& io, Hide<T>& t, size_t index)
{
return Impl::element(io, *t, index);
}
static const bool flow = Impl::flow;
};
template <typename T>
struct ScalarEnumerationTraits<Hide<T>>
{
static void enumeration(IO& io, Hide<T>& value)
{
sn::EnumTraits<T, IO>::enumeration(io, *value);
}
};
template <typename T>
struct CustomMappingTraits<Hide<T>>
{
using Impl = sn::CustomMappingTraits<T, IO>;
static void inputOne(IO& io, StringRef key, Hide<T>& value)
{
Impl::inputOne(io, key.str(), *value);
}
static void output(IO& io, Hide<T>& value)
{
Impl::output(io, *value);
}
};
/**
* Add serialization for small floating point types. Defer to built-in fp32 serialization with conversion.
*/
template <typename T>
requires(rocRoller::CIsAnyOf<T,
rocRoller::Half,
rocRoller::BFloat16,
rocRoller::FP8,
rocRoller::BF8,
rocRoller::FP6,
rocRoller::BF6,
rocRoller::FP4,
rocRoller::E8M0,
rocRoller::E5M3,
rocRoller::E4M3>) struct ScalarTraits<T>
{
static void output(const T& value, void* ctx, llvm::raw_ostream& out)
{
float floatVal = value;
ScalarTraits<float>::output(floatVal, ctx, out);
}
static StringRef input(StringRef scalar, void* ctx, T& value)
{
float floatVal = 0.0f;
auto rv = ScalarTraits<float>::input(scalar, ctx, floatVal);
value = T(floatVal);
return rv;
}
static QuotingType mustQuote(StringRef ref)
{
return ScalarTraits<float>::mustQuote(ref);
}
};
template <>
struct ScalarTraits<rocRoller::Raw32>
{
static void output(const rocRoller::Raw32& value, void* ctx, llvm::raw_ostream& out)
{
auto outputVal = static_cast<uint32_t>(value);
ScalarTraits<float>::output(outputVal, ctx, out);
}
static StringRef input(StringRef scalar, void* ctx, rocRoller::Raw32& value)
{
uint32_t inputVal = 0u;
auto rv = ScalarTraits<uint32_t>::input(scalar, ctx, inputVal);
value = rocRoller::Raw32(inputVal);
return rv;
}
static QuotingType mustQuote(StringRef ref)
{
return ScalarTraits<std::string>::mustQuote(ref);
}
};
template <rocRoller::Serialization::CHasScalarTraits Scalar>
struct ScalarTraits<Scalar>
{
using rrTraits = rocRoller::Serialization::ScalarTraits<Scalar>;
static void output(const Scalar& value, void* ctx, llvm::raw_ostream& out)
{
auto string = rrTraits::output(value);
ScalarTraits<std::string>::output(string, ctx, out);
}
static StringRef input(StringRef scalar, void* ctx, Scalar& value)
{
std::string string;
auto rv = ScalarTraits<std::string>::input(scalar, ctx, string);
rrTraits::input(string, value);
return rv;
}
static QuotingType mustQuote(StringRef ref)
{
return ScalarTraits<std::string>::mustQuote(ref);
}
};
// Explicit vector traits to ensure they're available for LLVM
template <>
struct SequenceTraits<std::vector<int>>
{
static size_t size(IO& io, std::vector<int>& seq)
{
return seq.size();
}
static int& element(IO& io, std::vector<int>& seq, size_t index)
{
if(index >= seq.size())
seq.resize(index + 1);
return seq[index];
}
static const bool flow = true;
};
template <>
struct SequenceTraits<std::vector<unsigned int>>
{
static size_t size(IO& io, std::vector<unsigned int>& seq)
{
return seq.size();
}
static unsigned int& element(IO& io, std::vector<unsigned int>& seq, size_t index)
{
if(index >= seq.size())
seq.resize(index + 1);
return seq[index];
}
static const bool flow = true;
};
} // namespace yaml
} // namespace llvm
#endif