当前位置: 首页 > news >正文

【CUDA代码实践03】m维网格n维线程块对二维矩阵的索引

文章目录

  • 一、数据存储方式
  • 二、二维网格二维线程块
  • 三、二维网格一维线程块
  • 四、一维网格一维线程块

为了方便下次找到文章,也方便联系我给大家提供帮助,欢迎大家点赞👍、收藏📂和关注🔔!一起讨论技术问题💻,一起学习成长📚!如果你有任何问题或想法,随时留言,我会尽快回复哦😊!


近年来,人工智能(AI)技术,尤其是大模型的快速发展,打开了全新的时代大门。对于想要在这个时代迅速成长并提升自身能力的个人而言,学会利用AI辅助学习已经成为一种趋势。不论是国内的文心一言、豆包,还是国外的ChatGPT、Claude,它们都能成为我们编程学习的有力助手。利用AI进行编程学习将大大提升自己的编程学习效率,这里给大家推荐一个我自己在用的集成ChatGPT和Claude的网站(国内可用,站点稳定):传送门

抓住AI时代每一个机会,加速自己成长,提高自己的核心价值!

一、数据存储方式

  • 数据在内存中是以线性、以行为主的方式存储
  • 本篇文章中,16x8的二维数组,在内存中一段连续的128个地址存储该数组
    在这里插入图片描述
    代码结构
    在这里插入图片描述

先放上头文件及main文件
common.cuh

#ifndef COMMON_CUH
#define COMMON_CUH#include "cuda_runtime.h"
#include <stdio.h>// 声明外部函数,它们将在其他文件中实现。
// 这些函数定义了 CUDA 的网格和块结构,分别表示
// 2维网格和2维线程块、2维网格和1维线程块、1维网格和1维线程块。
extern void grid2D_block2D();
extern void grid2D_block1D();
extern void grid1D_block1D();// ErrorCheck 是一个内联函数,用于检查 CUDA 函数的返回错误码。
// 如果有错误发生,它将打印错误代码、错误名称、错误描述、文件名和行号。
// 此函数的目的是帮助调试 CUDA 错误。
inline cudaError_t ErrorCheck(cudaError_t error_code, const char* filename, int lineNumber) {if (error_code != cudaSuccess) {printf("CUDA error:\ncode=%d, name=%s, description=%s\nfile=%s,line=%d\n",error_code, cudaGetErrorName(error_code), cudaGetErrorString(error_code), filename, lineNumber);return error_code;  // 返回错误码以便调用方了解错误情况。}return error_code;  // 如果没有错误,返回相同的错误码。
}// setGPU 是一个内联函数,用于设置 GPU 设备。
// 它首先获取系统中可用的 CUDA 兼容 GPU 数量。
// 如果没有找到可用的 GPU,程序将退出,否则设置设备并显示相应信息。
inline void setGPU() {int iDeviceCount = 0;  // 存储系统中可用 GPU 的数量// 获取设备数量并检查返回的错误码。cudaError_t error = ErrorCheck(cudaGetDeviceCount(&iDeviceCount), __FILE__, __LINE__);// 如果没有 GPU 或发生错误,则终止程序。if (error != cudaSuccess || iDeviceCount == 0) {printf("No CUDA compatible GPU found\n");exit(-1);  // 返回非零值,表示错误。} else {printf("The count of GPUs is %d.\n", iDeviceCount);  // 显示找到的 GPU 数量。}// 设置设备 ID 为 0 的 GPUint iDevice = 0;error = ErrorCheck(cudaSetDevice(iDevice), __FILE__, __LINE__);if (error != cudaSuccess) {printf("cudaSetDevice failed!\n");exit(-1);  // 设置失败时终止程序。} else {printf("cudaSetDevice success!\n");  // 成功设置 GPU 后的确认信息。}
}#endif // COMMON_CUH

main.cu

#include "cuda_runtime.h"
#include <stdio.h>
#include "./common.cuh" // 包含自定义的通用 CUDA 工具,例如 setGPU 和 ErrorCheckint main() {// grid2D_block2D();  // 使用 2维网格和 2维线程块的函数,已注释掉// grid2D_block1D();  // 使用 2维网格和 1维线程块的函数,已注释掉grid1D_block1D();    // 使用 1维网格和 1维线程块的函数,执行矩阵加法return 0; // 返回 0 表示程序执行成功
}

二、二维网格二维线程块

二维网格和二维线程块对二维矩阵进行索引,每个线程可负责一个矩阵元素的计算任务

