首页 > 其他分享 >OpenCL中的SVM使用案例

OpenCL中的SVM使用案例

时间:2024-06-23 13:59:18浏览次数:24  
标签:SVM last svmBox cl MLinkedList OpenCL Element 案例 struct

SVM(共享虚拟内存)是为了解决向显卡传输数据中包含指针的问题。此时仅用cl::Buffer拷贝数据是不够的,因为数据中的指针会因为拷贝变成野指针。这就需要SVM的帮助,它可以保证数据中的指针到达GPU后仍然可以使用。这里给出一个计算单向链表中数字的和的例子。代码运行环境是VS2017,OpenCL3,显卡是Intel Core i5的核芯显卡。CPP文件如下:

string kernelStr = R"(
    struct Element
    {
        struct Element* next;
        float data;
    };

    struct MLinkedList 
    {
        struct Element* first;
        struct Element* last;
    };

    global volatile atomic_float sum = ATOMIC_VAR_INIT(0);
    kernel void add(global const struct MLinkedList* input, global float* output)
    {
        struct Element* iter = input->first;
        while (iter)
        {
            atomic_fetch_add(&sum, iter->data);
            iter = iter->next;
        }
        *output = atomic_load(&sum);
    })";

class MLinkedList
{
private:
    struct Element;

public:
    using Pointer = cl::pointer<MLinkedList::Element, cl::detail::Deleter<
        cl::SVMAllocator<MLinkedList::Element, cl::SVMTraitCoarse<>>>>;
    MLinkedList();
    void append(float value, vector<Pointer>& box);

private:
    Element* first;
    Element* last;
};

struct MLinkedList::Element
{
    Element* next;
    float data;
};

MLinkedList::MLinkedList()
{
    first = 0;
    last = 0;
}

void MLinkedList::append(float value, vector<Pointer>& box)
{
    Pointer elem = cl::allocate_svm<MLinkedList::Element, cl::SVMTraitCoarse<>>();
    elem->data = value;
    elem->next = 0;
    if (!last)
    {
        first = elem.get();
        last = first;
    }
    else
    {
        last->next = elem.get();
        last = last->next;
    }
    box.push_back(std::move(elem));
}

int main()
{
    cl::Program program(kernelStr);
    try 
    {
        program.build("-cl-std=CL2.0");
    }
    catch (...)
    {
        cl_int buildErr = CL_SUCCESS;
        auto buildInfo = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(&buildErr);
        for (auto &pair : buildInfo)
        {
            std::cerr << pair.second << std::endl << std::endl;
        }
        return 1;
    }

    vector<MLinkedList::Pointer> svmBox;
    auto svmList = cl::allocate_svm<MLinkedList, cl::SVMTraitCoarse<>>();
    svmList->append(100.5f, svmBox);
    svmList->append(200.5f, svmBox);
    svmList->append(300.5f, svmBox);
    svmList->append(400.5f, svmBox);
    vector<float> b(1, 0);
    cl::Buffer outputb(b.begin(), b.end(), false);
    auto kernel = cl::KernelFunctor<decltype(svmList)&, cl::Buffer&>(program, "add");

    //std::for_each(svmBox.begin(), svmBox.end(), /* 注释1,× */
    //    [&kernel](MLinkedList::Pointer& p) { kernel.setSVMPointers(p); });

    //vector<void*> svmps; /* 注释2,√ */
    //std::for_each(svmBox.begin(), svmBox.end(),
    //    [&svmps](MLinkedList::Pointer& p) { svmps.push_back(p.get()); });
    //kernel.setSVMPointers(svmps);

    kernel.setSVMPointers(svmBox[0], svmBox[1], svmBox[2], svmBox[3]);

    int64 t1, t2;
    t1 = getTickCount();

    kernel(cl::EnqueueArgs(cl::NDRange(1)), svmList, outputb);
    cl::copy(outputb, b.begin(), b.end());
    cout << b[0] << endl;

    t2 = getTickCount();
    cout << "CL1(ms):" << (t2 - t1) / getTickFrequency() * 1000 << endl;

    int c;
    cin >> c;
    return 0;
}

