MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Macros | Functions
mpsort.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MPSORT_DISABLE_GATHER_SORT   (1 << 3)
 
#define MPSORT_REQUIRE_GATHER_SORT   (1 << 4)
 
#define mpsort_mpi(base, nmemb, elsize, radix, rsize, arg, comm)
 
#define mpsort_mpi_newarray(base, nmemb, out, outnmemb, elsize, radix, rsize, arg, comm)
 

Functions

void mpsort_mpi_set_options (int options)
 
int mpsort_mpi_has_options (int options)
 
void mpsort_mpi_unset_options (int options)
 
void mpsort_mpi_impl (void *base, size_t nmemb, size_t elsize, void(*radix)(const void *ptr, void *radix, void *arg), size_t rsize, void *arg, MPI_Comm comm, const int line, const char *file)
 
void mpsort_mpi_newarray_impl (void *base, size_t nmemb, void *out, size_t outnmemb, size_t size, void(*radix)(const void *ptr, void *radix, void *arg), size_t rsize, void *arg, MPI_Comm comm, const int line, const char *file)
 
void mpsort_mpi_report_last_run ()
 
void mpsort_setup_timers (int ntimers)
 
void mpsort_free_timers (void)
 

Macro Definition Documentation

◆ MPSORT_DISABLE_GATHER_SORT

#define MPSORT_DISABLE_GATHER_SORT   (1 << 3)

Definition at line 5 of file mpsort.h.

◆ mpsort_mpi

#define mpsort_mpi (   base,
  nmemb,
  elsize,
  radix,
  rsize,
  arg,
  comm 
)
Value:
mpsort_mpi_impl(base, nmemb, elsize, radix, rsize, arg, comm, \
__LINE__, __FILE__)
void mpsort_mpi_impl(void *base, size_t nmemb, size_t elsize, void(*radix)(const void *ptr, void *radix, void *arg), size_t rsize, void *arg, MPI_Comm comm, const int line, const char *file)
Definition: mpsort.c:775

Definition at line 26 of file mpsort.h.

◆ mpsort_mpi_newarray

#define mpsort_mpi_newarray (   base,
  nmemb,
  out,
  outnmemb,
  elsize,
  radix,
  rsize,
  arg,
  comm 
)
Value:
mpsort_mpi_newarray_impl(base, nmemb, out, outnmemb, elsize, \
radix, rsize, arg, comm, __LINE__, __FILE__)
void mpsort_mpi_newarray_impl(void *base, size_t nmemb, void *out, size_t outnmemb, size_t size, void(*radix)(const void *ptr, void *radix, void *arg), size_t rsize, void *arg, MPI_Comm comm, const int line, const char *file)
Definition: mpsort.c:809

Definition at line 30 of file mpsort.h.

◆ MPSORT_REQUIRE_GATHER_SORT

#define MPSORT_REQUIRE_GATHER_SORT   (1 << 4)

Definition at line 6 of file mpsort.h.

Function Documentation

◆ mpsort_free_timers()

void mpsort_free_timers ( void  )

Definition at line 745 of file mpsort.c.

746 {
747  if(!(_TIMERS.tmr)) {
748  myfree(_TIMERS.tmr);
749  _TIMERS.tmr = NULL;
750  _TIMERS.ntimer = 0;
751  _TIMERS.curtmr = 0;
752  }
753 }
static struct TIMERS _TIMERS
#define myfree(x)
Definition: mymalloc.h:19
int ntimer
Definition: mpsort.c:551
struct TIMER * tmr
Definition: mpsort.c:549
int curtmr
Definition: mpsort.c:550

References _TIMERS, TIMERS::curtmr, myfree, TIMERS::ntimer, and TIMERS::tmr.

◆ mpsort_mpi_has_options()

int mpsort_mpi_has_options ( int  options)

Definition at line 1444 of file mpsort.c.

1445 {
1447  return _mpsort_mpi_options & options;
1448 }
static void _mpsort_mpi_parse_env()
Definition: mpsort.c:1424
static int _mpsort_mpi_options
Definition: mpsort.c:460

References _mpsort_mpi_options, and _mpsort_mpi_parse_env().

Referenced by mpsort_mpi_newarray_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mpsort_mpi_impl()

