Пример #1
0
/* communicate an object to all other processors */
int COMOBJALL (MPI_Comm comm,
	       OBJ_Pack pack,
	       void *data,
	       OBJ_Unpack unpack,
	       void *object,
	       COMOBJ **recv, int *nrecv) /* recv is contiguous => free (*recv) releases all memory */
{
  COMOBJ *send_data;
  int i, j, rank, ncpu, ret;

  if (object)
  {
    MPI_Comm_rank (comm, &rank);
    MPI_Comm_size (comm, &ncpu);

    ERRMEM (send_data = MEM_CALLOC ((ncpu - 1) * sizeof (COMOBJ)));

    for (i = j = 0; i < ncpu; i ++)
    {
      if (i != rank)
      {
	send_data [j].rank = i;
	send_data [j].o = object;
	j ++;
      }
    }

    ret = COMOBJSALL (comm, pack, data, unpack, send_data, ncpu - 1, recv, nrecv);

    free (send_data);
  }
  else ret = COMOBJSALL (comm, pack, data, unpack, NULL, 0, recv, nrecv);

  return ret;
}
Пример #2
0
/* recursive create */
static KDT* create (KDT *u, int n, double **q)
{
  KDT *kd;
  int k;

  ERRMEM (kd = MEM_CALLOC (sizeof (KDT)));
  kd->u = u;

  if (n == 0)
  {
    kd->d = -1; /* leaf */
    return kd;
  }

  k = split (n, q, kd->p, &kd->d);

  if (k == -1) /* coincident points */
  {
    kd->l = create (kd, 0, NULL);
    kd->r = create (kd, 0, NULL);
  }
  else
  {
    kd->l = create (kd, k, q); /* ends at q [k-1] */
    kd->r = create (kd, n-k-1, q+k+1); /* starts at q [k+1] */
  }

  return kd;
}
Пример #3
0
/*******************************************************************************
 *
 * Render backend context functions.
 *
 ******************************************************************************/
int
rb_create_context
  (struct mem_allocator* specific_allocator,
   struct rb_context** out_ctxt)
{
  struct mem_allocator* allocator = NULL;
  struct rb_context* ctxt = NULL;
  int err = 0;

  if(!out_ctxt)
    goto error;

  allocator = specific_allocator ? specific_allocator : &mem_default_allocator;
  ctxt = MEM_CALLOC(allocator, 1, sizeof(struct rb_context));
  if(!ctxt)
    goto error;
  ctxt->allocator = allocator;
  ref_init(&ctxt->ref);

  setup_config(&ctxt->config);

exit:
  if(ctxt)
    *out_ctxt = ctxt;
  return err;

error:
  if(ctxt) {
    RB(context_ref_put(ctxt));
    ctxt = NULL;
  }
  err = -1;
  goto exit;
}
Пример #4
0
/* unpack sphere from double and integer buffers (unpacking starts at dpos and ipos in
 * d and i and no more than a specific number of doubles and ints can be red) */
SPHERE* SPHERE_Unpack (void *solfec, int *dpos, double *d, int doubles, int *ipos, int *i, int ints)
{
  SPHERE *sph;
  int j;

  ERRMEM (sph = MEM_CALLOC (sizeof (SPHERE)));

  sph->surface = unpack_int (ipos, i, ints);
  sph->volume = unpack_int (ipos, i, ints);

  unpack_doubles (dpos, d, doubles, sph->cur_center, 3);
  unpack_doubles (dpos, d, doubles, (double*)sph->cur_point, 9);
  sph->cur_radius = unpack_double  (dpos, d, doubles);

  unpack_doubles (dpos, d, doubles, sph->ref_center, 3);
  unpack_doubles (dpos, d, doubles, (double*)sph->ref_point, 9);
  sph->ref_radius = unpack_double  (dpos, d, doubles);

  j = unpack_int (ipos, i, ints); /* unpack material existence flag */

  if (j)
  {
    SOLFEC *sol = solfec;
    char *label = unpack_string (ipos, i, ints);
    ASSERT_DEBUG_EXT (sph->mat = MATSET_Find (sol->mat, label), "Failed to find material when unpacking a sphere");
    free (label);
  }

  return sph;
}
Пример #5
0
/* communicate one set of integers and doubles to all other processors */
int COMONEALL (MPI_Comm comm, COMDATA send,
	       COMDATA **recv, int *nrecv) /* recv is contiguous => free (*recv) releases all memory */
{
  COMDATA *send_data;
  int i, j, rank, ncpu, ret;

  MPI_Comm_rank (comm, &rank);
  MPI_Comm_size (comm, &ncpu);

  ERRMEM (send_data = MEM_CALLOC ((ncpu - 1) * sizeof (COMDATA)));

  for (i = 0; i < ncpu; i ++)
  {
    if (i != rank)
    {
      send_data [j] = send;
      send_data [j].rank = i;
      j ++;
    }
  }

  ret = COMALL (comm, send_data, ncpu - 1, recv, nrecv);

  free (send_data);

  return ret;
}
Пример #6
0
/* unpack ellipsoid from double and integer buffers (unpacking starts at dpos and ipos in
 * d and i and no more than a specific number of doubles and ints can be red) */
ELLIP* ELLIP_Unpack (void *solfec, int *dpos, double *d, int doubles, int *ipos, int *i, int ints)
{
  ELLIP *eli;
  int j;

  ERRMEM (eli = MEM_CALLOC (sizeof (ELLIP)));

  eli->surface = unpack_int (ipos, i, ints);
  eli->volume = unpack_int (ipos, i, ints);

  unpack_doubles (dpos, d, doubles, eli->cur_center, 3);
  unpack_doubles (dpos, d, doubles, (double*)eli->cur_point, 9);

  unpack_doubles (dpos, d, doubles, eli->ref_center, 3);
  unpack_doubles (dpos, d, doubles, (double*)eli->ref_point, 9);

  unpack_doubles (dpos, d, doubles, eli->ref_sca, 3);
  unpack_doubles (dpos, d, doubles, eli->ref_rot, 9);

  unpack_doubles (dpos, d, doubles, eli->cur_sca, 3);
  unpack_doubles (dpos, d, doubles, eli->cur_rot, 9);

  j = unpack_int (ipos, i, ints); /* unpack material existence flag */

  if (j)
  {
    SOLFEC *sol = solfec;
    char *label = unpack_string (ipos, i, ints);
    ASSERT_DEBUG_EXT (eli->mat = MATSET_Find (sol->mat, label), "Failed to find material when unpacking a eliere");
    free (label);
  }

  return eli;
}
Пример #7
0
/*******************************************************************************
 *
 * Picking functions
 *
 ******************************************************************************/
enum edit_error
edit_create_picking
  (struct app* app,
   struct edit_imgui* imgui,
   struct edit_model_instance_selection* instance_selection,
   struct mem_allocator* allocator,
   struct edit_picking** out_picking)
{
  struct edit_picking* picking = NULL;
  enum edit_error edit_err = EDIT_NO_ERROR;
  enum sl_error sl_err = SL_NO_ERROR;

  if(UNLIKELY(!app || !instance_selection || !allocator || !out_picking)) {
    edit_err = EDIT_INVALID_ARGUMENT;
    goto error;
  }

  picking = MEM_CALLOC(allocator, 1, sizeof(struct edit_picking));
  if(!picking) {
    edit_err = EDIT_MEMORY_ERROR;
    goto error;
  }
  ref_init(&picking->ref);
  APP(ref_get(app));
  picking->app = app;
  EDIT(imgui_ref_get(imgui));
  picking->imgui = imgui;
  EDIT(model_instance_selection_ref_get(instance_selection));
  picking->instance_selection = instance_selection;
  picking->allocator = allocator;

  sl_err = sl_create_hash_table
    (sizeof(uint32_t),
     ALIGNOF(uint32_t),
     sizeof(uint32_t),
     ALIGNOF(uint32_t),
     hash_uint32,
     eq_uint32,
     allocator,
     &picking->picked_instances_htbl);
  if(sl_err != SL_NO_ERROR) {
    edit_err = sl_to_edit_error(sl_err);
    goto error;
  }

exit:
  if(out_picking)
    *out_picking = picking;
  return edit_err;
error:
  if(picking) {
    EDIT(picking_ref_put(picking));
    picking = NULL;
  }
  goto exit;
}
Пример #8
0
/*******************************************************************************
 *
 * Flat map functions.
 *
 ******************************************************************************/
EXPORT_SYM enum sl_error
sl_create_flat_map
  (size_t key_size,
   size_t key_alignment,
   size_t data_size,
   size_t data_alignment,
   int (*cmp_key)(const void*, const void*),
   struct mem_allocator* specific_allocator,
   struct sl_flat_map** out_map)
{
  struct mem_allocator* allocator = NULL;
  struct sl_flat_map* map = NULL;
  enum sl_error err = SL_NO_ERROR;

  if(!data_size
  || !key_size
  || !cmp_key
  || !out_map) {
    err = SL_INVALID_ARGUMENT;
    goto error;
  }
  if(!SL_IS_POWER_OF_2(data_alignment) || !SL_IS_POWER_OF_2(key_alignment)) {
    err = SL_ALIGNMENT_ERROR;
    goto error;
  }
  allocator = specific_allocator ? specific_allocator : &mem_default_allocator;
  map = MEM_CALLOC(allocator, 1, sizeof(struct sl_flat_map));
  if(map == NULL) {
    err = SL_MEMORY_ERROR;
    goto error;
  }
  err = sl_create_flat_set
    (key_size, key_alignment, cmp_key, allocator, &map->key_set);
  if(err != SL_NO_ERROR)
    goto error;
  err = sl_create_vector(data_size, data_alignment, allocator, &map->data_list);
  if(err != SL_NO_ERROR)
    goto error;
  map->allocator = allocator;

exit:
  if(out_map)
    *out_map = map;
  return err;
error:
  if(map) {
    if(map->key_set)
      SL(free_flat_set(map->key_set));
    if(map->data_list)
      SL(free_vector(map->data_list));
    MEM_FREE(allocator, map);
    map = NULL;
  }
  goto exit;
}
Пример #9
0
static SHAPE* psc_read_shape (FILE *f)
{
  SHAPE *shp;

  ERRMEM (shp = MEM_CALLOC (sizeof (SHAPE)));

  shp->kind = SHAPE_MESH;
  shp->data = psc_read_mesh (f);

  return shp;
}
Пример #10
0
/* levels: number of skip levels
 * compare: item key comparison (NULL implies pointer comparison)
 * return: skip list or NULL when out of memory;
 * create skip list */
