一个 hipsolver 特征值示例

news2024/11/24 18:28:23

1,原理

通过雅可比旋转,对对称矩阵计算特征值和特征向量;

通过初等正交变换,每次把其中一个非主对角元素消成零,最终只剩主对角线非零元素为特征值,同时把初等变换累积下来,构成特征向量。

2,源码

yevj.cpp

计算一个512 阶的矩阵的特征值和特征向量:

#include <hip/hip_runtime.h>
#include <hipsolver/hipsolver.h>

#include <iostream>
#include <random>
#include <vector>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <string>

#define NA 512
#define PR_D 0

constexpr int error_exit_code = -1;

inline int report_validation_result(int errors)
{
    if(errors)
    {
        std::cout << "Validation failed. Errors: " << errors << std::endl;
        return error_exit_code;
    }

    std::cout << "Validation passed." << std::endl;
    return 0;
}

template<typename T>
void multiply_matrices(T        alpha,
                       T        beta,
                       int      m,
                       int      n,
                       int      k,
                       const T* A,
                       int      stride1_a,
                       int      stride2_a,
                       const T* B,
                       int      stride1_b,
                       int      stride2_b,
                       T*       C,
                       int      stride_c)
{
    for(int i1 = 0; i1 < m; ++i1)
    {
        for(int i2 = 0; i2 < n; ++i2)
        {
            T t = T(0.0);
            for(int i3 = 0; i3 < k; ++i3)
            {
                t += A[i1 * stride1_a + i3 * stride2_a] * B[i3 * stride1_b + i2 * stride2_b];
            }
            C[i1 + i2 * stride_c] = beta * C[i1 + i2 * stride_c] + alpha * t;
        }
    }
}

template<class BidirectionalIterator>
inline std::string format_range(const BidirectionalIterator begin, const BidirectionalIterator end)
{
    std::stringstream sstream;
    sstream << "[ ";
    for(auto it = begin; it != end; ++it)
    {
        sstream << *it;
        if(it != std::prev(end))
        {
            sstream << ", ";
        }
    }
    sstream << " ]";
    return sstream.str();
}

inline const char* hipsolverStatusToString(hipsolverStatus_t status)
{
    switch(status)
    {
        case HIPSOLVER_STATUS_SUCCESS: return "HIPSOLVER_STATUS_SUCCESS";
        case HIPSOLVER_STATUS_NOT_INITIALIZED: return "HIPSOLVER_STATUS_NOT_INITIALIZED";
        case HIPSOLVER_STATUS_ALLOC_FAILED: return "HIPSOLVER_STATUS_ALLOC_FAILED";
        case HIPSOLVER_STATUS_INVALID_VALUE: return "HIPSOLVER_STATUS_INVALID_VALUE";
        case HIPSOLVER_STATUS_MAPPING_ERROR: return "HIPSOLVER_STATUS_MAPPING_ERROR";
        case HIPSOLVER_STATUS_EXECUTION_FAILED: return "HIPSOLVER_STATUS_EXECUTION_FAILED";
        case HIPSOLVER_STATUS_INTERNAL_ERROR: return "HIPSOLVER_STATUS_INTERNAL_ERROR";
        case HIPSOLVER_STATUS_NOT_SUPPORTED: return "HIPSOLVER_STATUS_NOT_SUPPORTED";
        case HIPSOLVER_STATUS_ARCH_MISMATCH: return "HIPSOLVER_STATUS_ARCH_MISMATCH";
        case HIPSOLVER_STATUS_HANDLE_IS_NULLPTR: return "HIPSOLVER_STATUS_HANDLE_IS_NULLPTR";
        case HIPSOLVER_STATUS_INVALID_ENUM: return "HIPSOLVER_STATUS_INVALID_ENUM";
        case HIPSOLVER_STATUS_UNKNOWN: return "HIPSOLVER_STATUS_UNKNOWN";
#if (hipsolverVersionMajor == 1 && hipsolverVersionMinor >= 8) || hipsolverVersionMajor >= 2
        case HIPSOLVER_STATUS_ZERO_PIVOT: return "HIPSOLVER_STATUS_ZERO_PIVOT";
#endif
    }
    // We don't use default so that the compiler warns if any valid enums are missing from the
    // switch. If the value is not a valid hipsolverStatus_t, we return the following.
    return "<undefined hipsolverStatus_t value>";
}