void mpsort_mpi_impl ( void *  base,
size_t  nmemb,
size_t  elsize,
void(*)(const void *ptr, void *radix, void *arg)  radix,
size_t  rsize,
void *  arg,
MPI_Comm  comm,
const int  line,
const char *  file 
)

Definition at line 775 of file mpsort.c.

781 {
782  mpsort_mpi_newarray_impl(mybase, mynmemb,
783  mybase, mynmemb,
784  size, radix, rsize, arg, comm, line, file);
785 }
void mpsort_mpi_newarray_impl(void *mybase, size_t mynmemb, void *myoutbase, size_t myoutnmemb, size_t elsize, void(*radix)(const void *ptr, void *radix, void *arg), size_t rsize, void *arg, MPI_Comm comm, const int line, const char *file)
Definition: mpsort.c:809

References mpsort_mpi_newarray_impl().

Here is the call graph for this function:

◆ mpsort_mpi_newarray_impl()

void mpsort_mpi_newarray_impl ( void *  base,
size_t  nmemb,
void *  out,
size_t  outnmemb,
size_t  size,
void(*)(const void *ptr, void *radix, void *arg)  radix,
size_t  rsize,
void *  arg,
MPI_Comm  comm,
const int  line,
const char *  file 
)

Definition at line 809 of file mpsort.c.

