P4 to Git Change 1305233 by lmoriche@lmoriche_opencl_dev on 2016/08/19 21:42:56
SWDEV-94637 - Add the logic to select the control function libraries. Add a gfxipVersion field to the DeviceInfo. Generate both CL1.2 and CL2.0 precompiled headers. Set the -mcpu target using the DeviceInfo.machineTarget_.
Affected files ...
... //depot/stg/opencl/drivers/opencl/library/build/Makefile.library#51 edit
... //depot/stg/opencl/drivers/opencl/make/amdgcn.git/headers/build/Makefile.headers#2 edit
... //depot/stg/opencl/drivers/opencl/make/amdgcn.git/irif/build/Makefile.irif#3 edit
... //depot/stg/opencl/drivers/opencl/make/amdgcn.git/ockl/build/Makefile.ockl#4 edit
... //depot/stg/opencl/drivers/opencl/make/amdgcn.git/oclc/build/Makefile.oclc#4 edit
... //depot/stg/opencl/drivers/opencl/make/amdgcn.git/ocml/build/Makefile.ocml#4 edit
... //depot/stg/opencl/drivers/opencl/make/amdgcn.git/opencl/build/Makefile.opencl#5 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdefs.hpp#5 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#9 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#10 edit
[ROCm/clr commit: d05240f908]
This commit is contained in:
@@ -16,7 +16,8 @@ struct AMDDeviceInfo {
|
||||
uint memChannelBankWidth_; //!< Memory channel bank width
|
||||
uint localMemSizePerCU_; //!< Local memory size per CU
|
||||
uint localMemBanks_; //!< Number of banks of local memory
|
||||
uint pciDeviceId; //!< PCIe device id
|
||||
uint gfxipVersion_; //!< The core engine GFXIP version
|
||||
uint pciDeviceId_; //!< PCIe device id
|
||||
};
|
||||
|
||||
//The device ID must match with the device's index into DeviceInfo
|
||||
@@ -33,15 +34,15 @@ const HsaDeviceId HSA_INVALID_DEVICE_ID = -1;
|
||||
|
||||
static const AMDDeviceInfo DeviceInfo[] = {
|
||||
// targetName machineTarget
|
||||
/* TARGET_KAVERI_SPECTRE */ {HSA_SPECTRE_ID, "Spectre", "Spectre", 4, 16, 1, 256, 64 * Ki, 32, 0 },
|
||||
/* TARGET_KAVERI_SPOOKY */ {HSA_SPOOKY_ID, "Spooky", "Spooky", 4, 16, 1, 256, 64 * Ki, 32, 0 },
|
||||
/* TARGET_TONGA */ {HSA_TONGA_ID, "Tonga", "Tonga", 4, 16, 1, 256, 64 * Ki, 32, 0},
|
||||
/* TARGET_CARRIZO */ {HSA_CARRIZO_ID, "Carrizo", "Carrizo", 4, 16, 1, 256, 64 * Ki, 32, 0},
|
||||
/* TARGET_ICELAND */ {HSA_ICELAND_ID, "Topaz", "Topaz", 4, 16, 1, 256, 64 * Ki, 32, 0},
|
||||
/* TARGET_FIJI */ {HSA_FIJI_ID, "Fiji", "Fiji", 4, 16, 1, 256, 64 * Ki, 32, 0 },
|
||||
/* TARGET HAWAII */ {HSA_HAWAII_ID, "Hawaii", "Hawaii", 4, 16, 1, 256, 64 * Ki, 32, 0 },
|
||||
/* TARGET ELLESMERE */ {HSA_ELLESMERE_ID, "Ellesmere", "Ellesmere", 4, 16, 1, 256, 64 * Ki, 32, 0 },
|
||||
/* TARGET BAFFIN */ {HSA_BAFFIN_ID, "Baffin", "Baffin", 4, 16, 1, 256, 64 * Ki, 32, 0 }
|
||||
/* TARGET_KAVERI_SPECTRE */ {HSA_SPECTRE_ID, "Spectre", "kaveri", 4, 16, 1, 256, 64 * Ki, 32, 0, 0 },
|
||||
/* TARGET_KAVERI_SPOOKY */ {HSA_SPOOKY_ID, "Spooky", "kaveri", 4, 16, 1, 256, 64 * Ki, 32, 0, 0 },
|
||||
/* TARGET_TONGA */ {HSA_TONGA_ID, "Tonga", "tonga", 4, 16, 1, 256, 64 * Ki, 32, 0, 0},
|
||||
/* TARGET_CARRIZO */ {HSA_CARRIZO_ID, "Carrizo", "carrizo", 4, 16, 1, 256, 64 * Ki, 32, 0, 0},
|
||||
/* TARGET_ICELAND */ {HSA_ICELAND_ID, "Topaz", "iceland", 4, 16, 1, 256, 64 * Ki, 32, 0, 0},
|
||||
/* TARGET_FIJI */ {HSA_FIJI_ID, "Fiji", "fiji", 4, 16, 1, 256, 64 * Ki, 32, 0, 0 },
|
||||
/* TARGET HAWAII */ {HSA_HAWAII_ID, "Hawaii", "hawaii", 4, 16, 1, 256, 64 * Ki, 32, 0, 0 },
|
||||
/* TARGET ELLESMERE */ {HSA_ELLESMERE_ID, "Ellesmere", "polaris10", 4, 16, 1, 256, 64 * Ki, 32, 0, 0 },
|
||||
/* TARGET BAFFIN */ {HSA_BAFFIN_ID, "Baffin", "polaris11", 4, 16, 1, 256, 64 * Ki, 32, 0, 0 }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -383,16 +383,6 @@ hsa_status_t Device::iterateAgentCallback(hsa_agent_t agent, void *data) {
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (!roc_device->mapHSADeviceToOpenCLDevice(agent)) {
|
||||
LogError("Failed mapping of HsaDevice to Device.");
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (!roc_device->create()) {
|
||||
LogError("Error creating new instance of Device.");
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
uint32_t pci_id;
|
||||
HsaDeviceId deviceId = getHsaDeviceId(agent, pci_id);
|
||||
if (deviceId == HSA_INVALID_DEVICE_ID) {
|
||||
@@ -412,7 +402,56 @@ hsa_status_t Device::iterateAgentCallback(hsa_agent_t agent, void *data) {
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
roc_device->deviceInfo_ = DeviceInfo[id];
|
||||
roc_device->deviceInfo_.pciDeviceId = pci_id;
|
||||
roc_device->deviceInfo_.pciDeviceId_ = pci_id;
|
||||
|
||||
// Query the agent's ISA name to fill deviceInfo.gfxipVersion_. We can't
|
||||
// have a static mapping as some marketing names cover multiple gfxip. For
|
||||
// example a Fiji could be 8.0.3 or 8.0.4. Same for Polaris11 and Polaris12.
|
||||
hsa_isa_t isa = {0};
|
||||
if (hsa_agent_get_info(agent, HSA_AGENT_INFO_ISA, &isa)
|
||||
!= HSA_STATUS_SUCCESS) {
|
||||
return HSA_STATUS_ERROR;
|
||||
}
|
||||
|
||||
uint32_t isaNameLength = 0;
|
||||
if (hsa_isa_get_info(isa, HSA_ISA_INFO_NAME_LENGTH, 0, &isaNameLength)
|
||||
!= HSA_STATUS_SUCCESS) {
|
||||
return HSA_STATUS_ERROR;
|
||||
}
|
||||
|
||||
char *isaName = (char*)alloca((size_t)isaNameLength + 1);
|
||||
if (hsa_isa_get_info(isa, HSA_ISA_INFO_NAME, 0, isaName)
|
||||
!= HSA_STATUS_SUCCESS) {
|
||||
return HSA_STATUS_ERROR;
|
||||
}
|
||||
isaName[isaNameLength] = '\0';
|
||||
|
||||
std::string str(isaName);
|
||||
std::vector<std::string> tokens;
|
||||
size_t end, pos = 0;
|
||||
do {
|
||||
end = str.find_first_of(':', pos);
|
||||
tokens.push_back(str.substr(pos, end-pos));
|
||||
pos = end + 1;
|
||||
} while (end != std::string::npos);
|
||||
|
||||
assert(tokens.size() == 5 && tokens[0] == "AMD" && tokens[1] == "AMDGPU");
|
||||
uint major = atoi(tokens[2].c_str());
|
||||
uint minor = atoi(tokens[3].c_str());
|
||||
uint stepping = atoi(tokens[4].c_str());
|
||||
assert(minor < 10 && stepping < 10 && "Invalid ISA string");
|
||||
|
||||
roc_device->deviceInfo_.gfxipVersion_ = major * 100 + minor * 10 + stepping;
|
||||
|
||||
if (!roc_device->mapHSADeviceToOpenCLDevice(agent)) {
|
||||
LogError("Failed mapping of HsaDevice to Device.");
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (!roc_device->create()) {
|
||||
LogError("Error creating new instance of Device.");
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
roc_device->registerDevice(); // no return code for this function
|
||||
|
||||
@@ -1021,7 +1060,7 @@ Device::bindExternalDevice(
|
||||
match &= info_.deviceTopology_.pcie.device==info.pci_device;
|
||||
match &= info_.deviceTopology_.pcie.function==info.pci_function;
|
||||
match &= info_.vendorId_==info.vendor_id;
|
||||
match &= deviceInfo_.pciDeviceId==info.device_id;
|
||||
match &= deviceInfo_.pciDeviceId_==info.device_id;
|
||||
|
||||
if(!validateOnly)
|
||||
mesa_=temp;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "rockernel.hpp"
|
||||
#if defined(WITH_LIGHTNING_COMPILER)
|
||||
#include "driver/AmdCompiler.h"
|
||||
#include "opencl-c.amdgcn.inc"
|
||||
#include "builtins-irif.amdgcn.inc"
|
||||
#include "builtins-ockl.amdgcn.inc"
|
||||
#include "builtins-ocml.amdgcn.inc"
|
||||
@@ -607,72 +606,106 @@ namespace roc {
|
||||
#if defined(WITH_LIGHTNING_COMPILER)
|
||||
bool HSAILProgram::linkImpl_LC(amd::option::Options *options)
|
||||
{
|
||||
using namespace amd::opencl_driver;
|
||||
|
||||
// call LinkLLVMBitcode
|
||||
std::vector<amd::opencl_driver::Data*> inputs;
|
||||
std::vector<Data*> inputs;
|
||||
|
||||
// open the input IR source
|
||||
const std::string llvmIR = codeObjBinary_->getLlvmIR();
|
||||
amd::opencl_driver::Data* llvm_src = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, llvmIR.c_str(), llvmIR.length());
|
||||
Data* input = device().compiler()->NewBufferReference(
|
||||
DT_LLVM_BC, llvmIR.c_str(), llvmIR.length());
|
||||
|
||||
if (!llvm_src) {
|
||||
if (!input) {
|
||||
buildLog_ += "Error: Failed to open the compiled program.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
inputs.push_back(llvm_src); //< must be the first input
|
||||
inputs.push_back(input); //< must be the first input
|
||||
|
||||
// open the bitcode libraries
|
||||
amd::opencl_driver::Data* opencl_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) builtins_opencl_amdgcn, builtins_opencl_amdgcn_size);
|
||||
amd::opencl_driver::Data* ocml_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) builtins_ocml_amdgcn, builtins_ocml_amdgcn_size);
|
||||
amd::opencl_driver::Data* ockl_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) builtins_ockl_amdgcn, builtins_ockl_amdgcn_size);
|
||||
amd::opencl_driver::Data* irif_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) builtins_irif_amdgcn, builtins_irif_amdgcn_size);
|
||||
Data* opencl_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) builtins_opencl_amdgcn, builtins_opencl_amdgcn_size);
|
||||
Data* ocml_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) builtins_ocml_amdgcn, builtins_ocml_amdgcn_size);
|
||||
Data* ockl_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) builtins_ockl_amdgcn, builtins_ockl_amdgcn_size);
|
||||
Data* irif_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) builtins_irif_amdgcn, builtins_irif_amdgcn_size);
|
||||
|
||||
if (!opencl_bc || !ocml_bc || !ockl_bc || !irif_bc) {
|
||||
buildLog_ += "Error: Failed to open the bitcode library.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
inputs.push_back(opencl_bc);
|
||||
inputs.push_back(ocml_bc);
|
||||
inputs.push_back(ockl_bc);
|
||||
inputs.push_back(irif_bc);
|
||||
inputs.push_back(ocml_bc); // depends on irif
|
||||
inputs.push_back(ockl_bc); // depends on irif
|
||||
inputs.push_back(opencl_bc); // depends on oclm & ockl
|
||||
|
||||
// open the control functions
|
||||
amd::opencl_driver::Data* correctly_rounded_sqrt_off_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) correctly_rounded_sqrt_off_amdgcn, correctly_rounded_sqrt_off_amdgcn_size);
|
||||
amd::opencl_driver::Data* daz_opt_off_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) daz_opt_off_amdgcn, daz_opt_off_amdgcn_size);
|
||||
amd::opencl_driver::Data* finite_only_off_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) finite_only_off_amdgcn, finite_only_off_amdgcn_size);
|
||||
amd::opencl_driver::Data* unsafe_math_off_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) unsafe_math_off_amdgcn, unsafe_math_off_amdgcn_size);
|
||||
amd::opencl_driver::Data* isa_version_803_bc = device().compiler()->NewBufferReference(
|
||||
amd::opencl_driver::DT_LLVM_BC, (const char*) isa_version_803_amdgcn, isa_version_803_amdgcn_size);
|
||||
std::pair<const void*, size_t> isa_version;
|
||||
switch (dev().deviceInfo().gfxipVersion_) {
|
||||
case 701: isa_version = std::make_pair(isa_version_701_amdgcn, isa_version_701_amdgcn_size); break;
|
||||
case 800: isa_version = std::make_pair(isa_version_800_amdgcn, isa_version_800_amdgcn_size); break;
|
||||
case 801: isa_version = std::make_pair(isa_version_801_amdgcn, isa_version_801_amdgcn_size); break;
|
||||
case 802: isa_version = std::make_pair(isa_version_802_amdgcn, isa_version_802_amdgcn_size); break;
|
||||
case 803: isa_version = std::make_pair(isa_version_803_amdgcn, isa_version_803_amdgcn_size); break;
|
||||
case 810: isa_version = std::make_pair(isa_version_810_amdgcn, isa_version_810_amdgcn_size); break;
|
||||
default: buildLog_ += "Error: Linking for this device is not supported\n"; return false;
|
||||
}
|
||||
|
||||
if (!correctly_rounded_sqrt_off_bc
|
||||
|| !daz_opt_off_bc
|
||||
|| !finite_only_off_bc
|
||||
|| !unsafe_math_off_bc
|
||||
|| !isa_version_803_bc) {
|
||||
Data* isa_version_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) isa_version.first, isa_version.second);
|
||||
|
||||
if (!isa_version_bc) {
|
||||
buildLog_ += "Error: Failed to open the control functions.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
inputs.push_back(correctly_rounded_sqrt_off_bc);
|
||||
inputs.push_back(daz_opt_off_bc);
|
||||
inputs.push_back(finite_only_off_bc);
|
||||
inputs.push_back(unsafe_math_off_bc);
|
||||
inputs.push_back(isa_version_803_bc);
|
||||
inputs.push_back(isa_version_bc);
|
||||
|
||||
auto correctly_rounded_sqrt = (options->oVariables->FP32RoundDivideSqrt)
|
||||
? std::make_pair(correctly_rounded_sqrt_on_amdgcn, correctly_rounded_sqrt_on_amdgcn_size)
|
||||
: std::make_pair(correctly_rounded_sqrt_off_amdgcn, correctly_rounded_sqrt_off_amdgcn_size);
|
||||
|
||||
auto daz_opt = (dev().deviceInfo().gfxipVersion_ < 900
|
||||
|| options->oVariables->DenormsAreZero)
|
||||
? std::make_pair(daz_opt_on_amdgcn, daz_opt_on_amdgcn_size)
|
||||
: std::make_pair(daz_opt_off_amdgcn, daz_opt_off_amdgcn_size);
|
||||
|
||||
auto finite_only = (options->oVariables->FiniteMathOnly
|
||||
|| options->oVariables->FastRelaxedMath)
|
||||
? std::make_pair(finite_only_on_amdgcn, finite_only_on_amdgcn_size)
|
||||
: std::make_pair(finite_only_off_amdgcn, finite_only_off_amdgcn_size);
|
||||
|
||||
auto unsafe_math = (options->oVariables->UnsafeMathOpt
|
||||
|| options->oVariables->FastRelaxedMath)
|
||||
? std::make_pair(unsafe_math_on_amdgcn, unsafe_math_on_amdgcn_size)
|
||||
: std::make_pair(unsafe_math_off_amdgcn, unsafe_math_off_amdgcn_size);
|
||||
|
||||
Data* correctly_rounded_sqrt_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) correctly_rounded_sqrt.first, correctly_rounded_sqrt.second);
|
||||
Data* daz_opt_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) daz_opt.first, daz_opt.second);
|
||||
Data* finite_only_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) finite_only.first, finite_only.second);
|
||||
Data* unsafe_math_bc = device().compiler()->NewBufferReference(DT_LLVM_BC,
|
||||
(const char*) unsafe_math.first, unsafe_math.second);
|
||||
|
||||
if (!correctly_rounded_sqrt_bc || !daz_opt_bc || !finite_only_bc || !unsafe_math_bc) {
|
||||
buildLog_ += "Error: Failed to open the control functions.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
inputs.push_back(correctly_rounded_sqrt_bc);
|
||||
inputs.push_back(daz_opt_bc);
|
||||
inputs.push_back(finite_only_bc);
|
||||
inputs.push_back(unsafe_math_bc);
|
||||
|
||||
// open the linked output
|
||||
std::vector<std::string> linkOptions;
|
||||
amd::opencl_driver::Data* linked_bc = device().compiler()->NewBuffer(
|
||||
amd::opencl_driver::DT_LLVM_BC);
|
||||
Data* linked_bc = device().compiler()->NewBuffer(DT_LLVM_BC);
|
||||
|
||||
if (!linked_bc) {
|
||||
buildLog_ += "Error: Failed to open the linked program.\n";
|
||||
@@ -689,21 +722,25 @@ namespace roc {
|
||||
inputs.clear();
|
||||
inputs.push_back(linked_bc);
|
||||
|
||||
amd::opencl_driver::Buffer* out_exec = device().compiler()->NewBuffer(
|
||||
amd::opencl_driver::DT_EXECUTABLE);
|
||||
Buffer* out_exec = device().compiler()->NewBuffer(DT_EXECUTABLE);
|
||||
if (!out_exec) {
|
||||
buildLog_ += "Error: Failed to create the linked executable.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string optionsstr = options->origOptionStr + hsailOptions();
|
||||
|
||||
// Set the machine target
|
||||
optionsstr.append(" -mcpu=");
|
||||
optionsstr.append(dev().deviceInfo().machineTarget_);
|
||||
|
||||
// Tokenize the options string into a vector of strings
|
||||
std::string optionsstr = options->origOptionStr + hsailOptions() + " -mcpu=fiji";
|
||||
std::istringstream strstr(optionsstr);
|
||||
std::istream_iterator<std::string> sit(strstr), end;
|
||||
std::vector<std::string> optionsvec(sit, end);
|
||||
|
||||
ret = device().compiler()->CompileAndLinkExecutable(
|
||||
inputs, (amd::opencl_driver::Data*) out_exec, optionsvec);
|
||||
inputs, out_exec, optionsvec);
|
||||
buildLog_ += device().compiler()->Output().c_str();
|
||||
if (!ret) {
|
||||
buildLog_ += "Error: Creating the executable failed: Compiling LLVM IRs to exe.\n";
|
||||
@@ -1184,18 +1221,14 @@ namespace roc {
|
||||
// All our devices support these options now
|
||||
hsailOptions.append(" -DFP_FAST_FMAF=1");
|
||||
hsailOptions.append(" -DFP_FAST_FMA=1");
|
||||
//TODO: this is a quick fix to restore original f32 denorm flushing
|
||||
//Make this target/option dependent
|
||||
#if defined(WITH_LIGHTNING_COMPILER)
|
||||
hsailOptions.append(" -Xclang");
|
||||
#endif // defined(WITH_LIGHTNING_COMPILER)
|
||||
hsailOptions.append(" -cl-denorms-are-zero");
|
||||
//TODO(sramalin) : Query the device for opencl version
|
||||
// and only set if -cl-std wasn't specified in
|
||||
// original build options (app)
|
||||
//hsailOptions.append(" -cl-std=CL1.2");
|
||||
|
||||
if (dev().deviceInfo().gfxipVersion_ < 900) {
|
||||
hsailOptions.append(" -cl-denorms-are-zero");
|
||||
}
|
||||
|
||||
//check if the host is 64 bit or 32 bit
|
||||
LP64_ONLY(hsailOptions.append(" -m64"));
|
||||
|
||||
//Now append each extension supported by the device
|
||||
// one by one
|
||||
std::string token;
|
||||
|
||||
Verwijs in nieuw issue
Block a user