Implement new load map API.
Change-Id: I5f148fe66f899b2fa6a2e75430afa988f38db58d
[ROCm/ROCR-Runtime commit: 0e4cab3001]
Tá an tiomantas seo le fáil i:
@@ -133,6 +133,7 @@ set ( CORE_SRCS ${CORE_SRCS} runtime/amd_gpu_agent.cpp )
|
||||
set ( CORE_SRCS ${CORE_SRCS} runtime/amd_aql_queue.cpp )
|
||||
set ( CORE_SRCS ${CORE_SRCS} runtime/amd_loader_context.cpp )
|
||||
set ( CORE_SRCS ${CORE_SRCS} runtime/hsa_ven_amd_loaded_code_object.cpp )
|
||||
set ( CORE_SRCS ${CORE_SRCS} runtime/hsa_ven_amd_loader.cpp )
|
||||
set ( CORE_SRCS ${CORE_SRCS} runtime/amd_memory_region.cpp )
|
||||
set ( CORE_SRCS ${CORE_SRCS} runtime/amd_topology.cpp )
|
||||
set ( CORE_SRCS ${CORE_SRCS} runtime/default_signal.cpp )
|
||||
|
||||
@@ -103,6 +103,7 @@ namespace amd {
|
||||
virtual uint64_t imageSize() const = 0;
|
||||
virtual uint64_t vaddr() const = 0;
|
||||
virtual uint64_t flags() const = 0;
|
||||
virtual uint64_t offset() const = 0;
|
||||
virtual const char* data() const = 0;
|
||||
virtual uint16_t getSegmentIndex() = 0;
|
||||
virtual bool updateAddSection(Section *section) = 0;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <cstdint>
|
||||
#include "hsa.h"
|
||||
#include "hsa_ext_image.h"
|
||||
#include "hsa_ven_amd_loader.h"
|
||||
#include "amd_hsa_elf.h"
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
@@ -317,6 +318,13 @@ public:
|
||||
void *data),
|
||||
void *data) = 0;
|
||||
|
||||
virtual size_t GetNumSegmentDescriptors() = 0;
|
||||
|
||||
virtual size_t QuerySegmentDescriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t total_num_segment_descriptors,
|
||||
size_t first_empty_segment_descriptor) = 0;
|
||||
|
||||
virtual uint64_t FindHostAddress(uint64_t device_address) = 0;
|
||||
|
||||
virtual void Print(std::ostream& out) = 0;
|
||||
@@ -368,6 +376,11 @@ public:
|
||||
void *data),
|
||||
void *data) = 0;
|
||||
|
||||
/// @brief same as hsa_ven_amd_loader_query_segment_descriptors.
|
||||
virtual hsa_status_t QuerySegmentDescriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t *num_segment_descriptors) = 0;
|
||||
|
||||
/// @brief Returns host address given @p device_address. If @p device_address
|
||||
/// is already host address, returns null pointer. If @p device_address is
|
||||
/// invalid address, returns null pointer.
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "core/inc/interrupt_signal.h"
|
||||
#include "core/inc/amd_loader_context.hpp"
|
||||
#include "inc/hsa_ven_amd_loaded_code_object.h"
|
||||
#include "inc/hsa_ven_amd_loader.h"
|
||||
|
||||
using namespace amd::hsa::code;
|
||||
|
||||
@@ -168,9 +169,7 @@ hsa_status_t
|
||||
uint16_t version_minor, bool* result) {
|
||||
IS_OPEN();
|
||||
|
||||
if ((extension > HSA_EXTENSION_AMD_PROFILER &&
|
||||
extension != HSA_EXTENSION_AMD_LOADED_CODE_OBJECT) ||
|
||||
(result == NULL)) {
|
||||
if (extension >= HSA_EXTENSION_COUNT || result == NULL) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@@ -213,9 +212,6 @@ hsa_status_t
|
||||
}
|
||||
|
||||
if (supported) {
|
||||
ExtTable& runtime_ext_table =
|
||||
core::Runtime::runtime_singleton_->extensions_.table;
|
||||
|
||||
if (extension == HSA_EXTENSION_IMAGES) {
|
||||
// Currently there is only version 1.00.
|
||||
hsa_ext_images_1_00_pfn_t* ext_table =
|
||||
@@ -253,6 +249,14 @@ hsa_status_t
|
||||
hsa_ven_amd_loaded_code_object_query_host_address;
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
} else if (extension == HSA_EXTENSION_AMD_LOADER) {
|
||||
// Currently there is only version 1.00.
|
||||
hsa_ven_amd_loader_1_00_pfn_t* ext_table =
|
||||
reinterpret_cast<hsa_ven_amd_loader_1_00_pfn_t*>(table);
|
||||
ext_table->hsa_ven_amd_loader_query_segment_descriptors =
|
||||
hsa_ven_amd_loader_query_segment_descriptors;
|
||||
ext_table->hsa_ven_amd_loader_query_host_address =
|
||||
hsa_ven_amd_loader_query_host_address;
|
||||
} else {
|
||||
return HSA_STATUS_ERROR;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The University of Illinois/NCSA
|
||||
// Open Source License (NCSA)
|
||||
//
|
||||
// Copyright (c) 2014-2015, Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Developed by:
|
||||
//
|
||||
// AMD Research and AMD HSA Software Development
|
||||
//
|
||||
// Advanced Micro Devices, Inc.
|
||||
//
|
||||
// www.amd.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal with 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:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimers.
|
||||
// - Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimers in
|
||||
// the documentation and/or other materials provided with the distribution.
|
||||
// - Neither the names of Advanced Micro Devices, Inc,
|
||||
// nor the names of its contributors may be used to endorse or promote
|
||||
// products derived from this Software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// 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 CONTRIBUTORS 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 WITH THE SOFTWARE.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsa_ven_amd_loader.h"
|
||||
|
||||
#include "core/inc/amd_hsa_loader.hpp"
|
||||
#include "core/inc/runtime.h"
|
||||
|
||||
using namespace core;
|
||||
|
||||
hsa_status_t HSA_API hsa_ven_amd_loader_query_segment_descriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t *num_segment_descriptors) {
|
||||
if (false == core::Runtime::runtime_singleton_->IsOpen()) {
|
||||
return HSA_STATUS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
// Arguments are checked by the loader.
|
||||
return Runtime::runtime_singleton_->loader()->QuerySegmentDescriptors(segment_descriptors, num_segment_descriptors);
|
||||
}
|
||||
|
||||
hsa_status_t HSA_API hsa_ven_amd_loader_query_host_address(
|
||||
const void *device_address,
|
||||
const void **host_address) {
|
||||
if (false == core::Runtime::runtime_singleton_->IsOpen()) {
|
||||
return HSA_STATUS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (nullptr == device_address) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (nullptr == host_address) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
uint64_t udaddr = reinterpret_cast<uint64_t>(device_address);
|
||||
uint64_t uhaddr = Runtime::runtime_singleton_->loader()->FindHostAddress(udaddr);
|
||||
if (0 == uhaddr) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
*host_address = reinterpret_cast<void*>(uhaddr);
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -462,9 +462,17 @@ typedef enum {
|
||||
*/
|
||||
HSA_EXTENSION_AMD_PROFILER = 2,
|
||||
/**
|
||||
* Loaded code object extension.
|
||||
* @deprecated Loaded code object extension.
|
||||
*/
|
||||
HSA_EXTENSION_AMD_LOADED_CODE_OBJECT = 3
|
||||
HSA_EXTENSION_AMD_LOADED_CODE_OBJECT = 3,
|
||||
/**
|
||||
* Loader extension.
|
||||
*/
|
||||
HSA_EXTENSION_AMD_LOADER = 4,
|
||||
/**
|
||||
* Extension count.
|
||||
*/
|
||||
HSA_EXTENSION_COUNT
|
||||
} hsa_extension_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The University of Illinois/NCSA
|
||||
// Open Source License (NCSA)
|
||||
//
|
||||
// Copyright (c) 2014-2015, Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Developed by:
|
||||
//
|
||||
// AMD Research and AMD HSA Software Development
|
||||
//
|
||||
// Advanced Micro Devices, Inc.
|
||||
//
|
||||
// www.amd.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal with 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:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimers.
|
||||
// - Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimers in
|
||||
// the documentation and/or other materials provided with the distribution.
|
||||
// - Neither the names of Advanced Micro Devices, Inc,
|
||||
// nor the names of its contributors may be used to endorse or promote
|
||||
// products derived from this Software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// 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 CONTRIBUTORS 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 WITH THE SOFTWARE.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// HSA AMD extension for additional loader functionality.
|
||||
|
||||
#ifndef HSA_VEN_AMD_LOADER_H
|
||||
#define HSA_VEN_AMD_LOADER_H
|
||||
|
||||
#include "hsa.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @brief The storage type of the code object that is backing loaded memory
|
||||
* segment.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* Loaded memory segment is not backed by any code object (anonymous), as the
|
||||
* case would be with BSS (uninitialized data).
|
||||
*/
|
||||
HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE = 0,
|
||||
/**
|
||||
* Loaded memory segment is backed by the code object that is stored in the
|
||||
* file.
|
||||
*/
|
||||
HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE = 1,
|
||||
/**
|
||||
* Loaded memory segment is backed by the code object that is stored in the
|
||||
* memory.
|
||||
*/
|
||||
HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY = 2
|
||||
} hsa_ven_amd_loader_code_object_storage_type_t;
|
||||
|
||||
/**
|
||||
* @brief Loaded memory segment descriptor.
|
||||
*
|
||||
*
|
||||
* @details Loaded memory segment descriptor describes underlying loaded memory
|
||||
* segment. Loaded memory segment is created/allocated by the executable during
|
||||
* the loading of the code object that is backing underlying memory segment.
|
||||
*
|
||||
* The lifetime of underlying memory segment is limited by the lifetime of the
|
||||
* executable that is managing underlying memory segment.
|
||||
*/
|
||||
typedef struct hsa_ven_amd_loader_segment_descriptor_s {
|
||||
/**
|
||||
* Agent underlying memory segment is allocated on. If the code object that is
|
||||
* backing underlying memory segment is program code object, then 0.
|
||||
*/
|
||||
hsa_agent_t agent;
|
||||
/**
|
||||
* Executable that is managing this underlying memory segment.
|
||||
*/
|
||||
hsa_executable_t executable;
|
||||
/**
|
||||
* Storage type of the code object that is backing underlying memory segment.
|
||||
*/
|
||||
hsa_ven_amd_loader_code_object_storage_type_t code_object_storage_type;
|
||||
/**
|
||||
* If the storage type of the code object that is backing underlying memory
|
||||
* segment is:
|
||||
* - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE, then null;
|
||||
* - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE, then null-terminated
|
||||
* filepath to the code object;
|
||||
* - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY, then host
|
||||
* accessible pointer to the first byte of the code object.
|
||||
*/
|
||||
const void *code_object_storage_base;
|
||||
/**
|
||||
* If the storage type of the code object that is backing underlying memory
|
||||
* segment is:
|
||||
* - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE, then 0;
|
||||
* - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE, then the length of
|
||||
* the filepath to the code object (including null-terminating character);
|
||||
* - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY, then the size, in
|
||||
* bytes, of the memory occupied by the code object.
|
||||
*/
|
||||
size_t code_object_storage_size;
|
||||
/**
|
||||
* If the storage type of the code object that is backing underlying memory
|
||||
* segment is:
|
||||
* - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE, then 0;
|
||||
* - other, then offset, in bytes, from the beginning of the code object to
|
||||
* the first byte in the code object data is copied from.
|
||||
*/
|
||||
size_t code_object_storage_offset;
|
||||
/**
|
||||
* Starting address of the underlying memory segment.
|
||||
*/
|
||||
const void *segment_base;
|
||||
/**
|
||||
* Size, in bytes, of the underlying memory segment.
|
||||
*/
|
||||
size_t segment_size;
|
||||
} hsa_ven_amd_loader_segment_descriptor_t;
|
||||
|
||||
/**
|
||||
* @brief Either queries loaded memory segment descriptors, or total number of
|
||||
* loaded memory segment descriptors.
|
||||
*
|
||||
*
|
||||
* @details If @p segment_descriptors is not null and @p num_segment_descriptors
|
||||
* points to number that exactly matches total number of loaded memory segment
|
||||
* descriptors, then queries loaded memory segment descriptors, and records them
|
||||
* in @p segment_descriptors. If @p segment_descriptors is null and @p
|
||||
* num_segment_descriptors points to zero, then queries total number of loaded
|
||||
* memory segment descriptors, and records it in @p num_segment_descriptors. In
|
||||
* all other cases returns appropriate error code (see below).
|
||||
*
|
||||
* The caller of this function is responsible for the allocation/deallocation
|
||||
* and the lifetime of @p segment_descriptors and @p num_segment_descriptors.
|
||||
*
|
||||
* The lifetime of loaded memory segments that are described by queried loaded
|
||||
* memory segment descriptors is limited by the lifetime of the executable that
|
||||
* is managing loaded memory segments.
|
||||
*
|
||||
* Queried loaded memory segment descriptors are always self-consistent: they
|
||||
* describe a complete set of loaded memory segments that are being backed by
|
||||
* fully loaded code objects that are present at the time (i.e. this function
|
||||
* is blocked until all executable manipulations are fully complete).
|
||||
*
|
||||
*
|
||||
* @param[out] segment_descriptors Pointer to application-allocated buffer to
|
||||
* record queried loaded memory segment descriptors in. Can be null if @p
|
||||
* num_segment_descriptors points to zero.
|
||||
*
|
||||
* @param[in,out] num_segment_descriptors Pointer to application-allocated
|
||||
* buffer that contains either total number of loaded memory segment descriptors
|
||||
* or zero.
|
||||
*
|
||||
*
|
||||
* @retval HSA_STATUS_SUCCESS Function is executed successfully.
|
||||
*
|
||||
* @retval HSA_STATUS_ERROR_NOT_INITIALIZED Runtime is not initialized.
|
||||
*
|
||||
* @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p segment_descriptors is null
|
||||
* while @p num_segment_descriptors points to non-zero number, @p
|
||||
* segment_descriptors is not null while @p num_segment_descriptors points to
|
||||
* zero, or @p num_segment_descriptors is null.
|
||||
*
|
||||
* @retval HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS @p num_segment_descriptors
|
||||
* does not point to number that exactly matches total number of loaded memory
|
||||
* segment descriptors.
|
||||
*/
|
||||
hsa_status_t HSA_API hsa_ven_amd_loader_query_segment_descriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t *num_segment_descriptors);
|
||||
|
||||
/**
|
||||
* @brief Queries equivalent host address for given @p device_address, and
|
||||
* records it in @p host_address.
|
||||
*
|
||||
*
|
||||
* @details Contents of memory pointed to by @p host_address would be identical
|
||||
* to contents of memory pointed to by @p device_address. Only difference
|
||||
* between the two is host accessibility: @p host_address is always accessible
|
||||
* from host, @p device_address might not be accessible from host.
|
||||
*
|
||||
* If @p device_address already points to host accessible memory, then the value
|
||||
* of @p device_address is simply copied into @p host_address.
|
||||
*
|
||||
* The lifetime of @p host_address is the same as the lifetime of @p
|
||||
* device_address, and both lifetimes are limited by the lifetime of the
|
||||
* executable that is managing these addresses.
|
||||
*
|
||||
*
|
||||
* @param[in] device_address Device address to query equivalent host address
|
||||
* for.
|
||||
*
|
||||
* @param[out] host_address Pointer to application-allocated buffer to record
|
||||
* queried equivalent host address in.
|
||||
*
|
||||
*
|
||||
* @retval HSA_STATUS_SUCCESS Function is executed successfully.
|
||||
*
|
||||
* @retval HSA_STATUS_ERROR_NOT_INITIALIZED Runtime is not initialized.
|
||||
*
|
||||
* @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p device_address is invalid or
|
||||
* null, or @p host_address is null.
|
||||
*/
|
||||
hsa_status_t HSA_API hsa_ven_amd_loader_query_host_address(
|
||||
const void *device_address,
|
||||
const void **host_address);
|
||||
|
||||
/**
|
||||
* @brief Extension version.
|
||||
*/
|
||||
#define hsa_ven_amd_loader 001000
|
||||
|
||||
/**
|
||||
* @brief Extension function table.
|
||||
*/
|
||||
typedef struct hsa_ven_amd_loader_1_00_pfn_s {
|
||||
hsa_status_t (*hsa_ven_amd_loader_query_segment_descriptors)(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t *num_segment_descriptors);
|
||||
|
||||
hsa_status_t (*hsa_ven_amd_loader_query_host_address)(
|
||||
const void *device_address,
|
||||
const void **host_address);
|
||||
} hsa_ven_amd_loader_1_00_pfn_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HSA_VEN_AMD_LOADER_H */
|
||||
@@ -456,6 +456,7 @@ namespace amd {
|
||||
uint64_t imageSize() const override { return phdr.p_filesz; }
|
||||
uint64_t vaddr() const override { return phdr.p_vaddr; }
|
||||
uint64_t flags() const override { return phdr.p_flags; }
|
||||
uint64_t offset() const override { return phdr.p_offset; }
|
||||
const char* data() const override;
|
||||
uint16_t getSegmentIndex() override;
|
||||
bool updateAddSection(Section *section) override;
|
||||
|
||||
@@ -137,7 +137,7 @@ void Loader::Destroy(Loader *loader)
|
||||
Executable* AmdHsaCodeLoader::CreateExecutable(
|
||||
hsa_profile_t profile, const char *options)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(executables_mutex);
|
||||
WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);
|
||||
|
||||
executables.push_back(new ExecutableImpl(profile, context, executables.size()));
|
||||
return executables.back();
|
||||
@@ -145,7 +145,8 @@ Executable* AmdHsaCodeLoader::CreateExecutable(
|
||||
|
||||
void AmdHsaCodeLoader::DestroyExecutable(Executable *executable)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(executables_mutex);
|
||||
WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);
|
||||
|
||||
executables[((ExecutableImpl*)executable)->id()] = nullptr;
|
||||
delete executable;
|
||||
}
|
||||
@@ -156,7 +157,7 @@ hsa_status_t AmdHsaCodeLoader::IterateExecutables(
|
||||
void *data),
|
||||
void *data)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(executables_mutex);
|
||||
WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);
|
||||
assert(callback);
|
||||
|
||||
for (auto &exec : executables) {
|
||||
@@ -169,12 +170,57 @@ hsa_status_t AmdHsaCodeLoader::IterateExecutables(
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t AmdHsaCodeLoader::QuerySegmentDescriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t *num_segment_descriptors)
|
||||
{
|
||||
if (!num_segment_descriptors) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (*num_segment_descriptors == 0 && segment_descriptors) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (*num_segment_descriptors != 0 && !segment_descriptors) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
this->EnableReadOnlyMode();
|
||||
|
||||
size_t actual_num_segment_descriptors = 0;
|
||||
for (auto &executable : executables) {
|
||||
if (executable) {
|
||||
actual_num_segment_descriptors += executable->GetNumSegmentDescriptors();
|
||||
}
|
||||
}
|
||||
|
||||
if (*num_segment_descriptors == 0) {
|
||||
*num_segment_descriptors = actual_num_segment_descriptors;
|
||||
this->DisableReadOnlyMode();
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
if (*num_segment_descriptors != actual_num_segment_descriptors) {
|
||||
this->DisableReadOnlyMode();
|
||||
return HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
for (auto &executable : executables) {
|
||||
if (executable) {
|
||||
i += executable->QuerySegmentDescriptors(segment_descriptors, actual_num_segment_descriptors, i);
|
||||
}
|
||||
}
|
||||
|
||||
this->DisableReadOnlyMode();
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t AmdHsaCodeLoader::FindHostAddress(uint64_t device_address)
|
||||
{
|
||||
ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);
|
||||
if (device_address == 0) {
|
||||
return 0;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(executables_mutex);
|
||||
|
||||
for (auto &exec : executables) {
|
||||
if (exec != nullptr) {
|
||||
uint64_t host_address = exec->FindHostAddress(device_address);
|
||||
@@ -186,6 +232,26 @@ uint64_t AmdHsaCodeLoader::FindHostAddress(uint64_t device_address)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AmdHsaCodeLoader::EnableReadOnlyMode()
|
||||
{
|
||||
rw_lock_.ReaderLock();
|
||||
for (auto &executable : executables) {
|
||||
if (executable) {
|
||||
((ExecutableImpl*)executable)->EnableReadOnlyMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmdHsaCodeLoader::DisableReadOnlyMode()
|
||||
{
|
||||
rw_lock_.ReaderUnlock();
|
||||
for (auto &executable : executables) {
|
||||
if (executable) {
|
||||
((ExecutableImpl*)executable)->DisableReadOnlyMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SymbolImpl. //
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -754,6 +820,44 @@ hsa_status_t ExecutableImpl::IterateLoadedCodeObjects(
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
size_t ExecutableImpl::GetNumSegmentDescriptors()
|
||||
{
|
||||
// assuming we are in readonly mode.
|
||||
size_t actual_num_segment_descriptors = 0;
|
||||
for (auto &obj : loaded_code_objects) {
|
||||
actual_num_segment_descriptors += obj->LoadedSegments().size();
|
||||
}
|
||||
return actual_num_segment_descriptors;
|
||||
}
|
||||
|
||||
size_t ExecutableImpl::QuerySegmentDescriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t total_num_segment_descriptors,
|
||||
size_t first_empty_segment_descriptor)
|
||||
{
|
||||
// assuming we are in readonly mode.
|
||||
assert(segment_descriptors);
|
||||
assert(first_empty_segment_descriptor < total_num_segment_descriptors);
|
||||
|
||||
size_t i = first_empty_segment_descriptor;
|
||||
for (auto &obj : loaded_code_objects) {
|
||||
assert(i < total_num_segment_descriptors);
|
||||
for (auto &seg : obj->LoadedSegments()) {
|
||||
segment_descriptors[i].agent = seg->Agent();
|
||||
segment_descriptors[i].executable = Executable::Handle(seg->Owner());
|
||||
segment_descriptors[i].code_object_storage_type = HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY;
|
||||
segment_descriptors[i].code_object_storage_base = obj->ElfData();
|
||||
segment_descriptors[i].code_object_storage_size = obj->ElfSize();
|
||||
segment_descriptors[i].code_object_storage_offset = seg->StorageOffset();
|
||||
segment_descriptors[i].segment_base = seg->Address(seg->VAddr());
|
||||
segment_descriptors[i].segment_size = seg->Size();
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return i - first_empty_segment_descriptor;
|
||||
}
|
||||
|
||||
uint64_t ExecutableImpl::FindHostAddress(uint64_t device_address)
|
||||
{
|
||||
for (auto &obj : loaded_code_objects) {
|
||||
@@ -771,6 +875,16 @@ uint64_t ExecutableImpl::FindHostAddress(uint64_t device_address)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExecutableImpl::EnableReadOnlyMode()
|
||||
{
|
||||
rw_lock_.ReaderLock();
|
||||
}
|
||||
|
||||
void ExecutableImpl::DisableReadOnlyMode()
|
||||
{
|
||||
rw_lock_.ReaderUnlock();
|
||||
}
|
||||
|
||||
#define HSAERRCHECK(hsc) \
|
||||
if (hsc != HSA_STATUS_SUCCESS) { \
|
||||
assert(false); \
|
||||
@@ -854,7 +968,7 @@ hsa_status_t ExecutableImpl::LoadCodeObject(
|
||||
}
|
||||
|
||||
if (loaderOptions.DumpAll()->is_set() || loaderOptions.DumpCode()->is_set()) {
|
||||
if (!code->SaveToFile(amd::hsa::DumpFileName(loaderOptions.DumpDir()->value(), LOADER_DUMP_PREFIX, "co", dumpNum))) {
|
||||
if (!code->SaveToFile(amd::hsa::DumpFileName(loaderOptions.DumpDir()->value(), LOADER_DUMP_PREFIX, "hsaco", dumpNum))) {
|
||||
// Ignore error.
|
||||
}
|
||||
}
|
||||
@@ -946,7 +1060,7 @@ hsa_status_t ExecutableImpl::LoadSegmentV1(hsa_agent_t agent, code::Segment* s)
|
||||
if (need_alloc) {
|
||||
void* ptr = context_->SegmentAlloc(segment, agent, s->memSize(), s->align(), true);
|
||||
if (!ptr) { return HSA_STATUS_ERROR_OUT_OF_RESOURCES; }
|
||||
new_seg = new Segment(this, agent, segment, ptr, s->memSize(), s->vaddr());
|
||||
new_seg = new Segment(this, agent, segment, ptr, s->memSize(), s->vaddr(), s->offset());
|
||||
new_seg->Copy(s->vaddr(), s->data(), s->imageSize());
|
||||
objects.push_back(new_seg);
|
||||
|
||||
@@ -1422,7 +1536,7 @@ hsa_status_t ExecutableImpl::LoadSegmentV2(hsa_agent_t agent, code::Segment* s,
|
||||
void* ptr = context_->SegmentAlloc(segment, agent, s->memSize(), s->align(), true);
|
||||
if (!ptr) { return HSA_STATUS_ERROR_OUT_OF_RESOURCES; }
|
||||
|
||||
Segment *new_seg = new Segment(this, agent, segment, ptr, s->memSize(), s->vaddr());
|
||||
Segment *new_seg = new Segment(this, agent, segment, ptr, s->memSize(), s->vaddr(), s->offset());
|
||||
new_seg->Copy(s->vaddr(), s->data(), s->imageSize());
|
||||
objects.push_back(new_seg);
|
||||
assert(new_seg);
|
||||
|
||||
@@ -273,16 +273,18 @@ private:
|
||||
size_t size;
|
||||
uint64_t vaddr;
|
||||
bool frozen;
|
||||
size_t storage_offset;
|
||||
|
||||
public:
|
||||
Segment(ExecutableImpl *owner_, hsa_agent_t agent_, amdgpu_hsa_elf_segment_t segment_, void* ptr_, size_t size_, uint64_t vaddr_)
|
||||
Segment(ExecutableImpl *owner_, hsa_agent_t agent_, amdgpu_hsa_elf_segment_t segment_, void* ptr_, size_t size_, uint64_t vaddr_, size_t storage_offset_)
|
||||
: ExecutableObject(owner_, agent_), segment(segment_),
|
||||
ptr(ptr_), size(size_), vaddr(vaddr_), frozen(false) { }
|
||||
ptr(ptr_), size(size_), vaddr(vaddr_), frozen(false), storage_offset(storage_offset_) { }
|
||||
|
||||
amdgpu_hsa_elf_segment_t ElfSegment() const { return segment; }
|
||||
void* Ptr() const { return ptr; }
|
||||
size_t Size() const { return size; }
|
||||
uint64_t VAddr() const { return vaddr; }
|
||||
size_t StorageOffset() const { return storage_offset; }
|
||||
|
||||
bool GetInfo(amd_loaded_segment_info_t attribute, void *value) override;
|
||||
|
||||
@@ -399,8 +401,18 @@ public:
|
||||
void *data),
|
||||
void *data);
|
||||
|
||||
size_t GetNumSegmentDescriptors() override;
|
||||
|
||||
size_t QuerySegmentDescriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t total_num_segment_descriptors,
|
||||
size_t first_empty_segment_descriptor) override;
|
||||
|
||||
uint64_t FindHostAddress(uint64_t device_address) override;
|
||||
|
||||
void EnableReadOnlyMode();
|
||||
void DisableReadOnlyMode();
|
||||
|
||||
void Print(std::ostream& out) override;
|
||||
bool PrintToFile(const std::string& filename) override;
|
||||
|
||||
@@ -455,7 +467,7 @@ class AmdHsaCodeLoader : public Loader {
|
||||
private:
|
||||
Context* context;
|
||||
std::vector<Executable*> executables;
|
||||
std::mutex executables_mutex;
|
||||
amd::hsa::common::ReaderWriterLock rw_lock_;
|
||||
|
||||
public:
|
||||
AmdHsaCodeLoader(Context* context_)
|
||||
@@ -473,7 +485,14 @@ public:
|
||||
void *data),
|
||||
void *data) override;
|
||||
|
||||
hsa_status_t QuerySegmentDescriptors(
|
||||
hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,
|
||||
size_t *num_segment_descriptors) override;
|
||||
|
||||
uint64_t FindHostAddress(uint64_t device_address) override;
|
||||
|
||||
void EnableReadOnlyMode();
|
||||
void DisableReadOnlyMode();
|
||||
};
|
||||
|
||||
} // namespace loader
|
||||
|
||||
Tagairt in Eagrán Nua
Cuir bac ar úsáideoir