[llvm] [SYCL][LLVM] Adding property set I/O library for SYCL (PR #110771)
Chris B via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 8 14:50:23 PST 2024
================
@@ -0,0 +1,309 @@
+// llvm/unittest/Support/SYCLPropertySetIOTest.cpp - SYCL Property set I/O tests
+// //
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/SYCLPropertySetIO.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::util;
+
+namespace {
+
+TEST(SYCLPropertySet, IncorrectValuesReadIO) {
+ auto Content = "Staff/Ages]\n";
+ auto MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ auto PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("property category missing")));
+
+ Content = "[Staff/Ages\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("invalid line")));
+
+ Content = "[Staff/Ages]\n"
+ "person1=\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("invalid property line")));
+
+ Content = "[Staff/Ages]\n"
+ "person1=|10\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("invalid property value")));
+
+ Content = "[Staff/Ages]\n"
+ "person1=abc|10\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("invalid property type")));
+
+ Content = "[Staff/Ages]\n"
+ "person1=1|IAQ\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("invalid property value")));
+
+ Content = "[Staff/Ages]\n"
+ "person1=2|IAQ\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr(
+ "Base64 encoded strings must be a multiple of 4 bytes in length")));
+
+ Content = "[Staff/Ages]\n"
+ "person1=100|10\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("bad property type")));
+
+ Content = "[Opt/Param]\n"
+ "kernel1=2|IAAAAAAAAAQA\tIAAAAAAAAAQ\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("Invalid Base64 character")));
+
+ Content = "[Opt/Param]\n"
+ "kernel1=2|IAAAAAAAAAQA\nIAAAAAAAAAQ\n";
+ MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+ EXPECT_THAT_ERROR(
+ std::move(PropSetsPtr.takeError()),
+ FailedWithMessage(testing::HasSubstr("invalid property line")));
+}
+
+TEST(SYCLPropertySet, DuplicateKeysRead) {
+ // '1' in '1|20' means 'integer property'
+ auto Content = "[Staff/Ages]\n"
+ "person1=1|20\n"
+ "person1=1|25\n";
+ // For duplicate keys, the latest key is selected
+ auto ExpectedContent = "[Staff/Ages]\n"
+ "person1=1|25\n";
+ auto MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ auto PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+
+ if (!PropSetsPtr)
+ FAIL() << "SYCLPropertySetRegistry::read failed\n";
+
+ std::string Serialized;
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSetsPtr->get()->write(OS);
+ }
+ // Check that the original and the serialized version are equal
+ EXPECT_EQ(Serialized, ExpectedContent);
+}
+
+// Test read-then-write of a list of integer values
+TEST(SYCLPropertySet, IntValuesIO) {
+ // '1' in '1|20' means 'integer property'
+ auto Content = "[Staff/Ages]\n"
+ "person1=1|20\n"
+ "person2=1|25\n"
+ "[Staff/Experience]\n"
+ "person1=1|1\n"
+ "person2=1|2\n"
+ "person3=1|12\n";
+ auto MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ auto PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+
+ if (!PropSetsPtr)
+ FAIL() << "SYCLPropertySetRegistry::read failed\n";
+
+ std::string Serialized;
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSetsPtr->get()->write(OS);
+ }
+ // Check that the original and the serialized version are equal
+ EXPECT_EQ(Serialized, Content);
+}
+
+// Test read-then-write of a list of byte arrays
+TEST(SYCLPropertySet, ByteArrayValuesIO) {
+ // '2' in '2|...' means 'byte array property', Base64-encoded
+ // encodes the following byte arrays:
+ // { 8, 0, 0, 0, 0, 0, 0, 0, 0x1 };
+ // { 40, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0x7F, 0xFF, 0x70 };
+ // first 8 bytes are the size in bits (40) of what follows (5 bytes).
+
+ auto Content = "[Opt/Param]\n"
+ "kernel1=2|IAAAAAAAAAQA\n"
+ "kernel2=2|oAAAAAAAAAAAw///3/wB\n";
+ auto MemBuf = MemoryBuffer::getMemBuffer(Content);
+ // Parse a property set registry
+ auto PropSetsPtr = SYCLPropertySetRegistry::read(MemBuf.get());
+
+ if (!PropSetsPtr)
+ FAIL() << "SYCLPropertySetRegistry::read failed\n";
+
+ std::string Serialized;
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSetsPtr->get()->write(OS);
+ }
+ // Check that the original and the serialized version are equal
+ EXPECT_EQ(Serialized, Content);
+}
+
+// Test write-then-read of boolean values
+TEST(SYCLPropertySet, Mask) {
+ SYCLPropertySetRegistry PropSet;
+ uint32_t Mask = 0;
+ std::map<StringRef, uint32_t> DevMask = {{"Mask", Mask}};
+ PropSet.add("MaskCategory", DevMask);
+ std::string Serialized;
+ std::string Expected("[MaskCategory]\nMask=1|0\n");
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSet.write(OS);
+ }
+ EXPECT_EQ(Serialized, Expected);
+}
+
+// Test write-then-read of std::map<StringRef, SYCLPropertyValue>
+// SYClPropertyValue is a class which contains one member, which is
+// std::variant<uint32_t, std::unique_ptr<std::byte, Deleter>> Val;
+TEST(SYCLPropertySet, SYCLPropertyValues) {
+ std::map<StringRef, SYCLPropertyValue> PropValues;
+ std::vector<uint32_t> Values = {1, 2, 3, 4};
+ uint32_t Size = 4;
+ PropValues["Values"] = std::move(Values);
+ PropValues["Size"] = Size;
+ SYCLPropertySetRegistry PropSet;
+ PropSet.add("Property Values", PropValues);
+ std::string Serialized;
+ std::string Expected(
+ "[Property Values]\nSize=1|4\nValues=2|AQAAAAIAAAADAAAABAAAAA==\n");
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSet.write(OS);
+ }
+ EXPECT_EQ(Serialized, Expected);
+}
+
+// Test write-then-read of MapVector of StringRef to a simple struct datatype.
+// Example of simple data structure:
+// struct SimpleDS {
+// unsigned ID;
+// unsigned Offset;
+// unsigned Size;
+// };
+struct SimpleDS {
+ unsigned ID;
+ unsigned Offset;
+ unsigned Size;
+};
+using MapTy = MapVector<StringRef, std::vector<SimpleDS>>;
+TEST(SYCLPropertySet, MapToStruct) {
+ MapTy Values;
+ std::vector<SimpleDS> SimpleDSVal(2);
+ unsigned Start = 0;
+ for (unsigned I = Start; I < Start + 2; ++I) {
+ SimpleDSVal[I - Start].ID = I;
+ SimpleDSVal[I - Start].Offset = I * 4;
+ SimpleDSVal[I - Start].Size = 4;
+ }
+ Values["Value0"] = SimpleDSVal;
+ Start += 8;
+ for (unsigned I = Start; I < Start + 2; ++I) {
+ SimpleDSVal[I - Start].ID = I;
+ SimpleDSVal[I - Start].Offset = I * 4;
+ SimpleDSVal[I - Start].Size = 4;
+ }
+ Values["Value1"] = SimpleDSVal;
+ SYCLPropertySetRegistry PropSet;
+ PropSet.add("Values", Values);
+ std::string Serialized;
+ std::string Expected(
+ "[Values]\nValue0=2|AAAAAAAAAAAEAAAAAQAAAAQAAAAEAAAA\nValue1=2|"
+ "CAAAACAAAAAEAAAACQAAACQAAAAEAAAA\n");
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSet.write(OS);
+ }
+ EXPECT_EQ(Serialized, Expected);
+}
+
+// Test write-then-read of vector of chars
+TEST(SYCLPropertySet, VectorOfChars) {
+ std::vector<char> Values;
+ for (unsigned I = 0; I < 8; ++I)
+ Values.push_back((char)(I + '0'));
+ SYCLPropertySetRegistry PropSet;
+ PropSet.add("Values", "all", Values);
+ std::string Serialized;
+ std::string Expected("[Values]\nall=2|MDEyMzQ1Njc=\n");
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSet.write(OS);
+ }
+ EXPECT_EQ(Serialized, Expected);
+}
+
+// Test write-then-read of a list of Name-Value pairs
+TEST(SYCLPropertySet, ListOfNameValuePairs) {
+ SYCLPropertySetRegistry PropSet;
+ std::vector<std::string> Names = {"Name0", "Name1", "Name2", "Name3"};
+ for (unsigned I = 0; I < 4; ++I) {
+ auto Value = I * 8;
+ PropSet.add("Values", Names[I], Value);
+ }
+ std::string Serialized;
+ std::string Expected(
+ "[Values]\nName0=1|0\nName1=1|8\nName2=1|16\nName3=1|24\n");
+ {
+ llvm::raw_string_ostream OS(Serialized);
+ // Serialize
+ PropSet.write(OS);
+ }
+ EXPECT_EQ(Serialized, Expected);
+}
+} // namespace
----------------
llvm-beanz wrote:
What about something like this?
`[SomeValue][OhNoAnotherValue]\nbleh=oops`
https://github.com/llvm/llvm-project/pull/110771
More information about the llvm-commits
mailing list