codes_mapping.c 25 KB
Newer Older
1
/*
Philip Carns's avatar
Philip Carns committed
2
 * Copyright (C) 2013 University of Chicago.
3
 * See COPYRIGHT notice in top-level directory.
Philip Carns's avatar
Philip Carns committed
4
 *
5 6 7 8 9 10 11
 */

/* SUMMARY:
 * CODES custom mapping file for ROSS
 */
#include "codes/codes_mapping.h"

12 13
#define CODES_MAPPING_DEBUG 0

14 15 16 17 18 19
/* number of LPs assigned to the current PE (abstraction of MPI rank).
 * for lp counts which are not divisible by the number of ranks, keep 
 * modulus around */
static int lps_per_pe_floor = 0;
static int lps_leftover = 0;

Jonathan Jenkins's avatar
Jonathan Jenkins committed
20
static int mem_factor = 256;
21

22 23 24 25 26 27 28 29 30
/* canonical group/lp/annotation name-index mappings */
static char const * * group_names;
static char const * * lp_names;
// unannotated is represented by index num_uniq_annos
static char const * * anno_names;
static int num_uniq_groups;
static int num_uniq_lptypes;
static int num_uniq_annos;

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
static int mini(int a, int b){ return a < b ? a : b; }

// compare passed in annotation strings (NULL or nonempty) against annotation
// strings in the config (empty or nonempty)
static int cmp_anno(const char * anno_user, const char * anno_config){
    return anno_user == NULL ? anno_config[0]=='\0'
                             : !strcmp(anno_user, anno_config);
}


#if 0
// TODO: this code seems useful, but I'm not sure where to put it for the time
// being. It should be useful when we are directly reading from the
// configuration file, which has the unprocessed annotated strings

// return code matches that of strcmp and friends, checks
// lp_type_name@annotation against full name
// NOTE: no argument should be NULL or invalid strings
static int strcmp_anno(
        const char * full_name,
        const char * prefix,
        const char * annotation){
    int i;
    // first phase - check full_name against prefix
    for (i = 0; i < MAX_NAME_LENGTH; i++){
        char cf = full_name[i], cl = prefix[i];
        if (cl == '\0')
            break; // match successful
        else if (cf != cl) // captures case where cf is null char or @
            return (int)(cf-cl); // lp name on full doesn't match
    }
    if (i==MAX_NAME_LENGTH) return 1;
    // second phase - ensure the next character after the match is an @
    if (full_name[i] != '@') return -1;
    // third phase, compare the remaining full_name against annotation
    return strcmp(full_name+i+1, annotation);
}
#endif
69

70
/* char arrays for holding lp type name and group name*/
71 72 73
// (unused var atm) static char local_group_name[MAX_NAME_LENGTH];
static char local_lp_name[MAX_NAME_LENGTH],
            local_annotation[MAX_NAME_LENGTH];
74

75 76
int codes_mapping_get_lps_for_pe()
{
77 78 79 80 81 82
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#if CODES_MAPPING_DEBUG
    printf("%d lps for rank %d\n", lps_per_pe_floor+(g_tw_mynode < lps_leftover), rank);
#endif
  return lps_per_pe_floor + (g_tw_mynode < lps_leftover);
83 84 85 86 87
}

/* Takes the global LP ID and returns the rank (PE id) on which the LP is mapped */
tw_peid codes_mapping( tw_lpid gid)
{
88 89 90 91 92 93 94 95
    int lps_on_pes_with_leftover = lps_leftover * (lps_per_pe_floor+1);
    if (gid < lps_on_pes_with_leftover){
        return gid / (lps_per_pe_floor+1);
    }
    else{
        return (gid-lps_on_pes_with_leftover)/lps_per_pe_floor + lps_leftover;
    }
  /*return gid / lps_per_pe_floor;*/
96 97
}

98
int codes_mapping_get_group_reps(const char* group_name)
99
{
100 101 102
  int grp;
  for(grp = 0; grp < lpconf.lpgroups_count; grp++)
  {
103
     if(strcmp(lpconf.lpgroups[grp].name, group_name) == 0)
104 105 106 107
	     return lpconf.lpgroups[grp].repetitions;
  }
  return -1;
}
108

