@@ -4362,9 +4362,9 @@ TEST(acl_kernel_reprogram_scheduler, device_global_reprogram) {
4362
4362
4363
4363
// Pretend execution starts now
4364
4364
m_device->last_bin ->unload_content ();
4365
- m_device->last_bin = nullptr ;
4365
+ m_device->last_bin = NULL ;
4366
4366
m_device->loaded_bin ->unload_content ();
4367
- m_device->loaded_bin = nullptr ;
4367
+ m_device->loaded_bin = NULL ;
4368
4368
4369
4369
acl_device_program_info_t *dp0 = check_dev_prog (m_program0);
4370
4370
m_context->reprogram_buf_read_callback = read_mem_callback;
@@ -4398,8 +4398,8 @@ TEST(acl_kernel_reprogram_scheduler, device_global_reprogram) {
4398
4398
.autodiscovery_def .binary_rand_hash );
4399
4399
4400
4400
// 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 );
4403
4403
4404
4404
acl_print_debug_msg (" Forcing user event completion for first kernel\n " );
4405
4405
CHECK_EQUAL (CL_SUCCESS, clSetUserEventStatus (ue1, CL_COMPLETE));
@@ -4598,6 +4598,135 @@ TEST(acl_kernel_reprogram_scheduler, device_global_reprogram) {
4598
4598
acl_print_debug_msg (" DONE!\n " );
4599
4599
}
4600
4600
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
+
4601
4730
TEST (acl_kernel_reprogram_scheduler, use_host_buf_as_arg) {
4602
4731
// Must be able to use a host-side buffer as a kernel argument.
4603
4732
cl_int status = 0 ;
0 commit comments