11 #include <sys/resource.h>
14 #include <gsl/gsl_rng.h>
16 #define __UTILS_SYSTEM_C
33 void enable_core_dumps_and_fpu_exceptions(
void)
67 gsl_rng * random_generator = gsl_rng_alloc(gsl_rng_ranlxd1);
70 gsl_rng_set(random_generator, seed);
74 RndTable[i] = gsl_rng_uniform(random_generator);
76 gsl_rng_free(random_generator);
100 dt = t1 + pow(2, 32) / CLOCKS_PER_SEC - t0;
116 write(STDOUT_FILENO, q, p - q + 1);
127 const char * warning =
"LASTMESSAGE did not end with new line: ";
128 write(STDOUT_FILENO, warning, strlen(warning));
129 write(STDOUT_FILENO, q, p - q);
130 write(STDOUT_FILENO,
"\n", 1);
149 MPIU_Tracev(MPI_Comm comm,
int where,
int error,
const char * fmt, va_list va)
159 vsnprintf(buf, 4096, fmt, va);
161 char err[] =
"ERROR: ";
182 void MPIU_Trace(MPI_Comm comm,
int where,
const char * fmt, ...)
194 MPI_Comm comm = MPI_COMM_WORLD;
197 MPI_Comm_size(comm, &
NTask);
202 numlist = (
int *)
mymalloc(
"numlist",
NTask * n *
sizeof(
int));
203 MPI_Allgather(src, n, MPI_INT, numlist, n, MPI_INT, MPI_COMM_WORLD);
205 for(j = 0; j < n; j++)
208 for(i = 0; i <
NTask; i++)
209 for(j = 0; j < n; j++)
210 res[j] += numlist[i * n + j];
217 MPI_Comm comm = MPI_COMM_WORLD;
220 MPI_Comm_size(comm, &
NTask);
225 numlist = (int64_t *)
mymalloc(
"numlist",
NTask * n *
sizeof(int64_t));
226 MPI_Allgather(src, n *
sizeof(int64_t), MPI_BYTE, numlist, n *
sizeof(int64_t), MPI_BYTE,
229 for(j = 0; j < n; j++)
232 for(i = 0; i <
NTask; i++)
233 for(j = 0; j < n; j++)
234 res[j] += numlist[i * n + j];
244 MPI_Comm_size(comm, &
NTask);
254 for(i = 1; i <
NTask; i ++) {
255 offset[i] = offset[i-1] + count[i-1];
266 MPI_Allreduce(&countLocal, &sum, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
279 MPI_Datatype sendtype,
void *recvbuf,
int *recvcnts,
280 int *rdispls, MPI_Datatype recvtype, MPI_Comm comm)
291 MPI_Comm_size(comm, &
NTask);
294 int *a_sdispls=NULL, *a_recvcnts=NULL, *a_rdispls=NULL;
295 for(i = 0; i <
NTask; i ++) {
296 if(sendcnts[i] > 0) {
300 if(recvcnts == NULL) {
302 recvcnts = a_recvcnts;
303 MPI_Alltoall(sendcnts, 1, MPI_INT,
304 recvcnts, 1, MPI_INT, comm);
306 if(recvbuf == NULL) {
308 for(i = 0; i <
NTask; i ++) {
309 totalrecv += recvcnts[i];
313 if(sdispls == NULL) {
317 for (i = 1; i <
NTask; i++) {
318 sdispls[i] = sdispls[i - 1] + sendcnts[i - 1];
321 if(rdispls == NULL) {
325 for (i = 1; i <
NTask; i++) {
326 rdispls[i] = rdispls[i - 1] + recvcnts[i - 1];
330 int dense = nn <
NTask * 0.2;
331 int tot_dense = 0, ret;
332 MPI_Allreduce(&dense, &tot_dense, 1, MPI_INT, MPI_SUM, comm);
335 ret = MPI_Alltoallv(sendbuf, sendcnts, sdispls,
337 recvcnts, rdispls, recvtype, comm);
341 recvcnts, rdispls, recvtype, comm);
354 MPI_Datatype sendtype,
void *recvbuf,
int *recvcnts,
355 int *rdispls, MPI_Datatype recvtype, MPI_Comm comm) {
360 MPI_Comm_size(comm, &
NTask);
364 for(PTask = 0;
NTask > (1 << PTask); PTask++);
367 ptrdiff_t send_elsize;
368 ptrdiff_t recv_elsize;
370 MPI_Type_get_extent(sendtype, &lb, &send_elsize);
371 MPI_Type_get_extent(recvtype, &lb, &recv_elsize);
373 #ifndef NO_ISEND_IRECV_IN_DOMAIN
375 MPI_Request *requests = (MPI_Request *)
mymalloc(
"requests",
NTask * 2 *
sizeof(MPI_Request));
378 for(ngrp = 0; ngrp < (1 << PTask); ngrp++)
382 if(target >=
NTask)
continue;
383 if(recvcnts[target] == 0)
continue;
385 ((
char*) recvbuf) + recv_elsize * rdispls[target],
387 recvtype, target, 101934, comm, &requests[n_requests++]);
397 for(ngrp = 0; ngrp < (1 << PTask); ngrp++)
400 if(target >=
NTask)
continue;
401 if(sendcnts[target] == 0)
continue;
402 MPI_Isend(((
char*) sendbuf) + send_elsize * sdispls[target],
404 sendtype, target, 101934, comm, &requests[n_requests++]);
407 MPI_Waitall(n_requests, requests, MPI_STATUSES_IGNORE);
410 for(ngrp = 0; ngrp < (1 << PTask); ngrp++)
414 if(target >=
NTask)
continue;
415 if(sendcnts[target] == 0 && recvcnts[target] == 0)
continue;
416 MPI_Sendrecv(((
char*)sendbuf) + send_elsize * sdispls[target],
417 sendcnts[target], sendtype,
419 ((
char*)recvbuf) + recv_elsize * rdispls[target],
420 recvcnts[target], recvtype,
422 comm, MPI_STATUS_IGNORE);
439 MPI_Comm_size(MPI_COMM_WORLD, &
NTask);
440 MPI_Comm_rank(MPI_COMM_WORLD, &
ThisTask);
444 const int bufsz = 256;
446 memset(buffer, 0, bufsz *
NTask);
448 gethostname(&buffer[bufsz*
ThisTask], bufsz);
449 buffer[bufsz *
ThisTask + bufsz - 1] =
'\0';
450 MPI_Allgather(MPI_IN_PLACE, bufsz, MPI_CHAR, buffer, bufsz, MPI_CHAR, MPI_COMM_WORLD);
454 for(j = 0; j <
NTask; j++) {
455 for(i = j+1; i <
NTask; i++) {
456 if(strncmp(buffer + i * bufsz, buffer + j * bufsz, bufsz) == 0)
469 #if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE
471 double pages = sysconf (_SC_PHYS_PAGES);
472 double pagesize = sysconf (_SC_PAGESIZE);
473 if (0 <= pages && 0 <= pagesize)
474 return pages * pagesize;
478 #if defined HW_PHYSMEM
480 unsigned int physmem;
481 size_t len =
sizeof physmem;
482 static int mib[2] = { CTL_HW, HW_PHYSMEM };
484 if (sysctl (mib, ARRAY_SIZE (mib), &physmem, &len, NULL, 0) == 0
485 && len ==
sizeof (physmem))
486 return (
double) physmem;
489 return 64 * 1024 * 1024;
503 MPI_Comm_size(comm, &
NTask);
508 for(i = 0; fn[i]; i ++) {
509 tag += (int)fn[i] * 8;
514 MPI_Igather(&tag, 1, MPI_INT, recvbuf, 1, MPI_INT, 0, comm, &request);
519 MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
526 MPIU_Trace(comm, 0,
"Waited more than %g seconds during barrier %s : %d \n", tsleep / 1000000., fn, line);
531 MPI_Wait(&request, MPI_STATUS_IGNORE);
534 for(i = 0; i <
NTask; i ++) {
535 if(recvbuf[i] != tag) {
536 MPIU_Trace(comm, 0,
"Task %d Did not hit barrier at %s : %d; expecting %d, got %d\n", i, fn, line, tag, recvbuf[i]);
547 MPI_Allreduce(MPI_IN_PLACE, &condition, 1, MPI_INT, MPI_LOR, comm);
554 MPI_Comm comm = MPI_COMM_WORLD;
557 MPI_Comm_size(comm, &
NTask);
560 int my_pid = getpid();
566 char * thishost = hosts +
NTask * bufsz;
567 gethostname(thishost, bufsz);
568 thishost[bufsz - 1] =
'\0';
570 MPI_Gather(thishost, bufsz, MPI_CHAR, hosts, bufsz, MPI_CHAR, 0, comm);
571 MPI_Gather(&my_pid, 1, MPI_INT, pids, 1, MPI_INT, 0, comm);
576 FILE *fd = fopen(filename,
"w");
578 endrun(5,
"Could not open pidfile %s\n", filename);
579 for(i = 0; i <
NTask; i++)
580 fprintf(fd,
"host: %s pid: %d\n", hosts+i*bufsz, pids[i]);
592 for(i = 0; i < narrays; i++)
594 memmove(dest + asize, srcs[i],
sizeof(
int) * sizes[i]);
604 for(i=0; i < narrays; i++) {
605 srcs[i] = dest + i * total_size;
613 check_reduce(
const void *inputcpy,
const void * recvbuf,
const int count, MPI_Datatype datatype, MPI_Op op,
const int line,
const char * file)
617 for(i=0; i < count; i++) {
619 if(datatype == MPI_INT) {
620 if(((
int *) inputcpy)[i] > ((
int *) recvbuf)[i])
621 endrun(12,
"MPI_Allreduce with MPI_INT MPI_MAX | MPI_SUM has int %d bad: (input %d > out %d) at %s:%d\n", i, *((
int*) inputcpy), *((
int*) recvbuf), file, line);
623 else if (datatype == MPI_LONG) {
624 if(((
long *) inputcpy)[i] > ((
long *) recvbuf)[i])
625 endrun(12,
"MPI_Allreduce with MPI_LONG MPI_MAX | MPI_SUM has int %d bad: (input %ld > out %ld) at %s:%d\n", i, *((
long*) inputcpy), *((
long*) recvbuf), file, line);
627 else if(datatype == MPI_DOUBLE) {
628 if(((
double *) inputcpy)[i] > ((
double *) recvbuf)[i])
629 endrun(12,
"MPI_Allreduce with MPI_DOUBLE MPI_MAX | MPI_SUM has int %d bad: (input %g > out %g) at %s:%d\n", i, *((
double*) inputcpy), *((
double*) recvbuf), file, line);
631 }
else if (op == MPI_MIN) {
632 if(datatype == MPI_INT) {
633 if(((
int *) inputcpy)[i] < ((
int *) recvbuf)[i])
634 endrun(12,
"MPI_Allreduce with MPI_INT MPI_MAX | MPI_SUM has int %d bad: (input %d < out %d) at %s:%d\n", i, *((
int*) inputcpy), *((
int*) recvbuf), file, line);
636 else if (datatype == MPI_LONG) {
637 if(((
long *) inputcpy)[i] < ((
long *) recvbuf)[i])
638 endrun(12,
"MPI_Allreduce with MPI_LONG MPI_MAX | MPI_SUM has int %d bad: (input %ld < out %ld) at %s:%d\n", i, *((
long*) inputcpy), *((
long*) recvbuf), file, line);
640 else if(datatype == MPI_DOUBLE) {
641 if(((
double *) inputcpy)[i] < ((
double *) recvbuf)[i])
642 endrun(12,
"MPI_Allreduce with MPI_DOUBLE MPI_MAX | MPI_SUM has int %d bad: (input %g < out %g) at %s:%d\n", i, *((
double*) inputcpy), *((
double*) recvbuf), file, line);
649 MPI_Allreduce_Checked(
const void *sendbuf,
void *recvbuf,
int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm,
const int line,
const char * file)
652 size_t datasz =
sizeof(char);
653 if(datatype == MPI_INT)
654 datasz =
sizeof(int);
655 else if(datatype == MPI_DOUBLE)
656 datasz =
sizeof(double);
657 else if (datatype == MPI_LONG || datatype ==
MPI_INT64)
658 datasz =
sizeof(long);
659 void * inputcpy = alloca(datasz * count);
660 if(sendbuf != MPI_IN_PLACE)
661 memcpy(inputcpy, sendbuf, datasz * count);
663 memcpy(inputcpy, recvbuf, datasz * count);
664 int retval = MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm);
667 check_reduce(inputcpy, recvbuf, count, datatype, op, line, file);
673 MPI_Reduce_Checked(
const void *sendbuf,
void *recvbuf,
int count,
674 MPI_Datatype datatype, MPI_Op op,
int root,
675 MPI_Comm comm,
const int line,
const char * file)
679 int datasz =
sizeof(int);
681 if(datatype == MPI_DOUBLE)
682 datasz =
sizeof(double);
683 else if (datatype == MPI_LONG)
684 datasz =
sizeof(long);
685 void * inputcpy = alloca(datasz * count);
686 if(sendbuf != MPI_IN_PLACE)
687 memcpy(inputcpy, sendbuf, datasz * count);
689 memcpy(inputcpy, recvbuf, datasz * count);
690 int retval = MPI_Reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
693 check_reduce(inputcpy, recvbuf, count, datatype, op, line, file);
void endrun(int where, const char *fmt,...)
#define mymalloc(name, size)
#define ta_malloc(name, type, nele)
void gadget_setup_thread_arrays(int *dest, int *srcs[], size_t sizes[], size_t total_size, int narrays)
int MPI_Alltoallv_sparse(void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype sendtype, void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype recvtype, MPI_Comm comm)
double get_random_number(uint64_t id)
int64_t count_sum(int64_t countLocal)
double get_physmem_bytes(void)
void sumup_longs(int n, int64_t *src, int64_t *res)
void MPIU_Tracev(MPI_Comm comm, int where, int error, const char *fmt, va_list va)
int cluster_get_num_hosts(void)
void MPIU_write_pids(char *filename)
int MPI_Alltoallv_smart(void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype sendtype, void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype recvtype, MPI_Comm comm)
void MPIU_Trace(MPI_Comm comm, int where, const char *fmt,...)
int _MPIU_Barrier(const char *fn, const int line, MPI_Comm comm)
size_t sizemax(size_t a, size_t b)
void sumup_large_ints(int n, int *src, int64_t *res)
static int putline(const char *prefix, const char *line)
double timediff(double t0, double t1)
void set_random_numbers(int seed)
size_t gadget_compact_thread_arrays(int *dest, int *srcs[], size_t sizes[], int narrays)
int MPIU_Any(int condition, MPI_Comm comm)
static double RndTable[RNDTABLE]
int64_t MPIU_cumsum(int64_t countLocal, MPI_Comm comm)