ubuntu 22.04 cuda12.x 上 cutensor 1.6.2 版本环境搭建

embedded/2025/2/9 9:46:59/

ubuntu 22.04 cuda12.x 运行 cutensor 1.6.2  sample

1.6.2 是比较久的cutensor 版本,但是nv对新的cuda 平台做了继续支持,故可以在cuda sdk 12上使用cutensor 1.6.2

1,下载libcutensor 1.6.2

下载 cutensor 1.6.2 for all Linux and all cuda
https://developer.nvidia.com/cutensor/1.6.2/downloads


wget https://developer.download.nvidia.com/compute/cutensor/redist/libcutensor/linux-x86_64/libcutensor-linux-x86_64-1.6.2.3-archive.tar.xz


tar xf libcutensor-linux-x86_64-1.6.2.3-archive.tar.xz
ls lib..../lib/
10.2/ 11/ 11.0/ 12/

2,运行示例

由于cutensor 2.x中的api有改写,例如 cutensorInit(&handle) 已经改名字;

故需要使用旧的 CUDALibrarySamples中的代码运行示例,例如:

Makefile:

CUTENSOR_ROOT := /home/hipper/cutensor_ex/libcutensor-linux-x86_64-1.6.2.3
CXX_FLAGS=-std=c++11 -I${CUTENSOR_ROOT}/include -L${CUTENSOR_ROOT}/lib/12 -lcutensor -lcudartall:nvcc einsum.cu -o  einsum ${CXX_FLAGS}nvcc contraction.cu -o  contraction ${CXX_FLAGS}nvcc contraction_simple.cu -o  contraction_simple ${CXX_FLAGS}nvcc contraction_autotuning.cu -o  contraction_autotuning ${CXX_FLAGS}nvcc elementwise_binary.cu -o  elementwise_binary ${CXX_FLAGS}nvcc elementwise_permute.cu -o  elementwise_permute ${CXX_FLAGS}nvcc elementwise_trinary.cu -o  elementwise_trinary ${CXX_FLAGS}nvcc reduction.cu -o  reduction ${CXX_FLAGS}clean:rm -f contraction contraction_simple contraction_autotuning elementwise_binary elementwise_permute elementwise_trinary reduction

contraction_simple.cu

