Added dispatch time, async copy and test template rocrtst tests

Change-Id: I57a844ee65c36bd61616ee6d60d358303f51db56
This commit is contained in:
Chris Freehill
2017-06-28 10:54:57 -05:00
parent 08d5efe29d
commit a12c5628ea
73 changed files with 1592 additions and 9290 deletions
+2 -3
View File
@@ -50,11 +50,9 @@
namespace rocrtst {
BaseRocR::BaseRocR(void) {
num_iteration_ = 100;
signal_.handle = 0;
num_iteration_ = 1;
cpu_device_.handle = -1;
gpu_device1_.handle = -1;
region_.handle = 0;
device_pool_.handle = 0;
kern_arg_pool_.handle = 0;
main_queue_ = nullptr;
@@ -66,6 +64,7 @@ BaseRocR::BaseRocR(void) {
orig_hsa_enable_interrupt_ = GetEnv("HSA_ENABLE_INTERRUPT");
set_kernel_file_name("");
set_verbosity(0);
set_title("unset_title");
}
BaseRocR::~BaseRocR() {
Regular → Executable
-17
View File
@@ -105,13 +105,6 @@ class BaseRocR {
return kernel_object_;
}
void set_signal(hsa_signal_t sig) {
signal_.handle = sig.handle;
}
const hsa_signal_t& signal(void) const {
return signal_;
}
void set_profile(hsa_profile_t in_prof) {
profile_ = in_prof;
}
@@ -151,10 +144,6 @@ class BaseRocR {
return aql_;
}
hsa_region_t& region(void) {
return region_;
}
void set_num_iteration(int num) {
num_iteration_ = num;
}
@@ -237,16 +226,12 @@ class BaseRocR {
private:
uint64_t num_iteration_; ///< Number of times to execute test
hsa_signal_t signal_; ///< Completion signal used for kernel execution
hsa_queue_t* main_queue_; ///< AQL queue used for packets
hsa_agent_t gpu_device1_; ///< Handle to first GPU found
hsa_agent_t cpu_device_; ///< Handle to CPU
hsa_region_t region_; ///< TODO(cfreehil): delete this
hsa_amd_memory_pool_t device_pool_; ///< Memory pool on gpu pool list
hsa_amd_memory_pool_t cpu_pool_; ///< Memory pool on cpu pool list
@@ -255,8 +240,6 @@ class BaseRocR {
uint64_t kernel_object_; ///< Handle to kernel code
std::string brig_file_; // TODO(cfreehil): delete this
std::string kernel_file_name_; ///< Code object file name
std::string kernel_name_; ///< Kernel name
+58 -64
View File
@@ -70,6 +70,8 @@ namespace rocrtst {
} \
}
// Clean up some of the common handles and memory used by BaseRocR code, then
// shut down hsa. Restore HSA_ENABLE_INTERRUPT to original value, if necessary
hsa_status_t CommonCleanUp(BaseRocR* test) {
hsa_status_t err;
@@ -87,13 +89,9 @@ hsa_status_t CommonCleanUp(BaseRocR* test) {
test->set_main_queue(nullptr);
}
if (0 != test->signal().handle) {
hsa_signal_t sig;
sig.handle = 0;
err = hsa_signal_destroy(test->signal());
if (test->aql().completion_signal.handle != 0) {
err = hsa_signal_destroy(test->aql().completion_signal);
RET_IF_HSA_UTILS_ERR(err);
test->set_signal(sig);
}
err = hsa_shut_down();
@@ -122,7 +120,7 @@ static const char* PROFILE_STR[] = {"HSA_PROFILE_BASE", "HSA_PROFILE_FULL", };
/// \returns bool
/// - true Machine meets test requirements
/// - false Machine does not meet test requirements
static bool CheckProfileAndInform(BaseRocR* test) {
bool CheckProfileAndInform(BaseRocR* test) {
if (test->verbosity() > 0) {
std::cout << "Target HW Profile is "
<< PROFILE_STR[test->profile()] << std::endl;
@@ -162,6 +160,10 @@ static hsa_status_t ProcessIterateError(hsa_status_t err) {
return err;
}
// Find pools for cpu, gpu and for kernel arguments. These pools have
// common basic requirements, but are not suitable for all cases. In
// that case, set cpu_pool(), device_pool() and/or kern_arg_pool()
// yourself instead of using this function.
hsa_status_t SetPoolsTypical(BaseRocR* test) {
hsa_status_t err;
@@ -180,11 +182,9 @@ hsa_status_t SetPoolsTypical(BaseRocR* test) {
return HSA_STATUS_SUCCESS;
}
// Enable interrupts if necessary, and call hsa_init()
hsa_status_t InitAndSetupHSA(BaseRocR* test) {
hsa_agent_t gpu_device1;
hsa_agent_t cpu_device;
hsa_status_t err;
hsa_signal_t sig;
if (test->enable_interrupt()) {
SetEnv("HSA_ENABLE_INTERRUPT", "1");
@@ -193,6 +193,15 @@ hsa_status_t InitAndSetupHSA(BaseRocR* test) {
err = hsa_init();
RET_IF_HSA_UTILS_ERR(err);
return HSA_STATUS_SUCCESS;
}
// Attempt to find and set test->cpu_device and test->gpu_device1
hsa_status_t SetDefaultAgents(BaseRocR* test) {
hsa_agent_t gpu_device1;
hsa_agent_t cpu_device;
hsa_status_t err;
gpu_device1.handle = 0;
err = hsa_iterate_agents(FindGPUDevice, &gpu_device1);
RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));
@@ -217,7 +226,7 @@ hsa_status_t InitAndSetupHSA(BaseRocR* test) {
char name[64] = {0};
err = hsa_agent_get_info(gpu_device1, HSA_AGENT_INFO_NAME, name);
RET_IF_HSA_UTILS_ERR(err);
std::cout << "The device name is " << name << std::endl;
std::cout << "The gpu device name is " << name << std::endl;
}
hsa_profile_t profile;
@@ -228,14 +237,11 @@ hsa_status_t InitAndSetupHSA(BaseRocR* test) {
if (!CheckProfileAndInform(test)) {
return HSA_STATUS_ERROR;
}
err = hsa_signal_create(1, 0, NULL, &sig);
RET_IF_HSA_UTILS_ERR(err);
test->set_signal(sig);
return HSA_STATUS_SUCCESS;
}
// See if the profile of the target matches any required profile by the
// test program.
bool CheckProfile(BaseRocR const* test) {
if (test->requires_profile() == -1) {
return true;
@@ -243,6 +249,19 @@ bool CheckProfile(BaseRocR const* test) {
return (test->requires_profile() == test->profile());
}
}
// Load the specified kernel code from the specified file, inspect and fill
// in BaseRocR member variables related to the kernel and executable.
// Required Input BaseRocR member variables:
// - gpu_device1()
// - kernel_file_name()
// - kernel_name()
//
// Written BaseRocR member variables:
// -kernel_object()
// -private_segment_size()
// -group_segment_size()
// -kernarg_size()
// -kernarg_align()
hsa_status_t LoadKernelFromObjFile(BaseRocR* test) {
hsa_status_t err;
hsa_code_object_reader_t code_obj_rdr = {0};
@@ -334,13 +353,16 @@ hsa_status_t CreateQueue(hsa_agent_t device, hsa_queue_t** queue,
return HSA_STATUS_SUCCESS;
}
void InitializeAQLPacket(const BaseRocR* test,
// Initialize the provided aql packet with standard default values, and
// values from provided BaseRocR object.
hsa_status_t InitializeAQLPacket(const BaseRocR* test,
hsa_kernel_dispatch_packet_t* aql) {
hsa_status_t err;
assert(aql != nullptr);
if (aql == nullptr) {
return;
return HSA_STATUS_ERROR;
}
aql->header = 0; // Set this right before doorbell ring
@@ -361,19 +383,25 @@ void InitializeAQLPacket(const BaseRocR* test,
// Pin kernel code and the kernel argument buffer to the aql packet->
aql->kernel_object = test->kernel_object();
aql->kernarg_address = NULL;
aql->completion_signal.handle = test->signal().handle;
// aql->kernarg_address may be filled in by AllocAndSetKernArgs() if it is
// called before this function, so we don't want overwrite it, therefore
// we ignore it in this function.
return;
err = hsa_signal_create(1, 0, NULL, &aql->completion_signal);
return err;
}
void WriteAQLToQueue(BaseRocR* test) {
// Copy BaseRocR aql object values to the BaseRocR object queue in the
// specified queue position (ind)
hsa_kernel_dispatch_packet_t * WriteAQLToQueue(BaseRocR* test, uint64_t *ind) {
assert(test);
assert(test->main_queue());
void *queue_base = test->main_queue()->base_address;
const uint32_t queue_mask = test->main_queue()->size - 1;
uint64_t que_idx = hsa_queue_add_write_index_relaxed(test->main_queue(), 1);
*ind = que_idx;
hsa_kernel_dispatch_packet_t* staging_aql_packet = &test->aql();
hsa_kernel_dispatch_packet_t* queue_aql_packet;
@@ -395,8 +423,12 @@ void WriteAQLToQueue(BaseRocR* test) {
queue_aql_packet->kernel_object = staging_aql_packet->kernel_object;
queue_aql_packet->kernarg_address = staging_aql_packet->kernarg_address;
queue_aql_packet->completion_signal = staging_aql_packet->completion_signal;
return queue_aql_packet;
}
// Allocate a buffer in the kern_arg_pool for the kernel arguments and write
// the arguments to buffer
hsa_status_t AllocAndSetKernArgs(BaseRocR* test, void* args, size_t arg_size) {
void* kern_arg_buf = nullptr;
hsa_status_t err;
@@ -421,56 +453,18 @@ hsa_status_t AllocAndSetKernArgs(BaseRocR* test, void* args, size_t arg_size) {
assert(((uintptr_t)adj_kern_arg_buf + arg_size) <
((uintptr_t)kern_arg_buf + buf_size));
err = hsa_memory_copy_workaround_cpu(adj_kern_arg_buf, args, arg_size);
RET_IF_HSA_UTILS_ERR(err);
hsa_agent_t ag_list[2] = {*test->gpu_device1(), *test->cpu_device()};
err = hsa_amd_agents_allow_access(2, ag_list, NULL, kern_arg_buf);
RET_IF_HSA_UTILS_ERR(err);
err = hsa_memory_copy(adj_kern_arg_buf, args, arg_size);
RET_IF_HSA_UTILS_ERR(err);
test->aql().kernarg_address = adj_kern_arg_buf;
return HSA_STATUS_SUCCESS;
}
hsa_status_t AllocAndAllowAccess(BaseRocR* test, size_t len,
hsa_amd_memory_pool_t pool, void**buffer) {
hsa_status_t err;
err = hsa_amd_memory_pool_allocate(pool, len, 0, buffer);
RET_IF_HSA_UTILS_ERR(err);
hsa_agent_t ag_list[2] = {*test->gpu_device1(), *test->cpu_device()};
err = hsa_amd_agents_allow_access(2, ag_list, NULL, *buffer);
RET_IF_HSA_UTILS_ERR(err);
return err;
}
hsa_status_t hsa_memory_fill_workaround_gen(void* ptr, uint32_t value,
size_t count, hsa_agent_t dst_ag, hsa_agent_t src_ag, BaseRocR* test) {
hsa_status_t err;
void *tmp_mem;
err = hsa_amd_memory_pool_allocate(test->cpu_pool(), count, 0, &tmp_mem);
RET_IF_HSA_UTILS_ERR(err);
hsa_agent_t ag_list[2] = {*test->gpu_device1(), *test->cpu_device()};
err = hsa_amd_agents_allow_access(2, ag_list, NULL, tmp_mem);
RET_IF_HSA_UTILS_ERR(err);
(void)memset(tmp_mem, value, count);
err = hsa_memory_copy_workaround_gen(ptr, tmp_mem, count, dst_ag, src_ag);
RET_IF_HSA_UTILS_ERR(err);
hsa_amd_memory_pool_free(tmp_mem);
return HSA_STATUS_SUCCESS;
}
#undef RET_IF_HSA_UTILS_ERR
} // namespace rocrtst
+19 -19
View File
@@ -60,14 +60,16 @@ namespace rocrtst {
/// \param[in] test Test for which the kernel will be loaded.
/// \returns HSA_STATUS_SUCCESS if no errors
hsa_status_t LoadKernelFromObjFile(BaseRocR* test);
/// Do initialization tasks for HSA test program. This includes calling
/// hsa_init(), finding and setting the cpu and gpu agent member variables,
/// creating the signal needed for queueing AQL packets and checking
/// HW requirements.
/// Do initialization tasks for HSA test program.
/// \param[in] test Test to initialize
/// \returns HSA_STATUS_SUCCESS if no errors
hsa_status_t InitAndSetupHSA(BaseRocR* test);
/// Find and set the cpu and gpu agent member variables. Also checks that
/// gpu agent meets test requirements (e.g., FULL profile vs. BASE profile).
hsa_status_t SetDefaultAgents(BaseRocR* test);
/// For the provided device agent, create an AQL queue
/// \param[in] device Device for which a queue is to be created
/// \param[out] queue Address to which created queue pointer will be written
@@ -84,16 +86,16 @@ hsa_status_t CreateQueue(hsa_agent_t device, hsa_queue_t** queue,
/// be drawn.
/// \param[inout] aql Caller provided pointer to aql packet that will be
/// populated
/// \returns void
void InitializeAQLPacket(const BaseRocR* test,
/// \returns Appropriate hsa_status_t
hsa_status_t InitializeAQLPacket(const BaseRocR* test,
hsa_kernel_dispatch_packet_t* aql);
/// This function writes all of the aql packet fields to the queue besides
/// "setup" and "header". This assumes all the aql fields have be set
/// appropriately.
/// \param[in] test Test containing the queue and aql packet to be written.
/// \returns void
void WriteAQLToQueue(BaseRocR* test);
/// \returns Pointer to dispatch packet in queue that was written to
hsa_kernel_dispatch_packet_t* WriteAQLToQueue(BaseRocR* test, uint64_t *ind);
/// This function writes the first 32 bits of an aql packet to the provided
/// aql packet. This function is meant to be called immediately before
@@ -139,6 +141,15 @@ bool CheckProfile(BaseRocR const* test);
hsa_status_t AllocAndSetKernArgs(BaseRocR* test, void* args,
size_t arg_size);
/// Verify that the machine running the test has the required profile.
/// This function will verify that the execution machine meets any specific
/// test requirement for a profile (HSA_PROFILE_BASE or HSA_PROFILE_FULL).
/// \param[in] test Test that provides profile requirements.
/// \returns bool
/// - true Machine meets test requirements
/// - false Machine does not meet test requirements
bool CheckProfileAndInform(BaseRocR* test);
/// This function will set the cpu and gpu memory pools to the type used in
/// many applications.
/// \param[in] test Test that provides profile requirements.
@@ -146,17 +157,6 @@ hsa_status_t AllocAndSetKernArgs(BaseRocR* test, void* args,
/// error code otherwise.
hsa_status_t SetPoolsTypical(BaseRocR* test);
/// Allocate memory from a specified pool and grant both standard BaseRocR
/// agents access
/// \param[in] test Test having the agents to which access is granted
/// \param[in] len Size of the memory buffer to allocate
/// \pool[in] Pool from which to allocate memory
/// \buffer[out] Address of pointer which will point to newly allocated memory
/// upon return
/// \returns HSA_STATUS_OK if no errors
hsa_status_t AllocAndAllowAccess(BaseRocR* test, size_t len,
hsa_amd_memory_pool_t pool, void**buffer);
/// Work-around for hsa_amd_memory_fill, which is currently broken.
/// \param[in] ptr Pointer to start of memory location to be filled
/// \param[in] value Value to write to each byte of input buffer
-39
View File
@@ -341,45 +341,6 @@ hsa_status_t DumpPointerInfo(void* ptr) {
return HSA_STATUS_SUCCESS;
}
hsa_status_t hsa_memory_fill_workaround_cpu(void* ptr, uint32_t value,
size_t count) {
(void)memset(ptr, value, count);
return HSA_STATUS_SUCCESS;
}
hsa_status_t hsa_memory_copy_workaround_cpu(void* dst, const void *src,
size_t size) {
(void)memcpy(dst, src, size);
return HSA_STATUS_SUCCESS;
}
hsa_status_t hsa_memory_copy_workaround_gen(void* dst, const void *src,
size_t size, hsa_agent_t dst_ag, hsa_agent_t src_ag) {
hsa_signal_t s;
hsa_status_t err;
err = hsa_signal_create(1, 0, NULL, &s);
RET_IF_HSA_COMMON_ERR(err);
err = hsa_amd_memory_async_copy(dst, dst_ag, src, src_ag, size, 0, NULL, s);
RET_IF_HSA_COMMON_ERR(err);
if (hsa_signal_wait_scacquire(s, HSA_SIGNAL_CONDITION_LT, 1,
UINT64_MAX, HSA_WAIT_STATE_BLOCKED) != 0) {
err = HSA_STATUS_ERROR;
std::cout << "Async copy signal error" << std::endl;
RET_IF_HSA_COMMON_ERR(err);
}
err = hsa_signal_destroy(s);
RET_IF_HSA_COMMON_ERR(err);
return err;
}
/*! \brief Writes to the buffer and increments the write pointer to the
* buffer. Also, ensures that the argument is written to an
-30
View File
@@ -140,35 +140,5 @@ hsa_status_t DumpMemoryPoolInfo(const hsa_amd_memory_pool_t pool,
/// \returns HSA_STATUS_SUCCESS if there are no errors
hsa_status_t DumpPointerInfo(void* ptr);
/// This is a work-around for filling cpu-memory to be used until
/// hsa_amd_memory_fill is fixed. Should only be used for cpu memory.
/// \param[in] ptr Start address of memory to be filled.
/// \param[in] value Value to fill buffer with
/// \param[in] count Size of buffer to fill
/// \returns HSA_STATUS_SUCCESS if there are no errors
hsa_status_t hsa_memory_fill_workaround_cpu(void* ptr, uint32_t value,
size_t count);
/// This is a work-around for copying cpu-memory to be used until
/// hsa_amd_memory_copy is fixed. Should only be used for cpu memory.
/// \param[in] dst Destination address of memory to be copied
/// \param[in] src Source address of memory to be copied
/// \param[in] size Size of buffer to fill
/// \returns HSA_STATUS_SUCCESS if there are no errors
hsa_status_t hsa_memory_copy_workaround_cpu(void* dst, const void *src,
size_t size);
/// This is a work-around for copying memory to be used until
/// hsa_amd_memory_copy is fixed. Should be used when gpu local memory is
/// involved.
/// \param[in] dst Destination address of memory to be copied
/// \param[in] src Source address of memory to be copied
/// \param[in] size Size of buffer to fill
/// \param[in] dst_ag Destination agent handle
/// \param[in] src_ag Source agent handle
/// \returns HSA_STATUS_SUCCESS if there are no errors
hsa_status_t hsa_memory_copy_workaround_gen(void* dst, const void *src,
size_t size, hsa_agent_t dst_ag, hsa_agent_t src_ag);
} // namespace rocrtst
#endif // ROCRTST_COMMON_COMMON_H_
+6 -10
View File
@@ -52,10 +52,10 @@
#include <iostream>
#include <string>
#include <vector>
#include <numeric>
namespace rocrtst {
template<typename T>
void PrintArray(const std::string header, const T* data, const int width,
const int height) {
@@ -191,7 +191,7 @@ AlignUp(void* value, size_t alignment) {
alignment));
}
double CalcMedian(std::vector<double> scores) {
double CalcMedian(const std::vector<double> &scores) {
double median;
size_t size = scores.size();
@@ -204,15 +204,11 @@ double CalcMedian(std::vector<double> scores) {
return median;
}
double CalcMean(std::vector<double> scores) {
double mean = 0;
size_t size = scores.size();
double CalcMean(const std::vector<double> &scores) {
double mean;
for (size_t i = 0; i < size; ++i) {
mean += scores[i];
}
return mean / size;
mean = std::accumulate(scores.begin(), scores.end(), 0.0);
return mean/scores.size();
}
double CalcMean(const std::vector<double>& v1, const std::vector<double>& v2) {
+2 -2
View File
@@ -60,7 +60,7 @@ bool Compare(const double* refData, const double* data,
const int length, const double epsilon = 1e-6);
/// Calculate the mean number of the vector
double CalcMean(std::vector<double> scores);
double CalcMean(const std::vector<double> &scores);
/// Calculate the mean time of difference of the two vectors
double CalcMean(const std::vector<double>& v1, const std::vector<double>& v2);
@@ -68,7 +68,7 @@ double CalcMean(const std::vector<double>& v1, const std::vector<double>& v2);
/// Return the median value of a vector of doubles
/// \param[in] scores Vector of doubles
/// \returns double Median value of provided vector
double CalcMedian(std::vector<double> scores);
double CalcMedian(const std::vector<double> &scores);
/// Calculate the standard deviation of the vector
double CalcStdDeviation(std::vector<double> scores, int score_mean);
+4
View File
@@ -70,6 +70,7 @@ PreDispatchCallback(const hsa_dispatch_callback_t* dispParam, void* usrArg) {
dispParam->aql_translation_handle, true);
assert((status == HSA_STATUS_SUCCESS) &&
"Error in beginning Perf Cntr Session");
(void)status; // Avoid warning
}
static void
@@ -82,6 +83,7 @@ PostDispatchCallback(const hsa_dispatch_callback_t* dispParam, void* usrArg) {
dispParam->aql_translation_handle);
assert((status == HSA_STATUS_SUCCESS) &&
"Error in endning Perf Cntr Session");
(void)status; // Avoid warning
}
/// Constructor of the class
@@ -192,6 +194,8 @@ void RocrPerfCntrApp::RegisterCallbacks(hsa_queue_t* queue) {
status = hsa_ext_tools_set_callback_arguments(queue, &perfMgr_, &perfMgr_);
assert((status == HSA_STATUS_SUCCESS) &&
"Error in registering Pre & Post Dispatch Callback Params");
(void)status; // Avoid warning
return;
}
+1 -2
View File
@@ -176,8 +176,7 @@ uint64_t PerfTimer::MeasureTSCFreqHz() {
do {
tscTicksEnd = __rdtscp(&unused);
}
while (tscTicksEnd - tscTicksBegin < 1000000000);
} while (tscTicksEnd - tscTicksBegin < 1000000000);
uint64_t coarseEndUs = CoarseTimestampUs();
+1
View File
@@ -91,6 +91,7 @@ class PerfTimer {
void ResetTimer(int index);
/// Read the time value of the timer associated with the provided index.
/// Units are seconds
/// \param[in] index Index of the timer to read
/// \returns double Value of the timer
double ReadTimer(int index);