一个用GPU写的一维卷积

代码说明:

本次代码采用GPU运算一维卷积.其中你需要输入两个数据,第一个是n是一位数据长度,一个是m卷积因子长度,代码会随机生成两个数组用于计算卷积.

代码思路:在CPU中生成数据复制到GPU中,其中GPU有两个函数,一个是__global__ void juanji(int *d_a,int *d_b,int *d_c,int *d_data,int n, int m),这个函数就是核函数,用于开n - m + 1个线程,因为数据长度为n卷积因子长度为m,那么卷积次数为n-m+1次所以这个核函数就是开卷积次数的线程,在这个核函数中还有另外一个核函数用于嵌套__global__ void neiji(int *d_a,int *d_b,int *d_c,int *d_data,int n, int m,int IJdx);因为卷积也可以并行计算的.在每一个卷积线程下,又开了m个线程用于计算卷积和,这样这个代码相当于开了 m *(n -m+1)个线程.直接就把卷积和算出了.其中不足之处就是求和的时候用的依然是串行算法.这里是一个可优化的地方.需要花时间搞搞并行求和的算法.

实验结果:

请输入一位向量的长度:
6
请输入卷积因子长度:
3
h_a[0] = 10	h_a[1] = 10	h_a[2] = 5	h_a[3] = 10	h_a[4] = 5	h_a[5] = 7	
h_b[0] = 7	h_b[1] = 10	h_b[2] = 9	
h_c[0] = 215	h_c[1] = 210	h_c[2] = 180	h_c[3] = 183	
运行结束

代码:

#include <iostream>
#include <cuda_runtime.h>
#include <stdlib.h>
#include <time.h>
__global__ void neiji(int *d_a,int *d_b,int *d_c,int *d_data,int n, int m,int IJdx)
{
	int temp = 0;
	int INdx = threadIdx.x;
	d_data[IJdx * m + INdx] = d_a[IJdx + INdx] * d_b[INdx];
	__syncthreads();
	for(int i = 0; i < m; ++i)
	{
		temp += d_data[IJdx * m + i];
	}
	d_c[IJdx] = temp;
}
__global__ void juanji(int *d_a,int *d_b,int *d_c,int *d_data,int n, int m)
{
	int IJdx = threadIdx.x;
	neiji<<<1,m>>>(d_a,d_b,d_c,d_data,n,m,IJdx);
	__syncthreads();
}
int main()
{
	int blag = 1;
	int m = 0, n = 0;
	do{
		std::cout << "请输入一位向量的长度:"<< std::endl;
		std::cin >> n;
		std::cout << "请输入卷积因子长度:" <<std::endl;
		std::cin >> m;
		if(m > n)
		{
			std::cout << "你输入的数据不合法,请重新输入!"<< std::endl;
		}else{
			blag = 0;
		}
	}while(blag);
	/*****申请主机内存*******/
	int *h_a,*h_b,*h_c;
	h_a = (int*)malloc(sizeof(int) * n);
	h_b = (int*)malloc(sizeof(int) * m);
	h_c = (int*)malloc(sizeof(int) * (n - m + 1));
	/******生成随机数据*******/
	srand(time(NULL));
	for(int i = 0; i < n; ++i)
	{
		h_a[i] = rand() % 11;
		printf("h_a[%d] = %d\t",i,h_a[i]);
	}
	printf("\n");
	for(int i = 0; i < m; ++i)
	{
		h_b[i] = rand() % 11;
		printf("h_b[%d] = %d\t",i,h_b[i]);
	}
	printf("\n");

	/******申请设备内存*************/
	int *d_a,*d_b,*d_c,*d_data;
	cudaMalloc((void**)&d_a,sizeof(int) * n);
	cudaMalloc((void**)&d_b,sizeof(int) * m);
	cudaMalloc((void**)&d_c,sizeof(int) * (n - m + 1));
	cudaMalloc((void**)&d_data,sizeof(int) * m * (n - m + 1));
	/******主机内存数据复制到设备内存中********/
	cudaMemcpy(d_a,h_a,sizeof(int) * n,cudaMemcpyHostToDevice);
	cudaMemcpy(d_b,h_b,sizeof(int) * m,cudaMemcpyHostToDevice);

	/*******启动核函数*******/
	juanji<<<1,n - m + 1>>>(d_a,d_b,d_c,d_data,n,m);

	/*******设备内存数据复制到主机内存中********/
	cudaMemcpy(h_c,d_c,sizeof(int) * (n - m + 1),cudaMemcpyDeviceToHost);

	for(int i = 0; i < n - m + 1; ++i)
	{
		printf("h_c[%d] = %d\t",i,h_c[i]);
	}
	printf("\n");

	/********释放内存********/
	free(h_a);
	free(h_b);
	free(h_c);
	cudaFree(d_a);
	cudaFree(d_b);
	cudaFree(d_c);
	std::cout << "运行结束" << std::endl;
	return 0;
}

 

一维卷积神经网络(1D Convolutional Neural Network, CNN)是卷积神经网络(Convolutional Neural Network, CNN)的一种简化版本,主要用于处理一维数据,如时间序列数据,例如音频信号或文本。CNN通常用于二维数据(图像)的分析,但在处理线性结构的数据时,一维CNN同样有效。 卷积神经网络的核心特别之处在于以下几个方面: 1. **局部连接和权重共享**:CNN中的卷积层利用每个过滤器(filter)对输入数据的局部区域进行卷积操作,这使得模型能够学习到数据中的局部特征。同时,同一个过滤器在不同位置使用相同的权重,减少了参数数量,提高了模型的效率。 2. **池化层**:CNN包含池化层,如最大池化或平均池化,用于下采样,提取数据的主要特征,同时降低计算复杂度和过拟合风险。 3. **深度学习**:CNN能够处理大量的层级结构,每一层捕捉数据的不同抽象特征,从低级的边缘、纹理,到高级的颜色和形状。 4. **平移不变性**:由于卷积操作,CNN对于输入中的特征变化具有一定的鲁棒性,即使特征在空间上移动,模型也能识别。 5. **训练效率**:对于图像数据,CNN通过并行计算的优势,可以在GPU上快速训练,尤其是在大型数据集上。 对于一维CNN来说,这些特性被调整为适应一维输入,例如在一维音乐数据或文本序列中检测模式和规律。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波雅_汉库克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值