@@ -1274,6 +1274,109 @@ struct urBaseKernelExecutionTest : urBaseKernelTest {
1274
1274
uint32_t current_arg_index = 0 ;
1275
1275
};
1276
1276
1277
+ template <typename T>
1278
+ struct urBaseKernelExecutionTestWithParam : urBaseKernelTestWithParam<T> {
1279
+ void SetUp () override {
1280
+ UUR_RETURN_ON_FATAL_FAILURE (urBaseKernelTestWithParam<T>::SetUp ());
1281
+ UUR_RETURN_ON_FATAL_FAILURE (urBaseKernelTestWithParam<T>::Build ());
1282
+ context = urBaseKernelTestWithParam<T>::context;
1283
+ kernel = urBaseKernelTestWithParam<T>::kernel;
1284
+ ASSERT_SUCCESS (urQueueCreate (
1285
+ context, urBaseKernelTestWithParam<T>::device, 0 , &queue));
1286
+ }
1287
+
1288
+ void TearDown () override {
1289
+ for (auto &buffer : buffer_args) {
1290
+ ASSERT_SUCCESS (urMemRelease (buffer));
1291
+ }
1292
+ UUR_RETURN_ON_FATAL_FAILURE (urBaseKernelTestWithParam<T>::TearDown ());
1293
+ if (queue) {
1294
+ EXPECT_SUCCESS (urQueueRelease (queue));
1295
+ }
1296
+ }
1297
+
1298
+ // Adds a kernel arg representing a sycl buffer constructed with a 1D range.
1299
+ void AddBuffer1DArg (size_t size, ur_mem_handle_t *out_buffer) {
1300
+ ur_mem_handle_t mem_handle = nullptr ;
1301
+ ASSERT_SUCCESS (urMemBufferCreate (context, UR_MEM_FLAG_READ_WRITE, size,
1302
+ nullptr , &mem_handle));
1303
+ char zero = 0 ;
1304
+ ASSERT_SUCCESS (urEnqueueMemBufferFill (queue, mem_handle, &zero,
1305
+ sizeof (zero), 0 , size, 0 , nullptr ,
1306
+ nullptr ));
1307
+ ASSERT_SUCCESS (urQueueFinish (queue));
1308
+ ASSERT_SUCCESS (urKernelSetArgMemObj (kernel, current_arg_index, nullptr ,
1309
+ mem_handle));
1310
+
1311
+ // SYCL device kernels have different interfaces depending on the
1312
+ // backend being used. Typically a kernel which takes a buffer argument
1313
+ // will take a pointer to the start of the buffer and a sycl::id param
1314
+ // which is a struct that encodes the accessor to the buffer. However
1315
+ // the AMD backend handles this differently and uses three separate
1316
+ // arguments for each of the three dimensions of the accessor.
1317
+
1318
+ ur_platform_backend_t backend;
1319
+ ASSERT_SUCCESS (urPlatformGetInfo (urBaseKernelTestWithParam<T>::platform,
1320
+ UR_PLATFORM_INFO_BACKEND,
1321
+ sizeof (backend), &backend, nullptr ));
1322
+ if (backend == UR_PLATFORM_BACKEND_HIP) {
1323
+ // this emulates the three offset params for buffer accessor on AMD.
1324
+ size_t val = 0 ;
1325
+ ASSERT_SUCCESS (urKernelSetArgValue (kernel, current_arg_index + 1 ,
1326
+ sizeof (size_t ), nullptr , &val));
1327
+ ASSERT_SUCCESS (urKernelSetArgValue (kernel, current_arg_index + 2 ,
1328
+ sizeof (size_t ), nullptr , &val));
1329
+ ASSERT_SUCCESS (urKernelSetArgValue (kernel, current_arg_index + 3 ,
1330
+ sizeof (size_t ), nullptr , &val));
1331
+ current_arg_index += 4 ;
1332
+ } else {
1333
+ // This emulates the offset struct sycl adds for a 1D buffer accessor.
1334
+ struct {
1335
+ size_t offsets[1 ] = {0 };
1336
+ } accessor;
1337
+ ASSERT_SUCCESS (urKernelSetArgValue (kernel, current_arg_index + 1 ,
1338
+ sizeof (accessor), nullptr ,
1339
+ &accessor));
1340
+ current_arg_index += 2 ;
1341
+ }
1342
+
1343
+ buffer_args.push_back (mem_handle);
1344
+ *out_buffer = mem_handle;
1345
+ }
1346
+
1347
+ template <class U > void AddPodArg (U data) {
1348
+ ASSERT_SUCCESS (urKernelSetArgValue (kernel, current_arg_index,
1349
+ sizeof (data), nullptr , &data));
1350
+ current_arg_index++;
1351
+ }
1352
+
1353
+ // Validate the contents of `buffer` according to the given validator.
1354
+ template <class U >
1355
+ void ValidateBuffer (ur_mem_handle_t buffer, size_t size,
1356
+ std::function<bool (U &)> validator) {
1357
+ std::vector<U> read_buffer (size / sizeof (U));
1358
+ ASSERT_SUCCESS (urEnqueueMemBufferRead (queue, buffer, true , 0 , size,
1359
+ read_buffer.data (), 0 , nullptr ,
1360
+ nullptr ));
1361
+ ASSERT_TRUE (
1362
+ std::all_of (read_buffer.begin (), read_buffer.end (), validator));
1363
+ }
1364
+
1365
+ // Helper that uses the generic validate function to check for a given value.
1366
+ template <class U >
1367
+ void ValidateBuffer (ur_mem_handle_t buffer, size_t size, U value) {
1368
+ auto validator = [&value](U result) -> bool { return result == value; };
1369
+
1370
+ ValidateBuffer<U>(buffer, size, validator);
1371
+ }
1372
+
1373
+ std::vector<ur_mem_handle_t > buffer_args;
1374
+ uint32_t current_arg_index = 0 ;
1375
+ ur_context_handle_t context;
1376
+ ur_kernel_handle_t kernel;
1377
+ ur_queue_handle_t queue;
1378
+ };
1379
+
1277
1380
struct urKernelExecutionTest : urBaseKernelExecutionTest {
1278
1381
void SetUp () {
1279
1382
UUR_RETURN_ON_FATAL_FAILURE (urBaseKernelExecutionTest::SetUp ());
0 commit comments