Mise à jour terminée. Pour connaître les apports de la version 13.8.4 par rapport à notre ancienne version vous pouvez lire les "Release Notes" suivantes :
https://about.gitlab.com/releases/2021/02/11/security-release-gitlab-13-8-4-released/
https://about.gitlab.com/releases/2021/02/05/gitlab-13-8-3-released/

Commit 68b61e3b authored by berenger-bramas's avatar berenger-bramas

Update sorting algorithm (refactoring)

and clean code.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@222 2616d619-271b-44dc-8df4-d4a8f33a7222
parent ec1dfab0
......@@ -9,7 +9,7 @@ endif(insource)
# Options
OPTION( SCALFMM_USE_CBLAS "Set to ON to build ScaFMM with BLAS" ON )
OPTION( SCALFMM_USE_MPI "Set to ON to build ScaFMM with MPI" ON )
OPTION( SCALFMM_USE_TRACE "Set to ON to print trace or use itac trace" ON )
OPTION( SCALFMM_USE_TRACE "Set to ON to print trace or use itac trace" OFF )
OPTION( SCALFMM_BUILD_TESTS "Set to ON to build fonctionnalities Tests" ON )
OPTION( SCALFMM_BUILD_UTESTS "Set to ON to build UTests" ON )
OPTION( SCALFMM_BUILD_DEBUG "Set to ON to build in Debug" OFF )
......
......@@ -3,7 +3,7 @@
#include "../Utils/FMpi.hpp"
#include "../Utils/FQuickSort.hpp"
#include "../Utils/BitonicSort.hpp"
#include "../Utils/FBitonicSort.hpp"
#include "../Utils/FMemUtils.hpp"
#include "../Utils/FTrace.hpp"
......@@ -165,11 +165,12 @@ public:
}
// sort particles
//FQuickSort::QsMpi<IndexedParticle,MortonIndex>(realParticlesIndexed, loader.getNumberOfParticles(),outputArray,outputSize);
//delete [] (realParticlesIndexed);
FQuickSort<IndexedParticle,MortonIndex, FSize>::QsMpi(realParticlesIndexed, loader.getNumberOfParticles(),outputArray,outputSize);
delete [] (realParticlesIndexed);
BitonicSort::sort<IndexedParticle,MortonIndex>( realParticlesIndexed, loader.getNumberOfParticles() );
outputArray = realParticlesIndexed;
//FBitonicSort::sort<IndexedParticle,MortonIndex>( realParticlesIndexed, loader.getNumberOfParticles() );
//outputArray = realParticlesIndexed;
//outputSize = loader.getNumberOfParticles();
}
// be sure there is no splited leaves
// to do that we exchange the first index with the left proc
......@@ -407,9 +408,16 @@ public:
const FSize iNeedToSendRightCount = currentLeafsOnMyLeft + currentNbLeafs - correctRightLeavesIndex;
endForMe -= iNeedToSendRightCount;
}
printf("iNeedToSendToLeft %s\n", iNeedToSendToLeft?"True":"False");
printf("iNeedToSendToRight %s\n", iNeedToSendToRight?"True":"False");
printf("currentNbLeafs %lld\n",currentNbLeafs);
printf("iNeedToSendLeftCount %lld\n",iNeedToSendLeftCount);
printf("correctLeftLeavesNumber %lld\n",correctLeftLeavesNumber);
printf("currentLeafsOnMyLeft %lld\n",currentLeafsOnMyLeft);
printf("endForMe %lld\n",endForMe);
// We have to jump the correct number of leaves
for(FSize idxLeaf = iNeedToSendLeftCount ; idxLeaf < endForMe ; ++idxLeaf){
for(FSize idxLeaf = Max(iNeedToSendLeftCount,0) ; idxLeaf < endForMe ; ++idxLeaf){
const int nbPartInLeaf = (*(int*)&intervals[currentIntervalPosition]);
currentIntervalPosition += (nbPartInLeaf * sizeof(ParticleClass)) + sizeof(int);
}
......@@ -513,7 +521,7 @@ public:
endForMe -= iNeedToSendRightCount;
}
for(FSize idxLeaf = iNeedToSendLeftCount ; idxLeaf < endForMe ; ++idxLeaf){
for(FSize idxLeaf = Max(iNeedToSendLeftCount,0) ; idxLeaf < endForMe ; ++idxLeaf){
const int nbPartInLeaf = (*(int*)&intervals[currentIntervalPosition]);
ParticleClass* const particles = reinterpret_cast<ParticleClass*>(&intervals[currentIntervalPosition] + sizeof(int));
......
......@@ -8,60 +8,11 @@
#include "FTrace.hpp"
#include "FMpi.hpp"
#include "FQuickSort.hpp"
class FBitonicSort {
private:
////////////////////////////////////////////////////////////////
// Sequential sort first!
////////////////////////////////////////////////////////////////
template <class SortType>
static inline void swap(SortType& v1, SortType& v2){
const SortType tmp = v1;
v1 = v2;
v2 = tmp;
}
template <class SortType, class CompareType, class FSize>
static FSize partition(SortType* const array, FSize left, FSize right){
FSize part = right;
swap( array[part], array[(right+left) / 2]);
--right;
while(true){
while( CompareType(array[left]) < CompareType(array[part]) ){
++left;
}
while(right >= left && CompareType(array[part]) <= CompareType(array[right])){
--right;
}
if(right < left) break;
swap(array[left],array[right]);
++left;
--right;
}
swap(array[part],array[left]);
return left;
}
template <class SortType, class CompareType, class FSize>
static void qs(SortType* const array, const FSize left, const FSize right){
if(left < right){
const FSize part = partition<SortType,CompareType>(array, left, right);
qs<SortType,CompareType>(array,part + 1,right);
qs<SortType,CompareType>(array,left,part - 1);
}
}
template <class SortType, class CompareType, class FSize>
static void quick(SortType* const array, const FSize size){
qs<SortType,CompareType,FSize>(array,0,size-1);
}
////////////////////////////////////////////////////////////////
// Bitonic parallel sort !
////////////////////////////////////////////////////////////////
......@@ -74,11 +25,11 @@ private:
// This function exchange data with the other rank,
// its send the max value and receive min value
template <class SortType, class CompareType, class FSize>
static void sendMaxAndGetMin(SortType array[], const FSize size, const int otherRank){
FSize left = -1;
FSize right = size - 1;
FSize pivot = left + (right - left + 1)/2;
template <class SortType, class CompareType, class IndexType>
static void sendMaxAndGetMin(SortType array[], const IndexType size, const int otherRank){
IndexType left = -1;
IndexType right = size - 1;
IndexType pivot = left + (right - left + 1)/2;
CompareType otherValue = -1;
CompareType tempCompareValue = CompareType(array[pivot]);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMin,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMax,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
......@@ -115,11 +66,11 @@ private:
// This function exchange data with the other rank,
// its send the min value and receive max value
template <class SortType, class CompareType, class FSize>
static void sendMinAndGetMax(SortType array[], const FSize size, const int otherRank){
FSize left = 0;
FSize right = size ;
FSize pivot = left + (right - left)/2;
template <class SortType, class CompareType, class IndexType>
static void sendMinAndGetMax(SortType array[], const IndexType size, const int otherRank){
IndexType left = 0;
IndexType right = size ;
IndexType pivot = left + (right - left)/2;
CompareType otherValue = -1;
CompareType tempCompareValue = CompareType(array[pivot]);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMax,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMin,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
......@@ -176,11 +127,11 @@ public:
endfor
endfor
*/
template <class SortType, class CompareType, class FSize>
static void sort(SortType array[], const FSize size, const int np, const int rank){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Quicksort" , __FILE__ , __LINE__) );
template <class SortType, class CompareType, class IndexType>
static void sort(SortType array[], const IndexType size, const int np, const int rank){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Bitonic" , __FILE__ , __LINE__) );
quick<SortType,CompareType>(array, size);
FQuickSort<SortType,CompareType,IndexType>::QsOmp(array, size);
const int logNp = int(log2(np));
for(int bitIdx = 1 ; bitIdx <= logNp ; ++bitIdx){
......@@ -202,13 +153,13 @@ public:
}
// A merge sort is possible since the array is composed
// by two part already sorted, but we want to do this in space
quick<SortType,CompareType>(array, size);
FQuickSort<SortType,CompareType,IndexType>::QsOmp(array, size);
}
}
}
template <class SortType, class CompareType, class FSize>
static void sort(SortType array[], const FSize size){
template <class SortType, class CompareType, class IndexType>
static void sort(SortType array[], const IndexType size){
int rank = 0;
int nprocs = 0;
......
......@@ -16,6 +16,7 @@
#include "FOmpBarrier.hpp"
template <class SortType, class CompareType, class IndexType>
class FQuickSort {
////////////////////////////////////////////////////////////
// Miscialenous functions
......@@ -47,19 +48,19 @@ class FQuickSort {
// Split information
////////////////////////////////////////////////////////////
static FSize getLeft(const FSize inSize, const int inIdProc, const int inNbProc) {
static IndexType getLeft(const IndexType inSize, const int inIdProc, const int inNbProc) {
const double step = (double(inSize) / inNbProc);
return FSize(ceil(step * inIdProc));
return IndexType(ceil(step * inIdProc));
}
static FSize getRight(const FSize inSize, const int inIdProc, const int inNbProc) {
static IndexType getRight(const IndexType inSize, const int inIdProc, const int inNbProc) {
const double step = (double(inSize) / inNbProc);
const FSize res = FSize(ceil(step * (inIdProc+1)));
const IndexType res = IndexType(ceil(step * (inIdProc+1)));
if(res > inSize) return inSize;
else return res;
}
static int getProc(const FSize position, const FSize inSize, const int inNbProc) {
static int getProc(const IndexType position, const IndexType inSize, const int inNbProc) {
const double step = double(inSize) / double(inNbProc);
return int(double(position)/step);
}
......@@ -95,12 +96,11 @@ class FQuickSort {
}
/** get the pivot from several procs in Comm */
template <class PivotType>
static PivotType MpiGetPivot(PivotType myData, MPI_Comm& comm, const int nbProcs){
PivotType result[nbProcs];
mpiassert( MPI_Allgather( &myData, sizeof(PivotType), MPI_BYTE, result, sizeof(PivotType), MPI_BYTE, comm), __LINE__ );
static CompareType MpiGetPivot(CompareType myData, MPI_Comm& comm, const int nbProcs){
CompareType result[nbProcs];
mpiassert( MPI_Allgather( &myData, sizeof(CompareType), MPI_BYTE, result, sizeof(CompareType), MPI_BYTE, comm), __LINE__ );
// We do an average of the first element of each proc array
PivotType sum = 0;
CompareType sum = 0;
for(int idxProc = 0 ; idxProc < nbProcs ;++idxProc){
sum += result[idxProc] / nbProcs;
}
......@@ -129,17 +129,16 @@ class FQuickSort {
////////////////////////////////////////////////////////////
/* use in the sequential qs */
template <class SortType, class PivotType>
static FSize QsPartition(SortType array[], FSize left, FSize right){
const FSize part = right;
static IndexType QsPartition(SortType array[], IndexType left, IndexType right){
const IndexType part = right;
Swap(array[part],array[(right + left ) / 2]);
--right;
while(true){
while(PivotType(array[left]) < PivotType(array[part])){
while(CompareType(array[left]) < CompareType(array[part])){
++left;
}
while(right >= left && PivotType(array[part]) <= PivotType(array[right])){
while(right >= left && CompareType(array[part]) <= CompareType(array[right])){
--right;
}
if(right < left) break;
......@@ -155,19 +154,18 @@ class FQuickSort {
}
/* a local iteration of qs */
template <class SortType, class PivotType>
static void QsLocal(SortType array[], const PivotType& pivot,
FSize myLeft, FSize myRight,
FSize& prefix, FSize& sufix){
static void QsLocal(SortType array[], const CompareType& pivot,
IndexType myLeft, IndexType myRight,
IndexType& prefix, IndexType& sufix){
FSize leftIter = myLeft;
FSize rightIter = myRight;
IndexType leftIter = myLeft;
IndexType rightIter = myRight;
while(true){
while(PivotType(array[leftIter]) <= pivot && leftIter < rightIter){
while(CompareType(array[leftIter]) <= pivot && leftIter < rightIter){
++leftIter;
}
while(leftIter <= rightIter && pivot < PivotType(array[rightIter])){
while(leftIter <= rightIter && pivot < CompareType(array[rightIter])){
--rightIter;
}
if(rightIter < leftIter) break;
......@@ -181,24 +179,39 @@ class FQuickSort {
sufix = myRight - myLeft - prefix + 1;
}
public:
/* a sequential qs */
template <class SortType, class PivotType>
static void QsSequential(SortType array[], const FSize left, const FSize right){
static void QsSequentialStep(SortType array[], const IndexType left, const IndexType right){
if(left < right){
const FSize part = QsPartition<SortType,PivotType>(array, left, right);
QsSequential<SortType,PivotType>(array,part + 1,right);
QsSequential<SortType,PivotType>(array,left,part - 1);
const IndexType part = QsPartition(array, left, right);
QsSequentialStep(array,part + 1,right);
QsSequentialStep(array,left,part - 1);
}
}
/** A task dispatcher */
static void QsOmpTask(SortType array[], const IndexType left, const IndexType right, const int deep){
if(left < right){
if( deep ){
const IndexType part = QsPartition(array, left, right);
#pragma omp task
QsOmpTask(array,part + 1,right, deep - 1);
#pragma omp task
QsOmpTask(array,left,part - 1, deep - 1);
}
else {
const IndexType part = QsPartition(array, left, right);
QsSequentialStep(array,part + 1,right);
QsSequentialStep(array,left,part - 1);
}
}
}
/* the openmp qs */
template <class SortType, class PivotType>
static void QsOmp(SortType array[], const FSize size){
static void QsOmpNoTask(SortType array[], const IndexType size){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Quicksort" , __FILE__ , __LINE__) );
struct Fix{
FSize pre;
FSize suf;
IndexType pre;
IndexType suf;
};
const int NbOfThreads = omp_get_max_threads();
......@@ -217,25 +230,25 @@ public:
{
const int myThreadId = omp_get_thread_num();
FSize myLeft = getLeft(size, myThreadId, omp_get_num_threads());
FSize myRight = getRight(size, myThreadId, omp_get_num_threads()) - 1;
IndexType myLeft = getLeft(size, myThreadId, omp_get_num_threads());
IndexType myRight = getRight(size, myThreadId, omp_get_num_threads()) - 1;
FSize startIndex = 0;
FSize endIndex = size - 1;
IndexType startIndex = 0;
IndexType endIndex = size - 1;
int firstProc = 0;
int lastProc = omp_get_num_threads() - 1;
while( firstProc != lastProc && (endIndex - startIndex + 1) != 0){
Fix* const fixesSum = &allFixesSum[0][firstProc];
const FSize nbElements = endIndex - startIndex + 1;
const IndexType nbElements = endIndex - startIndex + 1;
if(myThreadId == firstProc){
barriers[firstProc].setNbThreads( lastProc - firstProc + 1);
}
// sort QsLocal part of the array
const PivotType pivot = (PivotType(array[startIndex]) + PivotType(array[endIndex]) )/2;
const CompareType pivot = (CompareType(array[startIndex]) + CompareType(array[endIndex]) )/2;
barriers[firstProc].wait();
QsLocal(array, pivot, myLeft, myRight, fixes[myThreadId].pre, fixes[myThreadId].suf);
......@@ -266,7 +279,7 @@ public:
FMemUtils::memcpy(&array[startIndex + fixesSum[myThreadId].pre], &temporaryArray[myLeft], sizeof(SortType) * fixes[myThreadId].pre);
// copy my result where it belong (> pivot)
const FSize sufoffset = fixesSum[lastProc + 1].pre + startIndex;
const IndexType sufoffset = fixesSum[lastProc + 1].pre + startIndex;
FMemUtils::memcpy(&array[sufoffset + fixesSum[myThreadId].suf], &temporaryArray[myLeft + fixes[myThreadId].pre ], sizeof(SortType) * fixes[myThreadId].suf);
barriers[firstProc].wait();
......@@ -290,20 +303,40 @@ public:
myRight = getRight(endIndex - startIndex + 1, myThreadId - firstProc, lastProc - firstProc + 1) + startIndex - 1;
}
QsSequential<SortType,PivotType>(array,myLeft,myRight);
QsSequentialStep(array,myLeft,myRight);
}
delete[] reinterpret_cast<char*>(temporaryArray);
}
public:
/* a sequential qs */
static void QsSequential(SortType array[], const IndexType size){
QsSequentialStep(array,0,size-1);
}
/** The openmp quick sort */
static void QsOmp(SortType array[], const IndexType size){
#if _OPENMP >= 200805
#pragma omp parallel
{
#pragma omp single nowait
{
QsOmpTask(array, 0, size - 1 , 15);
}
}
#else
QsOmpNoTask(array, size);
#endif
}
/* the mpi qs */
template <class SortType, class PivotType>
static void QsMpi(const SortType originalArray[], FSize size, SortType* & outputArray, FSize& outputSize, MPI_Comm originalComm = MPI_COMM_WORLD){
static void QsMpi(const SortType originalArray[], IndexType size, SortType* & outputArray, IndexType& outputSize, MPI_Comm originalComm = MPI_COMM_WORLD){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Quicksort" , __FILE__ , __LINE__) );
// We need a structure see the algorithm detail to know more
struct Fix{
FSize pre;
FSize suf;
IndexType pre;
IndexType suf;
};
// first we copy data into our working buffer : outputArray
......@@ -318,7 +351,7 @@ public:
memset(fixesSum,0,sizeof(Fix) * (MpiGetNbProcs(MPI_COMM_WORLD) + 1) );
// receiving buffer
FSize bufferSize = 0;
IndexType bufferSize = 0;
SortType* buffer = 0;
// Create the first group
......@@ -342,7 +375,7 @@ public:
/////////////////////////////////////////////////
// sort QsLocal part of the outputArray
const PivotType pivot = MpiGetPivot<PivotType>(outputArray[size/2], currentComm, currentNbProcs);
const CompareType pivot = MpiGetPivot(outputArray[size/2], currentComm, currentNbProcs);
Fix myFix;
QsLocal(outputArray, pivot, 0, size - 1, myFix.pre, myFix.suf);
......@@ -371,15 +404,15 @@ public:
if( fixes[currentRank].suf ){
const int procsInSuf = currentNbProcs - 1 - splitProc;
const int firstProcInSuf = splitProc + 1;
const FSize elementsInSuf = fixesSum[currentNbProcs].suf;
const IndexType elementsInSuf = fixesSum[currentNbProcs].suf;
const int firstProcToSend = getProc(fixesSum[currentRank].suf, elementsInSuf, procsInSuf) + firstProcInSuf;
const int lastProcToSend = getProc(fixesSum[currentRank + 1].suf - 1, elementsInSuf, procsInSuf) + firstProcInSuf;
FSize sent = 0;
IndexType sent = 0;
for(int idxProc = firstProcToSend ; idxProc <= lastProcToSend ; ++idxProc){
const FSize thisProcRight = getRight(elementsInSuf, idxProc - firstProcInSuf, procsInSuf);
FSize sendToProc = thisProcRight - fixesSum[currentRank].suf - sent;
const IndexType thisProcRight = getRight(elementsInSuf, idxProc - firstProcInSuf, procsInSuf);
IndexType sendToProc = thisProcRight - fixesSum[currentRank].suf - sent;
if(sendToProc + sent > fixes[currentRank].suf){
sendToProc = fixes[currentRank].suf - sent;
......@@ -394,15 +427,15 @@ public:
// under pivot (left part)
if( fixes[currentRank].pre ){
const int procsInPre = splitProc + 1;
const FSize elementsInPre = fixesSum[currentNbProcs].pre;
const IndexType elementsInPre = fixesSum[currentNbProcs].pre;
const int firstProcToSend = getProc(fixesSum[currentRank].pre, elementsInPre, procsInPre);
const int lastProcToSend = getProc(fixesSum[currentRank + 1].pre - 1, elementsInPre, procsInPre);
FSize sent = 0;
IndexType sent = 0;
for(int idxProc = firstProcToSend ; idxProc <= lastProcToSend ; ++idxProc){
const FSize thisProcRight = getRight(elementsInPre, idxProc, procsInPre);
FSize sendToProc = thisProcRight - fixesSum[currentRank].pre - sent;
const IndexType thisProcRight = getRight(elementsInPre, idxProc, procsInPre);
IndexType sendToProc = thisProcRight - fixesSum[currentRank].pre - sent;
if(sendToProc + sent > fixes[currentRank].pre){
sendToProc = fixes[currentRank].pre - sent;
......@@ -421,10 +454,10 @@ public:
if( currentRank <= splitProc ){
// I am in S-Part (smaller than pivot)
const int procsInPre = splitProc + 1;
const FSize elementsInPre = fixesSum[currentNbProcs].pre;
const IndexType elementsInPre = fixesSum[currentNbProcs].pre;
FSize myLeft = getLeft(elementsInPre, currentRank, procsInPre);
FSize myRightLimit = getRight(elementsInPre, currentRank, procsInPre);
IndexType myLeft = getLeft(elementsInPre, currentRank, procsInPre);
IndexType myRightLimit = getRight(elementsInPre, currentRank, procsInPre);
size = myRightLimit - myLeft;
if(bufferSize < size){
......@@ -438,11 +471,11 @@ public:
++idxProc;
}
FSize indexArray = 0;
IndexType indexArray = 0;
while( idxProc < currentNbProcs && indexArray < myRightLimit - myLeft){
const FSize firstIndex = Max(myLeft , fixesSum[idxProc].pre );
const FSize endIndex = Min(fixesSum[idxProc + 1].pre, myRightLimit);
const IndexType firstIndex = Max(myLeft , fixesSum[idxProc].pre );
const IndexType endIndex = Min(fixesSum[idxProc + 1].pre, myRightLimit);
if( (endIndex - firstIndex) ){
mpiassert( MPI_Irecv(&buffer[indexArray], int((endIndex - firstIndex) * sizeof(SortType)), MPI_BYTE, idxProc, FMpi::TagQuickSort, currentComm, &requests[iterRequest++]), __LINE__ );
}
......@@ -457,11 +490,11 @@ public:
else{
// I am in L-Part (larger than pivot)
const int procsInSuf = currentNbProcs - 1 - splitProc;
const FSize elementsInSuf = fixesSum[currentNbProcs].suf;
const IndexType elementsInSuf = fixesSum[currentNbProcs].suf;
const int rankInL = currentRank - splitProc - 1;
FSize myLeft = getLeft(elementsInSuf, rankInL, procsInSuf);
FSize myRightLimit = getRight(elementsInSuf, rankInL, procsInSuf);
IndexType myLeft = getLeft(elementsInSuf, rankInL, procsInSuf);
IndexType myRightLimit = getRight(elementsInSuf, rankInL, procsInSuf);
size = myRightLimit - myLeft;
if(bufferSize < size){
......@@ -475,11 +508,11 @@ public:
++idxProc;
}
FSize indexArray = 0;
IndexType indexArray = 0;
while( idxProc < currentNbProcs && indexArray < myRightLimit - myLeft){
const FSize firstIndex = Max(myLeft , fixesSum[idxProc].suf );
const FSize endIndex = Min(fixesSum[idxProc + 1].suf, myRightLimit);
const IndexType firstIndex = Max(myLeft , fixesSum[idxProc].suf );
const IndexType endIndex = Min(fixesSum[idxProc + 1].suf, myRightLimit);
if( (endIndex - firstIndex) ){
mpiassert( MPI_Irecv(&buffer[indexArray], int((endIndex - firstIndex) * sizeof(SortType)), MPI_BYTE, idxProc, FMpi::TagQuickSort, currentComm, &requests[iterRequest++]), __LINE__ );
}
......@@ -514,7 +547,7 @@ public:
MPI_Group_free(&currentGroup);
// Normal Quick sort
QsOmp<SortType,PivotType>(outputArray, size);
QsOmp(outputArray, size);
outputSize = size;
}
......
......@@ -33,7 +33,7 @@ class TestQuickSort : public FUTester<TestQuickSort> {
array[idx] = rand();
}
FQuickSort::QsOmp<long long, long long>(array, Size);
FQuickSort<long long, long long, long>::QsOmp(array, Size);
assert(IsSorted(array,Size));
}
......@@ -50,7 +50,7 @@ class TestQuickSort : public FUTester<TestQuickSort> {
array[idx] = rand();
}
FQuickSort::QsOmp<long long, long long>(array, Size);
FQuickSort<long long, long long, long>::QsOmp(array, Size);
assert(IsSorted(array,Size));
delete [] array;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment