Example #1
0
/**
 * I shouldn't really initialize more than once
 */
static inline int
check_pe_status (void)
{
    int yn = 1;
    const pe_status_t s = GET_STATE (pe_status);

    switch (s) {
    case PE_UNINITIALIZED:     /* this is what it should be */
        yn = 1;
        break;
    case PE_UNKNOWN:
    case PE_RUNNING:
    case PE_SHUTDOWN:
    case PE_FAILED:
        shmemi_trace (SHMEM_LOG_INFO,
                      "OpenSHMEM has already been initialized (%s)",
                      shmemi_state_as_string (s));
        yn = 0;
        break;
    default:                   /* shouldn't be here */
        yn = 0;
        break;
    }

    return yn;
}
Example #2
0
/**
 * initialize the ping sub-system.  Respect any environment setting
 * asking for different ping timeout.
 *
 */
void
shmemi_ping_init (void)
{
#if 0
    double timeout = DEFAULT_PE_ACCESSIBLE_TIMEOUT;
    char *pt = shmemi_comms_getenv (ping_timeout_envvar);

    if (pt != (char *) NULL) {
        timeout = atof (pt);
    }

    /* sanity check it */
    if (timeout < 0.0) {
        double ot = timeout;
        timeout = DEFAULT_PE_ACCESSIBLE_TIMEOUT;
        shmemi_trace (SHMEM_LOG_INIT,
                      "PE accessibility timeout %f negative, reset to default %f sec",
                      ot, timeout);
    }

    shmemi_set_ping_timeout (timeout);

    assign_timer (0, 0, &zero);
#endif
}
Example #3
0
/*
 * Tree based broadcast generates a binary tree with the PEs in the
 * active with PE_root as the root.  The puts happen in a top down
 * approach.
 *
 */
static inline void
set_2tree (int PE_start, int PE_stride, int PE_size,
           int *parent, int *child_l, int *child_r, int my_pe)
{
    int max_pe = PE_start + PE_stride * (PE_size - 1);
    *child_l = 2 * (my_pe - PE_start) + PE_stride + PE_start;
    *child_r = *child_l + PE_stride;
    /* set parent */
    if (my_pe == PE_start) {
        *parent = -1;
    }
    else {
        *parent = (my_pe - PE_start - PE_stride) / 2;
        *parent -= *parent % PE_stride;
        *parent += PE_start;
    }
    if (*child_l > max_pe) {
        *child_l = *child_r = -1;
    }
    else if (*child_r > max_pe) {
        *child_r = -1;
    }
    shmemi_trace (SHMEM_LOG_BROADCAST,
                  "set2tree: parent = %d, L_child = %d, R_child = %d",
                  *parent, *child_l, *child_r);
}
Example #4
0
void
shmemi_barrier_linear (int PE_start, int logPE_stride, int PE_size, long *pSync)
{
    const int me = shmem_my_pe ();
    const int step = 1 << logPE_stride;
    const long nreplies = SHMEM_SYNC_VALUE + PE_size - 1;
    int i, round;
    int thatpe;

    for (round = 0; round < 2; round += 1) {

        for (thatpe = PE_start, i = 0; i < PE_size; thatpe += step, i += 1) {

            if (thatpe != me) {
                shmem_long_inc (&pSync[round], thatpe);

                shmemi_trace (SHMEM_LOG_BARRIER,
                              "round = %d, sent increment to PE %d",
                              round, thatpe);
            }

        }
        shmem_long_wait_until (&pSync[round], SHMEM_CMP_EQ, nreplies);

        pSync[round] = SHMEM_SYNC_VALUE;

    }
}
Example #5
0
static void
print_global_var_table (shmem_trace_t msgtype)
{
    globalvar_t *g;
    globalvar_t *tmp;

    if (!shmemi_trace_is_enabled (msgtype)) {
        return;
    }

    shmemi_trace (msgtype, "-- start hash table --");

    HASH_SORT (gvp, addr_sort);

    HASH_ITER (hh, gvp, g, tmp) {
        shmemi_trace (msgtype,
                      "address %p: name \"%s\", size %ld",
                      g->addr, g->name, g->size);
    }
Example #6
0
void
debug_alloc_dump (void)
{
    alloc_table_t *tmp;
    alloc_table_t *s;

    HASH_ITER (hh, atp, s, tmp) {
        shmemi_trace (SHMEM_LOG_MEMORY,
                      "addr = %p, size = %ld", s->addr, s->size);
    }
Example #7
0
/**
 * inspect our own executable: find the real program name, and open a
 * file descriptor
 */
void
shmemi_executable_init (void)
{
    ssize_t s;
    int fd;

    /* see if the shortcut works */
    s = readlink (self, GET_STATE (exe_name), MAXPATHLEN - 1);

    /* if not, try finding our PID */
    if (EXPR_UNLIKELY (s < 0)) {
        char buf[MAXPATHLEN];
        snprintf (buf, MAXPATHLEN, self_fmt, getpid ());
        s = readlink (buf, GET_STATE (exe_name), MAXPATHLEN - 1);
    }

    /* dunno who I am, complain */
    if (EXPR_UNLIKELY (s < 0)) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "can't find my own executable name (%s)",
                      strerror (errno));
        goto bail;
        /* NOT REACHED */
    }

    /* bleagh, readlink doesn't null-terminate */
    GET_STATE (exe_name)[s] = '\0';

    /* get a file descriptor */
    fd = open (GET_STATE (exe_name), O_RDONLY, 0);
    if (EXPR_UNLIKELY (fd < 0)) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "can't open \"%s\" (%s)",
                      GET_STATE (exe_name), strerror (errno));
        return;
        /* NOT REACHED */
    }

    SET_STATE (exe_fd, fd);