#define HIP_CHECK(condition)                                                                \
    {                                                                                       \
        const hipError_t error = condition;                                                 \
        if(error != hipSuccess)                                                             \
        {                                                                                   \
            std::cerr << "An error encountered: \"" << hipGetErrorString(error) << "\" at " \
                      << __FILE__ << ':' << __LINE__ << std::endl;                          \
            std::exit(error_exit_code);                                                     \
        }                                                                                   \
    }

#define HIPSOLVER_CHECK(condition)                                                            \
    {                                                                                         \
        const hipsolverStatus_t status = condition;                                           \
        if(status != HIPSOLVER_STATUS_SUCCESS)                                                \
        {                                                                                     \
            std::cerr << "hipSOLVER error encountered: \"" << hipsolverStatusToString(status) \
                      << "\" at " << __FILE__ << ':' << __LINE__ << std::endl;                \
            std::exit(error_exit_code);                                                       \
        }                                                                                     \
    }

void init_matrix(std::vector<double> &A, int n, int lda)
{
    std::default_random_engine             generator;
    std::uniform_real_distribution<double> distribution(0., 2.);
    auto                                   random_number = std::bind(distribution, generator);

    for(int i = 0; i < n; i++)
    {
        A[(lda + 1) * i] = random_number();
        for(int j = 0; j < i; j++)
        {
            A[i * lda + j] = A[j * lda + i] = random_number();
        }
    }
}

int main(const int argc, char* argv[])
{
    int n = NA;
    if(n <= 0)
    {
        std::cout << "Value of 'n' should be greater than 0" << std::endl;
        return 0;
    }
    const int lda = n;

    // 2. Data vectors
    std::vector<double> A(n * lda); // Input matrix
    std::vector<double> V(n * lda); // Resulting eigenvectors
    std::vector<double> W(n); // resulting eigenvalues

    // 3. Generate a random symmetric matrix
    init_matrix(A, n, lda);

    // 4. Set hipsolver parameters
    const hipsolverEigMode_t  jobz = HIPSOLVER_EIG_MODE_VECTOR;
    const hipsolverFillMode_t uplo = HIPSOLVER_FILL_MODE_LOWER;

    hipsolverSyevjInfo_t params;
    HIPSOLVER_CHECK(hipsolverCreateSyevjInfo(&params));
    HIPSOLVER_CHECK(hipsolverXsyevjSetMaxSweeps(params, 100));
    HIPSOLVER_CHECK(hipsolverXsyevjSetTolerance(params, 1.e-7));
    HIPSOLVER_CHECK(hipsolverXsyevjSetSortEig(params, 1));

    // 5. Reserve and copy data to device
    double* d_A    = nullptr;
    double* d_W    = nullptr;
    int*    d_info = nullptr;

    HIP_CHECK(hipMalloc(&d_A, sizeof(double) * A.size()));
    HIP_CHECK(hipMalloc(&d_W, sizeof(double) * W.size()));
    HIP_CHECK(hipMalloc(&d_info, sizeof(int)));
    HIP_CHECK(hipMemcpy(d_A, A.data(), sizeof(double) * A.size(), hipMemcpyHostToDevice));

    // 6. Initialize hipsolver
    hipsolverHandle_t hipsolver_handle;
    HIPSOLVER_CHECK(hipsolverCreate(&hipsolver_handle));

    // 7. Get and reserve the working space on device.
    int     lwork  = 0;
    double* d_work = nullptr;
    HIPSOLVER_CHECK(
        hipsolverDsyevj_bufferSize(hipsolver_handle, jobz, uplo, n, d_A, lda, d_W, &lwork, params));


    std::cout<< "LL:: 1 lwork = "<<lwork<<"bytes"<<std::endl;
    lwork += 64;
//    lwork = ((lwork+64-1)/64)*64;

    std::cout<< "LL:: 2 lwork = "<<lwork<<"bytes"<<std::endl;

    HIP_CHECK(hipMalloc(&d_work, sizeof(double) * lwork));

    // 8. Compute eigenvectors and eigenvalues
    HIPSOLVER_CHECK(hipsolverDsyevj(hipsolver_handle,
                                    jobz,
                                    uplo,
                                    n,
                                    d_A,
                                    lda,
                                    d_W,
                                    d_work,
                                    lwork,
                                    d_info,
                                    params));
    // 9. Get results from host.
    int info = 0;
    HIP_CHECK(hipMemcpy(V.data(), d_A, sizeof(double) * V.size(), hipMemcpyDeviceToHost));
    HIP_CHECK(hipMemcpy(W.data(), d_W, sizeof(double) * W.size(), hipMemcpyDeviceToHost));
    HIP_CHECK(hipMemcpy(&info, d_info, sizeof(int), hipMemcpyDeviceToHost));

    // 10. Print results
    if(info == 0)
    {
        std::cout << "SYEVJ converges." << std::endl;
    }
    else if(info > 0)
    {
        std::cout << "SYEVJ does not converge (" << info << " elements did not converge)."
                  << std::endl;
    }

    std::cout << "\nGiven the n x n square input matrix A; we computed the linearly independent "
                 "eigenvectors V and the associated eigenvalues W."
              << std::endl;
#if PR_D
    std::cout << "A = " << format_range(A.begin(), A.end()) << std::endl;
    std::cout << "W = " << format_range(W.begin(), W.end()) << std::endl;
    std::cout << "V = " << format_range(V.begin(), V.end()) << std::endl;
#endif

    int    sweeps   = 0;
    double residual = 0;
    HIPSOLVER_CHECK(hipsolverXsyevjGetSweeps(hipsolver_handle, params, &sweeps));
    HIPSOLVER_CHECK(hipsolverXsyevjGetResidual(hipsolver_handle, params, &residual));

    std::cout << "\nWhich was computed in " << sweeps << " sweeps, with a residual of " << residual
              << std::endl;

    // 11. Validate that 'AV == VD' and that 'AV - VD == 0'.
    std::cout << "\nLet D be the diagonal constructed from W.\n"
              << "The right multiplication of A * V should result in V * D [AV == VD]:"
              << std::endl;

    // Right multiplication of the input matrix with the eigenvectors.
    std::vector<double> AV(n * lda);
    multiply_matrices(1.0, 0.0, n, n, n, A.data(), lda, 1, V.data(), 1, lda, AV.data(), lda);
#if PR_D
    std::cout << "AV = " << format_range(AV.begin(), AV.end()) << std::endl;
#endif
    // Construct the diagonal D from eigenvalues W.
    std::vector<double> D(n * n);
    for(int i = 0; i < n; i++)
    {
        D[(n + 1) * i] = W[i];
    }

    // Scale eigenvectors V with W by multiplying V with D.
    std::vector<double> VD(n * lda);
    multiply_matrices(1.0, 0.0, n, n, n, V.data(), 1, lda, D.data(), lda, 1, VD.data(), lda);
#if PR_D
    std::cout << "VD = " << format_range(VD.begin(), VD.end()) << std::endl;
#endif
    double epsilon = 1.0e5 * std::numeric_limits<double>::epsilon();
    int    errors  = 0;
    double mse     = 0;
    for(int i = 0; i < n * n; i++)
    {
        double diff = (AV[i] - VD[i]);
        diff *= diff;
        mse += diff;

        errors += (diff > epsilon);
    }
    mse /= n * n;
    std::cout << "\nMean Square Error of [AV == VD]:\n  " << mse << std::endl;

    // 12. Clean up device allocations.
    HIPSOLVER_CHECK(hipsolverDestroy(hipsolver_handle));
    HIPSOLVER_CHECK(hipsolverDestroySyevjInfo(params));
    HIP_CHECK(hipFree(d_A));
    HIP_CHECK(hipFree(d_W));
    HIP_CHECK(hipFree(d_work));
    HIP_CHECK(hipFree(d_info));

    return report_validation_result(errors);
}

