remove need for static class member variables in Dump and Irregular
The dump and irregular classes were using qsort() from the C-library for sorting lists through custom comparison functions, which required access to additional data, which was passed via static class variables, i.e. globals. This collides with having multiple LAMMPS instances in the same address space. the calls to qsort() are replaced with a custom merge sort, which passes a void pointer to the comparison functions, which can contain any kind of desired information, e.g. a class handle or a list
This commit is contained in:
79
src/dump.cpp
79
src/dump.cpp
@ -30,9 +30,7 @@
|
|||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
// allocate space for static class variable
|
#include "mergesort.h"
|
||||||
|
|
||||||
Dump *Dump::dumpptr;
|
|
||||||
|
|
||||||
#define BIG 1.0e20
|
#define BIG 1.0e20
|
||||||
#define EPSILON 1.0e-6
|
#define EPSILON 1.0e-6
|
||||||
@ -690,11 +688,10 @@ void Dump::sort()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!reorderflag) {
|
if (!reorderflag) {
|
||||||
dumpptr = this;
|
|
||||||
for (i = 0; i < nme; i++) index[i] = i;
|
for (i = 0; i < nme; i++) index[i] = i;
|
||||||
if (sortcol == 0) qsort(index,nme,sizeof(int),idcompare);
|
if (sortcol==0) merge_sort(index,nme,(void *)this,idcompare);
|
||||||
else if (sortorder == ASCEND) qsort(index,nme,sizeof(int),bufcompare);
|
else if (sortorder==ASCEND) merge_sort(index,nme,(void *)this,bufcompare);
|
||||||
else qsort(index,nme,sizeof(int),bufcompare_reverse);
|
else merge_sort(index,nme,(void *)this,bufcompare_reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset buf size and maxbuf to largest of any post-sort nme values
|
// reset buf size and maxbuf to largest of any post-sort nme values
|
||||||
@ -718,62 +715,52 @@ void Dump::sort()
|
|||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compare two atom IDs
|
compare two atom IDs
|
||||||
called via qsort() in sort() method
|
called via merge_sort() in sort() method
|
||||||
is a static method so access data via dumpptr
|
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
int Dump::idcompare(const int i, const int j, void *ptr) {
|
||||||
int Dump::idcompare(const void *pi, const void *pj)
|
tagint *idsort = ((Dump *)ptr)->idsort;
|
||||||
{
|
|
||||||
tagint *idsort = dumpptr->idsort;
|
|
||||||
|
|
||||||
int i = *((int *) pi);
|
|
||||||
int j = *((int *) pj);
|
|
||||||
|
|
||||||
if (idsort[i] < idsort[j]) return -1;
|
if (idsort[i] < idsort[j]) return -1;
|
||||||
if (idsort[i] > idsort[j]) return 1;
|
else if (idsort[i] > idsort[j]) return 1;
|
||||||
return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compare two buffer values with size_one stride
|
compare two buffer values with size_one stride
|
||||||
called via qsort() in sort() method
|
called via merge_sort() in sort() method
|
||||||
is a static method so access data via dumpptr
|
|
||||||
sort in ASCENDing order
|
sort in ASCENDing order
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int Dump::bufcompare(const void *pi, const void *pj)
|
int Dump::bufcompare(const int i, const int j, void *ptr) {
|
||||||
{
|
Dump *dptr = (Dump *) ptr;
|
||||||
double *bufsort = dumpptr->bufsort;
|
double *bufsort = dptr->bufsort;
|
||||||
int size_one = dumpptr->size_one;
|
const int size_one = dptr->size_one;
|
||||||
int sortcolm1 = dumpptr->sortcolm1;
|
const int sortcolm1 = dptr->sortcolm1;
|
||||||
|
|
||||||
int i = *((int *) pi)*size_one + sortcolm1;
|
const int ii=i*size_one + sortcolm1;
|
||||||
int j = *((int *) pj)*size_one + sortcolm1;
|
const int jj=j*size_one + sortcolm1;
|
||||||
|
|
||||||
if (bufsort[i] < bufsort[j]) return -1;
|
if (bufsort[ii] < bufsort[jj]) return -1;
|
||||||
if (bufsort[i] > bufsort[j]) return 1;
|
else if (bufsort[ii] > bufsort[jj]) return 1;
|
||||||
return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compare two buffer values with size_one stride
|
compare two buffer values with size_one stride
|
||||||
called via qsort() in sort() method
|
called via merge_sort() in sort() method
|
||||||
is a static method so access data via dumpptr
|
|
||||||
sort in DESCENDing order
|
sort in DESCENDing order
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int Dump::bufcompare_reverse(const void *pi, const void *pj)
|
int Dump::bufcompare_reverse(const int i, const int j, void *ptr) {
|
||||||
{
|
Dump *dptr = (Dump *) ptr;
|
||||||
double *bufsort = dumpptr->bufsort;
|
double *bufsort = dptr->bufsort;
|
||||||
int size_one = dumpptr->size_one;
|
const int size_one = dptr->size_one;
|
||||||
int sortcolm1 = dumpptr->sortcolm1;
|
const int sortcolm1 = dptr->sortcolm1;
|
||||||
|
|
||||||
int i = *((int *) pi)*size_one + sortcolm1;
|
const int ii=i*size_one + sortcolm1;
|
||||||
int j = *((int *) pj)*size_one + sortcolm1;
|
const int jj=j*size_one + sortcolm1;
|
||||||
|
|
||||||
if (bufsort[i] > bufsort[j]) return -1;
|
if (bufsort[ii] < bufsort[jj]) return 1;
|
||||||
if (bufsort[i] < bufsort[j]) return 1;
|
else if (bufsort[ii] > bufsort[jj]) return -1;
|
||||||
return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
|
|||||||
10
src/dump.h
10
src/dump.h
@ -33,10 +33,6 @@ class Dump : protected Pointers {
|
|||||||
int comm_forward; // size of forward communication (0 if none)
|
int comm_forward; // size of forward communication (0 if none)
|
||||||
int comm_reverse; // size of reverse communication (0 if none)
|
int comm_reverse; // size of reverse communication (0 if none)
|
||||||
|
|
||||||
// static variable across all Dump objects
|
|
||||||
|
|
||||||
static Dump *dumpptr; // holds a ptr to Dump currently being used
|
|
||||||
|
|
||||||
Dump(class LAMMPS *, int, char **);
|
Dump(class LAMMPS *, int, char **);
|
||||||
virtual ~Dump();
|
virtual ~Dump();
|
||||||
void init();
|
void init();
|
||||||
@ -134,9 +130,9 @@ class Dump : protected Pointers {
|
|||||||
void pbc_allocate();
|
void pbc_allocate();
|
||||||
|
|
||||||
void sort();
|
void sort();
|
||||||
static int idcompare(const void *, const void *);
|
static int idcompare(const int, const int, void *);
|
||||||
static int bufcompare(const void *, const void *);
|
static int bufcompare(const int, const int, void *);
|
||||||
static int bufcompare_reverse(const void *, const void *);
|
static int bufcompare_reverse(const int, const int, void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,13 +21,13 @@
|
|||||||
#include "comm.h"
|
#include "comm.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
#include "mergesort.h"
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
// allocate space for static class variable
|
|
||||||
// prototype for non-class function
|
// prototype for non-class function
|
||||||
|
|
||||||
int *Irregular::proc_recv_copy;
|
static int compare_standalone(const int, const int, void *);
|
||||||
int compare_standalone(const void *, const void *);
|
|
||||||
|
|
||||||
enum{LAYOUT_UNIFORM,LAYOUT_NONUNIFORM,LAYOUT_TILED}; // several files
|
enum{LAYOUT_UNIFORM,LAYOUT_NONUNIFORM,LAYOUT_TILED}; // several files
|
||||||
|
|
||||||
@ -423,8 +423,7 @@ int Irregular::create_atom(int n, int *sizes, int *proclist, int sortflag)
|
|||||||
int *length_recv_ordered = new int[nrecv_proc];
|
int *length_recv_ordered = new int[nrecv_proc];
|
||||||
|
|
||||||
for (i = 0; i < nrecv_proc; i++) order[i] = i;
|
for (i = 0; i < nrecv_proc; i++) order[i] = i;
|
||||||
proc_recv_copy = proc_recv;
|
merge_sort(order,nrecv_proc,(void *)proc_recv,compare_standalone);
|
||||||
qsort(order,nrecv_proc,sizeof(int),compare_standalone);
|
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for (i = 0; i < nrecv_proc; i++) {
|
for (i = 0; i < nrecv_proc; i++) {
|
||||||
@ -451,15 +450,13 @@ int Irregular::create_atom(int n, int *sizes, int *proclist, int sortflag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
comparison function invoked by qsort()
|
comparison function invoked by merge_sort()
|
||||||
accesses static class member proc_recv_copy, set before call to qsort()
|
void pointer contains proc_recv list;
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int compare_standalone(const void *iptr, const void *jptr)
|
int compare_standalone(const int i, const int j, void *ptr)
|
||||||
{
|
{
|
||||||
int i = *((int *) iptr);
|
int *proc_recv = (int *) ptr;
|
||||||
int j = *((int *) jptr);
|
|
||||||
int *proc_recv = Irregular::proc_recv_copy;
|
|
||||||
if (proc_recv[i] < proc_recv[j]) return -1;
|
if (proc_recv[i] < proc_recv[j]) return -1;
|
||||||
if (proc_recv[i] > proc_recv[j]) return 1;
|
if (proc_recv[i] > proc_recv[j]) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -671,8 +668,7 @@ int Irregular::create_data(int n, int *proclist, int sortflag)
|
|||||||
int *num_recv_ordered = new int[nrecv_proc];
|
int *num_recv_ordered = new int[nrecv_proc];
|
||||||
|
|
||||||
for (i = 0; i < nrecv_proc; i++) order[i] = i;
|
for (i = 0; i < nrecv_proc; i++) order[i] = i;
|
||||||
proc_recv_copy = proc_recv;
|
merge_sort(order,nrecv_proc,(void *)proc_recv,compare_standalone);
|
||||||
qsort(order,nrecv_proc,sizeof(int),compare_standalone);
|
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for (i = 0; i < nrecv_proc; i++) {
|
for (i = 0; i < nrecv_proc; i++) {
|
||||||
|
|||||||
@ -21,10 +21,6 @@ namespace LAMMPS_NS {
|
|||||||
class Irregular : protected Pointers {
|
class Irregular : protected Pointers {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// static variable across all Irregular objects, for qsort callback
|
|
||||||
|
|
||||||
static int *proc_recv_copy;
|
|
||||||
|
|
||||||
Irregular(class LAMMPS *);
|
Irregular(class LAMMPS *);
|
||||||
~Irregular();
|
~Irregular();
|
||||||
void migrate_atoms(int sortflag = 0, int preassign = 0,
|
void migrate_atoms(int sortflag = 0, int preassign = 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user