在这里插入图片描述
在这里插入图片描述

//
// Created by Administrator on 2024/10/25.
//
#include "common.cuh"// 定义一个 CUDA 内核函数 addMatrix,用于对两个矩阵进行元素逐一相加。
// A、B 是输入矩阵,C 是输出矩阵,nx 和 ny 分别是矩阵的列数和行数。
__global__ void addMatrix(int *A, int *B, int *C, const int nx, const int ny) {int ix = blockIdx.x * blockDim.x + threadIdx.x; // 确定线程在 x 方向上的索引int iy = blockIdx.y * blockDim.y + threadIdx.y; // 确定线程在 y 方向上的索引unsigned int idx = iy * nx + ix; // 计算该线程对应矩阵中的一维索引// 仅当索引在矩阵范围内时执行加法运算,以避免越界访问if (ix < nx && iy < ny) {C[idx] = A[idx] + B[idx];}
}// 定义一个函数 grid2D_block2D 来设置并调用 CUDA 内核
// 该函数配置并使用二维网格和二维块结构
void grid2D_block2D(void) {setGPU(); // 设置 GPU// 初始化矩阵大小和字节数int nx = 16; // 列数int ny = 8;  // 行数int nxy = nx * ny; // 矩阵元素总数size_t stBytesCount = nxy * sizeof(int); // 矩阵所需的总字节数// 在主机(CPU)上分配内存int *ipHost_A, *ipHost_B, *ipHost_C;ipHost_A = (int *)malloc(stBytesCount); // 矩阵 AipHost_B = (int *)malloc(stBytesCount); // 矩阵 BipHost_C = (int *)malloc(stBytesCount); // 矩阵 C// 初始化 A 和 B 的值,C 初始化为零if (ipHost_A != NULL && ipHost_B != NULL && ipHost_C != NULL) {for (int i = 0; i < nxy; i++) {ipHost_A[i] = i;        // 矩阵 A 的元素值设为 iipHost_B[i] = i + 1;    // 矩阵 B 的元素值设为 i+1}memset(ipHost_C, 0, stBytesCount); // 矩阵 C 的元素初始化为 0}else {printf("fail to malloc memory.\n");exit(-1); // 如果内存分配失败,退出程序}// 在设备(GPU)上分配内存int *ipDevice_A, *ipDevice_B, *ipDevice_C;ErrorCheck(cudaMalloc((int **)&ipDevice_A, stBytesCount), __FILE__, __LINE__);ErrorCheck(cudaMalloc((int **)&ipDevice_B, stBytesCount), __FILE__, __LINE__);ErrorCheck(cudaMalloc((int **)&ipDevice_C, stBytesCount), __FILE__, __LINE__);if (ipDevice_A != NULL && ipDevice_B != NULL && ipDevice_C != NULL) {// 将 A 和 B 从主机复制到设备ErrorCheck(cudaMemcpy(ipDevice_A, ipHost_A, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);ErrorCheck(cudaMemcpy(ipDevice_B, ipHost_B, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);ErrorCheck(cudaMemcpy(ipDevice_C, ipHost_C, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);}else {printf("fail to malloc memory.\n");free(ipHost_A);free(ipHost_B);free(ipHost_C);exit(-1); // 如果设备内存分配失败,退出程序}// 设置线程块和网格维度dim3 block(4, 4); // 定义每个块的尺寸(4x4 线程块)dim3 grid((nx + block.x - 1) / block.x, (ny + block.y - 1) / block.y); // 定义网格尺寸printf("Thread config : grid (%d, %d) block (%d, %d)\n", grid.x, grid.y, block.x, block.y);// 启动 CUDA 内核addMatrix<<<grid, block>>>(ipDevice_A, ipDevice_B, ipDevice_C, nx, ny);ErrorCheck(cudaDeviceSynchronize(), __FILE__, __LINE__);// 将结果从设备复制回主机ErrorCheck(cudaMemcpy(ipHost_C, ipDevice_C, stBytesCount, cudaMemcpyDeviceToHost), __FILE__, __LINE__);// 输出前 10 个元素的加法结果,验证计算是否正确for (int i = 0; i < 10; i++) {printf("idx=%2d\tmatrix_A:%d\tmatrix_B:%d\tresult=%d\n", i + 1, ipHost_A[i], ipHost_B[i], ipHost_C[i]);}// 释放主机和设备上的内存free(ipHost_A);free(ipHost_B);free(ipHost_C);ErrorCheck(cudaFree(ipDevice_A), __FILE__, __LINE__);ErrorCheck(cudaFree(ipDevice_B), __FILE__, __LINE__);ErrorCheck(cudaFree(ipDevice_C), __FILE__, __LINE__);ErrorCheck(cudaDeviceReset(), __FILE__, __LINE__);return;
}

