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

Jonathan Jenkins's avatar
Jonathan Jenkins committed
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_model_types *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 || g_st_model_stats || g_st_use_analysis_lps)
493
         {
494
495
             trace_type = st_model_type_lookup(lp_type_name);
             st_model_settype(ross_lid, (st_model_types*) 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;
Jonathan Jenkins's avatar
Jonathan Jenkins committed
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
 */