codes_mapping.c 24.8 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
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
74
    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);
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)
{
80
81
82
83
84
85
86
87
    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;*/
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];
456
     int 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]);

464
465
466
467
     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);
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
552
553

  // 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 +
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
600
 */
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++){
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
 */