三、二维网格一维线程块

二维网格和一维线程块对二维矩阵进行索引
每个线程可负责一个矩阵元素的计算任务
与二维网格二维线程块的情况极为相似

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//
// Created by Administrator on 2024/10/25.
//
#include "common.cuh"// 定义一个 CUDA 内核函数 addMatrix_21D,用于执行矩阵相加操作。
// 与标准的 2维线程块不同,此内核使用 2维网格和 1维线程块配置。
// A、B 是输入矩阵,C 是输出矩阵,nx 和 ny 分别是矩阵的列数和行数。
__global__ void addMatrix_21D(int *A, int *B, int *C, const int nx, const int ny)
{int ix = blockIdx.x * blockDim.x + threadIdx.x; // 计算线程在 x 方向上的索引int iy = threadIdx.y;                           // 线程在 y 方向上的索引unsigned int idx = iy * nx + ix; // 将二维索引转换为一维索引// 仅在索引位于矩阵范围内时执行加法操作,避免越界访问if (ix < nx && iy < ny){C[idx] = A[idx] + B[idx];}
}// 定义一个函数 grid2D_block1D 来配置并调用 CUDA 内核。
// 该函数使用二维网格和一维块的配置。
void grid2D_block1D(void)
{setGPU(); // 设置 GPU 设备// 设置矩阵的尺寸int nx = 16; // 矩阵列数int ny = 8;  // 矩阵行数int nxy = nx * ny; // 矩阵总元素数size_t stBytesCount = nxy * sizeof(int); // 矩阵所需的总字节数// 在主机(CPU)上分配内存int *ipHost_A, *ipHost_B, *ipHost_C;ipHost_A = (int *)malloc(stBytesCount); // 分配矩阵 A 的内存ipHost_B = (int *)malloc(stBytesCount); // 分配矩阵 B 的内存ipHost_C = (int *)malloc(stBytesCount); // 分配结果矩阵 C 的内存// 初始化矩阵 A 和 B 的数据if(ipHost_A != NULL && ipHost_B != NULL && ipHost_C != NULL){for(int i = 0; i < nxy; i++){ipHost_A[i] = i;        // A 的每个元素为 iipHost_B[i] = i + 1;    // B 的每个元素为 i+1}} else {printf("fail to malloc memory.\n");exit(-1); // 如果内存分配失败,退出程序}// 在设备(GPU)上分配内存int *ipDevice_A, *ipDevice_B, *ipDevice_C;ErrorCheck(cudaMalloc((int **)&ipDevice_A, stBytesCount), __FILE__, __LINE__);ErrorCheck(cudaMalloc((int **)&ipDevice_B, stBytesCount), __FILE__, __LINE__);ErrorCheck(cudaMalloc((int **)&ipDevice_C, stBytesCount), __FILE__, __LINE__);if(ipDevice_A != NULL && ipDevice_B != NULL && ipDevice_C != NULL){// 将主机内存复制到设备ErrorCheck(cudaMemcpy(ipDevice_A, ipHost_A, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);ErrorCheck(cudaMemcpy(ipDevice_B, ipHost_B, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);ErrorCheck(cudaMemcpy(ipDevice_C, ipHost_C, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);} else {// 如果分配失败,释放内存并退出程序free(ipHost_A);free(ipHost_B);free(ipHost_C);exit(-1);}// 定义线程块和网格的尺寸dim3 block(4); // 每个块有 4 个线程dim3 grid((nx + block.x - 1) / block.x, (ny + block.y - 1) / block.y); // 配置网格尺寸printf("Thread config: grid (%d, %d), block(%d, %d).\n", grid.x, grid.y, block.x, block.y);// 启动 CUDA 内核addMatrix_21D<<<grid, block>>>(ipDevice_A, ipDevice_B, ipDevice_C, nx , ny);ErrorCheck(cudaDeviceSynchronize(), __FILE__, __LINE__);// 将结果从设备复制回主机ErrorCheck(cudaMemcpy(ipHost_C, ipDevice_C, stBytesCount, cudaMemcpyDeviceToHost), __FILE__, __LINE__);// 输出前 10 个元素的加法结果,进行验证for(int i = 0; i < 10; i++){printf("idx=%2d\tmatrix_A:%d\tmatrix_B:%d\tresult=%d\n", i + 1, ipHost_A[i], ipHost_B[i], ipHost_C[i]);}// 释放主机和设备上的内存free(ipHost_A);free(ipHost_B);free(ipHost_C);ErrorCheck(cudaFree(ipDevice_A), __FILE__, __LINE__);ErrorCheck(cudaFree(ipDevice_B), __FILE__, __LINE__);ErrorCheck(cudaFree(ipDevice_C), __FILE__, __LINE__);ErrorCheck(cudaDeviceReset(), __FILE__, __LINE__);return;
}