第一种 Makefile:

使用g++ 编译

SRC := hipsolver_Dsyevj.cpp

EXE := hipsolver_Dsyevj

all: $(EXE)

INC      := -I/opt/rocm/include
LD_FLAGS := -L/opt/rocm/lib -lamdhip64 -lrocblas -lhipsolver -lrocsolver -D__HIP_PLATFORM_AMD__


%: %.cpp
	g++ $< -o $@ $(INC) $(LD_FLAGS)


.PHONY: clean
clean:
	rm -rf $(EXE)

第二种 Makefile:

使用hipcc编译



EXAMPLE := hipsolver_syevj
COMMON_INCLUDE_DIR := ./Common
GPU_RUNTIME := HIP

# HIP variables
ROCM_INSTALL_DIR := /opt/rocm
CUDA_INSTALL_DIR := /usr/local/cuda

HIP_INCLUDE_DIR       := $(ROCM_INSTALL_DIR)/include
HIPSOLVER_INCLUDE_DIR := $(HIP_INCLUDE_DIR)

HIPCXX ?= $(ROCM_INSTALL_DIR)/bin/hipcc
CUDACXX ?= $(CUDA_INSTALL_DIR)/bin/nvcc

# Common variables and flags
CXX_STD   := c++17
ICXXFLAGS := -std=$(CXX_STD)
ICPPFLAGS := -isystem $(HIPSOLVER_INCLUDE_DIR) -I $(COMMON_INCLUDE_DIR)
ILDFLAGS  := -L $(ROCM_INSTALL_DIR)/lib
ILDLIBS   := -lhipsolver

