Initial HMM support

- Expose ROCclr interfaces for HIP usage
- ROCr interfaces aren't available in staging, thus control the
build with AMD_HMM_SUPPORT define

Change-Id: Iadc2bcc230e78d3b0dc22b235189c8cc80843446


[ROCm/clr commit: c5afd5d412]
This commit is contained in:
German Andryeyev
2020-06-11 14:26:15 -04:00
parent 2e49374d58
commit 0a6056ac82
12 changed files with 368 additions and 16 deletions
+46 -1
View File
@@ -76,6 +76,7 @@ class SvmCopyMemoryCommand;
class SvmFillMemoryCommand;
class SvmMapMemoryCommand;
class SvmUnmapMemoryCommand;
class SvmPrefetchAsyncCommand;
class TransferBufferFileCommand;
class HwDebugManager;
class Device;
@@ -86,6 +87,30 @@ namespace option {
class Options;
} // namespace option
//! @note: the defines match hip values
enum MemoryAdvice : uint32_t {
SetReadMostly = 1, ///< Data will mostly be read and only occassionally be written to
UnsetReadMostly = 2, ///< Undo the effect of hipMemAdviseSetReadMostly
SetPreferredLocation = 3, ///< Set the preferred location for the data as the specified device
UnsetPreferredLocation = 4, ///< Clear the preferred location for the data
SetAccessedBy = 5, ///< Data will be accessed by the specified device,
///< so prevent page faults as much as possible
UnsetAccessedBy = 6 ///< Let the Unified Memory subsystem decide on
///< the page faulting policy for the specified device
};
enum MemRangeAttribute : uint32_t {
ReadMostly = 1, ///< Whether the range will mostly be read and only
///< occassionally be written to
PreferredLocation = 2, ///< The preferred location of the range
AccessedBy = 3, ///< Memory range has hipMemAdviseSetAccessedBy
///< set for specified device
LastPrefetchLocation = 4, ///< The last location to which the range was prefetched
};
constexpr int CpuDeviceId = static_cast<int>(-1);
constexpr int InvalidDeviceId = static_cast<int>(-2);
} // namespace amd
enum OclExtensions {
@@ -1111,7 +1136,9 @@ class VirtualDevice : public amd::HeapObject {
virtual void submitTransferBufferFromFile(amd::TransferBufferFileCommand& cmd) {
ShouldNotReachHere();
}
virtual void submitSvmPrefetchAsync(amd::SvmPrefetchAsyncCommand& cmd) {
ShouldNotReachHere();
}
//! Get the blit manager object
device::BlitManager& blitMgr() const { return *blitMgr_; }
@@ -1341,6 +1368,24 @@ class Device : public RuntimeObject {
*/
virtual void svmFree(void* ptr) const = 0;
/**
* @return True if the device successfully applied the SVM attributes in HMM for device memory
*/
virtual bool SetSvmAttributes(const void* dev_ptr, size_t count,
amd::MemoryAdvice advice, bool first_alloc = false) const {
ShouldNotCallThis();
return false;
}
/**
* @return True if the device successfully retrieved the SVM attributes from HMM for device memory
*/
virtual bool GetSvmAttributes(void** data, size_t* data_sizes, int* attributes,
size_t num_attributes, const void* dev_ptr, size_t count) const {
ShouldNotCallThis();
return false;
}
//! Validate kernel
virtual bool validateKernel(const amd::Kernel& kernel,
const device::VirtualDevice* vdev,
@@ -36,6 +36,11 @@ target_include_directories(oclrocm
${ROCM_OCL_INCLUDES}
${ROCR_INCLUDES})
option(BUILD_HMM "Build HMM support" OFF)
if (BUILD_HMM)
target_compile_definitions(oclrocm
PRIVATE AMD_HMM_SUPPORT)
endif()
if(USE_COMGR_LIBRARY)
target_compile_definitions(oclrocm
@@ -178,6 +178,7 @@ Device::Device(hsa_agent_t bkendDevice)
system_coarse_segment_.handle = 0;
gpuvm_segment_.handle = 0;
gpu_fine_grained_segment_.handle = 0;
prefetch_signal_.handle = 0;
}
void Device::setupCpuAgent() {
@@ -786,6 +787,11 @@ bool Device::create(bool sramEccEnabled) {
}
}
// Create signal for HMM prefetch operation on device
if (HSA_STATUS_SUCCESS != hsa_signal_create(InitSignalValue, 0, nullptr, &prefetch_signal_)) {
return false;
}
return true;
}
@@ -1904,6 +1910,187 @@ void* Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_
return svmPtr;
}
// ================================================================================================
bool Device::SetSvmAttributes(const void* dev_ptr, size_t count,
amd::MemoryAdvice advice, bool first_alloc) const {
if ((settings().hmmFlags_ & Settings::Hmm::EnableSvmTracking) && !first_alloc) {
amd::Memory* svmMem = svmMem = amd::MemObjMap::FindMemObj(dev_ptr);
if (nullptr == svmMem) {
LogPrintfError("SetSvmAttributes received unknown memory for update: %p!", dev_ptr);
return false;
}
}
#if AMD_HMM_SUPPORT
std::vector<hsa_amd_svm_attribute_pair_t> attr;
if (first_alloc) {
attr.push_back({HSA_AMD_SVM_ATTRIB_GLOBAL_FLAG, HSA_AMD_SVM_GLOBAL_FLAG_COARSE_GRAINED});
}
switch (advice) {
case amd::MemoryAdvice::SetReadMostly:
attr.push_back({HSA_AMD_SVM_ATTRIB_READ_ONLY, true});
break;
case amd::MemoryAdvice::UnsetReadMostly:
attr.push_back({HSA_AMD_SVM_ATTRIB_READ_ONLY, false});
break;
case amd::MemoryAdvice::SetPreferredLocation:
attr.push_back({HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION, getBackendDevice().handle});
break;
case amd::MemoryAdvice::UnsetPreferredLocation:
// Note: The current behavior doesn't match hip spec precisely
attr.push_back({HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION, getCpuAgent().handle});
break;
case amd::MemoryAdvice::SetAccessedBy:
attr.push_back({HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE, getBackendDevice().handle});
break;
case amd::MemoryAdvice::UnsetAccessedBy:
// @note: The current behavior doesn't match hip spec precisely
attr.push_back({HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE, getCpuAgent().handle});
break;
default:
return false;
break;
}
hsa_status_t status = hsa_amd_svm_attributes_set(const_cast<void*>(dev_ptr), count,
attr.data(), attr.size());
if (status != HSA_STATUS_SUCCESS) {
LogError("hsa_amd_svm_attributes_set() failed");
return false;
}
#endif // AMD_HMM_SUPPORT
return true;
}
// ================================================================================================
bool Device::GetSvmAttributes(void** data, size_t* data_sizes, int* attributes,
size_t num_attributes, const void* dev_ptr, size_t count) const {
if (settings().hmmFlags_ & Settings::Hmm::EnableSvmTracking) {
amd::Memory* svmMem = svmMem = amd::MemObjMap::FindMemObj(dev_ptr);
if (nullptr == svmMem) {
LogPrintfError("GetSvmAttributes received unknown memory %p for state!", dev_ptr);
return false;
}
}
#if AMD_HMM_SUPPORT
std::vector<hsa_amd_svm_attribute_pair_t> attr;
for (int i = 0; i < num_attributes; ++i) {
switch (attributes[i]) {
case amd::MemRangeAttribute::ReadMostly:
attr.push_back({HSA_AMD_SVM_ATTRIB_READ_ONLY, 0});
break;
case amd::MemRangeAttribute::PreferredLocation:
attr.push_back({HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION, 0});
break;
case amd::MemRangeAttribute::AccessedBy:
attr.push_back({HSA_AMD_SVM_ATTRIB_ACCESS_QUERY, 0});
break;
case amd::MemRangeAttribute::LastPrefetchLocation:
attr.push_back({HSA_AMD_SVM_ATTRIB_PREFETCH_LOCATION, 0});
break;
default:
return false;
break;
}
}
hsa_status_t status = hsa_amd_svm_attributes_get(const_cast<void*>(dev_ptr), count,
attr.data(), attr.size());
if (status != HSA_STATUS_SUCCESS) {
LogError("hsa_amd_svm_attributes_get() failed");
return false;
}
uint32_t idx = 0;
for (auto& it : attr) {
switch (it.attribute) {
case HSA_AMD_SVM_ATTRIB_READ_ONLY:
if (data_sizes[idx] != sizeof(uint32_t)) {
return false;
}
// Cast ROCr value into the hip format
*reinterpret_cast<uint32_t*>(data[idx]) = static_cast<uint32_t>(it.value);
break;
// The logic should be identical for the both queries
case HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION:
case HSA_AMD_SVM_ATTRIB_PREFETCH_LOCATION:
if (data_sizes[idx] != sizeof(uint32_t)) {
return false;
}
*reinterpret_cast<int32_t*>(data[idx]) = static_cast<int32_t>(amd::InvalidDeviceId);
// Find device agent returned by ROCr
for (auto& device : devices()) {
if (static_cast<Device*>(device)->getBackendDevice().handle == it.value) {
*reinterpret_cast<uint32_t*>(data[idx]) = static_cast<uint32_t>(device->index());
}
}
// Find CPU agent returned by ROCr
for (auto& agent_info : getCpuAgents()) {
if (agent_info.agent.handle == it.value) {
*reinterpret_cast<int32_t*>(data[idx]) = static_cast<int32_t>(amd::CpuDeviceId);
}
}
break;
case HSA_AMD_SVM_ATTRIB_ACCESS_QUERY:
// Make sure it's multiple of 4
if (data_sizes[idx] % 4 != 0) {
return false;
}
// @note currently it's a nop
break;
default:
return false;
break;
}
// Find the next location in the query
++idx;
}
#endif // AMD_HMM_SUPPORT
return true;
}
// ================================================================================================
bool Device::SvmAllocInit(void* memory, size_t size) const {
amd::MemoryAdvice advice = amd::MemoryAdvice::SetAccessedBy;
constexpr bool kFirstAlloc = true;
SetSvmAttributes(memory, size, advice, kFirstAlloc);
if (settings().hmmFlags_ & Settings::Hmm::EnableSystemMemory) {
advice = amd::MemoryAdvice::UnsetPreferredLocation;
SetSvmAttributes(memory, size, advice);
} else {
advice = amd::MemoryAdvice::SetPreferredLocation;
SetSvmAttributes(memory, size, advice);
}
if ((settings().hmmFlags_ & Settings::Hmm::EnableMallocPrefetch) == 0) {
return true;
}
#if AMD_HMM_SUPPORT
// Initialize signal for the barrier
hsa_signal_store_relaxed(prefetch_signal_, InitSignalValue);
// Initiate a prefetch command which should force memory update in HMM
hsa_status_t status = hsa_amd_svm_prefetch_async(memory, size, getBackendDevice(),
0, nullptr, prefetch_signal_);
if (status != HSA_STATUS_SUCCESS) {
LogError("hsa_amd_svm_attributes_get() failed");
return false;
}
// Wait for the prefetch
if (hsa_signal_wait_acquire(prefetch_signal_, HSA_SIGNAL_CONDITION_EQ, 0, uint64_t(-1),
HSA_WAIT_STATE_BLOCKED) != 0) {
LogError("Barrier packet submission failed");
return false;
}
#endif // AMD_HMM_SUPPORT
return true;
}
// ================================================================================================
void Device::svmFree(void* ptr) const {
amd::Memory* svmMem = nullptr;
svmMem = amd::MemObjMap::FindMemObj(ptr);
+15 -2
View File
@@ -79,7 +79,7 @@ class IProDevice;
class Sampler : public device::Sampler {
public:
//! Constructor
Sampler(const Device& dev) : dev_(dev) {}
Sampler(const Device& dev) : dev_(dev) {}
//! Default destructor for the device memory object
virtual ~Sampler();
@@ -381,7 +381,13 @@ class Device : public NullDevice {
virtual void svmFree(void* ptr) const;
virtual bool SetClockMode(const cl_set_device_clock_mode_input_amd setClockModeInput, cl_set_device_clock_mode_output_amd* pSetClockModeOutput);
virtual bool SetSvmAttributes(const void* dev_ptr, size_t count,
amd::MemoryAdvice advice, bool first_alloc = false) const;
virtual bool GetSvmAttributes(void** data, size_t* data_sizes, int* attributes,
size_t num_attributes, const void* dev_ptr, size_t count) const;
virtual bool SetClockMode(const cl_set_device_clock_mode_input_amd setClockModeInput,
cl_set_device_clock_mode_output_amd* pSetClockModeOutput);
//! Returns transfer engine object
const device::BlitManager& xferMgr() const { return xferQueue()->blitMgr(); }
@@ -464,7 +470,12 @@ class Device : public NullDevice {
roc::Memory* getGpuMemory(amd::Memory* mem //!< Pointer to AMD memory object
) const;
//! Initialize memory in AMD HMM on the current device or keeps it in the host memory
bool SvmAllocInit(void* memory, size_t size) const;
private:
static const hsa_signal_value_t InitSignalValue = 1;
static hsa_ven_amd_loader_1_00_pfn_t amd_loader_ext_table;
amd::Monitor* mapCacheOps_; //!< Lock to serialise cache for the map resources
@@ -485,6 +496,8 @@ class Device : public NullDevice {
hsa_amd_memory_pool_t system_coarse_segment_;
hsa_amd_memory_pool_t gpuvm_segment_;
hsa_amd_memory_pool_t gpu_fine_grained_segment_;
hsa_signal_t prefetch_signal_; //!< Prefetch signal, used to explicitly prefetch SVM on device
size_t gpuvm_segment_max_alloc_;
size_t alloc_granularity_;
static const bool offlineDevice_;
+42 -11
View File
@@ -42,7 +42,7 @@
namespace roc {
/////////////////////////////////roc::Memory//////////////////////////////
// ======================================= roc::Memory ============================================
Memory::Memory(const roc::Device& dev, amd::Memory& owner)
: device::Memory(owner),
dev_(dev),
@@ -620,8 +620,7 @@ void Memory::mgpuCacheWriteBack() {
}
}
/////////////////////////////////roc::Buffer//////////////////////////////
// ==================================== roc::Buffer ===============================================
Buffer::Buffer(const roc::Device& dev, amd::Memory& owner) : roc::Memory(dev, owner) {}
Buffer::Buffer(const roc::Device& dev, size_t size) : roc::Memory(dev, size) {}
@@ -634,6 +633,7 @@ Buffer::~Buffer() {
}
}
// ================================================================================================
void Buffer::destroy() {
if (owner()->parent() != nullptr) {
return;
@@ -647,15 +647,24 @@ void Buffer::destroy() {
cl_mem_flags memFlags = owner()->getMemFlags();
if (owner()->getSvmPtr() != nullptr) {
if (dev().forceFineGrain(owner()) ||
dev().isFineGrainedSystem(true)) {
if (dev().forceFineGrain(owner()) || dev().isFineGrainedSystem(true)) {
memFlags |= CL_MEM_SVM_FINE_GRAIN_BUFFER;
}
const bool isFineGrain = memFlags & CL_MEM_SVM_FINE_GRAIN_BUFFER;
if (kind_ != MEMORY_KIND_PTRGIVEN) {
if (isFineGrain) {
dev().hostFree(deviceMemory_, size());
if (memFlags & CL_MEM_ALLOC_HOST_PTR) {
#if AMD_HMM_SUPPORT
// AMD HMM path. Destroy system memory
amd::Os::uncommitMemory(deviceMemory_, size());
amd::Os::releaseMemory(deviceMemory_, size());
#else
dev().hostFree(deviceMemory_, size());;
#endif // AMD_HMM_SUPPORT
} else {
dev().hostFree(deviceMemory_, size());
}
} else {
dev().memFree(deviceMemory_, size());
}
@@ -705,6 +714,7 @@ void Buffer::destroy() {
}
}
// ================================================================================================
bool Buffer::create() {
if (owner() == nullptr) {
deviceMemory_ = dev().hostAlloc(size(), 1, false);
@@ -731,7 +741,19 @@ bool Buffer::create() {
if (owner()->getSvmPtr() == reinterpret_cast<void*>(1)) {
if (isFineGrain) {
if (memFlags & CL_MEM_SVM_ATOMICS) {
if (memFlags & CL_MEM_ALLOC_HOST_PTR) {
#if AMD_HMM_SUPPORT
// AMD HMM path. Just allocate system memory and KFD will manage it
deviceMemory_ = amd::Os::reserveMemory(
0, size(), amd::Os::pageSize(), amd::Os::MEM_PROT_RW);
amd::Os::commitMemory(deviceMemory_, size(), amd::Os::MEM_PROT_RW);
// Currently HMM requires cirtain initial calls to mark sysmem allocation as
// GPU accessible or prefetch memory into GPU
dev().SvmAllocInit(deviceMemory_, size());
#else
deviceMemory_ = dev().hostAlloc(size(), 1, false);
#endif // AMD_HMM_SUPPORT
} else if (memFlags & CL_MEM_SVM_ATOMICS) {
deviceMemory_ = dev().hostAlloc(size(), 1, true);
}
else {
@@ -745,6 +767,14 @@ bool Buffer::create() {
} else {
deviceMemory_ = owner()->getSvmPtr();
kind_ = MEMORY_KIND_PTRGIVEN;
#if AMD_HMM_SUPPORT
if (memFlags & CL_MEM_ALLOC_HOST_PTR) {
// Currently HMM requires cirtain initial calls to mark sysmem allocation as
// GPU accessible or prefetch memory into the current device
// @note: Skip any allocaiton here, since sysmem was allocated on another device.
dev().SvmAllocInit(deviceMemory_, size());
}
#endif // AMD_HMM_SUPPORT
}
if (!isFineGrain && (owner()->parent() != nullptr) &&
@@ -870,9 +900,10 @@ bool Buffer::create() {
if (owner()->getSvmPtr() != owner()->getHostMem()) {
if (memFlags & (CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR)) {
hsa_amd_memory_pool_t pool = (memFlags & CL_MEM_SVM_ATOMICS)? dev().SystemSegment() : dev().SystemCoarseSegment();
hsa_status_t status = hsa_amd_memory_lock_to_pool(owner()->getHostMem(), owner()->getSize(), nullptr,
0, pool, 0, &deviceMemory_);
hsa_amd_memory_pool_t pool = (memFlags & CL_MEM_SVM_ATOMICS) ?
dev().SystemSegment() : dev().SystemCoarseSegment();
hsa_status_t status = hsa_amd_memory_lock_to_pool(owner()->getHostMem(),
owner()->getSize(), nullptr, 0, pool, 0, &deviceMemory_);
if (status != HSA_STATUS_SUCCESS) {
DevLogPrintfError("Failed to lock memory to pool, failed with hsa_status: %d \n", status);
deviceMemory_ = nullptr;
@@ -887,7 +918,7 @@ bool Buffer::create() {
return deviceMemory_ != nullptr;
}
/////////////////////////////////roc::Image//////////////////////////////
// ======================================= roc::Image =============================================
typedef struct ChannelOrderMap {
uint32_t cl_channel_order;
hsa_ext_image_channel_order_t hsa_channel_order;
@@ -86,6 +86,9 @@ Settings::Settings() {
lcWavefrontSize64_ = true;
imageBufferWar_ = false;
hmmFlags_ = (!flagIsDefault(ROC_HMM_FLAGS)) ? ROC_HMM_FLAGS :
Hmm::EnableSystemMemory | Hmm::EnableMallocPrefetch;
}
bool Settings::create(bool fullProfile, int gfxipMajor, int gfxipMinor, bool coop_groups) {
@@ -34,6 +34,13 @@ namespace roc {
//! Device settings
class Settings : public device::Settings {
public:
enum Hmm : uint32_t {
EnableSystemMemory = 0x01, //!< Forces system memory preference by default
EnableMallocPrefetch = 0x02, //!< Skips default prefetch after allocation
EnableSvmTracking = 0x04, //!< Enables SW SVM tracking
EnableDebugSvm = 0x08 //!< Extra debug flag (reserved for runtime developers)
};
union {
struct {
uint doublePrecision_ : 1; //!< Enables double precision support
@@ -75,6 +82,8 @@ class Settings : public device::Settings {
size_t sdmaCopyThreshold_; //!< Use SDMA to copy above this size
uint32_t hmmFlags_; //!< HMM functionality control flags
//! Default constructor
Settings();
@@ -1170,6 +1170,7 @@ void VirtualGPU::submitWriteMemory(amd::WriteMemoryCommand& cmd) {
profilingEnd(cmd);
}
// ================================================================================================
void VirtualGPU::submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd) {
// Make sure VirtualGPU has an exclusive access to the resources
amd::ScopedLock lock(execution());
@@ -1191,6 +1192,31 @@ void VirtualGPU::submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd) {
profilingEnd(cmd);
}
// ================================================================================================
void VirtualGPU::submitSvmPrefetchAsync(amd::SvmPrefetchAsyncCommand& cmd) {
#if ROCR_HMM_SUPPORT
// Initialize signal for the barrier
hsa_signal_store_relaxed(barrier_signal_, InitSignalValue);
// Find the requested agent for the transfer
hsa_agent_t agent = cmd.cpu_access() ? dev().cpu_agent() ? gpu_device();
// Initiate a prefetch command
hsa_amd_svm_prefetch_async(cmd.dev_prt(), cmd.count(), agent, 0, nullptr, barrier_signal_);
// Wait for the prefetch
if (hsa_signal_wait_acquire(barrier_signal_, HSA_SIGNAL_CONDITION_EQ, 0, uint64_t(-1),
HSA_WAIT_STATE_BLOCKED) != 0) {
LogError("Barrier packet submission failed");
return false;
}
// Add system scope, since the prefetch scope is unclear
addSystemScope();
#endif // ROCR_HMM_SUPPORT
}
// ================================================================================================
bool VirtualGPU::copyMemory(cl_command_type type, amd::Memory& srcMem, amd::Memory& dstMem,
bool entire, const amd::Coord3D& srcOrigin,
const amd::Coord3D& dstOrigin, const amd::Coord3D& size,
@@ -208,6 +208,7 @@ class VirtualGPU : public device::VirtualDevice {
void submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd);
void submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd);
void submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd);
void submitSvmPrefetchAsync(amd::SvmPrefetchAsyncCommand& cmd);
// { roc OpenCL integration
// Added these stub (no-ops) implementation of pure virtual methods,
+9 -1
View File
@@ -203,7 +203,6 @@ bool Event::awaitCompletion() {
lock_.wait();
}
}
ClPrint(LOG_DEBUG, LOG_WAIT, "event %p wait completed", this);
}
@@ -633,4 +632,13 @@ bool CopyMemoryP2PCommand::validateMemory() {
return true;
}
// ================================================================================================
bool SvmPrefetchAsyncCommand::validateMemory() {
amd::Memory* svmMem = svmMem = amd::MemObjMap::FindMemObj(dev_ptr());
if (nullptr == svmMem) {
LogPrintfError("SvmPrefetchAsync received unknown memory for prefetch: %p!", dev_ptr());
return false;
}
}
} // namespace amd
+23 -1
View File
@@ -1364,7 +1364,6 @@ class TransferBufferFileCommand : public OneMemoryArgCommand {
* as 1D structures so origin_[0] and size_[0] are
* equivalent to offset_ and count_ respectively.
*/
class CopyMemoryP2PCommand : public CopyMemoryCommand {
public:
CopyMemoryP2PCommand(HostQueue& queue, cl_command_type cmdType,
@@ -1378,6 +1377,29 @@ class CopyMemoryP2PCommand : public CopyMemoryCommand {
bool validateMemory();
};
/*! \brief Prefetch command for SVM memory
*
* \details Prefetches SVM memory into the current device or CPU
*/
class SvmPrefetchAsyncCommand : public Command {
const void* dev_ptr_; //!< Device pointer to memory for prefetch
size_t count_; //!< the size for prefetch
bool cpu_access_; //!< Prefetch data into CPU location
public:
SvmPrefetchAsyncCommand(HostQueue& queue, const EventWaitList& eventWaitList,
const void* dev_ptr, size_t count, bool cpu_access)
: Command(queue, 1, eventWaitList), dev_ptr_(dev_ptr), count_(count), cpu_access_(cpu_access) {}
virtual void submit(device::VirtualDevice& device) { device.submitSvmPrefetchAsync(*this); }
bool validateMemory();
const void* dev_ptr() const { return dev_ptr_; }
size_t count() const { return count_; }
size_t cpu_access() const { return cpu_access_; }
};
/*! @}
* @}
*/
+2
View File
@@ -56,6 +56,8 @@ debug(size_t, PARAMETERS_MIN_ALIGNMENT, 16, \
"Minimum alignment required for the abstract parameters stack") \
debug(size_t, MEMOBJ_BASE_ADDR_ALIGN, 4*Ki, \
"Alignment of the base address of any allocate memory object") \
release(uint, ROC_HMM_FLAGS, 0, \
"ROCm HMM configuration flags") \
release(cstring, GPU_DEVICE_ORDINAL, "", \
"Select the device ordinal (comma seperated list of available devices)") \
release(bool, REMOTE_ALLOC, false, \