[llvm] [SYCL][LLVM] Adding property set I/O library for SYCL (PR #110771)
Chris B via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 10 14:12:44 PDT 2024
================
@@ -0,0 +1,268 @@
+//=- SYCLPropertySetIO.h -- models a sequence of property sets and their I/O =//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Models a sequence of property sets and their input and output operations.
+// SYCLPropertyValue set format:
+// '['<SYCLPropertyValue set name>']'
+// <property name>=<property type>'|'<property value>
+// <property name>=<property type>'|'<property value>
+// ...
+// '['<SYCLPropertyValue set name>']'
+// <property name>=<property type>'|'<property value>
+// where
+// <SYCLPropertyValue set name>, <property name> are strings
+// <property type> - string representation of the property type
+// <property value> - string representation of the property value.
+//
+// For example:
+// [Staff/Ages]
+// person1=1|20
+// person2=1|25
+// [Staff/Experience]
+// person1=1|1
+// person2=1|2
+// person3=1|12
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SYCLPROPERTYSETIO_H
+#define LLVM_SUPPORT_SYCLPROPERTYSETIO_H
+
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/xxhash.h"
+#include <variant>
+
+namespace llvm {
+namespace util {
+
+// Represents a SYCL property value. SYCLPropertyValue name is stored in the
+// encompassing container.
+class SYCLPropertyValue {
+public:
+ // Type of the size of the value. Value size gets serialized along with the
+ // value data in some cases for later reading at runtime, so size_t is not
+ // suitable as its size varies.
+ using SizeTy = uint64_t;
+
+ // Defines supported property types
+ enum Type { first = 0, NONE = first, UINT32, BYTE_ARRAY, last = BYTE_ARRAY };
+
+ // Translates C++ type to the corresponding type tag.
+ template <typename T> static Type getTypeTag();
+
+ // Casts from int value to a type tag.
+ static Expected<Type> getTypeTag(int T) {
+ if (T < first || T > last)
+ return createStringError(std::error_code(), "bad property type ", T);
+ return static_cast<Type>(T);
+ }
+
+ ~SYCLPropertyValue() {}
+
+ SYCLPropertyValue() = default;
+ SYCLPropertyValue(Type T) : Ty(T) {}
+
+ SYCLPropertyValue(uint32_t Val) : Ty(UINT32), Val({Val}) {}
+ SYCLPropertyValue(const std::byte *Data, SizeTy DataBitSize);
+ template <typename C, typename T = typename C::value_type>
+ SYCLPropertyValue(const C &Data)
+ : SYCLPropertyValue(reinterpret_cast<const std::byte *>(Data.data()),
+ Data.size() * sizeof(T) * CHAR_BIT) {}
+ SYCLPropertyValue(const llvm::StringRef &Str)
+ : SYCLPropertyValue(reinterpret_cast<const std::byte *>(Str.data()),
+ Str.size() * sizeof(char) *
+ /* bits in one byte */ 8) {}
+ SYCLPropertyValue(const SYCLPropertyValue &P);
+ SYCLPropertyValue(SYCLPropertyValue &&P);
+
+ SYCLPropertyValue &operator=(SYCLPropertyValue &&P);
+
+ SYCLPropertyValue &operator=(const SYCLPropertyValue &P);
+
+ // Get property value as unsigned 32-bit integer
+ uint32_t asUint32() const {
+ assert((Ty == UINT32) && "must be UINT32 value");
+ return std::get<uint32_t>(Val);
+ }
+
+ // Get raw data size in bits.
+ SizeTy getByteArraySizeInBits() const {
+ assert((Ty == BYTE_ARRAY) && "must be BYTE_ARRAY value");
+ SizeTy Res = 0;
+
+ for (size_t I = 0; I < sizeof(SizeTy); ++I) {
+ auto ByteArrayVal = std::get<std::byte *>(Val);
+ Res |= (SizeTy)ByteArrayVal[I] << (8 * I);
+ }
+ return Res;
+ }
+
+ // Get byte array data size in bytes.
+ SizeTy getByteArraySize() const {
+ SizeTy SizeInBits = getByteArraySizeInBits();
+ constexpr unsigned int MASK = 0x7;
+ return ((SizeInBits + MASK) & ~MASK) / 8;
+ }
+
+ // Get byte array data size in bytes, including the leading bytes encoding the
+ // size.
+ SizeTy getRawByteArraySize() const {
+ return getByteArraySize() + sizeof(SizeTy);
+ }
+
+ // Get byte array data including the leading bytes encoding the size.
+ const std::byte *asRawByteArray() const {
+ assert((Ty == BYTE_ARRAY) && "must be BYTE_ARRAY value");
+ auto *ByteArrayVal = std::get<std::byte *>(Val);
+ return ByteArrayVal;
+ }
+
+ // Get byte array data excluding the leading bytes encoding the size.
+ const std::byte *asByteArray() const {
+ assert((Ty == BYTE_ARRAY) && "must be BYTE_ARRAY value");
+
+ auto ByteArrayVal = std::get<std::byte *>(Val);
+ return ByteArrayVal + sizeof(SizeTy);
+ }
+
+ bool isValid() const { return getType() != NONE; }
+
+ // Set property value when data type is UINT32_T
+ void set(uint32_t V) {
+ assert((Ty == UINT32) && "must be UINT32 value");
+ Val = V;
+ }
+
+ // Set property value when data type is BYTE_ARRAY
+ void set(std::byte *V, int DataSize) {
+ assert((Ty == BYTE_ARRAY) && "must be BYTE_ARRAY value");
+ size_t DataBitSize = DataSize * CHAR_BIT;
+ constexpr size_t SizeFieldSize = sizeof(SizeTy);
+ // Allocate space for size and data.
+ Val = new std::byte[SizeFieldSize + DataSize];
+
+ // Write the size into first bytes.
+ for (size_t I = 0; I < SizeFieldSize; ++I) {
+ auto ByteArrayVal = std::get<std::byte *>(Val);
+ ByteArrayVal[I] = (std::byte)DataBitSize;
+ DataBitSize >>= CHAR_BIT;
+ }
+ // Append data.
+ auto ByteArrayVal = std::get<std::byte *>(Val);
+ std::memcpy(ByteArrayVal + SizeFieldSize, V, DataSize);
+ }
+
+ Type getType() const { return Ty; }
+
+ SizeTy size() const {
+ switch (Ty) {
+ case UINT32:
+ return sizeof(uint32_t);
+ case BYTE_ARRAY:
+ return getRawByteArraySize();
+ default:
+ llvm_unreachable_internal("unsupported SYCL property type");
+ }
+ }
+
+private:
+ void copy(const SYCLPropertyValue &P);
+
+ Type Ty = NONE;
+ std::variant<uint32_t, std::byte *> Val;
----------------
llvm-beanz wrote:
It's a little redundant to store the type and a variant (which itself stores the type). Should this just be a union?
https://github.com/llvm/llvm-project/pull/110771
More information about the llvm-commits
mailing list