四、一维网格一维线程块

一维网格和一维线程块对二维矩阵进行索引
每个线程负责矩阵一列的运算
编写核函数时,需要使用循环

在这里插入图片描述
在这里插入图片描述

//
// Created by Administrator on 2024/10/28.
//
#include "common.cuh"// 定义一个 CUDA 内核函数 addMatrix_11D,使用 1D 网格和 1D 块来执行矩阵相加。
// A、B 是输入矩阵,C 是输出矩阵,nx 和 ny 分别是矩阵的列数和行数。
__global__ void addMatrix_11D(int *A, int *B, int *C, const int nx, const int ny)
{int ix = blockIdx.x * blockDim.x + threadIdx.x; // 计算线程在 x 方向的索引// 确保索引在矩阵范围内if (ix < nx){// 在 y 方向上循环遍历for (int iy = 0; iy < ny; iy++){unsigned int idx = iy * nx + ix; // 将二维索引转换为一维索引C[idx] = A[idx] + B[idx]; // 将 A 和 B 对应位置相加并存储在 C 中}}
}// 定义一个函数 grid1D_block1D 来配置并调用 CUDA 内核,使用 1D 网格和 1D 块
void grid1D_block1D(void)
{printf("grid1D_block1D\n");setGPU(); // 设置 GPU 设备// 定义矩阵的尺寸int nx = 16; // 矩阵的列数int ny = 8;  // 矩阵的行数int nxy = nx * ny; // 矩阵的总元素数size_t stBytesCount = nxy * sizeof(int); // 矩阵所需的总字节数// 在主机(CPU)上分配内存int *ipHost_A, *ipHost_B, *ipHost_C;ipHost_A = (int *)malloc(stBytesCount); // 分配矩阵 A 的内存ipHost_B = (int *)malloc(stBytesCount); // 分配矩阵 B 的内存ipHost_C = (int *)malloc(stBytesCount); // 分配结果矩阵 C 的内存// 初始化矩阵 A 和 B 的数据if(ipHost_A != NULL && ipHost_B != NULL && ipHost_C != NULL){for(int i = 0; i < nxy; i++){ipHost_A[i] = i;       // 矩阵 A 的元素设为 iipHost_B[i] = i + 1;   // 矩阵 B 的元素设为 i+1}} else {printf("fail to malloc memory.\n");exit(-1); // 如果分配失败,退出程序}// 在设备(GPU)上分配内存int *ipDevice_A, *ipDevice_B, *ipDevice_C;ErrorCheck(cudaMalloc((int **)&ipDevice_A, stBytesCount), __FILE__, __LINE__);ErrorCheck(cudaMalloc((int **)&ipDevice_B, stBytesCount), __FILE__, __LINE__);ErrorCheck(cudaMalloc((int **)&ipDevice_C, stBytesCount), __FILE__, __LINE__);if(ipDevice_A != NULL && ipDevice_B != NULL && ipDevice_C != NULL){// 将主机内存复制到设备ErrorCheck(cudaMemcpy(ipDevice_A, ipHost_A, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);ErrorCheck(cudaMemcpy(ipDevice_B, ipHost_B, stBytesCount, cudaMemcpyHostToDevice), __FILE__, __LINE__);} else {// 如果分配失败,释放内存并退出程序free(ipHost_A);free(ipHost_B);free(ipHost_C);exit(-1);}// 设置线程块和网格的尺寸dim3 block(4); // 每个块包含 4 个线程dim3 grid((nx + block.x - 1) / block.x); // 设置 1D 网格的维度printf("Thread config: grid (%d, %d), block(%d, %d).\n", grid.x, grid.y, block.x, block.y);// 启动 CUDA 内核addMatrix_11D<<<grid, block>>>(ipDevice_A, ipDevice_B, ipDevice_C, nx , ny);ErrorCheck(cudaDeviceSynchronize(), __FILE__, __LINE__);// 将结果从设备复制回主机ErrorCheck(cudaMemcpy(ipHost_C, ipDevice_C, stBytesCount, cudaMemcpyDeviceToHost), __FILE__, __LINE__);// 输出前 10 个元素的加法结果,验证计算正确性for(int i = 0; i < 10; i++){printf("idx=%2d\tmatrix_A:%d\tmatrix_B:%d\tresult=%d\n", i + 1, ipHost_A[i], ipHost_B[i], ipHost_C[i]);}// 释放主机和设备上的内存free(ipHost_A);free(ipHost_B);free(ipHost_C);ErrorCheck(cudaFree(ipDevice_A), __FILE__, __LINE__);ErrorCheck(cudaFree(ipDevice_B), __FILE__, __LINE__);ErrorCheck(cudaFree(ipDevice_C), __FILE__, __LINE__);ErrorCheck(cudaDeviceReset(), __FILE__, __LINE__);return;
}

