Scheduled maintenance on Monday 2019-06-24 between 10:00-11:00 CEST

Commit d7589e77 authored by Berenger Bramas's avatar Berenger Bramas

Update for skylake and add function to sort pair of integers

parent 42f6a711
Pipeline #15521 passed with stage
in 22 seconds
//////////////////////////////////////////////////////////
/// Code to sort an array of integer or double
/// using avx 512 (targeting intel KNL).
/// using avx 512 (targeting intel KNL/SKL).
/// By berenger.bramas@mpcdf.mpg.de 2017.
/// Licence is MIT.
/// Comes without any warranty.
......@@ -14,8 +14,12 @@
/// (should be less than 16 AVX512 vectors)
///
/// To compile such flags can be used to enable avx 512 and openmp:
/// - KNL
/// Gcc : -mavx512f -mavx512pf -mavx512er -mavx512cd -fopenmp
/// Intel : -xCOMMON-AVX512 -xMIC-AVX512 -qopenmp
/// - SKL
/// Gcc : -mavx512f -mavx512cd -mavx512vl -mavx512bw -mavx512dq -fopenmp
/// Intel : -xCOMMON-AVX512 -xCORE-AVX512 -qopenmp
//////////////////////////////////////////////////////////
#ifndef SORT512_HPP
#define SORT512_HPP
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -8,11 +8,16 @@
/// This file contains tests (which may be used as examples)
///
/// Can be compiled with:
/// - KNL
/// Gcc : g++ -DNDEBUG -O3 -funroll-loops -faggressive-loop-optimizations -std=c++11 -mavx512f -mavx512pf -mavx512er -mavx512cd -fopenmp sort512test.cpp -o sort512test.gcc.exe
/// Intel : icpc -DNDEBUG -O3 -std=c++11 -xCOMMON-AVX512 -xMIC-AVX512 -qopenmp sort512test.cpp -o sort512test.intel.exe
/// - SKL
/// Gcc : g++ -DNDEBUG -O3 -funroll-loops -faggressive-loop-optimizations -std=c++11 -mavx512f -mavx512cd -mavx512vl -mavx512bw -mavx512dq -fopenmp sort512test.cpp -o sort512test.gcc.exe
/// Intel : icpc -DNDEBUG -O3 -std=c++11 -xCOMMON-AVX512 -xCORE-AVX512 -qopenmp sort512test.cpp -o sort512test.intel.exe
//////////////////////////////////////////////////////////
#include "sort512.hpp"
#include "sort512kv.hpp"
#include <iostream>
#include <memory>
......@@ -212,6 +217,47 @@ void testSortVec(){
}
}
void testSortVec_pair(){
std::cout << "Start testSortVec_pair int...\n";
{
{
int vecTest[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
int vecRes[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
testSortVec_Core_Equal(vecTest, vecRes);
}
{
int vecTest[16] = { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
int vecRes[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
testSortVec_Core_Equal(vecTest, vecRes);
}
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[16];
createRandVec(vecTest, 16);
int values[16];
for(int idxval = 0 ; idxval < 16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
{
Sort512kv::CoreSmallSort(vecTest, values);
assertNotSorted(vecTest, 16, "testSortVec_Core_Equal");
}
for(int idxval = 0 ; idxval < 16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort2Vec_Core_Equal(const double toSort[16], const double sorted[16]){
double res[16];
......@@ -344,6 +390,34 @@ void testSort2Vec(){
}
}
void testSort2Vec_pair(){
std::cout << "Start testSort2Vec_pair int...\n";
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[32];
createRandVec(vecTest, 32);
int values[32];
for(int idxval = 0 ; idxval < 32 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
{
Checker<int> checker(vecTest, vecTest, 32);
Sort512kv::CoreSmallSort2(vecTest, values);
assertNotSorted(vecTest, 32, "testSortVec_Core_Equal");
}
for(int idxval = 0 ; idxval < 32 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
void testSort3Vec(){
std::cout << "Start testSort3Vec double...\n";
......@@ -429,6 +503,69 @@ void testSort4Vec(){
}
}
void testSort3Vec_pair(){
std::cout << "Start testSort3Vec_pair int...\n";
{
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[48];
createRandVec(vecTest, 48);
int values[48];
for(int idxval = 0 ; idxval < 48 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
{
Checker<int> checker(vecTest, vecTest, 48);
Sort512kv::CoreSmallSort3(vecTest, values);
assertNotSorted(vecTest, 48, "testSortVec_Core_Equal");
}
for(int idxval = 0 ; idxval < 48 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort4Vec_pair(){
std::cout << "Start testSort4Vec_pair int...\n";
{
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[64];
createRandVec(vecTest, 64);
int values[64];
for(int idxval = 0 ; idxval < 64 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
{
Checker<int> checker(vecTest, vecTest, 64);
Sort512kv::CoreSmallSort4(vecTest, values);
assertNotSorted(vecTest, 64, "testSortVec_Core_Equal");
}
for(int idxval = 0 ; idxval < 64 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort5Vec(){
std::cout << "Start testSort5Vec double...\n";
{
......@@ -460,6 +597,36 @@ void testSort5Vec(){
}
}
void testSort5Vec_pair(){
std::cout << "Start testSort5Vec_pair int...\n";
{
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[5*16];
createRandVec(vecTest, 5*16);
int values[5*16];
for(int idxval = 0 ; idxval < 5*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, 5*16);
Sort512kv::CoreSmallSort5(vecTest, values);
assertNotSorted(vecTest, 5*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < 5*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort6Vec(){
std::cout << "Start testSort6Vec double...\n";
......@@ -492,6 +659,37 @@ void testSort6Vec(){
}
}
void testSort6Vec_pair(){
std::cout << "Start testSort6Vec_pair int...\n";
{
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[6*16];
createRandVec(vecTest, 6*16);
int values[6*16];
for(int idxval = 0 ; idxval < 6*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, 6*16);
Sort512kv::CoreSmallSort6(vecTest, values);
assertNotSorted(vecTest, 6*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < 6*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort7Vec(){
std::cout << "Start testSort7Vec double...\n";
......@@ -524,6 +722,38 @@ void testSort7Vec(){
}
}
void testSort7Vec_pair(){
std::cout << "Start testSort7Vec_pair int...\n";
{
static const int Size = 7;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort7(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort8Vec(){
std::cout << "Start testSort8Vec double...\n";
{
......@@ -555,6 +785,39 @@ void testSort8Vec(){
}
}
void testSort8Vec_pair(){
std::cout << "Start testSort8Vec_pair int...\n";
{
static const int Size = 8;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort8(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort9Vec(){
const int nbVecs = 9;
std::cout << "Start testSort9Vec double...\n";
......@@ -591,6 +854,38 @@ void testSort9Vec(){
}
}
void testSort9Vec_pair(){
std::cout << "Start testSort9Vec_pair int...\n";
{
static const int Size = 9;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort9(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort10Vec(){
const int nbVecs = 10;
std::cout << "Start testSort10Vec double...\n";
......@@ -627,6 +922,38 @@ void testSort10Vec(){
}
}
void testSort10Vec_pair(){
std::cout << "Start testSort10Vec_pair int...\n";
{
static const int Size = 10;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort10(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort11Vec(){
const int nbVecs = 11;
std::cout << "Start testSort11Vec double...\n";
......@@ -663,6 +990,38 @@ void testSort11Vec(){
}
}
void testSort11Vec_pair(){
std::cout << "Start testSort11Vec_pair int...\n";
{
static const int Size = 11;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort11(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort12Vec(){
const int nbVecs = 12;
std::cout << "Start testSort12Vec double...\n";
......@@ -699,6 +1058,38 @@ void testSort12Vec(){
}
}
void testSort12Vec_pair(){
std::cout << "Start testSort12Vec_pair int...\n";
{
static const int Size = 12;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort12(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort13Vec(){
const int nbVecs = 13;
std::cout << "Start testSort13Vec double...\n";
......@@ -735,6 +1126,38 @@ void testSort13Vec(){
}
}
void testSort13Vec_pair(){
std::cout << "Start testSort13Vec_pair int...\n";
{
static const int Size = 13;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort13(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort14Vec(){
const int nbVecs = 14;
std::cout << "Start testSort14Vec double...\n";
......@@ -771,6 +1194,38 @@ void testSort14Vec(){
}
}
void testSort14Vec_pair(){
std::cout << "Start testSort14Vec_pair int...\n";
{
static const int Size = 14;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort14(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort15Vec(){
const int nbVecs = 15;
std::cout << "Start testSort15Vec double...\n";
......@@ -807,6 +1262,39 @@ void testSort15Vec(){
}
}
void testSort15Vec_pair(){
std::cout << "Start testSort15Vec_pair int...\n";
{
static const int Size = 15;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort15(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
void testSort16Vec(){
const int nbVecs = 16;
......@@ -844,6 +1332,37 @@ void testSort16Vec(){
}
}
void testSort16Vec_pair(){
std::cout << "Start testSort16Vec_pair int...\n";
{
static const int Size = 16;
srand48(0);
const static int NbLoops = 1000;
for(int idx = 0 ; idx < NbLoops ; ++idx){
int vecTest[Size*16];
createRandVec(vecTest, Size*16);
int values[Size*16];
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
values[idxval] = vecTest[idxval]*100+1;
}
Checker<int> checker(vecTest, vecTest, Size*16);
Sort512kv::CoreSmallSort16(vecTest, values);
assertNotSorted(vecTest, Size*16, "testSortVec_Core_Equal");
for(int idxval = 0 ; idxval < Size*16 ; ++idxval){
if(values[idxval] != vecTest[idxval]*100+1){
std::cout << "Error in testSortVec_pair "
" is " << values[idxval] <<
" should be " << vecTest[idxval]*100+1 << std::endl;
test_res = 1;
}
}
}
}
}
template <class NumType>
void testQs512(){
......@@ -866,6 +1385,48 @@ void testQs512(){
#endif
}
template <class NumType>
void testQs512_pair(){
std::cout << "Start testQs512_pair...\n";
for(size_t idx = 1 ; idx <= (1<<10); idx *= 2){
std::cout << " " << idx << std::endl;
std::unique_ptr<NumType[]> array(new NumType[idx]);
createRandVec(array.get(), idx); Checker<NumType> checker(array.get(), array.get(), idx);
std::unique_ptr<NumType[]> values(new NumType[idx]);
for(size_t idxval = 0 ; idxval < idx ; ++idxval){
values[idxval] = array[idxval]*100+1;
}
Sort512kv::Sort<NumType,size_t>(array.get(), values.get(), idx);
assertNotSorted(array.get(), idx, "");
for(size_t idxval = 0 ; idxval < idx ; ++idxval){
if(values[idxval] != array[idxval]*100+1){
std::cout << "Error in testNewPartition512V2_pair, pair/key do not match" << std::endl;
test_res = 1;
}
}
}
#if defined(_OPENMP)
for(size_t idx = 1 ; idx <= (1<<10); idx *= 2){
std::cout << " " << idx << std::endl;
std::unique_ptr<NumType[]> array(new NumType[idx]);
createRandVec(array.get(), idx); Checker<NumType> checker(array.get(), array.get(), idx);
std::unique_ptr<NumType[]> values(new NumType[idx]);
for(size_t idxval = 0 ; idxval < idx ; ++idxval){
values[idxval] = array[idxval]*100+1;
}
Sort512kv::SortOmp<NumType,size_t>(array.get(), values.get(), idx);
assertNotSorted(array.get(), idx, "");
for(size_t idxval = 0 ; idxval < idx ; ++idxval){
if(values[idxval] != array[idxval]*100+1){
std::cout << "Error in testNewPartition512V2_pair, pair/key do not match" << std::endl;
test_res = 1;
}
}
}
#endif
}
template <class NumType>
void testPartition(){
std::cout << "Start Sort512::Partition512...\n";
......@@ -900,6 +1461,71 @@ void testPartition(){
}
}
template <class NumType>
void testPartition_pair(){
std::cout << "Start testPartition_pair...\n";
for(size_t idx = 1 ; idx <= (1<<10); idx *= 2){
std::cout << " " << idx << std::endl;
std::unique_ptr<NumType[]> array(new NumType[idx]);
createRandVec(array.get(), idx); Checker<NumType> checker(array.get(), array.get(), idx);
std::unique_ptr<NumType[]> values(new NumType[idx]);
for(size_t idxval = 0 ; idxval < idx ; ++idxval){
values[idxval] = array[idxval]*100+1;
}
const NumType pivot = NumType(idx/2);
size_t limite = Sort512kv::Partition512<size_t>(&array[0], &values[0], 0, idx-1, pivot);
assertNotPartitioned(array.get(), idx, pivot, limite, "");
for(size_t idxval = 0 ; idxval < idx ; ++idxval){
if(values[idxval] != array[idxval]*100+1){
std::cout << "Error in testNewPartition512V2_pair, pair/key do not match" << std::endl;
test_res = 1;
}
}
}
for(size_t idx = 1 ; idx <= 1000; ++idx){
if(idx%100 == 0) std::cout << " " << idx << std::endl;
std::unique_ptr<NumType[]> array(new NumType[idx]);