109 110 111 112 113 114 115 116 117 118
int codes_mapping_get_lp_count(
        const char * group_name,
        int          ignore_repetitions,
        const char * lp_type_name,
        const char * annotation,
        int          ignore_annos){
    int lp_type_ct_total = 0;

    // check - if group name is null, then disable ignore_repetitions (the
    // former takes precedence)
119
    if (group_name == NULL)
120 121
        ignore_repetitions = 0;
    for (int g = 0; g < lpconf.lpgroups_count; g++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
122
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
123 124 125 126
        // iterate over the lps if the group is null (count across all groups)
        // or if the group names match
        if (group_name == NULL || strcmp(lpg->name, group_name) == 0){
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
127
                const config_lptype_t *lpt = &lpg->lptypes[l];
128 129 130 131 132 133 134 135 136
                if (strcmp(lp_type_name, lpt->name) == 0){
                    // increment the count if we are ignoring annotations,
                    // query and entry are both unannotated, or if the
                    // annotations match
                    if (ignore_annos || cmp_anno(annotation, lpt->anno)){
                        if (ignore_repetitions)
                            lp_type_ct_total += lpt->count;
                        else
                            lp_type_ct_total += lpt->count * lpg->repetitions;
137 138
                        if (ignore_annos == 1)
                            break;
139 140
                    }
                }
141
            }
142
            if (group_name != NULL) break; // we've processed the exact group
143 144
        }
    }
145 146
    // no error needed here - 0 is a valid value
    return lp_type_ct_total;
147 148
}

149 150 151 152 153 154 155 156 157 158 159 160 161 162
void codes_mapping_get_lp_id(
        const char * group_name,
        const char * lp_type_name,
        const char * annotation,
        int          ignore_anno,
        int          rep_id,
        int          offset,
        tw_lpid    * gid){
    // sanity checks
    if (rep_id < 0 || offset < 0 || group_name == NULL || lp_type_name == NULL)
        goto ERROR;
    *gid = 0;
    // for each group
    for (int g = 0; g < lpconf.lpgroups_count; g++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
163
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
164 165 166 167 168 169 170
        // in any case, count up the lps (need for repetition handling)
        tw_lpid rep_count = 0;
        for (int l = 0; l < lpg->lptypes_count; l++){
            rep_count += lpg->lptypes[l].count;
        }
        // does group name match?
        if (strcmp(lpg->name, group_name) == 0){
171
            tw_lpid local_lp_count = 0;
172 173
            // for each lp type
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
174
                const config_lptype_t *lpt = &lpg->lptypes[l];
175 176 177 178 179 180 181 182 183 184
                // does lp name match?
                if (strcmp(lpt->name, lp_type_name) == 0){
                    // does annotation match (or are we ignoring annotations?)
                    if (ignore_anno || cmp_anno(annotation, lpt->anno)){
                        // return if sane offset 
                        if (offset >= (int) lpt->count){
                            goto ERROR;
                        }
                        else{
                            *gid += (rep_count * (tw_lpid)rep_id) + 
185
                                local_lp_count + (tw_lpid)offset;
186 187 188 189
                            return;
                        }
                    }
                }
190
                local_lp_count += lpt->count;
191 192 193 194 195 196 197 198
            }
            // after a group match, short circuit to end if lp not found
            goto ERROR;
        }
        // group name doesn't match, add count to running total and move on
        else{
            *gid += lpg->repetitions * rep_count;
        }
199
    }
200 201 202 203 204
ERROR:
    // LP not found
    tw_error(TW_LOC, "Unable to find LP id given "
                     "group \"%s\", "
                     "typename \"%s\", "
205
                     "annotation \"%s\", "
206
                     "repetition %d, and offset %d",
207 208 209
                     group_name==NULL   ? "<NULL>" : group_name,
                     lp_type_name==NULL ? "<NULL>" : lp_type_name,
                     annotation==NULL   ? "<NULL>" : annotation,
210
                     rep_id, offset);
