Skip to content

Commit ba2a295

Browse files
committed
kernel: add unit test to check skip reprogram when no device global present
1 parent 9cd7a78 commit ba2a295

File tree

1 file changed

+133
-4
lines changed

1 file changed

+133
-4
lines changed

test/acl_kernel_test.cpp

Lines changed: 133 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));
@@ -4598,6 +4598,135 @@ TEST(acl_kernel_reprogram_scheduler, device_global_reprogram) {
45984598
acl_print_debug_msg("DONE!\n");
45994599
}
46004600

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

0 commit comments

Comments
 (0)