Adding HSA extension AMD AQL profile library, see Readme.txt

Change-Id: Icbc1e0fb0185642eabbab411a2138ea030d22be8
This commit is contained in:
Evgeny
2017-06-06 14:59:08 -05:00
committed by Evgeny Shcherbakov
parent da831502ab
commit 25035b8d09
84 changed files with 16322 additions and 0 deletions
@@ -0,0 +1,91 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include <assert.h>
#include "simple_convolution.h"
#include "test_hsa.h"
#include "test_pgen_pmc.h"
#include "test_pgen_sqtt.h"
int main(int argc, char* argv[]) {
#if defined(NDEBUG)
clog.rdbuf(NULL);
#endif
bool ret_val = true;
// Create SimpleConvolution test object
TestKernel* test_kernel = new SimpleConvolution();
TestAql* test_aql = new TestHSA(test_kernel);
const bool pmc_enable = (getenv("ROCR_ENABLE_PMC") != NULL);
const bool sqtt_enable = (getenv("ROCR_ENABLE_SQTT") != NULL);
if (pmc_enable)
test_aql = new TestPGenPMC(test_aql);
else if (sqtt_enable)
test_aql = new TestPGenSQTT(test_aql);
assert(test_aql != NULL);
if (test_aql == NULL) return 1;
// Initialization of Hsa Runtime
ret_val = test_aql->initialize(argc, argv);
if (ret_val == false) {
std::cout << "Error in the test initialization" << std::endl;
assert(ret_val);
return 1;
}
// Setup Hsa resources needed for execution
ret_val = test_aql->setup();
if (ret_val == false) {
std::cout << "Error in creating hsa resources" << std::endl;
assert(ret_val);
return 1;
}
// Run SimpleConvolution kernel
ret_val = test_aql->run();
if (ret_val == false) {
std::cout << "Error in running the test kernel" << std::endl;
assert(ret_val);
return 1;
}
// Verify the results of the execution
ret_val = test_aql->verify_results();
if (ret_val) {
std::cout << "Test : Passed" << std::endl;
} else {
std::cout << "Test : Failed" << std::endl;
}
// Print time taken by sample
test_aql->print_time();
test_aql->cleanup();
return (ret_val) ? 0 : 1;
}
@@ -0,0 +1,87 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TESTAQL_H_
#define _TESTAQL_H_
#include "hsa.h"
#include "hsa_rsrc_factory.hpp"
#include "hsa_ext_amd_aql_profile.h"
#define test_assert(cond) \
{ \
if (cond) { \
std::cout << "ASSERT FAILED: " << #cond << " : " << __FILE__ << "(" << __LINE__ << ")" \
<< std::endl; \
abort(); \
} \
}
// Test AQL interface
class TestAql {
TestAql* const test_aql;
public:
TestAql(TestAql* t = 0) : test_aql(t) {}
virtual ~TestAql() {}
TestAql* testAql() { return test_aql; }
virtual AgentInfo* getAgentInfo() { return (test_aql) ? test_aql->getAgentInfo() : 0; }
virtual hsa_queue_t* getQueue() { return (test_aql) ? test_aql->getQueue() : 0; }
virtual HsaRsrcFactory* getRsrcFactory() { return (test_aql) ? test_aql->getRsrcFactory() : 0; }
// Initialize application environment including setting
// up of various configuration parameters based on
// command line arguments
// @return bool true on success and false on failure
virtual bool initialize(int argc, char** argv) {
return (test_aql) ? test_aql->initialize(argc, argv) : true;
}
// Setup application parameters for exectuion
// @return bool true on success and false on failure
virtual bool setup() { return (test_aql) ? test_aql->setup() : true; }
// Run the kernel
// @return bool true on success and false on failure
virtual bool run() { return (test_aql) ? test_aql->run() : true; }
// Verify results
// @return bool true on success and false on failure
virtual bool verify_results() { return (test_aql) ? test_aql->verify_results() : true; }
// Print to console the time taken to execute kernel
virtual void print_time() {
if (test_aql) test_aql->print_time();
}
// Release resources e.g. memory allocations
// @return bool true on success and false on failure
virtual bool cleanup() { return (test_aql) ? test_aql->cleanup() : true; }
};
#endif // _TESTAQL_H_
@@ -0,0 +1,234 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include "os.h"
#include "helper_funcs.hpp"
#include "hsa_rsrc_factory.hpp"
#include "test_hsa.h"
bool TestHSA::initialize(int arg_cnt, char** arg_list) {
std::cout << "TestHSA::initialize :" << std::endl;
// Initialize command line arguments
hsa_cmdline_arg_cnt = arg_cnt;
hsa_cmdline_arg_list = arg_list;
// Instantiate a Timer object
setup_timer_idx_ = hsa_timer_.CreateTimer();
dispatch_timer_idx_ = hsa_timer_.CreateTimer();
// Instantiate an instance of Hsa Resources Factory
hsa_rsrc_ = new HsaRsrcFactory();
// Print properties of the agents
hsa_rsrc_->PrintGpuAgents("> GPU agents");
// Create an instance of Gpu agent
const char* p = getenv("ROCR_AGENT_IND");
const uint32_t agent_ind = (p == NULL) ? 0 : atol(p);
if (!hsa_rsrc_->GetGpuAgentInfo(agent_ind, &agent_info_)) {
std::cout << "> error: agent[" << agent_ind << "] is not found" << std::endl;
return false;
}
std::cout << "> Using agent[" << agent_ind << "] : " << agent_info_->name << std::endl;
// Create an instance of Aql Queue
uint32_t num_pkts = 128;
hsa_rsrc_->CreateQueue(agent_info_, num_pkts, &hsa_queue_);
// Obtain handle of signal
hsa_rsrc_->CreateSignal(1, &hsa_signal_);
// Obtain the code object file name
std::string agentName(agent_info_->name);
if (agentName.compare(0, 4, "gfx8") == 0) {
brig_path_obj_.append("gfx8");
} else if (agentName.compare(0, 4, "gfx9") == 0) {
brig_path_obj_.append("gfx9");
} else {
assert(false);
return false;
}
brig_path_obj_.append("_" + name_ + ".hsaco");
return true;
}
bool TestHSA::setup() {
std::cout << "TestHSA::setup :" << std::endl;
// Start the timer object
hsa_timer_.StartTimer(setup_timer_idx_);
mem_map_t& mem_map = test_->get_mem_map();
for (mem_it_t it = mem_map.begin(); it != mem_map.end(); ++it) {
mem_descr_t& des = it->second;
void* ptr = (des.local) ? hsa_rsrc_->AllocateLocalMemory(agent_info_, des.size)
: hsa_rsrc_->AllocateSysMemory(agent_info_, des.size);
des.ptr = ptr;
assert(ptr != NULL);
if (ptr == NULL) return false;
}
test_->init();
// Load and Finalize Kernel Code Descriptor
char* brig_path = (char*)brig_path_obj_.c_str();
const bool ret_val =
hsa_rsrc_->LoadAndFinalize(agent_info_, brig_path, strdup(name_.c_str()), &kernel_code_desc_);
if (ret_val == false) {
std::cout << "Error in loading and finalizing Kernel" << std::endl;
return ret_val;
}
// Stop the timer object
hsa_timer_.StopTimer(setup_timer_idx_);
setup_time_taken_ = hsa_timer_.ReadTimer(setup_timer_idx_);
total_time_taken_ = setup_time_taken_;
return true;
}
bool TestHSA::run() {
std::cout << "TestHSA::run :" << std::endl;
const uint32_t work_group_size = 64;
const uint32_t work_grid_size = test_->get_elements_count();
uint32_t group_segment_size = 0;
uint32_t private_segment_size = 0;
const size_t kernarg_segment_size = test_->get_kernarg_size();
uint64_t code_handle = 0;
// Retrieve the amount of group memory needed
hsa_executable_symbol_get_info(
kernel_code_desc_, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE, &group_segment_size);
// Retrieve the amount of private memory needed
hsa_executable_symbol_get_info(kernel_code_desc_,
HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE,
&private_segment_size);
// Check the kernel args size
size_t size_info = 0;
hsa_executable_symbol_get_info(
kernel_code_desc_, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE, &size_info);
assert(kernarg_segment_size == size_info);
if (kernarg_segment_size != size_info) return false;
// Retrieve handle of the code block
hsa_executable_symbol_get_info(kernel_code_desc_, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT,
&code_handle);
// Initialize the dispatch packet.
hsa_kernel_dispatch_packet_t aql;
memset(&aql, 0, sizeof(aql));
// Set the packet's type, acquire and release fences
aql.header = HSA_PACKET_TYPE_KERNEL_DISPATCH;
aql.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;
aql.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;
// Populate Aql packet with default values
aql.setup = 1;
aql.grid_size_x = work_grid_size;
aql.grid_size_y = 1;
aql.grid_size_z = 1;
aql.workgroup_size_x = work_group_size;
aql.workgroup_size_y = 1;
aql.workgroup_size_z = 1;
// Bind the kernel code descriptor and arguments
aql.kernel_object = code_handle;
aql.kernarg_address = test_->get_kernarg_ptr();
aql.group_segment_size = group_segment_size;
aql.private_segment_size = private_segment_size;
// Initialize Aql packet with handle of signal
aql.completion_signal = hsa_signal_;
// Compute the write index of queue and copy Aql packet into it
const uint64_t que_idx = hsa_queue_load_write_index_relaxed(hsa_queue_);
const uint32_t mask = hsa_queue_->size - 1;
std::cout << "> Executing kernel: \"" << name_ << "\"" << std::endl;
// Start the timer object
hsa_timer_.StartTimer(dispatch_timer_idx_);
// Disable packet so that submission to HW is complete
const auto header = aql.header;
const uint8_t packet_type_mask = (1 << HSA_PACKET_HEADER_WIDTH_TYPE) - 1;
aql.header &= (~packet_type_mask) << HSA_PACKET_HEADER_TYPE;
aql.header |= HSA_PACKET_TYPE_INVALID << HSA_PACKET_HEADER_TYPE;
// Copy Aql packet into queue buffer
((hsa_kernel_dispatch_packet_t*)(hsa_queue_->base_address))[que_idx & mask] = aql;
// After AQL packet is fully copied into queue buffer
// update packet header from invalid state to valid state
std::atomic_thread_fence(std::memory_order_release);
((hsa_kernel_dispatch_packet_t*)(hsa_queue_->base_address))[que_idx & mask].header = header;
// Increment the write index and ring the doorbell to dispatch the kernel.
hsa_queue_store_write_index_relaxed(hsa_queue_, (que_idx + 1));
hsa_signal_store_relaxed(hsa_queue_->doorbell_signal, que_idx);
std::cout << "> Waiting on kernel dispatch signal" << std::endl;
// Wait on the dispatch signal until the kernel is finished.
// Update wait condition to HSA_WAIT_STATE_ACTIVE for Polling
hsa_signal_value_t value = hsa_signal_wait_acquire(hsa_signal_, HSA_SIGNAL_CONDITION_LT, 1,
(uint64_t)-1, HSA_WAIT_STATE_BLOCKED);
// Stop the timer object
hsa_timer_.StopTimer(dispatch_timer_idx_);
dispatch_time_taken_ = hsa_timer_.ReadTimer(dispatch_timer_idx_);
total_time_taken_ += dispatch_time_taken_;
// Copy kernel buffers from local memory into system memory
hsa_rsrc_->TransferData((uint8_t*)test_->get_output_ptr(), (uint8_t*)test_->get_local_ptr(),
test_->get_output_size(), false);
test_->print_output();
return true;
}
bool TestHSA::verify_results() {
// Compare the results and see if they match
const int32_t cmp_val =
memcmp(test_->get_output_ptr(), test_->get_refout_ptr(), test_->get_output_size());
return (cmp_val == 0);
}
void TestHSA::print_time() {
std::cout << "Time taken for Setup by " << this->name_ << " : " << this->setup_time_taken_
<< std::endl;
std::cout << "Time taken for Dispatch by " << this->name_ << " : " << this->dispatch_time_taken_
<< std::endl;
std::cout << "Time taken in Total by " << this->name_ << " : " << this->total_time_taken_
<< std::endl;
}
bool TestHSA::cleanup() {
// shutdown Hsa Runtime system
hsa_status_t ret_val = hsa_shut_down();
return (HSA_STATUS_SUCCESS == ret_val);
}
@@ -0,0 +1,115 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TEST_HSA_H_
#define _TEST_HSA_H_
#include "test_aql.h"
#include "test_kernel.h"
#include "hsa_rsrc_factory.hpp"
// Class implements HSA test
class TestHSA : public TestAql {
public:
// Constructor
TestHSA(TestKernel* test) : test_(test), name_(test->Name()) {
total_time_taken_ = 0;
setup_time_taken_ = 0;
dispatch_time_taken_ = 0;
}
// Get methods for Agent Info, HAS queue, HSA Resourcse Manager
AgentInfo* getAgentInfo() { return agent_info_; }
hsa_queue_t* getQueue() { return hsa_queue_; }
HsaRsrcFactory* getRsrcFactory() { return hsa_rsrc_; }
// Initialize application environment including setting
// up of various configuration parameters based on
// command line arguments
// @return bool true on success and false on failure
bool initialize(int argc, char** argv);
// Setup application parameters for exectuion
// @return bool true on success and false on failure
bool setup();
// Run the BinarySearch kernel
// @return bool true on success and false on failure
bool run();
// Verify against reference implementation
// @return bool true on success and false on failure
bool verify_results();
// Print to console the time taken to execute kernel
void print_time();
// Release resources e.g. memory allocations
// @return bool true on success and false on failure
bool cleanup();
private:
typedef TestKernel::mem_descr_t mem_descr_t;
typedef TestKernel::mem_map_t mem_map_t;
typedef TestKernel::mem_it_t mem_it_t;
// Test object
TestKernel* test_;
// Path of Brig file
std::string brig_path_obj_;
// Used to track time taken to run the sample
double total_time_taken_;
double setup_time_taken_;
double dispatch_time_taken_;
// Handle to an Hsa Gpu Agent
AgentInfo* agent_info_;
// Handle to an Hsa Queue
hsa_queue_t* hsa_queue_;
// Handle of signal
hsa_signal_t hsa_signal_;
// Handle of Kernel Code Descriptor
hsa_executable_symbol_t kernel_code_desc_;
// Instance of timer object
uint32_t setup_timer_idx_;
uint32_t dispatch_timer_idx_;
PerfTimer hsa_timer_;
// Instance of Hsa Resources Factory
HsaRsrcFactory* hsa_rsrc_;
// Test kernel name
std::string name_;
};
#endif // _TEST_HSA_H_
@@ -0,0 +1,105 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TEST_KERNEL_H_
#define _TEST_KERNEL_H_
#include <map>
#include <stdint.h>
// Class implements Kernel test
class TestKernel {
public:
// Memory descriptors IDs
enum { INPUT_DES_ID, OUTPUT_DES_ID, LOCAL_DES_ID, MASK_DES_ID, KERNARG_DES_ID, REFOUT_DES_ID };
// Memory descriptors vector declaration
struct mem_descr_t {
void* ptr;
uint32_t size;
bool local;
};
// Memory map declaration
typedef std::map<uint32_t, mem_descr_t> mem_map_t;
typedef mem_map_t::iterator mem_it_t;
typedef mem_map_t::const_iterator mem_const_it_t;
// Initialize method
virtual void init() = 0;
// Return kernel memory map
mem_map_t& get_mem_map() { return mem_map_; }
// Return NULL descriptor
static mem_descr_t null_descriptor() { return {0, 0, 0}; }
// Methods to get the kernel attributes
void* get_kernarg_ptr() const { return get_descr(KERNARG_DES_ID).ptr; }
uint32_t get_kernarg_size() const { return get_descr(KERNARG_DES_ID).size; }
void* get_output_ptr() const { return get_descr(OUTPUT_DES_ID).ptr; }
uint32_t get_output_size() const { return get_descr(OUTPUT_DES_ID).size; }
void* get_local_ptr() const { return get_descr(LOCAL_DES_ID).ptr; }
void* get_refout_ptr() const { return get_descr(REFOUT_DES_ID).ptr; }
virtual uint32_t get_elements_count() const = 0;
// Print output
virtual void print_output() const = 0;
// Return name
virtual std::string Name() const = 0;
protected:
// Set system memory descriptor
bool set_sys_descr(const uint32_t& id, const uint32_t& size) {
return set_mem_descr(id, size, false);
}
// Set local memory descriptor
bool set_local_descr(const uint32_t& id, const uint32_t& size) {
return set_mem_descr(id, size, true);
}
// Get memory descriptor
mem_descr_t get_descr(const uint32_t& id) const {
mem_const_it_t it = mem_map_.find(id);
return (it != mem_map_.end()) ? it->second : null_descriptor();
}
private:
// Set memory descriptor
bool set_mem_descr(const uint32_t& id, const uint32_t& size, const bool& local) {
const mem_descr_t des = {NULL, size, local};
auto ret = mem_map_.insert(mem_map_t::value_type(id, des));
return ret.second;
}
// Kernel memory map object
mem_map_t mem_map_;
};
#endif // _TEST_KERNEL_H_
@@ -0,0 +1,46 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TEST_PGEN_H_
#define _TEST_PGEN_H_
#include "test_pmgr.h"
#include "hsa_ext_amd_aql_profile.h"
// SimpleConvolution: Class implements OpenCL SimpleConvolution sample
class TestPGen : public TestPMgr {
typedef hsa_ext_amd_aql_pm4_packet_t packet_t;
protected:
packet_t* PrePacket() { return reinterpret_cast<packet_t*>(&prePacket); }
packet_t* PostPacket() { return reinterpret_cast<packet_t*>(&postPacket); }
public:
TestPGen(TestAql* t) : TestPMgr(t) {}
};
#endif // _TEST_PGEN_H_
@@ -0,0 +1,142 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TEST_PGEN_PMC_H_
#define _TEST_PGEN_PMC_H_
#include "test_pgen.h"
hsa_status_t TestPGenPMC_Callback(hsa_ext_amd_aql_profile_info_type_t info_type,
hsa_ext_amd_aql_profile_info_data_t* info_data,
void* callback_data) {
hsa_status_t status = HSA_STATUS_SUCCESS;
typedef std::vector<hsa_ext_amd_aql_profile_info_data_t> passed_data_t;
reinterpret_cast<passed_data_t*>(callback_data)->push_back(*info_data);
return status;
}
// SimpleConvolution: Class implements OpenCL SimpleConvolution sample
class TestPGenPMC : public TestPGen {
const static uint32_t buffer_alignment = 0x1000; // 4K
hsa_agent_t agent;
hsa_ext_amd_aql_profile_profile_t profile;
hsa_ext_amd_aql_profile_event_t events[2];
bool buildPackets() { return true; }
bool dumpData() {
std::cout << "TestPGenPMC::dumpData :" << std::endl;
typedef std::vector<hsa_ext_amd_aql_profile_info_data_t> callback_data_t;
callback_data_t data;
hsa_ext_amd_aql_profile_iterate_data(&profile, TestPGenPMC_Callback, &data);
for (callback_data_t::iterator it = data.begin(); it != data.end(); ++it) {
std::cout << "> sample(" << dec << it->sample_id << ") block("
<< it->pmc_data.event.block_name << "_" << it->pmc_data.event.block_index
<< ") result(" << hex << it->pmc_data.result << ")" << std::endl;
}
return true;
}
public:
TestPGenPMC(TestAql* t) : TestPGen(t) { std::cout << "Test: PGen PMC" << std::endl; }
bool initialize(int arg_cnt, char** arg_list) {
if (!TestPMgr::initialize(arg_cnt, arg_list)) return false;
hsa_status_t status;
hsa_agent_t agent;
uint32_t command_buffer_alignment;
uint32_t command_buffer_size;
uint32_t output_buffer_alignment;
uint32_t output_buffer_size;
// GPU identificator
agent = getAgentInfo()->dev_id;
// Instantiation of the profile object
// //////////////////////////////////////////////////////////////
// Set the event fields
events[0].block_name = HSA_EXT_AQL_PROFILE_BLOCK_SQ;
events[0].block_index = 0;
events[0].counter_id = 0x4; // SQ_SQ_PERF_SEL_WAVES
events[1].block_name = HSA_EXT_AQL_PROFILE_BLOCK_SQ;
events[1].block_index = 0;
events[1].counter_id = 0xe; // SQ_SQ_PERF_SEL_ITEMS
// Initialization the profile
memset(&profile, 0, sizeof(profile));
profile.agent = agent;
profile.type = HSA_EXT_AQL_PROFILE_EVENT_PMC;
// set enabled events list
profile.events = events;
profile.event_count = 2;
// Profile buffers attributes
command_buffer_alignment = buffer_alignment;
status = hsa_ext_amd_aql_profile_get_info(
&profile, HSA_EXT_AQL_PROFILE_INFO_COMMAND_BUFFER_SIZE, &command_buffer_size);
assert(status == HSA_STATUS_SUCCESS);
output_buffer_alignment = buffer_alignment;
status = hsa_ext_amd_aql_profile_get_info(&profile, HSA_EXT_AQL_PROFILE_INFO_PMC_DATA_SIZE,
&output_buffer_size);
assert(status == HSA_STATUS_SUCCESS);
// Application is allocating the command buffer
// Allocate(command_buffer_alignment, command_buffer_size,
// MODE_HOST_ACC|MODE_DEV_ACC|MODE_EXEC_DATA)
profile.command_buffer.ptr =
getRsrcFactory()->AllocateSysMemory(getAgentInfo(), command_buffer_size);
profile.command_buffer.size = command_buffer_size;
// Application is allocating the output buffer
// Allocate(output_buffer_alignment, output_buffer_size,
// MODE_HOST_ACC|MODE_DEV_ACC)
profile.output_buffer.ptr =
getRsrcFactory()->AllocateSysMemory(getAgentInfo(), output_buffer_size);
profile.output_buffer.size = output_buffer_size;
memset(profile.output_buffer.ptr, 0x77, output_buffer_size);
// Populating the AQL start packet
status = hsa_ext_amd_aql_profile_start(&profile, PrePacket());
assert(status == HSA_STATUS_SUCCESS);
if (status != HSA_STATUS_SUCCESS) return false;
// Populating the AQL stop packet
status = hsa_ext_amd_aql_profile_stop(&profile, PostPacket());
assert(status == HSA_STATUS_SUCCESS);
return (status == HSA_STATUS_SUCCESS);
}
};
#endif // _TEST_PGEN_PMC_H_
@@ -0,0 +1,160 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TEST_PGEN_SQTT_H_
#define _TEST_PGEN_SQTT_H_
#include <iostream>
#include <iomanip>
#include <fstream>
#include "test_pgen.h"
hsa_status_t TestPGenSQTT_Callback(hsa_ext_amd_aql_profile_info_type_t info_type,
hsa_ext_amd_aql_profile_info_data_t* info_data,
void* callback_data) {
hsa_status_t status = HSA_STATUS_SUCCESS;
typedef std::vector<hsa_ext_amd_aql_profile_info_data_t> passed_data_t;
reinterpret_cast<passed_data_t*>(callback_data)->push_back(*info_data);
return status;
}
// SimpleConvolution: Class implements OpenCL SimpleConvolution sample
class TestPGenSQTT : public TestPGen {
const static uint32_t buffer_alignment = 0x1000; // 4K
const static uint32_t buffer_size = 0x2000000; // 32M
hsa_agent_t agent;
hsa_ext_amd_aql_profile_profile_t profile;
bool buildPackets() { return true; }
bool dumpData() {
std::cout << "TestPGenSQTT::dumpData :" << std::endl;
typedef std::vector<hsa_ext_amd_aql_profile_info_data_t> callback_data_t;
callback_data_t data;
hsa_ext_amd_aql_profile_iterate_data(&profile, TestPGenSQTT_Callback, &data);
for (callback_data_t::iterator it = data.begin(); it != data.end(); ++it) {
std::cout << "> sample(" << dec << it->sample_id << ") ptr(" << hex << it->sqtt_data.ptr
<< ") size(" << dec << it->sqtt_data.size << ")" << std::endl;
void* sys_buf = getRsrcFactory()->AllocateSysMemory(getAgentInfo(), it->sqtt_data.size);
assert(sys_buf != NULL);
if (sys_buf == NULL) return HSA_STATUS_ERROR;
hsa_status_t status = hsa_memory_copy(sys_buf, it->sqtt_data.ptr, it->sqtt_data.size);
assert(status == HSA_STATUS_SUCCESS);
if (status != HSA_STATUS_SUCCESS) return status;
std::string file_name;
file_name.append("sqtt_dump_");
file_name.append(std::to_string(it->sample_id));
file_name.append(".txt");
std::ofstream out_file;
out_file.open(file_name);
// Write the buffer in terms of shorts (16 bits)
short* sqtt_data = (short*)sys_buf;
for (int i = 0; i < (it->sqtt_data.size / sizeof(short)); ++i) {
out_file << std::setw(4) << std::setfill('0') << std::hex << sqtt_data[i] << "\n";
}
out_file.close();
}
return true;
}
public:
TestPGenSQTT(TestAql* t) : TestPGen(t) { std::cout << "Test: PGen SQTT" << std::endl; }
bool initialize(int arg_cnt, char** arg_list) {
if (!TestPMgr::initialize(arg_cnt, arg_list)) return false;
hsa_status_t status;
hsa_agent_t agent;
uint32_t command_buffer_alignment;
uint32_t command_buffer_size;
uint32_t output_buffer_alignment;
uint32_t output_buffer_size;
// GPU identificator
agent = getAgentInfo()->dev_id;
// Instantiation of the profile object
// //////////////////////////////////////////////////////////////
// Set the parameters
// parameters = ....;
// Initialization the profile
memset(&profile, 0, sizeof(profile));
profile.agent = agent;
profile.type = HSA_EXT_AQL_PROFILE_EVENT_SQTT;
// set parameters
// profile.parameters = &event;
// profile.parameter_count = 1;
// Profile buffers attributes
command_buffer_alignment = buffer_alignment;
status = hsa_ext_amd_aql_profile_get_info(
&profile, HSA_EXT_AQL_PROFILE_INFO_COMMAND_BUFFER_SIZE, &command_buffer_size);
assert(status == HSA_STATUS_SUCCESS);
output_buffer_alignment = buffer_alignment;
output_buffer_size = buffer_size;
// Application is allocating the command buffer
// AllocateSystem(command_buffer_alignment, command_buffer_size,
// MODE_HOST_ACC|MODE_DEV_ACC|MODE_EXEC_DATA)
profile.command_buffer.ptr =
getRsrcFactory()->AllocateSysMemory(getAgentInfo(), command_buffer_size);
profile.command_buffer.size = command_buffer_size;
// Application is allocating the output buffer
// AllocateLocal(output_buffer_alignment, output_buffer_size,
// MODE_DEV_ACC)
profile.output_buffer.ptr =
getRsrcFactory()->AllocateLocalMemory(getAgentInfo(), output_buffer_size);
profile.output_buffer.size = output_buffer_size;
// Populating the AQL start packet
status = hsa_ext_amd_aql_profile_start(&profile, PrePacket());
assert(status == HSA_STATUS_SUCCESS);
if (status != HSA_STATUS_SUCCESS) return false;
// Populating the AQL stop packet
status = hsa_ext_amd_aql_profile_stop(&profile, PostPacket());
assert(status == HSA_STATUS_SUCCESS);
return (status == HSA_STATUS_SUCCESS);
}
};
#endif // _TEST_PGEN_SQTT_H_
@@ -0,0 +1,98 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include <atomic>
#include <assert.h>
#include "test_pmgr.h"
bool TestPMgr::addPacket(const packet_t* packet) {
packet_t aql_packet = *packet;
// Compute the write index of queue and copy Aql packet into it
uint64_t que_idx = hsa_queue_load_write_index_relaxed(getQueue());
const uint32_t mask = getQueue()->size - 1;
// Disable packet so that submission to HW is complete
const auto header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE;
aql_packet.header &= (~((1 << HSA_PACKET_HEADER_WIDTH_TYPE) - 1)) << HSA_PACKET_HEADER_TYPE;
aql_packet.header |= HSA_PACKET_TYPE_INVALID << HSA_PACKET_HEADER_TYPE;
// Copy Aql packet into queue buffer
((packet_t*)(getQueue()->base_address))[que_idx & mask] = aql_packet;
// After AQL packet is fully copied into queue buffer
// update packet header from invalid state to valid state
std::atomic_thread_fence(std::memory_order_release);
((packet_t*)(getQueue()->base_address))[que_idx & mask].header = header;
// Increment the write index and ring the doorbell to dispatch the kernel.
hsa_queue_store_write_index_relaxed(getQueue(), (que_idx + 1));
hsa_signal_store_relaxed(getQueue()->doorbell_signal, que_idx);
return true;
}
bool TestPMgr::run() {
// Build Aql Pkts
const bool active = buildPackets();
if (active) {
// Submit Pre-Dispatch Aql packet
addPacket(&prePacket);
}
testAql()->run();
if (active) {
// Set post packet completion signal
postPacket.completion_signal = postSignal;
// Submit Post-Dispatch Aql packet
addPacket(&postPacket);
// Wait for Post-Dispatch packet to complete
hsa_signal_wait_acquire(postSignal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)-1,
HSA_WAIT_STATE_BLOCKED);
// Dumping profiling data
dumpData();
}
return true;
}
bool TestPMgr::initialize(int argc, char** argv) {
TestAql::initialize(argc, argv);
hsa_status_t status = hsa_signal_create(1, 0, NULL, &postSignal);
assert(status == HSA_STATUS_SUCCESS);
return (status == HSA_STATUS_SUCCESS);
}
TestPMgr::TestPMgr(TestAql* t) : TestAql(t) {
dummySignal.handle = 0;
postSignal = dummySignal;
}
@@ -0,0 +1,57 @@
/******************************************************************************
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TEST_SMGR_H_
#define _TEST_SMGR_H_
#include "test_aql.h"
#include "amd_aql_pm4_ib_packet.h"
// SimpleConvolution: Class implements OpenCL SimpleConvolution sample
class TestPMgr : public TestAql {
public:
typedef amd_aql_pm4_ib_packet_t packet_t;
private:
bool addPacket(const packet_t* packet);
protected:
packet_t prePacket;
packet_t postPacket;
hsa_signal_t dummySignal;
hsa_signal_t postSignal;
virtual bool buildPackets() { return false; }
virtual bool dumpData() { return false; }
virtual bool initialize(int argc, char** argv);
public:
TestPMgr(TestAql* t);
bool run();
};
#endif // _TEST_SMGR_H_