211 212
}

213 214 215 216 217 218 219
int codes_mapping_get_lp_relative_id(
        tw_lpid gid,
        int     group_wise,
        int     annotation_wise){
    int group_index, lp_type_index, rep_id, offset;
    codes_mapping_get_lp_info(gid, NULL, &group_index,
            local_lp_name, &lp_type_index, local_annotation, &rep_id, &offset);
Jonathan Jenkins's avatar
Jonathan Jenkins committed
220
    const char * anno = (local_annotation[0]=='\0') ? NULL : local_annotation;
221 222 223 224 225 226

    uint64_t group_lp_count = 0;
    // if not group_specific, then count up LPs of all preceding groups
    if (!group_wise){
        for (int g = 0; g < group_index; g++){
            uint64_t lp_count = 0;
Jonathan Jenkins's avatar
Jonathan Jenkins committed
227
            const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
228
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
229
                const config_lptype_t *lpt = &lpg->lptypes[l];
230 231 232 233 234 235 236
                if (strcmp(local_lp_name, lpt->name) == 0){
                    // increment the count if we are ignoring annotations,
                    // both LPs are unannotated, or if the annotations match
                    if (!annotation_wise || cmp_anno(anno, lpt->anno)){
                        lp_count += lpt->count;
                    }
                }
237
            }
238
            group_lp_count += lp_count * lpg->repetitions;
239 240
        }
    }
241 242 243 244 245 246
    // count up LPs within my group occuring before me 
    // (the loop is necessary because different annotated LPs may exist in the
    // same group)
    uint64_t lp_count = 0;
    uint64_t lp_pre_count = 0;
    for (int l = 0; l < lpconf.lpgroups[group_index].lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
247
        const config_lptype_t *lpt = &lpconf.lpgroups[group_index].lptypes[l];
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
        if (strcmp(local_lp_name, lpt->name) == 0){
            if (!annotation_wise || cmp_anno(anno, lpt->anno)){
                lp_count += lpt->count;
                // special case: if we find an LP entry that matches, but is not
                // the same entry where the input gid comes from, then increment
                // a separate "pre" counter
                if (l < lp_type_index){
                    lp_pre_count += lpt->count;
                }
            }
        }
    }
    // now we have the necessary counts
    // return lps in groups that came before + 
    // lps within the group that came before the target LP
    return (int) (group_lp_count + (lp_count * rep_id) + lp_pre_count + offset);
264 265
}

266 267 268 269 270 271 272 273 274 275 276 277
tw_lpid codes_mapping_get_lpid_from_relative(
        int          relative_id,
        const char * group_name,
        const char * lp_type_name,
        const char * annotation,
        int          annotation_wise){
    // strategy: count up all preceding LPs. When we reach a point where an LP
    // type matches, count up the relative ID. When the accumulated relative ID
    // matches or surpasses the input, then we've found our LP
    int rel_id_count = 0;
    tw_lpid gid_count = 0;
    for (int g = 0; g < lpconf.lpgroups_count; g++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
278
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
279 280 281 282 283
        if (group_name == NULL || strcmp(group_name, lpg->name) == 0){
            // consider this group for counting
            tw_lpid local_gid_count = 0;
            int local_rel_id_count = 0;
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
284
                const config_lptype_t *lpt = &lpg->lptypes[l];
285 286 287 288 289 290
                local_gid_count += lpt->count;
                if (strcmp(lp_type_name, lpt->name) == 0 &&
                        (!annotation_wise || cmp_anno(annotation, lpt->anno))){
                    local_rel_id_count += lpt->count;
                }
            }
291 292
            // is our relative id within this group?
            if (relative_id < rel_id_count +
293 294 295 296 297 298 299 300
                    lpg->repetitions * local_rel_id_count){
                tw_lpid gid = gid_count;
                int rem = relative_id - rel_id_count;
                int rep = rem / local_rel_id_count;
                rem -= (rep * local_rel_id_count);
                gid += local_gid_count * rep;
                // count up lps listed prior to this entry
                for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
301
                    const config_lptype_t *lpt = &lpg->lptypes[l];
302
                    if (    strcmp(lp_type_name, lpt->name) == 0 &&
303
                            (!annotation_wise ||
304 305 306 307 308
                            cmp_anno(annotation, lpt->anno))){
                        if (rem < (int) lpt->count){
                            return gid + (tw_lpid) rem;
                        }
                        else{
309
                            rem -= lpt->count;
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
                        }
                    }
                    gid += lpt->count;
                }
                // this shouldn't happen
                goto NOT_FOUND;
            }
            else if (group_name != NULL){
                // immediate error - found the group, but not the id
                goto NOT_FOUND;
            }
            else{
                // increment and move to the next group
                rel_id_count += local_rel_id_count * lpg->repetitions;
                gid_count    += local_gid_count    * lpg->repetitions;
            }
        }
        else{
            // just count up the group LPs
            tw_lpid local_gid_count = 0;
            for (int l = 0; l < lpg->lptypes_count; l++){
                local_gid_count += lpg->lptypes[l].count;
            }
333
            gid_count += local_gid_count * lpg->repetitions;
334 335 336 337 338 339 340 341 342 343 344 345
        }
    }