bail:
    return;
}
Example #8
0
/**
 * set the time out.  Can also be used to tune library behavior
 *
 */
void
shmemi_set_ping_timeout (double secs)
{
#if 0
    parse_alarm_time (secs, &GET_STATE (ping_timeout));

    shmemi_trace (SHMEM_LOG_INIT,
                  "PE accessibility timeout set to %f sec", secs);
#endif
}
Example #9
0
void
shmemi_symmetric_test_with_abort (void *remote_addr,
                                  void *local_addr,
                                  const char *name, const char *routine)
{
    if (EXPR_UNLIKELY (remote_addr == NULL)) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "shmem_%s_%s: address %p is not symmetric",
                      name, routine, local_addr);
        /* NOT REACHED */
    }
}
Example #10
0
static inline void
report_up (void)
{
    int maj, min;
    const int n = GET_STATE (numpes);
    const size_t h = GET_STATE (heapsize);

    if (shmemi_version (&maj, &min) == 0) {
        shmemi_trace (SHMEM_LOG_INIT,
                      "version %d.%d running on %d PE%s, using %zd bytes of symmetric heap",
                      maj, min, n, (n == 1) ? "" : "s", h);
    }
}
Example #11
0
/**
 * clear the alarm after doing a ping
 *
 */
void
shmemi_ping_clear_alarm (void)
{
#if 0
    int s = setitimer (ITIMER_REAL, &zero, NULL);
    if (s != 0) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "internal error: couldn't clear accessibility timer (%s)",
                      strerror (errno));
        return;
        /* NOT REACHED */
    }
#endif
}
Example #12
0
/**
 * set up the alarm before doing a ping
 *
 */
void
shmemi_ping_set_alarm (void)
{
#if 0
    int s = setitimer (ITIMER_REAL, &GET_STATE (ping_timeout), NULL);
    if (s != 0) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "internal error: couldn't set accessibility timer (%s)",
                      strerror (errno));
        return;
        /* NOT REACHED */
    }
