Commit ded76aad authored by Jonathan Jenkins's avatar Jonathan Jenkins

codes-mapping: 'relative id' -> LP id conversion function + tests

parent 0299a20f
......@@ -82,6 +82,28 @@ int codes_mapping_get_lp_relative_id(
int group_wise,
int annotation_wise);
/* Calculates the ROSS global LP ID of an LP given the relative ID and LP type
* information
*
* relative_id - LP id relative to set of "like" LPs
* group_name - name of LP's group. If non-NULL, ID is considered local
* to that group. If NULL, then ID is considered across all
* groups
* lp_type_name - name of the LP to look up. Must be provided
* annotation - LP's annotation. If NULL, ID is considered among
* unannotated LPs
* annotation_wise - whether to consider ID across a specific annotation (using
* the annotation parameter) or all annotations (ignoring the
* annotation parameter)
*/
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);
/* Returns configuration group information for a given LP-id
*
* gid - LP to look up
......
......@@ -256,6 +256,86 @@ int codes_mapping_get_lp_relative_id(
return (int) (group_lp_count + (lp_count * rep_id) + lp_pre_count + offset);
}
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++){
config_lpgroup_t *lpg = &lpconf.lpgroups[g];
if (group_name == NULL || strcmp(group_name, lpg->name) == 0){
// 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++){
config_lptype_t *lpt = &lpg->lptypes[l];
local_gid_count += lpt->count;
if (strcmp(lp_type_name, lpt->name) == 0 &&
(!annotation_wise || cmp_anno(annotation, lpt->anno))){
local_rel_id_count += lpt->count;
}
}
// is our relative id within this group?
if (relative_id < rel_id_count +
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++){
config_lptype_t *lpt = &lpg->lptypes[l];
if ( strcmp(lp_type_name, lpt->name) == 0 &&
(!annotation_wise ||
cmp_anno(annotation, lpt->anno))){
if (rem < (int) lpt->count){
return gid + (tw_lpid) rem;
}
else{
rem -= lpt->count;
}
}
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;
}
gid_count += local_gid_count * lpg->repetitions;
}
}
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
}
void codes_mapping_get_lp_info(
tw_lpid gid,
char * group_name,
......
......@@ -11,74 +11,103 @@
/* define three types of lps for mapping test */
typedef struct a_state_s{
typedef struct state_s{
int id_global, id_by_group, id_by_anno, id_by_group_anno;
const char * anno;
} a_state;
typedef a_state b_state;
typedef a_state c_state;
char group_name[MAX_NAME_LENGTH], lp_name[MAX_NAME_LENGTH],
anno[MAX_NAME_LENGTH];
} state;
static void init(state *ns, tw_lp *lp){
int dummy;
// only need the names
codes_mapping_get_lp_info(lp->gid, ns->group_name, &dummy,
ns->lp_name, &dummy, ns->anno, &dummy, &dummy);
const char * anno = codes_mapping_get_annotation_by_lpid(lp->gid);
// annotation check
if ( (anno == NULL && ns->anno[0] != '\0') ||
(anno != NULL && strcmp(anno, ns->anno) != 0)){
fprintf(stderr, "LP %lu: annotations don't match: "
"_get_lp_info:\"%s\", _get_anno_by_lpid:\"%s\"\n",
lp->gid, ns->anno, anno);
}
static void a_init(a_state *ns, tw_lp *lp){
ns->anno = codes_mapping_get_annotation_by_lpid(lp->gid);
ns->id_global = codes_mapping_get_lp_relative_id(lp->gid, 0, 0);
ns->id_by_group = codes_mapping_get_lp_relative_id(lp->gid, 1, 0);
ns->id_by_anno = codes_mapping_get_lp_relative_id(lp->gid, 0, 1);
ns->id_by_group_anno = codes_mapping_get_lp_relative_id(lp->gid, 1, 1);
}
static void b_init(b_state *ns, tw_lp *lp){ a_init(ns,lp); }
static void c_init(c_state *ns, tw_lp *lp){ a_init(ns,lp); }
static void a_finalize(a_state *ns, tw_lp *lp){
char anno[128];
if (ns->anno == NULL)
anno[0] = '\0';
else
sprintf(anno, "@%s", ns->anno);
printf("TEST2 %2lu %2d %2d %2d %2d a%s\n", lp->gid, ns->id_global,
ns->id_by_group, ns->id_by_anno, ns->id_by_group_anno, anno);
}
static void b_finalize(b_state *ns, tw_lp *lp){
char anno[128];
if (ns->anno == NULL)
anno[0] = '\0';
else
sprintf(anno, "@%s", ns->anno);
printf("TEST2 %2lu %2d %2d %2d %2d b%s\n", lp->gid, ns->id_global,
ns->id_by_group, ns->id_by_anno, ns->id_by_group_anno, anno);
}
static void c_finalize(c_state *ns, tw_lp *lp){
char anno[128];
if (ns->anno == NULL)
anno[0] = '\0';
// relative ID check - looking up the gid works correctly
tw_lpid id_from_global_rel =
codes_mapping_get_lpid_from_relative(ns->id_global, NULL,
ns->lp_name, NULL, 0);
tw_lpid id_from_group_rel =
codes_mapping_get_lpid_from_relative(ns->id_by_group, ns->group_name,
ns->lp_name, NULL, 0);
tw_lpid id_from_anno_rel =
codes_mapping_get_lpid_from_relative(ns->id_by_anno, NULL,
ns->lp_name, anno, 1);
tw_lpid id_from_group_anno_rel =
codes_mapping_get_lpid_from_relative(ns->id_by_group_anno, ns->group_name,
ns->lp_name, anno, 1);
if (lp->gid != id_from_global_rel){
fprintf(stderr, "LP %lu (%s): "
"global relative id %d doesn't match (got %lu)\n",
lp->gid, ns->lp_name, ns->id_global, id_from_global_rel);
}
if (lp->gid != id_from_group_rel){
fprintf(stderr, "LP %lu (%s): "
"group %s relative id %d doesn't match (got %lu)\n",
lp->gid, ns->lp_name, ns->group_name, ns->id_by_group,
id_from_group_rel);
}
if (lp->gid != id_from_anno_rel){
fprintf(stderr, "LP %lu (%s): "
"anno \"%s\" relative id %d doesn't match (got %lu)\n",
lp->gid, ns->lp_name, ns->anno, ns->id_by_group,
id_from_anno_rel);
}
if (lp->gid != id_from_group_anno_rel){
fprintf(stderr, "LP %lu (%s): "
"group %s anno \"%s\" relative id %d doesn't match (got %lu)\n",
lp->gid, ns->lp_name, ns->group_name, ns->anno, ns->id_by_group,
id_from_group_anno_rel);
}
// output-based check - print out IDs, compare against expected
char tmp[128];
if (ns->anno == NULL || ns->anno[0]=='\0')
tmp[0] = '\0';
else
sprintf(anno, "@%s", ns->anno);
printf("TEST2 %2lu %2d %2d %2d %2d c%s\n", lp->gid, ns->id_global,
ns->id_by_group, ns->id_by_anno, ns->id_by_group_anno, anno);
sprintf(tmp, "@%s", ns->anno);
printf("TEST2 %2lu %2d %2d %2d %2d %s%s\n", lp->gid, ns->id_global,
ns->id_by_group, ns->id_by_anno, ns->id_by_group_anno, ns->lp_name,
tmp);
}
tw_lptype a_lp = {
(init_f) a_init,
(init_f) init,
(event_f) NULL,
(revent_f) NULL,
(final_f) a_finalize,
(final_f) NULL,
(map_f) codes_mapping,
sizeof(a_state),
sizeof(state),
};
tw_lptype b_lp = {
(init_f) b_init,
(init_f) init,
(event_f) NULL,
(revent_f) NULL,
(final_f) b_finalize,
(final_f) NULL,
(map_f) codes_mapping,
sizeof(b_state),
sizeof(state),
};
tw_lptype c_lp = {
(init_f) c_init,
(init_f) init,
(event_f) NULL,
(revent_f) NULL,
(final_f) c_finalize,
(final_f) NULL,
(map_f) codes_mapping,
sizeof(c_state),
sizeof(state),
};
static char conf_file_name[128] = {'\0'};
......@@ -134,7 +163,6 @@ int main(int argc, char *argv[])
codes_mapping_get_lp_count(groups[g], 0, lps[l], NULL, 1),
groups[g], lps[l]);
}
}
tw_run();
......
......@@ -2,12 +2,20 @@
tst=$srcdir/tests
set -e
tests/mapping_test --sync=1 --codes-config=$tst/conf/mapping_test.conf | \
grep TEST > mapping_test.out
tests/mapping_test --sync=1 --codes-config=$tst/conf/mapping_test.conf \
2> mapping_test.err \
1| grep TEST > mapping_test.out
diff $tst/expected/mapping_test.out mapping_test.out
err=$?
if [ -s mapping_test.err ] ; then
echo ERROR: see mapping_test.err
exit 1
fi
if [ "$err" -eq 0 ]; then
rm mapping_test.out
rm mapping_test.out mapping_test.err
fi
exit $err
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment