@@ -56,20 +56,39 @@ class ManagedBinaryFile {
56
56
};
57
57
58
58
std::vector<uint8_t > generateRandomImage () {
59
- std::mt19937 Rng (42 );
60
- std::uniform_int_distribution<uint64_t > SizeDist (0 , 256 );
61
- std::uniform_int_distribution<uint16_t > KindDist (0 );
62
- std::uniform_int_distribution<uint16_t > BinaryDist (
59
+ static std::mt19937 Rng (42 );
60
+ static std::uniform_int_distribution<uint64_t > SizeDist (0 , 256 );
61
+ static std::uniform_int_distribution<uint16_t > BinaryDist (
63
62
std::numeric_limits<uint8_t >::min (), std::numeric_limits<uint8_t >::max ());
64
63
std::vector<uint8_t > Image (SizeDist (Rng));
65
64
std::generate (Image.begin (), Image.end (), [&]() { return BinaryDist (Rng); });
66
65
return Image;
67
66
}
68
67
69
- } // namespace
68
+ std::vector<std::vector<uint8_t >> generateUniqueRandomImages (size_t NumImages) {
69
+ std::vector<std::vector<uint8_t >> Images;
70
+ Images.reserve (NumImages);
71
+ Images.emplace_back (generateRandomImage ());
72
+ for (size_t I = 1 ; I < NumImages; ++I) {
73
+ std::vector<uint8_t > GenImage;
74
+ auto CheckImageExist = [&](const std::vector<uint8_t > &Image) {
75
+ return GenImage.size () == Image.size () &&
76
+ std::memcmp (GenImage.data (), Image.data (), GenImage.size ()) == 0 ;
77
+ };
78
+ // Generate images until we get a unique one.
79
+ do {
80
+ GenImage = generateRandomImage ();
81
+ } while (std::any_of (Images.begin (), Images.end (), CheckImageExist));
82
+ Images.emplace_back (std::move (GenImage));
83
+ }
84
+ return Images;
85
+ }
70
86
71
- TEST (SYCLBINTest, checkSYCLBINBinaryBasicIRModule) {
87
+ template <size_t NumIRModules, size_t NumNativeDeviceCodeImages>
88
+ void CommonCheck () {
89
+ constexpr size_t NumImages = NumIRModules + NumNativeDeviceCodeImages;
72
90
constexpr SYCLBIN::BundleState State = SYCLBIN::BundleState::Input;
91
+ static constexpr char Arch[] = " some-arch" ;
73
92
74
93
// Create unique temporary directory for these tests
75
94
SmallString<128 > TestDirectory;
@@ -78,21 +97,32 @@ TEST(SYCLBINTest, checkSYCLBINBinaryBasicIRModule) {
78
97
fs::createUniqueDirectory (" SYCLBINTest-test" , TestDirectory));
79
98
}
80
99
81
- // Create a random file to be used in the SYCLBIN.
82
- SmallString<128 > File1 (TestDirectory);
83
- File1.append (" /image_file1" );
84
- std::vector<uint8_t > Image = generateRandomImage ();
85
- Expected<ManagedBinaryFile> ManagedModuleFileOrError =
86
- ManagedBinaryFile::create (File1, Image);
87
- ASSERT_THAT_EXPECTED (ManagedModuleFileOrError, Succeeded ());
88
- ManagedBinaryFile ManagedModuleFile = std::move (*ManagedModuleFileOrError);
89
-
90
- // Create IR module.
91
- std::vector<module_split::SplitModule> SplitModules{module_split::SplitModule{
92
- File1.c_str (), util::PropertySetRegistry{}, " " }};
93
- SmallVector<SYCLBIN::SYCLBINModuleDesc> MDs{
94
- SYCLBIN::SYCLBINModuleDesc{" " , std::move (SplitModules)}};
95
- SYCLBIN::SYCLBINDesc Desc{SYCLBIN::BundleState::Input, MDs};
100
+ // Create random files to be used in the SYCLBIN. If the same image is
101
+ // generated, retry until they are unique.
102
+ std::vector<std::vector<uint8_t >> Images =
103
+ generateUniqueRandomImages (NumImages);
104
+
105
+ std::vector<ManagedBinaryFile> ManagedModuleFiles;
106
+ SmallVector<SYCLBIN::SYCLBINModuleDesc> MDs;
107
+ ManagedModuleFiles.reserve (NumImages);
108
+ MDs.reserve (NumImages);
109
+ for (size_t I = 0 ; I < NumImages; ++I) {
110
+ SmallString<128 > File (TestDirectory);
111
+ llvm::sys::path::append (File, " image_file" + std::to_string (I));
112
+ Expected<ManagedBinaryFile> ManagedModuleFileOrError =
113
+ ManagedBinaryFile::create (File, Images[I]);
114
+ ASSERT_THAT_EXPECTED (ManagedModuleFileOrError, Succeeded ());
115
+ ManagedModuleFiles.emplace_back (std::move (*ManagedModuleFileOrError));
116
+ std::vector<module_split::SplitModule> SplitModules{
117
+ module_split::SplitModule{File.c_str (), util::PropertySetRegistry{},
118
+ " " }};
119
+ const char *ArchStr = I < NumIRModules ? " " : Arch;
120
+ MDs.emplace_back (
121
+ SYCLBIN::SYCLBINModuleDesc{ArchStr, std::move (SplitModules)});
122
+ }
123
+
124
+ // Create IR modules.
125
+ SYCLBIN::SYCLBINDesc Desc{State, MDs};
96
126
size_t SYCLBINByteSize = 0 ;
97
127
if (Error E = Desc.getSYCLBINByteSite ().moveInto (SYCLBINByteSize))
98
128
FAIL () << " Failed to get SYCLBIN byte size." ;
@@ -133,146 +163,106 @@ TEST(SYCLBINTest, checkSYCLBINBinaryBasicIRModule) {
133
163
ASSERT_EQ (GlobalMetadataState.getType (), PropertyValue::Type::UINT32);
134
164
EXPECT_EQ (GlobalMetadataState.asUint32 (), static_cast <uint32_t >(State));
135
165
136
- ASSERT_EQ (SYCLBINObj->AbstractModules .size (), size_t {1 });
137
- const SYCLBIN::AbstractModule &AM = SYCLBINObj->AbstractModules [0 ];
138
-
139
- // This metadata should be the same as in the corresponding split module, so
140
- // testing should be expanded to ensure preservation.
141
- ASSERT_NE (AM.Metadata .get (), nullptr );
142
- EXPECT_TRUE (AM.Metadata ->getPropSets ().empty ());
143
-
144
- // There was no arch string, so there should be no native device code images.
145
- EXPECT_TRUE (AM.NativeDeviceCodeImages .empty ());
146
-
147
- // There was a single module with no arch string, so we should have an IR
148
- // module.
149
- ASSERT_EQ (AM.IRModules .size (), size_t {1 });
150
- const SYCLBIN::IRModule &IRM = AM.IRModules [0 ];
151
-
152
- ASSERT_NE (IRM.Metadata .get (), nullptr );
153
- SmallString<16 > IRMMetadataKey{
154
- PropertySetRegistry::SYCLBIN_IR_MODULE_METADATA};
155
- const auto &IRMMetadataIt = IRM.Metadata ->getPropSets ().find (IRMMetadataKey);
156
- ASSERT_NE (IRMMetadataIt, IRM.Metadata ->end ());
157
- const PropertySet &IRMMetadata = IRMMetadataIt->second ;
158
- EXPECT_EQ (IRMMetadata.size (), size_t {1 });
159
-
160
- // The type is currently locked to SPIR-V. This will change in the future.
161
- SmallString<16 > IRMMetadataTypeKey{" type" };
162
- const auto &IRMMetadataTypeIt = IRMMetadata.find (IRMMetadataTypeKey);
163
- ASSERT_NE (IRMMetadataTypeIt, IRMMetadata.end ());
164
- const PropertyValue &IRMMetadataType = IRMMetadataTypeIt->second ;
165
- ASSERT_EQ (IRMMetadataType.getType (), PropertyValue::Type::UINT32);
166
- EXPECT_EQ (IRMMetadataType.asUint32 (), uint32_t {0 });
167
-
168
- // Check that the image is the same.
169
- ASSERT_EQ (Image.size (), IRM.RawIRBytes .size ());
170
- EXPECT_EQ (std::memcmp (Image.data (), IRM.RawIRBytes .data (), Image.size ()), 0 );
171
- }
172
-
173
- TEST (SYCLBINTest, checkSYCLBINBinaryBasicNativeDeviceCodeImage) {
174
- constexpr SYCLBIN::BundleState State = SYCLBIN::BundleState::Input;
175
- static constexpr char Arch[] = " some-arch" ;
176
-
177
- // Create unique temporary directory for these tests
178
- SmallString<128 > TestDirectory;
179
- {
180
- ASSERT_NO_ERROR (
181
- fs::createUniqueDirectory (" SYCLBINTest-test" , TestDirectory));
166
+ // Currently we have an abstract module per image.
167
+ ASSERT_EQ (SYCLBINObj->AbstractModules .size (), size_t {NumImages});
168
+
169
+ std::vector<decltype (Images)::const_iterator> ImageIts;
170
+ ImageIts.reserve (NumImages);
171
+ size_t ObservedIRModules = 0 , ObservedNativeDeviceCodeImages = 0 ;
172
+ for (size_t I = 0 ; I < NumImages; ++I) {
173
+ const SYCLBIN::AbstractModule &AM = SYCLBINObj->AbstractModules [I];
174
+
175
+ // This metadata should be the same as in the corresponding split module, so
176
+ // testing should be expanded to ensure preservation.
177
+ ASSERT_NE (AM.Metadata .get (), nullptr );
178
+ EXPECT_TRUE (AM.Metadata ->getPropSets ().empty ());
179
+
180
+ ObservedIRModules += AM.IRModules .size ();
181
+ for (size_t J = 0 ; J < AM.IRModules .size (); ++J) {
182
+ const SYCLBIN::IRModule &IRM = AM.IRModules [J];
183
+ ASSERT_NE (IRM.Metadata .get (), nullptr );
184
+ SmallString<16 > IRMMetadataKey{
185
+ PropertySetRegistry::SYCLBIN_IR_MODULE_METADATA};
186
+ const auto &IRMMetadataIt =
187
+ IRM.Metadata ->getPropSets ().find (IRMMetadataKey);
188
+ ASSERT_NE (IRMMetadataIt, IRM.Metadata ->end ());
189
+ const PropertySet &IRMMetadata = IRMMetadataIt->second ;
190
+ EXPECT_EQ (IRMMetadata.size (), size_t {1 });
191
+
192
+ // The type is currently locked to SPIR-V. This will change in the future.
193
+ SmallString<16 > IRMMetadataTypeKey{" type" };
194
+ const auto &IRMMetadataTypeIt = IRMMetadata.find (IRMMetadataTypeKey);
195
+ ASSERT_NE (IRMMetadataTypeIt, IRMMetadata.end ());
196
+ const PropertyValue &IRMMetadataType = IRMMetadataTypeIt->second ;
197
+ ASSERT_EQ (IRMMetadataType.getType (), PropertyValue::Type::UINT32);
198
+ EXPECT_EQ (IRMMetadataType.asUint32 (), uint32_t {0 });
199
+
200
+ // Find the image that matches.
201
+ std::vector<uint8_t > IRImage{IRM.RawIRBytes .begin (),
202
+ IRM.RawIRBytes .end ()};
203
+ auto ImageMatchIt = std::find (Images.begin (), Images.end (), IRImage);
204
+ ASSERT_NE (ImageMatchIt, Images.end ());
205
+ ImageIts.push_back (ImageMatchIt);
206
+ }
207
+
208
+ ObservedNativeDeviceCodeImages += AM.NativeDeviceCodeImages .size ();
209
+ for (size_t J = 0 ; J < AM.NativeDeviceCodeImages .size (); ++J) {
210
+ const SYCLBIN::NativeDeviceCodeImage &NDCI = AM.NativeDeviceCodeImages [J];
211
+
212
+ ASSERT_NE (NDCI.Metadata .get (), nullptr );
213
+ SmallString<16 > NDCIMetadataKey{
214
+ PropertySetRegistry::SYCLBIN_NATIVE_DEVICE_CODE_IMAGE_METADATA};
215
+ const auto &NDCIMetadataIt =
216
+ NDCI.Metadata ->getPropSets ().find (NDCIMetadataKey);
217
+ ASSERT_NE (NDCIMetadataIt, NDCI.Metadata ->end ());
218
+ const PropertySet &NDCIMetadata = NDCIMetadataIt->second ;
219
+ ASSERT_EQ (NDCIMetadata.size (), size_t {1 });
220
+
221
+ // Make sure the arch string is preserved.
222
+ SmallString<16 > NDCIMetadataArchKey{" arch" };
223
+ const auto &NDCIMetadataArchIt = NDCIMetadata.find (NDCIMetadataArchKey);
224
+ ASSERT_NE (NDCIMetadataArchIt, NDCIMetadata.end ());
225
+ const PropertyValue &NDCIMetadataArch = NDCIMetadataArchIt->second ;
226
+ ASSERT_EQ (NDCIMetadataArch.getType (), PropertyValue::Type::BYTE_ARRAY);
227
+ ASSERT_EQ (NDCIMetadataArch.getByteArraySize (), strlen (Arch));
228
+ EXPECT_EQ (std::memcmp (NDCIMetadataArch.asByteArray (), Arch, strlen (Arch)),
229
+ 0 );
230
+
231
+ // Find the image that matches.
232
+ std::vector<uint8_t > RawDeviceCodeImage{
233
+ NDCI.RawDeviceCodeImageBytes .begin (),
234
+ NDCI.RawDeviceCodeImageBytes .end ()};
235
+ auto ImageMatchIt =
236
+ std::find (Images.begin (), Images.end (), RawDeviceCodeImage);
237
+ ASSERT_NE (ImageMatchIt, Images.end ());
238
+ ImageIts.push_back (ImageMatchIt);
239
+ }
182
240
}
241
+ ASSERT_EQ (NumIRModules, ObservedIRModules);
242
+ ASSERT_EQ (NumNativeDeviceCodeImages, ObservedNativeDeviceCodeImages);
243
+ // The images may not appear in the same order they were written. They
244
+ // shouldn't be the same however.
245
+ ASSERT_TRUE (std::unique (ImageIts.begin (), ImageIts.end ()) == ImageIts.end ());
246
+ }
183
247
184
- // Create a random file to be used in the SYCLBIN.
185
- SmallString<128 > File1 (TestDirectory);
186
- File1.append (" /image_file1" );
187
- std::vector<uint8_t > Image = generateRandomImage ();
188
- Expected<ManagedBinaryFile> ManagedModuleFileOrError =
189
- ManagedBinaryFile::create (File1, Image);
190
- ASSERT_THAT_EXPECTED (ManagedModuleFileOrError, Succeeded ());
191
- ManagedBinaryFile ManagedModuleFile = std::move (*ManagedModuleFileOrError);
192
-
193
- // Create IR module.
194
- std::vector<module_split::SplitModule> SplitModules{module_split::SplitModule{
195
- File1.c_str (), util::PropertySetRegistry{}, " " }};
196
- SmallVector<SYCLBIN::SYCLBINModuleDesc> MDs{
197
- SYCLBIN::SYCLBINModuleDesc{Arch, std::move (SplitModules)}};
198
- SYCLBIN::SYCLBINDesc Desc{SYCLBIN::BundleState::Input, MDs};
199
- size_t SYCLBINByteSize = 0 ;
200
- if (Error E = Desc.getSYCLBINByteSite ().moveInto (SYCLBINByteSize))
201
- FAIL () << " Failed to get SYCLBIN byte size." ;
202
-
203
- // Serialize the SYCLBIN.
204
- SmallString<0 > SYCLBINImage;
205
- SYCLBINImage.reserve (SYCLBINByteSize);
206
- raw_svector_ostream SYCLBINImageOS{SYCLBINImage};
207
- if (Error E = SYCLBIN::write (Desc, SYCLBINImageOS))
208
- FAIL () << " Failed to write SYCLBIN." ;
248
+ } // namespace
209
249
210
- // Deserialize the SYCLBIN.
211
- std::unique_ptr<MemoryBuffer> SYCBINDataBuffer =
212
- MemoryBuffer::getMemBuffer (SYCLBINImage, /* BufferName=*/ " " ,
213
- /* RequiresNullTerminator=*/ false );
214
- Expected<std::unique_ptr<SYCLBIN>> SYCLBINObjOrError =
215
- SYCLBIN::read (*SYCBINDataBuffer);
216
- ASSERT_THAT_EXPECTED (SYCLBINObjOrError, Succeeded ());
217
- SYCLBIN *SYCLBINObj = SYCLBINObjOrError->get ();
218
- ASSERT_NE (SYCLBINObj, nullptr );
250
+ TEST (SYCLBINTest, checkSYCLBINBinaryBasicIRModule) {
251
+ CommonCheck</* NumIRModules=*/ 1 , /* NumNativeDeviceCodeImages=*/ 0 >();
252
+ }
219
253
220
- EXPECT_EQ (SYCLBINObj->Version , SYCLBIN::CurrentVersion);
254
+ TEST (SYCLBINTest, checkSYCLBINBinaryDoubleBasicIRModules) {
255
+ CommonCheck</* NumIRModules=*/ 2 , /* NumNativeDeviceCodeImages=*/ 0 >();
256
+ }
221
257
222
- ASSERT_NE (SYCLBINObj->GlobalMetadata .get (), nullptr );
223
- SmallString<16 > GlobalMetadataKey{
224
- PropertySetRegistry::SYCLBIN_GLOBAL_METADATA};
225
- const auto &GlobalMetadataIt =
226
- SYCLBINObj->GlobalMetadata ->getPropSets ().find (GlobalMetadataKey);
227
- ASSERT_NE (GlobalMetadataIt, SYCLBINObj->GlobalMetadata ->end ());
228
- const PropertySet &GlobalMetadata = GlobalMetadataIt->second ;
229
- EXPECT_EQ (GlobalMetadata.size (), size_t {1 });
258
+ TEST (SYCLBINTest, checkSYCLBINBinaryBasicNativeDeviceCodeImage) {
259
+ CommonCheck</* NumIRModules=*/ 0 , /* NumNativeDeviceCodeImages=*/ 1 >();
260
+ }
230
261
231
- SmallString<16 > GlobalMetadataStateKey{" state" };
232
- const auto &GlobalMetadataStateIt =
233
- GlobalMetadata.find (GlobalMetadataStateKey);
234
- ASSERT_NE (GlobalMetadataStateIt, GlobalMetadata.end ());
235
- const PropertyValue &GlobalMetadataState = GlobalMetadataStateIt->second ;
236
- ASSERT_EQ (GlobalMetadataState.getType (), PropertyValue::Type::UINT32);
237
- EXPECT_EQ (GlobalMetadataState.asUint32 (), static_cast <uint32_t >(State));
262
+ TEST (SYCLBINTest, checkSYCLBINBinaryDoubleBasicNativeDeviceCodeImages) {
263
+ CommonCheck</* NumIRModules=*/ 0 , /* NumNativeDeviceCodeImages=*/ 2 >();
264
+ }
238
265
239
- ASSERT_EQ (SYCLBINObj->AbstractModules .size (), size_t {1 });
240
- const SYCLBIN::AbstractModule &AM = SYCLBINObj->AbstractModules [0 ];
241
-
242
- // This metadata should be the same as in the corresponding split module, so
243
- // testing should be expanded to ensure preservation.
244
- ASSERT_NE (AM.Metadata .get (), nullptr );
245
- EXPECT_TRUE (AM.Metadata ->getPropSets ().empty ());
246
-
247
- // There was a single module with an arch string, so we should not have an IR
248
- // module.
249
- EXPECT_TRUE (AM.IRModules .empty ());
250
-
251
- // There was an arch string, so there should be a native device code images.
252
- ASSERT_EQ (AM.NativeDeviceCodeImages .size (), size_t {1 });
253
- const SYCLBIN::NativeDeviceCodeImage &NDCI = AM.NativeDeviceCodeImages [0 ];
254
-
255
- ASSERT_NE (NDCI.Metadata .get (), nullptr );
256
- SmallString<16 > NDCIMetadataKey{
257
- PropertySetRegistry::SYCLBIN_NATIVE_DEVICE_CODE_IMAGE_METADATA};
258
- const auto &NDCIMetadataIt =
259
- NDCI.Metadata ->getPropSets ().find (NDCIMetadataKey);
260
- ASSERT_NE (NDCIMetadataIt, NDCI.Metadata ->end ());
261
- const PropertySet &NDCIMetadata = NDCIMetadataIt->second ;
262
- ASSERT_EQ (NDCIMetadata.size (), size_t {1 });
263
-
264
- // Make sure the arch string is preserved.
265
- SmallString<16 > NDCIMetadataArchKey{" arch" };
266
- const auto &NDCIMetadataArchIt = NDCIMetadata.find (NDCIMetadataArchKey);
267
- ASSERT_NE (NDCIMetadataArchIt, NDCIMetadata.end ());
268
- const PropertyValue &NDCIMetadataArch = NDCIMetadataArchIt->second ;
269
- ASSERT_EQ (NDCIMetadataArch.getType (), PropertyValue::Type::BYTE_ARRAY);
270
- ASSERT_EQ (NDCIMetadataArch.getByteArraySize (), strlen (Arch));
271
- EXPECT_EQ (std::memcmp (NDCIMetadataArch.asByteArray (), Arch, strlen (Arch)), 0 );
272
-
273
- // Check that the image is the same.
274
- ASSERT_EQ (Image.size (), NDCI.RawDeviceCodeImageBytes .size ());
275
- EXPECT_EQ (std::memcmp (Image.data (), NDCI.RawDeviceCodeImageBytes .data (),
276
- Image.size ()),
277
- 0 );
266
+ TEST (SYCLBINTest, checkSYCLBINBinaryMixBasicImages) {
267
+ CommonCheck</* NumIRModules=*/ 1 , /* NumNativeDeviceCodeImages=*/ 1 >();
278
268
}
0 commit comments