TreeBlog - 代码编程 http://bk.treeblog.top/index.php/category/code/ Window下Bandicoot库的使用 http://bk.treeblog.top/index.php/archives/178/ 2025-11-01T19:18:00+08:00 Windows环境下Bandicoot-CUDA GPU加速计算配置指南概述本文档详细介绍了在Windows环境下配置和使用Bandicoot-CUDA进行GPU加速计算的完整流程。Bandicoot是一个基于CUDA的C++线性代数库,能够显著提升矩阵运算性能。目录环境要求CUDA环境安装与验证Bandicoot库编译配置Visual Studio项目配置代码实现与测试常见问题解决环境要求硬件要求支持CUDA的NVIDIA显卡显卡计算能力(Compute Capability)3.0及以上软件要求Windows 10/11操作系统Visual Studio 2019/2022CUDA Toolkit 12.0或更高版本CMake 3.15或更高版本显卡兼容性查询请访问以下官方网站查询您的显卡是否支持CUDA:CUDA兼容显卡列表历史版本显卡支持下面文章中配置写的 sm 61 ,也是在这两个网页里面查看CUDA环境安装与验证1. CUDA Toolkit安装步骤1:卸载旧版本如果系统中已安装CUDA,建议先完全卸载后重新安装,确保环境干净。步骤2:下载安装CUDA访问NVIDIA CUDA官网下载适合Windows的CUDA Toolkit安装时务必选择"Developer"组件,记住安装路径参考资料: CUDA环境配置详细教程2. CUDA安装验证比较客观;步骤1:创建测试项目打开Visual Studio创建新项目,选择"CUDA 12.0 Runtime"模板使用默认的测试代码进行编译运行步骤2:处理兼容性问题如果遇到显卡计算能力不足的错误,需要:查询显卡的SM(Streaming Multiprocessor)版本在项目属性中调整CUDA编译设置设置合适的计算能力版本注意对于非 cuda 项目,例如纯 qt 项目,属性里面没有 cuda c/C++,可以如下图进行配置:步骤3:验证安装成功测试代码能够正常编译并运行,说明CUDA环境配置成功,注意测试代码可以在 main 最下面加上 std::cin.get() 暂停看下结果。3. 其他项目中的CUDA配置如需在非 CUDA 项目中使用 CUDA 功能,请参考:Visual Studio中CUDA配置方法Bandicoot库编译配置1. 依赖库准备下载Bandicoot源码访问Bandicoot官网下载最新版本的源代码包下载OpenBLAS库访问OpenBLAS GitHub发布页下载Windows x64版本(注意不要下载ARM版本)2. 使用CMake编译步骤1:CMake-GUI配置打开CMake-GUI后进行以下配置:源代码路径(Where is the source code):指向Bandicoot解压后的文件夹构建路径(等下构建内容在这里面):创建一个空的英文路径文件夹配置编译器:点击"Configure"按钮步骤2:处理配置错误配置过程中会出现红色错误提示,这是正常现象:按照提示逐项修改配置参数:步骤3:生成项目文件配置完成后,点击"Generate"生成Visual Studio解决方案文件。3. 编译动态链接库在构建目录中打开生成的.sln文件在Solution Explorer中找到"bandicoot"项目分别编译Debug和Release版本编译完成后,在对应目录下会生成所需的DLL文件Visual Studio项目配置1. 创建新项目重要提示: 请创建新的项目,不要在CUDA Runtime测试项目中添加Bandicoot,避免CUDA代码冲突。2. 项目属性配置右键项目 → 属性,进行以下配置:包含目录配置库目录配置预处理器定义3. 链接库配置在"附加依赖项"中添加以下库文件:bandicoot.lib libopenblas.lib cublas.lib cublasLt.lib cuda.lib cudadevrt.lib cudart.lib cudart_static.lib curand.lib cusolver.lib nvrtc.lib注意: OpenBLAS库路径需要根据实际安装位置调整,例如:E:\vsproject\bandicoot-2.1.1\OpenBLAS\lib\libopenblas.lib参考资料: 完整的CUDA库配置列表(并不需要这么完整的)代码实现与测试1. 基础配置代码创建Qt Console项目后,在代码开头添加必要的配置:// 禁用OpenCL支持(必须) #define COOT_DONT_USE_OPENCL 1 // 数学常量定义(必须) #define _USE_MATH_DEFINES #include <math.h> #include <cmath> // Bandicoot库 #include <bandicoot> using namespace coot;重要说明:#define COOT_DONT_USE_OPENCL 1 必须添加,否则会与CUDA产生冲突数学头文件是Bandicoot库的必要依赖2. 编译问题修复常见编译错误修复:在alias_wrapper.hpp文件第66行附近,找到以下代码:template<typename T2> constexpr //static // 注释掉这个static关键字 coot_inline typename enable_if2< !is_Mat<T2>::value && !is_subview<T2>::value && !is_diagview<T2>::value && !is_Cube<T2>::value && !is_subview_cube<T2>::value, bool >::result check(const T2&)将static关键字注释掉即可解决C++语法兼容性问题。3. 完整测试代码以下是集成了Armadillo(CPU)和Bandicoot(GPU)的性能对比测试代码:#if defined(_MSC_VER) && (_MSC_VER >= 1600) # pragma execution_character_set("utf-8") #endif #include <QtCore/QCoreApplication> #include <qdebug.h> #include <QElapsedTimer> // 必要的数学库定义 #define _USE_MATH_DEFINES #include <math.h> #include <cmath> // Bandicoot GPU库配置 #define COOT_DONT_USE_OPENCL 1 #include <bandicoot> #define COOT_KERNEL_CACHE_DIR "D:\\cuda_cache_can_delete" //这个可能没效果 using namespace coot; // Armadillo CPU库 #include <armadillo> using namespace arma; int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); qDebug() << "GPU加速计算性能测试程序启动...\n"; // 矩阵维度配置 const int rows = 10000; const int cols = 10000; // ======================== CPU计算流程(Armadillo) ======================== qDebug() << "=== CPU计算(Armadillo库) ==="; QElapsedTimer cpu_create_timer, cpu_calc_timer, cpu_total_timer; // CPU矩阵创建阶段 cpu_total_timer.start(); cpu_create_timer.start(); arma::mat cpu_A(rows, cols, arma::fill::randu); arma::mat cpu_B(rows, cols, arma::fill::randu); qint64 cpu_create_elapsed = cpu_create_timer.elapsed(); qDebug() << "CPU创建矩阵耗时:" << cpu_create_elapsed << "毫秒"; // CPU计算阶段 cpu_calc_timer.start(); arma::mat cpu_C = cpu_A * cpu_B; qint64 cpu_calc_elapsed = cpu_calc_timer.elapsed(); qint64 cpu_total_elapsed = cpu_total_timer.elapsed(); qDebug() << "CPU矩阵乘法计算耗时:" << cpu_calc_elapsed << "毫秒"; qDebug() << "CPU总流程耗时:" << cpu_total_elapsed << "毫秒"; // 显示CPU计算结果样本 qDebug() << "CPU计算结果(第一行前11列):"; cpu_C.row(0).cols(0, 10).print(); // ======================== GPU计算流程(Bandicoot) ======================== qDebug() << "\n=== GPU计算(Bandicoot库) ==="; QElapsedTimer gpu_create_timer, gpu_calc_timer, gpu_total_timer; // GPU矩阵创建阶段 gpu_total_timer.start(); gpu_create_timer.start(); coot::fmat gpu_X1(rows, cols, coot::fill::randu); coot::fmat gpu_X2(rows, cols, coot::fill::randu); qint64 gpu_create_elapsed = gpu_create_timer.elapsed(); qDebug() << "GPU创建矩阵耗时:" << gpu_create_elapsed << "毫秒"; // GPU计算阶段 gpu_calc_timer.start(); coot::fmat gpu_X3 = gpu_X1 * gpu_X2; qint64 gpu_calc_elapsed = gpu_calc_timer.elapsed(); qint64 gpu_total_elapsed = gpu_total_timer.elapsed(); qDebug() << "GPU矩阵乘法计算耗时:" << gpu_calc_elapsed << "毫秒"; qDebug() << "GPU总流程耗时:" << gpu_total_elapsed << "毫秒"; // ======================== 性能对比分析 ======================== qDebug() << "\n=== 性能对比分析 ==="; qDebug() << "测试矩阵规模:" << rows << "×" << cols << " × " << rows << "×" << cols; qDebug() << "----------------------------------------"; qDebug() << "| 计算阶段 | CPU耗时(ms) | GPU耗时(ms) | 加速比 |"; qDebug() << "----------------------------------------"; double create_speedup = gpu_create_elapsed > 0 ? (double)cpu_create_elapsed / gpu_create_elapsed : 0.0; double calc_speedup = gpu_calc_elapsed > 0 ? (double)cpu_calc_elapsed / gpu_calc_elapsed : 0.0; double total_speedup = gpu_total_elapsed > 0 ? (double)cpu_total_elapsed / gpu_total_elapsed : 0.0; qDebug() << QString("| 矩阵创建 | %1 | %2 | %3x |") .arg(cpu_create_elapsed, 8) .arg(gpu_create_elapsed, 8) .arg(create_speedup, 0, 'f', 2); qDebug() << QString("| 矩阵乘法 | %1 | %2 | %3x |") .arg(cpu_calc_elapsed, 8) .arg(gpu_calc_elapsed, 8) .arg(calc_speedup, 0, 'f', 2); qDebug() << QString("| 总体流程 | %1 | %2 | %3x |") .arg(cpu_total_elapsed, 8) .arg(gpu_total_elapsed, 8) .arg(total_speedup, 0, 'f', 2); qDebug() << "----------------------------------------"; if (calc_speedup > 1.0) { qDebug() << QString("GPU在矩阵乘法计算中实现了 %1 倍加速!").arg(calc_speedup, 0, 'f', 2); } else { qDebug() << "注意:当前测试中GPU性能未超过CPU,可能原因:"; qDebug() << "1. 矩阵规模较小,GPU并行优势未充分体现"; qDebug() << "2. GPU初始化开销较大"; qDebug() << "3. 建议增大矩阵规模进行测试"; } return app.exec(); }4. 代码说明关键配置项:COOT_DONT_USE_OPENCL 1:禁用OpenCL,避免与CUDA冲突_USE_MATH_DEFINES:启用数学常量定义COOT_KERNEL_CACHE_DIR:设置CUDA内核缓存目录(可选)性能测试功能:同时测试CPU(Armadillo)和GPU(Bandicoot)的矩阵运算性能分别计时矩阵创建和矩阵乘法操作自动计算加速比并生成对比报告常见问题解决1. 编译错误问题: alias_wrapper.hpp中的static关键字编译错误解决方案: 在该文件第66行附近注释掉static关键字问题: 缺少数学常量定义解决方案: 确保在代码开头添加:#define _USE_MATH_DEFINES #include <math.h> #include <cmath>2. 链接错误问题: 找不到CUDA库文件解决方案:检查CUDA安装路径是否正确确认项目配置中的库目录设置验证所有必需的.lib文件是否存在问题: OpenBLAS库路径错误解决方案: 根据实际安装位置调整库文件路径3. 运行时错误问题: 显卡计算能力不足解决方案:查询显卡的Compute Capability版本在CUDA项目属性中设置合适的SM版本参考NVIDIA官方兼容性列表问题: GPU性能未达到预期解决方案:增大矩阵规模以充分利用GPU并行计算优势进行GPU预热操作,排除初始化开销检查显卡驱动是否为最新版本4. 环境配置问题问题: CMake配置失败解决方案:确保使用英文路径检查CMake版本是否满足要求验证Visual Studio编译器配置问题: DLL文件缺失解决方案:确认编译生成了Debug和Release版本的DLL将必要的DLL文件复制到项目输出目录检查系统PATH环境变量总结本文档提供了在Windows环境下配置Bandicoot-CUDA GPU加速计算的完整指南。通过正确配置CUDA环境、编译Bandicoot库并在Visual Studio中进行项目配置,可以实现显著的矩阵运算性能提升。关键要点:确保显卡支持CUDA并正确安装CUDA Toolkit使用CMake正确编译Bandicoot库在Visual Studio中配置所有必要的包含目录和链接库注意代码中的关键配置宏定义通过性能测试验证GPU加速效果遵循本指南的步骤,您应该能够成功在 windows 下配置并使用Bandicoot进行高性能的GPU加速计算。 远程控制大战 http://bk.treeblog.top/index.php/archives/172/ 2025-05-22T18:12:02+08:00 这两天突发奇想再次捣鼓远程桌面,也是因为之前一直用 mstsc 微软的 RDP 远程桌面,感觉还是稍微有点卡, 之前也弄过解锁 60 FPS 什么的,但是还是感觉不明显,今天记录下各个远程软件和推荐;各个软件微软 RDP,网易 UU 远程,RustDesk(知名开源),向日葵,ToDesk,连连控,云玩加(个人开发者)前提要节对于一些国内厂商的远程,一般都提供他们自己的服务器进行进行搭桥或者连接,网易 UU 好像在网络好的时候可以 p2p 。例如向日葵,ToDesk 两个比较知名了,平时办公用用也还是可以的,但是也还是有些小问题,例如跨境连接等。所以,基于以上原因,对于我来说,先把两个外网的设备内网穿透桥接起来。用 皎月连 (需要打卡)或者 openp2p 这两个都可以;至于 zerotier 和 tailscale,前一个没弄好,后一个没用过;微软 RDP基于 皎月连 或者 openp2p 就可以通过 windows 的 mstsc 访问了,但好像貌似专业版系统,还要简单设置下一个知乎设置教程一个免密码登陆教程然后还有两个解锁 60 FPS 的教程,解锁60fps-1, 解锁2 怎么说了?之前平时一直是这么用的,感觉也还好,但是就是感觉(外网-手机热点)60 fps 还是没有这两天看了检查方法检测 60 fps 是否达到肉眼检测,😂,这个网站: https://frameratetest.org/zh/fps-test ,看看那两个竖着的黑杠杠动的是否流畅,还是可以看出分别,可以本机电脑开一个,远控电脑开一个,放在屏幕上对比了看,还是比较明显的,🤣推荐 RustDeskRustDesk 也是看的别人的教程,内网穿透后使用的,有两个软件要安装;被控端(服务端+客户端)安装;本机电脑(客户端安装),客户端下载链接, 服务端下载链接,这是两个 github 的链接,这是 github加速网站;看的这个教程:教程,主要就是下载好这几个软件,设置下 ip 和 key有几个小细节就是;可以吧下图的那个取消掉,网络好的话就是 p 2 p 直接连接,判断通过为全屏时左上角是✔就是 p 2 p,是刷新符号就是中继如果声音没有,可以看看 github 的 issue,我是把下图的禁用勾选了,就有声音了总体来说体验还是很不错的,速度上好像还比较快其他软件uu 远程有时候还可以,有时候可以 60 FPS然后是,连连控,还可以,可以稳定 60 FPS,稳定!!我都用的手机热点,还是可以,但是有些要开 vip云玩加,b 站上一个 up 开发的,还可以适配了手柄,还是开源免费的,fps 没确定,但是好像是自己弄了服务器,帮助记录下账号和两个机器握手,大概是这样小结就这些,推荐 RustDesk。但其实还有 Parsec(steamcommunity_302. exe 用的这个软件提供网络访问协助,Parsec 国内有些不好访问),但是我屋里电脑没弄那个显示器,Parsec 这个速度倒是可以,但是居然没自带虚拟显示器,ParsecVDisplay 这个 github 项目可以添加,但是今天还是下单了个 HDMI 欺骗器 5¥就这些了,RustDesk 还是可以的! PDF翻译-ai加持下的梅开二度 http://bk.treeblog.top/index.php/archives/170/ 2025-04-21T10:50:28+08:00 之前 pdf 翻译,看了别人的开源项目,一般是先解析为 md 文件,再翻译,现在借助多模态 ai 强大的图片ocr 可以直接翻译主要思路,把 PDF 转为一张张图片,然后给 ai ,让其输出翻译好的 md 文本,工具如下:我用的豆包 1.5 的 vision 版本-大模型 api,提示词也可以自定义效果大概如下图:推荐火山引擎 api: https://console.volcengine.com/auth/login还有一个硅基流动的: https://siliconflow.cn/zh-cn/openrouter 好像也有些免费的蓝奏云工具下载链接,api 在 config.json 里面要自己填下:https://wwzw.lanzoup.com/i70mH2u34nve这是源代码: https://wwzw.lanzoup.com/i60jm2u34ydc 神奇bug http://bk.treeblog.top/index.php/archives/138/ 2024-11-25T21:58:00+08:00 记录下今天的遇到的神奇bug,2024-11-25 ,21:56程序在windows下转为了qt creator的项目,让后在arm linux麒麟上运行,一个label突然就出错了,我的label上面写的(AAA\nBBB)本来应该是AAA一行BBB一行,排列的好好,但是编译出来就是AAA一行,然后空了一行,再才是BBB,摸不着头脑🧠。解决的也很奇葩,我把ui文件用designer打开,把\n删了,又输入了一遍,好了!?其他几个相同问题的label也好了,我都没有动😂感谢万能了网友上周5的时候,那个qt翻译ts文件,真的是多,200多条词语和句子,那个啥ts还是个必须是utf-8的奇怪xml结构,不像自己写工具,在网上找了找,还真有这样的工具,感谢网友,Qt-ts翻译工具, 帮忙节省了大量时间,先用这个把ts转为了xlsx,然后用本地的ollama 翻译了下,good😂,有瑕疵但是也可以tk 大模型import ollama def fanyiollama(danci): wenti = "翻译为英语:%s,注意第一个字母大写,直接给出英文翻译,甚至不要引号,重点直接给出英文翻译"%(danci) # 如果Ollama的host和port未更改,使用默认设置 res = ollama.chat(model="qwen2.5-coder:7b", stream=False, messages=[{"role": "user", "content": wenti}], options={"temperature": 0}) fanyi = res['message']['content'] print(res['message']['content']) return fanyi import openpyxl import os from fanyi2 import fanyiollama # 定义翻译函数(这里你可以替换为实际的翻译函数) def translate(text): return f"Translated: {text}" # 读取xlsx文件 input_file = r'G:\MyCodeGP\python\ollama翻译ts\untitled.xlsx' output_file = r'G:\MyCodeGP\python\ollama翻译ts\output_translated.xlsx' # 加载工作簿 if not os.path.exists(input_file): raise FileNotFoundError(f"File '{input_file}' not found!") workbook = openpyxl.load_workbook(input_file) sheet = workbook.active # 遍历第一列,查找第一列有值,第二列和第三列为空的单元格 for row in range(2, sheet.max_row + 1): # 假设第一行是标题,从第二行开始 first_col_value = sheet.cell(row=row, column=1).value second_col_value = sheet.cell(row=row, column=2).value third_col_value = sheet.cell(row=row, column=3).value if first_col_value and not second_col_value and not third_col_value: # 使用翻译函数将第一列的内容翻译,并保存到第二列和第三列 translated_text = fanyiollama(first_col_value) sheet.cell(row=row, column=2, value=translated_text) sheet.cell(row=row, column=3, value=translated_text) # 保存为新的xlsx文件 workbook.save(output_file) print(f"Translation complete. Results saved to '{output_file}'") 弄了一个火车票查询软件 http://bk.treeblog.top/index.php/archives/137/ 2024-10-13T12:54:00+08:00 用python弄了个火车票查询的,主要是想快点看看有哪些火车票hhh 感兴趣的可以看看 https://wwzw.lanzoup.com/icUop2cfnb4d ollama 如何跨设备调用 http://bk.treeblog.top/index.php/archives/101/ 2024-06-06T15:02:49+08:00 ollama 跨设备访问,轻松搞定远程调用用 Ollama API 调用本地大模型,通过 localhost:11434 就能搞定。但是,想在其他电脑上用 IP 地址调用,可能会存在问题。网上搜了搜,要么是 Linux 环境下的设置,要么是调整 windows 环境变量。st, Windows 下也能这么操作。ollama -h 看下帮助,然后ollama serve -h,看下帮助window 下面可以设置 OLLAMA_HOST所以 cmd 里面命令如下:set OLLAMA_HOST=0.0.0.0:11434bat 脚本则可以这么写:@echo off set OLLAMA_HOST=0.0.0.0:11434 set OLLAMA_ORIGINS=app://obsidian.md* ollama serve中间 3 句是方便 obsidian 访问的,没有需要的话可以不写 如何下载气象数据 http://bk.treeblog.top/index.php/archives/38/ 2023-07-30T21:46:00+08:00 如何下载气象数据下载数据,数据网站有两个,全球气象在分析数据下载 ,这个网站可以下载气象再分析数据,但是数据的时效性会有一点的延迟,第二个:ecmwf预报网站 这个网站的数据,是预报数据,可以预报之后几天的气象数据。两者数据都有 grib 格式,需要解析。python 解析 grib 文件。首先就是 python 环境的安装,xarray 这个工具可以直接读取 grib 文件。主要有三个插件需要安装,xarray,cfgrib,eccodes 这个三个, 安装环境最后就是对 grib 解析,上面有代码,为确定‘元素’的定位方法 (时间, 经纬度), 然后用 read_data.fg10.sel(longitude=115.4,latitude=22.2,time=i.data).to_pandas() 这样去读取就可以了,read_data,使用xarray读到的数据,fg10是grib中气象的变量名,sel是一个定位的方法.ok 【C++】C++ qt 与 python 简单进程通讯 http://bk.treeblog.top/index.php/archives/15/ 2022-09-03T11:47:00+08:00 【C++】C++ qt 与 python 简单进程通讯前言准备用 C++写一个简单的文字转语音的小东西,对 C++ qt 这个怎么弄不太清楚(现在看到 qt5.8 后有个叫 QTextToSpeech 的东西),发现 python 调用一些库来进行文字转语音的发声比较简单,准备用 python 来进行接受 C++信息,转成语音。python 端python 文字转语音还比较简单,导入 pyttsx3 这个库,然后调用一下就可以了。用的 socket 通讯,python 是作为服务端接受信息。import socket # 导入 socket 模块 import pyttsx3 as py3 port = '127.0.0.1' #定义ip ip = 12345 #定义端口 #申请socket服务端对象 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 创建 socket 对象 s.bind((ip, int(port))) # 绑定端口 s.listen(5) # 等待客户端连接 while True: print("> 服务成功开启,等待连接") client,addr = s.accept() # 建立客户端连接 data = client.recv(2048) #一次最多接受2048个字节 receive_data = data.decode('gb18030') #接受到的信息转成这个编码,这个编码范围广一些 engine = py3.init() engine.say(receive_data) engine.runAndWait() client.close()C++端C++端作为客户端,发送消息给 python。用的 VS2013 环境,其中要把 qt 的 web socket 模块加上。在调用的地方加上 #include <QtNetwork/QtNetwork> 这是一个全局的,qtcpsocket 在里面。可能需要在配置,链接器,输入中添加 Qt5Networkd. lib 这个库。这么用的头文件里面添加了个 QTcpSocket *m_tcpClient; 指针。 QString english_word = mWordList[index].mWord;//得到英语文本信息; std::string res = english_word.toLocal8Bit().toStdString();//转成string类型; char *buff = const_cast<char *>(res.c_str());//转成char类型发送; m_tcpClient->close();//关闭之前在主程序初始化时写了m_tcpClient = new QTcpSocket(this);生成的一个m_tcpClient;这段代码就可以多次调用了; delete(m_tcpClient);//释放指针空间; m_tcpClient = new QTcpSocket(this);//新建对象; m_tcpClient->connectToHost(QHostAddress("127.0.0.1"), 12345);//建立链接; m_tcpClient->write(buff);//发送信号C++端接受数据接受数据填上一句这 m_tcpClient->waitForReadyRead(); 就可以了,下面是接收的代码m_tcpClient->waitForReadyRead(); QByteArray data = m_tcpClient->readAll(); // 读取缓冲区数据 QString received_data = QString::fromUtf8(data.data(), data.size());注意在这么用的时候,需要在. h 文件里面先创建一个 QTcpSocket *m_tcpClient 指针,在构造函数里面先生请下空间,然后在后面才可以直接 close -- m_tcpClient->close(); OK。