#endif
}
Example #13
0
void
debug_alloc_del (void *a)
{
    alloc_table_t *at = debug_alloc_find (a);

    if (at == NULL) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "internal error: no hash table entry for address %p", a);
        return;
        /* NOT REACHED */
    }
    HASH_DEL (atp, at);

    free (at);
}
Example #14
0
static inline alloc_table_t *
debug_alloc_new (void *a, size_t s)
{
    alloc_table_t *at = (alloc_table_t *) malloc (sizeof (*at));

    if (at == NULL) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "internal error: out of memory"
                      " allocating address/size record");
        return NULL;
        /* NOT REACHED */
    }
    at->addr = a;
    at->size = s;
    return at;
}
Example #15
0
void *
shmem_ptr (const void *target, int pe)
{
    INIT_CHECK ();
    PE_RANGE_CHECK (pe, 2);

#ifdef SHMEM_PUTGET_SHARED_MEMORY

    shmemi_trace (SHMEM_LOG_NOTICE, "shmem_ptr() not implemented yet");
    return (void *) NULL;

#else /* ! SHMEM_PUTGET_SHARED_MEMORY */

    return (void *) NULL;

#endif /* SHMEM_PUTGET_SHARED_MEMORY */
}
Example #16
0
int
debug_alloc_check (void *a)
{
    alloc_table_t *tmp;
    alloc_table_t *s;

    HASH_ITER (hh, atp, s, tmp) {
        const size_t off = a - s->addr;

        /* if ( (s->size > off) && (off >= 0) ) */
        if (s->size > off) {
            return 1;
            /* NOT REACHED */
        }
    }

    shmemi_trace (SHMEM_LOG_MEMORY,
                  "address %p is not in a known symmetric allocation", a);
    return 0;
}
Example #17
0
void
shmem_pcontrol (int level)
{
    char *msg = NULL;

    switch (level) {
    case 0:
        msg = "disabled";
        break;
    case 1:
        msg = "enabled (default detail)";
        break;
    default:
        msg = "tool-specific";
        break;
    }

    shmemi_trace (SHMEM_LOG_INFO, "shmem_pcontrol(%d) is %s", level, msg);
    return;
}
Example #18
0
static inline void
shmem_init_private (int npes)
{
    if (!check_pe_status ()) {
        return;
    }

    shmemi_comms_init ();

    /* just note start_pes() not passed 0, it's not a big deal */
    if (npes != 0) {
        shmemi_trace (SHMEM_LOG_INFO,
                      "start_pes() was passed %d, should be 0", npes);
    }

    report_up ();

    /*
     * and we're up and running
     */
}
Example #19
0
/**
 * return number of (fractional) seconds
 * since program started
 */
