Skip to content

Commit 71d527e

Browse files
committed
kernel: add unit test to check skip reprogram when no device global present
1 parent 566edef commit 71d527e

File tree

1 file changed

+131
-4
lines changed

1 file changed

+131
-4
lines changed

test/acl_kernel_test.cpp

Lines changed: 131 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4362,9 +4362,9 @@ TEST(acl_kernel_reprogram_scheduler, device_global_reprogram) {
43624362

43634363
// Pretend execution starts now
43644364
m_device->last_bin->unload_content();
4365-
m_device->last_bin = nullptr;
4365+
m_device->last_bin = NULL;
43664366
m_device->loaded_bin->unload_content();
4367-
m_device->loaded_bin = nullptr;
4367+
m_device->loaded_bin = NULL;
43684368

43694369
acl_device_program_info_t *dp0 = check_dev_prog(m_program0);
43704370
m_context->reprogram_buf_read_callback = read_mem_callback;
@@ -4398,8 +4398,8 @@ TEST(acl_kernel_reprogram_scheduler, device_global_reprogram) {
43984398
.autodiscovery_def.binary_rand_hash);
43994399

44004400
// last_bin and loaded_bin should still in a reset state
4401-
CHECK(m_device->last_bin == nullptr);
4402-
CHECK(m_device->loaded_bin == nullptr);
4401+
CHECK(m_device->last_bin == NULL);
4402+
CHECK(m_device->loaded_bin == NULL);
44034403

44044404
acl_print_debug_msg("Forcing user event completion for first kernel\n");
44054405
CHECK_EQUAL(CL_SUCCESS, clSetUserEventStatus(ue1, CL_COMPLETE));
@@ -4596,6 +4596,133 @@ TEST(acl_kernel_reprogram_scheduler, device_global_reprogram) {
45964596
m_device->def.autodiscovery_def.device_global_mem_defs.clear();
45974597
}
45984598

4599+
TEST(acl_kernel_reprogram_scheduler, skip_reprogram_on_start) {
4600+
// Test if reprogram is skipped if the binary currently loaded
4601+
// on the board is the same as the one to be loaded
4602+
4603+
// Initial eager reprogram
4604+
int offset = m_devlog.num_ops;
4605+
CHECK_EQUAL(3, offset);
4606+
// Just the initial program load.
4607+
CHECK_EQUAL(m_first_dev_bin, m_device->last_bin);
4608+
CHECK_EQUAL(m_first_dev_bin, m_device->loaded_bin);
4609+
4610+
// Pretend execution starts now
4611+
m_device->last_bin->unload_content();
4612+
m_device->last_bin = NULL;
4613+
m_device->loaded_bin->unload_content();
4614+
m_device->loaded_bin = NULL;
4615+
4616+
acl_device_program_info_t *dp0 = check_dev_prog(m_program0);
4617+
m_context->reprogram_buf_read_callback = read_mem_callback;
4618+
m_context->reprogram_buf_write_callback = write_mem_callback;
4619+
4620+
// A device side buffer
4621+
cl_int status = CL_INVALID_VALUE;
4622+
cl_mem mem = clCreateBuffer(m_context, CL_MEM_READ_WRITE, 2048, 0, &status);
4623+
CHECK_EQUAL(CL_SUCCESS, status);
4624+
CHECK(mem);
4625+
memset(mem->host_mem.aligned_ptr, 'X', mem->size);
4626+
memset(mem->block_allocation->range.begin, 'x', mem->size);
4627+
4628+
CHECK_EQUAL(1, m_context->device_buffers_have_backing_store);
4629+
CHECK_EQUAL(0, mem->block_allocation->region->is_host_accessible);
4630+
CHECK_EQUAL(0, mem->writable_copy_on_host);
4631+
4632+
cl_kernel k = get_kernel(m_program0);
4633+
cl_event ue = get_user_event();
4634+
cl_event k_e = 0;
4635+
4636+
// Launch the kernel for the first time
4637+
CHECK_EQUAL(CL_SUCCESS, clSetKernelArg(k, 0, sizeof(cl_mem), &mem));
4638+
CHECK_EQUAL(CL_SUCCESS, clSetKernelArg(k, 1, sizeof(cl_mem), &mem));
4639+
CHECK_EQUAL(CL_SUCCESS, clEnqueueTask(m_cq, k, 1, &ue, &k_e));
4640+
CHECK_EQUAL(CL_COMMAND_TASK, k_e->cmd.type);
4641+
CHECK(m_device->def.autodiscovery_def.binary_rand_hash ==
4642+
k_e->cmd.info.ndrange_kernel.dev_bin->get_devdef()
4643+
.autodiscovery_def.binary_rand_hash);
4644+
4645+
// last_bin and loaded_bin should still in a reset state
4646+
CHECK(m_device->last_bin == NULL);
4647+
CHECK(m_device->loaded_bin == NULL);
4648+
4649+
acl_print_debug_msg("Forcing user event completion for first kernel\n");
4650+
CHECK_EQUAL(CL_SUCCESS, clSetUserEventStatus(ue, CL_COMPLETE));
4651+
CHECK_EQUAL(CL_SUCCESS, clReleaseEvent(ue));
4652+
4653+
// Since reprogram didn't occur, only last_bin should be updated
4654+
CHECK_EQUAL(&(dp0->device_binary), m_device->last_bin);
4655+
CHECK(m_device->loaded_bin == NULL);
4656+
4657+
// set MEM_MIGRATE 1 to RUNNING +
4658+
// set MEM_MIGRATE 1 to COMPLETE +
4659+
// set MEM_MIGRATE 2 to RUNNING +
4660+
// set MEM_MIGRATE 2 to COMPLETE +
4661+
// submit KERNEL = 5
4662+
CHECK_EQUAL(offset + 5, m_devlog.num_ops);
4663+
const acl_device_op_t *op0submit = &(m_devlog.before[7]);
4664+
CHECK_EQUAL(ACL_DEVICE_OP_KERNEL, op0submit->info.type);
4665+
CHECK_EQUAL(k_e, op0submit->info.event);
4666+
CHECK_EQUAL(CL_SUBMITTED, op0submit->status);
4667+
CHECK_EQUAL(0, op0submit->info.num_printf_bytes_pending);
4668+
CHECK_EQUAL(0, op0submit->first_in_group); // mem migrate is first
4669+
CHECK_EQUAL(1, op0submit->last_in_group);
4670+
4671+
// The user-level event is linked to the kernel device op now.
4672+
CHECK_EQUAL(op0submit->id, k_e->current_device_op->id);
4673+
4674+
// Pretend to start the kernel
4675+
acl_print_debug_msg("Say kernel is running\n");
4676+
ACL_LOCKED(acl_receive_kernel_update(k_e->current_device_op->id, CL_RUNNING));
4677+
CHECK_EQUAL(CL_RUNNING, k_e->current_device_op->execution_status);
4678+
4679+
ACL_LOCKED(acl_idle_update(m_context));
4680+
4681+
// Now we have a "running" transition
4682+
CHECK_EQUAL(offset + 6, m_devlog.num_ops);
4683+
const acl_device_op_t *op0running = &(m_devlog.after[8]);
4684+
CHECK_EQUAL(ACL_DEVICE_OP_KERNEL, op0running->info.type);
4685+
CHECK_EQUAL(k_e, op0running->info.event);
4686+
CHECK_EQUAL(CL_RUNNING, op0running->status);
4687+
CHECK_EQUAL(0, op0running->info.num_printf_bytes_pending);
4688+
CHECK_EQUAL(0, op0running->first_in_group);
4689+
CHECK_EQUAL(1, op0running->last_in_group);
4690+
4691+
// The running status was propagated up to the user-level event.
4692+
CHECK_EQUAL(CL_RUNNING, k_e->execution_status);
4693+
4694+
acl_print_debug_msg("Say kernel is complete\n");
4695+
ACL_LOCKED(
4696+
acl_receive_kernel_update(k_e->current_device_op->id, CL_COMPLETE));
4697+
CHECK_EQUAL(CL_COMPLETE, k_e->current_device_op->execution_status);
4698+
4699+
ACL_LOCKED(acl_idle_update(m_context));
4700+
// Now we have a "complete" transition
4701+
CHECK_EQUAL(offset + 7, m_devlog.num_ops);
4702+
const acl_device_op_t *op0complete = &(m_devlog.after[9]);
4703+
CHECK_EQUAL(ACL_DEVICE_OP_KERNEL, op0complete->info.type);
4704+
CHECK_EQUAL(k_e, op0complete->info.event);
4705+
CHECK_EQUAL(CL_COMPLETE, op0complete->status);
4706+
CHECK_EQUAL(0, op0complete->info.num_printf_bytes_pending);
4707+
CHECK_EQUAL(0, op0complete->first_in_group);
4708+
CHECK_EQUAL(1, op0complete->last_in_group);
4709+
4710+
// Completion timestamp has propagated up to the user level event.
4711+
CHECK_EQUAL(
4712+
acl_platform.device_op_queue.op[op0complete->id].timestamp[CL_COMPLETE],
4713+
k_e->timestamp[CL_COMPLETE]);
4714+
4715+
// Completion wipes out the downlink.
4716+
CHECK_EQUAL(0, k_e->current_device_op);
4717+
4718+
// And let go.
4719+
// (Don't check for CL_INVALID_EVENT on a second release of each of
4720+
// these events because the events might be reused.)
4721+
CHECK_EQUAL(CL_SUCCESS, clReleaseMemObject(mem));
4722+
CHECK_EQUAL(CL_SUCCESS, clReleaseEvent(k_e));
4723+
CHECK_EQUAL(CL_SUCCESS, clReleaseKernel(k));
4724+
}
4725+
45994726
TEST(acl_kernel_reprogram_scheduler, use_host_buf_as_arg) {
46004727
// Must be able to use a host-side buffer as a kernel argument.
46014728
cl_int status = 0;

0 commit comments

Comments
 (0)