Ejemplo n.º 1
0
/* Read context properties from a null-terminated sequence of
 * 'cl_context_properties' elements in guest memory */
void si_opencl_context_set_properties(struct si_opencl_context_t *context, struct mem_t *mem, unsigned int addr)
{
	unsigned int property;
	unsigned int value;

	while (addr)
	{
		/* Read property */
		mem_read(mem, addr, 4, &property);
		if (!property)
			break;
		mem_read(mem, addr + 4, 4, &value);
		addr += 8;

		/* Analyze property */
		switch (property)
		{

		case 0x1084:  /* CL_CONTEXT_PLATFORM */
			context->platform_id = value;
			si_opencl_repo_get_object(si_emu->opencl_repo, si_opencl_object_platform, value);
			si_opencl_debug("    property CL_CONTEXT_PLATFORM assigned: 0x%x\n", value);
			break;

		default:
			fatal("opencl_context_read_properties: invalid property (0x%x)\n", property);
		}
	}
}
Ejemplo n.º 2
0
int si_opencl_command_queue_can_wakeup(struct x86_ctx_t *ctx, void *data)
{
	struct si_opencl_command_queue_t *command_queue;
	struct linked_list_t *command_list;

	int can_wakeup;

	/* x86 context can wakeup if command list is empty */
	command_queue = data;
	command_list = command_queue->command_list;
	can_wakeup = !command_list->count;

	/* Debug */
	if (can_wakeup)
		si_opencl_debug("\tcycle %lld - command queue 0x%x empty"
			" - context resumed\n", esim_cycle, command_queue->id);

	/* Return */
	return can_wakeup;
}
Ejemplo n.º 3
0
void si_ndrange_setup_args(struct si_ndrange_t *ndrange)
{
	struct si_opencl_kernel_t *kernel = ndrange->kernel;
	struct si_opencl_kernel_arg_t *arg;
	int i;
	int j;
	int cb_index = 0;

	/* Kernel arguments */
	for (i = 0; i < list_count(kernel->arg_list); i++)
	{
		arg = list_get(kernel->arg_list, i);
		assert(arg);

		/* Check that argument was set */
		if (!arg->set)
			fatal("kernel '%s': argument '%s' has not been assigned with 'clKernelSetArg'.",
				kernel->name, arg->name);

		/* Process argument depending on its type */
		switch (arg->kind)
		{

		case SI_OPENCL_KERNEL_ARG_KIND_VALUE:
		{
			/* Value copied directly into device constant memory */
			for (j = 0; j < arg->size/4; j++)
			{
				si_isa_const_mem_write(1, (cb_index*4)*4+j, &arg->data.value[j]);
				si_opencl_debug("    arg %d: value '0x%x' loaded into "
						"CB1[%d][%d]\n", i, arg->data.value[j], 
						cb_index, j);
			}
			cb_index++;
			break;
		}

		case SI_OPENCL_KERNEL_ARG_KIND_POINTER:
		{
			switch (arg->mem_scope)
			{

			case SI_OPENCL_MEM_SCOPE_CONSTANT:
			case SI_OPENCL_MEM_SCOPE_GLOBAL:
			{
				struct si_opencl_mem_t *mem;

				/* Pointer in __global scope.
				 * Argument value is a pointer to an 'opencl_mem' object.
				 * It is translated first into a device memory pointer. */
				mem = si_opencl_repo_get_object(si_emu->opencl_repo,
					si_opencl_object_mem, arg->data.ptr);
				si_isa_const_mem_write(1, (cb_index*4)*4, &mem->device_ptr);
				si_opencl_debug("    arg %d: opencl_mem id 0x%x loaded into CB1[%d],"
					" device_ptr=0x%x\n", i, arg->data.ptr, cb_index,
					mem->device_ptr);
				cb_index++;
				break;
			}

			case SI_OPENCL_MEM_SCOPE_LOCAL:
			{
				/* Pointer in __local scope.
				 * Argument value is always NULL, just assign space for it. */
				si_isa_const_mem_write(1, (cb_index*4)*4, &ndrange->local_mem_top);
				si_opencl_debug("    arg %d: %d bytes reserved in local memory at 0x%x\n",
					i, arg->size, ndrange->local_mem_top);
				ndrange->local_mem_top += arg->size;
				cb_index++;
				break;
			}

			default:
			{
				fatal("%s: argument in memory scope %d not supported",
					__FUNCTION__, arg->mem_scope);
			}

			}

			break;
		}

		default:
		{
			fatal("%s: argument type not reconized", __FUNCTION__);
		}

		}
	}	
}
Ejemplo n.º 4
0
static void si_opencl_kernel_load_metadata(struct si_opencl_kernel_t *kernel)
{
	char line[MAX_STRING_SIZE];
	char *line_ptrs[MAX_STRING_SIZE];
	int token_count;
	struct si_opencl_kernel_arg_t *arg;
	struct elf_buffer_t *buffer;

	/* Open as text file */
	buffer = &kernel->metadata_buffer;
	elf_buffer_seek(buffer, 0);
	si_opencl_debug("Kernel Metadata:\n");
	for (;;)
	{
		/* Read line from buffer */
		elf_buffer_read_line(buffer, line, MAX_STRING_SIZE);
		if (!line[0])
			break;
		si_opencl_debug("\t%s\n", line);

		/* Split line */
		line_ptrs[0] = strtok(line, ":;\n");
		for (token_count = 1; (line_ptrs[token_count] = strtok(NULL, ":\n")); token_count++);

		/* Ignored entries */
		if (!line_ptrs[0] ||
			!strcmp(line_ptrs[0], "ARGSTART") ||
			!strcmp(line_ptrs[0], "version") ||
			!strcmp(line_ptrs[0], "device") ||
			!strcmp(line_ptrs[0], "uniqueid") ||
			!strcmp(line_ptrs[0], "uavid") ||
			!strcmp(line_ptrs[0], "privateid") ||
			!strcmp(line_ptrs[0], "reflection") ||
			!strcmp(line_ptrs[0], "ARGEND"))
			continue;

		/* Image */
		if (!strcmp(line_ptrs[0], "image"))
		{
			/* Create input image argument */
			arg = si_opencl_kernel_arg_create(line_ptrs[1]);
			arg->kind = SI_OPENCL_KERNEL_ARG_KIND_IMAGE;
			if (!strcmp(line_ptrs[2], "2D"))
			{
				/* Ignore dimensions for now */
			}
			else if (!strcmp(line_ptrs[2], "3D"))
			{
				/* Ignore dimensions for now */
			}
			else
			{
				fatal("%s: Invalid number of dimensions for OpenCL Image (%s)\n%s",
					__FUNCTION__, line_ptrs[2], si_err_opencl_param_note);
			}
			
			if (!strcmp(line_ptrs[3], "RO"))
			{
				arg->access_type = SI_OPENCL_KERNEL_ARG_READ_ONLY;
			}
			else if (!strcmp(line_ptrs[3], "WO"))
			{
				arg->access_type = SI_OPENCL_KERNEL_ARG_WRITE_ONLY;
			}
			else
			{
				fatal("%s: Invalid memory access type for OpenCL Image (%s)\n%s",
					__FUNCTION__, line_ptrs[3], si_err_opencl_param_note);
			}
			arg->uav = atoi(line_ptrs[4]);
			arg->mem_scope = SI_OPENCL_MEM_SCOPE_GLOBAL;

			list_add(kernel->arg_list, arg);

			continue;

		} 

		/* Memory */
		if (!strcmp(line_ptrs[0], "memory"))
		{
			if (!strcmp(line_ptrs[1], "hwprivate"))
			{
				SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(2, "0");
			}
			else if (!strcmp(line_ptrs[1], "hwregion"))
			{
				SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
				SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(2, "0");
			}
			else if (!strcmp(line_ptrs[1], "hwlocal"))
			{
				SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
				kernel->func_mem_local = atoi(line_ptrs[2]);
			}
			else if (!strcmp(line_ptrs[1], "datareqd"))
			{
				SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(2);
			}
			else if (!strcmp(line_ptrs[1], "uavprivate"))
			{
				SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
			}
			else
				SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED(1);

			continue;
		}

		/* Entry 'value'. Format: value:<ArgName>:<DataType>:<Size>:<ConstNum>:<ConstOffset> */
		if (!strcmp(line_ptrs[0], "value"))
		{
			SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(6);
			//SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(3, "1");
			SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(4, "1");
			arg = si_opencl_kernel_arg_create(line_ptrs[1]);
			arg->kind = SI_OPENCL_KERNEL_ARG_KIND_VALUE;
			list_add(kernel->arg_list, arg);

			continue;
		}

		/* Entry 'pointer'. Format: pointer:<name>:<type>:?:?:<addr>:?:?:<elem_size> */
		if (!strcmp(line_ptrs[0], "pointer"))
		{
			/* APP SDK 2.5 supplies 9 tokens, 2.6 supplies 10 tokens */
			/* Metadata version 3:1:104 (as specified in entry 'version') uses 12 items. */
			if (token_count != 9 && token_count != 10 && token_count != 12)
			{
				SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(10);
			}
			SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(3, "1");
			SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(4, "1");

			/* We don't know what the two last entries are, so make sure that they are
			 * set to 0. If they're not 0, it probably means something important. */
			if (token_count == 12)
			{
				SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(10, "0");
				SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(11, "0");
			}

			arg = si_opencl_kernel_arg_create(line_ptrs[1]);
			arg->kind = SI_OPENCL_KERNEL_ARG_KIND_POINTER;

			list_add(kernel->arg_list, arg);
			if (!strcmp(line_ptrs[6], "uav"))
			{
				arg->mem_scope = SI_OPENCL_MEM_SCOPE_GLOBAL;
				arg->uav = atoi(line_ptrs[7]);
			}
			else if (!strcmp(line_ptrs[6], "hl"))
			{
				arg->mem_scope = SI_OPENCL_MEM_SCOPE_LOCAL;
				arg->uav = atoi(line_ptrs[7]);
			}
			else if (!strcmp(line_ptrs[6], "hc"))
			{
				arg->mem_scope = SI_OPENCL_MEM_SCOPE_CONSTANT;
				arg->uav = atoi(line_ptrs[7]);
			}
			else
				SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED(6);

			continue;
		}

		/* Entry 'function'. Format: function:?:<uniqueid> */
		if (!strcmp(line_ptrs[0], "function"))
		{
			SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
			SI_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(1, "1");
			kernel->func_uniqueid = atoi(line_ptrs[2]);
			continue;
		}

		/* Entry 'sampler'. Format: sampler:name:ID:location:value.
		 * 'location' is 1 for kernel defined samplers, 0 for kernel argument.
		 * 'value' is bitfield value of sampler (0 if a kernel argument) */
		if (!strcmp(line_ptrs[0], "sampler"))
		{
			/* As far as I can tell, the actual sampler data is stored 
			 * as a value, so adding it to the argument list is not required */
			continue;
		}

		/* Entry 'reflection'. Format: reflection:<arg_id>:<type>
		 * Observed first in version 3:1:104 of metadata.
		 * This entry specifies the type of the argument, as specified in the OpenCL
		 * kernel function header. It is currently ignored, since this information
		 * is extracted from the argument descriptions in 'value' and 'pointer' entries.
		 */
		if (!strcmp(line_ptrs[0], "reflection"))
		{
			SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
			continue;
		}

		/* Entry 'privateid'. Format: privateid:<id>
		 * Observed first in version 3:1:104 of metadata. Not sure what this entry is for.
		 */
		if (!strcmp(line_ptrs[0], "privateid"))
		{
			SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(2);
			continue;
		}

		/* Entry 'constarg'. Format: constarg:<arg_id>:<arg_name>
		 * Observed first in version 3:1:104 of metadata. It shows up when an argument
		 * is declared as '__global const'. Entry ignored here. */
		if (!strcmp(line_ptrs[0], "constarg"))
		{
			SI_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
			continue;
		}

		/* Warn about uninterpreted entries */
		warning("kernel '%s': unknown meta data entry '%s'",
			kernel->name, line_ptrs[0]);
	}
}