<commit_before>#include <ross.h>

/**
 * @file tw-setup.c
 * @brief tw_define_lps is defined here!
 */

#define VERIFY_MAPPING 0

static tw_pe *setup_pes(void);
unsigned int nkp_per_pe = 16;

static const tw_optdef kernel_options[] = {
    TWOPT_GROUP("ROSS Kernel"),
    TWOPT_UINT("synch", g_tw_synchronization_protocol, "Sychronization Protocol: SEQUENTIAL=1, CONSERVATIVE=2, OPTIMISTIC=3, OPTIMISTIC_DEBUG=4"),
    TWOPT_UINT("nkp", nkp_per_pe, "number of kernel processes (KPs) per pe"),
    TWOPT_STIME("end", g_tw_ts_end, "simulation end timestamp"),
    TWOPT_UINT("batch", g_tw_mblock, "messages per scheduler block"),
    TWOPT_UINT("extramem", g_tw_events_per_pe_extra, "Number of extra events allocated per PE."),
    TWOPT_UINT("buddy_size", g_tw_buddy_alloc, "delta encoding buddy system allocation (2^X)"),
#ifdef AVL_TREE
    TWOPT_UINT("avl_size", g_tw_avl_node_count, "AVL Treet contians 2^avl_size nodes"),
#endif
    TWOPT_END()
};

void tw_init(int *argc, char ***argv) {
    int i;
#if HAVE_CTIME
    time_t raw_time;
#endif

    tw_opt_add(tw_net_init(argc, argv));

    // Print out the command-line so we know what we passed in
    if (tw_ismaster()) {
        for (i = 0; i < *argc; i++) {
            printf("%s ", (*argv)[i]);
        }
        printf("\n\n");
    }

    // Print our revision if we have it
#ifdef ROSS_VERSION
    if (tw_ismaster()) {
#if HAVE_CTIME
        time(&raw_time);
        printf("%s\n", ctime(&raw_time));
#endif
        printf("ROSS Revision: %s\n\n", ROSS_VERSION);
    }
#endif

    tw_opt_add(kernel_options);
    tw_opt_add(tw_gvt_setup());
    tw_opt_add(tw_clock_setup());

    // by now all options must be in
    tw_opt_parse(argc, argv);

    if(tw_ismaster() && NULL == (g_tw_csv = fopen("ross.csv", "a"))) {
        tw_error(TW_LOC, "Unable to open: ross.csv\n");
    }

    tw_opt_print();

    tw_net_start();
    tw_gvt_start();
}

static void early_sanity_check(void) {
#if ROSS_MEMORY
    if(0 == g_tw_memory_nqueues) {
        tw_error(TW_LOC, "ROSS memory library enabled!");
    }
#endif

    if (!g_tw_npe) {
        tw_error(TW_LOC, "need at least one PE");
    }
    if (!g_tw_nlp) {
        tw_error(TW_LOC, "need at least one LP");
    }
    if (!nkp_per_pe) {
        tw_printf(TW_LOC, "number of KPs (%u) must be >= PEs (%u), adjusting.", g_tw_nkp, g_tw_npe);
        g_tw_nkp = g_tw_npe;
    }
}

/*
 * map: map LPs->KPs->PEs linearly
 */
void map_linear(void) {
    tw_pe   *pe;

    int  nlp_per_kp;
    int  lpid;
    int  kpid;
    int  i;
    int  j;

    // may end up wasting last KP, but guaranteed each KP has == nLPs
    nlp_per_kp = (int)ceil((double) g_tw_nlp / (double) g_tw_nkp);

    if(!nlp_per_kp) {
        tw_error(TW_LOC, "Not enough KPs defined: %d", g_tw_nkp);
    }

    g_tw_lp_offset = g_tw_mynode * g_tw_nlp;

#if VERIFY_MAPPING
    printf("NODE %d: nlp %lld, offset %lld\n", g_tw_mynode, g_tw_nlp, g_tw_lp_offset);
#endif

    for(kpid = 0, lpid = 0, pe = NULL; (pe = tw_pe_next(pe)); ) {
#if VERIFY_MAPPING
        printf("\tPE %d\n", pe->id);
#endif

        for(i = 0; i < nkp_per_pe; i++, kpid++) {
            tw_kp_onpe(kpid, pe);

#if VERIFY_MAPPING
            printf("\t\tKP %d", kpid);
#endif

            for(j = 0; j < nlp_per_kp && lpid < g_tw_nlp; j++, lpid++) {
                tw_lp_onpe(lpid, pe, g_tw_lp_offset+lpid);
                tw_lp_onkp(g_tw_lp[lpid], g_tw_kp[kpid]);

#if VERIFY_MAPPING
                if(0 == j % 20) {
                    printf("\n\t\t\t");
                }
                printf("%lld ", lpid+g_tw_lp_offset);
#endif
            }

#if VERIFY_MAPPING
            printf("\n");
#endif
        }
    }

    if(!g_tw_lp[g_tw_nlp-1]) {
        tw_error(TW_LOC, "Not all LPs defined! (g_tw_nlp=%d)", g_tw_nlp);
    }

    if(g_tw_lp[g_tw_nlp-1]->gid != g_tw_lp_offset + g_tw_nlp - 1) {
        tw_error(TW_LOC, "LPs not sequentially enumerated!");
    }
}

