【CUDA 】-Thrust sort&sortbykey

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<algorithm>
// includes CUDA
#include <cuda_runtime.h>
#include<device_launch_parameters.h>
// includes, project
#include <helper_cuda.h>
#include <helper_functions.h> // helper functions for SDK examples
//include thrust
#include <thrust/device_ptr.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/copy.h>
using namespace std;
#define N (3)  //每个对象的条件属性个数
#define M (12) //保存对象个数
__device__ __managed__ int d_attrSelect[N];//定义全局变量,保存有效的属性选择。
struct Element
{
    int attrval[N];//保存该对象的所有的条件属性值
    bool __host__ __device__ operator<(const Element& e)const
    {
        for (int i = 0; i < N; i++)
        {
            if (d_attrSelect[i] == 0)//为0表示该属性无效
            {
                continue;
            }
            if (attrval[i]<e.attrval[i])
            {
                return true;
            }
            if (attrval[i]>e.attrval[i])
            {
                return false;
            }
            if (attrval[i] == e.attrval[i])
            {
                continue;
            }
        }
        return false;
    }
    bool __host__ __device__ operator == (const Element & e)const
    {
        bool res = true;
        for (int i = 0; i < N; i++)
        {
            if (d_attrSelect[i] == 0)//如果为0则无效
                continue;
            if (attrval[i] != e.attrval[i])
            {
                res = false;
                break;
            }
        }
        return res;
    }
};
void Split(const string& src, const string& separator, vector<string>& dest)
{
    string str = src;
    string substring;
    string::size_type start = 0, index;

    do
    {
        index = str.find_first_of(separator, start);
        if (index != string::npos)
        {
            substring = str.substr(start, index - start);
            dest.push_back(substring);
            start = str.find_first_not_of(separator, index);
            if (start == string::npos) return;
        }
    } while (index != string::npos);

    //the last token
    substring = str.substr(start);
    dest.push_back(substring);
}
void InData(const char* fname, thrust::host_vector<Element>&all_elments)
{
#ifdef TIME_TEST
    double timeuse;
    StartTimer();
#endif
    ifstream fin(fname);
    if (!fin)
    {
        // NO, abort program
        cerr << "can't open input file \"" << fname << "\"" << endl;
        getchar();
        exit(EXIT_FAILURE);
    }
    string line;
    string separtor = " ";
    while (getline(fin, line))
    {
        //cout << line << endl;
        Element temp_obj;
        vector<string> temp_string;
        Split(line, separtor, temp_string);

        for (int i = 0; i < temp_string.size(); i++)//去掉最后的决策属性
        {
            temp_obj.attrval[i] = stoi(temp_string[i]);
            //cout << temp_obj.attrval[i] << "  ";
        }
        //cout << endl;
        all_elments.push_back(temp_obj);
    }
    fin.close();
#ifdef TIME_TEST
    timeuse = GetTimer();
    std::cerr << "[CPU] InData 读取数据的时间(in second)\t" << timeuse << std::endl;
    StartTimer();
#endif
}
int main()
{
    for (int i = 0; i < N; i++)
    {
        d_attrSelect[i] = 1;
    }
    d_attrSelect[2] = 0;
    for (int i = 0; i <N; i++)
    {
        printf("Host: the value of the global variable is %d\n", d_attrSelect[i]);
    }
    thrust::host_vector <Element> ElementList;
    char s[1024] = "C://Users//hym//Desktop//test.txt";
    InData(s, ElementList);
    cout << " CPU: before sort" << endl;
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cout << ElementList[i].attrval[j] << "  ";
        }
        cout << endl;
        //printf("CPU Sort before:%d %d %d\n", ElementList[i].attrval[0], ElementList[i].attrval[1], ElementList[i].attrval[2]);
    }
    std::sort(ElementList.begin(), ElementList.end());// cpu 串行排序
    thrust::device_vector<Element> dev_element = ElementList;
        thrust::sort(dev_element.begin(), dev_element.end());
        ElementList = dev_element;
    cout << " CPU: After sort" << endl;
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cout << ElementList[i].attrval[j] << "  ";
        }
        cout << endl;
    }
    thrust::host_vector<int> h_value(M);
    for (int i = 0; i < M; i++)
    {
        h_value[i] = i + 1;
    }
    thrust::device_vector<int> d_value = h_value;
    thrust::sort_by_key(dev_element.begin(), dev_element.end(), d_value.begin());
    ElementList = dev_element;
    h_value = d_value;
    for (int i = 0; i < M; i++)
    {
        cout << "id=" << h_value[i] << " ";
        for (int j = 0; j < N; j++)
        {
            cout << ElementList[i].attrval[j] << "  ";
        }
        cout << endl;
    }
    getchar();
    return 0;
}

my test:

0 0 0
0 0 1
1 0 1
1 1 1
0 0 0 
1 1 2
0 0 0 
1 1 1
1 1 2
0 1 1 
1 0 2
1 1 1

