codes_mapping.c 24.9 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
/* 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 */
Jonathan Jenkins's avatar
Jonathan Jenkins committed
17 18
static tw_lpid lps_per_pe_floor = 0;
static tw_lpid lps_leftover = 0;
19

20
static int mem_factor = 256;
21

22 23 24 25 26
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){
27 28 29
    return anno_user == NULL ? anno_config == NULL
                             : (anno_config != NULL
                                     && !strcmp(anno_user, anno_config));
30 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
}


#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
61

62
/* char arrays for holding lp type name and group name*/
63 64 65
// (unused var atm) static char local_group_name[MAX_NAME_LENGTH];
static char local_lp_name[MAX_NAME_LENGTH],
            local_annotation[MAX_NAME_LENGTH];
66

67 68
int codes_mapping_get_lps_for_pe()
{
69 70 71 72 73
    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
Jonathan Jenkins's avatar
Jonathan Jenkins committed
74
  return lps_per_pe_floor + ((tw_lpid)g_tw_mynode < lps_leftover);
75 76 77 78 79
}

/* Takes the global LP ID and returns the rank (PE id) on which the LP is mapped */
tw_peid codes_mapping( tw_lpid gid)
{
Jonathan Jenkins's avatar
Jonathan Jenkins committed
80
    tw_lpid lps_on_pes_with_leftover = lps_leftover * (lps_per_pe_floor+1);
81 82 83 84 85 86 87
    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;*/
88 89
}

90
int codes_mapping_get_group_reps(const char* group_name)
91
{
92 93 94
  int grp;
  for(grp = 0; grp < lpconf.lpgroups_count; grp++)
  {
95
     if(strcmp(lpconf.lpgroups[grp].name.ptr, group_name) == 0)
96 97 98 99
	     return lpconf.lpgroups[grp].repetitions;
  }
  return -1;
}
100

101 102 103 104 105 106 107 108 109 110
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)
111
    if (group_name == NULL)
112 113
        ignore_repetitions = 0;
    for (int g = 0; g < lpconf.lpgroups_count; g++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
114
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
115 116
        // iterate over the lps if the group is null (count across all groups)
        // or if the group names match
117
        if (group_name == NULL || strcmp(lpg->name.ptr, group_name) == 0){
118
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
119
                const config_lptype_t *lpt = &lpg->lptypes[l];
120
                if (strcmp(lp_type_name, lpt->name.ptr) == 0){
121 122 123
                    // increment the count if we are ignoring annotations,
                    // query and entry are both unannotated, or if the
                    // annotations match
124
                    if (ignore_annos || cmp_anno(annotation, lpt->anno.ptr)){
125 126 127 128
                        if (ignore_repetitions)
                            lp_type_ct_total += lpt->count;
                        else
                            lp_type_ct_total += lpt->count * lpg->repetitions;
129 130
                        if (ignore_annos == 1)
                            break;
131 132
                    }
                }
133
            }
134
            if (group_name != NULL) break; // we've processed the exact group
135 136
        }
    }
137 138
    // no error needed here - 0 is a valid value
    return lp_type_ct_total;
139 140
}

141 142 143 144 145 146 147 148 149 150 151 152 153 154
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
155
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
156 157 158 159 160 161
        // 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?
162
        if (strcmp(lpg->name.ptr, group_name) == 0){
163
            tw_lpid local_lp_count = 0;
164 165
            // for each lp type
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
166
                const config_lptype_t *lpt = &lpg->lptypes[l];
167
                // does lp name match?
168
                if (strcmp(lpt->name.ptr, lp_type_name) == 0){
169
                    // does annotation match (or are we ignoring annotations?)
170
                    if (ignore_anno || cmp_anno(annotation, lpt->anno.ptr)){
171 172 173 174 175 176
                        // return if sane offset 
                        if (offset >= (int) lpt->count){
                            goto ERROR;
                        }
                        else{
                            *gid += (rep_count * (tw_lpid)rep_id) + 
177
                                local_lp_count + (tw_lpid)offset;
178 179 180 181
                            return;
                        }
                    }
                }
182
                local_lp_count += lpt->count;
183 184 185 186 187 188 189 190
            }
            // 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;
        }
191
    }
192 193 194 195 196
ERROR:
    // LP not found
    tw_error(TW_LOC, "Unable to find LP id given "
                     "group \"%s\", "
                     "typename \"%s\", "
197
                     "annotation \"%s\", "
198
                     "repetition %d, and offset %d",
199 200 201
                     group_name==NULL   ? "<NULL>" : group_name,
                     lp_type_name==NULL ? "<NULL>" : lp_type_name,
                     annotation==NULL   ? "<NULL>" : annotation,
202
                     rep_id, offset);
203 204
}

205 206 207 208 209 210 211
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
212
    const char * anno = (local_annotation[0]=='\0') ? NULL : local_annotation;
213

214
    int group_lp_count = 0;
215 216 217
    // if not group_specific, then count up LPs of all preceding groups
    if (!group_wise){
        for (int g = 0; g < group_index; g++){
218
            int lp_count = 0;
Jonathan Jenkins's avatar
Jonathan Jenkins committed
219
            const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
220
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
221
                const config_lptype_t *lpt = &lpg->lptypes[l];
222
                if (strcmp(local_lp_name, lpt->name.ptr) == 0){
223 224
                    // increment the count if we are ignoring annotations,
                    // both LPs are unannotated, or if the annotations match
225
                    if (!annotation_wise || cmp_anno(anno, lpt->anno.ptr)){
226 227 228
                        lp_count += lpt->count;
                    }
                }
229
            }
230
            group_lp_count += lp_count * lpg->repetitions;
231 232
        }
    }
233 234 235
    // count up LPs within my group occuring before me 
    // (the loop is necessary because different annotated LPs may exist in the
    // same group)
236 237
    int lp_count = 0;
    int lp_pre_count = 0;
238
    for (int l = 0; l < lpconf.lpgroups[group_index].lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
239
        const config_lptype_t *lpt = &lpconf.lpgroups[group_index].lptypes[l];
240 241
        if (strcmp(local_lp_name, lpt->name.ptr) == 0){
            if (!annotation_wise || cmp_anno(anno, lpt->anno.ptr)){
242 243 244 245 246 247 248 249 250 251 252 253 254 255
                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);
256 257
}

258 259 260 261 262 263 264 265 266 267 268 269
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
270
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
271
        if (group_name == NULL || strcmp(group_name, lpg->name.ptr) == 0){
272 273 274 275
            // 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
276
                const config_lptype_t *lpt = &lpg->lptypes[l];
277
                local_gid_count += lpt->count;
278 279
                if (strcmp(lp_type_name, lpt->name.ptr) == 0 &&
                        (!annotation_wise || cmp_anno(annotation, lpt->anno.ptr))){
280 281 282
                    local_rel_id_count += lpt->count;
                }
            }
283 284
            // is our relative id within this group?
            if (relative_id < rel_id_count +
285 286 287 288 289 290 291 292
                    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
293
                    const config_lptype_t *lpt = &lpg->lptypes[l];
294
                    if (    strcmp(lp_type_name, lpt->name.ptr) == 0 &&
295
                            (!annotation_wise ||
296
                            cmp_anno(annotation, lpt->anno.ptr))){
297 298 299 300
                        if (rem < (int) lpt->count){
                            return gid + (tw_lpid) rem;
                        }
                        else{
301
                            rem -= lpt->count;
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
                        }
                    }
                    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;
            }
325
            gid_count += local_gid_count * lpg->repetitions;
326 327 328 329 330 331 332 333 334 335 336 337
        }
    }
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
}

338 339 340 341 342 343 344 345 346 347 348 349 350
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
351
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
352 353 354 355 356 357 358 359 360 361
        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)
362
                strcpy(group_name, lpg->name.ptr);
363 364 365 366 367 368
            *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
369
                const config_lptype_t *lpt = &lpg->lptypes[l];
370 371 372
                if (rem < num_id_per_rep + lpt->count){
                    // found the specific LP
                    if (lp_type_name != NULL)
373
                        strcpy(lp_type_name, lpt->name.ptr);
374 375 376 377
                    if (annotation != NULL) {
                        if (lpt->anno.ptr == NULL)
                            annotation[0] = '\0';
                        else
378
                            strcpy(annotation, lpt->anno.ptr);
379
                    }
380 381 382 383 384 385 386 387 388 389 390 391
                    *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;
        }