NOT_FOUND:
    tw_error(TW_LOC, "Unable to find LP-ID for ID %d relative to group %s, "
            "lp name %s, annotation %s",
            relative_id,
            group_name == NULL ? "(all)" : group_name,
            lp_type_name,
            annotation_wise ? annotation : "(all)");
    return 0; // dummy return
}

346 347 348 349 350 351 352 353 354 355 356 357 358
void codes_mapping_get_lp_info(
        tw_lpid gid,
        char  * group_name,
        int   * group_index,
        char  * lp_type_name,
        int   * lp_type_index,
        char  * annotation,
        int   * rep_id,
        int   * offset){
    // running total of lp's we've seen so far
    tw_lpid id_total = 0;
    // for each group
    for (int g = 0; g < lpconf.lpgroups_count; g++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
359
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
        tw_lpid num_id_group, num_id_per_rep = 0;
        // count up the number of ids in this group
        for (int l = 0; l < lpg->lptypes_count; l++){
            num_id_per_rep += lpg->lptypes[l].count;
        }
        num_id_group = num_id_per_rep * lpg->repetitions;
        if (num_id_group+id_total > gid){
            // we've found the group
            tw_lpid rem = gid - id_total;
            if (group_name != NULL)
                strncpy(group_name, lpg->name, MAX_NAME_LENGTH);
            *group_index = g;
            // find repetition within group
            *rep_id = (int) (rem / num_id_per_rep);
            rem -=  num_id_per_rep * (tw_lpid)*rep_id;
            num_id_per_rep = 0;
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
377
                const config_lptype_t *lpt = &lpg->lptypes[l];
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
                if (rem < num_id_per_rep + lpt->count){
                    // found the specific LP
                    if (lp_type_name != NULL)
                        strncpy(lp_type_name, lpt->name, MAX_NAME_LENGTH);
                    if (annotation != NULL)
                        strncpy(annotation, lpt->anno, MAX_NAME_LENGTH);
                    *offset = (int) (rem - num_id_per_rep);
                    *lp_type_index = l;
                    return; // done
                }
                else{
                    num_id_per_rep += lpg->lptypes[l].count;
                }
            }
        }
        else{
            id_total += num_id_group;
        }
396
    }
397 398
    // LP not found
    tw_error(TW_LOC, "Unable to find LP info given gid %lu", gid);
399 400 401
}