818 {
819  if(MPI_TYPE_PTRDIFF == 0) {
820  if(MPI_SUCCESS != MPI_Type_match_size(MPI_TYPECLASS_INTEGER, sizeof(ptrdiff_t), &MPI_TYPE_PTRDIFF))
821  endrun(3, "Ptrdiff size %ld not recognised\n", sizeof(ptrdiff_t));
822  }
823 
824  struct SegmentGroupDescr seggrp[1];
825 
826  uint64_t sum1 = checksum(mybase, elsize * mynmemb, comm);
827 
828  int NTask;
829  int ThisTask;
830  MPI_Comm_size(comm, &NTask);
831  MPI_Comm_rank(comm, &ThisTask);
832 
833  if(elsize > 8 && elsize % 8 != 0) {
834  if(ThisTask == 0) {
835  endrun(12, "MPSort: element size is large (%d) but not aligned to 8 bytes. "
836  "This is known to frequently trigger MPI bugs. "
837  "Caller site: %s:%d\n",
838  elsize, file, line);
839  }
840  }
841  if(rsize > 8 && rsize % 8 != 0) {
842  if(ThisTask == 0) {
843  endrun(12, "MPSort: radix size is large (%d) but not aligned to 8 bytes. "
844  "This is known to frequently trigger MPI bugs. "
845  "Caller site: %s:%d\n",
846  rsize, file, line);
847  }
848  }
849 
850  size_t * sizes = ta_malloc("sizes", size_t, NTask);
851  size_t myoffset;
852  size_t totalsize = _collect_sizes(mynmemb, sizes, &myoffset, comm);
853 
854  size_t avgsegsize = NTask; /* combine very small ranks to segments */
855  if (avgsegsize * elsize > 4 * 1024 * 1024) {
856  /* do not use more than 4MB in a segment */
857  avgsegsize = 4 * 1024 * 1024 / elsize;
858  }
860  message(0, "MPSort: gathering all data to a single rank for sorting due to MPSORT_REQUIRE_GATHER_SORT. "
861  "Total number of items is %ld. Caller site: %s:%d\n",
862  totalsize, file, line);
863  avgsegsize = totalsize;
864  }
865 
867  avgsegsize = 0;
868  message(0, "MPSort: disable gathering data into larger chunks due to MPSORT_DISABLE_GATHER_SORT. "
869  "Caller site: %s:%d\n",
870  file, line);
871  }
872 
873  /* use as many groups as possible (some will be empty) but at most 1 segment per group */
874  _create_segment_group(seggrp, sizes, avgsegsize, NTask, comm);
875 
876  myfree(sizes);
877  /* group comm == seg comm */
878 
879  void * mysegmentbase = NULL;
880  void * myoutsegmentbase = NULL;
881  size_t mysegmentnmemb;
882  size_t myoutsegmentnmemb;
883 
884  int groupsize;
885  int grouprank;
886  MPI_Comm_size(seggrp->Group, &groupsize);
887  MPI_Comm_rank(seggrp->Group, &grouprank);
888 
889  MPI_Allreduce(&mynmemb, &mysegmentnmemb, 1, MPI_TYPE_PTRDIFF, MPI_SUM, seggrp->Group);
890  MPI_Allreduce(&myoutnmemb, &myoutsegmentnmemb, 1, MPI_TYPE_PTRDIFF, MPI_SUM, seggrp->Group);
891 
892  if (groupsize > 1) {
893  if(grouprank == seggrp->group_leader_rank) {
894  mysegmentbase = mymalloc("segmentbase", mysegmentnmemb * elsize);
895  myoutsegmentbase = mymalloc("outsegment", myoutsegmentnmemb * elsize);
896  }
897  MPIU_Gather(seggrp->Group, seggrp->group_leader_rank, mybase, mysegmentbase, mynmemb, elsize, NULL);
898  } else {
899  mysegmentbase = mybase;
900  myoutsegmentbase = myoutbase;
901  }
902 
903  /* only do sorting on the group leaders for each segment */
904  if(seggrp->is_group_leader) {
905 
906  struct crstruct d;
907  struct crmpistruct o;
908 
909  _setup_radix_sort(&d, mysegmentbase, mysegmentnmemb, elsize, radix, rsize, arg);
910 
911  _setup_mpsort_mpi(&o, &d, myoutsegmentbase, myoutsegmentnmemb, seggrp->Leaders);
912 
914 
916  }
917 
918  if(groupsize > 1) {
919  MPIU_Scatter(seggrp->Group, seggrp->group_leader_rank, myoutsegmentbase, myoutbase, myoutnmemb, elsize, NULL);
920  }
921 
922 /* {
923  int ntmr;
924  if(seggrp->is_group_leader)
925  ntmr = (mpsort_mpi_find_ntimers(tmr) + 1);
926 
927  MPI_Bcast(&ntmr, 1, MPI_INT, seggrp->group_leader_rank, seggrp->Group);
928  MPI_Bcast(tmr, sizeof(tmr[0]) * ntmr, MPI_BYTE, seggrp->group_leader_rank, seggrp->Group);
929  }*/
930 
931  if(grouprank == seggrp->group_leader_rank) {
932  if(myoutsegmentbase != myoutbase)
933  myfree(myoutsegmentbase);
934  if(mysegmentbase != mybase)
935  myfree(mysegmentbase);
936  }
937 
938  _destroy_segment_group(seggrp);
939 
940  uint64_t sum2 = checksum(myoutbase, elsize * myoutnmemb, comm);
941  if (sum1 != sum2) {
942  endrun(5, "Data changed after sorting; checksum mismatch.\n");
943  }
944 }
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
int mpsort_mpi_has_options(int options)
Definition: mpsort.c:1444
static uint64_t checksum(void *base, size_t nbytes, MPI_Comm comm)
Definition: mpsort.c:796
static size_t _collect_sizes(size_t localsize, size_t *sizes, size_t *myoffset, MPI_Comm comm)
Definition: mpsort.c:593
static void MPIU_Gather(MPI_Comm comm, int root, const void *sendbuffer, void *recvbuffer, int nsend, size_t elsize, int *totalnrecv)
Definition: mpsort.c:947
static void _create_segment_group(struct SegmentGroupDescr *descr, size_t *sizes, size_t avgsegsize, int Ngroup, MPI_Comm comm)
Definition: mpsort.c:670
static void _destroy_segment_group(struct SegmentGroupDescr *descr)
Definition: mpsort.c:715
static void _setup_mpsort_mpi(struct crmpistruct *o, struct crstruct *d, void *myoutbase, size_t myoutnmemb, MPI_Comm comm)
Definition: mpsort.c:493
static int mpsort_mpi_histogram_sort(struct crstruct d, struct crmpistruct o)
Definition: mpsort.c:1022
static void _destroy_mpsort_mpi(struct crmpistruct *o)
Definition: mpsort.c:523
static void MPIU_Scatter(MPI_Comm comm, int root, const void *sendbuffer, void *recvbuffer, int nrecv, size_t elsize, int *totalnsend)
Definition: mpsort.c:985
void _setup_radix_sort(struct crstruct *d, void *base, size_t nmemb, size_t size, void(*radix)(const void *ptr, void *radix, void *arg), size_t rsize, void *arg)
Definition: mpsort.c:129
static MPI_Datatype MPI_TYPE_PTRDIFF
Definition: mpsort.c:476
#define MPSORT_REQUIRE_GATHER_SORT
Definition: mpsort.h:6
#define MPSORT_DISABLE_GATHER_SORT
Definition: mpsort.h:5
#define mymalloc(name, size)
Definition: mymalloc.h:15
#define ta_malloc(name, type, nele)
Definition: mymalloc.h:25
size_t totalsize
Definition: mpsort.c:624
MPI_Comm comm
Definition: mpsort.c:481
size_t myoutnmemb
Definition: mpsort.c:486
void * mybase
Definition: mpsort.c:482
void * myoutbase
Definition: mpsort.c:483
int ThisTask
Definition: test_exchange.c:23
int NTask
Definition: test_exchange.c:23