392
    }
393 394
    // LP not found
    tw_error(TW_LOC, "Unable to find LP info given gid %lu", gid);
395 396
}

397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
void codes_mapping_get_lp_info2(
        tw_lpid gid,
        char const * * group_name,
        char const * * lp_type_name,
        char const * * 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++){
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
        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)
                *group_name = lpg->name.ptr;
            // 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++){
                const config_lptype_t *lpt = &lpg->lptypes[l];
                if (rem < num_id_per_rep + lpt->count){
                    // found the specific LP
                    if (lp_type_name != NULL)
                        *lp_type_name = lpt->name.ptr;
                    if (annotation != NULL)
                        *annotation = lpt->anno.ptr;
                    *offset = (int) (rem - num_id_per_rep);
                    return; // done
                }
                else{
                    num_id_per_rep += lpg->lptypes[l].count;
                }
            }
        }
        else{
            id_total += num_id_group;
        }
    }
    // LP not found
    tw_error(TW_LOC, "Unable to find LP info given gid %lu", gid);
}

449
/* This function assigns local and global LP Ids to LPs */
450
static void codes_mapping_init(void)
451 452 453 454 455
{
     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];
Jonathan Jenkins's avatar
Jonathan Jenkins committed
456
     tw_lpid nkp_per_pe = g_tw_nkp;
457
     tw_lpid         lpid, kpid;
458
     const tw_lptype *lptype;
459 460 461 462 463

     /* 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]);

Jonathan Jenkins's avatar
Jonathan Jenkins committed
464
     tw_lpid lp_start =
465
         g_tw_mynode * lps_per_pe_floor + mini(g_tw_mynode,lps_leftover);
Jonathan Jenkins's avatar
Jonathan Jenkins committed
466
     tw_lpid lp_end =
467
         (g_tw_mynode+1) * lps_per_pe_floor + mini(g_tw_mynode+1,lps_leftover);
468

469
     for (lpid = lp_start; lpid < lp_end; lpid++)
470 471
      {
	 ross_gid = lpid;
472
	 ross_lid = lpid - lp_start;
473 474
	 kpid = ross_lid % g_tw_nkp;
	 pe = tw_getpe(kpid % g_tw_npe);
475 476
	 codes_mapping_get_lp_info(ross_gid, NULL, &grp_id, lp_type_name,
                 &lpt_id, NULL, &rep_id, &offset);
477 478 479
#if CODES_MAPPING_DEBUG
         printf("lp:%lu --> kp:%lu, pe:%llu\n", ross_gid, kpid, pe->id);
#endif
480
	 tw_lp_onpe(ross_lid, pe, ross_gid);
481
	 tw_lp_onkp(g_tw_lp[ross_lid], g_tw_kp[kpid]);
482 483 484 485 486
         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
487 488
             /* sorry, const... */
             tw_lp_settype(ross_lid, (tw_lptype*) lptype);
489 490 491 492 493 494 495
     }
     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 */
496
static tw_lp * codes_mapping_to_lp( tw_lpid lpid)
497
{
498 499
   int index = lpid - (g_tw_mynode * lps_per_pe_floor) -
       mini(g_tw_mynode, lps_leftover);
500 501 502 503
//   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];
}

504
/* This function loads the configuration file and sets up the number of LPs on each PE */
505
void codes_mapping_setup_with_seed_offset(int offset)
506 507 508 509
{
  int grp, lpt, message_size;
  int pes = tw_nnodes();

510
  lps_per_pe_floor = 0;
511 512 513
  for (grp = 0; grp < lpconf.lpgroups_count; grp++)
   {
    for (lpt = 0; lpt < lpconf.lpgroups[grp].lptypes_count; lpt++)
514
	lps_per_pe_floor += (lpconf.lpgroups[grp].lptypes[lpt].count * lpconf.lpgroups[grp].repetitions);
515
   }
516
  tw_lpid global_nlps = lps_per_pe_floor;
517 518 519
  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);
