P4 to Git Change 2061101 by skudchad@skudchad_test2_win_opencl on 2020/01/21 16:47:25

SWDEV-219917 - [VDI Cleanup] Remove some direct OpenCL references, introduce a common functionality.

	ReviewBoardURL = http://ocltc.amd.com/reviews/r/18488/diff/

Affected files ...

... //depot/stg/opencl/drivers/opencl/api/hip/build/Makefile.hip#30 edit
... //depot/stg/opencl/drivers/opencl/api/hip/fixme.cpp#3 edit
... //depot/stg/opencl/drivers/opencl/api/hip/hip_internal.hpp#51 edit
... //depot/stg/opencl/drivers/opencl/api/hip/hiprtc_internal.hpp#3 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/build/Makefile.api#190 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_common.hpp#25 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_context.cpp#61 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_device.cpp#75 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_execute.cpp#31 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_icd.cpp#36 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_platform_amd.cpp#3 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_program.cpp#54 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.cpp#610 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.cpp#180 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#150 edit
... //depot/stg/opencl/drivers/opencl/runtime/include/vdi_agent_amd.h#1 add
... //depot/stg/opencl/drivers/opencl/runtime/include/vdi_common.hpp#1 add
... //depot/stg/opencl/drivers/opencl/runtime/os/os.hpp#32 edit
... //depot/stg/opencl/drivers/opencl/runtime/os/os_posix.cpp#49 edit
... //depot/stg/opencl/drivers/opencl/runtime/os/os_win32.cpp#50 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/agent.cpp#9 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/agent.hpp#7 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/context.cpp#54 edit
... //depot/stg/opencl/drivers/opencl/runtime/runtimedefs#54 edit