ifeq ($(GPU_RUNTIME), CUDA)
	CXXFLAGS += -x cu
	CPPFLAGS += -D__HIP_PLATFORM_NVIDIA__
	COMPILER := $(CUDACXX)
else ifeq ($(GPU_RUNTIME), HIP)
	CXXFLAGS ?= -Wall -Wextra
	CPPFLAGS += -D__HIP_PLATFORM_AMD__
	COMPILER := $(HIPCXX)
else
	$(error GPU_RUNTIME is set to "$(GPU_RUNTIME)". GPU_RUNTIME must be either CUDA or HIP)
endif

ICXXFLAGS += $(CXXFLAGS)
ICPPFLAGS += $(CPPFLAGS)
ILDFLAGS  += $(LDFLAGS)
ILDLIBS   += $(LDLIBS)

$(EXAMPLE): hipsolver_Dsyevj.cpp
	$(COMPILER) -g $(ICXXFLAGS) $(ICPPFLAGS) $(ILDFLAGS) -o $@ $< $(ILDLIBS)

clean:
	$(RM) $(EXAMPLE)

.PHONY: clean

3,编译运行

make

 

4,提炼出来了

 

git@github.com:Kleenelan/yevj_batched_little_rocm.git

5, 参考

GitHub - amd/rocm-examples

结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1557875.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用1panel部署Ollama WebUI(dcoekr版)浅谈

文章目录 说明配置镜像加速Ollama WebUI容器部署Ollama WebUI使用问题解决&#xff1a;访问页面空白 说明 1Panel简化了docker的部署&#xff0c;提供了可视化的操作&#xff0c;但是我在尝试创建Ollama WebUI容器时&#xff0c;遇到了从github拉取镜像网速很慢的问题&#xf…

Java反射系列(3):从spring反射工具ReflectionUtils说起

传送门 在比较早的时候&#xff0c;就讨论过java反射的一些用法及概念&#xff1a; Java反射系列(1)&#xff1a;入门基础 以及反射的基石Class对象&#xff01; Java反射系列(2)&#xff1a;从Class获取父类方法说起 今天就从工作中实际的例子来看看反射的应用。 兼容…

pytest--python的一种测试框架--request请求加入headers

一、request headers中的cookie和session机制的作用与区别 Cookie 和 Session 是两种在客户端和服务器之间保持状态的技术。HTTP 协议本身是无状态的&#xff0c;这意味着服务器无法从上一次的请求中保留任何信息到下一次请求。Cookie 和 Session 机制就是为了解决这个问题。 …

240330-大模型资源-使用教程-部署方式-部分笔记

A. 大模型资源 Models - Hugging FaceHF-Mirror - Huggingface 镜像站模型库首页 魔搭社区 B. 使用教程 HuggingFace HuggingFace 10分钟快速入门&#xff08;一&#xff09;&#xff0c;利用Transformers&#xff0c;Pipeline探索AI。_哔哩哔哩_bilibiliHuggingFace快速入…

遥感数字图像处理的学习笔记

相关链接&#xff1a; 遥感数字图像处理实验教程&#xff08;韦玉春&#xff09;--部分实验问题回答 目录 1.什么是图像&#xff0c;什么是数字图像&#xff1f; 2.什么是遥感数字图像&#xff1f;模拟图像(照片)与遥感数字图像有什么区别&#xff1f; 3.什么是遥感数字图像…

小小狠招:巧妙使用HANA数据库的jdbc driver

SAP旗下的HANA数据库&#xff0c;实际上是分为两个系列进行发布&#xff0c;一种是基于本地部署的称之为HANA Platform。另一种是面向Cloud平台的&#xff0c;称之为HANA Cloud。 在实际使用当用&#xff0c;因为两者基本上共用同一代码库&#xff0c;除个别地方略有差异以外&…

C++要学到什么程度才能找到实习?

在考虑 C 学习到何种程度可以找到实习时&#xff0c;以下是一些具体的方向和建议。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我…

HarmonyOS 应用开发之模型切换

本文介绍如何将一个FA模型开发的声明式范式应用切换到Stage模型&#xff0c;您需要完成如下动作&#xff1a; 工程切换&#xff1a;新建一个Stage模型的应用工程。 配置文件切换&#xff1a;config.json切换为app.json5和module.json5。 组件切换&#xff1a;PageAbility/Serv…

