Ejemplo n.º 1
0
bstring parse_workgroup(Workgroup* group, const_bstring str, DataType type)
{
    CpuTopology_t topo;
    struct bstrList* tokens;
    bstring cpustr;
    int numThreads = 0;
    bstring domain;


    tokens = bsplit(str,':');
    if (tokens->qty == 2)
    {
        topo = get_cpuTopology();
        numThreads = topo->activeHWThreads;
        cpustr = bformat("E:%s:%d", bdata(tokens->entry[0]), numThreads );
    }
    else if (tokens->qty == 3)
    {
        cpustr = bformat("E:%s:%s", bdata(tokens->entry[0]), bdata(tokens->entry[2]));
        numThreads = str2int(bdata(tokens->entry[2]));
        if (numThreads < 0)
        {
            fprintf(stderr, "Cannot convert %s to integer\n", bdata(tokens->entry[2]));
            bstrListDestroy(tokens);
            return NULL;
        }
    }
    else if (tokens->qty == 5)
    {
        cpustr = bformat("E:%s:%s:%s:%s", bdata(tokens->entry[0]),
                                          bdata(tokens->entry[2]),
                                          bdata(tokens->entry[3]),
                                          bdata(tokens->entry[4]));
        numThreads = str2int(bdata(tokens->entry[2]));
        if (numThreads < 0)
        {
            fprintf(stderr, "Cannot convert %s to integer\n", bdata(tokens->entry[2]));
            bstrListDestroy(tokens);
            return NULL;
        }
    }
    else
    {
        fprintf(stderr, "Misformated workgroup string\n");
        bstrListDestroy(tokens);
        return NULL;
    }

    group->size = bstr_to_doubleSize(tokens->entry[1], type);
    if (group->size == 0)
    {
        fprintf(stderr, "Stream size cannot be read, should look like <domain>:<size>\n");
        bstrListDestroy(tokens);
        return NULL;
    }
    group->processorIds = (int*) malloc(numThreads * sizeof(int));
    if (group->processorIds == NULL)
    {
        fprintf(stderr, "No more memory to allocate list of processors\n");
        bstrListDestroy(tokens);
        return NULL;
    }
    group->numberOfThreads = numThreads;
    if (cpustr_to_cpulist(bdata(cpustr),group->processorIds, numThreads) < 0 )
    {
        free(group->processorIds);
        bstrListDestroy(tokens);
        return NULL;
    }
    domain = bstrcpy(tokens->entry[0]);
    bdestroy(cpustr);
    bstrListDestroy(tokens);
    return domain;
}
Ejemplo n.º 2
0
void bstr_to_workgroup(Workgroup* group, const_bstring str, DataType type, int numberOfStreams)
{
    uint32_t i;
    int parseStreams = 0;
    bstring threadInfo;
    bstring streams= bformat("0");
    struct bstrList* tokens;
    struct bstrList* subtokens;
    AffinityDomains_t domains;
    AffinityDomain* domain = NULL;

    /* split the workgroup into the thread and the streams part */
    tokens = bsplit(str,'-');

    if (tokens->qty == 2)
    {
        threadInfo = bstrcpy(tokens->entry[0]);
        streams = bstrcpy(tokens->entry[1]);
        parseStreams = 1;
    }
    else if (tokens->qty == 1)
    {
        threadInfo = bstrcpy(tokens->entry[0]);
    }
    else
    {
        fprintf(stderr, "Error in parsing workgroup string\n");
    }

    bstrListDestroy (tokens);
    tokens = bsplit(threadInfo,':');

    if (tokens->qty == 5)
    {
        uint32_t maxNumThreads;
        int chunksize;
        int stride;
        int counter;
        int currentId = 0;
        int startId = 0;

        domains = get_affinityDomains();
        for (i = 0; i < domains->numberOfAffinityDomains; i++)
        {
            if (bstrcmp(domains->domains[i].tag, tokens->entry[0]) == BSTR_OK)
            {
                domain = &(domains->domains[i]);
                break;
            }
        }

        if (domain == NULL)
        {
            fprintf(stderr, "Error: Domain %s not available on current machine.\nTry likwid-bench -p for supported domains.",
                bdata(tokens->entry[0]));
            exit(EXIT_FAILURE);
        }

        group->size = bstr_to_doubleSize(tokens->entry[1], type);
        group->numberOfThreads = str2int(bdata(tokens->entry[2]));
        chunksize = str2int(bdata(tokens->entry[3]));
        stride = str2int(bdata(tokens->entry[4]));
        maxNumThreads = ceil((double)domain->numberOfProcessors / stride) * chunksize;

        if (group->numberOfThreads > maxNumThreads)
        {
            fprintf(stderr, "Warning: More threads (%d) requested than CPUs in domain %s fulfilling expression (%d).\n",
                    group->numberOfThreads, bdata(tokens->entry[0]), maxNumThreads);
        }

        group->processorIds = (int*) malloc(group->numberOfThreads * sizeof(int));

        counter = chunksize;

        counter = 0;
        for (int j=0; j<group->numberOfThreads; j+=chunksize)
        {
            for(i=0;i<chunksize && j+i<group->numberOfThreads ;i++)
            {
                group->processorIds[startId++] = domain->processorList[counter+i];
            }
            counter += stride;
            if (counter >= domain->numberOfProcessors)
            {
                counter = counter-domain->numberOfProcessors;
            }
        }
    }
    else if (tokens->qty == 3)
    {
        domains = get_affinityDomains();
        for (i = 0; i < domains->numberOfAffinityDomains; i++)
        {
            if (bstrcmp(domains->domains[i].tag, tokens->entry[0]) == BSTR_OK)
            {
                domain = &(domains->domains[i]);
                break;
            }
        }

        if (domain == NULL)
        {
            fprintf(stderr, "Error: Domain %s not available on current machine.\nTry likwid-bench -p for supported domains.",
                    bdata(tokens->entry[0]));
            exit(EXIT_FAILURE);
        }

        group->size = bstr_to_doubleSize(tokens->entry[1], type);
        group->numberOfThreads = str2int(bdata(tokens->entry[2]));

        if (group->numberOfThreads > domain->numberOfProcessors)
        {
            fprintf(stderr, "Warning: More threads (%d) requested than CPUs in domain %s (%d).\n",
                    group->numberOfThreads, bdata(tokens->entry[0]), domain->numberOfProcessors);
        }

        group->processorIds = (int*) malloc(group->numberOfThreads * sizeof(int));

        for (i=0; i<group->numberOfThreads; i++)
        {
            group->processorIds[i] = domain->processorList[i % domain->numberOfProcessors];
        }
    }
    else if (tokens->qty == 2)
    {
        domains = get_affinityDomains();
        for (i = 0; i < domains->numberOfAffinityDomains; i++)
        {
            if (bstrcmp(domains->domains[i].tag, tokens->entry[0]) == BSTR_OK)
            {
                domain = &(domains->domains[i]);
                break;
            }
        }

        if (domain == NULL)
        {
            fprintf(stderr, "Error: Domain %s not available on current machine.\nTry likwid-bench -p for supported domains.",
                            bdata(tokens->entry[0]));
            exit(EXIT_FAILURE);
        }

        group->size = bstr_to_doubleSize(tokens->entry[1], type);
        group->numberOfThreads = domain->numberOfProcessors;
        group->processorIds = (int*) malloc(group->numberOfThreads * sizeof(int));

        for (i=0; i<group->numberOfThreads; i++)
        {
            group->processorIds[i] = domain->processorList[i];
        }
    }
    else
    {
        fprintf(stderr, "Error in parsing workgroup string\n");
    }

    bstrListDestroy(tokens);

    /* parse stream list */
    if (parseStreams)
    {
        tokens = bsplit(streams,',');

        if (tokens->qty < numberOfStreams)
        {
            fprintf(stderr, "Error: Testcase requires at least %d streams\n", numberOfStreams);
        }

        group->streams = (Stream*) malloc(numberOfStreams * sizeof(Stream));

        for (i=0;i<(uint32_t) tokens->qty;i++)
        {
            subtokens = bsplit(tokens->entry[i],':');

            if ( subtokens->qty == 3 )
            {
                int index = str2int(bdata(subtokens->entry[0]));
                if (index >= numberOfStreams)
                {
                    fprintf(stderr, "Error: Stream index %d out of range\n",index);
                }
                group->streams[index].domain = bstrcpy(subtokens->entry[1]);
                group->streams[index].offset = str2int(bdata(subtokens->entry[2]));
            }
            else if ( subtokens->qty == 2 )
            {
                int index = str2int(bdata(subtokens->entry[0]));
                if (index >= numberOfStreams)
                {
                    fprintf(stderr, "Error: Stream index %d out of range\n",index);
                }
                group->streams[index].domain = bstrcpy(subtokens->entry[1]);
                group->streams[index].offset = 0;
            }
            else
            {
                fprintf(stderr, "Error: Cannot parse stream placement defintition in %s\n", bdata(str));
            }

            bstrListDestroy(subtokens);
        }

        bstrListDestroy(tokens);
    }
    else
    {
        group->streams = (Stream*) malloc(numberOfStreams * sizeof(Stream));

        for (i=0; i< (uint32_t)numberOfStreams; i++)
        {
            group->streams[i].domain = domain->tag;
            group->streams[i].offset = 0;
        }
    }

    group->size /= numberOfStreams;
    return;
}