LIST* LIST_Create (int levels, LIST_Compare compare)
{
  LIST *list;

  if (!(list = malloc (sizeof (LIST)))) return NULL;
  MEM_Init (&list->mem, sizeof (ITEM) + levels * sizeof (ITEM*), CHUNK);
  list->maxlevel = levels - 1;
  list->level = 0;
  list->size = 0;

  if (!(list->header.forward = MEM_CALLOC (levels * sizeof (ITEM*)))) return NULL;
  if (!(list->update = malloc (levels * sizeof (ITEM*)))) return NULL;

  list->compare = compare;

  return list;
}
Пример #11
0
static MX* psc_read_matrix (FILE *f)
{
  MX *a;

  ERRMEM (a = MEM_CALLOC (sizeof (MX)));

  fread (&a->kind, sizeof (a->kind), 1, f);
  fread (&a->flags, sizeof (a->flags), 1, f);

  fread (&a->nzmax, sizeof (int), 1, f);
  fread (&a->m, sizeof (int), 1, f);
  fread (&a->n, sizeof (int), 1, f);
  fread (&a->nz, sizeof (int), 1, f);

  switch (a->kind)
  {
  case MXDENSE:
  {
    ERRMEM (a->x = malloc (a->nzmax * sizeof (double)));
    fread (a->x, sizeof (double), a->nzmax, f);
  }
  break;
  case MXBD:
  {
    ERRMEM (a->p = malloc ((a->n+1) * sizeof (int)));
    ERRMEM (a->i = malloc ((a->n+1) * sizeof (int)));
    ERRMEM (a->x = malloc (a->nzmax * sizeof (double)));
    fread (a->p, sizeof (int), a->n + 1, f);
    fread (a->i, sizeof (int), a->n + 1, f);
    fread (a->x, sizeof (double), a->nzmax, f);
  }
  break;
  case MXCSC:
  {
    ERRMEM (a->p = malloc ((a->n+1) * sizeof (int)));
    ERRMEM (a->i = malloc (a->nzmax * sizeof (int)));
    ERRMEM (a->x = malloc (a->nzmax * sizeof (double)));
    fread (a->p, sizeof (int), a->n + 1, f);
    fread (a->i, sizeof (int), a->nzmax, f);
    fread (a->x, sizeof (double), a->nzmax, f);
  }
  break;
  }

  return a;
}
Пример #12
0
/*******************************************************************************
 *
 * Implementation of the vector container.
 *
 ******************************************************************************/
EXPORT_SYM enum sl_error
sl_create_vector
  (size_t data_size,
   size_t data_alignment,
   struct mem_allocator* specific_allocator,
   struct sl_vector** out_vec)
{
  struct mem_allocator* allocator = NULL;
  struct sl_vector* vec = NULL;
  enum sl_error err = SL_NO_ERROR;