最新的cuda中kernel函数中也可以使用thrust了。
Thrust inside user written kernels

使用仿函数进行排序

////////////////////////////////////////////////////////////////////////////
//
// Copyright 1993-2015 NVIDIA Corporation.  All rights reserved.
//
// Please refer to the NVIDIA end user license agreement (EULA) associated
// with this source code for terms and conditions that govern your use of
// this software. Any use, reproduction, disclosure, or distribution of
// this software and related documentation outside the terms of the EULA
// is strictly prohibited.
//
////////////////////////////////////////////////////////////////////////////

/* Template project which demonstrates the basics on how to setup a project
* example application.
* Host code.
*/
///*
// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<algorithm>
#include<map>
#include <iomanip>//输出格式限制
// includes CUDA
#include <cuda_runtime.h>
#include<device_launch_parameters.h>
#include<cusparse.h>
// includes, project
#include <helper_cuda.h>
#include <helper_functions.h> // helper functions for SDK examples
//include thrust
#include <thrust/device_ptr.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/copy.h>
#include <thrust/functional.h>
#include <thrust/sequence.h>
#include "basic.h"
using namespace std;
///*
#define N (2)
#define M (12)
#define D (3)
/*/
//*
#define N (16)
#define M (20000)
#define D (26)
//*/
#define TILE_X 8
#define TILE_Y 32
struct Element
{
    int attrval[N];//条件属性值
    int attrdec;//决策属性值
};

struct compare_element
{
    thrust::device_vector<int> attr;
    compare_element(thrust::device_vector<int> temp)
    {
        attr = temp;
    }
    __device__ bool operator()(const Element &a, const Element &b)const
    {
        for (int i = 0; i < N; i++)
        {
            if (attr[i] == 0)
            {
                continue;
            }
            if (a.attrval[i]<b.attrval[i])
            {
                return true;
            }
            if (a.attrval[i]>b.attrval[i])
            {
                return false;
            }
            if (a.attrval[i] == b.attrval[i])
            {
                continue;
            }
        }
        return false;
    }
};

void Split(const string& src, const string& separator, vector<string>& dest)
{
    string str = src;
    string substring;
    string::size_type start = 0, index;
    do
    {
        index = str.find_first_of(separator, start);
        if (index != string::npos)
        {
            substring = str.substr(start, index - start);
            dest.push_back(substring);
            start = str.find_first_not_of(separator, index);
            if (start == string::npos) return;
        }
    } while (index != string::npos);

    //the last token
    substring = str.substr(start);
    dest.push_back(substring);
}
void InData(const char* fname, thrust::host_vector<Element>&all_elments)
{
#ifdef TIME_TEST
    double timeuse;
    StartTimer();
#endif
    ifstream fin(fname);
    if (!fin)
    {
        // NO, abort program
        cerr << "can't open input file \"" << fname << "\"" << endl;
        getchar();
        exit(EXIT_FAILURE);
    }
    string line;
    string separtor = " ";
    int obj_cnt = 0;
    while (getline(fin, line) && obj_cnt<M)
    {
        vector<string> temp_string;
        Split(line, separtor, temp_string);
        int length = temp_string.size();
        if ((length - 1) != N)
        {
            cerr << "属性个数不正确:N=" << N << "   实际的属性个数:" << length - 1 << endl;
            getchar();
            exit(EXIT_FAILURE);
        }
        for (int i = 0; i < length - 1; i++)//去掉最后的决策属性
        {
            all_elments[obj_cnt].attrval[i] = stoi(temp_string[i]);
        }
        all_elments[obj_cnt].attrdec = stoi(temp_string[length - 1]);
        obj_cnt++;
    }
    fin.close();
#ifdef TIME_TEST
    timeuse = GetTimer();
    std::cerr << "[CPU] InData 读取数据的时间(in second)\t" << timeuse << std::endl;
    StartTimer();
#endif
}


void printData(thrust::host_vector<Element> all_Elements)
{
    cout << "-------------Data------" << endl;
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cout << all_Elements[i].attrval[j] << "   ";
        }
        cout << "   dec=" << all_Elements[i].attrdec << endl;
    }
    cout << endl;
}


int main()
{
    thrust::host_vector<Element> all_Elements(M);//考虑到push_back很慢
    //char s[1024] = "C://Users//hym//Desktop//GPU_Data//letter.txt";//20000 16 26
    char s[1024] = "C://Users//hym//Desktop//GPU_Data//test.txt";//12 2 3
    InData(s, all_Elements);
    printData(all_Elements);
    thrust::device_vector<Element> dev_element = all_Elements;
    thrust::device_vector<int> attr(N, 1);
    compare_element cmp(attr);
    //thrust::sort(dev_element.begin(), dev_element.end(),cmp);
    all_Elements = dev_element;
    printData(all_Elements);
    getchar();
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容