#include <stdlib.h>
#include <stdio.h>#include <unordered_map>
#include <vector>#include <cuda_runtime.h>
#include <cutensor.h>#define HANDLE_ERROR(x)                                               \
{ const auto err = x;                                                 \if( err != CUTENSOR_STATUS_SUCCESS )                                \{ printf("Error: %s\n", cutensorGetErrorString(err)); return err; } \
};#define HANDLE_CUDA_ERROR(x)                                      \
{ const auto err = x;                                             \if( err != cudaSuccess )                                        \{ printf("Error: %s\n", cudaGetErrorString(err)); return err; } \
};/* This routine computes the tensor contraction \f[ D = alpha * A * B + beta * C \f] using the staged-API */
cutensorStatus_t cutensorContractionSimple(const cutensorHandle_t* handle,const void* alpha, const void *A, const cutensorTensorDescriptor_t* descA, const int32_t modeA[],const void *B, const cutensorTensorDescriptor_t* descB, const int32_t modeB[],const void* beta,  const void *C, const cutensorTensorDescriptor_t* descC, const int32_t modeC[],void *D, const cutensorTensorDescriptor_t* descD, const int32_t modeD[],cutensorComputeType_t typeCompute, cutensorAlgo_t algo, cutensorWorksizePreference_t workPref,cudaStream_t stream)
{/*********************************************** Retrieve the memory alignment for each tensor**********************************************/ uint32_t alignmentRequirementA;HANDLE_ERROR(cutensorGetAlignmentRequirement(handle,A, descA, &alignmentRequirementA));uint32_t alignmentRequirementB;HANDLE_ERROR(cutensorGetAlignmentRequirement(handle,B, descB, &alignmentRequirementB));uint32_t alignmentRequirementC;HANDLE_ERROR(cutensorGetAlignmentRequirement(handle,C, descC, &alignmentRequirementC));uint32_t alignmentRequirementD;HANDLE_ERROR(cutensorGetAlignmentRequirement(handle,D, descD, &alignmentRequirementD));/******************************** Create Contraction Descriptor*******************************/cutensorContractionDescriptor_t desc;HANDLE_ERROR(cutensorInitContractionDescriptor(handle, &desc,descA, modeA, alignmentRequirementA,descB, modeB, alignmentRequirementB,descC, modeC, alignmentRequirementC,descD, modeD, alignmentRequirementD,typeCompute));/*************************** Set the algorithm to use***************************/cutensorContractionFind_t find;HANDLE_ERROR(cutensorInitContractionFind( handle, &find, algo));/*********************** Query workspace**********************/size_t worksize = 0;HANDLE_ERROR(cutensorContractionGetWorkspaceSize(handle,&desc,&find,workPref, &worksize));void *work = nullptr;if (worksize > 0){if(cudaSuccess != cudaMalloc(&work, worksize)){work = nullptr;worksize = 0;}} /*************************** Create Contraction Plan**************************/cutensorContractionPlan_t plan;HANDLE_ERROR(cutensorInitContractionPlan(handle,&plan,&desc,&find,worksize));/*********************** Run**********************/HANDLE_ERROR(cutensorContraction(handle,&plan,(void*) &alpha, A, B,(void*) &beta,  C, D, work, worksize, stream));return CUTENSOR_STATUS_SUCCESS;
}int main()
{typedef float floatTypeA;typedef float floatTypeB;typedef float floatTypeC;typedef float floatTypeCompute;cudaDataType_t typeA = CUDA_R_32F;cudaDataType_t typeB = CUDA_R_32F;cudaDataType_t typeC = CUDA_R_32F;cutensorComputeType_t typeCompute = CUTENSOR_COMPUTE_32F;floatTypeCompute alpha = (floatTypeCompute) 1.1f;floatTypeCompute beta  = (floatTypeCompute) 0.f;/*********************** Computing: C_{m,u,n,v} = alpha * A_{m,h,k,n} B_{u,k,v,h} + beta * C_{m,u,n,v}**********************/std::vector<int> modeC{'m','u','n','v'};std::vector<int> modeA{'m','h','k','n'};std::vector<int> modeB{'u','k','v','h'};int nmodeA = modeA.size();int nmodeB = modeB.size();int nmodeC = modeC.size();std::unordered_map<int, int64_t> extent;extent['m'] = 96;extent['n'] = 96;extent['u'] = 96;extent['v'] = 64;extent['h'] = 64;extent['k'] = 64;double gflops = (2.0 * extent['m'] * extent['n'] * extent['u'] * extent['v'] * extent['k'] * extent['h']) /1e9;std::vector<int64_t> extentC;for (auto mode : modeC)extentC.push_back(extent[mode]);std::vector<int64_t> extentA;for (auto mode : modeA)extentA.push_back(extent[mode]);std::vector<int64_t> extentB;for (auto mode : modeB)extentB.push_back(extent[mode]);/*********************** Allocating data**********************/size_t elementsA = 1;for (auto mode : modeA)elementsA *= extent[mode];size_t elementsB = 1;for (auto mode : modeB)elementsB *= extent[mode];size_t elementsC = 1;for (auto mode : modeC)elementsC *= extent[mode];size_t sizeA = sizeof(floatTypeA) * elementsA;size_t sizeB = sizeof(floatTypeB) * elementsB;size_t sizeC = sizeof(floatTypeC) * elementsC;printf("Total memory: %.2f GiB\n", (sizeA + sizeB + sizeC)/1024./1024./1024);void *A_d, *B_d, *C_d;HANDLE_CUDA_ERROR(cudaMalloc((void**) &A_d, sizeA));HANDLE_CUDA_ERROR(cudaMalloc((void**) &B_d, sizeB));HANDLE_CUDA_ERROR(cudaMalloc((void**) &C_d, sizeC));floatTypeA *A = (floatTypeA*) malloc(sizeof(floatTypeA) * elementsA);floatTypeB *B = (floatTypeB*) malloc(sizeof(floatTypeB) * elementsB);floatTypeC *C = (floatTypeC*) malloc(sizeof(floatTypeC) * elementsC);if (A == NULL || B == NULL || C == NULL){printf("Error: Host allocation of A, B, or C.\n");return -1;}/******************** Initialize data*******************/for (int64_t i = 0; i < elementsA; i++)A[i] = (((float) rand())/RAND_MAX - 0.5)*100;for (int64_t i = 0; i < elementsB; i++)B[i] = (((float) rand())/RAND_MAX - 0.5)*100;for (int64_t i = 0; i < elementsC; i++)C[i] = (((float) rand())/RAND_MAX - 0.5)*100;HANDLE_CUDA_ERROR(cudaMemcpy(A_d, A, sizeA, cudaMemcpyHostToDevice));HANDLE_CUDA_ERROR(cudaMemcpy(B_d, B, sizeB, cudaMemcpyHostToDevice));HANDLE_CUDA_ERROR(cudaMemcpy(C_d, C, sizeC, cudaMemcpyHostToDevice));/************************** cuTENSOR*************************/ cutensorHandle_t handle;HANDLE_ERROR(cutensorInit(&handle));/*********************** Create Tensor Descriptors**********************/cutensorTensorDescriptor_t descA;HANDLE_ERROR(cutensorInitTensorDescriptor(&handle,&descA,nmodeA,extentA.data(),NULL /* stride */,typeA, CUTENSOR_OP_IDENTITY));cutensorTensorDescriptor_t descB;HANDLE_ERROR(cutensorInitTensorDescriptor(&handle,&descB,nmodeB,extentB.data(),NULL /* stride */,typeB, CUTENSOR_OP_IDENTITY));cutensorTensorDescriptor_t descC;HANDLE_ERROR(cutensorInitTensorDescriptor(&handle,&descC,nmodeC,extentC.data(),NULL /* stride */,typeC, CUTENSOR_OP_IDENTITY));HANDLE_ERROR(cutensorContractionSimple(&handle,(void*)&alpha, A_d, &descA, modeA.data(),B_d, &descB, modeB.data(),(void*)&beta,  C_d, &descC, modeC.data(),C_d, &descC, modeC.data(),typeCompute, CUTENSOR_ALGO_DEFAULT,CUTENSOR_WORKSPACE_RECOMMENDED, 0 /* stream */));return 0;
}

