utils.c 3.38 KB
Newer Older
Valentin Reis's avatar
Valentin Reis committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
/* Copyright (C) 2010 The Trustees of Indiana University.                  */
/*                                                                         */
/* Use, modification and distribution is subject to the Boost Software     */
/* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at */
/* http://www.boost.org/LICENSE_1_0.txt)                                   */
/*                                                                         */
/*  Authors: Jeremiah Willcock                                             */
/*           Andrew Lumsdaine                                              */

#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "splittable_mrg.h"
#include "graph_generator.h"
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __MTA__
#include <sys/mta_task.h>
#endif
#ifdef GRAPH_GENERATOR_MPI
#include <mpi.h>
#endif
#ifdef GRAPH_GENERATOR_OMP
#include <omp.h>
#endif
#include "utils.h"

#if defined(_OPENMP)
#define OMP(x_) _Pragma(x_)
#else
#define OMP(x_)
#endif

#if defined(HAVE_LIBNUMA)
#include <numa.h>
static int numa_inited = 0;
static int numa_avail = -1;

void *
xmalloc (size_t sz)
{
  void * out;
  if (!numa_inited) {
    OMP("omp critical") {
      numa_inited = 1;
      numa_avail = numa_available ();
    }
  }

  if (numa_avail)
    out = numa_alloc (sz);
  else
    out = malloc (sz);
  if (!out) {
    fprintf(stderr, "Out of memory trying to allocate %zu byte(s)\n", sz);
    abort ();
  }
  return out;
}
void *
xcalloc (size_t n, size_t sz)
{
  void * out;
  if (!numa_inited) {
    OMP("omp critical") {
      numa_inited = 1;
      numa_avail = numa_available ();
    }
  }

  if (numa_avail) {
    size_t to_alloc;
    to_alloc = n * sz;
    if (to_alloc < n || to_alloc < sz) {
      fprintf(stderr,
	      "Allocation size out of range for %zu items of %zu byte(s)\n",
	      n, sz);
      abort ();
    }
    out = numa_alloc (n * sz);
#if defined(_OPENMP)
#pragma omp parallel for
      for (size_t k = 0; k < n; ++k)
	memset (out + k * sz, 0, sz);
#else
    memset (out, 0, n * sz);
#endif
  } else
    out = calloc (n, sz);
  if (!out) {
    fprintf(stderr,
	    "Out of memory trying to allocate/clear %zu items of %zu byte(s)\n",
	    n, sz);
    abort ();
  }
  return out;
}
void
xfree (void * p, size_t sz)
{
  if (!p) return;
  if (numa_avail >= 0)
    numa_free (p, sz);
  else
    free (p);
}
#else
void *
xmalloc (size_t sz)
{
  void * out;
  out = malloc (sz);
  if (!out) {
    fprintf(stderr, "Out of memory trying to allocate %zu byte(s)\n", sz);
    abort ();
  }
  return out;
}
void *
xcalloc (size_t n, size_t sz)
{
  void * out;
  out = calloc (n, sz);
  if (!out) {
    fprintf(stderr,
	    "Out of memory trying to allocate/clear %zu items of %zu byte(s)\n",
	    n, sz);
    abort ();
  }
  return out;
}
void
xfree (void * p, size_t sz)
{
  free (p);
}
#endif

/* Spread the two 64-bit numbers into five nonzero values in the correct
 * range. */
void make_mrg_seed(uint64_t userseed1, uint64_t userseed2, uint_fast32_t* seed) {
  seed[0] = (uint32_t)(userseed1 & UINT32_C(0x3FFFFFFF)) + 1;
  seed[1] = (uint32_t)((userseed1 >> 30) & UINT32_C(0x3FFFFFFF)) + 1;
  seed[2] = (uint32_t)(userseed2 & UINT32_C(0x3FFFFFFF)) + 1;
  seed[3] = (uint32_t)((userseed2 >> 30) & UINT32_C(0x3FFFFFFF)) + 1;
  seed[4] = (uint32_t)((userseed2 >> 60) << 4) + (uint32_t)(userseed1 >> 60) + 1;
}