Пример #1
0
void si_ndrange_free(struct si_ndrange_t *ndrange)
{
	/* Set event status to complete if an event was set. */
	if(ndrange->event)
		ndrange->event->status = SI_OPENCL_EVENT_STATUS_COMPLETE;

	int i;

	/* Clear task from command queue */
	if (ndrange->command_queue && ndrange->command)
	{
		si_opencl_command_queue_complete(ndrange->command_queue, ndrange->command);
		si_opencl_command_free(ndrange->command);
	}

	/* Clear all states that affect lists. */
	si_ndrange_clear_status(ndrange, si_ndrange_pending);
	si_ndrange_clear_status(ndrange, si_ndrange_running);
	si_ndrange_clear_status(ndrange, si_ndrange_finished);

	/* Extract from ND-Range list in Southern Islands emulator */
	assert(DOUBLE_LINKED_LIST_MEMBER(si_emu, ndrange, ndrange));
	DOUBLE_LINKED_LIST_REMOVE(si_emu, ndrange, ndrange);

	/* Free lists */
	list_free(ndrange->uav_list);

	/* Free work-groups */
	for (i = 0; i < ndrange->work_group_count; i++)
		si_work_group_free(ndrange->work_groups[i]);
	free(ndrange->work_groups);

	/* Free wavefronts */
	for (i = 0; i < ndrange->wavefront_count; i++)
	{
		si_wavefront_free(ndrange->wavefronts[i]);
		si_work_item_free(ndrange->scalar_work_items[i]);
	}
	free(ndrange->wavefronts);
	free(ndrange->scalar_work_items);

	/* Free work-items */
	for (i = 0; i < ndrange->work_item_count; i++)
		si_work_item_free(ndrange->work_items[i]);
	free(ndrange->work_items);

	/* Free instruction histogram */
	if (ndrange->inst_histogram)
		free(ndrange->inst_histogram);

	/* Free ndrange */
	free(ndrange->name);
	free(ndrange);
}
Пример #2
0
void si_ndrange_free(struct si_ndrange_t *ndrange)
{
	int i;

	/* Run free notify call-back */
	if (ndrange->free_notify_func)
		ndrange->free_notify_func(ndrange->free_notify_data);

	/* Clear all states that affect lists. */
	si_ndrange_clear_status(ndrange, si_ndrange_pending);
	si_ndrange_clear_status(ndrange, si_ndrange_running);
	si_ndrange_clear_status(ndrange, si_ndrange_finished);

	/* Extract from ND-Range list in Southern Islands emulator */
	assert(DOUBLE_LINKED_LIST_MEMBER(si_emu, ndrange, ndrange));
	DOUBLE_LINKED_LIST_REMOVE(si_emu, ndrange, ndrange);

	/* Free work-groups */
	for (i = 0; i < ndrange->work_group_count; i++)
		si_work_group_free(ndrange->work_groups[i]);
	free(ndrange->work_groups);

	/* Free wavefronts */
	for (i = 0; i < ndrange->wavefront_count; i++)
	{
		si_wavefront_free(ndrange->wavefronts[i]);
		si_work_item_free(ndrange->scalar_work_items[i]);
	}
	free(ndrange->wavefronts);
	free(ndrange->scalar_work_items);

	/* Free work-items */
	for (i = 0; i < ndrange->work_item_count; i++)
		si_work_item_free(ndrange->work_items[i]);
	free(ndrange->work_items);

	/* Free instruction histogram */
	if (ndrange->inst_histogram)
		free(ndrange->inst_histogram);

	/* Free instruction buffer */
	if (ndrange->inst_buffer)
		free(ndrange->inst_buffer);

	/* Free ndrange */
	free(ndrange->name);
	free(ndrange);
}
Пример #3
0
/* 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;
}
Пример #4
0
/* Run one iteration of the Southern Islands GPU timing simulation loop. */
int si_gpu_run(void)
{
    struct si_ndrange_t *ndrange;

    struct si_compute_unit_t *compute_unit;
    struct si_compute_unit_t *compute_unit_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 one ND-Range in state 'pending' */
    while ((ndrange = si_emu->pending_ndrange_list_head))
    {
        /* Currently not supported for more than 1 ND-Range */
        if (si_gpu->ndrange)
            fatal("%s: Southern Islands GPU timing simulation not supported "
                  "for multiple ND-Ranges", __FUNCTION__);

        /* Set ND-Range status to 'running' */
        si_ndrange_clear_status(ndrange, si_ndrange_pending);
        si_ndrange_set_status(ndrange, si_ndrange_running);

        /* Trace */
        si_trace("si.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 */
        si_gpu_map_ndrange(ndrange);
        si_calc_plot();
    }

    /* Mapped ND-Range */
    ndrange = si_gpu->ndrange;
    assert(ndrange);

    /* Allocate work-groups to compute units */
    while (si_gpu->compute_unit_ready_list_head && ndrange->pending_list_head)
        si_compute_unit_map_work_group(si_gpu->compute_unit_ready_list_head,
                                       ndrange->pending_list_head);

    /* One more cycle */
    si_gpu->cycle++;

    /* Stop if maximum number of GPU cycles exceeded */
    if (si_emu_max_cycles && si_gpu->cycle >= si_emu_max_cycles)
        esim_finish = esim_finish_si_max_cycles;

    /* Stop if maximum number of GPU instructions exceeded */
    if (si_emu_max_inst && si_emu->inst_count >= si_emu_max_inst)
        esim_finish = esim_finish_si_max_inst;

    /* Stop if any reason met */
    if (esim_finish)
        return 1;

    /* Free instructions in trash */
    si_gpu_uop_trash_empty();

    /* Run one loop iteration on each busy compute unit */
    for (compute_unit = si_gpu->compute_unit_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->compute_unit_busy_list_next;

        /* Run one cycle */
        si_compute_unit_run(compute_unit);
    }

    /* If ND-Range finished execution in all compute units, free it. */
    if (!si_gpu->compute_unit_busy_list_count)
    {
        /* 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;

        /* Finalize and free ND-Range */
        assert(si_ndrange_get_status(ndrange, si_ndrange_finished));
        si_gpu_uop_trash_empty();
        si_gpu_unmap_ndrange();
        si_ndrange_free(ndrange);
    }

    /* Return true */
    return 1;
}