Commit 0299a20f authored by Jonathan Jenkins's avatar Jonathan Jenkins

codes mapping overhaul to support annotations

Contains the following:
- annotation-aware codes-mapping API
- updated mapping tests
- updated codes-base models to use the new API
- updated LSM to configure based on annotation
  - fixed initialization issue (was doing config as an event)
  - no need for lsm_send_init from outside LPs
parent b2d7138f
......@@ -22,36 +22,128 @@ tw_peid codes_mapping( tw_lpid gid);
void codes_mapping_setup(void);
/*Takes the group name and returns the number of repetitions in the group */
int codes_mapping_get_group_reps(char* grp_name);
int codes_mapping_get_group_reps(const char* group_name);
/* Takes the group name and lp type name, returns the count for that lp type */
int codes_mapping_get_lp_count(char* grp_name, char* lp_type_name);
/* Gets the total lp type count across all groups */
int codes_mapping_get_global_lp_count(char* lp_type_name);
/* Calculates the count for LPs of the given type
*
* group_name - name of group. If NULL, count is across all groups.
* ignore_repetitions - if group_name is given, then don't include repetitions
* in count. This exists at the moment to support some
* uses of the function that haven't been fleshed out in
* other parts of the API (used by the dragonfly/torus
* models)
* lp_type_name - name of LP type
* annotation - optional annotation. If NULL, entry is considered
* unannotated
* ignore_annos - If non-zero, then count across all annotations (and
* ignore whatever annotation parameter is passed in)
*
* returns the number of LPs found (0 in the case of some combination of group,
* lp_type_name, and annotation not being found)
*/
int codes_mapping_get_lp_count(
const char * group_name,
int ignore_repetitions,
const char * lp_type_name,
const char * annotation,
int ignore_annos);
/* Takes the group name , type name, rep ID and offset (for that lp type + repetition) and then returns the global LP ID. */
void codes_mapping_get_lp_id(char* grp_name, char* lp_type_name, int rep_id, int offset, tw_lpid* gid);
/* Calculates the global LP ID given config identifying info.
*
* group_name - name of group
* lp_type_name - name of LP type
* annotation - optional annotation (NULL -> unannotated)
* ignore_anno - ignores annotation and sets gid to the first found LP type
* with matching names
* rep_id - repetition within the group
* offset - lp offset within the repetition
* gid - output ID
*
* If the LP is unable to be found, a tw_error will occur
*/
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);
/* Takes the LP ID and returns its logical ID across LPs of the same type in
* all groups */
int codes_mapping_get_lp_global_rel_id(tw_lpid gid);
/* Calculates the LP ID relative to other LPs (0..N-1, where N is the number of
* LPs sharing the same type)
*
* gid - LP ID
* group_wise - whether to compute id relative to the LP's group
* annotation_wise - whether to compute id relative to the annotation the LP has
*/
int codes_mapping_get_lp_relative_id(
tw_lpid gid,
int group_wise,
int annotation_wise);
/* takes the LP ID and returns its grp name and index, lp type name and ID, repetition ID and the offset of the LP
* (for multiple LPs in a repetition). */
void codes_mapping_get_lp_info(tw_lpid gid, char* grp_name, int* grp_id, int* lp_type_id, char* lp_type_name, int* grp_rep_id, int* offset);
/* Returns configuration group information for a given LP-id
*
* gid - LP to look up
* group_name - output LP group name
* group_index - index in config struct of group (mostly used internally)
* lp_type_name - output LP type name
* lp_type_index - index in config struct of lp type (mostly used internally)
* annotation - output annotation (given that the caller is responsible for
* providing the memory, if there's no annotation then the empty
* string is returned)
* rep_id - output repetition within the group
* offset - output LP offset within the LP (for multiple lps in a rep.)
*
* The *_name and annotation parameters can be NULL, in which case the result
* strings aren't copied to them. This is useful when you just need the
* repetition ID and/or the offset. Otherwise, the caller is expected to pass in
* properly-allocated buffers for each (of size MAX_NAME_LENGTH)
*/
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);
//void codes_mapping_get_lp_info(tw_lpid gid, char* group_name, int* grp_id, int* lp_type_id, char* lp_type_name, int* grp_rep_id, int* offset);
/* given the group and LP type name, return the annotation (or NULL if there is
* none) */
const char* codes_mapping_get_annotation_by_name(char *grp_name, char *lp_type_name);
/* given the LP ID, return the annotation (or NULL if there is none)
* NOTE: both functions have equivalent results. The different ways of accessing
* are for convenience */
/* Returns the annotation for the given LP.
*
* group_name - group name of LP
* lp_type_name - name of the LP
*
* NOTE: This function returns the annotation for the first found LP with
* lp_type_name within the group. In the case of having multiple LP types with
* different annotations in the same group, use the _by_lpid version.
*
* Either the annotation string or NULL (in the case of an unannotated entry) is
* returned. */
const char* codes_mapping_get_annotation_by_name(
const char * group_name,
const char * lp_type_name);
/* Returns the annotation for the given LP.
*
* gid - LP id to look up
*
* NOTE: both functions have equivalent results if there is only one LP type in
* the requested group. The different ways of accessing are for convenience.
* This function is the one to use if there are multiple group entries of the
* same LP type (and different annotations)
*
* Either the annotation string or NULL (in the case of an unannotated entry) is
* returned. */
const char* codes_mapping_get_annotation_by_lpid(tw_lpid gid);
/*
* Returns a mapping of LP name to all annotations used with the type
*
* lp_name - lp name as used in the configuration
* lp_name - lp name as used in the configuration
*/
const config_anno_map_t *
codes_mapping_get_lp_anno_map(const char *lp_name);
......
......@@ -9,13 +9,14 @@
#include <ross.h>
#define LSM_NAME "lsm"
/*
* lsm_event_t
* - events supported by the local storage model
*/
typedef enum lsm_event_e
{
LSM_INIT = 0,
LSM_WRITE_REQUEST = 1,
LSM_READ_REQUEST = 2,
LSM_WRITE_COMPLETION = 3,
......@@ -41,7 +42,8 @@ tw_event* lsm_event_new(const char* category,
void* lsm_event_data(tw_event *event);
void lsm_init(void);
void lsm_register(void);
void lsm_configure(void);
void lsm_send_init (tw_lpid gid, tw_lp *lp, char *name);
......
......@@ -23,6 +23,7 @@
#include "codes/configuration.h"
#include "codes/model-net.h"
#include "codes/lp-type-lookup.h"
#include "codes/local-storage-model.h"
static int num_reqs = 0;/* number of requests sent by each server (read from config) */
static int payload_sz = 0; /* size of simulated data payload, bytes (read from config) */
......@@ -237,8 +238,9 @@ int main(
* codes */
codes_mapping_setup();
/* calculate the number of servers in this simulation */
num_servers = codes_mapping_get_group_reps(group_name) * codes_mapping_get_lp_count(group_name, "server");
/* calculate the number of servers in this simulation,
* ignoring annotations */
num_servers = codes_mapping_get_lp_count(group_name, 0, "server", NULL, 1);
/* for this example, we read from a separate configuration group for
* server message parameters. Since they are constant for all LPs,
......@@ -391,18 +393,20 @@ tw_lpid get_next_server(tw_lpid sender_id)
/* first, get callers LP and group info from codes-mapping. Caching this
* info in the LP struct isn't a bad idea for preventing a huge number of
* lookups */
char grp_name[MAX_NAME_LENGTH], lp_type_name[MAX_NAME_LENGTH];
char grp_name[MAX_NAME_LENGTH], lp_type_name[MAX_NAME_LENGTH],
annotation[MAX_NAME_LENGTH];
int lp_type_id, grp_id, grp_rep_id, offset, num_reps;
int dest_rep_id;
codes_mapping_get_lp_info(sender_id, grp_name, &grp_id, &lp_type_id,
lp_type_name, &grp_rep_id, &offset);
codes_mapping_get_lp_info(sender_id, grp_name, &grp_id, lp_type_name,
&lp_type_id, annotation, &grp_rep_id, &offset);
/* in this example, we assume that, for our group of servers, each
* "repetition" consists of a single server/NIC pair. Hence, we grab the
* server ID for the next repetition, looping around if necessary */
num_reps = codes_mapping_get_group_reps(grp_name);
dest_rep_id = (grp_rep_id+1) % num_reps;
/* finally, get the server (exactly 1 server per rep -> offset w/in rep = 0 */
codes_mapping_get_lp_id(grp_name, lp_type_name, dest_rep_id, 0, &rtn_id);
codes_mapping_get_lp_id(grp_name, lp_type_name, NULL, 1, dest_rep_id,
0, &rtn_id);
return rtn_id;
}
......
This diff is collapsed.
......@@ -392,11 +392,13 @@ int configuration_get_lpgroups (ConfigHandle *handle,
* given annotation. Used for configuration schemes where an array of
* configuration values is generated based on the annotations in
* config_anno_map_t
* If annotation is not found, -1 is returned */
* If anno is not found or a NULL anno is passed in,
* -1 is returned */
int configuration_get_annotation_index(const char * anno,
const config_anno_map_t * anno_map){
if (anno == NULL) return -1;
for (uint64_t i = 0; i < anno_map->num_annos; i++){
if (strcmp(anno, anno_map->annotations[i]) == 0){
if (!strcmp(anno, anno_map->annotations[i])){
return (int)i;
}
}
......
This diff is collapsed.
......@@ -415,8 +415,8 @@ void resource_finalize(
char *out_buf = malloc(1<<12);
int written;
// see if I'm the "first" resource
if (codes_mapping_get_lp_global_rel_id(lp->gid) == 0){
// see if I'm the "first" resource (currently doing it globally)
if (codes_mapping_get_lp_relative_id(lp->gid, 0, 0) == 0){
written = sprintf(out_buf,
"# format: <LP> <max used general> <max used token...>\n");
lp_io_write(lp->gid, RESOURCE_LP_NM, written, out_buf);
......@@ -496,13 +496,15 @@ static void resource_lp_issue_event(
tw_lpid resource_lpid;
/* map out the lpid of the resource */
int mapping_grp_id, mapping_type_id, mapping_rep_id, mapping_offset;
char lp_type_name[MAX_NAME_LENGTH], lp_group_name[MAX_NAME_LENGTH];
codes_mapping_get_lp_info(sender->gid, lp_group_name,
&mapping_grp_id, &mapping_type_id, lp_type_name,
int mapping_rep_id, mapping_offset, dummy;
char lp_group_name[MAX_NAME_LENGTH];
// TODO: currently ignoring annotations... perhaps give annotation as a
// parameter?
codes_mapping_get_lp_info(sender->gid, lp_group_name, &dummy,
NULL, &dummy, NULL,
&mapping_rep_id, &mapping_offset);
codes_mapping_get_lp_id(lp_group_name, RESOURCE_LP_NM, mapping_rep_id,
mapping_offset, &resource_lpid);
codes_mapping_get_lp_id(lp_group_name, RESOURCE_LP_NM, NULL, 1,
mapping_rep_id, mapping_offset, &resource_lpid);
tw_event *e = codes_event_new(resource_lpid, codes_local_latency(sender),
sender);
......
......@@ -5,12 +5,16 @@ LPGROUPS
repetitions="2";
a="1";
b="2";
a@foo="1";
c="1";
}
GRP2
{
repetitions="3";
c="1";
b="1";
c@bar="1";
b@foo="1";
c="2";
a@foo="1";
}
}
......
TEST1 2 a
TEST1 3 c
TEST1 7 b
TEST2 0 0 a
TEST2 1 0 b
TEST2 2 1 b
TEST2 3 1 a
TEST2 4 2 b
TEST2 5 3 b
TEST2 6 0 c
TEST2 7 4 b
TEST2 8 1 c
TEST2 9 5 b
TEST2 10 2 c
TEST2 11 6 b
TEST1 2 (null) a
TEST1 5 (null) a@foo
TEST1 0 (null) a@bar
TEST1 7 (null) a ignore annos
TEST1 2 GRP1 a
TEST1 2 GRP1 a@foo
TEST1 0 GRP1 a@bar
TEST1 4 GRP1 a ignore annos
TEST1 0 GRP2 a
TEST1 3 GRP2 a@foo
TEST1 0 GRP2 a@bar
TEST1 3 GRP2 a ignore annos
TEST1 4 (null) b
TEST1 3 (null) b@foo
TEST1 0 (null) b@bar
TEST1 7 (null) b ignore annos
TEST1 4 GRP1 b
TEST1 0 GRP1 b@foo
TEST1 0 GRP1 b@bar
TEST1 4 GRP1 b ignore annos
TEST1 0 GRP2 b
TEST1 3 GRP2 b@foo
TEST1 0 GRP2 b@bar
TEST1 3 GRP2 b ignore annos
TEST1 8 (null) c
TEST1 0 (null) c@foo
TEST1 3 (null) c@bar
TEST1 11 (null) c ignore annos
TEST1 2 GRP1 c
TEST1 0 GRP1 c@foo
TEST1 0 GRP1 c@bar
TEST1 2 GRP1 c ignore annos
TEST1 6 GRP2 c
TEST1 0 GRP2 c@foo
TEST1 3 GRP2 c@bar
TEST1 9 GRP2 c ignore annos
TEST2 0 0 0 0 0 a
TEST2 1 0 0 0 0 b
TEST2 2 1 1 1 1 b
TEST2 3 1 1 0 0 a@foo
TEST2 4 0 0 0 0 c
TEST2 5 2 2 1 1 a
TEST2 6 2 2 2 2 b
TEST2 7 3 3 3 3 b
TEST2 8 3 3 1 1 a@foo
TEST2 9 1 1 1 1 c
TEST2 10 2 0 0 0 c@bar
TEST2 11 4 0 0 0 b@foo
TEST2 12 3 1 2 0 c
TEST2 13 4 2 3 1 c
TEST2 14 4 0 2 0 a@foo
TEST2 15 5 3 1 1 c@bar
TEST2 16 5 1 1 1 b@foo
TEST2 17 6 4 4 2 c
TEST2 18 7 5 5 3 c
TEST2 19 5 1 3 1 a@foo
TEST2 20 8 6 2 2 c@bar
TEST2 21 6 2 2 2 b@foo
TEST2 22 9 7 6 4 c
TEST2 23 10 8 7 5 c
TEST2 24 6 2 4 2 a@foo
......@@ -156,10 +156,12 @@ int main(
}
lp_type_register("server", &svr_lp);
lsm_init();
lsm_register();
codes_mapping_setup();
lsm_configure();
ret = lp_io_prepare("lsm-test", LP_IO_UNIQ_SUFFIX, &handle, MPI_COMM_WORLD);
if(ret < 0)
{
......@@ -315,7 +317,6 @@ static void handle_kickoff_event(
(unsigned long long)lp->gid,
rate,
seek);
lsm_send_init(lp->gid, lp, NULL);
e_new = lsm_event_new("test", lp->gid, 0, 0, PAYLOAD_SZ, LSM_WRITE_REQUEST, sizeof(svr_msg), lp, 1.0);
m_new = lsm_event_data(e_new);
......
......@@ -12,25 +12,48 @@
/* define three types of lps for mapping test */
typedef struct a_state_s{
int id;
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;
static void a_init(a_state *ns, tw_lp *lp){
ns->id = codes_mapping_get_lp_global_rel_id(lp->gid);
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){
printf("TEST2 %lu %d a\n", lp->gid, ns->id);
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){
printf("TEST2 %lu %d b\n", lp->gid, ns->id);
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){
printf("TEST2 %lu %d c\n", lp->gid, ns->id);
char anno[128];
if (ns->anno == NULL)
anno[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);
}
tw_lptype a_lp = {
......@@ -88,9 +111,31 @@ int main(int argc, char *argv[])
codes_mapping_setup();
printf("TEST1 %d a\n", codes_mapping_get_global_lp_count("a"));
printf("TEST1 %d b\n", codes_mapping_get_global_lp_count("b"));
printf("TEST1 %d c\n", codes_mapping_get_global_lp_count("c"));
printf("# test 2 format:\n"
"# <lp> rel id <global <group-wise> <anno.-wise> <both> <lp name>\n");
const char * lps[] = {"a", "b", "c"};
const char * groups[] = {NULL, "GRP1", "GRP2"};
const char * annos[] = {NULL, "foo", "bar"};
char lpnm[128];
for (int l = 0; l < 3; l++){
for (int g = 0; g < 3; g++){
for (int a = 0; a < 3; a++){
if (annos[a]==NULL)
sprintf(lpnm, "%s", lps[l]);
else
sprintf(lpnm, "%s@%s", lps[l], annos[a]);
printf("TEST1 %2d %6s %s\n",
codes_mapping_get_lp_count(groups[g], 0, lps[l],
annos[a], 0),
groups[g], lpnm);
}
printf("TEST1 %2d %6s %s ignore annos\n",
codes_mapping_get_lp_count(groups[g], 0, lps[l], NULL, 1),
groups[g], lps[l]);
}
}
tw_run();
tw_end();
......
......@@ -3,7 +3,7 @@
tst=$srcdir/tests
set -e
tests/mapping_test --sync=1 --codes-config=$tst/conf/mapping_test.conf | \
grep TEST | sort -s -k 1d,1d -k 2n,2n > mapping_test.out
grep TEST > mapping_test.out
diff $tst/expected/mapping_test.out mapping_test.out
err=$?
......
......@@ -35,7 +35,7 @@ typedef struct {
static void s_init(s_state *ns, tw_lp *lp){
ns->mem = 0;
ns->mem_max = 0;
ns->id = codes_mapping_get_lp_global_rel_id(lp->gid);
ns->id = codes_mapping_get_lp_relative_id(lp->gid, 0, 0);
tw_event *e = codes_event_new(lp->gid, codes_local_latency(lp), lp);
s_msg *m = tw_event_data(e);
msg_set_header(s_magic, S_KICKOFF, lp->gid, &m->h);
......
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