P4 to Git Change 1394146 by gandryey@gera-w8 on 2017/04/04 11:59:55
SWDEV-79445 - OCL generic changes and code clean-up - Added a simple hang analysis (PAL path only). GPU_ANALYZE_HANG controls the feature. It will create ocl_hang_dump.txt, which will contain OCL resident resources used in the last submissions on this queue and last kernel name. Its recommended to use this feature with GPU_FLUSH_ON_EXECUTION or AMD_OCL_WAIT_COMMAND Affected files ... ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.cpp#46 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.hpp#20 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.hpp#270 edit
This commit is contained in:
@@ -360,6 +360,57 @@ VirtualGPU::Queue::isDone(uint id)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VirtualGPU::Queue::DumpMemoryReferences() const
|
||||
{
|
||||
std::fstream dump;
|
||||
std::stringstream file_name("ocl_hang_dump.txt");
|
||||
uint64_t start = amd::Os::timeNanos() / 1e9;
|
||||
|
||||
dump.open(file_name.str().c_str(), (std::fstream::out | std::fstream::app));
|
||||
// Check if we have OpenCL program
|
||||
if (dump.is_open()) {
|
||||
dump << start << " Queue: ";
|
||||
switch (iQueue_->Type()) {
|
||||
case Pal::QueueTypeCompute:
|
||||
dump << "Compute";
|
||||
break;
|
||||
case Pal::QueueTypeDma:
|
||||
dump << "SDMA";
|
||||
break;
|
||||
default:
|
||||
dump << "unknown";
|
||||
break;
|
||||
}
|
||||
dump << "\n" << "Resident memory resources:\n";
|
||||
uint idx = 0;
|
||||
for (auto it : memReferences_) {
|
||||
dump << " " << idx << "\t[";
|
||||
dump.setf(std::ios::hex, std::ios::basefield);
|
||||
dump.setf(std::ios::showbase);
|
||||
dump << (it.first)->Desc().gpuVirtAddr << ", " <<
|
||||
(it.first)->Desc().gpuVirtAddr + (it.first)->Desc().size;
|
||||
dump.setf(std::ios::dec);
|
||||
dump << "] CbId:" << it.second << "\n";
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
if (last_kernel_ != nullptr) {
|
||||
const amd::KernelSignature& signature = last_kernel_->signature();
|
||||
const amd::KernelParameters& params = last_kernel_->parameters();
|
||||
dump << last_kernel_->name() << std::endl;
|
||||
for (size_t i = 0; i < signature.numParameters(); ++i) {
|
||||
const amd::KernelParameterDescriptor& desc = signature.at(i);
|
||||
// Find if the current argument is a memory object
|
||||
if ((desc.type_ == T_POINTER) &&
|
||||
(desc.addressQualifier_ != CL_KERNEL_ARG_ADDRESS_LOCAL)) {
|
||||
dump << " " << desc.name_ << ": " << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
dump.close();
|
||||
}
|
||||
|
||||
bool
|
||||
VirtualGPU::MemoryDependency::create(size_t numMemObj)
|
||||
{
|
||||
@@ -1998,6 +2049,8 @@ VirtualGPU::submitKernelInternal(
|
||||
VirtualGPU* gpuDefQueue = nullptr;
|
||||
amd::HwDebugManager * dbgManager = dev().hwDebugMgr();
|
||||
|
||||
AddKernel(kernel);
|
||||
|
||||
// Get the HSA kernel object
|
||||
const HSAILKernel& hsaKernel =
|
||||
static_cast<const HSAILKernel&>(*(kernel.getDeviceKernel(dev())));
|
||||
@@ -3177,18 +3230,21 @@ VirtualGPU::profilingCollectResults(CommandBatch* cb, const amd::Event* waitingE
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
VirtualGPU::addVmMemory(const Memory* memory)
|
||||
{
|
||||
queues_[MainEngine]->addCmdMemRef(memory->iMem());
|
||||
return true;
|
||||
}
|
||||
void
|
||||
VirtualGPU::AddKernel(const amd::Kernel& kernel) const
|
||||
{
|
||||
queues_[MainEngine]->last_kernel_ = &kernel;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
VirtualGPU::addDoppRef(const Memory* memory, bool lastDoppCmd, bool pfpaDoppCmd)
|
||||
{
|
||||
queues_[MainEngine]->addCmdDoppRef(memory->iMem(), lastDoppCmd, pfpaDoppCmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -50,6 +50,9 @@ public:
|
||||
static const uint64_t WaitTimeoutInNsec = 6000000000;
|
||||
static const uint64_t PollIntervalInNsec = 200000;
|
||||
|
||||
Queue(const Queue&) = delete;
|
||||
Queue& operator=(const Queue&) = delete;
|
||||
|
||||
static Queue* Create(
|
||||
Pal::IDevice* palDev, //!< PAL device object
|
||||
Pal::QueueType queueType, //!< PAL queue type
|
||||
@@ -60,13 +63,13 @@ public:
|
||||
);
|
||||
|
||||
Queue(Pal::IDevice* palDev)
|
||||
: iQueue_(NULL), iDev_(palDev),
|
||||
: iQueue_(nullptr), last_kernel_(nullptr), iDev_(palDev),
|
||||
cmdBufIdSlot_(StartCmdBufIdx), cmdBufIdCurrent_(StartCmdBufIdx),
|
||||
cmbBufIdRetired_(0), cmdCnt_(0), vlAlloc_(64 * Ki)
|
||||
{
|
||||
for (uint i = 0; i < MaxCmdBuffers; ++i) {
|
||||
iCmdBuffs_[i] = NULL;
|
||||
iCmdFences_[i] = NULL;
|
||||
iCmdBuffs_[i] = nullptr;
|
||||
iCmdFences_[i] = nullptr;
|
||||
}
|
||||
vlAlloc_.Init();
|
||||
}
|
||||
@@ -82,12 +85,12 @@ public:
|
||||
{
|
||||
Pal::GpuMemoryRef memRef = {};
|
||||
memRef.pGpuMemory = iMem;
|
||||
iDev_->AddGpuMemoryReferences(1, &memRef, NULL,
|
||||
iDev_->AddGpuMemoryReferences(1, &memRef, nullptr,
|
||||
Pal::GpuMemoryRefCantTrim);
|
||||
}
|
||||
void removeMemRef(Pal::IGpuMemory* iMem) const
|
||||
{
|
||||
iDev_->RemoveGpuMemoryReferences(1, &iMem, NULL);
|
||||
iDev_->RemoveGpuMemoryReferences(1, &iMem, nullptr);
|
||||
}
|
||||
|
||||
// ibReuse forces event wait without polling, to make sure event occured
|
||||
@@ -112,6 +115,9 @@ public:
|
||||
else if ((Pal::Result::NotReady == result) ||
|
||||
(Pal::Result::Timeout == result)) {
|
||||
LogWarning("PAL fence isn't ready!");
|
||||
if (GPU_ANALYZE_HANG) {
|
||||
DumpMemoryReferences();
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogError("PAL wait for a fence failed!");
|
||||
@@ -134,10 +140,12 @@ public:
|
||||
Pal::ICmdBuffer* iCmd() const { return iCmdBuffs_[cmdBufIdSlot_]; }
|
||||
|
||||
Pal::IQueue* iQueue_; //!< PAL queue object
|
||||
Pal::ICmdBuffer* iCmdBuffs_[MaxCmdBuffers]; //!< PAL command buffers
|
||||
Pal::IFence* iCmdFences_[MaxCmdBuffers]; //!< PAL fences, associated with CMD
|
||||
Pal::ICmdBuffer* iCmdBuffs_[MaxCmdBuffers]; //!< PAL command buffers
|
||||
Pal::IFence* iCmdFences_[MaxCmdBuffers];//!< PAL fences, associated with CMD
|
||||
const amd::Kernel* last_kernel_; //!< Last submitted kernel
|
||||
|
||||
private:
|
||||
void DumpMemoryReferences() const;
|
||||
Pal::IDevice* iDev_; //!< PAL device
|
||||
uint cmdBufIdSlot_; //!< Command buffer ID slot for submissions
|
||||
uint cmdBufIdCurrent_; //!< Current global command buffer ID
|
||||
@@ -207,7 +215,7 @@ public:
|
||||
public:
|
||||
//! Default constructor
|
||||
MemoryDependency()
|
||||
: memObjectsInQueue_(NULL)
|
||||
: memObjectsInQueue_(nullptr)
|
||||
, numMemObjectsInQueue_(0)
|
||||
, maxMemObjectsInQueue_(0) {}
|
||||
|
||||
@@ -294,7 +302,7 @@ public:
|
||||
const amd::Kernel& kernel, //!< Kernel for execution
|
||||
const_address parameters, //!< Parameters for the kernel
|
||||
bool nativeMem = true, //!< Native memory objects
|
||||
amd::Event* enqueueEvent = NULL //!< Event provided in the enqueue kernel command
|
||||
amd::Event* enqueueEvent = nullptr //!< Event provided in the enqueue kernel command
|
||||
);
|
||||
void submitNativeFn(amd::NativeFnCommand& vcmd);
|
||||
void submitFillMemory(amd::FillMemoryCommand& vcmd);
|
||||
@@ -316,7 +324,7 @@ public:
|
||||
|
||||
void releaseMemory(Pal::IGpuMemory* iMem, bool wait = true);
|
||||
|
||||
void flush(amd::Command* list = NULL, bool wait = false);
|
||||
void flush(amd::Command* list = nullptr, bool wait = false);
|
||||
bool terminate() { return true; }
|
||||
|
||||
//! Returns GPU device object associated with this kernel
|
||||
@@ -350,7 +358,7 @@ public:
|
||||
//! Wait for all engines on this Virtual GPU
|
||||
//! Returns TRUE if CPU didn't wait for GPU
|
||||
bool waitAllEngines(
|
||||
CommandBatch* cb = NULL //!< Command batch
|
||||
CommandBatch* cb = nullptr //!< Command batch
|
||||
);
|
||||
|
||||
//! Waits for the latest GPU event with a lock to prevent multiple entries
|
||||
@@ -382,12 +390,17 @@ public:
|
||||
);
|
||||
|
||||
//! Adds a memory handle into the GSL memory array for Virtual Heap
|
||||
bool addVmMemory(
|
||||
void addVmMemory(
|
||||
const Memory* memory //!< GPU memory object
|
||||
);
|
||||
|
||||
//! Adds the last submitted kernel to the queue for tracking a possible hang
|
||||
void AddKernel(
|
||||
const amd::Kernel& kernel //!< AMD kernel object
|
||||
) const;
|
||||
|
||||
//! Adds a dopp desktop texture reference
|
||||
bool addDoppRef(
|
||||
void addDoppRef(
|
||||
const Memory* memory, //!< GPU memory object
|
||||
bool lastDoopCmd, //!< is the last submission for the pre-present primary
|
||||
bool pfpaDoppCmd //!< is a submission for the pre-present primary
|
||||
@@ -565,7 +578,7 @@ private:
|
||||
//! Awaits a command batch with a waiting event
|
||||
bool awaitCompletion(
|
||||
CommandBatch* cb, //!< Command batch for to wait
|
||||
const amd::Event* waitingEvent = NULL //!< A waiting event
|
||||
const amd::Event* waitingEvent = nullptr //!< A waiting event
|
||||
);
|
||||
|
||||
//! Detects memory dependency for HSAIL kernels and flushes caches
|
||||
|
||||
@@ -183,6 +183,8 @@ release(bool, GPU_WAVE_LIMIT_ENABLE, false, \
|
||||
"1 = Enable adaptive wave limiter") \
|
||||
release(bool, OCL_STUB_PROGRAMS, false, \
|
||||
"1 = Enables OCL programs stubing") \
|
||||
release(bool, GPU_ANALYZE_HANG, false, \
|
||||
"1 = Enables GPU hang analysis") \
|
||||
release_on_stg(uint, GPU_WAVE_LIMIT_CU_PER_SH, 0, \
|
||||
"Assume the number of CU per SH for wave limiter") \
|
||||
release_on_stg(uint, GPU_WAVE_LIMIT_MAX_WAVE, 10, \
|
||||
|
||||
Fai riferimento in un nuovo problema
Block a user