ファイル
Sean Keely 9969ed9f0d Add cu masking test.
Change-Id: I8b62ebd60f2edde3ea0b298f0353381855163fea


[ROCm/ROCR-Runtime commit: d27d4545e2]
2022-06-28 11:22:42 -04:00

255 行
8.2 KiB
C++

/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2021-2021, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include "common/rocr.h"
System System::sys;
bool DeviceDiscovery(System& devices) {
hsa_status_t err;
err = hsa_iterate_agents([](hsa_agent_t agent, void* data) {
hsa_status_t err;
System* devices = (System*)data;
Device dev;
dev.agent = agent;
dev.fine = -1u;
dev.coarse = -1u;
hsa_device_type_t type;
err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &type);
CHECK(err);
err = hsa_amd_agent_iterate_memory_pools(agent, [](hsa_amd_memory_pool_t pool, void* data) {
std::vector<Device::Memory>& pools = *reinterpret_cast<std::vector<Device::Memory>*>(data);
hsa_status_t err;
hsa_amd_segment_t segment;
err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);
CHECK(err);
if(segment != HSA_AMD_SEGMENT_GLOBAL)
return HSA_STATUS_SUCCESS;
uint32_t flags;
err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flags);
CHECK(err);
Device::Memory mem;
mem.pool=pool;
mem.fine = (flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED);
mem.kernarg = (flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT);
err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SIZE, &mem.size);
CHECK(err);
err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE, &mem.granule);
CHECK(err);
pools.push_back(mem);
return HSA_STATUS_SUCCESS;
}, (void*)&dev.pools);
if(!dev.pools.empty()) {
for(size_t i=0; i<dev.pools.size(); i++) {
if(dev.pools[i].fine && dev.pools[i].kernarg && dev.fine==-1u)
dev.fine = i;
if(dev.pools[i].fine && !dev.pools[i].kernarg)
dev.fine = i;
if(!dev.pools[i].fine)
dev.coarse = i;
}
if(type == HSA_DEVICE_TYPE_CPU)
devices->cpu_.push_back(dev);
else
devices->gpu_.push_back(dev);
devices->all_devices_.push_back(dev.agent);
}
return HSA_STATUS_SUCCESS;
}, &devices);
[&]() {
for(auto& dev : devices.cpu_) {
for(auto& mem : dev.pools) {
if(mem.fine && mem.kernarg) {
devices.kernarg_ = mem;
return;
}
}
}
}();
if(devices.cpu_.empty() || devices.gpu_.empty() || devices.kernarg_.pool.handle == 0)
return false;
return true;
}
void System::Init() {
hsa_status_t err = hsa_init();
CHECK(err);
DeviceDiscovery(sys);
}
void System::Shutdown() {
sys.~System();
new (&sys) System();
hsa_status_t err = hsa_shut_down();
ASSERT_EQ(HSA_STATUS_SUCCESS, err);
err = hsa_shut_down();
EXPECT_EQ(HSA_STATUS_ERROR_NOT_INITIALIZED, err);
}
CodeObject::CodeObject(std::string filename, Device& agent) : agent(agent.agent) {
hsa_status_t err;
file = open(filename.c_str(), O_RDONLY);
if(file == -1) {
throw std::runtime_error("Could not open file.\n");
}
MAKE_NAMED_SCOPE_GUARD(fileGuard, [&](){ close(file); });
err = hsa_code_object_reader_create_from_file(file, &code_obj_rdr);
CHECK(err);
MAKE_NAMED_SCOPE_GUARD(readerGuard, [&](){ hsa_code_object_reader_destroy(code_obj_rdr); });
err = hsa_executable_create_alt(HSA_PROFILE_FULL, HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT, nullptr, &executable);
CHECK(err);
MAKE_NAMED_SCOPE_GUARD(exeGuard, [&](){ hsa_executable_destroy(executable); });
err = hsa_executable_load_agent_code_object(executable, agent.agent, code_obj_rdr, nullptr, nullptr);
CHECK(err);
err = hsa_executable_freeze(executable, nullptr);
CHECK(err);
exeGuard.Dismiss();
readerGuard.Dismiss();
fileGuard.Dismiss();
}
CodeObject::~CodeObject() {
hsa_executable_destroy(executable);
hsa_code_object_reader_destroy(code_obj_rdr);
close(file);
}
bool CodeObject::GetKernel(std::string name, Kernel& kern) {
hsa_executable_symbol_t symbol;
hsa_status_t err = hsa_executable_get_symbol_by_name(executable, name.c_str(), &agent, &symbol);
if(err != HSA_STATUS_SUCCESS) {
err = hsa_executable_get_symbol_by_name(executable, (name+".kd").c_str(), &agent, &symbol);
if(err != HSA_STATUS_SUCCESS) {
return false;
}
}
err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &kern.handle);
CHECK(err);
err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE, &kern.scratch);
CHECK(err);
//printf("Scratch: %d\n", kern.scratch);
err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE, &kern.group);
CHECK(err);
//printf("LDS: %d\n", kern.group);
// Remaining needs code object v2 or comgr.
err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE, &kern.kernarg_size);
CHECK(err);
//printf("Kernarg Size: %d\n", kern.kernarg_size);
err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT, &kern.kernarg_align);
CHECK(err);
//printf("Kernarg Align: %d\n", kern.kernarg_align);
return true;
}
// Not for parallel insertion.
bool SubmitPacket(hsa_queue_t* queue, Aql& pkt) {
size_t mask = queue->size - 1;
Aql* ring = (Aql*)queue->base_address;
uint64_t write = hsa_queue_load_write_index_relaxed(queue);
uint64_t read = hsa_queue_load_read_index_relaxed(queue);
//if(write - read + 1 > queue->size)
// return false;
Aql& dst = ring[write & mask];
uint16_t header = pkt.header.raw;
pkt.header.raw = dst.header.raw;
dst = pkt;
__atomic_store_n(&dst.header.raw, header, __ATOMIC_RELEASE);
pkt.header.raw = header;
hsa_queue_store_write_index_release(queue, write+1);
hsa_signal_store_screlease(queue->doorbell_signal, write);
return true;
}
void* hsaMalloc(size_t size, const Device::Memory& mem) {
void* ret;
hsa_status_t err = hsa_amd_memory_pool_allocate(mem.pool, size, 0, &ret);
CHECK(err);
err = hsa_amd_agents_allow_access(System::all_devices().size(), &System::all_devices()[0], nullptr, ret);
CHECK(err);
return ret;
}
void* hsaMalloc(size_t size, const Device& dev, bool fine) {
uint32_t index = fine ? dev.fine : dev.coarse;
assert(index != -1u && "Memory type unavailable.");
return hsaMalloc(size, dev.pools[index]);
}