相关文章:

【CUDA代码实践03】m维网格n维线程块对二维矩阵的索引

文章目录 一、数据存储方式二、二维网格二维线程块三、二维网格一维线程块四、一维网格一维线程块 为了方便下次找到文章&#xff0c;也方便联系我给大家提供帮助&#xff0c;欢迎大家点赞&#x1f44d;、收藏&#x1f4c2;和关注&#x1f514;&#xff01;一起讨论技术问题&am…...

VSCode Qt6安装OpenSSL

报错 Could NOT find OpenSSL, try to set the path to OpenSSL root folder in thesystem variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARYOPENSSL_INCLUDE_DIR SSL Crypto) (Required is at least version "3.0")问题确认 这个错误显示在Windows环境…...

JAVA学习-练习试用Java实现“定义一个用户类,包含用户名和密码”

问题&#xff1a; 定义一个用户类&#xff08;User&#xff09;&#xff0c;包含用户名&#xff08;username&#xff09;和密码&#xff08;password&#xff09;属性&#xff0c;提供静态方法验证密码是否有效&#xff08;长度至少为6&#xff09;&#xff0c;并提供getter和…...

大数据之VIP(Virtual IP,虚拟IP)负载均衡

VIP&#xff08;Virtual IP&#xff0c;虚拟IP&#xff09;负载均衡是一种在计算机网络中常用的技术&#xff0c;用于将网络请求流量均匀地分散到多个服务器上&#xff0c;以提高系统的可扩展性、可靠性和性能。以下是对VIP负载均衡的详细解释&#xff1a; 一、VIP负载均衡的基…...

鸿蒙网络编程系列38-Web组件文件下载示例

1. web组件文件下载能力简介 在本系列的第22篇文章&#xff0c;介绍了web组件的文件上传能力&#xff0c;同样的&#xff0c;web组件也具备文件下载能力&#xff0c;鸿蒙API提供了处理web组件下载事件的委托类型WebDownloadDelegate&#xff0c;该类型包括四个下载事件的回调接…...

Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置

文章目录 构建拓扑图配置IP地址配置路由器命令说明测试效果 构建拓扑图 1&#xff0c;添加2811路由器。 2&#xff0c;添加pc0。 3&#xff0c;使用交叉线连接路由器和pc&#xff08;注意线路端口&#xff09;。 4&#xff0c;使用配置线连接路由器和pc&#xff08;注意线路…...

Flink系列之:学习理解通过状态快照实现容错

Flink系列之&#xff1a;学习理解通过状态快照实现容错 状态后端检查点存储状态快照状态快照如何工作&#xff1f;确保精确一次&#xff08;exactly once&#xff09;端到端精确一次 状态后端 由 Flink 管理的 keyed state 是一种分片的键/值存储&#xff0c;每个 keyed state…...

Linux 读者写者模型

1.背景概念 在编写多线程的时候&#xff0c;有一种情况是十分常见的。那就是&#xff0c;有些公共数据修改的机会比较少。相比较改写&#xff0c;它们读的机会反而高的多。这样就衍生出了读者写者模型&#xff0c;在这个模型中&#xff0c;有两类线程&#xff1a;读者和写者。读…...

JavaScript 的 axios 实现文件下载功能

