Changeset 3314 in CLRX


Ignore:
Timestamp:
Sep 6, 2017, 3:21:01 PM (13 months ago)
Author:
matszpk
Message:

CLRadeonExtender: AmdCL2: Add writing HSA configuration to binary. Move code to calculate kernel arg size to method.

Location:
CLRadeonExtender/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/CLRX/amdbin/AmdCL2BinGen.h

    r3313 r3314  
    8080    bool useEnqueue; ///< this kernel enqueues other kernel
    8181    bool useGeneric;    ///< use generic pointer addresses (for flat instrs)
     82   
     83    size_t calculateKernelArgSize(bool is64Bit, bool newBinaries) const;
    8284};
    8385
  • CLRadeonExtender/trunk/amdasm/AsmAmdCL2Format.cpp

    r3313 r3314  
    19071907    const GPUArchitecture arch = getGPUArchitectureFromDeviceType(assembler.deviceType);
    19081908    cxuint maxTotalSgprsNum = getGPUMaxRegistersNum(arch, REGTYPE_SGPR, 0);
     1909    const cxuint ldsShift = arch<GPUArchitecture::GCN1_1 ? 8 : 9;
     1910    const uint32_t ldsMask = (1U<<ldsShift)-1U;
     1911   
     1912    // driver version setup
     1913    if (output.driverVersion==0 && (assembler.flags&ASM_TESTRUN)==0)
     1914    {
     1915        if (assembler.driverVersion==0) // just detect driver version
     1916            output.driverVersion = detectedDriverVersion;
     1917        else // from assembler setup
     1918            output.driverVersion = assembler.driverVersion;
     1919    }
     1920   
    19091921    // set up number of the allocated SGPRs and VGPRs for kernel
    19101922    for (size_t i = 0; i < kernelsNum; i++)
     
    19121924        if (!output.kernels[i].useConfig)
    19131925            continue;
    1914         AmdCL2KernelConfig& config = output.kernels[i].config;
    1915         cxuint userSGPRsNum = 4;
    1916         if (config.useGeneric)
    1917             userSGPRsNum = 12;
    1918         else if (config.useEnqueue)
    1919             userSGPRsNum = 10;
    1920         else if (config.useSetup)
    1921             userSGPRsNum = 8;
    1922         else if (config.useArgs)
    1923             userSGPRsNum = 6;
    19241926       
    1925         /* include userData sgprs */
    1926         cxuint dimMask = (config.dimMask!=BINGEN_DEFAULT) ? config.dimMask :
    1927                 ((config.pgmRSRC2>>7)&7);
    1928         cxuint minRegsNum[2];
    1929         getGPUSetupMinRegistersNum(arch, dimMask, userSGPRsNum,
    1930                    ((config.tgSize) ? GPUSETUP_TGSIZE_EN : 0) |
    1931                    ((config.scratchBufferSize!=0) ? GPUSETUP_SCRATCH_EN : 0), minRegsNum);
    1932        
    1933         const cxuint neededExtraSGPRsNum = arch>=GPUArchitecture::GCN1_2 ? 6 : 4;
    1934         const cxuint extraSGPRsNum = (config.useEnqueue || config.useGeneric) ?
    1935                     neededExtraSGPRsNum : 2;
    1936         if (config.usedSGPRsNum!=BINGEN_DEFAULT)
    1937         {   // check only if sgprsnum set explicitly
    1938             if (maxTotalSgprsNum-extraSGPRsNum < config.usedSGPRsNum)
    1939             {
     1927        if (!kernelStates[i]->useHsaConfig)
     1928        {   // previous form of config (non-HSA)
     1929            AmdCL2KernelConfig& config = output.kernels[i].config;
     1930            cxuint userSGPRsNum = 4;
     1931            if (config.useGeneric)
     1932                userSGPRsNum = 12;
     1933            else if (config.useEnqueue)
     1934                userSGPRsNum = 10;
     1935            else if (config.useSetup)
     1936                userSGPRsNum = 8;
     1937            else if (config.useArgs)
     1938                userSGPRsNum = 6;
     1939           
     1940            /* include userData sgprs */
     1941            cxuint dimMask = (config.dimMask!=BINGEN_DEFAULT) ? config.dimMask :
     1942                    ((config.pgmRSRC2>>7)&7);
     1943            cxuint minRegsNum[2];
     1944            getGPUSetupMinRegistersNum(arch, dimMask, userSGPRsNum,
     1945                    ((config.tgSize) ? GPUSETUP_TGSIZE_EN : 0) |
     1946                    ((config.scratchBufferSize!=0) ? GPUSETUP_SCRATCH_EN : 0), minRegsNum);
     1947           
     1948            const cxuint neededExtraSGPRsNum = arch>=GPUArchitecture::GCN1_2 ? 6 : 4;
     1949            const cxuint extraSGPRsNum = (config.useEnqueue || config.useGeneric) ?
     1950                        neededExtraSGPRsNum : 2;
     1951            if (config.usedSGPRsNum!=BINGEN_DEFAULT)
     1952            {   // check only if sgprsnum set explicitly
     1953                if (maxTotalSgprsNum-extraSGPRsNum < config.usedSGPRsNum)
     1954                {
     1955                    char numBuf[64];
     1956                    snprintf(numBuf, 64, "(max %u)", maxTotalSgprsNum);
     1957                    assembler.printError(assembler.kernels[i].sourcePos, (std::string(
     1958                        "Number of total SGPRs for kernel '")+
     1959                        output.kernels[i].kernelName.c_str()+"' is too high "
     1960                        +numBuf).c_str());
     1961                    good = false;
     1962                }
     1963            }
     1964           
     1965            if (config.usedSGPRsNum==BINGEN_DEFAULT)
     1966                config.usedSGPRsNum = std::min(maxTotalSgprsNum-extraSGPRsNum,
     1967                    std::max(minRegsNum[0], kernelStates[i]->allocRegs[0]));
     1968            if (config.usedVGPRsNum==BINGEN_DEFAULT)
     1969                config.usedVGPRsNum = std::max(minRegsNum[1],
     1970                                kernelStates[i]->allocRegs[1]);
     1971        }
     1972        else // setup HSA configuration
     1973        {
     1974            AsmAmdHsaKernelConfig config;
     1975            const CString& kernelName = output.kernels[i].kernelName;
     1976           
     1977            const Kernel& kernel = *kernelStates[i];
     1978            if (kernelStates[i]->config != nullptr)
     1979                // if HSA config set in this kernel
     1980                ::memcpy(&config, kernel.config.get(), sizeof(AsmAmdHsaKernelConfig));
     1981            else
     1982                ::memset(&config, 0xff, 128); // fill by defaults
     1983           
     1984            // setup some params: pgmRSRC1 and PGMRSRC2 and others
     1985            // setup config
     1986            // fill default values
     1987            if (config.amdCodeVersionMajor == BINGEN_DEFAULT)
     1988                config.amdCodeVersionMajor = 1;
     1989            if (config.amdCodeVersionMinor == BINGEN_DEFAULT)
     1990                config.amdCodeVersionMinor = 0;
     1991            if (config.amdMachineKind == BINGEN16_DEFAULT)
     1992                config.amdMachineKind = 1;
     1993            if (config.amdMachineMajor == BINGEN16_DEFAULT)
     1994                config.amdMachineMajor = 0;
     1995            if (config.amdMachineMinor == BINGEN16_DEFAULT)
     1996                config.amdMachineMinor = 0;
     1997            if (config.amdMachineStepping == BINGEN16_DEFAULT)
     1998                config.amdMachineStepping = 0;
     1999            if (config.kernelCodeEntryOffset == BINGEN64_DEFAULT)
     2000                config.kernelCodeEntryOffset = 256;
     2001            if (config.kernelCodePrefetchOffset == BINGEN64_DEFAULT)
     2002                config.kernelCodePrefetchOffset = 0;
     2003            if (config.kernelCodePrefetchSize == BINGEN64_DEFAULT)
     2004                config.kernelCodePrefetchSize = 0;
     2005            if (config.maxScrachBackingMemorySize == BINGEN64_DEFAULT) // ??
     2006                config.maxScrachBackingMemorySize = 0;
     2007           
     2008            if (config.workitemPrivateSegmentSize == BINGEN_DEFAULT) // scratch buffer
     2009                config.workitemPrivateSegmentSize =  0;
     2010            if (config.workgroupGroupSegmentSize == BINGEN_DEFAULT) // local size
     2011                config.workgroupGroupSegmentSize = 0;
     2012            if (config.gdsSegmentSize == BINGEN_DEFAULT)
     2013                config.gdsSegmentSize = 0;
     2014            if (config.kernargSegmentSize == BINGEN64_DEFAULT)
     2015            {   // calculate kernel arg size
     2016                const bool newBinaries = output.driverVersion >= 191205;
     2017                config.kernargSegmentSize =
     2018                        output.kernels[i].config.calculateKernelArgSize(
     2019                            assembler.is64Bit(), newBinaries);
     2020            }
     2021            if (config.workgroupFbarrierCount == BINGEN_DEFAULT)
     2022                config.workgroupFbarrierCount = 0;
     2023            if (config.debugWavefrontPrivateSegmentOffsetSgpr == BINGEN16_DEFAULT)
     2024                config.debugWavefrontPrivateSegmentOffsetSgpr = 0;
     2025            if (config.debugPrivateSegmentBufferSgpr == BINGEN16_DEFAULT)
     2026                config.debugPrivateSegmentBufferSgpr = 0;
     2027            if (config.kernargSegmentAlignment == BINGEN8_DEFAULT)
     2028                config.kernargSegmentAlignment = 4; // 16 bytes
     2029            if (config.groupSegmentAlignment == BINGEN8_DEFAULT)
     2030                config.groupSegmentAlignment = 4; // 16 bytes
     2031            if (config.privateSegmentAlignment == BINGEN8_DEFAULT)
     2032                config.privateSegmentAlignment = 4; // 16 bytes
     2033            if (config.wavefrontSize == BINGEN8_DEFAULT)
     2034                config.wavefrontSize = 6; // 64 threads
     2035           
     2036            cxuint userSGPRsNum = 0;
     2037            if (config.userDataNum == BINGEN8_DEFAULT)
     2038            {   // calcuate userSGPRs
     2039                const uint16_t sgprFlags = config.enableSgprRegisterFlags;
     2040                userSGPRsNum =
     2041                    ((sgprFlags&AMDHSAFLAG_USE_PRIVATE_SEGMENT_BUFFER)!=0 ? 4 : 0) +
     2042                    ((sgprFlags&AMDHSAFLAG_USE_DISPATCH_PTR)!=0 ? 2 : 0) +
     2043                    ((sgprFlags&AMDHSAFLAG_USE_QUEUE_PTR)!=0 ? 2 : 0) +
     2044                    ((sgprFlags&AMDHSAFLAG_USE_KERNARG_SEGMENT_PTR)!=0 ? 2 : 0) +
     2045                    ((sgprFlags&AMDHSAFLAG_USE_DISPATCH_ID)!=0 ? 2 : 0) +
     2046                    ((sgprFlags&AMDHSAFLAG_USE_FLAT_SCRATCH_INIT)!=0 ? 2 : 0) +
     2047                    ((sgprFlags&AMDHSAFLAG_USE_PRIVATE_SEGMENT_SIZE)!=0) +
     2048                    /* use_grid_workgroup_count */
     2049                    ((sgprFlags&AMDHSAFLAG_USE_GRID_WORKGROUP_COUNT_X)!=0) +
     2050                    ((sgprFlags&AMDHSAFLAG_USE_GRID_WORKGROUP_COUNT_Y)!=0) +
     2051                    ((sgprFlags&AMDHSAFLAG_USE_GRID_WORKGROUP_COUNT_Z)!=0);
     2052                userSGPRsNum = std::min(16U, userSGPRsNum);
     2053            }
     2054            else // default
     2055                userSGPRsNum = config.userDataNum;
     2056           
     2057            /* include userData sgprs */
     2058            cxuint dimMask = (config.dimMask!=BINGEN_DEFAULT) ? config.dimMask :
     2059                    ((config.computePgmRsrc2>>7)&7);
     2060            // extra sgprs for dimensions
     2061            cxuint minRegsNum[2];
     2062            getGPUSetupMinRegistersNum(arch, dimMask, userSGPRsNum,
     2063                    ((config.tgSize) ? GPUSETUP_TGSIZE_EN : 0) |
     2064                    ((config.workitemPrivateSegmentSize!=0) ?
     2065                            GPUSETUP_SCRATCH_EN : 0), minRegsNum);
     2066           
     2067            if (config.usedSGPRsNum!=BINGEN_DEFAULT &&
     2068                    maxTotalSgprsNum < config.usedSGPRsNum)
     2069            {   // check only if sgprsnum set explicitly
    19402070                char numBuf[64];
    19412071                snprintf(numBuf, 64, "(max %u)", maxTotalSgprsNum);
    19422072                assembler.printError(assembler.kernels[i].sourcePos, (std::string(
    1943                     "Number of total SGPRs for kernel '")+
    1944                     output.kernels[i].kernelName.c_str()+"' is too high "+numBuf).c_str());
     2073                        "Number of total SGPRs for kernel '")+
     2074                        kernelName.c_str()+"' is too high "+numBuf).c_str());
    19452075                good = false;
    19462076            }
     2077            // set usedSGPRsNum
     2078            cxuint progSgprsNum = 0;
     2079            cxuint flags = kernelStates[i]->allocRegFlags |
     2080                // flat_scratch_init
     2081                ((config.enableSgprRegisterFlags&ROCMFLAG_USE_FLAT_SCRATCH_INIT)!=0?
     2082                            GCN_FLAT : 0) |
     2083                // enable_xnack
     2084                ((config.enableFeatureFlags&ROCMFLAG_USE_XNACK_ENABLED)!=0 ?
     2085                            GCN_XNACK : 0);
     2086            cxuint extraSgprsNum = getGPUExtraRegsNum(arch, REGTYPE_SGPR, flags|GCN_VCC);
     2087           
     2088            if (config.usedSGPRsNum==BINGEN_DEFAULT)
     2089            {
     2090                progSgprsNum = std::max(minRegsNum[0], kernelStates[i]->allocRegs[0]);
     2091                config.usedSGPRsNum = std::min(progSgprsNum + extraSgprsNum,
     2092                        maxTotalSgprsNum); // include all extra sgprs
     2093            }
     2094            else // calculate progs SPGRs num (without extra SGPR num)
     2095                progSgprsNum = std::max(cxint(config.usedSGPRsNum - extraSgprsNum), 0);
     2096           
     2097            // set usedVGPRsNum
     2098            if (config.usedVGPRsNum==BINGEN_DEFAULT)
     2099                config.usedVGPRsNum = std::max(minRegsNum[1],
     2100                                kernelStates[i]->allocRegs[1]);
     2101           
     2102            cxuint sgprsNum = std::max(config.usedSGPRsNum, 1U);
     2103            cxuint vgprsNum = std::max(config.usedVGPRsNum, 1U);
     2104            // computePGMRSRC1
     2105            config.computePgmRsrc1 |= ((vgprsNum-1)>>2) |
     2106                    (((sgprsNum-1)>>3)<<6) | ((uint32_t(config.floatMode)&0xff)<<12) |
     2107                    (config.ieeeMode?1U<<23:0) | (uint32_t(config.priority&3)<<10) |
     2108                    (config.privilegedMode?1U<<20:0) | (config.dx10Clamp?1U<<21:0) |
     2109                    (config.debugMode?1U<<22:0);
     2110                   
     2111            uint32_t dimValues = 0;
     2112            if (config.dimMask != BINGEN_DEFAULT)
     2113                dimValues = ((config.dimMask&7)<<7) |
     2114                        (((config.dimMask&4) ? 2 : (config.dimMask&2) ? 1 : 0)<<11);
     2115            else
     2116                dimValues |= (config.computePgmRsrc2 & 0x1b80U);
     2117            // computePGMRSRC2
     2118            config.computePgmRsrc2 = (config.computePgmRsrc2 & 0xffffe440U) |
     2119                            (userSGPRsNum<<1) | ((config.tgSize) ? 0x400 : 0) |
     2120                            ((config.workitemPrivateSegmentSize)?1:0) | dimValues |
     2121                            (((config.workgroupGroupSegmentSize+ldsMask)>>ldsShift)<<15) |
     2122                            ((uint32_t(config.exceptions)&0x7f)<<24);
     2123           
     2124            if (config.wavefrontSgprCount == BINGEN16_DEFAULT)
     2125                config.wavefrontSgprCount = sgprsNum;
     2126            if (config.workitemVgprCount == BINGEN16_DEFAULT)
     2127                config.workitemVgprCount = vgprsNum;
     2128            if (config.reservedVgprFirst == BINGEN16_DEFAULT)
     2129                config.reservedVgprFirst = vgprsNum;
     2130            if (config.reservedVgprCount == BINGEN16_DEFAULT)
     2131                config.reservedVgprCount = 0;
     2132            if (config.reservedSgprFirst == BINGEN16_DEFAULT)
     2133                config.reservedSgprFirst = progSgprsNum;
     2134            if (config.reservedSgprCount == BINGEN16_DEFAULT)
     2135                config.reservedSgprCount = 0;
     2136           
     2137            if (config.callConvention == BINGEN_DEFAULT)
     2138                config.callConvention = 0;
     2139            if (config.runtimeLoaderKernelSymbol == BINGEN64_DEFAULT)
     2140                config.runtimeLoaderKernelSymbol = 0;
     2141           
     2142            config.reserved1[0] = config.reserved1[1] = config.reserved1[2] = 0;
     2143           
     2144            config.toLE(); // to little-endian
     2145            // put control directive section to config
     2146            if (kernel.ctrlDirSection!=ASMSECT_NONE &&
     2147                assembler.sections[kernel.ctrlDirSection].content.size()==128)
     2148                ::memcpy(config.controlDirective,
     2149                    assembler.sections[kernel.ctrlDirSection].content.data(), 128);
     2150            else // zeroing if not supplied
     2151                ::memset(config.controlDirective, 0, 128);
    19472152        }
    1948        
    1949         if (config.usedSGPRsNum==BINGEN_DEFAULT)
    1950             config.usedSGPRsNum = std::min(maxTotalSgprsNum-extraSGPRsNum,
    1951                 std::max(minRegsNum[0], kernelStates[i]->allocRegs[0]));
    1952         if (config.usedVGPRsNum==BINGEN_DEFAULT)
    1953             config.usedVGPRsNum = std::max(minRegsNum[1], kernelStates[i]->allocRegs[1]);
    19542153    }
    19552154   
     
    20092208            }
    20102209        }
    2011     }
    2012     // driver version setup
    2013     if (output.driverVersion==0 && (assembler.flags&ASM_TESTRUN)==0)
    2014     {
    2015         if (assembler.driverVersion==0) // just detect driver version
    2016             output.driverVersion = detectedDriverVersion;
    2017         else // from assembler setup
    2018             output.driverVersion = assembler.driverVersion;
    20192210    }
    20202211    return good;
  • CLRadeonExtender/trunk/amdbin/AmdCL2BinGen.cpp

    r3313 r3314  
    11741174}
    11751175
     1176size_t AmdCL2KernelConfig::calculateKernelArgSize(bool is64Bit, bool newBinaries) const
     1177{
     1178    cxuint kernelArgSize = 0;
     1179    for (const AmdKernelArgInput arg: args)
     1180    {
     1181        if (arg.argType == KernelArgType::POINTER ||
     1182            arg.argType == KernelArgType::PIPE ||
     1183            arg.argType == KernelArgType::CLKEVENT ||
     1184            arg.argType == KernelArgType::STRUCTURE ||
     1185            arg.argType == KernelArgType::CMDQUEUE ||
     1186            arg.argType == KernelArgType::SAMPLER || isKernelArgImage(arg.argType))
     1187        {
     1188            cxuint size = (is64Bit) ? 8 : 4;
     1189            if ((kernelArgSize&(size-1))!=0)    // alignment
     1190                kernelArgSize += size-(kernelArgSize&(size-1));
     1191            kernelArgSize += size;
     1192        }
     1193        else
     1194        {   // scalar
     1195            const ArgTypeSizes& argTypeSizes = argTypeSizesTable[cxuint(arg.argType)];
     1196            cxuint vectorLength = argTypeSizes.vectorSize;
     1197            if (newBinaries && vectorLength==3)
     1198                vectorLength = 4;
     1199            if ((kernelArgSize & (argTypeSizes.elemSize-1))!=0)
     1200                kernelArgSize += argTypeSizes.elemSize -
     1201                        (kernelArgSize & (argTypeSizes.elemSize-1));
     1202            kernelArgSize += vectorLength * argTypeSizes.elemSize;
     1203        }
     1204    }
     1205    if (newBinaries)
     1206        kernelArgSize = (kernelArgSize+15)&~15U;
     1207    return kernelArgSize;
     1208}
     1209
    11761210static void generateKernelSetup(GPUArchitecture arch, const AmdCL2KernelConfig& config,
    11771211                FastOutputBuffer& fob, bool newBinaries, bool useLocals, bool usePipes,
     
    12181252    setupData.zero3 = 0;
    12191253   
    1220     cxuint kernelArgSize = 0;
    1221     for (const AmdKernelArgInput arg: config.args)
    1222     {
    1223         if (arg.argType == KernelArgType::POINTER ||
    1224             arg.argType == KernelArgType::PIPE ||
    1225             arg.argType == KernelArgType::CLKEVENT ||
    1226             arg.argType == KernelArgType::STRUCTURE ||
    1227             arg.argType == KernelArgType::CMDQUEUE ||
    1228             arg.argType == KernelArgType::SAMPLER || isKernelArgImage(arg.argType))
    1229         {
    1230             cxuint size = (is64Bit) ? 8 : 4;
    1231             if ((kernelArgSize&(size-1))!=0)    // alignment
    1232                 kernelArgSize += size-(kernelArgSize&(size-1));
    1233             kernelArgSize += size;
    1234         }
    1235         else
    1236         {   // scalar
    1237             const ArgTypeSizes& argTypeSizes = argTypeSizesTable[cxuint(arg.argType)];
    1238             cxuint vectorLength = argTypeSizes.vectorSize;
    1239             if (newBinaries && vectorLength==3)
    1240                 vectorLength = 4;
    1241             if ((kernelArgSize & (argTypeSizes.elemSize-1))!=0)
    1242                 kernelArgSize += argTypeSizes.elemSize -
    1243                         (kernelArgSize & (argTypeSizes.elemSize-1));
    1244             kernelArgSize += vectorLength * argTypeSizes.elemSize;
    1245         }
    1246     }
    1247     if (newBinaries)
    1248         kernelArgSize = (kernelArgSize+15)&~15U;
     1254    const cxuint kernelArgSize = config.calculateKernelArgSize(is64Bit, newBinaries);
    12491255    SLEV(setupData.kernelArgsSize, kernelArgSize);
    12501256    SLEV(setupData.sgprsNumAll, sgprsNum);
Note: See TracChangeset for help on using the changeset viewer.