static inline double
read_clock (void)
{
    struct timeval tv;
    double t;
    int s;

    s = gettimeofday (&tv, (struct timezone *) NULL);
    if (EXPR_UNLIKELY (s != 0)) {
        shmemi_trace (SHMEM_LOG_FATAL,
                      "internal error: can't read system clock (%s)",
                      strerror (errno)
            );
        /* NOT REACHED */
    }

    t = (double) tv.tv_sec;
    t += (double) tv.tv_usec / 1000000.0;

    return t;
}
Example #20
0
void
shmemi_collect_dispatch_init (void)
{
    char *name = shmemi_comms_getenv ("SHMEM_COLLECT_ALGORITHM");

    if (EXPR_LIKELY (name == (char *) NULL)) {
        name = default_implementation;
    }

    if (strcmp (name, "linear") == 0) {
        func32 = shmemi_collect32_linear;
        func64 = shmemi_collect64_linear;
    }
    else {
        ;                       /* error */
    }

    /* 
     * report which implementation we set up
     */
    shmemi_trace (SHMEM_LOG_BROADCAST, "using collect \"%s\"", name);
}
Example #21
0
void
shmemi_barrier_tree (int PE_start, int logPE_stride, int PE_size, long *pSync)
{
    int child_l, child_r, parent;
    const int step = 1 << logPE_stride;
    int my_pe = GET_STATE (mype);
    int no_children;
    long is_ready, lchild_ready, rchild_ready;


    is_ready = 1;
    lchild_ready = -1;
    rchild_ready = -1;

    shmem_long_wait_until (&pSync[0], SHMEM_CMP_EQ, SHMEM_SYNC_VALUE);
    shmem_long_wait_until (&pSync[1], SHMEM_CMP_EQ, SHMEM_SYNC_VALUE);

    /* printf("Tree barrier\n"); */
    set_2tree (PE_start, step, PE_size, &parent, &child_l, &child_r, my_pe);

    no_children = 0;

    shmemi_trace (SHMEM_LOG_BARRIER,
                  "before barrier, R_child = %d L_child = %d",
                  child_r, child_l);

    /* The actual barrier */

    if (PE_size > 1) {
        pSync[0] = 0;
        pSync[1] = 0;

        if (my_pe == PE_start) {
            pSync[0] = SHMEM_SYNC_VALUE;

            if (child_l != -1) {
                shmem_long_get (&lchild_ready, (const long *) &pSync[0],
                                1, child_l);
                while (lchild_ready != 0)
                    shmem_long_get (&lchild_ready, &pSync[0], 1, child_l);
                shmem_long_put (&pSync[0], &is_ready, 1, child_l);
                no_children = 1;
            }

            if (child_r != -1) {
                shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);
                while (rchild_ready != 0)
                    shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);
                shmem_long_put (&pSync[0], &is_ready, 1, child_r);
                no_children = 2;
            }

            shmem_long_wait_until (&pSync[1], SHMEM_CMP_EQ,
                                   (long) no_children);
            pSync[1] = SHMEM_SYNC_VALUE;

        }
        else {
            shmem_long_wait_until (&pSync[0], SHMEM_CMP_EQ, is_ready);

            shmemi_trace (SHMEM_LOG_BARRIER, "inside else");

            if (child_l != -1) {
                shmem_long_get (&lchild_ready, &pSync[0], 1, child_l);
                while (lchild_ready != 0)
                    shmem_long_get (&lchild_ready, &pSync[0], 1, child_l);
                shmem_long_put (&pSync[0], &is_ready, 1, child_l);
                no_children = 1;
            }

            if (child_r != -1) {
                shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);
                while (rchild_ready != 0)
                    shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);
                shmem_long_put (&pSync[0], &is_ready, 1, child_r);
                no_children = 2;
            }
            pSync[0] = SHMEM_SYNC_VALUE;

            if (no_children == 0) {
                pSync[1] = SHMEM_SYNC_VALUE;
                shmem_long_inc (&pSync[1], parent);
            }
            else {
                shmem_long_wait_until (&pSync[1], SHMEM_CMP_EQ,
                                       (long) no_children);
                pSync[1] = SHMEM_SYNC_VALUE;
                shmem_long_inc (&pSync[1], parent);
            }

        }
        shmemi_trace (SHMEM_LOG_BARRIER, "at the end of barrier");

    }
}
Example #22
0
/*
 * scan the ELF image to build table of global symbold and the image
 * regions where they can be found (BSS and DATA)
 */