/* This function assigns local and global LP Ids to LPs */
402
static void codes_mapping_init(void)
403 404 405 406 407
{
     int grp_id, lpt_id, rep_id, offset;
     tw_lpid ross_gid, ross_lid; /* ross global and local IDs */
     tw_pe * pe;
     char lp_type_name[MAX_NAME_LENGTH];
408
     int nkp_per_pe = g_tw_nkp;
409
     tw_lpid         lpid, kpid;
410
     const tw_lptype *lptype;
411 412 413 414 415

     /* have 16 kps per pe, this is the optimized configuration for ROSS custom mapping */
     for(kpid = 0; kpid < nkp_per_pe; kpid++)
	tw_kp_onpe(kpid, g_tw_pe[0]);

416 417 418 419
     int lp_start =
         g_tw_mynode * lps_per_pe_floor + mini(g_tw_mynode,lps_leftover);
     int lp_end =
         (g_tw_mynode+1) * lps_per_pe_floor + mini(g_tw_mynode+1,lps_leftover);
420

421
     for (lpid = lp_start; lpid < lp_end; lpid++)
422 423
      {
	 ross_gid = lpid;
424
	 ross_lid = lpid - lp_start;
425 426
	 kpid = ross_lid % g_tw_nkp;
	 pe = tw_getpe(kpid % g_tw_npe);
427 428
	 codes_mapping_get_lp_info(ross_gid, NULL, &grp_id, lp_type_name,
                 &lpt_id, NULL, &rep_id, &offset);
429 430 431
#if CODES_MAPPING_DEBUG
         printf("lp:%lu --> kp:%lu, pe:%llu\n", ross_gid, kpid, pe->id);
#endif
432
	 tw_lp_onpe(ross_lid, pe, ross_gid);
433
	 tw_lp_onkp(g_tw_lp[ross_lid], g_tw_kp[kpid]);
434 435 436 437 438
         lptype = lp_type_lookup(lp_type_name);
         if (lptype == NULL)
             tw_error(TW_LOC, "could not find LP with type name \"%s\", "
                     "did you forget to register the LP?\n", lp_type_name);
         else
439 440
             /* sorry, const... */
             tw_lp_settype(ross_lid, (tw_lptype*) lptype);
441 442 443 444 445 446 447
     }
     return;
}

/* This function takes the global LP ID, maps it to the local LP ID and returns the LP 
 * lps have global and local LP IDs
 * global LP IDs are unique across all PEs, local LP IDs are unique within a PE */
448
static tw_lp * codes_mapping_to_lp( tw_lpid lpid)
449
{
450 451
   int index = lpid - (g_tw_mynode * lps_per_pe_floor) -
       mini(g_tw_mynode, lps_leftover);
452 453 454 455
//   printf("\n global id %d index %d lps_before %d lps_offset %d local index %d ", lpid, index, lps_before, g_tw_mynode, local_index);
   return g_tw_lp[index];
}

456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
/* helper for setting up the canonical name mapping */
static void check_add_uniq_str(
        char const *** str_array_ref,
        int * num_strs,
        int * cap, // buffer capacity for resizing
        char const * str)
{
    int slen = strlen(str);

    for (int i = 0; i < *num_strs; i++) {
        char const * b = (*str_array_ref)[i];
        int blen = strlen(b);
        if (slen == blen && memcmp(b, str, blen) == 0)
            return;
    }

    if (*num_strs == *cap) {
        *cap *= 2;
        *str_array_ref =
            realloc(*str_array_ref, *cap * sizeof(**str_array_ref));
        assert(*str_array_ref);
    }

    (*str_array_ref)[*num_strs] = str;
    *num_strs += 1;
}

static void setup_canonical_name_mapping()
{
    num_uniq_groups = 0;
    num_uniq_lptypes = 0;
    num_uniq_annos = 0;
    int group_cap = 8;
    int lptype_cap = 8;
    int anno_cap = 8;
    group_names = malloc(group_cap*sizeof(*group_names));
    lp_names = malloc(lptype_cap*sizeof(*lp_names));
    anno_names = malloc(anno_cap*sizeof(*anno_names));

    for (int g = 0; g < lpconf.lpgroups_count; g++) {
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
        check_add_uniq_str(&group_names, &num_uniq_groups, &group_cap,
                lpg->name);
        for (int l = 0; l < lpg->lptypes_count; l++) {
            const config_lptype_t *lpt = &lpg->lptypes[l];
            check_add_uniq_str(&lp_names, &num_uniq_lptypes, &lptype_cap,
                    lpt->name);
            // have to treat empty annotations specially
            if (lpt->anno[0] != '\0')
                check_add_uniq_str(&anno_names, &num_uniq_annos, &anno_cap,
                        lpt->anno);
        }
    }

    assert(num_uniq_groups);
    assert(num_uniq_lptypes);
    if (num_uniq_annos == 0) {
        free(anno_names);
        anno_names = NULL;
    }
}

