codes_mapping.c 23.1 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
                strncpy(group_name, lpg->name.ptr, MAX_NAME_LENGTH);
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
374
375
376
377
378
379
                        strncpy(lp_type_name, lpt->name.ptr, MAX_NAME_LENGTH);
                    if (annotation != NULL) {
                        if (lpt->anno.ptr == NULL)
                            annotation[0] = '\0';
                        else
                            strncpy(annotation, lpt->anno.ptr, MAX_NAME_LENGTH);
                    }
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
}

/* This function assigns local and global LP Ids to LPs */
398
static void codes_mapping_init(void)
399
400
401
402
403
{
     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];
404
     int nkp_per_pe = g_tw_nkp;
405
     tw_lpid         lpid, kpid;
406
     const tw_lptype *lptype;
407
408
409
410
411

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

412
413
414
415
     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);
416

417
     for (lpid = lp_start; lpid < lp_end; lpid++)
418
419
      {
	 ross_gid = lpid;
420
	 ross_lid = lpid - lp_start;
421
422
	 kpid = ross_lid % g_tw_nkp;
	 pe = tw_getpe(kpid % g_tw_npe);
423
424
	 codes_mapping_get_lp_info(ross_gid, NULL, &grp_id, lp_type_name,
                 &lpt_id, NULL, &rep_id, &offset);
425
426
427
#if CODES_MAPPING_DEBUG
         printf("lp:%lu --> kp:%lu, pe:%llu\n", ross_gid, kpid, pe->id);
#endif
428
	 tw_lp_onpe(ross_lid, pe, ross_gid);
429
	 tw_lp_onkp(g_tw_lp[ross_lid], g_tw_kp[kpid]);
430
431
432
433
434
         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
435
436
             /* sorry, const... */
             tw_lp_settype(ross_lid, (tw_lptype*) lptype);
437
438
439
440
441
442
443
     }
     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 */
444
static tw_lp * codes_mapping_to_lp( tw_lpid lpid)
445
{
446
447
   int index = lpid - (g_tw_mynode * lps_per_pe_floor) -
       mini(g_tw_mynode, lps_leftover);
448
449
450
451
//   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];
}

452
/* This function loads the configuration file and sets up the number of LPs on each PE */
453
void codes_mapping_setup_with_seed_offset(int offset)
454
455
456
457
{
  int grp, lpt, message_size;
  int pes = tw_nnodes();

458
  lps_per_pe_floor = 0;
459
460
461
  for (grp = 0; grp < lpconf.lpgroups_count; grp++)
   {
    for (lpt = 0; lpt < lpconf.lpgroups[grp].lptypes_count; lpt++)
462
	lps_per_pe_floor += (lpconf.lpgroups[grp].lptypes[lpt].count * lpconf.lpgroups[grp].repetitions);
463
   }
464
  tw_lpid global_nlps = lps_per_pe_floor;
465
466
467
  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);
468
469
470
  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
471
472
473
474
475
476
477
478

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

479
  g_tw_events_per_pe = mem_factor * codes_mapping_get_lps_for_pe();
480
  configuration_get_value_int(&config, "PARAMS", "message_size", NULL, &message_size);
481
482
483
484
485
  if(!message_size)
  {
      message_size = 256;
      printf("\n Warning: ross message size not defined, resetting it to %d", message_size);
  }
486
487
488
489
490

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

491
  tw_define_lps(codes_mapping_get_lps_for_pe(), message_size, 0);
492
493
494
495
496
497
498
499
500
501

  // 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 +
502
                          global_nlps * offset) * g_tw_nRNG_per_lp + i);
503
504
505
506
507
508
509
          }
      }
  }
}

void codes_mapping_setup(){
    codes_mapping_setup_with_seed_offset(0);
510
511
}

512
/* given the group and LP type name, return the annotation (or NULL) */
513
514
515
516
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
517
        const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
518
        if (strcmp(lpg->name.ptr, group_name) == 0){
519
520
            // group found, iterate through types
            for (int l = 0; l < lpg->lptypes_count; l++){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
521
                const config_lptype_t *lpt = &lpg->lptypes[l];
522
                if (strcmp(lpt->name.ptr, lp_type_name) == 0){
523
                    // type found, return the annotation
524
                    return lpt->anno.ptr;
525
526
                }
            }
527
528
        }
    }
529
530
531
    tw_error(TW_LOC, "unable to find annotation using "
            "group \"%s\" and lp_type_name \"%s\"", group_name, lp_type_name);
    return NULL;
532
533
534
}

const char* codes_mapping_get_annotation_by_lpid(tw_lpid gid){
535
536
537
    int group_index, lp_type_index, dummy;
    codes_mapping_get_lp_info(gid, NULL, &group_index, NULL, &lp_type_index,
            NULL, &dummy, &dummy);
538
    return lpconf.lpgroups[group_index].lptypes[lp_type_index].anno.ptr;
539
}
Philip Carns's avatar
Philip Carns committed
540

541
542
543
/*
 * Returns a mapping of LP name to all annotations used with the type
 *
544
 * lp_name - lp name as used in the configuration
545
546
547
548
 */
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++){
549
        if (strcmp(lp_name, lpconf.lpannos[i].lp_name.ptr) == 0){
550
551
552
553
554
555
            return &lpconf.lpannos[i];
        }
    }
    return NULL;
}

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
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)
{
581
582
    return get_cid_by_name(group_name, lpconf.group_names,
            lpconf.lpgroups_count);
583
584
585
586
587
588
589
590
591
592
593
594
595
}

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)
{
596
    return get_name_by_cid(cid, lpconf.group_names, lpconf.lpgroups_count);
597
598
599
600
}

int codes_mapping_get_lp_cid_by_name(char const * lp_type_name)
{
601
602
    return get_cid_by_name(lp_type_name, lpconf.lp_names,
            lpconf.num_uniq_lptypes);
603
604
605
606
607
608
609
610
611
612
613
614
615
}

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)
{
616
    return get_name_by_cid(cid, lpconf.lp_names, lpconf.num_uniq_lptypes);
617
618
619
620
621
}

int codes_mapping_get_anno_cid_by_name(char const * annotation)
{
    if (annotation == NULL || annotation[0] == '\0')
622
        return lpconf.num_uniq_annos;
623
    else
624
625
        return get_cid_by_name(annotation, lpconf.anno_names,
                lpconf.num_uniq_annos);
626
627
628
629
630
631
632
633
634
635
636
637
638
}

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)
{
639
    return get_name_by_cid(cid, lpconf.anno_names, lpconf.num_uniq_annos);
640
641
}

Philip Carns's avatar
Philip Carns committed
642
643
644
645
646
647
648
649
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */