From bae6f34b087508aa118eadb3281599fb3c46fdde Mon Sep 17 00:00:00 2001
From: foreman
Date: Mon, 10 Sep 2018 11:57:07 -0400
Subject: [PATCH] P4 to Git Change 1603595 by gandryey@gera-ocl-lc on
2018/09/10 11:45:44
SWDEV-79445 - OCL generic changes and code clean-up
- Make a fallback to system memory without device access if USWC allocation failed
- Destroy the backing store after the load of all kernels
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palkernel.cpp#65 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palkernel.hpp#24 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.cpp#69 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.hpp#24 edit
[ROCm/clr commit: 8e02d82368b8685959ef016b14dc0ea59819d0e9]
---
.../rocclr/runtime/device/pal/palkernel.cpp | 15 +++---
.../rocclr/runtime/device/pal/palkernel.hpp | 20 +++----
.../rocclr/runtime/device/pal/palprogram.cpp | 54 +++++++++++++++----
.../rocclr/runtime/device/pal/palprogram.hpp | 23 ++++----
4 files changed, 75 insertions(+), 37 deletions(-)
diff --git a/projects/clr/rocclr/runtime/device/pal/palkernel.cpp b/projects/clr/rocclr/runtime/device/pal/palkernel.cpp
index fbfe429231..2b2df120ed 100644
--- a/projects/clr/rocclr/runtime/device/pal/palkernel.cpp
+++ b/projects/clr/rocclr/runtime/device/pal/palkernel.cpp
@@ -29,13 +29,15 @@ bool HSAILKernel::aqlCreateHWInfo(amd::hsa::loader::Symbol* sym) {
return false;
}
- amd_kernel_code_t* akc =
- reinterpret_cast(prog().findHostKernelAddress(code_));
- cpuAqlCode_ = akc;
if (!sym->GetInfo(HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_SIZE,
- reinterpret_cast(&codeSize_))) {
+ reinterpret_cast(&codeSize_))) {
return false;
}
+
+ amd_kernel_code_t* akc = &akc_;
+ // Copy codeobject of this kernel from the program CPU segment
+ memcpy(akc, reinterpret_cast(prog().findHostKernelAddress(code_)), sizeof(amd_kernel_code_t));
+
size_t akc_align = 0;
if (!sym->GetInfo(HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_ALIGN,
reinterpret_cast(&akc_align))) {
@@ -74,7 +76,8 @@ HSAILKernel::HSAILKernel(std::string name, HSAILProgram* prog, std::string compi
prog_(*prog),
index_(0),
code_(0),
- codeSize_(0) {
+ codeSize_(0)
+ {
flags_.hsa_ = true;
}
@@ -359,7 +362,7 @@ hsa_kernel_dispatch_packet_t* HSAILKernel::loadArguments(
hsaDisp->completion_signal.handle = 0;
memcpy(aqlArgBuf + argsBufferSize(), hsaDisp, sizeof(hsa_kernel_dispatch_packet_t));
- if (AMD_HSA_BITS_GET(cpuAqlCode_->kernel_code_properties,
+ if (AMD_HSA_BITS_GET(akc_.kernel_code_properties,
AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_QUEUE_PTR)) {
gpu.addVmMemory(gpu.hsaQueueMem());
}
diff --git a/projects/clr/rocclr/runtime/device/pal/palkernel.hpp b/projects/clr/rocclr/runtime/device/pal/palkernel.hpp
index c7477697c0..d94ae849d3 100644
--- a/projects/clr/rocclr/runtime/device/pal/palkernel.hpp
+++ b/projects/clr/rocclr/runtime/device/pal/palkernel.hpp
@@ -66,10 +66,10 @@ class HSAILKernel : public device::Kernel {
const HSAILProgram& prog() const;
//! Returns LDS size used in this kernel
- uint32_t ldsSize() const { return cpuAqlCode_->workgroup_group_segment_byte_size; }
+ uint32_t ldsSize() const { return akc_.workgroup_group_segment_byte_size; }
//! Returns pointer on CPU to AQL code info
- const amd_kernel_code_t* cpuAqlCode() const { return cpuAqlCode_; }
+ const amd_kernel_code_t* cpuAqlCode() const { return &akc_; }
//! Returns memory object with AQL code
uint64_t gpuAqlCode() const { return code_; }
@@ -78,10 +78,10 @@ class HSAILKernel : public device::Kernel {
size_t aqlCodeSize() const { return codeSize_; }
//! Returns the size of argument buffer
- size_t argsBufferSize() const { return cpuAqlCode_->kernarg_segment_byte_size; }
+ size_t argsBufferSize() const { return akc_.kernarg_segment_byte_size; }
//! Returns spill reg size per workitem
- int spillSegSize() const { return amd::alignUp(cpuAqlCode_->workitem_private_segment_byte_size, sizeof(uint32_t)); }
+ int spillSegSize() const { return amd::alignUp(akc_.workitem_private_segment_byte_size, sizeof(uint32_t)); }
//! Returns AQL packet in CPU memory
//! if the kernel arguments were successfully loaded, otherwise NULL
@@ -109,13 +109,13 @@ class HSAILKernel : public device::Kernel {
//! Creates AQL kernel HW info
bool aqlCreateHWInfo(amd::hsa::loader::Symbol* sym);
- std::string compileOptions_; //!< compile used for finalizing this kernel
- amd_kernel_code_t* cpuAqlCode_; //!< AQL kernel code on CPU
- const HSAILProgram& prog_; //!< Reference to the parent program
- uint index_; //!< Kernel index in the program
+ std::string compileOptions_; //!< compile used for finalizing this kernel
+ amd_kernel_code_t akc_; //!< AQL kernel code on CPU
+ const HSAILProgram& prog_; //!< Reference to the parent program
+ uint index_; //!< Kernel index in the program
- uint64_t code_; //!< GPU memory pointer to the kernel
- size_t codeSize_; //!< Size of ISA code
+ uint64_t code_; //!< GPU memory pointer to the kernel
+ size_t codeSize_; //!< Size of ISA code
};
#if defined(WITH_LIGHTNING_COMPILER)
diff --git a/projects/clr/rocclr/runtime/device/pal/palprogram.cpp b/projects/clr/rocclr/runtime/device/pal/palprogram.cpp
index b71f6de041..0417ba3279 100644
--- a/projects/clr/rocclr/runtime/device/pal/palprogram.cpp
+++ b/projects/clr/rocclr/runtime/device/pal/palprogram.cpp
@@ -28,13 +28,22 @@
namespace pal {
-Segment::Segment() : gpuAccess_(nullptr), cpuAccess_(nullptr) {}
+Segment::Segment() : gpuAccess_(nullptr), cpuAccess_(nullptr), cpuMem_(nullptr) {}
Segment::~Segment() {
delete gpuAccess_;
+ DestroyCpuAccess();
+}
+
+void Segment::DestroyCpuAccess() {
if (cpuAccess_ != nullptr) {
cpuAccess_->unmap(nullptr);
delete cpuAccess_;
+ cpuAccess_ = nullptr;
+ }
+ if (cpuMem_ != nullptr) {
+ delete[] cpuMem_;
+ cpuMem_ = nullptr;
}
}
@@ -48,13 +57,18 @@ bool Segment::alloc(HSAILProgram& prog, amdgpu_hsa_elf_segment_t segment, size_t
return false;
}
if (segment == AMDGPU_HSA_SEGMENT_CODE_AGENT) {
+ void* ptr = nullptr;
cpuAccess_ = new pal::Memory(prog.dev(), amd::alignUp(size, align));
if ((cpuAccess_ == nullptr) || !cpuAccess_->create(pal::Resource::Remote)) {
delete cpuAccess_;
cpuAccess_ = nullptr;
- return false;
+ ptr = cpuMem_ = reinterpret_cast(new char[amd::alignUp(size, align)]);
+ if (cpuMem_ == nullptr) {
+ return false;
+ }
+ } else {
+ ptr = cpuAccess_->map(nullptr, 0);
}
- void* ptr = cpuAccess_->map(nullptr, 0);
if (zero) {
memset(ptr, 0, size);
}
@@ -75,7 +89,7 @@ bool Segment::alloc(HSAILProgram& prog, amdgpu_hsa_elf_segment_t segment, size_t
prog.setGlobalVariableTotalSize(prog.globalVariableTotalSize() + size);
break;
case AMDGPU_HSA_SEGMENT_CODE_AGENT:
- prog.setCodeObjects(gpuAccess_, cpuAccess_->data());
+ prog.setCodeObjects(this, gpuAccess_, reinterpret_cast(cpuAddress(0)));
break;
default:
break;
@@ -87,6 +101,9 @@ void Segment::copy(size_t offset, const void* src, size_t size) {
if (cpuAccess_ != nullptr) {
amd::Os::fastMemcpy(cpuAddress(offset), src, size);
} else {
+ if (cpuMem_ != nullptr) {
+ amd::Os::fastMemcpy(cpuAddress(offset), src, size);
+ }
amd::ScopedLock k(gpuAccess_->dev().xferMgr().lockXfer());
VirtualGPU& gpu = *gpuAccess_->dev().xferQueue();
Memory& xferBuf = gpu.xferWrite().Acquire(size);
@@ -124,7 +141,7 @@ HSAILProgram::HSAILProgram(Device& device)
rawBinary_(nullptr),
kernels_(nullptr),
codeSegGpu_(nullptr),
- codeSegCpu_(nullptr),
+ codeSegment_(nullptr),
maxScratchRegs_(0),
flags_(0),
executable_(nullptr),
@@ -145,7 +162,7 @@ HSAILProgram::HSAILProgram(NullDevice& device)
rawBinary_(nullptr),
kernels_(nullptr),
codeSegGpu_(nullptr),
- codeSegCpu_(nullptr),
+ codeSegment_(nullptr),
maxScratchRegs_(0),
flags_(0),
executable_(nullptr),
@@ -695,6 +712,9 @@ bool HSAILProgram::linkImpl(amd::option::Options* options) {
return false;
}
}
+
+ DestroySegmentCpuAccess();
+
// Save the binary in the interface class
saveBinaryAndSetType(TYPE_EXECUTABLE);
buildLog_ += aclGetCompilerLog(dev().compiler());
@@ -1426,6 +1446,8 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s
}
size_t progvarsTotalSize = 0;
+ size_t dynamicSize = 0;
+ size_t progvarsWriteSize = 0;
// Begin the Elf image from memory
Elf* e = elf_memory((char*)binary, size, NULL);
@@ -1481,8 +1503,16 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s
}
}
// Accumulate the size of R & !X loadable segments
- else if (pHdr.p_type == PT_LOAD && (pHdr.p_flags & PF_R) && !(pHdr.p_flags & PF_X)) {
- progvarsTotalSize += pHdr.p_memsz;
+ else if (pHdr.p_type == PT_LOAD && !(pHdr.p_flags & PF_X)) {
+ if (pHdr.p_flags & PF_R) {
+ progvarsTotalSize += pHdr.p_memsz;
+ }
+ if (pHdr.p_flags & PF_W) {
+ progvarsWriteSize += pHdr.p_memsz;
+ }
+ }
+ else if (pHdr.p_type == PT_DYNAMIC) {
+ dynamicSize += pHdr.p_memsz;
}
}
@@ -1495,8 +1525,8 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s
return false;
}
- // note: The global variable size is updated in the context loader
- // setGlobalVariableTotalSize(progvarsTotalSize);
+ progvarsTotalSize -= dynamicSize;
+ setGlobalVariableTotalSize(progvarsTotalSize);
// Get the list of kernels
std::vector kernelNameList;
@@ -1506,7 +1536,7 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s
return false;
}
- for (auto& kernelName : kernelNameList) {
+ for (const auto& kernelName : kernelNameList) {
auto kernel =
new LightningKernel(kernelName, this, options->origOptionStr + ProcessOptions(options));
@@ -1538,6 +1568,8 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s
return false;
}
+ DestroySegmentCpuAccess();
+
// Save the binary and type
clBinary()->saveBIFBinary((char*)binary, size);
setType(TYPE_EXECUTABLE);
diff --git a/projects/clr/rocclr/runtime/device/pal/palprogram.hpp b/projects/clr/rocclr/runtime/device/pal/palprogram.hpp
index 068c4a552f..fceded4764 100644
--- a/projects/clr/rocclr/runtime/device/pal/palprogram.hpp
+++ b/projects/clr/rocclr/runtime/device/pal/palprogram.hpp
@@ -54,11 +54,15 @@ class Segment : public amd::HeapObject {
uint64_t gpuAddress(size_t offset) const { return gpuAccess_->vmAddress() + offset; }
//! Returns address for CPU access in the segment
- void* cpuAddress(size_t offset) const { return cpuAccess_->data() + offset; }
+ void* cpuAddress(size_t offset) const
+ { return ((cpuAccess_ != nullptr) ? cpuAccess_->data() : cpuMem_) + offset; }
+
+ void DestroyCpuAccess();
private:
- Memory* gpuAccess_; //!< GPU memory for segment access
- Memory* cpuAccess_; //!< CPU memory for segment (backing store)
+ Memory* gpuAccess_; //!< GPU memory for segment access
+ Memory* cpuAccess_; //!< CPU memory for segment (backing store)
+ address cpuMem_; //!< CPU memory for segment without GPU direct access (backing store)
};
class PALHSALoaderContext final : public Context {
@@ -135,9 +139,9 @@ class HSAILProgram : public device::Program {
void addGlobalStore(Memory* mem) { globalStores_.push_back(mem); }
- void setCodeObjects(Memory* codeGpu, address codeCpu) {
+ void setCodeObjects(Segment* seg, Memory* codeGpu, address codeCpu) {
codeSegGpu_ = codeGpu;
- codeSegCpu_ = codeCpu;
+ codeSegment_ = seg;
}
const std::vector& globalStores() const { return globalStores_; }
@@ -169,9 +173,6 @@ class HSAILProgram : public device::Program {
//! Returns code segement on GPU
const Memory& codeSegGpu() const { return *codeSegGpu_; }
- //! Returns code segement on CPU
- address codeSegCpu() const { return codeSegCpu_; }
-
//! Returns CPU address for a kernel
uint64_t findHostKernelAddress(uint64_t devAddr) const {
return loader_->FindHostAddress(devAddr);
@@ -219,9 +220,11 @@ class HSAILProgram : public device::Program {
virtual bool isElf(const char* bin) const {
return amd::isElfMagic(bin);
- // return false;
}
+ //! Destroys CPU allocations in the code segment
+ void DestroySegmentCpuAccess() const { codeSegment_->DestroyCpuAccess(); }
+
private:
//! Disable default copy constructor
HSAILProgram(const HSAILProgram&);
@@ -242,7 +245,7 @@ class HSAILProgram : public device::Program {
std::vector globalStores_; //!< Global memory for the program
Memory* kernels_; //!< Table with kernel object pointers
Memory* codeSegGpu_; //!< GPU memory with code objects
- address codeSegCpu_; //!< CPU memory with code objects
+ Segment* codeSegment_; //!< Pointer to the code segment for this program
uint
maxScratchRegs_; //!< Maximum number of scratch regs used in the program by individual kernel
std::list staticSamplers_; //!< List od internal static samplers