Files
rocm-systems/rocclr/runtime/device/rocm/rocvirtual.hpp
T
foreman 5ba83829e2 P4 to Git Change 1294024 by lmoriche@lmoriche_opencl_dev on 2016/07/21 12:33:32
SWDEV-94640 - Re-submit CL#1292110 after integration from fsa_foundation:
	      - [OCL-LC-ROCm] OpenCL Runtime Library Implements OpenCL runtime API. Add HSA virtual device to ORCA.
	        Rename hsa_foundation to ROCm

Affected files ...

... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/Makefile#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/build/Makefile#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/build/Makefile.rocm#1 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/mesa_glinterop.h#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocappprofile.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocappprofile.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocbinary.cpp#1 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocbinary.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompiler.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdefs.hpp#4 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#4 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roclib.cpp#1 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roclib.h#1 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprintf.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprintf.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocregisters.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocsettings.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocsettings.hpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.cpp#3 add
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.hpp#3 add
2016-07-21 12:41:26 -04:00

252 lines
8.6 KiB
C++

//
// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved.
//
#pragma once
#include "rocdevice.hpp"
#include "utils/util.hpp"
#include "hsa.h"
#include "hsa_ext_image.h"
#include "hsa_ext_finalize.h"
#include "hsa_ext_amd.h"
#include "rocprintf.hpp"
namespace roc {
class Device;
class Memory;
class Timestamp;
struct ProfilingSignal : public amd::HeapObject
{
hsa_signal_t signal_; //!< HSA signal to track profiling information
Timestamp* ts_; //!< Timestamp object associated with the signal
ProfilingSignal(): ts_(nullptr) { signal_.handle = 0; }
};
// Timestamp for keeping track of some profiling information for various commands
// including EnqueueNDRangeKernel and clEnqueueCopyBuffer.
class Timestamp {
private:
uint64_t start_;
uint64_t end_;
ProfilingSignal* profilingSignal_;
hsa_agent_t agent_;
static double ticksToTime_;
public:
uint64_t getStart() { checkGpuTime(); return start_; }
uint64_t getEnd() { checkGpuTime(); return end_; }
void setProfilingSignal(ProfilingSignal* signal) { profilingSignal_ = signal; }
const ProfilingSignal* getProfilingSignal() const { return profilingSignal_; }
void setAgent(hsa_agent_t agent) { agent_ = agent; }
Timestamp() : start_(0), end_(0), profilingSignal_(nullptr) {
agent_.handle = 0;
}
~Timestamp() {}
//! Finds execution ticks on GPU
void checkGpuTime() {
if (profilingSignal_ != nullptr) {
hsa_amd_profiling_dispatch_time_t time;
hsa_amd_profiling_get_dispatch_time(agent_, profilingSignal_->signal_, &time);
start_ = time.start * ticksToTime_;
end_ = time.end * ticksToTime_;
profilingSignal_->ts_ = nullptr;
profilingSignal_ = nullptr;
}
}
// Start a timestamp (get timestamp from OS)
void start() {
start_ = amd::Os::timeNanos();
}
// End a timestamp (get timestamp from OS)
void end() {
end_ = amd::Os::timeNanos();
}
static void setGpuTicksToTime(double ticksToTime) { ticksToTime_=ticksToTime; }
static double getGpuTicksToTime() { return ticksToTime_; }
};
class VirtualGPU : public device::VirtualDevice {
public:
//! Initial signal value
static const hsa_signal_value_t InitSignalValue = 1;
class MemoryDependency : public amd::EmbeddedObject
{
public:
//! Default constructor
MemoryDependency()
: memObjectsInQueue_(NULL)
, numMemObjectsInQueue_(0)
, maxMemObjectsInQueue_(0) {}
~MemoryDependency() { delete [] memObjectsInQueue_; }
//! Creates memory dependecy structure
bool create(size_t numMemObj);
//! Notify the tracker about new kernel
void newKernel() { endMemObjectsInQueue_ = numMemObjectsInQueue_; }
//! Validates memory object on dependency
void validate(VirtualGPU& gpu, const Memory* memory, bool readOnly);
//! Clear memory dependency
void clear(bool all = true);
private:
struct MemoryState {
uint64_t start_; //! Busy memory start address
uint64_t end_; //! Busy memory end address
bool readOnly_; //! Current GPU state in the queue
};
MemoryState* memObjectsInQueue_; //!< Memory object state in the queue
size_t endMemObjectsInQueue_; //!< End of mem objects in the queue
size_t numMemObjectsInQueue_; //!< Number of mem objects in the queue
size_t maxMemObjectsInQueue_; //!< Maximum number of mem objects in the queue
};
VirtualGPU(Device &device);
~VirtualGPU();
bool create(bool profilingEna);
bool terminate();
const Device& dev() const { return roc_device_; }
void profilingBegin(amd::Command &command, bool drmProfiling = false);
void profilingEnd(amd::Command &command);
void updateCommandsState(amd::Command* list);
void submitReadMemory(amd::ReadMemoryCommand& cmd);
void submitWriteMemory(amd::WriteMemoryCommand& cmd);
void submitCopyMemory(amd::CopyMemoryCommand& cmd);
void submitMapMemory(amd::MapMemoryCommand& cmd);
void submitUnmapMemory(amd::UnmapMemoryCommand& cmd);
void submitKernel(amd::NDRangeKernelCommand& cmd);
bool submitKernelInternal(
const amd::NDRangeContainer& sizes, //!< Workload sizes
const amd::Kernel& kernel, //!< Kernel for execution
const_address parameters, //!< Parameters for the kernel
void *event_handle //!< Handle to OCL event for debugging
);
void submitNativeFn(amd::NativeFnCommand& cmd);
void submitMarker(amd::Marker& cmd);
void submitAcquireExtObjects(amd::AcquireExtObjectsCommand& cmd);
void submitReleaseExtObjects(amd::ReleaseExtObjectsCommand& cmd);
void submitPerfCounter(amd::PerfCounterCommand& cmd){};
void flush(amd::Command* list = NULL, bool wait = false);
void submitFillMemory(amd::FillMemoryCommand& cmd);
void submitMigrateMemObjects(amd::MigrateMemObjectsCommand& cmd);
// { roc OpenCL integration
// Added these stub (no-ops) implementation of pure virtual methods,
// when integrating HSA and OpenCL branches.
// TODO: After inegration, whoever is working on VirtualGPU should write
// actual implemention.
virtual void submitSignal(amd::SignalCommand &cmd) {}
virtual void submitMakeBuffersResident(amd::MakeBuffersResidentCommand &cmd) {}
virtual void submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd);
virtual void submitSvmCopyMemory(amd::SvmCopyMemoryCommand& cmd);
virtual void submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd);
virtual void submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd);
virtual void submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd);
void submitThreadTraceMemObjects(amd::ThreadTraceMemObjectsCommand &cmd) {}
void submitThreadTrace(amd::ThreadTraceCommand &vcmd) {}
/**
* @brief Waits on an outstanding kernel without regard to how
* it was dispatched - with or without a signal
*
* @return bool true if Wait returned successfully, false
* otherwise
*/
bool releaseGpuMemoryFence();
hsa_agent_t gpu_device() { return gpu_device_; }
hsa_queue_t* gpu_queue() { return gpu_queue_; }
// Return pointer to PrintfDbg
PrintfDbg* printfDbg() const {return printfdbg_;}
//! Returns memory dependency class
MemoryDependency& memoryDependency() { return memoryDependency_; }
//! Detects memory dependency for HSAIL kernels and uses appropriate AQL header
bool processMemObjects(
const amd::Kernel& kernel, //!< AMD kernel object for execution
const_address params //!< Pointer to the param's store
);
// } roc OpenCL integration
private:
bool dispatchAqlPacket(
hsa_kernel_dispatch_packet_t* packet, bool blocking = true);
bool dispatchAqlPacket(
hsa_barrier_and_packet_t* packet, bool blocking = true);
template<typename AqlPacket> bool dispatchGenericAqlPacket(
AqlPacket* packet, bool blocking);
void dispatchBarrierPacket(const hsa_barrier_and_packet_t* packet);
void initializeDispatchPacket(hsa_kernel_dispatch_packet_t* packet,
amd::NDRangeContainer& sizes);
bool initPool(size_t kernarg_pool_size, uint signal_pool_count);
void destroyPool();
void* allocKernArg(size_t size, size_t alignment);
void resetKernArgPool() { kernarg_pool_cur_offset_ = 0; }
//! Updates AQL header for the upcomming dispatch
void setAqlHeader(uint16_t header) { aqlHeader_ = header; }
/**
* @brief Maintains the list of sampler allocated for one or more kernel
* submissions.
*/
std::vector<hsa_ext_sampler_t> samplerList_;
/**
* @brief Indicates if a kernel dispatch is outstanding. This flag is
* used to synchronized on kernel outputs.
*/
bool hasPendingDispatch_;
Timestamp* timestamp_;
hsa_agent_t gpu_device_; //!< Physical device
hsa_queue_t* gpu_queue_; //!< Queue associated with a gpu
hsa_barrier_and_packet_t barrier_packet_;
hsa_signal_t barrier_signal_;
uint32_t dispatch_id_; //!< This variable must be updated atomically.
Device& roc_device_; //!< roc device object
void * tools_lib_;
PrintfDbg* printfdbg_;
MemoryDependency memoryDependency_; //!< Memory dependency class
uint16_t aqlHeader_; //!< AQL header for dispatch
char* kernarg_pool_base_;
size_t kernarg_pool_size_;
uint kernarg_pool_cur_offset_;
std::vector<ProfilingSignal> signal_pool_; //!< Pool of signals for profiling
friend class Timestamp;
};
}