codes_mapping.c 25.2 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
    int rank;
70
    MPI_Comm_rank(MPI_COMM_CODES, &rank);
71 72 73
#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 164
            // sanity check rep_id
            if (rep_id >= lpg->repetitions) goto ERROR;
165
            tw_lpid local_lp_count = 0;
166 167
            // for each lp type
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
168
                const config_lptype_t *lpt = &lpg->lptypes[l];
169
                // does lp name match?
170
                if (strcmp(lpt->name.ptr, lp_type_name) == 0){
171
                    // does annotation match (or are we ignoring annotations?)
172
                    if (ignore_anno || cmp_anno(annotation, lpt->anno.ptr)){
173 174 175 176 177 178
                        // return if sane offset 
                        if (offset >= (int) lpt->count){
                            goto ERROR;
                        }
                        else{
                            *gid += (rep_count * (tw_lpid)rep_id) + 
179
                                local_lp_count + (tw_lpid)offset;
180 181 182 183
                            return;
                        }
                    }
                }
184
                local_lp_count += lpt->count;
185 186 187 188 189 190 191 192
            }
            // 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;
        }
193
    }
194 195 196 197 198
ERROR:
    // LP not found
    tw_error(TW_LOC, "Unable to find LP id given "
                     "group \"%s\", "
                     "typename \"%s\", "
199
                     "annotation \"%s\", "
200
                     "repetition %d, and offset %d",
201 202 203
                     group_name==NULL   ? "<NULL>" : group_name,
                     lp_type_name==NULL ? "<NULL>" : lp_type_name,
                     annotation==NULL   ? "<NULL>" : annotation,
204
                     rep_id, offset);
205 206
}

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

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

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

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

451
/* This function assigns local and global LP Ids to LPs */
452
static void codes_mapping_init(void)
453 454 455 456 457
{
     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
458
     tw_lpid nkp_per_pe = g_tw_nkp;
459
     tw_lpid         lpid, kpid;
460
     const tw_lptype *lptype;
461
     const st_trace_type *trace_type;
462 463 464 465 466

     /* 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
467
     tw_lpid lp_start =
468
         g_tw_mynode * lps_per_pe_floor + mini(g_tw_mynode,lps_leftover);
Jonathan Jenkins's avatar
Jonathan Jenkins committed
469
     tw_lpid lp_end =
470
         (g_tw_mynode+1) * lps_per_pe_floor + mini(g_tw_mynode+1,lps_leftover);
471

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

512
/* This function loads the configuration file and sets up the number of LPs on each PE */
513
void codes_mapping_setup_with_seed_offset(int offset)
514 515 516 517
{
  int grp, lpt, message_size;
  int pes = tw_nnodes();

518
  lps_per_pe_floor = 0;
519 520 521
  for (grp = 0; grp < lpconf.lpgroups_count; grp++)
   {
    for (lpt = 0; lpt < lpconf.lpgroups[grp].lptypes_count; lpt++)
522
	lps_per_pe_floor += (lpconf.lpgroups[grp].lptypes[lpt].count * lpconf.lpgroups[grp].repetitions);
523
   }
524
  tw_lpid global_nlps = lps_per_pe_floor;
525 526 527
  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);
528 529 530
  g_tw_mapping=CUSTOM;
  g_tw_custom_initial_mapping=&codes_mapping_init;
  g_tw_custom_lp_global_to_local_map=&codes_mapping_to_lp;
531 532 533 534 535 536 537 538

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

539
  g_tw_events_per_pe = mem_factor * codes_mapping_get_lps_for_pe();
540
  configuration_get_value_int(&config, "PARAMS", "message_size", NULL, &message_size);
541 542 543 544 545
  if(!message_size)
  {
      message_size = 256;
      printf("\n Warning: ross message size not defined, resetting it to %d", message_size);
  }
546 547 548 549 550

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

551
  tw_define_lps(codes_mapping_get_lps_for_pe(), message_size);
552 553 554 555 556 557 558 559

  // 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
560
          for (unsigned int i = 0; i < g_tw_nRNG_per_lp; i++){
561
              tw_rand_initial_seed(&g_tw_lp[l]->rng[i], (g_tw_lp[l]->gid +
562
                          global_nlps * offset) * g_tw_nRNG_per_lp + i);
563 564 565 566 567 568 569
          }
      }
  }
}

void codes_mapping_setup(){
    codes_mapping_setup_with_seed_offset(0);
570 571
}

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

const char* codes_mapping_get_annotation_by_lpid(tw_lpid gid){
595 596 597
    int group_index, lp_type_index, dummy;
    codes_mapping_get_lp_info(gid, NULL, &group_index, NULL, &lp_type_index,
            NULL, &dummy, &dummy);
598
    return lpconf.lpgroups[group_index].lptypes[lp_type_index].anno.ptr;
599
}
Philip Carns's avatar
Philip Carns committed
600

601 602 603
/*
 * Returns a mapping of LP name to all annotations used with the type
 *
604
 * lp_name - lp name as used in the configuration
605 606 607
 */
const config_anno_map_t * 
codes_mapping_get_lp_anno_map(const char *lp_name){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
608
    for (int i = 0; i < lpconf.lpannos_count; i++){
609
        if (strcmp(lp_name, lpconf.lpannos[i].lp_name.ptr) == 0){
610 611 612 613 614 615
            return &lpconf.lpannos[i];
        }
    }
    return NULL;
}

616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
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)
{
641 642
    return get_cid_by_name(group_name, lpconf.group_names,
            lpconf.lpgroups_count);
643 644 645 646 647 648 649 650 651 652 653 654 655
}

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)
{
656
    return get_name_by_cid(cid, lpconf.group_names, lpconf.lpgroups_count);
657 658 659 660
}

int codes_mapping_get_lp_cid_by_name(char const * lp_type_name)
{
661 662
    return get_cid_by_name(lp_type_name, lpconf.lp_names,
            lpconf.num_uniq_lptypes);
663 664 665 666 667 668 669 670 671 672 673 674 675
}

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)
{
676
    return get_name_by_cid(cid, lpconf.lp_names, lpconf.num_uniq_lptypes);
677 678 679 680 681
}

int codes_mapping_get_anno_cid_by_name(char const * annotation)
{
    if (annotation == NULL || annotation[0] == '\0')
682
        return lpconf.num_uniq_annos;
683
    else
684 685
        return get_cid_by_name(annotation, lpconf.anno_names,
                lpconf.num_uniq_annos);
686 687 688 689 690 691 692 693 694 695 696 697 698
}

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)
{
699
    return get_name_by_cid(cid, lpconf.anno_names, lpconf.num_uniq_annos);
700 701
}

Philip Carns's avatar
Philip Carns committed
702 703 704 705 706 707 708 709
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */