Skip to content

Commit

Permalink
[All] Replace qsort with faster std sort (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
noelchalmers authored Dec 24, 2020
1 parent 052f509 commit d2ad425
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 365 deletions.
6 changes: 3 additions & 3 deletions include/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ SOFTWARE.
#define CORE_HPP

#include <mpi.h>
#include <occa.h>
#include <occa.hpp>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <cmath>
#include <algorithm>
#include "utils.hpp"

// sort entries in an array in parallel
Expand Down
74 changes: 16 additions & 58 deletions libs/mesh/meshConnect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,56 +37,10 @@ typedef struct{
dlong elementNeighbor; // neighbor element
int faceNeighbor; // neighbor face

int NfaceVertices;

hlong v[4];

}face_t;

// comparison function that orders vertices
// based on their combined vertex indices
static int compareVertices(const void *a,
const void *b){

face_t *fa = (face_t*) a;
face_t *fb = (face_t*) b;

for(int n=0;n<fa->NfaceVertices;++n){
if(fa->v[n] < fb->v[n]) return -1;
if(fa->v[n] > fb->v[n]) return +1;
}

return 0;

}
/* comparison function that orders element/face
based on their indexes */
static int compareFaces(const void *a,
const void *b){

face_t *fa = (face_t*) a;
face_t *fb = (face_t*) b;

if(fa->element < fb->element) return -1;
if(fa->element > fb->element) return +1;

if(fa->face < fb->face) return -1;
if(fa->face > fb->face) return +1;

return 0;

}

static int isLower(const void *a, const void *b){

hlong *pta = (hlong*) a;
hlong *ptb = (hlong*) b;

if(*pta > *ptb) return -1;
if(*pta < *ptb) return +1;

return 0;
}

/* routine to find EToE (Element To Element)
and EToF (Element To Local Face) connectivity arrays */
Expand All @@ -105,9 +59,8 @@ void mesh_t::Connect(){
faces[cnt].v[n] = EToV[vid];
}

qsort(faces[cnt].v, NfaceVertices, sizeof(hlong), isLower);

faces[cnt].NfaceVertices = NfaceVertices;
std::sort(faces[cnt].v, faces[cnt].v+NfaceVertices,
std::less<hlong>());

faces[cnt].element = e;
faces[cnt].face = f;
Expand All @@ -120,15 +73,17 @@ void mesh_t::Connect(){
}

/* sort faces by their vertex number pairs */
qsort(faces,
Nelements*Nfaces,
sizeof(face_t),
compareVertices);
std::sort(faces, faces+Nelements*Nfaces,
[&](const face_t& a, const face_t& b) {
return std::lexicographical_compare(a.v, a.v+NfaceVertices,
b.v, b.v+NfaceVertices);
});

/* scan through sorted face lists looking for adjacent
faces that have the same vertex ids */
for(cnt=0;cnt<Nelements*Nfaces-1;++cnt){
if(!compareVertices(faces+cnt, faces+cnt+1)){
if(std::equal(faces[cnt].v, faces[cnt].v+NfaceVertices,
faces[cnt+1].v)){
// match
faces[cnt].elementNeighbor = faces[cnt+1].element;
faces[cnt].faceNeighbor = faces[cnt+1].face;
Expand All @@ -139,10 +94,13 @@ void mesh_t::Connect(){
}

/* resort faces back to the original element/face ordering */
qsort(faces,
Nelements*Nfaces,
sizeof(face_t),
compareFaces);
std::sort(faces, faces+Nelements*Nfaces,
[](const face_t& a, const face_t& b) {
if(a.element < b.element) return true;
if(a.element > b.element) return false;

return (a.face < b.face);
});

/* extract the element to element and element to face connectivity */
EToE = (dlong*) calloc(Nelements*Nfaces, sizeof(dlong));
Expand Down
46 changes: 11 additions & 35 deletions libs/mesh/meshConnectBoundary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,12 @@ typedef struct{
dlong element;
int face;

int NfaceVertices;

hlong v[4]; // max number of face vertices

int bctype;

}boundaryFace_t;

// comparison function that orders vertices
// based on their combined vertex indices
static int compareBoundaryFaces(const void *a,
const void *b){

boundaryFace_t *fa = (boundaryFace_t*) a;
boundaryFace_t *fb = (boundaryFace_t*) b;

for(int n=0;n<fa->NfaceVertices;++n){
if(fa->v[n] < fb->v[n]) return -1;
if(fa->v[n] > fb->v[n]) return +1;
}

return 0;

}

static int isLower(const void *a, const void *b){

hlong *pta = (hlong*) a;
hlong *ptb = (hlong*) b;

if(*pta > *ptb) return -1;
if(*pta < *ptb) return +1;

return 0;
}

/* routine to find EToB (Element To Boundary)*/
void mesh_t::ConnectBoundary(){
Expand Down Expand Up @@ -101,9 +72,9 @@ void mesh_t::ConnectBoundary(){
boundaryFaces[bcnt].v[n] = EToV[vid];
}

qsort(boundaryFaces[bcnt].v,NfaceVertices, sizeof(hlong), isLower);
std::sort(boundaryFaces[bcnt].v, boundaryFaces[bcnt].v+NfaceVertices,
std::less<hlong>());

boundaryFaces[bcnt].NfaceVertices = NfaceVertices;
boundaryFaces[bcnt].element = e;
boundaryFaces[bcnt].face = f;
boundaryFaces[bcnt].bctype = -1;
Expand All @@ -118,9 +89,9 @@ void mesh_t::ConnectBoundary(){
for(int n=0;n<NfaceVertices;++n)
boundaryFaces[bcnt].v[n] = boundaryInfo[b*(NfaceVertices+1)+n+1];

qsort(boundaryFaces[bcnt].v,NfaceVertices, sizeof(hlong), isLower);
std::sort(boundaryFaces[bcnt].v, boundaryFaces[bcnt].v+NfaceVertices,
std::less<hlong>());

boundaryFaces[bcnt].NfaceVertices = NfaceVertices;
boundaryFaces[bcnt].element = -1;
boundaryFaces[bcnt].face = -1;
boundaryFaces[bcnt].bctype = boundaryInfo[b*(NfaceVertices+1)];
Expand All @@ -142,14 +113,19 @@ void mesh_t::ConnectBoundary(){
#endif

/* sort boundaryFaces by their vertex number pairs */
qsort(boundaryFaces, bcnt, sizeof(boundaryFace_t), compareBoundaryFaces);
std::sort(boundaryFaces, boundaryFaces+bcnt,
[&](const boundaryFace_t& a, const boundaryFace_t& b) {
return std::lexicographical_compare(a.v, a.v+NfaceVertices,
b.v, b.v+NfaceVertices);
});

/* scan through sorted face lists looking for element-boundary matches */
EToB = (int*) calloc(Nelements*Nfaces, sizeof(int));
for(dlong n=0;n<Nelements*Nfaces;++n) EToB[n] = -1;

for(hlong cnt=0;cnt<bcnt-1;++cnt){
if(!compareBoundaryFaces(boundaryFaces+cnt, boundaryFaces+cnt+1)){
if(std::equal(boundaryFaces[cnt].v, boundaryFaces[cnt].v+NfaceVertices,
boundaryFaces[cnt+1].v)){
dlong e = mymax(boundaryFaces[cnt].element, boundaryFaces[cnt+1].element);
int f = mymax(boundaryFaces[cnt].face, boundaryFaces[cnt+1].face);

Expand Down
62 changes: 16 additions & 46 deletions libs/mesh/meshHaloRingSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,48 +35,6 @@ typedef struct{

}vertex_t;

// comparator on destination rank
static int compareDest(const void *a,
const void *b){

vertex_t *va = (vertex_t*) a;
vertex_t *vb = (vertex_t*) b;

if(va->dest < vb->dest) return -1;
if(va->dest > vb->dest) return +1;

return 0;
}

// comparator on global id
static int compareGlobalId(const void *a,
const void *b){

vertex_t *va = (vertex_t*) a;
vertex_t *vb = (vertex_t*) b;

if(va->gid < vb->gid) return -1;
if(va->gid > vb->gid) return +1;

return 0;
}

// comparator on rank and element
static int compareRank(const void *a,
const void *b){

vertex_t *va = (vertex_t*) a;
vertex_t *vb = (vertex_t*) b;

if(va->rank < vb->rank) return -1;
if(va->rank > vb->rank) return +1;

if(va->element < vb->element) return -1;
if(va->element > vb->element) return +1;

return 0;
}

// set up halo exchange for entire boundary ring elements for inter-processor MPI
// exchange of trace nodes
void mesh_t::HaloRingSetup(){
Expand Down Expand Up @@ -161,7 +119,9 @@ void mesh_t::HaloRingSetup(){
free(minRank); free(maxRank);

// sort based on destination (=gid%size)
qsort(vertexSendList, NsendVerts, sizeof(vertex_t), compareDest);
std::sort(vertexSendList, vertexSendList+NsendVerts,
[](const vertex_t& a, const vertex_t& b)
{return a.dest < b.dest;});

// share counts
MPI_Alltoall(vertexSendCounts, 1, MPI_INT,
Expand All @@ -184,7 +144,9 @@ void mesh_t::HaloRingSetup(){
comm);

// sort based on globalId to find matches
qsort(vertexRecvList, NrecvVerts, sizeof(vertex_t), compareGlobalId);
std::sort(vertexRecvList, vertexRecvList+NrecvVerts,
[](const vertex_t& a, const vertex_t& b)
{return a.gid < b.gid;});

//count the number of unique vertices we have
dlong Nunique=(NrecvVerts) ? 1:0; //at least one if there's any
Expand Down Expand Up @@ -247,7 +209,9 @@ void mesh_t::HaloRingSetup(){
}

// sort based on destination
qsort(vertexSendList, NsendVerts, sizeof(vertex_t), compareDest);
std::sort(vertexSendList, vertexSendList+NsendVerts,
[](const vertex_t& a, const vertex_t& b)
{return a.dest < b.dest;});

// share counts
MPI_Alltoall(vertexSendCounts, 1, MPI_INT,
Expand All @@ -271,7 +235,13 @@ void mesh_t::HaloRingSetup(){
comm);

// sort based on rank then element id to find matches
qsort(vertexRecvList, NrecvVerts, sizeof(vertex_t), compareRank);
std::sort(vertexRecvList, vertexRecvList+NrecvVerts,
[](const vertex_t& a, const vertex_t& b) {
if(a.rank < b.rank) return true;
if(a.rank > b.rank) return false;

return a.element < b.element;
});

//count the number of elements in the 1-ring
totalRingElements=(NrecvVerts) ? 1:0;
Expand Down
Loading

0 comments on commit d2ad425

Please sign in to comment.