@@ -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+
45994726TEST (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