用 JavaScript 的 axios 实现文件下载功能&#xff0c;咱们要分几个步骤来搞定它&#xff01;最主要的部分是处理 二进制数据&#xff0c;可以生成一个进度检测&#xff0c;然后把它保存为文件。 文件名的获取二进制数据获取创建下载链接 const axios require(axios);const g…...

合合信息亮相2024中国模式识别与计算机视觉大会,用AI构建图像内容安全防线

近日&#xff0c;第七届中国模式识别与计算机视觉大会&#xff08;简称“PRCV 2024”&#xff09;在乌鲁木齐举办。大会由中国自动化学会&#xff08;CAA&#xff09;、中国图象图形学学会&#xff08;CSIG&#xff09;、中国人工智能学会&#xff08;CAAI&#xff09;和中国计…...

深度学习:匿名函数lambda函数的使用与numerical_gradient函数

背景&#xff1a; 假设我们有一个简单的线性回归模型&#xff0c;其损失函数是均方误差&#xff08;MSE&#xff09;&#xff1a; class LinearModel:def __init__(self):self.W np.random.randn(1, 1) # 初始化权重def predict(self, x):return np.dot(x, self.W) # 线性预…...

PHP数据类型

几种常用的数据类型&#xff1a; String&#xff08;字符串&#xff09; Integer&#xff08;整型&#xff09; Float&#xff08;浮点型&#xff09; Boolean&#xff08;布尔型&#xff09; NULL&#xff08;空值&#xff09; Array&#xff08;数组&#xff09; Obje…...

2FA-双因素认证

双因素认证&#xff08;2FA&#xff0c;Two-Factor Authentication&#xff09;是一种提高安全性的方法&#xff0c;要求用户在登录或进行某些敏感操作时提供两种不同类型的身份验证信息。这种方法通过引入第二层验证&#xff0c;增加了账户被未经授权访问的难度。 项目结构 …...

解决 Python 中的 TypeError 错误

解决 Python 中的 TypeError 错误 在 Python 编程中&#xff0c;TypeError 是一种常见的错误&#xff0c;通常发生在尝试对不兼容的类型进行操作时。了解这个错误的原因以及如何有效解决它&#xff0c;对于提高代码的可靠性和可读性至关重要。本文将详细讨论 TypeError 的成因…...

快速学会C 语言基本概念和语法结构

&#x1f600;前言 本篇博文是关于C 语言的基本概念和语法结构&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&a…...

Python酷库之旅-第三方库Pandas(172)

目录 一、用法精讲 791、pandas.UInt8Dtype类 791-1、语法 791-2、参数 791-3、功能 791-4、返回值 791-5、说明 791-6、用法 791-6-1、数据准备 791-6-2、代码示例 791-6-3、结果输出 792、pandas.UInt16Dtype类 792-1、语法 792-2、参数 792-3、功能 792-4、…...

Linux系统下minio设置SSL证书进行HTTPS远程连接访问

文章目录 1.配置SSL证书使用HTTPS访问2.MINIO SDK 忽略证书验证3.使用受信任的证书 1.配置SSL证书使用HTTPS访问 生成域名对应的SSL证书&#xff0c;下载Apache版本&#xff0c;我目前只发现Apache这个里面有对应的私钥和证书 私钥重命名为private.key证书重命名为public.crt&…...

npm 包的命名空间介绍,以及@typescript-eslint/typescript-eslint

npm 包的命名空间是一个重要的概念&#xff0c;用于组织和管理相关的包。通过命名空间&#xff0c;开发者可以避免命名冲突、增强包的可读性和可维护性。以下是关于 npm 命名空间的详细介绍&#xff0c;并以 typescript-eslint 作为示例。 1. 命名空间的结构 命名空间的格式为…...

ecovadis评估是什么,有什么提成自己评分等级

EcoVadis评估是一个企业社会责任&#xff08;CSR&#xff09;评级平台&#xff0c;旨在评估全球供应链的可持续性和道德情况。以下是对EcoVadis评估的详细介绍以及提升其评分等级的方法&#xff1a; 一、EcoVadis评估概述 定义&#xff1a;EcoVadis评估通过一系列框架评估公司…...

Vue3中ref、toRef和toRefs之间有什么区别?

前言 Vue 3 引入了组合式 API&#xff0c;其中 ref、toRef 和 toRefs 是处理响应式数据的核心工具。作为高级计算机工程师&#xff0c;我们有必要深入理解这些工具的细微差别&#xff0c;以便在实际项目中更加高效地管理状态。本文将详细解析 ref、toRef 和 toRefs 的区别&…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...