本例仅用来展示SVM的用法,在运算效率上对CPU是没有任何优势的,因为此例GPU也是串行计算数字的和的。代码里MLinkedList是一个单向链表,只有十几行代码,对于有一定基础的人很容易看懂。需注意setSVMPointers(...)函数只能调用一次,需一次性将核函数引用的所有SVM指针设置完毕。所以上述代码中的注释1是错的,它分4次设置指针。注释2是对的,它是一次性设置完的,只不过用的是setSVMPointers(...)的另一个重载函数。下面是程序运行截图:

 

标签:SVM,last,svmBox,cl,MLinkedList,OpenCL,Element,案例,struct
From: https://www.cnblogs.com/mengxiangdu/p/18260264

相关文章

  • JAVA【案例5-2】模拟默认密码自动生成
    【模拟默认密码自动生成】1、案例描述本案例要求编写一个程序,模拟默认密码的自动生成策略,手动输入用户名,根据用户名自动生成默认密码。在生成密码时,将用户名反转即为默认的密码。2、案例目的(1)学会分析“模拟默认密码的生成”案例的实现思路(2)根据思路完成“模拟默认密码的......
  • Kimichat使用案例026:AI翻译英语PDF文档的3种方法
    文章目录一、介绍二、腾讯交互翻译TranSmarthttps://transmart.qq.com/三、沉浸式翻译三、谷歌网页翻译一、介绍短的文章,直接丢进kimichat、ChatGPT里面很快就可以翻译完成,而且效果很佳。但是,很长的PDF文档整篇需要翻译,怎么办呢?二、腾讯交互翻译TranSmartht......
  • 大数据运维学习笔记之filebeat+kafka+MM1跨机房实时日志传输案例——筑梦之路
    日志数据量:日均30亿  ......
  • VMware Workstation环境下,用作测试的客户端,ubuntu安装体验案例
    需求说明:作为学习者,为了学习网络技术,网络操作系统管理技术,学习者首先需要有台计算机,其次需要在自己的计算机安装学习要用到的网络操作系统、模拟软件等。但由于计算机上一般使用的是Windows10或Windows7桌面操作系统,而且或多或少有一些重要的数据、软件存放在硬盘里。那么......
  • 538个代码示例!麻省理工教授的Python程序设计+人工智能案例实践
    Python简单易学,且提供了丰富的第三方库,可以用较少的代码完成较多的工作,使开发者能够专注于如何解决问题而只花较少的时间去考虑如何编程。此外,Python还具有免费开源、跨平台、面向对象、胶水语言等优点,在系统编程、图形界面开发、科学计算、Web开发、数据分析、人工智能等方面......
  • 【设计文档】软件详细设计说明书案例文档(word直接套用)
    一、关于本文档(一)编写目的(二)预期读者二、项目概要(一)建设背景(二)建设目标(三)建设内容三、总体设计(一)需求规定(二)设计原则1.先进性2.实用性3.规范性4.安全性5.可维护性6.可扩展性(三)平台设计思路1.全面对象化和组件化2.良好的系统架......
  • 鸿蒙案例-食物列表页和底部Panel的实现
    前言  食物列表页是健康和饮食管理应用中的一个关键功能,它允许用户浏览、搜索和选择不同的食物项来记录他们的饮食习惯。食物列表以列表形式展示食物名称、图片和简要信息。点击食物项后,展示详细的营养信息,包括热量、脂肪、碳水化合物、蛋白质等。  食物列表页是用户......
  • 鸿蒙案例-欢迎页面的实现
    前言‘案例来源于b站课程’实现过程1.首页面主要有三部分<1>中央slogan;<2>logo;<3>文字描述设置中央slogan要使用layoutWeight(1)实现布局全中;Row(){Image($r('app.media.home_slogan')).width(260)}.layoutWeight(1)logo即图片设置好图片......
  • Swagger使用案例
    1、新建SpringBoot项目,导入swagger依赖<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><dependency><groupId&g......
  • 机器学习(一)——递归特征消除法实现SVM(matlab)
    机器学习方法对多维特征数据进行分类:本文用到非常经典的机器学习方法,使用递归特征消除进行特征选择,使用支持向量机构建分类模型,使用留一交叉验证的方法来评判模型的性能。构建模型:支持向量机(SupportVectorMachine,SVM);特征选择:递归特征消除(RecursiveFeatureElimination,RFE);......