Fix a crash when printf used in a kernel launched on a stream with custom CU mask

SWDEV-249719 - root cause: queues with custom CU mask are not inserted
into queuePool_ (i.e., queue of reusable HSA queues) of ROC device class
causing a crash when creating hostcall buffers for printf

Change-Id: Ieee7005d9a5a30b3113394ce23ee65927126d0d6


[ROCm/clr commit: 2e199bd492]
Этот коммит содержится в:
Aryan Salmanpour
2020-09-09 14:56:12 -04:00
коммит произвёл Aryan Salmanpour
родитель 1aa5e56135
Коммит b01d49542c
3 изменённых файлов: 27 добавлений и 12 удалений
+18 -7
Просмотреть файл
@@ -143,6 +143,7 @@ Device::Device(hsa_agent_t bkendDevice)
, hsa_exclusive_gpu_access_(false)
, queuePool_(QueuePriority::Total)
, coopHostcallBuffer_(nullptr)
, queueWithCUMaskPool_(QueuePriority::Total)
, numOfVgpus_(0) {
group_segment_.handle = 0;
system_segment_.handle = 0;
@@ -2300,7 +2301,13 @@ hsa_queue_t* Device::acquireQueue(uint32_t queue_size_hint, bool coop_queue,
hsa_queue_destroy(queue);
return nullptr;
}
// Skip queue recycling for queues with custom CU mask
// add queues with custom CU mask into their special pool to keep track
// of mapping of these queues to their associated queueInfo (i.e., hostcall buffers)
auto result = queueWithCUMaskPool_[qIndex].emplace(std::make_pair(queue, QueueInfo()));
assert(result.second && "QueueInfo already exists");
auto &qInfo = result.first->second;
qInfo.refCount = 1;
return queue;
}
if (coop_queue) {
@@ -2315,8 +2322,8 @@ hsa_queue_t* Device::acquireQueue(uint32_t queue_size_hint, bool coop_queue,
return queue;
}
void Device::releaseQueue(hsa_queue_t* queue) {
for (auto& it : queuePool_) {
void Device::releaseQueue(hsa_queue_t* queue, const std::vector<uint32_t>& cuMask) {
for (auto& it : cuMask.size() == 0 ? queuePool_ : queueWithCUMaskPool_) {
auto qIter = it.find(queue);
if (qIter != it.end()) {
auto &qInfo = qIter->second;
@@ -2345,18 +2352,22 @@ void Device::releaseQueue(hsa_queue_t* queue) {
hsa_queue_destroy(queue);
}
void* Device::getOrCreateHostcallBuffer(hsa_queue_t* queue, bool coop_queue) {
void* Device::getOrCreateHostcallBuffer(hsa_queue_t* queue, bool coop_queue,
const std::vector<uint32_t>& cuMask) {
decltype(queuePool_)::value_type::iterator qIter;
if (!coop_queue) {
for (auto &it : queuePool_) {
for (auto &it : cuMask.size() == 0 ? queuePool_ : queueWithCUMaskPool_) {
qIter = it.find(queue);
if (qIter != it.end()) {
break;
}
}
assert(qIter != queuePool_[QueuePriority::High].end());
if (cuMask.size() == 0) {
assert(qIter != queuePool_[QueuePriority::High].end());
} else {
assert(qIter != queueWithCUMaskPool_[QueuePriority::High].end());
}
if (qIter->second.hostcallBuffer_) {
return qIter->second.hostcallBuffer_;
+7 -3
Просмотреть файл
@@ -459,11 +459,12 @@ class Device : public NullDevice {
amd::CommandQueue::Priority priority = amd::CommandQueue::Priority::Normal);
//! Release HSA queue
void releaseQueue(hsa_queue_t*);
void releaseQueue(hsa_queue_t*, const std::vector<uint32_t>& cuMask = {});
//! For the given HSA queue, return an existing hostcall buffer or create a
//! new one. queuePool_ keeps a mapping from HSA queue to hostcall buffer.
void* getOrCreateHostcallBuffer(hsa_queue_t* queue, bool coop_queue = false);
void* getOrCreateHostcallBuffer(hsa_queue_t* queue, bool coop_queue = false,
const std::vector<uint32_t>& cuMask = {});
//! Return multi GPU grid launch sync buffer
address MGSync() const { return mg_sync_; }
@@ -524,7 +525,7 @@ class Device : public NullDevice {
void* hostcallBuffer_;
};
//!< a vector for keeping Pool of HSA queues with low, normal and high priorities for recycling
//! a vector for keeping Pool of HSA queues with low, normal and high priorities for recycling
std::vector<std::map<hsa_queue_t*, QueueInfo>> queuePool_;
//! returns a hsa queue from queuePool with least refCount and updates the refCount as well
@@ -535,6 +536,9 @@ class Device : public NullDevice {
virtual bool findLinkInfo(const hsa_amd_memory_pool_t& pool,
std::vector<LinkAttrType>* link_attr);
//! Pool of HSA queues with custom CU masks
std::vector<std::map<hsa_queue_t*, QueueInfo>> queueWithCUMaskPool_;
public:
std::atomic<uint> numOfVgpus_; //!< Virtual gpu unique index
+2 -2
Просмотреть файл
@@ -761,7 +761,7 @@ VirtualGPU::~VirtualGPU() {
}
if (gpu_queue_) {
roc_device_.releaseQueue(gpu_queue_);
roc_device_.releaseQueue(gpu_queue_, cuMask_);
}
}
@@ -2238,7 +2238,7 @@ bool VirtualGPU::submitKernelInternal(const amd::NDRangeContainer& sizes, const
}
case amd::KernelParameterDescriptor::HiddenHostcallBuffer: {
if (amd::IS_HIP) {
auto buffer = roc_device_.getOrCreateHostcallBuffer(gpu_queue_, coopGroups);
auto buffer = roc_device_.getOrCreateHostcallBuffer(gpu_queue_, coopGroups, cuMask_);
if (!buffer) {
ClPrint(amd::LOG_ERROR, amd::LOG_KERN,
"Kernel expects a hostcall buffer, but none found");