运行:

export LD_LIBRARY_PATH=/home/hipper/cutensor_ex/libcutensor-linux-x86_64-1.6.2.3/lib/12


http://www.ppmy.cn/embedded/160773.html

相关文章

华为支付-免密支付接入签约代扣场景开发步骤

一、预签约&#xff08;服务器开发&#xff09; 1.开发者按照商户模型调用预直连商户预签约或服务商预签约接口获取preSignNo构建签约信息参数contractStr。 为保证支付订单的安全性和可靠性需要对请求body和请求头PayMercAuth对象内的入参排序拼接进行签名。请参考排序拼接和…

DeepSeek 提示词之角色扮演的使用技巧

老六哥的小提示&#xff1a;我们可能不会被AI轻易淘汰&#xff0c;但是会被“会使用AI的人”淘汰。 在DeepSeek的官方提示库中&#xff0c;有“角色扮演&#xff08;自定义人设&#xff09;”的提示词案例。截图如下&#xff1a; 在“角色扮演”的提示词案例中&#xff0c;其实…

【第一篇章】 C++ 初识

一、进门首先说 say hello 编写 helloworld.cpp 的文件&#xff0c;具体内容如下&#xff1a; #include <iostream> using namespace std; int main() {cout << "Hello, world!" << endl;return 0; }编译文件 g helloworld.cpp -o helloworld运…

python中的flask框架

Flask 是一个用Python编写的轻量级Web应用框架 基于WSGI和Jinja2模板引擎 被称为“微框架”&#xff0c;其核心功能简单&#xff0c;不捆绑数据库管理、表单验证等功能&#xff0c;而是通过扩展来增加其他功能 Flask提供最基本的功能&#xff0c;不强制使用特定工具或库 通…

认识网络安全

一 网络攻击链 踩点-工具准备-载荷投递-漏洞利用-释放载荷-建立通道-目标达成 简化下&#xff1a; 目标侦察&#xff1a;准确识别目标&#xff0c;收集目标详细信息&#xff0c;比如 网络、 邮箱、员工、社会关系、对外提供服务、漏洞 信息等&#xff0c;为 后续攻击做准备。…

Java实现状态模式

一、简介 1、定义 状态模式 (State Pattern)是一种行为型设计模式&#xff0c;允许对象在内部状态改变时改变它的行为。通过定义状态接口和具体状态类&#xff0c;将对象的状态和行为分开&#xff0c;使得状态改变时可以改变行为。 2、状态模式的结构 状态模式涉及以下几个角…

【C语言】C语言经典面试题详解

文章目录 引言1. 指针与数组1.1 指针与数组的区别1.2 指针数组与数组指针 2. 内存管理2.1 malloc与free2.2 内存泄漏与悬空指针 3. 函数指针3.1 函数指针的定义与使用3.2 回调函数 4. 结构体与联合体4.1 结构体的内存对齐4.2 联合体的使用场景4.3 位段 5. 预处理器与宏5.1 宏定…

直接插入排序

一&#xff1a;直接插入排序是什么。 二&#xff1a;如何实现直接插入排序 三&#xff1a;直接插入排序时间复杂度 一&#xff1a;直接插入排序它是排序得一种&#xff0c;其目的无非是将乱序通过排序排成有序的。 我们可以通过动画直观看什么是直接插入排序 这是我找的直接…