518
/* This function loads the configuration file and sets up the number of LPs on each PE */
519
void codes_mapping_setup_with_seed_offset(int offset)
520 521 522 523
{
  int grp, lpt, message_size;
  int pes = tw_nnodes();

524 525
  setup_canonical_name_mapping();

526
  lps_per_pe_floor = 0;
527 528 529
  for (grp = 0; grp < lpconf.lpgroups_count; grp++)
   {
    for (lpt = 0; lpt < lpconf.lpgroups[grp].lptypes_count; lpt++)
530
	lps_per_pe_floor += (lpconf.lpgroups[grp].lptypes[lpt].count * lpconf.lpgroups[grp].repetitions);
531
   }
532
  tw_lpid global_nlps = lps_per_pe_floor;
533 534 535
  lps_leftover = lps_per_pe_floor % pes;
  lps_per_pe_floor /= pes;
 //printf("\n LPs for this PE are %d reps %d ", lps_per_pe_floor,  lpconf.lpgroups[grp].repetitions);
536 537 538
  g_tw_mapping=CUSTOM;
  g_tw_custom_initial_mapping=&codes_mapping_init;
  g_tw_custom_lp_global_to_local_map=&codes_mapping_to_lp;
Jonathan Jenkins's avatar
Jonathan Jenkins committed
539 540 541 542 543 544 545 546

  // configure mem-factor
  int mem_factor_conf;
  int rc = configuration_get_value_int(&config, "PARAMS", "pe_mem_factor", NULL,
          &mem_factor_conf);
  if (rc == 0 && mem_factor_conf > 0)
    mem_factor = mem_factor_conf;

547
  g_tw_events_per_pe = mem_factor * codes_mapping_get_lps_for_pe();
548
  configuration_get_value_int(&config, "PARAMS", "message_size", NULL, &message_size);
549 550 551 552 553
  if(!message_size)
  {
      message_size = 256;
      printf("\n Warning: ross message size not defined, resetting it to %d", message_size);
  }
554 555 556 557 558

  // we increment the number of RNGs used to let codes_local_latency use the
  // last one
  g_tw_nRNG_per_lp++;

559
  tw_define_lps(codes_mapping_get_lps_for_pe(), message_size, 0);
560 561 562 563 564 565 566 567 568 569

  // use a similar computation to codes_mapping_init to compute the lpids and
  // offsets to use in tw_rand_initial_seed
  // an "offset" of 0 reverts to default RNG seeding behavior - see
  // ross/rand-clcg4.c for the specific computation
  // an "offset" < 0 is ignored
  if (offset > 0){
      for (tw_lpid l = 0; l < g_tw_nlp; l++){
          for (int i = 0; i < g_tw_nRNG_per_lp; i++){
              tw_rand_initial_seed(&g_tw_lp[l]->rng[i], (g_tw_lp[l]->gid +
570
                          global_nlps * offset) * g_tw_nRNG_per_lp + i);
571 572 573 574 575 576 577
          }
      }
  }
}

void codes_mapping_setup(){
    codes_mapping_setup_with_seed_offset(0);
578 579
}

580
/* given the group and LP type name, return the annotation (or NULL) */
581 582 583 584
const char* codes_mapping_get_annotation_by_name(
        const char * group_name,
        const char * lp_type_name){
    for (int g = 0; g < lpconf.lpgroups_count; g++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
585
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
586 587 588
        if (strcmp(lpg->name, group_name) == 0){
            // group found, iterate through types
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
589
                const config_lptype_t *lpt = &lpg->lptypes[l];
590 591 592 593 594 595 596 597
                if (strcmp(lpt->name, lp_type_name) == 0){
                    // type found, return the annotation
                    if (lpt->anno[0] == '\0')
                        return NULL;
                    else
                        return lpt->anno;
                }
            }
598 599
        }
    }