[ROCm/clr commit: 29dd0eb7a2]
Этот коммит содержится в:
foreman
2020-01-21 16:52:40 -05:00
родитель 46fa3c4e53
Коммит c56bbc1f40
11 изменённых файлов: 397 добавлений и 295 удалений
+1 -1
Просмотреть файл
@@ -21,7 +21,7 @@
#include "acl.h"
#include "amdocl/cl_common.hpp"
#include "vdi_common.hpp"
#include "CL/cl_gl.h"
#ifdef _WIN32
+1 -1
Просмотреть файл
@@ -21,7 +21,7 @@
#include "cz_id.h"
#include "acl.h"
#include "amdocl/cl_common.hpp"
#include "vdi_common.hpp"
#ifdef _WIN32
#include <d3d9.h>
+1 -1
Просмотреть файл
@@ -14,7 +14,7 @@
#include "thread/monitor.hpp"
#include "CL/cl_ext.h"
#include "amdocl/cl_common.hpp"
#include "vdi_common.hpp"
#include "device/rocm/rocdevice.hpp"
#include "device/rocm/rocblit.hpp"
#include "device/rocm/rocvirtual.hpp"
+171
Просмотреть файл
@@ -0,0 +1,171 @@
//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//
#ifndef _VDI_AGENT_AMD_H
#define _VDI_AGENT_AMD_H
#include <CL/cl.h>
#include "amdocl/cl_icd_amd.h"
#define cl_amd_agent 1
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef const struct _vdi_agent vdi_agent;
#define VDI_AGENT_VERSION_1_0 100
/* Context Callbacks */
typedef void(CL_CALLBACK* acContextCreate_fn)(vdi_agent* /* agent */, cl_context /* context */);
typedef void(CL_CALLBACK* acContextFree_fn)(vdi_agent* /* agent */, cl_context /* context */);
/* Command Queue Callbacks */
typedef void(CL_CALLBACK* acCommandQueueCreate_fn)(vdi_agent* /* agent */,
cl_command_queue /* queue */);
typedef void(CL_CALLBACK* acCommandQueueFree_fn)(vdi_agent* /* agent */,
cl_command_queue /* queue */);
/* Event Callbacks */
typedef void(CL_CALLBACK* acEventCreate_fn)(vdi_agent* /* agent */, cl_event /* event */,
cl_command_type /* type */);
typedef void(CL_CALLBACK* acEventFree_fn)(vdi_agent* /* agent */, cl_event /* event */);
typedef void(CL_CALLBACK* acEventStatusChanged_fn)(vdi_agent* /* agent */, cl_event /* event */,
cl_int /* execution_status */,
cl_long /* epoch_time_stamp */);
/* Memory Object Callbacks */
typedef void(CL_CALLBACK* acMemObjectCreate_fn)(vdi_agent* /* agent */, cl_mem /* memobj */);
typedef void(CL_CALLBACK* acMemObjectFree_fn)(vdi_agent* /* agent */, cl_mem /* memobj */);
typedef void(CL_CALLBACK* acMemObjectAcquired_fn)(vdi_agent* /* agent */, cl_mem /* memobj */,
cl_device_id /* device */,
cl_long /* elapsed_time */);
/* Sampler Callbacks */
typedef void(CL_CALLBACK* acSamplerCreate_fn)(vdi_agent* /* agent */, cl_sampler /* sampler */);
typedef void(CL_CALLBACK* acSamplerFree_fn)(vdi_agent* /* agent */, cl_sampler /* sampler */);
/* Program Callbacks */
typedef void(CL_CALLBACK* acProgramCreate_fn)(vdi_agent* /* agent */, cl_program /* program */);
typedef void(CL_CALLBACK* acProgramFree_fn)(vdi_agent* /* agent */, cl_program /* program */);
typedef void(CL_CALLBACK* acProgramBuild_fn)(vdi_agent* /* agent */, cl_program /* program */);
/* Kernel Callbacks */
typedef void(CL_CALLBACK* acKernelCreate_fn)(vdi_agent* /* agent */, cl_kernel /* kernel */);
typedef void(CL_CALLBACK* acKernelFree_fn)(vdi_agent* /* agent */, cl_kernel /* kernel */);
typedef void(CL_CALLBACK* acKernelSetArg_fn)(vdi_agent* /* agent */, cl_kernel /* kernel */,
cl_int /* arg_index */, size_t /* size */,
const void* /* value_ptr */);
typedef struct _vdi_agent_callbacks {
/* Context Callbacks */
acContextCreate_fn ContextCreate;
acContextFree_fn ContextFree;
/* Command Queue Callbacks */
acCommandQueueCreate_fn CommandQueueCreate;
acCommandQueueFree_fn CommandQueueFree;
/* Event Callbacks */
acEventCreate_fn EventCreate;
acEventFree_fn EventFree;
acEventStatusChanged_fn EventStatusChanged;
/* Memory Object Callbacks */
acMemObjectCreate_fn MemObjectCreate;
acMemObjectFree_fn MemObjectFree;
acMemObjectAcquired_fn MemObjectAcquired;
/* Sampler Callbacks */
acSamplerCreate_fn SamplerCreate;
acSamplerFree_fn SamplerFree;
/* Program Callbacks */
acProgramCreate_fn ProgramCreate;
acProgramFree_fn ProgramFree;
acProgramBuild_fn ProgramBuild;
/* Kernel Callbacks */
acKernelCreate_fn KernelCreate;
acKernelFree_fn KernelFree;
acKernelSetArg_fn KernelSetArg;
} vdi_agent_callbacks;
typedef cl_uint vdi_agent_capability_action;
#define VDI_AGENT_ADD_CAPABILITIES 0x0
#define VDI_AGENT_RELINQUISH_CAPABILITIES 0x1
typedef struct _vdi_agent_capabilities {
cl_bitfield canGenerateContextEvents : 1;
cl_bitfield canGenerateCommandQueueEvents : 1;
cl_bitfield canGenerateEventEvents : 1;
cl_bitfield canGenerateMemObjectEvents : 1;
cl_bitfield canGenerateSamplerEvents : 1;
cl_bitfield canGenerateProgramEvents : 1;
cl_bitfield canGenerateKernelEvents : 1;
} vdi_agent_capabilities;
struct _vdi_agent {
cl_int(CL_API_CALL* GetVersionNumber)(vdi_agent* /* agent */, cl_int* /* version_ret */);
cl_int(CL_API_CALL* GetPlatform)(vdi_agent* /* agent */, cl_platform_id* /* platform_id_ret */);
cl_int(CL_API_CALL* GetTime)(vdi_agent* /* agent */, cl_long* /* time_nanos */);
cl_int(CL_API_CALL* SetCallbacks)(vdi_agent* /* agent */,
const vdi_agent_callbacks* /* callbacks */, size_t /* size */);
cl_int(CL_API_CALL* GetPotentialCapabilities)(vdi_agent* /* agent */,
vdi_agent_capabilities* /* capabilities */);
cl_int(CL_API_CALL* GetCapabilities)(vdi_agent* /* agent */,
vdi_agent_capabilities* /* capabilities */);
cl_int(CL_API_CALL* SetCapabilities)(vdi_agent* /* agent */,
const vdi_agent_capabilities* /* capabilities */,
vdi_agent_capability_action /* action */);
cl_int(CL_API_CALL* GetICDDispatchTable)(vdi_agent* /* agent */,
cl_icd_dispatch_table* /* table */, size_t /* size */);
cl_int(CL_API_CALL* SetICDDispatchTable)(vdi_agent* /* agent */,
const cl_icd_dispatch_table* /* table */,
size_t /* size */);
/* add Kernel/Program helper functions, etc... */
};
extern cl_int CL_CALLBACK vdiAgent_OnLoad(vdi_agent* /* agent */);
extern void CL_CALLBACK vdiAgent_OnUnload(vdi_agent* /* agent */);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _VDI_AGENT_AMD_H */
+164
Просмотреть файл
@@ -0,0 +1,164 @@
/*
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef VDI_COMMON_HPP_
#define VDI_COMMON_HPP_
#include "top.hpp"
#include "platform/runtime.hpp"
#include "platform/command.hpp"
#include "platform/memory.hpp"
#include "thread/thread.hpp"
#include "platform/commandqueue.hpp"
#include <vector>
#include <utility>
//! \cond ignore
namespace amd {
template <typename T>
class NotNullWrapper
{
private:
T* const ptrOrNull_;
protected:
explicit NotNullWrapper(T* ptrOrNull)
: ptrOrNull_(ptrOrNull)
{ }
public:
void operator = (T value) const
{
if (ptrOrNull_ != NULL) {
*ptrOrNull_ = value;
}
}
};
template <typename T>
class NotNullReference : protected NotNullWrapper<T>
{
public:
explicit NotNullReference(T* ptrOrNull)
: NotNullWrapper<T>(ptrOrNull)
{ }
const NotNullWrapper<T>& operator * () const { return *this; }
};
} // namespace amd
template <typename T>
inline amd::NotNullReference<T>
not_null(T* ptrOrNull)
{
return amd::NotNullReference<T>(ptrOrNull);
}
#define VDI_CHECK_THREAD(thread) \
(thread != NULL || ((thread = new amd::HostThread()) != NULL \
&& thread == amd::Thread::current()))
#define RUNTIME_ENTRY_RET(ret, func, args) \
CL_API_ENTRY ret CL_API_CALL \
func args \
{ \
amd::Thread* thread = amd::Thread::current(); \
if (!VDI_CHECK_THREAD(thread)) { \
*not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; \
return (ret) 0; \
}
#define RUNTIME_ENTRY_RET_NOERRCODE(ret, func, args) \
CL_API_ENTRY ret CL_API_CALL \
func args \
{ \
amd::Thread* thread = amd::Thread::current(); \
if (!VDI_CHECK_THREAD(thread)) { \
return (ret) 0; \
}
#define RUNTIME_ENTRY(ret, func, args) \
CL_API_ENTRY ret CL_API_CALL \
func args \
{ \
amd::Thread* thread = amd::Thread::current(); \
if (!VDI_CHECK_THREAD(thread)) { \
return CL_OUT_OF_HOST_MEMORY; \
}
#define RUNTIME_ENTRY_VOID(ret, func, args) \
CL_API_ENTRY ret CL_API_CALL \
func args \
{ \
amd::Thread* thread = amd::Thread::current(); \
if (!VDI_CHECK_THREAD(thread)) { \
return; \
}
#define RUNTIME_EXIT \
/* FIXME_lmoriche: we should check to thread->lastError here! */ \
}
namespace amd {
namespace detail {
template <typename T>
struct ParamInfo
{
static inline std::pair<const void*, size_t> get(const T& param) {
return std::pair<const void*, size_t>(&param, sizeof(T));
}
};
template <>
struct ParamInfo<const char*>
{
static inline std::pair<const void*, size_t> get(const char* param) {
return std::pair<const void*, size_t>(param, strlen(param) + 1);
}
};
template <int N>
struct ParamInfo<char[N]>
{
static inline std::pair<const void*, size_t> get(const char* param) {
return std::pair<const void*, size_t>(param, strlen(param) + 1);
}
};
} // namespace detail
struct PlatformIDS { const struct KHRicdVendorDispatchRec* dispatch_; };
class PlatformID {
public:
static PlatformIDS Platform;
};
#define AMD_PLATFORM (reinterpret_cast<cl_platform_id>(&amd::PlatformID::Platform))
} // namespace amd
#endif /* _VDI_COMMON_H */
-2
Просмотреть файл
@@ -227,8 +227,6 @@ class Os : AllStatic {
static void unloadLibrary(void* handle);
//! Return the address of the function identified by \a name.
static void* getSymbol(void* handle, const char* name);
//! Get all the __kernel functions in the given shared library.
static bool iterateSymbols(void* handle, SymbolCallback func, void* data);
// Time routines:
//
+1 -90
Просмотреть файл
@@ -154,95 +154,6 @@ static void __exit() { Os::tearDown(); }
void Os::tearDown() { Thread::tearDown(); }
bool Os::iterateSymbols(void* handle, Os::SymbolCallback callback, void* data) {
const char magic[] = "__OpenCL_";
const size_t len = sizeof(magic) - 1;
struct link_map* link_map = NULL;
if (::dlinfo(handle, RTLD_DI_LINKMAP, &link_map) != 0) {
return false;
}
assert(link_map != NULL && "just checking");
const ElfW(Dyn)* dyn = (ElfW(Dyn)*)(link_map->l_ld);
const Elf32_Word* gnuhash = NULL;
const Elf_Symndx* hash = NULL;
const ElfW(Sym)* symbols = NULL;
const char* stringTable = NULL;
size_t tableSize = 0;
// Search for the string table address and size.
while (dyn->d_tag != DT_NULL) {
switch (dyn->d_tag) {
case DT_HASH:
hash = (Elf_Symndx*)dyn->d_un.d_ptr;
break;
case DT_GNU_HASH:
gnuhash = (Elf32_Word*)dyn->d_un.d_ptr;
break;
case DT_SYMTAB:
symbols = (ElfW(Sym)*)dyn->d_un.d_ptr;
break;
case DT_STRTAB:
stringTable = (const char*)dyn->d_un.d_ptr;
break;
case DT_STRSZ:
tableSize = dyn->d_un.d_val;
break;
default:
break;
}
++dyn;
}
if (stringTable == NULL || tableSize == 0 || symbols == NULL ||
(hash == NULL && gnuhash == NULL)) {
// Could not find the string table
return false;
}
if (gnuhash == NULL) {
// Read the defined symbols out of the classic SYSV hashtable.
Elf_Symndx nbuckets = hash[1];
for (Elf_Symndx i = 0; i < nbuckets; ++i) {
if (symbols[i].st_shndx == SHN_UNDEF && symbols[i].st_value == 0) {
continue;
}
const char* name = &stringTable[symbols[i].st_name];
if (::strncmp(name, magic, len) == 0) {
callback(name, (const void*)(link_map->l_addr + symbols[i].st_value), data);
}
}
return true;
}
// Read the defined symbols out of the GNU hashtable.
Elf_Symndx nbuckets = gnuhash[0];
Elf32_Word bias = gnuhash[1];
Elf32_Word nwords = gnuhash[2];
const Elf32_Word* buckets = &gnuhash[4 + __ELF_NATIVE_CLASS / 32 * nwords];
const Elf32_Word* chain0 = &buckets[nbuckets] - bias;
for (Elf_Symndx i = 0; i < nbuckets; ++i) {
size_t index = buckets[i];
const Elf32_Word* hasharr = &chain0[index];
do {
if (symbols[index].st_shndx != SHN_UNDEF || symbols[index].st_value != 0) {
const char* name = &stringTable[symbols[index].st_name];
if (::strncmp(name, magic, len) == 0) {
callback(name, (const void*)(link_map->l_addr + symbols[index].st_value), data);
}
}
++index;
} while ((*hasharr++ & 1) == 0);
}
return true;
}
void* Os::loadLibrary_(const char* filename) {
return (*filename == '\0') ? NULL : ::dlopen(filename, RTLD_LAZY);
}
@@ -354,7 +265,7 @@ void Os::alignedFree(void* mem) { ::free(mem); }
void Os::currentStackInfo(address* base, size_t* size) {
// There could be some issue trying to get the pthread_attr of
// the primordial thread if the pthread library is not present
// at load time (a binary loads the OpenCL app/runtime dynamically.
// at load time (a binary loads the OpenCL/HIP app/runtime dynamically.
// We should look into this... -laurent
pthread_t self = ::pthread_self();
-143
Просмотреть файл
@@ -80,149 +80,6 @@ __declspec(allocate(".CRT$XTU")) void (*__exit)(void) = Os::tearDown;
void Os::tearDown() { Thread::tearDown(); }
//#define DEBUG_getExportsFromMemory
/**
get export symbols from dll given by start address \param dosHeader
of dll in memory and push_back
addresses and names of exports into \param kernels
*/
static void getExportsFromMemory(PIMAGE_DOS_HEADER dosHeader, Os::SymbolCallback callback,
void* data) {
PCHAR base = (PCHAR)dosHeader;
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)(base + dosHeader->e_lfanew);
DWORD exportsStart =
pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
if (exportsStart == 0) {
return;
}
PIMAGE_EXPORT_DIRECTORY exportDir = (PIMAGE_EXPORT_DIRECTORY)(base + exportsStart);
PSTR filename = (PSTR)(exportDir->Name + base);
#if defined(DEBUG_getExportsFromMemory)
printf("\nExports Table:\n");
printf(" Name: %s\n", filename);
printf(" Characteristics: %08X\n", exportDir->Characteristics);
printf(" TimeDateStamp: %08X -> %s", exportDir->TimeDateStamp,
ctime((const time_t*)&exportDir->TimeDateStamp));
printf(" Version: %u.%02u\n", exportDir->MajorVersion, exportDir->MinorVersion);
printf(" Ordinal base: %08X\n", exportDir->Base);
printf(" # of functions: %08X\n", exportDir->NumberOfFunctions);
printf(" # of Names: %08X\n", exportDir->NumberOfNames);
#endif
/* address of Export Address table (EAT). */
PDWORD functions = (PDWORD)(base + (DWORD)exportDir->AddressOfFunctions);
DWORD numberOfFunctions = exportDir->NumberOfFunctions;
/* address of the Export Name Table (ENT).
ENT is an array of RVAs to ASCII strings - each string corresponds to
a symbol (function or variable) exported by name. */
DWORD* name = (DWORD*)(base + (DWORD)exportDir->AddressOfNames);
/* \note: number below is always <= numberOfFunctions */
DWORD numberOfNames = exportDir->NumberOfNames;
/* address of the Export Ordinal Table.
This table maps an array index from ENT into
the corresponding index in EAT.
*/
PWORD ordinals = (PWORD)(base + (DWORD)exportDir->AddressOfNameOrdinals);
#if defined(DEBUG_getExportsFromMemory)
/* \note On Ordinals and Algorithm Below.
Each exported symbol has an ordinal number associated with it that can
be used to look the exported symbol up. Also, there is almost always
an ASCII name associated with the symbol. Expectedly, the exported
symbol name is the same as the name of the function or variable, but
in general it is not guaranteed. Usually, when an executable imports
a symbol, it uses the symbol name rather than its ordinal. If it was
always a case the algorithm below could be much simple - just go over
all the names and print them, but some functions may be exported only
by ordinals. When importing by name, the system just uses the name to
look up the export ordinal of the desired symbol, and retrieves the
address using the ordinal value. It might be slightly faster if an
ordinal had been used in the first place. Exporting and importing by
name is solely a convenience for programmers.
The use of the ORDINAL keyword in the Exports section of a .DEF file
tells the linker to create an import library that forces an API to be
imported by ordinal, not by name.
The algorithm in the comments shows how to retrieve all the exports in
the general case. If we assume that all is exported by names then a
simple version (code below) is sufficient.
\note removed file exportdump.cpp contains examples of reading
exported symbols from DLL loaded in memory or file.
*/
DWORD exportsEnd = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
printf("\n Entry Pt Ordn Name\n");
for (DWORD ii = 0; ii < numberOfFunctions; ii++) {
DWORD entryPoint = functions[ii];
if (entryPoint == 0) { // Skip over gaps in exported function
continue; // ordinals (the entrypoint is 0 for
} // these functions).
printf(" %08X %4u", entryPoint, ii + exportDir->Base);
// Browse thru all names and check out if a function has
// an associated exported name.
for (DWORD jj = 0; jj < exportDir->NumberOfNames; jj++) {
if (ordinals[jj] == ii) {
printf(" %s", name[jj] + base);
}
}
// Is it a forwarder? If so, the entry point RVA is inside the
// .edata section, and is an RVA to the DllName.EntryPointName
if ((entryPoint >= exportsStart) && (entryPoint <= exportsEnd)) {
printf(" (forwarder -> %s)", entryPoint + base);
}
printf("\n");
}
#endif
char OpenCL_prefix[] = "___OpenCL_";
size_t OpenCL_prefix_sz = sizeof(OpenCL_prefix) - 1;
for (DWORD jj = 0; jj < numberOfNames; jj++) {
const char* OpenCL_name = (const char*)(base + name[jj]);
if (strncmp(OpenCL_name, OpenCL_prefix, OpenCL_prefix_sz) == 0) {
address addr = (address)(base + functions[ordinals[jj]]);
unsigned char opcode = *(unsigned char*)addr;
if (opcode == 0xE9) { // jmp instruction at address of export name
long disp = *(long*)(addr + 1); // dislacement in jmp
addr += 5 /* skip instruction */ + disp;
}
#if defined(DEBUG_getExportsFromMemory)
printf("%08X: %s\n", addr, OpenCL_name);
#endif
callback(&OpenCL_name[1], (const void*)addr, data);
} else if (strncmp(OpenCL_name, &OpenCL_prefix[1], OpenCL_prefix_sz - 1) == 0) {
address addr = (address)(base + functions[ordinals[jj]]);
#if defined(DEBUG_getExportsFromMemory)
printf("%08X: %s\n", addr, OpenCL_name);
#endif
callback(OpenCL_name, (const void*)addr, data);
}
}
}
bool Os::iterateSymbols(void* handle, SymbolCallback callback, void* data) {
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)handle;
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
// checking validity of NT header was removed since we do not want
// exception handling. It can be found in rev #21.
getExportsFromMemory((PIMAGE_DOS_HEADER)handle, callback, data);
return TRUE;
}
return FALSE;
}
void* Os::loadLibrary_(const char* filename) {
if (filename != NULL) {
HMODULE hModule = ::LoadLibrary(filename);
+45 -44
Просмотреть файл
@@ -5,7 +5,8 @@
#include "platform/agent.hpp"
#include "platform/object.hpp"
#include "os/os.hpp"
#include "amdocl/cl_common.hpp"
#include "vdi_agent_amd.h"
#include "vdi_common.hpp"
#include <cstdlib>
#include <cstring>
@@ -15,8 +16,8 @@
namespace amd {
typedef cl_int(CL_CALLBACK* clAgent_OnLoad_fn)(cl_agent* agent);
typedef void(CL_CALLBACK* clAgent_OnUnload_fn)(cl_agent* agent);
typedef cl_int(CL_CALLBACK* vdiAgent_OnLoad_fn)(vdi_agent* agent);
typedef void(CL_CALLBACK* vdiAgent_OnUnload_fn)(vdi_agent* agent);
Agent::Agent(const char* moduleName) : ready_(false) {
::memset(&callbacks_, '\0', sizeof(callbacks_));
@@ -27,13 +28,13 @@ Agent::Agent(const char* moduleName) : ready_(false) {
return;
}
clAgent_OnLoad_fn onLoad =
reinterpret_cast<clAgent_OnLoad_fn>(Os::getSymbol(library_, "clAgent_OnLoad"));
vdiAgent_OnLoad_fn onLoad =
reinterpret_cast<vdiAgent_OnLoad_fn>(Os::getSymbol(library_, "vdiAgent_OnLoad"));
if (onLoad == NULL) {
return;
}
_cl_agent* agent = static_cast<_cl_agent*>(this);
_vdi_agent* agent = static_cast<_vdi_agent*>(this);
::memcpy(agent, &entryPoints_, sizeof(entryPoints_));
// Register in the agents linked-list.
@@ -50,24 +51,24 @@ Agent::Agent(const char* moduleName) : ready_(false) {
Agent::~Agent() {
if (library_ != NULL) {
clAgent_OnUnload_fn onUnload =
reinterpret_cast<clAgent_OnUnload_fn>(Os::getSymbol(library_, "clAgent_OnUnload"));
vdiAgent_OnUnload_fn onUnload =
reinterpret_cast<vdiAgent_OnUnload_fn>(Os::getSymbol(library_, "vdiAgent_OnUnload"));
if (onUnload != NULL) {
onUnload(static_cast<cl_agent*>(this));
onUnload(static_cast<vdi_agent*>(this));
}
Os::unloadLibrary(library_);
}
}
cl_int Agent::setCallbacks(const cl_agent_callbacks* callbacks, size_t size) {
cl_int Agent::setCallbacks(const vdi_agent_callbacks* callbacks, size_t size) {
// FIXME_lmoriche: check size
memcpy(&callbacks_, callbacks, size);
return CL_SUCCESS;
}
cl_int Agent::getCapabilities(cl_agent_capabilities* caps) {
cl_int Agent::getCapabilities(vdi_agent_capabilities* caps) {
if (caps == NULL) {
return CL_INVALID_VALUE;
}
@@ -75,50 +76,50 @@ cl_int Agent::getCapabilities(cl_agent_capabilities* caps) {
return CL_SUCCESS;
}
static inline cl_agent_capabilities operator~(const cl_agent_capabilities& src) {
cl_agent_capabilities result;
static inline vdi_agent_capabilities operator~(const vdi_agent_capabilities& src) {
vdi_agent_capabilities result;
const char* a = reinterpret_cast<const char*>(&src);
char* b = reinterpret_cast<char*>(&result);
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
for (size_t i = 0; i < sizeof(vdi_agent_capabilities); ++i) {
*b++ = ~*a++;
}
return result;
}
static inline cl_agent_capabilities operator|(const cl_agent_capabilities& lhs,
const cl_agent_capabilities& rhs) {
cl_agent_capabilities result;
static inline vdi_agent_capabilities operator|(const vdi_agent_capabilities& lhs,
const vdi_agent_capabilities& rhs) {
vdi_agent_capabilities result;
const char* a = reinterpret_cast<const char*>(&lhs);
const char* b = reinterpret_cast<const char*>(&rhs);
char* c = reinterpret_cast<char*>(&result);
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
for (size_t i = 0; i < sizeof(vdi_agent_capabilities); ++i) {
*c++ = *a++ | *b++;
}
return result;
}
static inline cl_agent_capabilities operator&(const cl_agent_capabilities& lhs,
const cl_agent_capabilities& rhs) {
cl_agent_capabilities result;
static inline vdi_agent_capabilities operator&(const vdi_agent_capabilities& lhs,
const vdi_agent_capabilities& rhs) {
vdi_agent_capabilities result;
const char* a = reinterpret_cast<const char*>(&lhs);
const char* b = reinterpret_cast<const char*>(&rhs);
char* c = reinterpret_cast<char*>(&result);
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
for (size_t i = 0; i < sizeof(vdi_agent_capabilities); ++i) {
*c++ = *a++ & *b++;
}
return result;
}
static inline bool operator==(const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs) {
static inline bool operator==(const vdi_agent_capabilities& lhs, const vdi_agent_capabilities& rhs) {
const char* a = reinterpret_cast<const char*>(&lhs);
const char* b = reinterpret_cast<const char*>(&rhs);
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
for (size_t i = 0; i < sizeof(vdi_agent_capabilities); ++i) {
if (*a++ != *b++) {
return false;
}
@@ -127,11 +128,11 @@ static inline bool operator==(const cl_agent_capabilities& lhs, const cl_agent_c
return true;
}
static inline bool operator!=(const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs) {
static inline bool operator!=(const vdi_agent_capabilities& lhs, const vdi_agent_capabilities& rhs) {
return !(lhs == rhs);
}
cl_int Agent::setCapabilities(const cl_agent_capabilities* caps, bool install) {
cl_int Agent::setCapabilities(const vdi_agent_capabilities* caps, bool install) {
ScopedLock sl(capabilitiesLock_);
if (caps == NULL || *caps != (*caps & potentialCapabilities_)) {
@@ -162,7 +163,7 @@ bool Agent::init() {
// potentialCapabilities_.canGenerateProgramEvents = 1;
// potentialCapabilities_.canGenerateKernelEvents = 1;
const char* envVar = ::getenv("CL_AGENT");
const char* envVar = ::getenv("VDI_AGENT");
if (envVar == NULL) {
return true;
}
@@ -194,15 +195,15 @@ void Agent::tearDown() {
namespace agent {
static cl_int CL_API_CALL GetVersionNumber(cl_agent* agent, cl_int* version_ret) {
static cl_int CL_API_CALL GetVersionNumber(vdi_agent* agent, cl_int* version_ret) {
if (version_ret == NULL) {
return CL_INVALID_VALUE;
}
*version_ret = CL_AGENT_VERSION_1_0;
*version_ret = VDI_AGENT_VERSION_1_0;
return CL_SUCCESS;
}
static cl_int CL_API_CALL GetPlatform(cl_agent* agent, cl_platform_id* platform_id_ret) {
static cl_int CL_API_CALL GetPlatform(vdi_agent* agent, cl_platform_id* platform_id_ret) {
if (platform_id_ret == NULL) {
return CL_INVALID_VALUE;
}
@@ -210,7 +211,7 @@ static cl_int CL_API_CALL GetPlatform(cl_agent* agent, cl_platform_id* platform_
return CL_SUCCESS;
}
static cl_int CL_API_CALL GetTime(cl_agent* agent, cl_long* time_nanos) {
static cl_int CL_API_CALL GetTime(vdi_agent* agent, cl_long* time_nanos) {
if (time_nanos == NULL) {
return CL_INVALID_VALUE;
}
@@ -218,13 +219,13 @@ static cl_int CL_API_CALL GetTime(cl_agent* agent, cl_long* time_nanos) {
return CL_SUCCESS;
}
static cl_int CL_API_CALL SetCallbacks(cl_agent* agent, const cl_agent_callbacks* callbacks,
static cl_int CL_API_CALL SetCallbacks(vdi_agent* agent, const vdi_agent_callbacks* callbacks,
size_t size) {
return Agent::get(agent)->setCallbacks(callbacks, size);
}
static cl_int CL_API_CALL GetPotentialCapabilities(cl_agent* agent,
cl_agent_capabilities* capabilities) {
static cl_int CL_API_CALL GetPotentialCapabilities(vdi_agent* agent,
vdi_agent_capabilities* capabilities) {
if (capabilities == NULL) {
return CL_INVALID_VALUE;
}
@@ -233,24 +234,24 @@ static cl_int CL_API_CALL GetPotentialCapabilities(cl_agent* agent,
return CL_SUCCESS;
}
static cl_int CL_API_CALL GetCapabilities(cl_agent* agent, cl_agent_capabilities* capabilities) {
static cl_int CL_API_CALL GetCapabilities(vdi_agent* agent, vdi_agent_capabilities* capabilities) {
return Agent::get(agent)->getCapabilities(capabilities);
}
static cl_int CL_API_CALL SetCapabilities(cl_agent* agent,
const cl_agent_capabilities* capabilities,
cl_agent_capability_action action) {
return Agent::get(agent)->setCapabilities(capabilities, action == CL_AGENT_ADD_CAPABILITIES);
static cl_int CL_API_CALL SetCapabilities(vdi_agent* agent,
const vdi_agent_capabilities* capabilities,
vdi_agent_capability_action action) {
return Agent::get(agent)->setCapabilities(capabilities, action == VDI_AGENT_ADD_CAPABILITIES);
}
static cl_int CL_API_CALL GetICDDispatchTable(cl_agent* agent, cl_icd_dispatch_table* table,
static cl_int CL_API_CALL GetICDDispatchTable(vdi_agent* agent, cl_icd_dispatch_table* table,
size_t size) {
// FIXME_lmoriche: check size
memcpy(table, amd::ICDDispatchedObject::icdVendorDispatch_, size);
return CL_SUCCESS;
}
static cl_int CL_API_CALL SetICDDispatchTable(cl_agent* agent, const cl_icd_dispatch_table* table,
static cl_int CL_API_CALL SetICDDispatchTable(vdi_agent* agent, const cl_icd_dispatch_table* table,
size_t size) {
// FIXME_lmoriche: check size
memcpy(amd::ICDDispatchedObject::icdVendorDispatch_, table, size);
@@ -259,7 +260,7 @@ static cl_int CL_API_CALL SetICDDispatchTable(cl_agent* agent, const cl_icd_disp
} // namespace agent
cl_agent Agent::entryPoints_ = {agent::GetVersionNumber,
vdi_agent Agent::entryPoints_ = {agent::GetVersionNumber,
agent::GetPlatform,
agent::GetTime,
agent::SetCallbacks,
@@ -433,7 +434,7 @@ void Agent::postKernelSetArg(cl_kernel kernel, cl_int index, size_t size, const
Agent* Agent::list_ = NULL;
Monitor Agent::capabilitiesLock_;
cl_agent_capabilities Agent::enabledCapabilities_ = {0};
cl_agent_capabilities Agent::potentialCapabilities_ = {0};
vdi_agent_capabilities Agent::enabledCapabilities_ = {0};
vdi_agent_capabilities Agent::potentialCapabilities_ = {0};
} // namespace amd
+12 -12
Просмотреть файл
@@ -8,20 +8,20 @@
#include "top.hpp"
#include "thread/monitor.hpp"
#include "amdocl/cl_agent_amd.h"
#include "vdi_agent_amd.h"
namespace amd {
class Agent : public _cl_agent {
class Agent : public _vdi_agent {
private:
//! Linked list of agent instances
static Agent* list_;
//! Agent API entry points
static cl_agent entryPoints_;
static vdi_agent entryPoints_;
//! Capabilities supported by this Agent implementation
static cl_agent_capabilities potentialCapabilities_;
static vdi_agent_capabilities potentialCapabilities_;
//! Union of all agent's enabled capabilities
static cl_agent_capabilities enabledCapabilities_;
static vdi_agent_capabilities enabledCapabilities_;
//! Monitor to protect the global capabilities
static Monitor capabilitiesLock_;
@@ -31,7 +31,7 @@ class Agent : public _cl_agent {
//! Teardown the agent.
static void tearDown();
//! Return the capabilities supported by this agent.
static cl_agent_capabilities potentialCapabilities() { return potentialCapabilities_; }
static vdi_agent_capabilities potentialCapabilities() { return potentialCapabilities_; }
#define AGENT_FLAG(name) \
inline static bool shouldPost##name() { return enabledCapabilities_.canGenerate##name != 0; }
@@ -97,9 +97,9 @@ class Agent : public _cl_agent {
bool ready_; //!< Is this instance ready?
//! Callbacks vector.
cl_agent_callbacks callbacks_;
vdi_agent_callbacks callbacks_;
//! Capabilities for this agent.
cl_agent_capabilities capabilities_;
vdi_agent_capabilities capabilities_;
#define AGENT_FLAG(name) \
inline bool canGenerate##name() { return capabilities_.canGenerate##name != 0; }
@@ -124,15 +124,15 @@ class Agent : public _cl_agent {
bool isReady() const { return ready_; }
//! Set the callback vector for this agent
cl_int setCallbacks(const cl_agent_callbacks* callbacks, size_t size);
cl_int setCallbacks(const vdi_agent_callbacks* callbacks, size_t size);
//! Return the current capabilities.
cl_int getCapabilities(cl_agent_capabilities* caps);
cl_int getCapabilities(vdi_agent_capabilities* caps);
//! Set the current capabilities.
cl_int setCapabilities(const cl_agent_capabilities* caps, bool install);
cl_int setCapabilities(const vdi_agent_capabilities* caps, bool install);
//! Return the Agent instance from the given cl_agent
inline static Agent* get(cl_agent* agent) {
inline static Agent* get(vdi_agent* agent) {
return const_cast<Agent*>(static_cast<const Agent*>(agent));
}
};
+1 -1
Просмотреть файл
@@ -4,7 +4,7 @@
#include "platform/context.hpp"
#include "amdocl/cl_gl_amd.hpp"
#include "amdocl/cl_common.hpp"
#include "vdi_common.hpp"
#include "platform/commandqueue.hpp"
#include <algorithm>