/* 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); } } }
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); } }
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; }
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]); } }