static inline int
table_init_helper (void)
{
    Elf *e = NULL;
    GElf_Ehdr ehdr;
    char *shstr_name = NULL;
    size_t shstrndx;
    Elf_Scn *scn = NULL;
    GElf_Shdr shdr;
    int ret = -1;
#if 0
    int (*getsi) ();            /* look up name of elf_get... routine */
#endif

    /* unrecognized format */
    if (elf_version (EV_CURRENT) == EV_NONE) {
        goto bail;
    }

    /* get the ELF object from already opened state */
    e = elf_begin (GET_STATE (exe_fd), ELF_C_READ, NULL);
    if (e == NULL) {
        goto bail;
    }

    /* do some sanity checks */
    if (elf_kind (e) != ELF_K_ELF) {
        goto bail;
    }
    if (gelf_getehdr (e, &ehdr) == NULL) {
        goto bail;
    }
    if (gelf_getclass (e) == ELFCLASSNONE) {
        goto bail;
    }

    /*
     * There are various elf_get* routines with different return values
     * in differnt libraries/versions - name of routine does not tell us
     * all we ned to know.  So let it go here, and we'll mop up any
     * problems later on.
     */

    /*
     * This routine is either "elf_getshdrstrndx" in newer ELF
     * libraries, or "elf_getshstrndx" in older ones.  Hard-code older
     * one for now since it is in the newer libraries, although marked as
     * deprecated.  This will be detected by autoconf later
     *
     * DEPRECATED
     */
    (void) elf_getshstrndx (e, &shstrndx);

    /* walk sections, look for RO/BSS/DATA and symbol table */
    scn = NULL;

    while ((scn = elf_nextscn (e, scn)) != NULL) {

        if (gelf_getshdr (scn, &shdr) != &shdr) {
            goto bail;
        }
        shstr_name = elf_strptr (e, shstrndx, shdr.sh_name);
        if (shstr_name == NULL) {
            goto bail;
        }

        /* found the read-only data */
        if (shdr.sh_type == SHT_PROGBITS && strcmp (shstr_name, ".rodata") == 0) {

            elfro.start = shdr.sh_addr;
            elfro.end = elfro.start + shdr.sh_size;

            shmemi_trace (SHMEM_LOG_SYMBOLS,
                          "ELF section .rodata for global variables = 0x%lX -> 0x%lX",
                          elfro.start, elfro.end);
            continue;           /* move to next scan */
        }

        /* found the uninitialized globals */
        if (shdr.sh_type == SHT_NOBITS && strcmp (shstr_name, ".bss") == 0) {

            elfbss.start = shdr.sh_addr;
            elfbss.end = elfbss.start + shdr.sh_size;

            shmemi_trace (SHMEM_LOG_SYMBOLS,
                          "ELF section .bss for global variables = 0x%lX -> 0x%lX",
                          elfbss.start, elfbss.end);
            continue;           /* move to next scan */
        }

        /* found the initialized globals */
        if (shdr.sh_type == SHT_PROGBITS && strcmp (shstr_name, ".data") == 0) {

            elfdata.start = shdr.sh_addr;
            elfdata.end = elfdata.start + shdr.sh_size;

            shmemi_trace (SHMEM_LOG_SYMBOLS,
                          "ELF section .data for global variables = 0x%lX -> 0x%lX",
                          elfdata.start, elfdata.end);
            continue;           /* move to next scan */
        }

        /* keep looking until we find the symbol table */
        if (shdr.sh_type == SHT_SYMTAB) {
            Elf_Data *data = NULL;
            while ((data = elf_getdata (scn, data)) != NULL) {
                GElf_Sym *es;
                GElf_Sym *last_es;

                es = (GElf_Sym *) data->d_buf;
                if (es == NULL) {
                    continue;
                }

                /* find out how many entries to look for */
                last_es = (GElf_Sym *) ((char *) data->d_buf + data->d_size);

                for (; es < last_es; es += 1) {
                    char *name;

                    /*
                     * need visible global or local (Fortran save) object with
                     * some kind of content
                     */
                    if (es->st_value == 0 || es->st_size == 0) {
                        continue;
                    }
                    /*
                     * this macro handles a symbol that is present
                     * in one libelf implementation but isn't in another
                     * (elfutils vs. libelf)
                     */
#ifndef GELF_ST_VISIBILITY
#define GELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o)
#endif
                    if (GELF_ST_TYPE (es->st_info) != STT_OBJECT &&
                        GELF_ST_VISIBILITY (es->st_info) != STV_DEFAULT) {
                        continue;
                    }
                    name = elf_strptr (e, shdr.sh_link, (size_t) es->st_name);
                    if (name == NULL || *name == '\0') {
                        continue;
                    }
                    /* put the symbol and info into the symbol hash table */
                    {
                        globalvar_t *gv = (globalvar_t *) malloc (sizeof (*gv));
                        if (gv == NULL) {
                            goto bail;
                        }
                        gv->name = strdup (name);
                        if (gv->name == NULL) {
                            free (gv);
                            goto bail;
                        }
                        gv->addr = (void *) es->st_value;
                        gv->size = es->st_size;
                        HASH_ADD_PTR (gvp, addr, gv);
                    }
                }
            }
            /*
             * pulled out all the global symbols => success,
             * don't need to scan further
             */
            ret = 0;
            break;
        }
    }

  bail:

    if (elf_end (e) != 0) {
        ret = -1;
    }

    return ret;
}
Example #23
0
void
shmemi_broadcast32_tree (void *target, const void *source,
                         size_t nlong,
                         int PE_root, int PE_start,
                         int logPE_stride, int PE_size, long *pSync)
{
    int child_l, child_r, parent;
    const int step = 1 << logPE_stride;
    int my_pe = GET_STATE (mype);
    int *target_ptr, *source_ptr;
    int no_children;
    long is_ready, lchild_ready, rchild_ready;


    is_ready = 1;
    lchild_ready = -1;
    rchild_ready = -1;

    shmem_long_wait_until (&pSync[0], SHMEM_CMP_EQ, SHMEM_SYNC_VALUE);
    shmem_long_wait_until (&pSync[1], SHMEM_CMP_EQ, SHMEM_SYNC_VALUE);

    pSync[0] = 0;
    pSync[1] = 0;

    target_ptr = (int *) target;
    source_ptr = (int *) source;

    set_2tree (PE_start, step, PE_size, &parent, &child_l, &child_r, my_pe);
    no_children = 0;
    build_tree (PE_start, step, PE_root, PE_size,
                &parent, &child_l, &child_r, my_pe);
    shmemi_trace (SHMEM_LOG_BROADCAST,
                  "before broadcast, R_child = %d L_child = %d",
                  child_r, child_l);
    /* The actual broadcast */

    if (PE_size > 1) {
        if (my_pe == (PE_start + step * PE_root)) {
            pSync[0] = SHMEM_SYNC_VALUE;

            if (child_l != -1) {
                shmem_long_get (&lchild_ready, (const long *) &pSync[0],
                                1, child_l);
                while (lchild_ready != 0)
                    shmem_long_get (&lchild_ready, &pSync[0], 1, child_l);

                shmem_int_put (target_ptr, source_ptr, nlong, child_l);
                shmem_fence ();
                shmem_long_put (&pSync[0], &is_ready, 1, child_l);
                no_children = 1;
            }
            if (child_r != -1) {
                shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);
                while (rchild_ready != 0)
                    shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);

                shmem_int_put (target_ptr, source_ptr, nlong, child_r);
                shmem_fence ();
                shmem_long_put (&pSync[0], &is_ready, 1, child_r);
                no_children = 2;
            }

            shmem_long_wait_until (&pSync[1], SHMEM_CMP_EQ,
                                   (long) no_children);
            pSync[1] = SHMEM_SYNC_VALUE;

        }
        else {
            shmem_long_wait_until (&pSync[0], SHMEM_CMP_EQ, is_ready);
            pSync[0] = SHMEM_SYNC_VALUE;
            shmemi_trace (SHMEM_LOG_BROADCAST, "inside else");
            memcpy (source_ptr, target_ptr, nlong * sizeof (int));
            if (child_l != -1) {
                shmem_long_get (&lchild_ready, &pSync[0], 1, child_l);
                while (lchild_ready != 0)
                    shmem_long_get (&lchild_ready, &pSync[0], 1, child_l);

                shmem_int_put (target_ptr, source_ptr, nlong, child_l);
                shmem_fence ();
                shmem_long_put (&pSync[0], &is_ready, 1, child_l);
                no_children = 1;
            }
            if (child_r != -1) {
                shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);
                while (rchild_ready != 0)
                    shmem_long_get (&rchild_ready, &pSync[0], 1, child_r);

                shmem_int_put (target_ptr, source_ptr, nlong, child_r);
                shmem_fence ();
                shmem_long_put (&pSync[0], &is_ready, 1, child_r);
                no_children = 2;
            }
            pSync[0] = SHMEM_SYNC_VALUE;

            if (no_children == 0) {
                pSync[1] = SHMEM_SYNC_VALUE;
                /* TO DO: Is check for parents pSync required? */
                shmem_long_inc (&pSync[1], parent);
            }
            else {
                shmem_long_wait_until (&pSync[1], SHMEM_CMP_EQ,
                                       (long) no_children);
                pSync[1] = SHMEM_SYNC_VALUE;
                /* printf("PE %d incrementing child count on PE
                   %d\n",my_pe,parent); */
                shmem_long_inc (&pSync[1], parent);
            }
        }
        shmemi_trace (SHMEM_LOG_BROADCAST, "at the end of bcast32");
        /* shmem_barrier(PE_start, logPE_stride, PE_size, pSync); */
    }
}