References _collect_sizes(), _create_segment_group(), _destroy_mpsort_mpi(), _destroy_segment_group(), _setup_mpsort_mpi(), _setup_radix_sort(), checksum(), crmpistruct::comm, endrun(), SegmentGroupDescr::Group, SegmentGroupDescr::group_leader_rank, SegmentGroupDescr::is_group_leader, SegmentGroupDescr::Leaders, message(), MPI_TYPE_PTRDIFF, MPIU_Gather(), MPIU_Scatter(), MPSORT_DISABLE_GATHER_SORT, mpsort_mpi_has_options(), mpsort_mpi_histogram_sort(), MPSORT_REQUIRE_GATHER_SORT, crmpistruct::mybase, myfree, mymalloc, crmpistruct::myoutbase, crmpistruct::myoutnmemb, NTask, ta_malloc, ThisTask, and SegmentGroupDescr::totalsize.

Referenced by mpsort_mpi_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mpsort_mpi_report_last_run()

void mpsort_mpi_report_last_run ( )

Definition at line 756 of file mpsort.c.

756  {
757  if(!(_TIMERS.tmr))
758  return;
759  double last = _TIMERS.tmr[0].time;
760  int i;
761  for(i = 1; i < _TIMERS.curtmr; i++) {
762  struct TIMER * tmr = &_TIMERS.tmr[i];
763  if(0 == strncmp(tmr->name, "END", 20))
764  break;
765  message(0, "%s: %g\n", tmr->name, tmr->time - last);
766  last = tmr->time;
767  }
768 }
Definition: mpsort.c:543
char name[20]
Definition: mpsort.c:545
double time
Definition: mpsort.c:544

References _TIMERS, TIMERS::curtmr, message(), TIMER::name, TIMER::time, and TIMERS::tmr.

Here is the call graph for this function:

◆ mpsort_mpi_set_options()

void mpsort_mpi_set_options ( int  options)

Definition at line 1437 of file mpsort.c.

1438 {
1440  _mpsort_mpi_options |= options;
1441 }

References _mpsort_mpi_options, and _mpsort_mpi_parse_env().

Referenced by _mpsort_mpi_parse_env(), and do_mpsort_test().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mpsort_mpi_unset_options()

void mpsort_mpi_unset_options ( int  options)

Definition at line 1451 of file mpsort.c.

1452 {
1454  _mpsort_mpi_options &= ~options;
1455 
1456 }

References _mpsort_mpi_options, and _mpsort_mpi_parse_env().

Referenced by do_mpsort_test().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mpsort_setup_timers()

void mpsort_setup_timers ( int  ntimers)

Definition at line 736 of file mpsort.c.

737 {
738  if(!(_TIMERS.tmr)) {
739  _TIMERS.tmr = (struct TIMER *) mymalloc2("timers", ntimers * sizeof(struct TIMER));
740  _TIMERS.ntimer = ntimers;
741  _TIMERS.curtmr = 0;
742  }
743 }
#define mymalloc2(name, size)
Definition: mymalloc.h:16

References _TIMERS, TIMERS::curtmr, mymalloc2, TIMERS::ntimer, and TIMERS::tmr.

Referenced by do_mpsort_test().

Here is the caller graph for this function: