Ignore:
Timestamp:
Jan 30, 2018, 8:53:10 PM (23 months ago)
Author:
matszpk
Message:

CLRadeonExtender: ROCmBin: ROCm YAML Metadata parser stuff (untested).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/amdbin/ROCmBinaries.cpp

    r3677 r3679  
    2121#include <cassert>
    2222#include <cstdio>
     23#include <cstring>
    2324#include <cstdint>
     25#include <string>
     26#include <vector>
    2427#include <algorithm>
    2528#include <utility>
     
    3235
    3336using namespace CLRX;
     37
     38/*
     39 * ROCm metadata YAML parser
     40 */
     41
     42// return trailing spaces
     43static size_t skipSpacesAndComments(const char*& ptr, const char* end, size_t& lineNo)
     44{
     45    const char* lineStart = ptr;
     46    while (ptr != end)
     47    {
     48        lineStart = ptr;
     49        while (ptr != end && *ptr!='\n' && isSpace(*ptr)) ptr++;
     50        if (ptr == end)
     51            break; // end of stream
     52        if (*ptr=='#')
     53        {
     54            // skip comment
     55            while (ptr != end && *ptr!='\n') ptr++;
     56            if (ptr == end)
     57                return 0; // no trailing spaces and end
     58        }
     59        else if (*ptr!='\n')
     60            break; // no comment and no end of line
     61        else
     62            lineNo++; // next line
     63    }
     64    return lineStart - ptr;
     65}
     66
     67static inline void skipSpacesToEnd(const char*& ptr, const char* end)
     68{
     69    while (ptr != end && *ptr!='\n' && isSpace(*ptr)) ptr++;
     70}
     71
     72static size_t parseYAMLKey(const char*& ptr, const char* end, size_t lineNo,
     73            size_t keywordsNum, const char** keywords)
     74{
     75    const char* keyPtr = ptr;
     76    while (ptr != end && (isAlnum(*ptr) || *ptr=='_')) ptr++;
     77    if (keyPtr == end)
     78        throw ParseException(lineNo, "Expected key name");
     79    const char* keyEnd = ptr;
     80    while (ptr != end && *ptr!='\n' && isSpace(*ptr)) ptr++;
     81    if (ptr == end || *ptr==':')
     82        throw ParseException(lineNo, "Expected colon");
     83    ptr++;
     84    const char* afterColon = ptr;
     85    skipSpacesToEnd(ptr, end);
     86    if (afterColon == ptr)
     87        throw ParseException("After key and colon must be space");
     88    CString keyword(keyPtr, keyEnd);
     89    const size_t index = binaryFind(keywords, keywords+keywordsNum,
     90                        keyword.c_str(), CStringLess()) - keywords;
     91    if (index == keywordsNum)
     92        throw ParseException(lineNo, "Unknown keyword");
     93    return index;
     94}
     95
     96template<typename T>
     97static T parseYAMLIntValue(const char*& ptr, const char* end, size_t lineNo)
     98{
     99    skipSpacesToEnd(ptr, end);
     100    if (ptr == end || *ptr=='\n')
     101        throw ParseException(lineNo, "Expected integer value");
     102    try
     103    { return cstrtovCStyle<T>(ptr, end, ptr); }
     104    catch(const ParseException& ex)
     105    { throw ParseException(lineNo, ex.what()); }
     106}
     107
     108static bool parseYAMLBoolValue(const char*& ptr, const char* end, size_t lineNo)
     109{
     110    skipSpacesToEnd(ptr, end);
     111    if (ptr == end || *ptr=='\n')
     112        throw ParseException(lineNo, "Expected boolean value");
     113   
     114    const char* wordPtr = ptr;
     115    while(ptr == end && isAlnum(*ptr)) ptr++;
     116    CString word(wordPtr, ptr);
     117   
     118    for (const char* v: { "1", "true", "t", "on", "yes", "y"})
     119        if (::strcasecmp(word.c_str(), v) == 0)
     120            return true;
     121    for (const char* v: { "0", "false", "f", "off", "no", "n"})
     122        if (::strcasecmp(word.c_str(), v) == 0)
     123            return false;
     124    throw ParseException(lineNo, "Is not boolean value");
     125}
     126
     127static std::string trimStrSpaces(const std::string& str)
     128{
     129    size_t i = 0;
     130    const size_t sz = str.size();
     131    while (i!=sz && isSpace(str[i])) i++;
     132    if (i == sz) return "";
     133    size_t j = sz-1;
     134    while (j>i && isSpace(str[j])) j--;
     135    return str.substr(i, j-i+1);
     136}
     137
     138static std::string parseYAMLString(const char*& linePtr, const char* end,
     139            size_t& lineNo)
     140{
     141    std::string strarray;
     142    if (linePtr == end || (*linePtr != '"' && *linePtr != '\''))
     143    {
     144        while (linePtr != end && !isSpace(*linePtr) && *linePtr != ',') linePtr++;
     145        throw ParseException(lineNo, "Expected string");
     146    }
     147    const char termChar = *linePtr;
     148    linePtr++;
     149   
     150    // main loop, where is character parsing
     151    while (linePtr != end && *linePtr != termChar)
     152    {
     153        if (*linePtr == '\\')
     154        {
     155            // escape
     156            linePtr++;
     157            uint16_t value;
     158            if (linePtr == end)
     159                throw ParseException(lineNo, "Unterminated character of string");
     160            if (*linePtr == 'x')
     161            {
     162                // hex literal
     163                linePtr++;
     164                if (linePtr == end)
     165                    throw ParseException(lineNo, "Unterminated character of string");
     166                value = 0;
     167                if (isXDigit(*linePtr))
     168                    for (; linePtr != end; linePtr++)
     169                    {
     170                        cxuint digit;
     171                        if (*linePtr >= '0' && *linePtr <= '9')
     172                            digit = *linePtr-'0';
     173                        else if (*linePtr >= 'a' && *linePtr <= 'f')
     174                            digit = *linePtr-'a'+10;
     175                        else if (*linePtr >= 'A' && *linePtr <= 'F')
     176                            digit = *linePtr-'A'+10;
     177                        else
     178                            break;
     179                        value = (value<<4) + digit;
     180                    }
     181                else
     182                    throw ParseException(lineNo, "Expected hexadecimal character code");
     183                value &= 0xff;
     184            }
     185            else if (isODigit(*linePtr))
     186            {
     187                // octal literal
     188                value = 0;
     189                for (cxuint i = 0; linePtr != end && i < 3; i++, linePtr++)
     190                {
     191                    if (!isODigit(*linePtr))
     192                        break;
     193                    value = (value<<3) + uint64_t(*linePtr-'0');
     194                    // checking range
     195                    if (value > 255)
     196                        throw ParseException(lineNo, "Octal code out of range");
     197                }
     198            }
     199            else
     200            {
     201                // normal escapes
     202                const char c = *linePtr++;
     203                switch (c)
     204                {
     205                    case 'a':
     206                        value = '\a';
     207                        break;
     208                    case 'b':
     209                        value = '\b';
     210                        break;
     211                    case 'r':
     212                        value = '\r';
     213                        break;
     214                    case 'n':
     215                        value = '\n';
     216                        break;
     217                    case 'f':
     218                        value = '\f';
     219                        break;
     220                    case 'v':
     221                        value = '\v';
     222                        break;
     223                    case 't':
     224                        value = '\t';
     225                        break;
     226                    case '\\':
     227                        value = '\\';
     228                        break;
     229                    case '\'':
     230                        value = '\'';
     231                        break;
     232                    case '\"':
     233                        value = '\"';
     234                        break;
     235                    default:
     236                        value = c;
     237                }
     238            }
     239            strarray.push_back(value);
     240        }
     241        else // regular character
     242        {
     243            if (*linePtr=='\n')
     244                lineNo++;
     245            strarray.push_back(*linePtr++);
     246        }
     247    }
     248    if (linePtr == end)
     249        throw ParseException(lineNo, "Unterminated string");
     250    linePtr++;
     251    return strarray;
     252}
     253
     254static std::string parseYAMLStringValue(const char*& ptr, const char* end, size_t& lineNo,
     255                    cxuint prevIndent)
     256{
     257    skipSpacesToEnd(ptr, end);
     258    if (ptr == end)
     259        return "";
     260    if (*ptr=='"' || *ptr== '\'')
     261        return parseYAMLString(ptr, end, lineNo);
     262   
     263    // otherwise parse stream
     264    if (*ptr == '|' || *ptr == '>')
     265    {
     266        // multiline
     267        bool newLineFold = *ptr=='>';
     268        while (ptr != end && *ptr!='\n') ptr++;
     269        if (ptr == end)
     270            return ""; // end
     271        lineNo++;
     272        ptr++; // skip newline
     273        const char* lineStart = ptr;
     274        skipSpacesToEnd(ptr, end);
     275        size_t indent = ptr - lineStart;
     276        if (indent <= prevIndent)
     277            throw ParseException(lineNo, "Unindented string block");
     278       
     279        std::string buf;
     280        while(ptr != end)
     281        {
     282            const char* strStart = ptr;
     283            while (ptr != end && *ptr!='\n') ptr++;
     284            buf.append(strStart, end);
     285           
     286            lineNo++;
     287            const char* lineStart = ptr;
     288            skipSpacesToEnd(ptr, end);
     289            if (size_t(ptr - lineStart) < indent)
     290            {
     291                if (ptr == end || *ptr=='\n')
     292                {
     293                    if (!newLineFold)
     294                        buf.append("\n");
     295                    continue;
     296                }
     297                // if smaller indent
     298                ptr = lineStart;
     299                return buf;
     300            }
     301            ptr = lineStart + indent;
     302            if (!newLineFold)
     303                buf.append("\n");
     304        }
     305        return buf;
     306    }
     307    const char* strStart = ptr;
     308    while (ptr != end && *ptr!='\n') ptr++;
     309    return std::string(strStart, ptr);
     310}
     311
     312class CLRX_INTERNAL YAMLElemConsumer
     313{
     314public:
     315    virtual void consume(const char*& ptr, const char* end, size_t& lineNo,
     316                cxuint prevIndent) = 0;
     317};
     318
     319static void parseYAMLValArray(const char*& ptr, const char* end, size_t& lineNo,
     320            size_t prevIndent, YAMLElemConsumer* elemConsumer)
     321{
     322    skipSpacesToEnd(ptr, end);
     323    if (ptr == end)
     324        return;
     325   
     326    if (*ptr == '[')
     327    {
     328        ptr++;
     329        skipSpacesAndComments(ptr, end, lineNo);
     330        while (ptr != end)
     331        {
     332            // parse in line
     333            elemConsumer->consume(ptr, end, lineNo, 0);
     334            if (ptr!=end && *ptr==',')
     335                throw ParseException(lineNo, "Expected ','");
     336            else if (ptr!=end && *ptr==']')
     337                // just end
     338                break;
     339            ptr++;
     340            skipSpacesAndComments(ptr, end, lineNo);
     341        }
     342        if (ptr == end)
     343            throw ParseException(lineNo, "Unterminated array");
     344        ptr++;
     345        return;
     346    }
     347    // sequence
     348    size_t oldLineNo = lineNo;
     349    size_t indent0 = skipSpacesAndComments(ptr, end, lineNo);
     350    if (ptr == end || lineNo == oldLineNo)
     351        throw ParseException(lineNo, "Expected sequence of values");
     352   
     353    if (indent0 < prevIndent)
     354        throw ParseException(lineNo, "Unindented sequence of objects");
     355   
     356    while (ptr != end)
     357    {
     358        if (*ptr != '-')
     359            throw ParseException(lineNo, "No '-' before element value");
     360        ptr++;
     361        const char* afterMinus = ptr;
     362        skipSpacesToEnd(ptr, end);
     363        if (afterMinus == ptr)
     364            throw ParseException(lineNo, "No spaces after '-'");
     365        elemConsumer->consume(ptr, end, lineNo, indent0+1 + afterMinus-ptr);
     366       
     367        size_t indent = skipSpacesAndComments(ptr, end, lineNo);
     368        if (indent < indent0)
     369        {
     370            // if parent level
     371            ptr -= indent;
     372            break;
     373        }
     374        if (indent != indent0)
     375            throw ParseException(lineNo, "Wrong indentation of element");
     376    }
     377}
     378
     379template<typename T>
     380class CLRX_INTERNAL YAMLIntArrayConsumer: public YAMLElemConsumer
     381{
     382private:
     383    size_t elemsNum;
     384    size_t requiredElemsNum;
     385public:
     386    T* array;
     387   
     388    YAMLIntArrayConsumer(size_t reqElemsNum, T* _array)
     389            : elemsNum(0), requiredElemsNum(reqElemsNum), array(_array)
     390    { }
     391   
     392    virtual void consume(const char*& ptr, const char* end, size_t& lineNo,
     393                cxuint prevIndent)
     394    {
     395        if (elemsNum == requiredElemsNum)
     396            throw ParseException(lineNo, "Too many elements");
     397        try
     398        { array[elemsNum] = cstrtovCStyle<T>(ptr, end, ptr); }
     399        catch(const ParseException& ex)
     400        { throw ParseException(lineNo, ex.what()); }
     401        elemsNum++;
     402    }
     403};
     404
     405// printf info string consumer
     406
     407class CLRX_INTERNAL YAMLPrintfVectorConsumer: public YAMLElemConsumer
     408{
     409public:
     410    std::vector<ROCmPrintfInfo> printInfos;
     411   
     412    YAMLPrintfVectorConsumer()
     413    { }
     414   
     415    virtual void consume(const char*& ptr, const char* end, size_t& lineNo,
     416                cxuint prevIndent)
     417    {
     418        std::string str = parseYAMLStringValue(ptr, end, lineNo, prevIndent);
     419        // parse printf string
     420        ROCmPrintfInfo printfInfo;
     421       
     422        const char* ptr2 = str.c_str();
     423        const char* end2 = str.c_str() + str.size();
     424        skipSpacesToEnd(ptr2, end2);
     425        printfInfo.id = cstrtovCStyle<uint32_t>(ptr2, end2, ptr2);
     426        skipSpacesToEnd(ptr2, end2);
     427        if (ptr2==end || *ptr2!=':')
     428            throw ParseException(lineNo, "No colon after printf callId");
     429        ptr2++;
     430        skipSpacesToEnd(ptr2, end2);
     431        uint32_t argsNum = cstrtovCStyle<uint32_t>(ptr2, end2, ptr2);
     432        skipSpacesToEnd(ptr2, end2);
     433        if (ptr2==end || *ptr2!=':')
     434            throw ParseException(lineNo, "No colon after printf argsNum");
     435        ptr2++;
     436       
     437        printfInfo.argSizes.resize(argsNum);
     438       
     439        // parse arg sizes
     440        for (size_t i = 0; i < argsNum; i++)
     441        {
     442            skipSpacesToEnd(ptr2, end2);
     443            printfInfo.argSizes[i] = cstrtovCStyle<uint32_t>(ptr2, end2, ptr2);
     444            skipSpacesToEnd(ptr2, end2);
     445            if (ptr2==end || *ptr2!=':')
     446                throw ParseException(lineNo, "No colon after printf argsNum");
     447            ptr2++;
     448        }
     449        // format
     450        printfInfo.format.assign(ptr2, end2);
     451    }
     452};
     453
     454enum {
     455    ROCMMT_MAIN_KERNELS = 0, ROCMMT_MAIN_PRINTF,  ROCMMT_MAIN_VERSION
     456};
     457
     458static const char* mainMetadataKeywords[] =
     459{
     460    "Kernels", "Printf", "Version"
     461};
     462
     463static const size_t mainMetadataKeywordsNum =
     464        sizeof(mainMetadataKeywords) / sizeof(const char*);
     465
     466enum {
     467    ROCMMT_KERNEL_ARGS = 0, ROCMMT_KERNEL_ATTRS, ROCMMT_KERNEL_CODEPROPS,
     468    ROCMMT_KERNEL_LANGUAGE, ROCMMT_KERNEL_LANGUAGE_VERSION,
     469    ROCMMT_KERNEL_NAME, ROCMMT_KERNEL_SYMBOLNAME
     470};
     471
     472static const char* kernelMetadataKeywords[] =
     473{
     474    "Args", "Attrs", "CodeProps", "Language", "LanguageVersion", "Name", "SymbolName"
     475};
     476
     477static const size_t kernelMetadataKeywordsNum =
     478        sizeof(kernelMetadataKeywords) / sizeof(const char*);
     479
     480enum {
     481    ROCMMT_ATTRS_REQD_WORK_GROUP_SIZE = 0, ROCMMT_ATTRS_RUNTIME_HANDLE,
     482    ROCMMT_ATTRS_VECTYPEHINT, ROCMMT_ATTRS_WORK_GROUP_SIZE_HINT
     483};
     484
     485static const char* kernelAttrMetadataKeywords[] =
     486{
     487    "ReqdWorkGroupSize", "RuntimeHandle", "VecTypeHint", "WorkGroupSizeHint"
     488};
     489
     490static const size_t kernelAttrMetadataKeywordsNum =
     491        sizeof(kernelAttrMetadataKeywords) / sizeof(const char*);
     492
     493enum {
     494    ROCMMT_CODEPROPS_FIXED_WORK_GROUP_SIZE = 0, ROCMMT_CODEPROPS_GROUP_SEGMENT_FIXED_SIZE,
     495    ROCMMT_CODEPROPS_KERNARG_SEGMENT_ALIGN, ROCMMT_CODEPROPS_KERNARG_SEGMENT_SIZE,
     496    ROCMMT_CODEPROPS_MAX_FLAT_WORK_GROUP_SIZE, ROCMMT_CODEPROPS_NUM_SGPRS,
     497    ROCMMT_CODEPROPS_NUM_SPILLED_SGPRS, ROCMMT_CODEPROPS_NUM_SPILLED_VGPRS,
     498    ROCMMT_CODEPROPS_NUM_VGPRS, ROCMMT_CODEPROPS_PRIVATE_SEGMENT_FIXED_SIZE,
     499    ROCMMT_CODEPROPS_WAVEFRONT_SIZE
     500};
     501
     502static const char* kernelCodePropsKeywords[] =
     503{
     504    "FixedWorkGroupSize", "GroupSegmentFixedSize", "KernargSegmentAlign",
     505    "KernargSegmentSize", "MaxFlatWorkGroupSize", "NumSGPRs",
     506    "NumSpilledSGPRs", "NumSpilledVGPRs", "NumVGPRs", "PrivateSegmentFixedSize",
     507    "WavefrontSize"
     508};
     509
     510static const size_t kernelCodePropsKeywordsNum =
     511        sizeof(kernelCodePropsKeywords) / sizeof(const char*);
     512
     513enum {
     514    ROCMMT_ARGS_ACCQUAL = 0, ROCMMT_ARGS_ACTUALACCQUAL, ROCMMT_ARGS_ADDRSPACEQUAL,
     515    ROCMMT_ARGS_ALIGN, ROCMMT_ARGS_ISCONST, ROCMMT_ARGS_ISPIPE, ROCMMT_ARGS_ISRESTRICT,
     516    ROCMMT_ARGS_ISVOLATILE, ROCMMT_ARGS_NAME, ROCMMT_ARGS_POINTEE_ALIGN,
     517    ROCMMT_ARGS_SIZE, ROCMMT_ARGS_TYPENAME, ROCMMT_ARGS_VALUEKIND,
     518    ROCMMT_ARGS_VALUETYPE
     519};
     520
     521static const char* kernelArgInfosKeywords[] =
     522{
     523    "AccQual", "ActualAccQual", "AddrSpaceQual", "Align", "IsConst", "IsPipe",
     524    "IsRestrict", "IsVolatile", "Name", "PointeeAlign", "Size", "TypeName",
     525    "ValueKind", "ValueType"
     526};
     527
     528static const size_t kernelArgInfosKeywordsNum =
     529        sizeof(kernelArgInfosKeywords) / sizeof(const char*);
     530
     531static const std::pair<const char*, ROCmValueKind> rocmValueKindNames[] =
     532{
     533    { "ByValue", ROCmValueKind::BY_VALUE },
     534    { "DynamicSharedPointer", ROCmValueKind::DYN_SHARED_PTR },
     535    { "GlobalBuffer", ROCmValueKind::GLOBAL_BUFFER },
     536    { "HiddenCompletionAction", ROCmValueKind::HIDDEN_COMPLETION_ACTION },
     537    { "HiddenDefaultQueue", ROCmValueKind::HIDDEN_DEFAULT_QUEUE },
     538    { "HiddenGlobalOffsetX", ROCmValueKind::HIDDEN_GLOBAL_OFFSET_X },
     539    { "HiddenGlobalOffsetY", ROCmValueKind::HIDDEN_GLOBAL_OFFSET_Y },
     540    { "HiddenglobalOffsetZ", ROCmValueKind::HIDDEN_GLOBAL_OFFSET_Z },
     541    { "HiddenNone", ROCmValueKind::HIDDEN_NONE },
     542    { "HiddenPrintfBuffer", ROCmValueKind::HIDDEN_PRINTF_BUFFER },
     543    { "Image", ROCmValueKind::IMAGE },
     544    { "Pipe", ROCmValueKind::PIPE },
     545    { "Queue", ROCmValueKind::QUEUE },
     546    { "Sampler", ROCmValueKind::SAMPLER }
     547};
     548
     549static const size_t rocmValueKindNamesNum =
     550        sizeof(rocmValueKindNames) / sizeof(std::pair<const char*, ROCmValueKind>);
     551
     552static const std::pair<const char*, ROCmValueType> rocmValueTypeNames[] =
     553{
     554    { "F16", ROCmValueType::FLOAT16 },
     555    { "F32", ROCmValueType::FLOAT32 },
     556    { "F64", ROCmValueType::FLOAT64 },
     557    { "I16", ROCmValueType::INT16 },
     558    { "I8", ROCmValueType::INT8 },
     559    { "I32", ROCmValueType::INT32 },
     560    { "I64", ROCmValueType::INT64 },
     561    { "U8", ROCmValueType::UINT8 },
     562    { "U16", ROCmValueType::UINT16 },
     563    { "U32", ROCmValueType::UINT32 },
     564    { "U64", ROCmValueType::UINT64 },
     565    { "Struct", ROCmValueType::STRUCTURE }
     566};
     567
     568static const size_t rocmValueTypeNamesNum =
     569        sizeof(rocmValueTypeNames) / sizeof(std::pair<const char*, ROCmValueType>);
     570
     571static const char* rocmAddrSpaceTypesTbl[] =
     572{ "Private", "Global", "Constant", "Local", "Generic", "Region" };
     573
     574static const char* rocmAccessQualifierTbl[] =
     575{ "ReadOnly", "WriteOnly", "ReadWrite", "Default" };
     576
     577void parseROCmMetadata(size_t metadataSize, const char* metadata,
     578                ROCmMetadata& metadataInfo)
     579{
     580    const char* ptr = metadata;
     581    const char* end = metadata + metadataSize;
     582    size_t lineNo = 1;
     583    // init metadata info object
     584    metadataInfo.kernels.clear();
     585    metadataInfo.printfInfos.clear();
     586    metadataInfo.version[0] = metadataInfo.version[1] = 0;
     587   
     588    std::vector<ROCmKernelMetadata> kernels;
     589    std::vector<ROCmKernelArgInfo> kernelArgs;
     590   
     591    cxuint levels[6] = { UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX };
     592    cxuint curLevel = 0;
     593    bool inKernels = false;
     594    bool inKernel = false;
     595    bool inKernelArgs = false;
     596    bool inKernelArg = false;
     597    bool inKernelCodeProps = false;
     598    bool inKernelAttrs = false;
     599    bool canToNextLevel = false;
     600   
     601    size_t oldLineNo = 0;
     602    while (ptr != end)
     603    {
     604        cxuint level = skipSpacesAndComments(ptr, end, lineNo);
     605        if (ptr == end || lineNo == oldLineNo)
     606            throw ParseException(lineNo, "Expected new line");
     607       
     608        if (levels[curLevel] == UINT_MAX)
     609            levels[curLevel] = level;
     610        else if (levels[curLevel] < level)
     611        {
     612            if (canToNextLevel)
     613                // go to next nesting level
     614                levels[++curLevel] = level;
     615            else
     616                throw ParseException(lineNo, "Unexpected nesting level");
     617            canToNextLevel = false;
     618        }
     619        else if (levels[curLevel] > level)
     620        {
     621            while (curLevel != UINT_MAX && levels[curLevel] > level)
     622                curLevel--;
     623            if (curLevel == UINT_MAX)
     624                throw ParseException(lineNo, "Indentation smaller than in main level");
     625           
     626            // pop from previous level
     627            if (curLevel < 3)
     628            {
     629                if (inKernelArgs)
     630                {
     631                    // leave from kernel args
     632                    ROCmKernelMetadata& kernel = kernels.back();
     633                    kernel.argInfos.assign(kernelArgs.begin(), kernelArgs.end());
     634                    kernelArgs.clear();
     635                    inKernelArgs = false;
     636                    inKernelArg = false;
     637                }
     638           
     639                inKernelCodeProps = false;
     640                inKernelAttrs = false;
     641            }
     642            if (curLevel < 1 && inKernels)
     643            {
     644                // leave from kernels
     645                metadataInfo.kernels.assign(kernels.begin(), kernels.end());
     646                kernels.clear();
     647                inKernels = false;
     648                inKernel = false;
     649            }
     650           
     651            if (levels[curLevel] != level)
     652                throw ParseException(lineNo, "Unexpected nesting level");
     653        }
     654       
     655        oldLineNo = lineNo;
     656        if (curLevel == 0)
     657        {
     658            const size_t keyIndex = parseYAMLKey(ptr, end, lineNo,
     659                        mainMetadataKeywordsNum, mainMetadataKeywords);
     660           
     661            switch(keyIndex)
     662            {
     663                case ROCMMT_MAIN_KERNELS:
     664                    inKernels = true;
     665                    canToNextLevel = true;
     666                    break;
     667                case ROCMMT_MAIN_PRINTF:
     668                {
     669                    YAMLPrintfVectorConsumer consumer;
     670                    parseYAMLValArray(ptr, end, lineNo, levels[curLevel], &consumer);
     671                    metadataInfo.printfInfos.assign(consumer.printInfos.begin(),
     672                                    consumer.printInfos.end());
     673                    break;
     674                }
     675                case ROCMMT_MAIN_VERSION:
     676                {
     677                    YAMLIntArrayConsumer<uint32_t> consumer(2, metadataInfo.version);
     678                    parseYAMLValArray(ptr, end, lineNo, levels[curLevel], &consumer);
     679                    break;
     680                }
     681                default:
     682                    break;
     683            }
     684        }
     685       
     686        if (curLevel==1 && inKernels)
     687        {
     688            // enter to kernel level
     689            if (ptr == end || *ptr != '-')
     690                throw ParseException(lineNo, "No '-' before kernel object");
     691            ptr++;
     692            const char* afterMinus = ptr;
     693            skipSpacesToEnd(ptr, end);
     694            levels[++curLevel] = level + 1 + ptr-afterMinus;
     695            level = levels[curLevel];
     696            inKernel = true;
     697           
     698            kernels.push_back(ROCmKernelMetadata());
     699        }
     700       
     701        if (curLevel==2 && inKernel)
     702        {
     703            // in kernel
     704            const size_t keyIndex = parseYAMLKey(ptr, end, lineNo,
     705                        kernelMetadataKeywordsNum, kernelMetadataKeywords);
     706           
     707            ROCmKernelMetadata& kernel = kernels.back();
     708            switch(keyIndex)
     709            {
     710                case ROCMMT_KERNEL_ARGS:
     711                    kernelArgs.clear();
     712                    inKernelArgs = true;
     713                    canToNextLevel = true;
     714                    break;
     715                case ROCMMT_KERNEL_ATTRS:
     716                    inKernelAttrs = true;
     717                    canToNextLevel = true;
     718                    break;
     719                case ROCMMT_KERNEL_CODEPROPS:
     720                    inKernelCodeProps = true;
     721                    canToNextLevel = true;
     722                    break;
     723                case ROCMMT_KERNEL_LANGUAGE:
     724                    kernel.language = parseYAMLStringValue(ptr, end, lineNo, level);
     725                    break;
     726                case ROCMMT_KERNEL_LANGUAGE_VERSION:
     727                {
     728                    YAMLIntArrayConsumer<uint32_t> consumer(2, kernel.langVersion);
     729                    parseYAMLValArray(ptr, end, lineNo, levels[curLevel], &consumer);
     730                    break;
     731                }
     732                case ROCMMT_KERNEL_NAME:
     733                    kernel.name = parseYAMLStringValue(ptr, end, lineNo, level);
     734                    break;
     735                case ROCMMT_KERNEL_SYMBOLNAME:
     736                    kernel.symbolName = parseYAMLStringValue(ptr, end, lineNo, level);
     737                    break;
     738                default:
     739                    break;
     740            }
     741        }
     742       
     743        if (curLevel==3 && inKernelAttrs)
     744        {
     745            // in kernel attributes
     746            const size_t keyIndex = parseYAMLKey(ptr, end, lineNo,
     747                        kernelAttrMetadataKeywordsNum, kernelAttrMetadataKeywords);
     748           
     749            ROCmKernelMetadata& kernel = kernels.back();
     750            switch(keyIndex)
     751            {
     752                case ROCMMT_ATTRS_REQD_WORK_GROUP_SIZE:
     753                {
     754                    YAMLIntArrayConsumer<cxuint> consumer(3, kernel.reqdWorkGroupSize);
     755                    parseYAMLValArray(ptr, end, lineNo, levels[curLevel], &consumer);
     756                    break;
     757                }
     758                case ROCMMT_ATTRS_RUNTIME_HANDLE:
     759                    kernel.runtimeHandle = parseYAMLStringValue(ptr, end, lineNo, level);
     760                    break;
     761                case ROCMMT_ATTRS_VECTYPEHINT:
     762                    kernel.vecTypeHint = parseYAMLStringValue(ptr, end, lineNo, level);
     763                    break;
     764                case ROCMMT_ATTRS_WORK_GROUP_SIZE_HINT:
     765                {
     766                    YAMLIntArrayConsumer<cxuint> consumer(3, kernel.workGroupSizeHint);
     767                    parseYAMLValArray(ptr, end, lineNo, levels[curLevel], &consumer);
     768                    break;
     769                }
     770                default:
     771                    break;
     772            }
     773        }
     774       
     775        if (curLevel==3 && inKernelCodeProps)
     776        {
     777            // in kernel codeProps
     778            const size_t keyIndex = parseYAMLKey(ptr, end, lineNo,
     779                        kernelCodePropsKeywordsNum, kernelCodePropsKeywords);
     780           
     781            ROCmKernelMetadata& kernel = kernels.back();
     782            switch(keyIndex)
     783            {
     784                case ROCMMT_CODEPROPS_FIXED_WORK_GROUP_SIZE:
     785                {
     786                    YAMLIntArrayConsumer<uint64_t> consumer(3, kernel.fixedWorkGroupSize);
     787                    parseYAMLValArray(ptr, end, lineNo, level, &consumer);
     788                    break;
     789                }
     790                case ROCMMT_CODEPROPS_GROUP_SEGMENT_FIXED_SIZE:
     791                    kernel.groupSegmentFixedSize =
     792                                parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     793                    break;
     794                case ROCMMT_CODEPROPS_KERNARG_SEGMENT_ALIGN:
     795                    kernel.kernargSegmentAlign =
     796                                parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     797                    break;
     798                case ROCMMT_CODEPROPS_KERNARG_SEGMENT_SIZE:
     799                    kernel.kernargSegmentSize =
     800                                parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     801                    break;
     802                case ROCMMT_CODEPROPS_MAX_FLAT_WORK_GROUP_SIZE:
     803                    kernel.maxFlatWorkGroupSize =
     804                                parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     805                    break;
     806                case ROCMMT_CODEPROPS_NUM_SGPRS:
     807                    kernel.sgprsNum = parseYAMLIntValue<cxuint>(ptr, end, lineNo);
     808                    break;
     809                case ROCMMT_CODEPROPS_NUM_SPILLED_SGPRS:
     810                    kernel.spilledSgprs = parseYAMLIntValue<cxuint>(ptr, end, lineNo);
     811                    break;
     812                case ROCMMT_CODEPROPS_NUM_SPILLED_VGPRS:
     813                    kernel.spilledVgprs = parseYAMLIntValue<cxuint>(ptr, end, lineNo);
     814                    break;
     815                case ROCMMT_CODEPROPS_NUM_VGPRS:
     816                    kernel.vgprsNum = parseYAMLIntValue<cxuint>(ptr, end, lineNo);
     817                    break;
     818                case ROCMMT_CODEPROPS_PRIVATE_SEGMENT_FIXED_SIZE:
     819                    kernel.privateSegmentFixedSize =
     820                                parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     821                    break;
     822                case ROCMMT_CODEPROPS_WAVEFRONT_SIZE:
     823                    kernel.wavefrontSize = parseYAMLIntValue<cxuint>(ptr, end, lineNo);
     824                    break;
     825                default:
     826                    break;
     827            }
     828        }
     829       
     830        if (curLevel==3 && inKernelArgs)
     831        {
     832            // enter to kernel argument level
     833            if (ptr == end || *ptr != '-')
     834                throw ParseException(lineNo, "No '-' before argument object");
     835            ptr++;
     836            const char* afterMinus = ptr;
     837            skipSpacesToEnd(ptr, end);
     838            levels[++curLevel] = level + 1 + ptr-afterMinus;
     839            level = levels[curLevel];
     840            inKernelArg = true;
     841           
     842            kernelArgs.push_back(ROCmKernelArgInfo());
     843        }
     844       
     845        if (curLevel==4 && inKernelArg)
     846        {
     847            // in kernel argument
     848            const size_t keyIndex = parseYAMLKey(ptr, end, lineNo,
     849                        kernelArgInfosKeywordsNum, kernelArgInfosKeywords);
     850           
     851            ROCmKernelArgInfo& kernelArg = kernelArgs.back();
     852            switch(keyIndex)
     853            {
     854                case ROCMMT_ARGS_ACCQUAL:
     855                case ROCMMT_ARGS_ACTUALACCQUAL:
     856                {
     857                    const std::string acc = trimStrSpaces(parseYAMLStringValue(
     858                                    ptr, end, lineNo, level));
     859                    size_t accIndex = 0;
     860                    for (; accIndex < 6; accIndex++)
     861                        if (::strcmp(rocmAccessQualifierTbl[accIndex], acc.c_str())==0)
     862                            break;
     863                    if (accIndex == 4)
     864                        throw ParseException(lineNo, "Wrong access qualifier");
     865                    if (keyIndex == ROCMMT_ARGS_ACCQUAL)
     866                        kernelArg.accessQual = ROCmAccessQual(accIndex);
     867                    else
     868                        kernelArg.actualAccessQual = ROCmAccessQual(accIndex);
     869                    break;
     870                }
     871                case ROCMMT_ARGS_ADDRSPACEQUAL:
     872                {
     873                    const std::string aspace = trimStrSpaces(parseYAMLStringValue(
     874                                    ptr, end, lineNo, level));
     875                    size_t aspaceIndex = 0;
     876                    for (; aspaceIndex < 6; aspaceIndex++)
     877                        if (::strcmp(rocmAddrSpaceTypesTbl[aspaceIndex],
     878                                    aspace.c_str())==0)
     879                            break;
     880                    if (aspaceIndex == 6)
     881                        throw ParseException(lineNo, "Wrong address space");
     882                    kernelArg.addressSpace = ROCmAddressSpace(aspaceIndex);
     883                    break;
     884                }
     885                case ROCMMT_ARGS_ALIGN:
     886                    kernelArg.align = parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     887                    break;
     888                case ROCMMT_ARGS_ISCONST:
     889                    kernelArg.isConst = parseYAMLBoolValue(ptr, end, lineNo);
     890                    break;
     891                case ROCMMT_ARGS_ISPIPE:
     892                    kernelArg.isPipe = parseYAMLBoolValue(ptr, end, lineNo);
     893                    break;
     894                case ROCMMT_ARGS_ISRESTRICT:
     895                    kernelArg.isRestrict = parseYAMLBoolValue(ptr, end, lineNo);
     896                    break;
     897                case ROCMMT_ARGS_ISVOLATILE:
     898                    kernelArg.isVolatile = parseYAMLBoolValue(ptr, end, lineNo);
     899                    break;
     900                case ROCMMT_ARGS_NAME:
     901                    kernelArg.name = parseYAMLStringValue(ptr, end, lineNo, level);
     902                    break;
     903                case ROCMMT_ARGS_POINTEE_ALIGN:
     904                    kernelArg.pointeeAlign = parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     905                    break;
     906                case ROCMMT_ARGS_SIZE:
     907                    kernelArg.size = parseYAMLIntValue<uint64_t>(ptr, end, lineNo);
     908                    break;
     909                case ROCMMT_ARGS_TYPENAME:
     910                    kernelArg.typeName = parseYAMLStringValue(ptr, end, lineNo, level);
     911                    break;
     912                case ROCMMT_ARGS_VALUEKIND:
     913                {
     914                    const std::string vkind = trimStrSpaces(parseYAMLStringValue(
     915                                ptr, end, lineNo, level));
     916                    const size_t vkindIndex = binaryMapFind(rocmValueKindNames,
     917                            rocmValueKindNames + rocmValueKindNamesNum, vkind.c_str(),
     918                            CStringLess()) - rocmValueKindNames;
     919                    // if unknown kind
     920                    if (vkindIndex == rocmValueKindNamesNum)
     921                        throw ParseException(lineNo, "Wrong argument value kind");
     922                    kernelArg.valueKind = rocmValueKindNames[vkindIndex].second;
     923                    break;
     924                }
     925                case ROCMMT_ARGS_VALUETYPE:
     926                {
     927                    const std::string vtype = trimStrSpaces(parseYAMLStringValue(
     928                                    ptr, end, lineNo, level));
     929                    const size_t vtypeIndex = binaryMapFind(rocmValueTypeNames,
     930                            rocmValueTypeNames + rocmValueTypeNamesNum, vtype.c_str(),
     931                            CStringLess()) - rocmValueTypeNames;
     932                    // if unknown type
     933                    if (vtypeIndex == rocmValueTypeNamesNum)
     934                        throw ParseException(lineNo, "Wrong argument value type");
     935                    kernelArg.valueKind = rocmValueKindNames[vtypeIndex].second;
     936                    break;
     937                }
     938                default:
     939                    break;
     940            }
     941        }
     942    }
     943}
     944
     945/*
     946 * ROCm binary reader and generator
     947 */
    34948
    35949/* TODO: add support for various kernel code offset (now only 256 is supported) */
Note: See TracChangeset for help on using the changeset viewer.