600 601 602
    tw_error(TW_LOC, "unable to find annotation using "
            "group \"%s\" and lp_type_name \"%s\"", group_name, lp_type_name);
    return NULL;
603 604 605
}

const char* codes_mapping_get_annotation_by_lpid(tw_lpid gid){
606 607 608 609 610 611 612 613 614
    int group_index, lp_type_index, dummy;
    codes_mapping_get_lp_info(gid, NULL, &group_index, NULL, &lp_type_index,
            NULL, &dummy, &dummy);
    const char * anno = 
        lpconf.lpgroups[group_index].lptypes[lp_type_index].anno;
    if (anno[0] == '\0')
        return NULL;
    else
        return anno;
615
}
Philip Carns's avatar
Philip Carns committed
616

617 618 619
/*
 * Returns a mapping of LP name to all annotations used with the type
 *
620
 * lp_name - lp name as used in the configuration
621 622 623 624 625 626 627 628 629 630 631
 */
const config_anno_map_t * 
codes_mapping_get_lp_anno_map(const char *lp_name){
    for (uint64_t i = 0; i < lpconf.lpannos_count; i++){
        if (strcmp(lp_name, lpconf.lpannos[i].lp_name) == 0){
            return &lpconf.lpannos[i];
        }
    }
    return NULL;
}

632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
static int get_cid_by_name(
        char const * name,
        char const * * names,
        int num_names)
{
    for (int i = 0; i < num_names; i++)
        if (strcmp(name, names[i]) == 0)
            return i;
    return -1;
}

static char const * get_name_by_cid(
        int cid,
        char const * * names,
        int num_names)
{
    if (cid < 0 || cid >= num_names)
        return NULL;
    else
        return names[cid];
}


int codes_mapping_get_group_cid_by_name(char const * group_name)
{
    return get_cid_by_name(group_name, group_names, num_uniq_groups);
}

int codes_mapping_get_group_cid_by_lpid(tw_lpid id)
{
    char group_name[MAX_NAME_LENGTH];
    int ignore;
    codes_mapping_get_lp_info(id, group_name, &ignore, NULL, &ignore, NULL,
            &ignore, &ignore);
    return codes_mapping_get_group_cid_by_name(group_name);
}

char const * codes_mapping_get_group_name_by_cid(int cid)
{
    return get_name_by_cid(cid, group_names, num_uniq_groups);
}

int codes_mapping_get_lp_cid_by_name(char const * lp_type_name)
{
    return get_cid_by_name(lp_type_name, lp_names, num_uniq_lptypes);
}

int codes_mapping_get_lp_cid_by_lpid(tw_lpid id)
{
    char lp_name[MAX_NAME_LENGTH];
    int ignore;
    codes_mapping_get_lp_info(id, NULL, &ignore, lp_name, &ignore, NULL,
            &ignore, &ignore);
    return codes_mapping_get_lp_cid_by_name(lp_name);
}

char const * codes_mapping_get_lp_name_by_cid(int cid)
{
    return get_name_by_cid(cid, lp_names, num_uniq_lptypes);
}

int codes_mapping_get_anno_cid_by_name(char const * annotation)
{
    if (annotation == NULL || annotation[0] == '\0')
        return num_uniq_annos;
    else
        return get_cid_by_name(annotation, anno_names, num_uniq_annos);
}

int codes_mapping_get_anno_cid_by_lpid(tw_lpid id)
{
    char anno[MAX_NAME_LENGTH];
    int ignore;
    codes_mapping_get_lp_info(id, NULL, &ignore, NULL, &ignore, anno,
            &ignore, &ignore);
    return codes_mapping_get_anno_cid_by_name(anno);
}

char const * codes_mapping_get_anno_name_by_cid(int cid)
{
    return get_name_by_cid(cid, anno_names, num_uniq_annos);
}

Philip Carns's avatar
Philip Carns committed
715 716 717 718 719 720 721 722
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */