int SIEmuRun(Emu *self) { SIEmu *emu = asSIEmu(self); struct si_ndrange_t *ndrange; struct si_wavefront_t *wavefront; struct si_work_group_t *work_group; int wavefront_id; long work_group_id; if (!list_count(emu->running_work_groups) && list_count(emu->waiting_work_groups)) { work_group_id = (long)list_dequeue(emu->waiting_work_groups); list_enqueue(emu->running_work_groups, (void*)work_group_id); } /* For efficiency when no Southern Islands emulation is selected, * exit here if the list of existing ND-Ranges is empty. */ if (!list_count(emu->running_work_groups)) return FALSE; assert(emu->ndrange); ndrange = emu->ndrange; /* Instantiate the next work-group */ work_group_id = (long)list_bottom(emu->running_work_groups); work_group = si_work_group_create(work_group_id, ndrange); // struct si_wavefront_t* wf = work_group->wavefronts[0]; // struct si_work_item_t* wi = wf->work_items[62]; //printf("Vsrc1 value V0: %d\n", wi->vreg[0].as_int); /* Execute the work-group to completion */ while (!work_group->finished_emu) { SI_FOREACH_WAVEFRONT_IN_WORK_GROUP(work_group, wavefront_id) { wavefront = work_group->wavefronts[wavefront_id]; if (wavefront->finished || wavefront->at_barrier) continue; /* Execute instruction in wavefront */ si_wavefront_execute(wavefront); } }
/* Run one iteration of the Southern Islands GPU emulation loop. * Return FALSE if there is no more emulation to perform. */ int si_emu_run(void) { struct si_ndrange_t *ndrange; struct si_ndrange_t *ndrange_next; struct si_work_group_t *work_group; struct si_work_group_t *work_group_next; struct si_wavefront_t *wavefront; struct si_wavefront_t *wavefront_next; /* For efficiency when no Southern Islands emulation is selected, exit here * if the list of existing ND-Ranges is empty. */ if (!si_emu->ndrange_list_count) return 0; /* Start any ND-Range in state 'pending' */ while ((ndrange = si_emu->pending_ndrange_list_head)) { /* Set all ready work-groups to running */ while ((work_group = ndrange->pending_list_head)) { si_work_group_clear_status(work_group, si_work_group_pending); si_work_group_set_status(work_group, si_work_group_running); } /* Set is in state 'running' */ si_ndrange_clear_status(ndrange, si_ndrange_pending); si_ndrange_set_status(ndrange, si_ndrange_running); } /* Run one instruction of each wavefront in each work-group of each * ND-Range that is in status 'running'. */ for (ndrange = si_emu->running_ndrange_list_head; ndrange; ndrange = ndrange_next) { /* Save next ND-Range in state 'running'. This is done because the state * might change during the execution of the ND-Range. */ ndrange_next = ndrange->running_ndrange_list_next; /* Execute an instruction from each work-group */ for (work_group = ndrange->running_list_head; work_group; work_group = work_group_next) { /* Save next running work-group */ work_group_next = work_group->running_list_next; /* Run an instruction from each wavefront */ for (wavefront = work_group->running_list_head; wavefront; wavefront = wavefront_next) { /* Save next running wavefront */ wavefront_next = wavefront->running_list_next; /* Execute instruction in wavefront */ si_wavefront_execute(wavefront); } } } /* Free ND-Ranges that finished */ while ((ndrange = si_emu->finished_ndrange_list_head)) { /* Dump ND-Range report */ si_ndrange_dump(ndrange, si_emu_report_file); /* Stop if maximum number of kernels reached */ if (si_emu_max_kernels && si_emu->ndrange_count >= si_emu_max_kernels) esim_finish = esim_finish_si_max_kernels; /* Extract from list of finished ND-Ranges and free */ si_ndrange_free(ndrange); } /* Return TRUE */ return 1; }