From fb77623fce3db559a50cc3b291beb15f73bb0e93 Mon Sep 17 00:00:00 2001 From: foreman Date: Fri, 19 Aug 2016 21:52:13 -0400 Subject: [PATCH] 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: d05240f90845a962cbdc2e4c5d422b8f8b8be420] --- .../rocclr/runtime/device/rocm/rocdefs.hpp | 21 +-- .../rocclr/runtime/device/rocm/rocdevice.cpp | 63 ++++++-- .../rocclr/runtime/device/rocm/rocprogram.cpp | 139 +++++++++++------- 3 files changed, 148 insertions(+), 75 deletions(-) diff --git a/projects/clr/rocclr/runtime/device/rocm/rocdefs.hpp b/projects/clr/rocclr/runtime/device/rocm/rocdefs.hpp index d94a10a1d7..45a809e447 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocdefs.hpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocdefs.hpp @@ -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 } }; } diff --git a/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp b/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp index 4a7d07e01d..5d6f6487da 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp @@ -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 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; diff --git a/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp b/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp index 729b738354..a943e0e56d 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp @@ -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 inputs; + std::vector 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 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 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 sit(strstr), end; std::vector 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;