  if(!out_vec || !data_size) {
    err = SL_INVALID_ARGUMENT;
    goto error;
  }
  if(!IS_POWER_OF_2(data_alignment)) {
    err = SL_ALIGNMENT_ERROR;
    goto error;
  }
  allocator = specific_allocator ? specific_allocator : &mem_default_allocator;
  vec = MEM_CALLOC(allocator, 1, sizeof(struct sl_vector));
  if(vec == NULL) {
    err = SL_MEMORY_ERROR;
    goto error;
  }
  vec->allocator = allocator;
  vec->data_size = data_size;
  vec->data_alignment = data_alignment;

exit:
  if(out_vec)
    *out_vec = vec;
  return err;

error:
  if(vec) {
    ASSERT(allocator);
    MEM_FREE(allocator, vec);
    vec = NULL;
  }
  goto exit;
}
Пример #13
0
hid_t dat1Reopen( hid_t file_id, unsigned int flags, hid_t fapl,
                  int *status ){

/* Local Variables; */
   HDSLoc **loc;
   HDSLoc **loclist;
   char **paths;
   char file[EMS__SZMSG+1];
   char path[EMS__SZMSG+1];
   hid_t *file_ids;
   hid_t id;
   int *isgroup;
   int iloc;
   int nlev;
   int nloc;
   ssize_t size;

/* Return immediately if an error has already occurred. */
   if( *status != SAI__OK ) return file_id;

/* Get a list of any active locators associated with the file. Also get a
   list of file_ids for the same file that have associated locators. */
   hds1GetLocators( file_id, &nloc, &loclist, &file_ids, status );

/* Check that none of the locators are mapped. */
   if( *status == SAI__OK ) {
      loc = loclist;
      for( iloc = 0; iloc < nloc; iloc++,loc++ ) {
         if( (*loc)->regpntr ) {
            hdsTrace( (*loc), &nlev, path, file, status, sizeof(path), sizeof(file) );
            *status = DAT__PRMAP;
            emsRepf( " ", "hdsOpen: Cannot re-open '%s' in read-write mode "
                     "since '%s' is currently mapped.", status, file, path );
            break;
         }
      }
   }

/* Store the path to the HDF5 object associated with each active locator,
   and also a flag indicating if the HDF5 object is a group or dataset.
   Then close the HDF5 objects. */
   paths = MEM_CALLOC( nloc, sizeof( *paths ) );
   isgroup = MEM_CALLOC( nloc, sizeof( *isgroup ) );
   if( paths && isgroup && *status == SAI__OK ) {
      loc = loclist;
      for( iloc = 0; iloc < nloc; iloc++,loc++ ) {
         if( (*loc)->group_id ) {
            isgroup[ iloc ] = 1;
            id = (*loc)->group_id;
         } else {
            isgroup[ iloc ] = 0;
            id = (*loc)->dataset_id;
         }
         if( id ) {
            size = H5Iget_name( id, NULL, 0 );
            paths[ iloc ] = MEM_CALLOC( size + 1, 1 );
            H5Iget_name( id, paths[ iloc ], size + 1 );
         } else {
            hdsTrace( (*loc), &nlev, path, file, status, sizeof(path), sizeof(file) );
            *status = DAT__FATAL;
            emsRepf( " ", "hdsOpen: Locator for '%s.%s' has no group or "
                     "dataset so cannot be reopened.", status, file, path );
            break;
         }
         if( H5Oclose( id ) < 0 ) {
            hdsTrace( (*loc), &nlev, path, file, status, sizeof(path), sizeof(file) );
            *status = DAT__FATAL;
            dat1H5EtoEMS( status );
            emsRepf( " ", "hdsOpen: Failed to close HDF5 object for '%s.%s'.",
                     status, file, path );
            break;
         }
      }
   }

/* Get the path for the file. */
   H5Fget_name( file_id, path, sizeof(path) );

/* Close all HDF5 file_ids associated with file. */
   if( *status == SAI__OK ) {
      int this_closed = 0;

      int i = -1;
      while( file_ids[ ++i ] ) {

         if( file_ids[ i ] == file_id ) this_closed = 1;

         if( H5Fclose( file_ids[ i ] ) < 0 ) {
            *status = DAT__FATAL;
            dat1H5EtoEMS( status );
            emsRepf( " ", "hdsOpen: Failed to close file '%s' prior to "
                     "re-opening it.", status, path );
            break;
         }
      }

/* Close the supplied file_id if it has not already been closed. */
      if( !this_closed ) {
         if( H5Fclose( file_id ) < 0 ) {
            *status = DAT__FATAL;
            dat1H5EtoEMS( status );
            emsRepf( " ", "hdsOpen: Failed to close file '%s' prior to "
                     "re-opening it.", status, path );
         }
      }
   }

/* Re-open it. */
   if( *status == SAI__OK ) {
      file_id = H5Fopen( path, flags, fapl );
      if( file_id < 0 ) {
         *status = DAT__FATAL;
         dat1H5EtoEMS( status );
         emsRepf( " ", "hdsOpen: Failed to reopen file '%s'.",
                  status, path );
      }
   }

/* Update the file, group and dataset id in each locator. */
   if( *status == SAI__OK ) {
      loc = loclist;
      for( iloc = 0; iloc < nloc; iloc++,loc++ ) {
         hds1SetFileId( (*loc), file_id, status );
         if( isgroup[ iloc ] ) {
            (*loc)->group_id = H5Gopen2( file_id, paths[ iloc ], H5P_DEFAULT );
         } else {
            (*loc)->dataset_id = H5Dopen2( file_id, paths[ iloc ], H5P_DEFAULT );
         }
      }
   }

/* Free resources. */
   if( paths ) {
      for( iloc = 0; iloc < nloc; iloc++ ) {
         MEM_FREE( paths[ iloc ] );
      }
      MEM_FREE( paths );
   }
   if( isgroup ) MEM_FREE( isgroup );
   if( loclist ) MEM_FREE( loclist );
   if( file_ids ) MEM_FREE( file_ids );

/* Return the new file id. */
   return file_id;
}
Пример #14
0
static MESH* psc_read_mesh (FILE *f)
{
  ELEMENT *ele, **tab, *tail;
  MESH *msh;
  int i, j;

  ERRMEM (msh = MEM_CALLOC (sizeof (MESH)));
  MEM_Init (&msh->elemem, sizeof (ELEMENT), 128);
  MEM_Init (&msh->facmem, sizeof (FACE), 128);
  MEM_Init (&msh->mapmem, sizeof (MAP), 128);

  fread (&msh->nodes_count, sizeof (int), 1, f);

  ERRMEM (msh->ref_nodes = malloc (2 * msh->nodes_count * sizeof (double [3])));
  msh->cur_nodes = msh->ref_nodes + msh->nodes_count;

  fread (msh->ref_nodes, sizeof (double [3]), msh->nodes_count, f);
  fread (msh->cur_nodes, sizeof (double [3]), msh->nodes_count, f);

  fread (&msh->surfeles_count, sizeof (int), 1, f);
  fread (&msh->bulkeles_count, sizeof (int), 1, f);

  ERRMEM (tab = malloc ((msh->surfeles_count + msh->bulkeles_count) * sizeof (ELEMENT*)));

  for (i = 0, tail = NULL; i < msh->surfeles_count; i ++)
  {
    ele = psc_read_element (&msh->elemem, &msh->facmem, f);
    ele->flag = i;

    if (tail) ele->prev = tail, tail->next = ele;
    else msh->surfeles = ele;
    tail = ele;
    tab [i] = ele;
  }

  for (tail = NULL; i < msh->surfeles_count + msh->bulkeles_count; i ++)
  {
    ele = psc_read_element (&msh->elemem, &msh->facmem, f);
    ele->flag = i;

    if (tail) ele->prev = tail, tail->next = ele;
    else msh->bulkeles = ele;
    tail = ele;
    tab [i] = ele;
  }

  for (i = 0; i < msh->surfeles_count + msh->bulkeles_count; i ++)
  {
    ele = tab [i];

    for (j = 0; j < ele->neighs; j ++)
    {
      int idx = (long) (void*) ele->adj[j];
      ASSERT_TEXT (idx >= 0 && idx < msh->surfeles_count + msh->bulkeles_count, "INCONSITENT ELEMENT INDEXING");
      ele->adj[j] = tab [idx];
    }
  }

  free (tab);

  return msh;
}
Пример #15
0
int
main(int argc, char** argv)
{
  /* Check command arguments */
  if(argc != 3) {
    printf("usage: %s RB_DRIVER FONT\n", argv[0]);
    return -1;
  }
  const char* driver_name = argv[1];
  const char* font_name = argv[2];

  FILE* file = fopen(driver_name, "r");
  if(!file) {
    fprintf(stderr, "Invalid driver %s\n", driver_name);
    return -1;
  }
  fclose(file);

  file = fopen(font_name, "r");
  if(!file) {
    fprintf(stderr, "Invalid font name %s\n", font_name);
    return -1;
  }
  fclose(file);

  /* Spawn a drawable windows */
  struct wm_device* device = NULL;
  struct wm_window* window = NULL;
  const struct wm_window_desc win_desc =
    { .width = 640, .height = 480, .fullscreen = false };
  WM(create_device(NULL, &device));
  WM(create_window(device, &win_desc, &window));

  /* Create a render backend */
  struct rbi rbi;
  struct rb_context* rb_ctxt = NULL;
  CHECK(rbi_init(driver_name, &rbi), 0);
  RBI(&rbi, create_context(NULL, &rb_ctxt));

  /* Load font resource */
  struct font_system* font_sys = NULL;
  struct font_rsrc* font_rsrc = NULL;
  bool is_font_scalable = false;
  int line_space = 0;
  FONT(system_create(NULL, &font_sys));
  FONT(rsrc_create(font_sys, font_name, &font_rsrc));
  FONT(rsrc_get_line_space(font_rsrc, &line_space));
  FONT(rsrc_is_scalable(font_rsrc, &is_font_scalable));
  if(is_font_scalable) {
    FONT(rsrc_set_size(font_rsrc, 24, 24));
  }

  /* Build x charset description */
  int glyph_min_width = INT_MAX;
  const wchar_t* charset =
    L"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    L" &~\"#'{([-|`_\\^@)]=}+$%*,?;.:/!<>";
  const size_t charset_len = wcslen(charset);
  size_t i = 0;
  struct lp_font_glyph_desc lp_font_glyph_desc_list[512];
  unsigned char* glyph_bitmap_list[512];
  ASSERT(charset_len <= 512);

  for(i = 0; i < charset_len; ++i) {
    struct font_glyph_desc font_glyph_desc;
    struct font_glyph* font_glyph = NULL;
    int width = 0;
    int height = 0;
    int Bpp = 0;

    FONT(rsrc_get_glyph(font_rsrc, charset[i], &font_glyph));

    FONT(glyph_get_desc(font_glyph, &font_glyph_desc));
    glyph_min_width = MIN(font_glyph_desc.width, glyph_min_width);
    lp_font_glyph_desc_list[i].width = font_glyph_desc.width;
    lp_font_glyph_desc_list[i].character = font_glyph_desc.character;
    lp_font_glyph_desc_list[i].bitmap_left = font_glyph_desc.bbox.x_min;
    lp_font_glyph_desc_list[i].bitmap_top = font_glyph_desc.bbox.y_min;

    FONT(glyph_get_bitmap(font_glyph, true, &width, &height, &Bpp, NULL));
    if(width && height ) {
      glyph_bitmap_list[i] = MEM_CALLOC
        (&mem_default_allocator, (size_t)(width*height), (size_t)Bpp);
      NCHECK(glyph_bitmap_list[i], NULL);
      FONT(glyph_get_bitmap
        (font_glyph, true, &width, &height, &Bpp, glyph_bitmap_list[i]));
    }

    lp_font_glyph_desc_list[i].bitmap.width = width;
    lp_font_glyph_desc_list[i].bitmap.height = height;
    lp_font_glyph_desc_list[i].bitmap.bytes_per_pixel = Bpp;
    lp_font_glyph_desc_list[i].bitmap.buffer = glyph_bitmap_list[i];

    FONT(glyph_ref_put(font_glyph));
  }

  /* Create the lp system and font  */
  struct lp* lp = NULL;
  struct lp_font* lp_font = NULL;
  LP(create(&rbi, rb_ctxt, NULL, &lp));
  LP(font_create(lp, &lp_font));
  LP(font_set_data
    (lp_font, line_space, (int)charset_len, lp_font_glyph_desc_list));

  /* Create the printer */
  struct lp_printer* lp_printer = NULL;
  LP(printer_create(lp, &lp_printer));
  LP(printer_set_font(lp_printer, lp_font));
  LP(printer_set_viewport(lp_printer, 0, 0, win_desc.width, win_desc.height));
  enum wm_state esc = WM_STATE_UNKNOWN;
  do {
    int cur[2] = { 0, 0 };

    RBI(&rbi, clear
      (rb_ctxt, RB_CLEAR_COLOR_BIT, (float[]){0.05f, 0.05f, 0.05f}, 0.f, 0));
    LP(printer_print_wstring
      (lp_printer, 50, 70, L">$ ",
       (float[]){0.f, 1.f, 0.f}, cur+0, cur+1));
    LP(printer_print_wstring
      (lp_printer, cur[0], cur[1], L"Hello",
       (float[]){1.f, 1.f, 1.f}, cur+0, cur+1));
Пример #16
0
/* read fracture state */
FS* fracture_state_read (BODY *bod)
{
  FS *out = NULL, *item, *instance;
  char path [1024];
  unsigned int id;
  int i, n, dofs;
  double *disp;

#if HDF5
  PBF *f, *g;

  snprintf (path, 1024, "%s/fracture", bod->dom->solfec->outpath);
  g = PBF_Read (path);

  do
  {
    double time;

    PBF_Time (g, &time); /* unused, but could be useful at some point */

    for (f = g; f; f = f->next)
    {
      int numbod;

      PBF_Int2 (f, "numbod", &numbod, 1);

      while (numbod > 0)
      {
	PBF_Uint (f, &id, 1);
	PBF_Int (f, &dofs, 1);
	ERRMEM (disp = malloc (dofs * sizeof (double)));
	PBF_Double (f, disp, dofs);
	PBF_Int (f, &n, 1);
	for (i = 0, instance = NULL; i < n; i ++)
	{
	  ERRMEM (item = MEM_CALLOC (sizeof (FS)));

	  PBF_Double (f, &item->radius, 1);
	  PBF_Double (f, item->point, 3);
	  PBF_Double (f, item->force, 3);

	  if (id == bod->id)
	  {
	    item->inext = instance;
	    instance = item;

	    if (i == (n-1))
	    {
	      item->disp = disp; /* put displacements into first element of instance list */
	      item->next = out;
	      out = item;
	    }
	  }
	  else free (item);
	}

	if (!out || out->disp != disp) free (disp);  /* not used */

	numbod --;
      }
    }
  } while (PBF_Forward (g, 1));

  PBF_Close (g);
#else
  FILE *f;
  XDR x;

  snprintf (path, 1024, "%s/fracture.dat", bod->dom->solfec->outpath);
  f = fopen (path, "r");
  /* TODO: read MPI mode data in case f == NULL but fractureRANK.dat exit */
  if (f)
  {
    xdrstdio_create (&x, f, XDR_DECODE);

    while (! feof (f))
    {
      if (xdr_u_int (&x, &id) == 0) break;
      ASSERT (xdr_int (&x, &dofs), ERR_FILE_READ);
      ERRMEM (disp = malloc (dofs * sizeof (double)));
      ASSERT (xdr_vector (&x, (char*)disp, dofs, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_READ);
      ASSERT (xdr_int (&x, &n), ERR_FILE_READ);
      for (i = 0, instance = NULL; i < n; i ++)
      {
        ERRMEM (item = MEM_CALLOC (sizeof (FS)));

	ASSERT (xdr_double (&x, &item->radius), ERR_FILE_READ);
        ASSERT (xdr_vector (&x, (char*)item->point, 3, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_READ);
        ASSERT (xdr_vector (&x, (char*)item->force, 3, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_READ);

	if (id == bod->id)
	{
	  item->inext = instance;
	  instance = item;

	  if (i == (n-1))
	  {
	    item->disp = disp; /* put displacements into first element of instance list */
	    item->next = out;
	    out = item;
	  }
	}
	else free (item);
      }

      if (!out || out->disp != disp) free (disp);  /* not used */
    }

    xdr_destroy (&x);
    fclose (f);
  }
#endif

  return out;
}
Пример #17
0
Handle *dat1HandleLock( Handle *handle, int oper, int recurs, int rdonly,
                        int *result, int *status ){

/* Local Variables; */
   Handle *child;
   int ichild;
   int top_level;
   pthread_t *locker;
   pthread_t *rlocker;
   int i;
   int j;
   Handle *error_handle = NULL;
   int child_result;

/* initialise */
   *result = 0;

/* Check inherited status. */
   if( *status != SAI__OK ) return error_handle;

/* Validate the supplied Handle */
   if( !dat1ValidateHandle( "dat1HandleLock", handle, status ) ) return error_handle;

/* To avoid deadlocks, we only lock the Handle mutex for top level
   entries to this function. If "oper" is negative, negate it and set a
   flag indicating we do not need to lock the mutex. */
   if( oper < 0 ) {
      oper = -oper;
      top_level = 0;
   } else {
      top_level = 1;
   }

/* For top-level entries to this function, we need to ensure no other thread
   is modifying the details in the handle, so attempt to lock the handle's
   mutex. */
   if( top_level ) pthread_mutex_lock( &(handle->mutex) );

/* Return information about the current lock on the supplied Handle.
   ------------------------------------------------------------------ */
   if( oper == 1 ) {

/* Default: unlocked */

      if( handle->nwrite_lock ) {
         if( pthread_equal( handle->write_locker, pthread_self() )) {

/* Locked for writing by the current thread. */
            *result = 1;
         } else {

/* Locked for writing by another thread. */
            *result = 2;
         }

      } else if( handle->nread_lock ){

/* Locked for reading by one or more other threads (the current thread does
   not have a read lock on the Handle). */
         *result = 4;

/* Now check to see if the current thread has a read lock, changing the
   above result value if it does. */
         locker = handle->read_lockers;
         for( i = 0; i < handle->nread_lock;i++,locker++ ) {
            if( pthread_equal( *locker, pthread_self() )) {

/* Locked for reading by the current thread (other threads may also have
   a read lock on the Handle). */
               *result = 3;
               break;
            }
         }
      }

/* If required, check any child handles. If we already have a status of
   2, (the supplied handle is locked read-write by another thread), we do
   not need to check the children. */
      if( recurs && *result != 2 ){
         for( ichild = 0; ichild < handle->nchild; ichild++ ) {
            child = handle->children[ichild];
            if( child ) {

/* Get the lock status of the child. */
               (void) dat1HandleLock( child, -1, 1, rdonly, &child_result,
                                      status );

/* If it's 2, we can set the final result and exit immediately. */
               if( child_result == 2 ) {
                  *result = 2;
                  break;

/* Otherwise, ensure the child gives the same result as all the others,
   breaking out and returning the catch-all value if not. */
               } else if(  child_result != *result ) {
                  *result = 5;
                  break;
               }
            }
         }
      }





/* Lock the handle for use by the current thread.
   ------------------------------------------------------------------ */
   } else if( oper == 2 ) {

/* A read-only lock requested.... */
      if( rdonly ) {

/* If the current thread has a read-write lock on the Handle, demote it
   to a read-only lock and return 1 (success). In this case, we know
   there will be no other read-locks. Otherwise if any other thread has
   read-write lock, return zero (failure). */
         if( handle->nwrite_lock ) {
            if( pthread_equal( handle->write_locker, pthread_self() )) {

/* If we do not have an array in which to store read lock thread IDs,
   allocate one now with room for NTHREAD locks. It will be extended as
   needed. */
               if( !handle->read_lockers ) {
                  handle->read_lockers = MEM_CALLOC(NTHREAD,sizeof(pthread_t));
                  if( !handle->read_lockers ) {
                     *status = DAT__NOMEM;
                     emsRep( "", "Could not allocate memory for HDS "
                             "Handle read locks list.", status );
                  }
               }

/* If we now have an array, store the current thread in the first element. */
               if( handle->read_lockers ) {
                  handle->read_lockers[ 0 ] = pthread_self();
                  handle->nread_lock = 1;
                  handle->nwrite_lock = 0;
                  *result = 1;
               }
            }

/* If there is no read-write lock on the Handle, add the current thread
   to the list of threads that currently have a read-only lock, but only
   if it is not already there. */
         } else {

/* Set "result" to 1 if the current thread already has a read-only lock. */
            locker = handle->read_lockers;
            for( i = 0; i < handle->nread_lock;i++,locker++ ) {
               if( pthread_equal( *locker, pthread_self() )) {
                  *result = 1;
                  break;
               }
            }

/* If not, extend the read lock thread ID array if necessary, and append
   the current thread ID to the end. */
            if( *result == 0 ) {
               handle->nread_lock++;
               if( handle->maxreaders < handle->nread_lock ) {
                  handle->maxreaders += NTHREAD;
                  handle->read_lockers = MEM_REALLOC( handle->read_lockers,
                                                    handle->maxreaders*sizeof(pthread_t));
                  if( !handle->read_lockers ) {
                     *status = DAT__NOMEM;
                     emsRep( "", "Could not reallocate memory for HDS "
                             "Handle read locks list.", status );
                  }
               }

               if( handle->read_lockers ) {
                  handle->read_lockers[ handle->nread_lock - 1 ] = pthread_self();

/* Indicate the read-only lock was applied successfully. */
                  *result = 1;
               }
            }
         }

/* A read-write lock requested. */
      } else {

/* If there are currently no locks of any kind, apply the lock. */
         if( handle->nread_lock == 0 ) {
            if( handle->nwrite_lock == 0 ) {
               handle->write_locker = pthread_self();
               handle->nwrite_lock = 1;
               *result = 1;

/* If the current thread already has a read-write lock, indicate success. */
            } else if( pthread_equal( handle->write_locker, pthread_self() )) {
               *result = 1;
            }

/* If there is currently only one read-only lock, and it is owned by the
   current thread, then promote it to a read-write lock. */
         } else if( handle->nread_lock == 1 &&
                    pthread_equal( handle->read_lockers[0], pthread_self() )) {
            handle->nread_lock = 0;
            handle->write_locker = pthread_self();
            handle->nwrite_lock = 1;
            *result = 1;
         }
      }

/* If required, and if the above lock operation was successful, lock any
   child handles that can be locked. */
      if( *result ){
         if( recurs ){
            for( ichild = 0; ichild < handle->nchild; ichild++ ) {
               child = handle->children[ichild];
               if( child ) {
                  error_handle = dat1HandleLock( child, -2, 1, rdonly,
                                                 result, status );
                  if( error_handle ) break;
               }
            }
         }

/* If the lock operation failed, return a pointer to the Handle. */
      } else {
         error_handle = handle;
      }




/* Unlock the handle.
   ----------------- */
   } else if( oper == 3 ) {

/* Assume failure. */
      *result = 0;

/* If the current thread has a read-write lock, remove it. */
      if( handle->nwrite_lock ) {
         if( pthread_equal( handle->write_locker, pthread_self() )) {
            handle->nwrite_lock = 0;
            *result = 1;
         } else {
            *result = -1;
         }

/* Otherwise, if the current thread has a read-only lock, remove it. */
      } else {

/* Loop through all the threads that have read-only locks. */
         locker = handle->read_lockers;
         for( i = 0; i < handle->nread_lock; i++,locker++ ) {

/* If the current thread is found, shuffle any remaining threads down one
   slot to fill the gap left by removing the current thread from the list. */
            if( pthread_equal( *locker, pthread_self() )) {
               rlocker = locker + 1;
               for( j = i + 1; j < handle->nread_lock; j++,locker++ ) {
                  *locker = *(rlocker++);
               }

/* Reduce the number of read-only locks. */
               handle->nread_lock--;
               *result = 1;
               break;
            }
         }
      }

/* If required, and if the above unlock operation was successful, unlock any
   child handles that can be unlocked. */
      if( *result == 1 ){
         if( recurs ){
            for( ichild = 0; ichild < handle->nchild; ichild++ ) {
               child = handle->children[ichild];
               if( child ) {
                  error_handle = dat1HandleLock( child, -3, 1, 0,
                                                 result, status );
                  if( error_handle ) break;
               }
            }
         }

/* If the unlock operation failed, return a pointer to the Handle. */
      } else {
         error_handle = handle;
      }




/* Report an error for any other "oper" value. */
   } else if( *status == SAI__OK ) {
      *status = DAT__FATAL;
      emsRepf( " ", "dat1HandleLock: Unknown 'oper' value (%d) supplied - "
               "(internal HDS programming error).", status, oper );
   }

/* If this is a top-level entry, unlock the Handle's mutex so that other
   threads can access the values in the Handle. */
   if( top_level ) pthread_mutex_unlock( &(handle->mutex) );

/* Return the error handle. */
   return error_handle;
}
Пример #18
0
static void
regular_test(struct mem_allocator* allocator)
{
    char dump[BUFSIZ];
    void* p = NULL;
    void* q[3] = {NULL, NULL, NULL};
    size_t i = 0;

    p = MEM_ALIGNED_ALLOC(allocator, 1024, ALIGNOF(char));
    NCHECK(p, NULL);
    CHECK(IS_ALIGNED((uintptr_t)p, ALIGNOF(char)), 1);
    MEM_FREE(allocator, p);

    q[0] = MEM_ALIGNED_ALLOC(allocator, 10, 8);
    q[1] = MEM_CALLOC(allocator, 1, 58);
    q[2] = MEM_ALLOC(allocator, 78);
    NCHECK(q[0], NULL);
    NCHECK(q[1], NULL);
    NCHECK(q[2], NULL);
    CHECK(IS_ALIGNED((uintptr_t)q[0], 8), 1);

    p = MEM_CALLOC(allocator, 2, 2);
    NCHECK(p, NULL);
    for(i = 0; i < 4; ++i)
        CHECK(((char*)p)[i], 0);
    for(i = 0; i < 4; ++i)
        ((char*)p)[i] = (char)i;

    MEM_DUMP(allocator, dump, BUFSIZ);
    printf("dump:\n%s\n", dump);
    MEM_DUMP(allocator, dump, 16);
    printf("truncated dump:\n%s\n", dump);
    MEM_DUMP(allocator, NULL, 0); /* may not crashed. */

    MEM_FREE(allocator, q[1]);

    p = MEM_REALLOC(allocator, p, 8);
    for(i = 0; i < 4; ++i)
        CHECK(((char*)p)[i], (char)i);
    for(i = 4; i < 8; ++i)
        ((char*)p)[i] = (char)i;

    MEM_FREE(allocator, q[2]);

    p = MEM_REALLOC(allocator, p, 5);
    for(i = 0; i < 5; ++i)
        CHECK(((char*)p)[i], (char)i);

    MEM_FREE(allocator, p);

    p = NULL;
    p = MEM_REALLOC(allocator, NULL, 16);
    NCHECK(p, NULL);
    p = MEM_REALLOC(allocator, p, 0);

    MEM_FREE(allocator, q[0]);

    CHECK(MEM_ALIGNED_ALLOC(allocator, 1024, 0), NULL);
    CHECK(MEM_ALIGNED_ALLOC(allocator, 1024, 3), NULL);
    CHECK(MEM_ALLOCATED_SIZE(allocator), 0);
}
Пример #19
0
int
main(int argc, char** argv)
{
  /* Window manager data structures. */
  struct wm_device* dev = NULL;
  struct wm_window* win = NULL;
  const struct wm_window_desc win_desc = { 800, 600, 0 };
  /* Renderer data structure. */
  struct rdr_glyph_desc glyph_desc_list[NB_CHARS];
  struct rdr_font* font = NULL;
  struct rdr_frame* frame = NULL;
  struct rdr_system* sys = NULL;
  struct rdr_term* term = NULL;
  /* Resources data structure. */
  struct rsrc_context* ctxt = NULL;
  struct rsrc_font* rfont = NULL;
  /* Miscellaneous data. */
  const char* driver_name = NULL;
  const char* font_name = NULL;
  size_t line_space = 0;
  size_t i = 0;
  bool b = false;

  if(argc != 3) {
    printf("usage: %s RB_DRIVER FONT\n", argv[0]);
    return -1;
  }
  driver_name = argv[1];
  font_name = argv[2];

  /* Setup the render font. */
  RSRC(create_context(NULL, &ctxt));
  RSRC(create_font(ctxt, font_name, &rfont));
  if(RSRC(is_font_scalable(rfont, &b)), b)
    RSRC(font_size(rfont, 18, 18));

  for(i = 0; i < NB_CHARS; ++i) {
    struct rsrc_glyph* glyph = NULL;
    struct rsrc_glyph_desc glyph_desc;
    size_t width = 0;
    size_t height = 0;
    size_t Bpp = 0;
    size_t size = 0;

    RSRC(font_glyph(rfont, (wchar_t)(i + FIRST_CHAR), &glyph));

    /* Get glyph desc. */
    RSRC(glyph_desc(glyph, &glyph_desc));
    glyph_desc_list[i].width = glyph_desc.width;
    glyph_desc_list[i].character = glyph_desc.character;
    glyph_desc_list[i].bitmap_left = glyph_desc.bbox.x_min;
    glyph_desc_list[i].bitmap_top = glyph_desc.bbox.y_min;

    /* Get glyph bitmap. */
    RSRC(glyph_bitmap(glyph, true, &width, &height, &Bpp, NULL));
    glyph_desc_list[i].bitmap.width = width;
    glyph_desc_list[i].bitmap.height = height;
    glyph_desc_list[i].bitmap.bytes_per_pixel = Bpp;
    glyph_desc_list[i].bitmap.buffer = NULL;
    size = width * height * Bpp;
    if(0 != size) {
      unsigned char* buffer = MEM_CALLOC(&mem_default_allocator, 1, size);
      RSRC(glyph_bitmap(glyph, true, NULL, NULL, NULL, buffer));
      glyph_desc_list[i].bitmap.buffer = buffer;
    }

    RSRC(glyph_ref_put(glyph));
  }

  RSRC(font_line_space(rfont, &line_space));
  RSRC(font_ref_put(rfont));
  RSRC(context_ref_put(ctxt));

  WM(create_device(NULL, &dev));
  WM(create_window(dev, &win_desc, &win));

  RDR(create_system(driver_name, NULL, &sys));
  RDR(create_frame
    (sys, (struct rdr_frame_desc[]){{win_desc.width,win_desc.height}}, &frame));
Пример #20
0
/* communicate integers and doubles using all to all communication */
int COMALL (MPI_Comm comm,
            COMDATA *send, int nsend,
	    COMDATA **recv, int *nrecv) /* recv is contiguous => free (*recv) releases all memory */
{
  COMDATA *cd;
  int rank,
      ncpu,
    (*send_sizes) [3],
     *send_counts,
     *send_disps,
     *send_position,
      send_size,
    (*recv_sizes) [3],
     *recv_counts,
     *recv_disps,
     *recv_position,
      recv_size,
      i, j, k;
  char *send_data,
       *recv_data;
  void *p;

  MPI_Comm_rank (comm, &rank);
  MPI_Comm_size (comm, &ncpu);

  ERRMEM (send_sizes = MEM_CALLOC (ncpu * sizeof (int [3])));
  ERRMEM (send_counts = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (send_disps = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (send_position = MEM_CALLOC (ncpu * sizeof (int)));

  /* compute send sizes */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    send_sizes [cd->rank][0] += cd->ints;
    send_sizes [cd->rank][1] += cd->doubles;
    MPI_Pack_size (cd->ints, MPI_INT, comm, &j);
    MPI_Pack_size (cd->doubles, MPI_DOUBLE, comm, &k);
    send_sizes [cd->rank][2] += (j + k);
  }

  /* compute send displacements */
  for (send_size = i = 0; i < ncpu; i ++)
  {
    send_counts [i] = send_sizes [i][2];
    send_size += send_counts [i];
    if (i < (ncpu - 1)) send_disps [i+1] = send_size;
  }
  send_disps [0] = 0;

  /* allocate send buffer */
  ERRMEM (send_data = malloc (send_size));

  /* pack ints */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    if (cd->ints)
    {
      MPI_Pack (cd->i, cd->ints, MPI_INT, &send_data [send_disps [cd->rank]], send_counts [cd->rank], &send_position [cd->rank], comm);
    }
  }

  /* pack doubles */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    if (cd->doubles)
    {
      MPI_Pack (cd->d, cd->doubles, MPI_DOUBLE, &send_data [send_disps [cd->rank]], send_counts [cd->rank], &send_position [cd->rank], comm); 
    }
  }

#if DEBUG
  for (i = 0; i < ncpu; i ++)
  {
    ASSERT_DEBUG (send_position [i] <= send_counts [i], "Incorrect packing");
  }
#endif

  ERRMEM (recv_sizes = MEM_CALLOC (ncpu * sizeof (int [3])));
  ERRMEM (recv_counts = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (recv_disps = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (recv_position = MEM_CALLOC (ncpu * sizeof (int)));

  /* distribute send sizes into receive sizes */
  MPI_Alltoall (send_sizes, 3, MPI_INT, recv_sizes, 3, MPI_INT, comm);

  /* compute receive displacements */
  for (recv_size = i = 0; i < ncpu; i ++)
  {
    recv_counts [i] = recv_sizes [i][2];
    recv_size += recv_counts [i];
    if (i < (ncpu - 1)) recv_disps [i+1] = recv_size;
  }
  recv_disps [0] = 0;

  /* allocate receive buffer */
  ERRMEM (recv_data = malloc (recv_size));

  /* all to all send and receive */
  MPI_Alltoallv (send_data, send_counts, send_disps, MPI_PACKED, recv_data, recv_counts, recv_disps, MPI_PACKED, comm);

  if (recv_size)
  {
    /* contiguous receive size */
    j = ncpu * sizeof (COMDATA);
    for (i = 0; i < ncpu; i ++)
    {
      j += recv_sizes [i][0] * sizeof (int) + 
	   recv_sizes [i][1] * sizeof (double);
    }

    /* prepare output receive data */
    ERRMEM ((*recv) = malloc (j));
    p = (*recv) + ncpu;
    for (i = 0, cd = *recv; i < ncpu; i ++, cd ++)
    {
      cd->rank = i;
      cd->ints = recv_sizes [i][0];
      cd->doubles = recv_sizes [i][1];
      cd->i = p; p = (cd->i + cd->ints);
      cd->d = p; p = (cd->d + cd->doubles);
    }

    /* unpack data */
    for (i = 0; i < ncpu; i ++)
    {
      MPI_Unpack (&recv_data [recv_disps [i]], recv_counts [i], &recv_position [i], (*recv) [i].i, (*recv) [i].ints, MPI_INT, comm);
      MPI_Unpack (&recv_data [recv_disps [i]], recv_counts [i], &recv_position [i], (*recv) [i].d, (*recv) [i].doubles, MPI_DOUBLE, comm);
    }

    /* compress receive storage */
    for (*nrecv = i = 0; i < ncpu; i ++)
    {
      if (recv_counts [i])
      {
	(*recv) [*nrecv] = (*recv) [i];
	(*nrecv) ++;
      }
    }
  }
  else
  {
    *recv = NULL;
    *nrecv = 0;
  }

  /* cleanup */
  free (send_sizes);
  free (send_counts);
  free (send_disps);
  free (send_position);
  free (recv_sizes);
  free (recv_counts);
  free (recv_disps);
  free (recv_position);
  free (send_data);
  free (recv_data);

  return send_size;
}
Пример #21
0
/* create rank coloring using adjacency graph between processors derived from the W graph */
static int* processor_coloring (GAUSS_SEIDEL *gs, LOCDYN *ldy)
{
  int i, n, m, ncpu, rank, *color, *size, *disp, *adj;
  SET *adjcpu, *item;
  MEM setmem;
  DIAB *dia;
  OFFB *blk;
  CON *con;

  adjcpu = NULL;
  rank = ldy->dom->rank;
  ncpu = ldy->dom->ncpu;
  MEM_Init (&setmem, sizeof (SET), 128);
  ERRMEM (color = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (disp = malloc (sizeof (int [ncpu + 1])));
  ERRMEM (size = malloc (sizeof (int [ncpu])));

  /* collaps W adjacency into processor adjacency */
  for (dia = ldy->dia; dia; dia = dia->n)
  {
    for (blk = dia->adjext; blk; blk = blk->n)
    {
      con = (CON*) blk->dia;
      SET_Insert (&setmem, &adjcpu, (void*) (long) con->rank, NULL);
    }
  }

  n = SET_Size (adjcpu);
  MPI_Allgather (&n, 1, MPI_INT, size, 1, MPI_INT, MPI_COMM_WORLD);

  for (i = disp [0] = 0; i < ncpu - 1; i ++) disp [i+1] = disp [i] + size [i];
  for (i = 0, item = SET_First (adjcpu); item; i ++, item = SET_Next (item)) color [i] = (int) (long) item->data;

  m = disp [ncpu] = (disp [ncpu-1] + size [ncpu-1]);
  ERRMEM (adj = malloc (sizeof (int [m])));

  MPI_Allgatherv (color, n, MPI_INT, adj, size, disp, MPI_INT, MPI_COMM_WORLD); /* gather graph adjacency */

  for (i = 0; i < ncpu; i ++) color [i] = 0; /* zero colors */

  for (i = 0; i < ncpu; i ++) /* simple BFS coloring */
  {
    int *j, *k;

    do
    {
      color [i] ++; /* start from first color */

      for (j = &adj[disp[i]], k = &adj[disp[i+1]]; j < k; j ++) /* for each adjacent vertex */
      {
	if (color [*j] == color [i]) break; /* see whether the trial color exists in the adjacency */
      }
    }
    while (j < k); /* if so try next color */
  }

  for (m = i = 0; i < ncpu; i ++) m = MAX (m, color [i]); /* compute number of colors */
  gs->colors = m; /* record number of colors */

  if (rank == 0 && ldy->dom->verbose && gs->verbose)
  {
#if DEBUG
  for (i = 0; i < ncpu; i ++)
  {
    int *j, *k;

    printf ("GAUSS_SEIDEL: RANK %d [%d] ADJCPU:", i, color [i]);
    for (j = &adj[disp[i]], k = &adj[disp[i+1]]; j < k; j ++) printf (" %d [%d]", *j, color [*j]);
    printf ("\n");
  }
#endif
    printf ("GAUSS_SEIDEL: PROCESSOR COLORS = %d\n", m);
  }

  MEM_Release (&setmem);
  free (size);
  free (disp);
  free (adj);

  return color;
}
Пример #22
0
/* create mesh from a vector of nodes, element list in format =>
 * {nuber of nodes, node0, node1, ..., material}, {REPEAT}, ..., 0 (end of list); and surface colors in format =>
 * global surface, {number of nodes, node0, node1, ..., surface}, {REPEAT}, ..., 0 (end of list); */
MESH_DATA* MESH_Create (REAL (*nodes) [3], int *elements, int *surfaces)
{
  int maximal_node,
      minimal_node,
      elements_count,
      faces_count,
      temp, *eleptr, n;
  REAL (*node) [3];
  MEM *elemem,
      facmem,
      mapmem;
  ELEMENT *ele, *enx, *elist;
  FACE *fac, *cac, *gac, *flist;
  MAP *faces, *smap;
  MESH_DATA *msh;
  
  maximal_node = 0;
  minimal_node = INT_MAX;
  elements_count = 0;
  faces_count = 0;

  /* create mesh storage */
  ERRMEM (msh = static_cast<MESH_DATA*>(MEM_CALLOC (sizeof (MESH_DATA))));
  elemem = &msh->elemem;
 
  /* calculate elements */ 
  for (eleptr = elements; eleptr [0]; eleptr += (eleptr [0]+2)) elements_count ++;

  MEM_Init (elemem, sizeof (ELEMENT), elements_count);
  MEM_Init (&facmem, sizeof (FACE), MEMCHUNK);
  MEM_Init (&mapmem, sizeof (MAP), MEMCHUNK);
  MEM_Init (&msh->mapmem, sizeof (MAP), MIN (elements_count, MEMCHUNK));

  elist = NULL;
  flist = NULL;
  faces = NULL;

  /* create elements list & face adjacency map */
  for (eleptr = elements; eleptr [0]; eleptr += (eleptr [0]+2))
  {
    ASSERT (
      eleptr [0] == 4 || /* tetrahedron */
      eleptr [0] == 5 || /* pyramid */
      eleptr [0] == 6 || /* wedge */
      eleptr [0] == 8,   /* hexahedron */
      "ERROR: unsupported element type");

    ele = create_element (elemem, eleptr);
    flist = create_faces (&facmem, &mapmem, &faces, ele, flist);
    ele->next = elist;
    elist = ele;

    /* node number extrema */
    temp = maximal (eleptr);
    if (temp > maximal_node)
      maximal_node = temp;
    temp = minimal (eleptr);
    if (temp < minimal_node)
      minimal_node = temp;
  }

  /* calculate faces */
  for (fac = flist; fac; fac = fac->next)
    if (fac->ele) faces_count ++;

  /* alocate additional storage */
  MEM_Init (&msh->facmem, sizeof (FACE), faces_count);
  msh->nodes_count = (maximal_node - minimal_node + 1);
  ERRMEM (msh->nodes = static_cast<REAL(*)[3]>(malloc (sizeof (REAL [3]) * (msh->nodes_count))));
  msh->surfeles_count = msh->bulkeles_count = 0;
  msh->surfeles = msh->bulkeles = NULL;

  /* set up elements */
  for (ele = elist; ele; ele = enx)
  {
    enx = ele->next;

    if (minimal_node > 0) /* impose 0-based indexing */
    {
      for (temp = 0; temp < ele->type; temp ++)
	ele->nodes [temp] -= minimal_node;
    }

    ele->prev = NULL;
   
    if (ele->neighs < neighs (ele->type)) /* surface element */
    {
      msh->surfeles_count ++;
      ele->next = msh->surfeles;
      if (msh->surfeles) msh->surfeles->prev = ele;
      msh->surfeles = ele;
    }
    else /* bulk element */
    {
      msh->bulkeles_count ++;
      ele->next = msh->bulkeles;
      if (msh->bulkeles) msh->bulkeles->prev = ele;
      msh->bulkeles = ele;
    }
  }

  /* create surfaces map => skip first element of 'surfaces' == the global surface kind */
  for (eleptr = (surfaces + 1), smap = NULL, temp = 0;
    eleptr [0]; eleptr += (eleptr [0]+2), temp ++)
  {
    fac = static_cast<FACE*>(MEM_Alloc (&facmem));
    
    ASSERT (
      eleptr [0] == 3 || /* triangle */
      eleptr [0] == 4,   /* quad */
      "ERROR: unsupported face type");

    fac->type = eleptr [0];
    for (n = 0; n < eleptr [0]; n ++)
      fac->nodes [n] = eleptr [n+1];
    sort (fac->nodes, fac->nodes+fac->type-1);

    fac->color = eleptr [eleptr [0] + 1];
    MAP_Insert (&mapmem, &smap, fac, /* map by the type/nodes key */
      fac, face_compare);
  }

  /* set up nodes */
  for (temp = minimal_node,
       node = msh->nodes;
       temp <= maximal_node;
       temp ++, node ++)
  {
    COPY (nodes [temp], *node);
  }

  /* set up faces */
  for (fac = flist; fac; fac = fac->next)
  {
    if (fac->ele) /* see (***) */
    {
      ele = fac->ele;

      cac = static_cast<FACE*>(MEM_Alloc (&msh->facmem));
      setup_face (ele, fac->index, cac, 0); /* setup face nodes without sorting them */
      cac->index = fac->index;
      cac->ele = fac->ele;
      setup_normal (msh->nodes, cac); /* calculate outer spatial normal */
      cac->next = ele->faces; /* append element face list */
      ele->faces = cac;

      /* set the mapped surface kind if possible => otherwise the global one */
      gac = static_cast<FACE*>(MAP_Find (smap, fac, face_compare));
      cac->color = (gac ? gac->color : surfaces [0]);
    }
  }

  /* create mesh face list */
  for (ele = msh->surfeles; ele; ele = ele->next)
  {
    for (fac = ele->faces; fac; fac = fac->next)
    {
      fac->n = msh->faces;
      msh->faces = fac;
    }
  }

  /* clean up */
  MEM_Release (&facmem);
  MEM_Release (&mapmem);

  return msh;
}
Пример #23
0
int
main(int argc, char** argv)
{
  char buf[BUFSIZ];
  struct font_glyph_desc desc;
  struct font_system* sys = NULL;
  struct font_rsrc* font = NULL;
  struct font_glyph* glyph = NULL;
  const char* path = NULL;
  unsigned char* buffer = NULL;
  size_t buffer_size = 0;
  int h = 0;
  int w = 0;
  int Bpp = 0;
  int i = 0;
  bool b = false;

  if(argc != 2) {
    printf("usage: %s FONT\n", argv[0]);
    goto error;
  }
  path = argv[1];

  CHECK(font_system_create( NULL, NULL ), BAD_ARG);
  CHECK(font_system_create(NULL, &sys), OK);

  CHECK(font_rsrc_create(NULL, NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_create(sys, NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_create(NULL, NULL, &font), BAD_ARG);
  CHECK(font_rsrc_create(sys, NULL, &font), OK);

  CHECK(font_rsrc_load(NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_load(font, NULL), BAD_ARG);
  CHECK(font_rsrc_load(NULL, path), BAD_ARG);
  CHECK(font_rsrc_load(font, path), OK);

  CHECK(font_rsrc_is_scalable(NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_is_scalable(font, NULL), BAD_ARG);
  CHECK(font_rsrc_is_scalable(NULL, &b), BAD_ARG);
  CHECK(font_rsrc_is_scalable(font, &b), OK);

  if(b) {
    CHECK(font_rsrc_set_size(NULL, 0, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 0, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(NULL, 32, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 32, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(NULL, 0, 64), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 0, 64), BAD_ARG);
    CHECK(font_rsrc_set_size(NULL, 32, 64), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 32, 64), OK);
    CHECK(font_rsrc_set_size(font, 16, 16), OK);
  }

  CHECK(font_rsrc_get_line_space(NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_get_line_space(font, NULL), BAD_ARG);
  CHECK(font_rsrc_get_line_space(NULL, &i), BAD_ARG);
  CHECK(font_rsrc_get_line_space(font, &i), OK);

  CHECK(font_rsrc_get_glyph(NULL, L'a', NULL), BAD_ARG);
  CHECK(font_rsrc_get_glyph(font, L'a', NULL), BAD_ARG);
  CHECK(font_rsrc_get_glyph(NULL, L'a', &glyph), BAD_ARG);
  CHECK(font_rsrc_get_glyph(font, L'a', &glyph), OK);

  CHECK(font_glyph_get_desc(NULL, NULL), BAD_ARG);
  CHECK(font_glyph_get_desc(glyph, NULL), BAD_ARG);
  CHECK(font_glyph_get_desc(NULL, &desc), BAD_ARG);
  CHECK(font_glyph_get_desc(glyph, &desc), OK);
  CHECK(desc.character, L'a');

  CHECK(font_glyph_get_bitmap(NULL, true, NULL, NULL, NULL, NULL), BAD_ARG);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, NULL, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, NULL, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, &h, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, NULL, &Bpp, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, NULL, &Bpp, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, &h, &Bpp, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, &Bpp, NULL), OK);
  NCHECK(w, 0);
  NCHECK(h, 0);
  NCHECK(Bpp, 0);

  buffer = MEM_CALLOC
    (&mem_default_allocator, (size_t)(w*h*Bpp), sizeof(unsigned char));
  NCHECK(buffer, NULL);
  buffer_size = (size_t)(w*h*Bpp) * sizeof(unsigned char);

  CHECK(font_glyph_get_bitmap(glyph, false, NULL, NULL, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, NULL, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, NULL, &h, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, &h, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, NULL, NULL, &Bpp, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, NULL, &Bpp, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, NULL, &h, &Bpp, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, &h, &Bpp, buffer), OK);

  CHECK(font_glyph_ref_get(NULL), BAD_ARG);
  CHECK(font_glyph_ref_get(glyph), OK);
  CHECK(font_glyph_ref_put(NULL), BAD_ARG);
  CHECK(font_glyph_ref_put(glyph), OK);
  CHECK(font_glyph_ref_put(glyph), OK);

  b = true;
  for(i = 0; b && i < w*h*Bpp; ++i)
    b = ((int)buffer[i] == 0);
  CHECK(b, false);

  for(i = 32; i < 127; ++i) {
    size_t required_buffer_size = 0;
    CHECK(font_rsrc_get_glyph(font, (wchar_t)i, &glyph), OK);

    CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, &Bpp, NULL), OK);
    required_buffer_size = (size_t)(w * h * Bpp) * sizeof(unsigned char);
    if(required_buffer_size > buffer_size) {
      buffer = MEM_REALLOC(&mem_default_allocator,buffer, required_buffer_size);
      NCHECK(buffer, NULL);
      buffer_size = required_buffer_size;
    }
    CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, &Bpp, buffer), OK);
    NCHECK(snprintf(buf, BUFSIZ, "/tmp/%.3d.ppm", i - 32), BUFSIZ);
    CHECK(image_ppm_write(buf, w, h, Bpp, buffer), 0);
    CHECK(font_glyph_ref_put(glyph), OK);
  }
  MEM_FREE(&mem_default_allocator, buffer);

  CHECK(font_rsrc_ref_get(NULL), BAD_ARG);
  CHECK(font_rsrc_ref_get(font), OK);
  CHECK(font_rsrc_ref_put(NULL), BAD_ARG);
  CHECK(font_rsrc_ref_put(font), OK);
  CHECK(font_rsrc_ref_put(font), OK);

  CHECK(font_system_ref_get(NULL), BAD_ARG);
  CHECK(font_system_ref_get(sys), OK);
  CHECK(font_system_ref_put(NULL), BAD_ARG);
  CHECK(font_system_ref_put(sys), OK);
  CHECK(font_system_ref_put(sys), OK);

  CHECK(MEM_ALLOCATED_SIZE(&mem_default_allocator), 0);

  return 0;

error:
  return -1;
}
Пример #24
0
/* communicate integers and doubles using point to point communication */
int COM (MPI_Comm comm, int tag,
         COMDATA *send, int nsend,
	 COMDATA **recv, int *nrecv) /* recv is contiguous => free (*recv) releases all memory */
{
  COMDATA *cd;
  int rank,
      ncpu,
      send_size,
    (*send_sizes) [3],
     *send_position,
     *send_rank,
      send_count,
     *send_rank_all,
     *send_count_all,
     *send_rank_disp,
     *recv_rank,
    (*recv_sizes) [3],
      recv_count,
      i, j, k, l;
  char **send_data,
       **recv_data;
  MPI_Request *req;
  MPI_Status *sta;
  void *p;

  MPI_Comm_rank (comm, &rank);
  MPI_Comm_size (comm, &ncpu);

  ERRMEM (send_sizes = MEM_CALLOC (ncpu * sizeof (int [3])));
  ERRMEM (send_position = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (send_rank = malloc (ncpu * sizeof (int)));
  ERRMEM (send_data = malloc (ncpu * sizeof (char*)));

  /* compute send sizes */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    send_sizes [cd->rank][0] += cd->ints;
    send_sizes [cd->rank][1] += cd->doubles;
    MPI_Pack_size (cd->ints, MPI_INT, comm, &j);
    MPI_Pack_size (cd->doubles, MPI_DOUBLE, comm, &k);
    send_sizes [cd->rank][2] += (j + k);
  }

  /* allocate send buffers */
  for (send_size = i = 0; i < ncpu; i ++)
  {
    if (send_sizes [i][2])
    {
      ERRMEM (send_data [i] = malloc (send_sizes [i][2]));
      send_position [i] = 0;
      send_size += send_sizes [i][2];
    }
  }

  /* pack ints */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    if (cd->ints)
    {
      MPI_Pack (cd->i, cd->ints, MPI_INT, send_data [cd->rank], send_sizes [cd->rank][2], &send_position [cd->rank], comm);
    }
  }

  /* pack doubles */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    if (cd->doubles)
    {
      MPI_Pack (cd->d, cd->doubles, MPI_DOUBLE, send_data [cd->rank], send_sizes [cd->rank][2], &send_position [cd->rank], comm);
    }
  }

#if DEBUG
  for (i = 0; i < ncpu; i ++)
  {
    ASSERT_DEBUG (send_position [i] <= send_sizes [i][2], "Incorrect packing");
  }
#endif

  /* compute send ranks and move data */
  for (send_count = i = 0; i < ncpu; i ++)
  {
    if (send_sizes [i][2])
    {
      send_rank [send_count] = i;
      send_data [send_count] = send_data [i];
      send_sizes [send_count][0] = send_sizes [i][0];
      send_sizes [send_count][1] = send_sizes [i][1];
      send_sizes [send_count][2] = send_sizes [i][2];
      send_count ++;
    }
  }

  ERRMEM (send_count_all = malloc (ncpu * sizeof (int)));
  ERRMEM (recv_rank = malloc (ncpu * sizeof (int)));

  /* gather all send ranks */
  MPI_Allgather (&send_count, 1, MPI_INT, send_count_all, 1, MPI_INT, comm);
  ERRMEM (send_rank_disp = malloc (ncpu * sizeof (int)));
  for (send_rank_disp [0] = l = i = 0; i < ncpu; i ++)
  { l += send_count_all [i]; if (i < ncpu-1) send_rank_disp [i+1] = l; }
  ERRMEM (send_rank_all = malloc (l * sizeof (int)));
  MPI_Allgatherv (send_rank, send_count, MPI_INT, send_rank_all, send_count_all, send_rank_disp, MPI_INT, comm);

  /* compute receive ranks */
  for (recv_count = k = i = 0; i < l; i += send_count_all [k], k ++)
  {
    for (j = 0; j < send_count_all [k]; j ++)
    {
      if (send_rank_all [i+j] == rank) /* 'k'th rank is sending here */
      {
	recv_rank [recv_count] = k;
	recv_count ++;
	break;
      }
    }
  }

  ERRMEM (recv_sizes = malloc (recv_count * sizeof (int [3])));
  ERRMEM (req = malloc (recv_count * sizeof (MPI_Request)));
  ERRMEM (sta = malloc (recv_count * sizeof (MPI_Status)));

  /* communicate receive sizes */
  for (i = 0; i < recv_count; i ++)
  {
    MPI_Irecv (recv_sizes [i], 3, MPI_INT, recv_rank [i], tag, comm, &req [i]);
  }
  MPI_Barrier (comm);
  for (i = 0; i < send_count; i ++)
  {
    MPI_Rsend (send_sizes [i], 3, MPI_INT, send_rank [i], tag, comm);
  }
  MPI_Waitall (recv_count, req, sta);

  /* contiguous receive size */
  j = recv_count * sizeof (COMDATA);
  for (i = 0; i < recv_count; i ++)
  {
    j += recv_sizes [i][0] * sizeof (int) + 
         recv_sizes [i][1] * sizeof (double);
  }

  /* prepare receive buffers */
  ERRMEM (recv_data = malloc (recv_count * sizeof (char*)));
  ERRMEM ((*recv) = malloc (j));
  p = (*recv) + recv_count;
  *nrecv = recv_count;
  for (i = 0, cd = *recv; i < recv_count; i ++, cd ++)
  {
    cd->rank = recv_rank [i];
    cd->ints = recv_sizes [i][0];
    cd->doubles = recv_sizes [i][1];
    cd->i = p; p = (cd->i + cd->ints);
    cd->d = p; p = (cd->d + cd->doubles);
    ERRMEM (recv_data [i] = malloc (recv_sizes [i][2]));
  }

  /* communicate data */
  for (i = 0; i < recv_count; i ++)
  {
    MPI_Irecv (recv_data [i], recv_sizes [i][2], MPI_PACKED, recv_rank [i], tag, comm, &req [i]);
  }
  MPI_Barrier (comm);
  for (i = 0; i < send_count; i ++)
  {
    MPI_Rsend (send_data [i], send_sizes [i][2], MPI_PACKED, send_rank [i], tag, comm);
  }
  MPI_Waitall (recv_count, req, sta);

  /* unpack data */
  for (i = j = 0; i < recv_count; i ++, j = 0)
  {
    MPI_Unpack (recv_data [i], recv_sizes [i][2], &j, (*recv) [i].i, (*recv) [i].ints, MPI_INT, comm);
    MPI_Unpack (recv_data [i], recv_sizes [i][2], &j, (*recv) [i].d, (*recv) [i].doubles, MPI_DOUBLE, comm);
  }

  /* cleanup */
  free (send_rank_disp);
  free (send_sizes);
  free (send_position);
  free (send_rank);
  for (i = 0; i < send_count; i ++)
    free (send_data [i]);
  free (send_data);
  free (send_count_all);
  free (send_rank_all);
  free (recv_rank);
  free (recv_sizes);
  for (i = 0; i < recv_count; i ++)
    free (recv_data [i]);
  free (recv_data);
  free (req);
  free (sta);

  return send_size;
}
Пример #25
0
/* create a repetitive point to point communication pattern;
 * ranks and sizes must not change during the communication;
 * pointers to send and receive buffers data must not change */
void* COM_Pattern (MPI_Comm comm, int tag,
                   COMDATA *send, int nsend,
	           COMDATA **recv, int *nrecv) /* recv is contiguous => free (*recv) releases all memory */
{
  COMPATTERN *pattern;
  COMDATA *cd;
  int rank,
      ncpu,
     *send_rank_all,
     *send_count_all,
     *send_rank_disp,
      i, j, k, l;
  void *p;

  MPI_Comm_rank (comm, &rank);
  MPI_Comm_size (comm, &ncpu);

  ERRMEM (pattern = malloc (sizeof (COMPATTERN)));
  ERRMEM (pattern->rankmap = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (pattern->send_sizes = MEM_CALLOC (ncpu * sizeof (int [3])));
  ERRMEM (pattern->send_position = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (pattern->send_rank = malloc (ncpu * sizeof (int)));
  ERRMEM (pattern->send_data = malloc (ncpu * sizeof (char*)));
  pattern->nsend = nsend;
  pattern->send = send;
  pattern->comm = comm;
  pattern->tag = tag;

  /* compute send sizes */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    pattern->send_sizes [cd->rank][0] += cd->ints;
    pattern->send_sizes [cd->rank][1] += cd->doubles;
    MPI_Pack_size (cd->ints, MPI_INT, comm, &j);
    MPI_Pack_size (cd->doubles, MPI_DOUBLE, comm, &k);
    pattern->send_sizes [cd->rank][2] += (j + k);
  }

  /* allocate send buffers and prepare rank map */
  for (pattern->send_size = i = j = 0; i < ncpu; i ++)
  {
    if (pattern->send_sizes [i][2])
    {
      ERRMEM (pattern->send_data [i] = malloc (pattern->send_sizes [i][2]));
      pattern->rankmap [i] = j;
      pattern->send_size += pattern->send_sizes [i][2];
      j ++;
    }
  }

  /* compute send ranks and move data */
  for (pattern->send_count = i = 0; i < ncpu; i ++)
  {
    if (pattern->send_sizes [i][2])
    {
      pattern->send_rank [pattern->send_count] = i;
      pattern->send_data [pattern->send_count] = pattern->send_data [i];
      pattern->send_sizes [pattern->send_count][0] = pattern->send_sizes [i][0];
      pattern->send_sizes [pattern->send_count][1] = pattern->send_sizes [i][1];
      pattern->send_sizes [pattern->send_count][2] = pattern->send_sizes [i][2];
      pattern->send_count ++;
    }
  }

  ERRMEM (send_count_all = malloc (ncpu * sizeof (int)));
  ERRMEM (pattern->recv_rank = malloc (ncpu * sizeof (int)));

  /* gather all send ranks */
  MPI_Allgather (&pattern->send_count, 1, MPI_INT, send_count_all, 1, MPI_INT, comm);
  ERRMEM (send_rank_disp = malloc (ncpu * sizeof (int)));
  for (send_rank_disp [0] = l = i = 0; i < ncpu; i ++)
  { l += send_count_all [i]; if (i < ncpu-1) send_rank_disp [i+1] = l; }
  ERRMEM (send_rank_all = malloc (l * sizeof (int)));
  MPI_Allgatherv (pattern->send_rank, pattern->send_count, MPI_INT, send_rank_all, send_count_all, send_rank_disp, MPI_INT, comm);

  /* compute receive ranks */
  for (pattern->recv_count = k = i = 0; i < l; i += send_count_all [k], k ++)
  {
    for (j = 0; j < send_count_all [k]; j ++)
    {
      if (send_rank_all [i+j] == rank) /* 'k'th rank is sending here */
      {
	pattern->recv_rank [pattern->recv_count] = k;
	pattern->recv_count ++;
	break;
      }
    }
  }

  ERRMEM (pattern->recv_sizes = malloc (pattern->recv_count * sizeof (int [3])));
  ERRMEM (pattern->recv_req = malloc (pattern->recv_count * sizeof (MPI_Request)));
  ERRMEM (pattern->recv_sta = malloc (pattern->recv_count * sizeof (MPI_Status)));
  ERRMEM (pattern->send_req = malloc (pattern->send_count * sizeof (MPI_Request)));
  ERRMEM (pattern->send_sta = malloc (pattern->send_count * sizeof (MPI_Status)));

  /* communicate receive sizes */
  for (i = 0; i < pattern->recv_count; i ++)
  {
    MPI_Irecv (pattern->recv_sizes [i], 3, MPI_INT, pattern->recv_rank [i], tag, comm, &pattern->recv_req [i]);
  }
  MPI_Barrier (comm);
  for (i = 0; i < pattern->send_count; i ++)
  {
    MPI_Rsend (pattern->send_sizes [i], 3, MPI_INT, pattern->send_rank [i], tag, comm);
  }
  MPI_Waitall (pattern->recv_count, pattern->recv_req, pattern->recv_sta);

  /* contiguous receive size */
  j = pattern->recv_count * sizeof (COMDATA);
  for (i = 0; i < pattern->recv_count; i ++)
  {
    j += pattern->recv_sizes [i][0] * sizeof (int) + 
         pattern->recv_sizes [i][1] * sizeof (double);
  }

  /* prepare receive buffers */
  ERRMEM (pattern->recv_data = malloc (pattern->recv_count * sizeof (char*)));
  ERRMEM (pattern->recv = malloc (j));
  p = pattern->recv + pattern->recv_count;
  pattern->nrecv = pattern->recv_count;
  for (i = 0, cd = pattern->recv; i < pattern->recv_count; i ++, cd ++)
  {
    cd->rank = pattern->recv_rank [i];
    cd->ints = pattern->recv_sizes [i][0];
    cd->doubles = pattern->recv_sizes [i][1];
    cd->i = p; p = (cd->i + cd->ints);
    cd->d = p; p = (cd->d + cd->doubles);
    ERRMEM (pattern->recv_data [i] = malloc (pattern->recv_sizes [i][2]));
  }

  /* truncate */
  if (pattern->send_count)
  {
    ERRMEM (pattern->send_sizes = realloc (pattern->send_sizes, pattern->send_count * sizeof (int [3])));
    ERRMEM (pattern->send_position = realloc (pattern->send_position, pattern->send_count * sizeof (int)));
    ERRMEM (pattern->send_rank = realloc (pattern->send_rank, pattern->send_count * sizeof (int)));
    ERRMEM (pattern->send_data = realloc (pattern->send_data, pattern->send_count * sizeof (char*)));
  }
  if (pattern->recv_count) ERRMEM (pattern->recv_rank = realloc (pattern->recv_rank, pattern->recv_count * sizeof (int)));
 
  /* cleanup */
  free (send_rank_disp);
  free (send_count_all);
  free (send_rank_all);

  /* output */
  *nrecv = pattern->nrecv;
  *recv = pattern->recv;

  return pattern;
}
Пример #26
0
static int
get_active_uniform
  (struct rb_context* ctxt,
   struct rb_program* program,
   GLuint index,
   GLsizei bufsize,
   GLchar* buffer,
   struct rb_uniform** out_uniform)
{
  struct rb_uniform* uniform = NULL;
  GLsizei uniform_namelen = 0;
  GLint uniform_size = 0;
  GLenum uniform_type;
  int err = 0;

  if(!ctxt
  || !program
  || !out_uniform
  || bufsize < 0
  || (bufsize && !buffer))
    goto error;

  OGL(GetActiveUniform
      (program->name,
       index,
       bufsize,
       &uniform_namelen,
       &uniform_size,
       &uniform_type,
       buffer));

  uniform = MEM_CALLOC(ctxt->allocator, 1, sizeof(struct rb_uniform));
  if(!uniform)
    goto error;
  ref_init(&uniform->ref);
  RB(context_ref_get(ctxt));
  uniform->ctxt = ctxt;
  RB(program_ref_get(program));
  uniform->program = program;
  uniform->index = index;
  uniform->type = uniform_type;
  uniform->set = get_uniform_setter(uniform_type);

  if(buffer) {
    /* Add 1 to namelen <=> include the null character. */
    ++uniform_namelen;

    uniform->name = MEM_ALLOC
      (ctxt->allocator, sizeof(char) * uniform_namelen);
    if(!uniform->name)
      goto error;

    uniform->name = strncpy(uniform->name, buffer, uniform_namelen);
    uniform->location = OGL(GetUniformLocation(program->name, uniform->name));
  }

exit:
  *out_uniform = uniform;
  return err;

error:
  if(uniform) {
    RB(uniform_ref_put(uniform));
    uniform = NULL;
  }
  err = -1;
  goto exit;
}
Пример #27
0
/* create a repetitive all to all communication pattern;
 * ranks and sizes must not change during the communication;
 * pointers to send and receive buffers data must not change */
void* COMALL_Pattern (MPI_Comm comm,
                      COMDATA *send, int nsend,
	              COMDATA **recv, int *nrecv) /* recv is contiguous => free (*recv) releases all memory */
{
  COMALLPATTERN *pattern;
  COMDATA *cd;
  int rank,
      ncpu,
      i, j, k;
  void *p;

  MPI_Comm_rank (comm, &rank);
  MPI_Comm_size (comm, &ncpu);

  ERRMEM (pattern = MEM_CALLOC (sizeof (COMALLPATTERN)));
  ERRMEM (pattern->send_sizes = MEM_CALLOC (ncpu * sizeof (int [3])));
  ERRMEM (pattern->send_counts = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (pattern->send_disps = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (pattern->send_position = MEM_CALLOC (ncpu * sizeof (int)));

  pattern->ncpu = ncpu;
  pattern->comm = comm;
  pattern->send = send;
  pattern->nsend = nsend;

  /* compute send sizes */
  for (i = 0, cd = send; i < nsend; i ++, cd ++)
  {
    pattern->send_sizes [cd->rank][0] += cd->ints;
    pattern->send_sizes [cd->rank][1] += cd->doubles;
    MPI_Pack_size (cd->ints, MPI_INT, comm, &j);
    MPI_Pack_size (cd->doubles, MPI_DOUBLE, comm, &k);
    pattern->send_sizes [cd->rank][2] += (j + k);
  }

  /* compute send displacements */
  for (pattern->send_size = i = 0; i < ncpu; i ++)
  {
    pattern->send_counts [i] = pattern->send_sizes [i][2];
    pattern->send_size += pattern->send_counts [i];
    if (i < (ncpu - 1)) pattern->send_disps [i+1] = pattern->send_size;
  }
  pattern->send_disps [0] = 0;

  /* allocate send buffer */
  ERRMEM (pattern->send_data = malloc (pattern->send_size));

  ERRMEM (pattern->recv_sizes = MEM_CALLOC (ncpu * sizeof (int [3])));
  ERRMEM (pattern->recv_counts = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (pattern->recv_disps = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (pattern->recv_position = MEM_CALLOC (ncpu * sizeof (int)));

  /* distribute send sizes into receive sizes */
  MPI_Alltoall (pattern->send_sizes, 3, MPI_INT, pattern->recv_sizes, 3, MPI_INT, comm);

  /* compute receive displacements */
  for (pattern->recv_size = i = 0; i < ncpu; i ++)
  {
    pattern->recv_counts [i] = pattern->recv_sizes [i][2];
    pattern->recv_size += pattern->recv_counts [i];
    if (i < (ncpu - 1)) pattern->recv_disps [i+1] = pattern->recv_size;
  }
  pattern->recv_disps [0] = 0;

  /* allocate receive buffer */
  ERRMEM (pattern->recv_data = malloc (pattern->recv_size));

  if (pattern->recv_size)
  {
    /* contiguous receive size */
    j = ncpu * sizeof (COMDATA);
    for (i = 0; i < ncpu; i ++)
    {
      j += pattern->recv_sizes [i][0] * sizeof (int) + 
	   pattern->recv_sizes [i][1] * sizeof (double);
    }

    /* prepare output receive data */
    ERRMEM (pattern->recv = malloc (j));
    ERRMEM ((*recv) = malloc (j));
    p = (*recv) + ncpu;
    for (i = 0, cd = *recv; i < ncpu; i ++, cd ++)
    {
      cd->rank = i;
      cd->ints = pattern->recv_sizes [i][0];
      cd->doubles = pattern->recv_sizes [i][1];
      cd->i = p; p = (cd->i + cd->ints);
      cd->d = p; p = (cd->d + cd->doubles);
      pattern->recv [i] = *cd;
    }

    /* compress receive storage */
    for (*nrecv = i = 0; i < ncpu; i ++)
    {
      if (pattern->recv_counts [i])
      {
	(*recv) [*nrecv] = (*recv) [i];
	(*nrecv) ++;
      }
    }
  }
  else
  {
    *recv = NULL;
    *nrecv = 0;
  }

  return pattern;
}