Exemplo n.º 1
0
/* Read context properties from a null-terminated sequence of
 * 'cl_context_properties' elements in guest memory */
void evg_opencl_context_set_properties(struct evg_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;
			evg_opencl_repo_get_object(evg_emu->opencl_repo, evg_opencl_object_platform, value);
			evg_opencl_debug("    property CL_CONTEXT_PLATFORM assigned: 0x%x\n", value);
			break;

		default:
			fatal("opencl_context_read_properties: invalid property (0x%x)\n", property);
		}
	}
}
Exemplo n.º 2
0
void evg_opencl_program_initialize_constant_buffers(struct evg_opencl_program_t *program)
{
	struct elf_file_t *elf_file;
	struct elf_symbol_t *elf_symbol;
	struct elf_buffer_t elf_buffer;
	struct evg_opencl_mem_t *mem;
	char symbol_name[MAX_STRING_SIZE];
	int i;

	elf_file = program->elf_file;

	/* We can't tell how many constant buffers exist in advance, but we
	 * know they should be enumerated, starting with '2'.  This loop
	 * searches until a constant buffer matching the format is not found. */
	for (i = 2; i < 25; i++) 
	{
		/* Create string of symbol name */
		sprintf(symbol_name, "__OpenCL_%d_global", i);

		/* Check to see if symbol exists */
		elf_symbol = elf_symbol_get_by_name(elf_file, symbol_name);
                if (elf_symbol == NULL) {

			break;
		}
		evg_opencl_debug("  constant buffer '%s' found with size %d\n",
			elf_symbol->name, elf_symbol->size);

		/* Read the elf symbol into a buffer */
		evg_opencl_program_read_symbol(program, elf_symbol->name, &elf_buffer);

		/* Create a memory object and copy the constant buffer data to it */
		mem = evg_opencl_mem_create();
		mem->type = 0;  /* FIXME */
		mem->size = elf_buffer.size;
		mem->flags = 0; /* TODO Change to CL_MEM_READ_ONLY */
		mem->host_ptr = 0;

		/* Assign position in device global memory */
		mem->device_ptr = evg_emu->global_mem_top;
		evg_emu->global_mem_top += mem->size;

		/* Copy constant buffer into device memory */
		mem_write(evg_emu->global_mem, mem->device_ptr, mem->size, elf_buffer.ptr);

		/* Add the memory object to the constant buffer list */
		list_set(program->constant_buffer_list, i, mem);
	}
} 
Exemplo n.º 3
0
int evg_opencl_command_queue_can_wakeup(struct x86_ctx_t *ctx, void *data)
{
	struct evg_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)
		evg_opencl_debug("\tcycle %lld - command queue 0x%x empty"
			" - context resumed\n", esim_cycle, command_queue->id);

	/* Return */
	return can_wakeup;
}
Exemplo n.º 4
0
static void evg_opencl_kernel_load_metadata(struct evg_opencl_kernel_t *kernel)
{
	char line[MAX_STRING_SIZE];
	char *line_ptrs[MAX_STRING_SIZE];
	int token_count;
	struct evg_opencl_kernel_arg_t *arg;
	struct elf_buffer_t *buffer;

	/* Open as text file */
	buffer = &kernel->metadata_buffer;
	elf_buffer_seek(buffer, 0);
	evg_opencl_debug("Kernel Metadata:\n"); 
	for (;;)
	{
		/* Read line from buffer */
		elf_buffer_read_line(buffer, line, MAX_STRING_SIZE);
		if (!line[0])
			break;
		evg_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], "ARGEND"))
			continue;

		/* Image */
		if (!strcmp(line_ptrs[0], "image"))
		{
			/* Create input image argument */
			arg = evg_opencl_kernel_arg_create(line_ptrs[1]);
			arg->kind = EVG_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], evg_err_opencl_param_note);
			}
			
			if (!strcmp(line_ptrs[3], "RO"))
			{
				arg->access_type = EVG_OPENCL_KERNEL_ARG_READ_ONLY;
			}
			else if (!strcmp(line_ptrs[3], "WO"))
			{
				arg->access_type = EVG_OPENCL_KERNEL_ARG_WRITE_ONLY;
			}
			else
			{
				fatal("%s: Invalid memory access type for OpenCL Image (%s)\n%s",
					__FUNCTION__, line_ptrs[3], evg_err_opencl_param_note);
			}
			arg->uav = atoi(line_ptrs[4]);
			arg->mem_scope = EVG_OPENCL_MEM_SCOPE_GLOBAL;

			list_add(kernel->arg_list, arg);

			continue;

		} 

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

			continue;
		}

		/* Entry 'value'. Format: value:<ArgName>:<DataType>:<Size>:<ConstNum>:<ConstOffset> */
		if (!strcmp(line_ptrs[0], "value"))
		{
			EVG_OPENCL_KERNEL_METADATA_TOKEN_COUNT(6);
			EVG_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(3, "1");
			EVG_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(4, "1");
			arg = evg_opencl_kernel_arg_create(line_ptrs[1]);
			arg->kind = EVG_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)
			{
				EVG_OPENCL_KERNEL_METADATA_TOKEN_COUNT(10);
			}
			EVG_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(3, "1");
			EVG_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)
			{
				EVG_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(10, "0");
				EVG_OPENCL_KERNEL_METADATA_NOT_SUPPORTED_NEQ(11, "0");
			}

			arg = evg_opencl_kernel_arg_create(line_ptrs[1]);
			arg->kind = EVG_OPENCL_KERNEL_ARG_KIND_POINTER;

			list_add(kernel->arg_list, arg);
			if (!strcmp(line_ptrs[6], "uav"))
			{
				arg->mem_scope = EVG_OPENCL_MEM_SCOPE_GLOBAL;
				arg->uav = atoi(line_ptrs[7]);
			}
			else if (!strcmp(line_ptrs[6], "hl"))
			{
				arg->mem_scope = EVG_OPENCL_MEM_SCOPE_LOCAL;
				arg->uav = atoi(line_ptrs[7]);
			}
			else if (!strcmp(line_ptrs[6], "hc"))
			{
				arg->mem_scope = EVG_OPENCL_MEM_SCOPE_CONSTANT;
				arg->uav = atoi(line_ptrs[7]);
			}
			else
				EVG_OPENCL_KERNEL_METADATA_NOT_SUPPORTED(6);

			continue;
		}

		/* Entry 'function'. Format: function:?:<uniqueid> */
		if (!strcmp(line_ptrs[0], "function"))
		{
			EVG_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
			EVG_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"))
		{
			EVG_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"))
		{
			EVG_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"))
		{
			EVG_OPENCL_KERNEL_METADATA_TOKEN_COUNT(3);
			continue;
		}

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