void map_round_robin(void) {
    tw_pe   *pe;

    int  kpid;
    int  i;

    for(i = 0; i < g_tw_nlp; i++) {
        kpid = i % g_tw_nkp;
        pe = tw_getpe(kpid % g_tw_npe);

        tw_lp_onpe(i, pe, g_tw_lp_offset+i);
        tw_kp_onpe(kpid, pe);
        tw_lp_onkp(g_tw_lp[i], g_tw_kp[kpid]);

#if VERIFY_MAPPING
        printf("LP %4d KP %4d PE %4d\n", i, kp->id, pe->id);
#endif
    }
}

/**
 * IMPORTANT: This function sets the value for g_tw_nlp which is a rather
 * important global variable.  It is also set in (very few) other places,
 * but mainly just here.
 */
void tw_define_lps(tw_lpid nlp, size_t msg_sz, tw_seed * seed) {
    int  i;

    g_tw_nlp = nlp;

#ifdef ROSS_MEMORY
    g_tw_memory_sz = sizeof(tw_memory);
#endif

    g_tw_msg_sz = msg_sz;
    g_tw_rng_seed = seed;

    early_sanity_check();

    /*
     * Construct the KP array.
     */
    if( g_tw_nkp == 1 ) { // if it is the default, then check with the overide param
        g_tw_nkp = nkp_per_pe * g_tw_npe;
    }
    // else assume the application overloaded and has BRAINS to set its own g_tw_nkp

    g_tw_kp = (tw_kp **) tw_calloc(TW_LOC, "KPs", sizeof(*g_tw_kp), g_tw_nkp);
<commit_msg>optimistic debug requires 1 kp<commit_after>#include <ross.h>

/**
 * @file tw-setup.c
 * @brief tw_define_lps is defined here!
 */

#define VERIFY_MAPPING 0

static tw_pe *setup_pes(void);
unsigned int nkp_per_pe = 16;

static const tw_optdef kernel_options[] = {
    TWOPT_GROUP("ROSS Kernel"),
    TWOPT_UINT("synch", g_tw_synchronization_protocol, "Sychronization Protocol: SEQUENTIAL=1, CONSERVATIVE=2, OPTIMISTIC=3, OPTIMISTIC_DEBUG=4"),
    TWOPT_UINT("nkp", nkp_per_pe, "number of kernel processes (KPs) per pe"),
    TWOPT_STIME("end", g_tw_ts_end, "simulation end timestamp"),
    TWOPT_UINT("batch", g_tw_mblock, "messages per scheduler block"),
    TWOPT_UINT("extramem", g_tw_events_per_pe_extra, "Number of extra events allocated per PE."),
    TWOPT_UINT("buddy_size", g_tw_buddy_alloc, "delta encoding buddy system allocation (2^X)"),
#ifdef AVL_TREE
    TWOPT_UINT("avl_size", g_tw_avl_node_count, "AVL Treet contians 2^avl_size nodes"),
#endif
    TWOPT_END()
};

void tw_init(int *argc, char ***argv) {
    int i;
#if HAVE_CTIME
    time_t raw_time;
#endif

    tw_opt_add(tw_net_init(argc, argv));

    // Print out the command-line so we know what we passed in
    if (tw_ismaster()) {
        for (i = 0; i < *argc; i++) {
            printf("%s ", (*argv)[i]);
        }
        printf("\n\n");
    }

    // Print our revision if we have it
#ifdef ROSS_VERSION
    if (tw_ismaster()) {
#if HAVE_CTIME
        time(&raw_time);
        printf("%s\n", ctime(&raw_time));
#endif
        printf("ROSS Revision: %s\n\n", ROSS_VERSION);
    }
#endif

    tw_opt_add(kernel_options);
    tw_opt_add(tw_gvt_setup());
    tw_opt_add(tw_clock_setup());

    // by now all options must be in
    tw_opt_parse(argc, argv);

    if(tw_ismaster() && NULL == (g_tw_csv = fopen("ross.csv", "a"))) {
        tw_error(TW_LOC, "Unable to open: ross.csv\n");
    }

    tw_opt_print();

    tw_net_start();
    tw_gvt_start();
}

static void early_sanity_check(void) {
#if ROSS_MEMORY
    if(0 == g_tw_memory_nqueues) {
        tw_error(TW_LOC, "ROSS memory library enabled!");
    }
#endif

    if (!g_tw_npe) {
        tw_error(TW_LOC, "need at least one PE");
    }
    if (!g_tw_nlp) {
        tw_error(TW_LOC, "need at least one LP");
    }
    if (!nkp_per_pe) {
        tw_printf(TW_LOC, "number of KPs (%u) must be >= PEs (%u), adjusting.", g_tw_nkp, g_tw_npe);
        g_tw_nkp = g_tw_npe;
    }
}

/*
 * map: map LPs->KPs->PEs linearly
 */
void map_linear(void) {
    tw_pe   *pe;

    int  nlp_per_kp;
    int  lpid;
    int  kpid;
    int  i;
    int  j;

    // may end up wasting last KP, but guaranteed each KP has == nLPs
    nlp_per_kp = (int)ceil((double) g_tw_nlp / (double) g_tw_nkp);

    if(!nlp_per_kp) {
        tw_error(TW_LOC, "Not enough KPs defined: %d", g_tw_nkp);
    }

    g_tw_lp_offset = g_tw_mynode * g_tw_nlp;

#if VERIFY_MAPPING
    printf("NODE %d: nlp %lld, offset %lld\n", g_tw_mynode, g_tw_nlp, g_tw_lp_offset);
#endif

    for(kpid = 0, lpid = 0, pe = NULL; (pe = tw_pe_next(pe)); ) {
#if VERIFY_MAPPING
        printf("\tPE %d\n", pe->id);
#endif

        for(i = 0; i < nkp_per_pe; i++, kpid++) {
            tw_kp_onpe(kpid, pe);

#if VERIFY_MAPPING
            printf("\t\tKP %d", kpid);
#endif

            for(j = 0; j < nlp_per_kp && lpid < g_tw_nlp; j++, lpid++) {
                tw_lp_onpe(lpid, pe, g_tw_lp_offset+lpid);
                tw_lp_onkp(g_tw_lp[lpid], g_tw_kp[kpid]);

#if VERIFY_MAPPING
                if(0 == j % 20) {
                    printf("\n\t\t\t");
                }
                printf("%lld ", lpid+g_tw_lp_offset);
#endif
            }

#if VERIFY_MAPPING
            printf("\n");
#endif
        }
    }

    if(!g_tw_lp[g_tw_nlp-1]) {
        tw_error(TW_LOC, "Not all LPs defined! (g_tw_nlp=%d)", g_tw_nlp);
    }

    if(g_tw_lp[g_tw_nlp-1]->gid != g_tw_lp_offset + g_tw_nlp - 1) {
        tw_error(TW_LOC, "LPs not sequentially enumerated!");
    }
}

void map_round_robin(void) {
    tw_pe   *pe;

    int  kpid;
    int  i;

    for(i = 0; i < g_tw_nlp; i++) {
        kpid = i % g_tw_nkp;
        pe = tw_getpe(kpid % g_tw_npe);

        tw_lp_onpe(i, pe, g_tw_lp_offset+i);
        tw_kp_onpe(kpid, pe);
        tw_lp_onkp(g_tw_lp[i], g_tw_kp[kpid]);

#if VERIFY_MAPPING
        printf("LP %4d KP %4d PE %4d\n", i, kp->id, pe->id);
#endif
    }
}

/**
 * IMPORTANT: This function sets the value for g_tw_nlp which is a rather
 * important global variable.  It is also set in (very few) other places,
 * but mainly just here.
 */
void tw_define_lps(tw_lpid nlp, size_t msg_sz, tw_seed * seed) {
    int  i;

    g_tw_nlp = nlp;

#ifdef ROSS_MEMORY
    g_tw_memory_sz = sizeof(tw_memory);
#endif

    g_tw_msg_sz = msg_sz;
    g_tw_rng_seed = seed;

    early_sanity_check();

    /*
     * Construct the KP array.
     */
    if( g_tw_nkp == 1 && g_tw_synchronization_protocol != OPTIMISTIC_DEBUG ) { // if it is the default, then check with the overide param
        g_tw_nkp = nkp_per_pe * g_tw_npe;
    }
    // else assume the application overloaded and has BRAINS to set its own g_tw_nkp

    g_tw_kp = (tw_kp **) tw_calloc(TW_LOC, "KPs", sizeof(*g_tw_kp), g_tw_nkp);

{'fraction_non_alphanumeric': 0.13737334372564303, 'fraction_numerical': 0.005163678877630553, 'mean_word_length': 2.7504567044208987, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '754955', 'n_tokens_mistral': 4400, 'n_tokens_neox': 4175, 'n_words': 936}