520 521 522
  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
523 524 525 526 527 528 529 530

  // 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;

531
  g_tw_events_per_pe = mem_factor * codes_mapping_get_lps_for_pe();
532
  configuration_get_value_int(&config, "PARAMS", "message_size", NULL, &message_size);
533 534 535 536 537
  if(!message_size)
  {
      message_size = 256;
      printf("\n Warning: ross message size not defined, resetting it to %d", message_size);
  }
538 539 540 541 542

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

543
  tw_define_lps(codes_mapping_get_lps_for_pe(), message_size);
544 545 546 547 548 549 550 551

  // 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++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
552
          for (unsigned int i = 0; i < g_tw_nRNG_per_lp; i++){
553
              tw_rand_initial_seed(&g_tw_lp[l]->rng[i], (g_tw_lp[l]->gid +
554
                          global_nlps * offset) * g_tw_nRNG_per_lp + i);
555 556 557 558 559 560 561
          }
      }
  }
}

void codes_mapping_setup(){
    codes_mapping_setup_with_seed_offset(0);
562 563
}

564
/* given the group and LP type name, return the annotation (or NULL) */
565 566 567 568
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
569
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
570
        if (strcmp(lpg->name.ptr, group_name) == 0){
571 572
            // group found, iterate through types
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
573
                const config_lptype_t *lpt = &lpg->lptypes[l];
574
                if (strcmp(lpt->name.ptr, lp_type_name) == 0){
575
                    // type found, return the annotation
576
                    return lpt->anno.ptr;
577 578
                }
            }
579 580
        }
    }
581 582 583
    tw_error(TW_LOC, "unable to find annotation using "
            "group \"%s\" and lp_type_name \"%s\"", group_name, lp_type_name);
    return NULL;
584 585 586
}

const char* codes_mapping_get_annotation_by_lpid(tw_lpid gid){
587 588 589
    int group_index, lp_type_index, dummy;
    codes_mapping_get_lp_info(gid, NULL, &group_index, NULL, &lp_type_index,
            NULL, &dummy, &dummy);
590
    return lpconf.lpgroups[group_index].lptypes[lp_type_index].anno.ptr;
591
}
Philip Carns's avatar
Philip Carns committed
592

593 594 595
/*
 * Returns a mapping of LP name to all annotations used with the type
 *
596
 * lp_name - lp name as used in the configuration
597 598 599
 */
const config_anno_map_t * 
codes_mapping_get_lp_anno_map(const char *lp_name){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
600
    for (int i = 0; i < lpconf.lpannos_count; i++){
601
        if (strcmp(lp_name, lpconf.lpannos[i].lp_name.ptr) == 0){
602 603 604 605 606 607
            return &lpconf.lpannos[i];
        }
    }
    return NULL;
}

608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
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)
{
633 634
    return get_cid_by_name(group_name, lpconf.group_names,
            lpconf.lpgroups_count);
635 636 637 638 639 640 641 642 643 644 645 646 647
}

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)
{
648
    return get_name_by_cid(cid, lpconf.group_names, lpconf.lpgroups_count);
649 650 651 652
}

int codes_mapping_get_lp_cid_by_name(char const * lp_type_name)
{
653 654
    return get_cid_by_name(lp_type_name, lpconf.lp_names,
            lpconf.num_uniq_lptypes);
655 656 657 658 659 660 661 662 663 664 665 666 667
}

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)
{
668
    return get_name_by_cid(cid, lpconf.lp_names, lpconf.num_uniq_lptypes);
669 670 671 672 673
}

int codes_mapping_get_anno_cid_by_name(char const * annotation)
{
    if (annotation == NULL || annotation[0] == '\0')
674
        return lpconf.num_uniq_annos;
675
    else
676 677
        return get_cid_by_name(annotation, lpconf.anno_names,
                lpconf.num_uniq_annos);
678 679 680 681 682 683 684 685 686 687 688 689 690
}

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)
{
691
    return get_name_by_cid(cid, lpconf.anno_names, lpconf.num_uniq_annos);
692 693
}

Philip Carns's avatar
Philip Carns committed
694 695 696 697 698 699 700 701
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */