void evg_ndrange_free(struct evg_ndrange_t *ndrange) { int i; /* Clear task from command queue */ if (ndrange->command_queue && ndrange->command) { evg_opencl_command_queue_complete(ndrange->command_queue, ndrange->command); evg_opencl_command_free(ndrange->command); } /* Clear all states that affect lists. */ evg_ndrange_clear_status(ndrange, evg_ndrange_pending); evg_ndrange_clear_status(ndrange, evg_ndrange_running); evg_ndrange_clear_status(ndrange, evg_ndrange_finished); /* Extract from ND-Range list in Evergreen emulator */ assert(DOUBLE_LINKED_LIST_MEMBER(evg_emu, ndrange, ndrange)); DOUBLE_LINKED_LIST_REMOVE(evg_emu, ndrange, ndrange); /* Free work-groups */ for (i = 0; i < ndrange->work_group_count; i++) evg_work_group_free(ndrange->work_groups[i]); free(ndrange->work_groups); /* Free wavefronts */ for (i = 0; i < ndrange->wavefront_count; i++) evg_wavefront_free(ndrange->wavefronts[i]); free(ndrange->wavefronts); /* Free work-items */ for (i = 0; i < ndrange->work_item_count; i++) evg_work_item_free(ndrange->work_items[i]); free(ndrange->work_items); /* Free instruction histogram */ if (ndrange->inst_histogram) free(ndrange->inst_histogram); /* Free ND-Range */ free(ndrange->name); free(ndrange); }
int EvgGpuRun(Timing *self) { EvgGpu *gpu = asEvgGpu(self); struct evg_ndrange_t *ndrange; struct evg_compute_unit_t *compute_unit; struct evg_compute_unit_t *compute_unit_next; /* For efficiency when no Evergreen emulation is selected, exit here * if the list of existing ND-Ranges is empty. */ if (!evg_emu->ndrange_list_count) return FALSE; /* Start one ND-Range in state 'pending' */ while ((ndrange = evg_emu->pending_ndrange_list_head)) { /* Currently not supported for more than 1 ND-Range */ if (gpu->ndrange) fatal("%s: Evergreen GPU timing simulation not supported for multiple ND-Ranges", __FUNCTION__); /* Set ND-Range status to 'running' */ evg_ndrange_clear_status(ndrange, evg_ndrange_pending); evg_ndrange_set_status(ndrange, evg_ndrange_running); /* Trace */ evg_trace("evg.new_ndrange " "id=%d " "wg_first=%d " "wg_count=%d\n", ndrange->id, ndrange->work_group_id_first, ndrange->work_group_count); /* Map ND-Range to GPU */ evg_gpu_map_ndrange(ndrange); evg_calc_plot(); } /* Mapped ND-Range */ ndrange = gpu->ndrange; assert(ndrange); /* Allocate work-groups to compute units */ while (gpu->ready_list_head && ndrange->pending_list_head) evg_compute_unit_map_work_group(gpu->ready_list_head, ndrange->pending_list_head); /* One more cycle */ asTiming(evg_gpu)->cycle++; /* Stop if maximum number of GPU cycles exceeded */ if (evg_emu_max_cycles && asTiming(evg_gpu)->cycle >= evg_emu_max_cycles) esim_finish = esim_finish_evg_max_cycles; /* Stop if maximum number of GPU instructions exceeded */ if (evg_emu_max_inst && asEmu(evg_emu)->instructions >= evg_emu_max_inst) esim_finish = esim_finish_evg_max_inst; /* Stop if there was a simulation stall */ if (asTiming(evg_gpu)->cycle - gpu->last_complete_cycle > 1000000) { warning("Evergreen GPU simulation stalled.\n%s", evg_err_stall); esim_finish = esim_finish_stall; } /* Stop if any reason met */ if (esim_finish) return TRUE; /* Free instructions in trash */ evg_gpu_uop_trash_empty(); /* Run one loop iteration on each busy compute unit */ for (compute_unit = gpu->busy_list_head; compute_unit; compute_unit = compute_unit_next) { /* Store next busy compute unit, since this can change * during the compute unit simulation loop iteration. */ compute_unit_next = compute_unit->busy_list_next; /* Run one cycle */ evg_compute_unit_run(compute_unit); } /* GPU-REL: insert stack faults */ evg_faults_insert(); /* If ND-Range finished execution in all compute units, free it. */ if (!gpu->busy_list_count) { /* Dump ND-Range report */ evg_ndrange_dump(ndrange, evg_emu_report_file); /* Stop if maximum number of kernels reached */ if (evg_emu_max_kernels && evg_emu->ndrange_count >= evg_emu_max_kernels) esim_finish = esim_finish_evg_max_kernels; /* Finalize and free ND-Range */ assert(evg_ndrange_get_status(ndrange, evg_ndrange_finished)); evg_gpu_uop_trash_empty(); evg_gpu_unmap_ndrange(); evg_ndrange_free(ndrange); } /* Still simulating */ return TRUE; }