如何计算KST指标,昂首资本一个公式计算

在上一篇文章中&#xff0c;Anzo Capital昂首资本和各位投资者一起了解了KST指标&#xff0c;今天我们继续分享如何计算KST指标。 首先投资者可以在时间范围9、12、18和24分析变化率值。 前三个值(时间帧9、12、18)用EMA 26平滑&#xff0c;最后一个值用EMA 39平滑。 然后&…

AndroidStudio出现类似 Could not create task ‘:app:ToolOperatorDemo.main()‘. 错误

先看我们的报错 翻译过来大概意思是:无法创建任务:app:ToolOperatorDemo.main()。 没有找到名称为“main”的源集。 解决方法&#xff1a; 在.idea文件夹下的gradle.xml文件中 <GradleProjectSettings>标签下添加<option name"delegatedBuild" value"f…

前端小白如何理解mvc mvp mvvm

架构、框架、设计模式是都是啥&#xff1f; 架构&#xff1a;抽象出来不同组织或者对象亦或是简单组件&#xff0c;根据需求和各个单元的功能&#xff0c;进行组合排列。 从而完成系统的运行或者是实现目标。 框架&#xff1a;使用什么样的规则&#xff0c;什么样的开发语言&…

政安晨:【Keras机器学习实践要点】(十)—— 自定义保存和序列化

目录 导言 涵盖的API Setup 状态保存自定义 构建和编译保存自定义 结论 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在…

2024年京东云主机租用价格_京东云服务器优惠价格表

2024年京东云服务器优惠价格表&#xff0c;轻量云主机优惠价格5.8元1个月、轻量云主机2C2G3M价格50元一年、196元三年&#xff0c;2C4G5M轻量云主机165元一年&#xff0c;4核8G5M云主机880元一年&#xff0c;游戏联机服务器4C16G配置26元1个月、4C32G价格65元1个月、8核32G费用…

速腾聚创上市后首份财报:冲击年销百万台,押注人形机器人

作者 |老缅 编辑 |德新 港股「激光雷达第一股」速腾聚创&#xff0c;交出了上市后的首份业绩报告。 3月27日&#xff0c;速腾聚创发布了2023年度财报。 报告期内&#xff0c;公司迎来高速的业务增长——2023年总收入达到人民币11.2亿元&#xff0c;同比增长达到111.2%。这主…

Artplayer视频JSON解析播放器源码|支持弹幕|json数据模式

全开源Artplayer播放器视频解析源码&#xff0c;支持两种返回模式&#xff1a;网页播放模式、json数据模式&#xff0c;json数据模式支持限制ip每分钟访问次数UA限制key密钥&#xff0c;也可理解为防盗链 &#xff0c;本播放器带弹幕库。 运行环境 推荐使用PHP8.0 redis扩展…

书生 浦语大模型全链路开源体系

通用大模型成为发展通用人工智能的重要途径 书生 浦语大模型的开源历程 书生 浦语 2.0体系&#xff0c;面向不同的使用需求&#xff0c;每个规格包含三个模型版本&#xff0c;&#xff08;7B、20B&#xff09;InternLM2-Base、InternLM2、InternLM2-Chat。 大模型是回归语言建…

前缀树/字典树Trie

目录 一、Trie的数据结构 二、代码示例 一、Trie的数据结构 Tire通常包括&#xff1a; 1.root节点(根节点)&#xff1a;插入、查找、删除、遍历等操作从root节点开始. 2.flag&#xff1a;结束标志true/false&#xff0c;用于表示当前节点是否为一个完整的字符串的结尾. 3.ke…

第几个幸运数字(蓝桥杯)

文章目录 第几个幸运数字题目描述答案&#xff1a;1905生成法C代码代码详细注释代码思路解释 第几个幸运数字 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 到x星球旅行的游客都被发给一个整数&#xff0c;作为…

软考高级架构师:信息安全保护等级

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

二十四种设计模式与六大设计原则(三):【装饰模式、迭代器模式、组合模式、观察者模式、责任链模式、访问者模式】的定义、举例说明、核心思想、适用场景和优缺点

接上次博客&#xff1a;二十四种设计模式与六大设计原则&#xff08;二&#xff09;&#xff1a;【门面模式、适配器模式、模板方法模式、建造者模式、桥梁模式、命令模式】的定义、举例说明、核心思想、适用场景和优缺点-CSDN博客 目录 装饰模式【Decorator Pattern】 定义…