c++和cuda混合编程 实现传统神经网络
直接放代码了。。。
实现的是x1+x2=y的预测,但梯度下降很慢。。。233333,gpu运行时间很快!!
//
// main.cpp
// bp
//
// Created by jzc on 2018/4/18.
// Copyright © 2018年 jzc. All rights reserved.
//
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <fstream>
#include <cuda_runtime.h>
using namespace std;
#define DATASIZE 10000
#define TESTSIZE 100
#define NEURESIZE 50
#define RW 0.1
#define EPOCH 1000
#define E 2.71828
//打印设备信息
void printDeviceProp(const cudaDeviceProp &prop)
{
printf("Device Name : %s.\n", prop.name);
printf("totalGlobalMem : %ld.\n", prop.totalGlobalMem);
printf("sharedMemPerBlock : %ld.\n", prop.sharedMemPerBlock);
printf("regsPerBlock : %d.\n", prop.regsPerBlock);
printf("warpSize : %d.\n", prop.warpSize);
printf("memPitch : %ld.\n", prop.memPitch);
printf("maxThreadsPerBlock : %d.\n", prop.maxThreadsPerBlock);
printf("maxThreadsDim[0 - 2] : %d %d %d.\n", prop.maxThreadsDim[], prop.maxThreadsDim[], prop.maxThreadsDim[]);
printf("maxGridSize[0 - 2] : %d %d %d.\n", prop.maxGridSize[], prop.maxGridSize[], prop.maxGridSize[]);
printf("totalConstMem : %ld.\n", prop.totalConstMem);
printf("major.minor : %d.%d.\n", prop.major, prop.minor);
printf("clockRate : %d.\n", prop.clockRate);
printf("textureAlignment : %ld.\n", prop.textureAlignment);
printf("deviceOverlap : %d.\n", prop.deviceOverlap);
printf("multiProcessorCount : %d.\n", prop.multiProcessorCount);
} //CUDA 初始化
bool InitCUDA()
{
int count; //取得支持Cuda的装置的数目
cudaGetDeviceCount(&count); if (count == ) {
fprintf(stderr, "There is no device.\n");
return false;
} int i; for (i = ; i < count; i++) { cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, i);
//打印设备信息
printDeviceProp(prop); if (cudaGetDeviceProperties(&prop, i) == cudaSuccess) {
if (prop.major >= ) {
break;
}
}
} if (i == count) {
fprintf(stderr, "There is no device supporting CUDA 1.x.\n");
return false;
} cudaSetDevice(i); return true;
}
void init(int num,int range,double a[],double offset){
for(int i=;i<num;i++){
a[i] = (double)(rand()%(range*)/1000.0) - offset;
}
} void getM(int num,double a[],double m[]){
m[] = m[] = 0.0;
for(int i=;i<num;i++){
if(a[i]<m[]){
m[] = a[i];
}else if(a[i]>m[]){
m[] = a[i];
}
}
} void normalize(int num,double a[],double m[]){
for(int i =;i<num;i++){
a[i] = (a[i]-m[]+)/(m[]-m[]+);
}
} void renorm(int num,double a[],double m[]){
for(int i =;i<num;i++){
a[i] = a[i]*(m[]-m[]+) + m[] - ;
}
} void printArray(int num,double a[]){
for(int i=;i<num;i++){
printf("%6.4lf ",a[i]);
if((i+)%==){
cout<<endl;
}
}
} __global__ static void hidenLayer(double x1,double x2,double w1[],double w2[],double yh[]){
/*for(int i=0;i<NEURESIZE;i++){
yh[i] = w1[i]*x1 + w2[i]*x2;
yh[i] = 1/(1+pow(E,0-yh[i]));
}*/
const int tid = threadIdx.x;
int i =tid;
yh[i] = w1[i]*x1 + w2[i]*x2;
yh[i] = /(+pow(E,-yh[i]));
} double outLayer(double yh[],double v[]){
double y2;
for(int i=;i<NEURESIZE;i++){
y2 += yh[i] * v[i];
}
y2 = /(+pow(E,-y2));
return y2; } __global__ static void update(double x1[],double x2[],double yh[],double v[],double w1[],double w2[],double *loss){
const int tid = threadIdx.x;
int i = tid;
/*for(int i=0;i<NEURESIZE;i++){
w1[i] += x1[i] * (1-x1[i]) * loss * RW;
w2[i] += x2[i] * (1-x2[i]) * loss * RW;
v[i] += yh[i] * loss * RW;
}*/
w1[i] += x1[i] * (-x1[i]) * (*loss) * RW;
w2[i] += x2[i] * (-x2[i]) * (*loss) * RW;
v[i] += yh[i] * (*loss) * RW;
} /*double test(double w1[],double w2[],double v[],double m1[],double m2[],double my[]){
double tx1[TESTSIZE],tx2[TESTSIZE],ty[TESTSIZE],tyh[NEURESIZE],ty2[TESTSIZE];
double avLoss = 0.0; init(TESTSIZE,10,tx1,0.0);
init(TESTSIZE,10,tx2,0.0); for(int i=0;i<TESTSIZE;i++){
ty[i] = tx1[i] + tx2[i];
}
normalize(TESTSIZE,tx1,m1);
normalize(TESTSIZE,tx2,m2);
for(int q=0;q<TESTSIZE;q++){
hidenLayer(tx1[q],tx2[q],w1,w2,tyh);
ty2[q] = outLayer(tyh,v);
} renorm(TESTSIZE,ty2,my);
for(int i=0;i<TESTSIZE;i++){
if(i<10){
printf("%2d y=%2.4f y2=%2.4f\n",i,ty[i],ty2[i]);
}
avLoss += pow(ty[i]-ty2[i],2);
}
avLoss /= TESTSIZE;
//cout<<avLoss<<endl;
return avLoss;
}*/ int main(){
ofstream outf;
outf.open("trainloss.txt");
srand( (unsigned)time(NULL) );
long starttime = clock();
double x1[DATASIZE],x2[DATASIZE],y[DATASIZE],y2[DATASIZE];
double w1[NEURESIZE],w2[NEURESIZE],v[NEURESIZE],yh[NEURESIZE];
double m1[],m2[],my[];
double cLoss,realLoss,minTrainLoss = 1.0,minTestLoss = 1.0;
init(DATASIZE,,x1,0.0);
init(DATASIZE,,x2,0.0);
init(NEURESIZE,,w1,1.0);
init(NEURESIZE,,w2,1.0);
init(NEURESIZE,,v,1.0); for(int i=;i<DATASIZE;i++){
y[i] = x1[i] + x2[i];
} //CUDA 初始化
if (!InitCUDA()) {
return ;
}
//cudaMalloc 取得一块显卡内存
double *x1_g,*x2_g,*y_g,*y2_g;
double *w1_g,*w2_g,*v_g,*yh_g;
double *cLoss_g;
cudaMalloc((void**)&x1_g, sizeof(double)* DATASIZE);
cudaMalloc((void**)&x2_g, sizeof(double)* DATASIZE);
cudaMalloc((void**)&y_g, sizeof(double)* DATASIZE);
cudaMalloc((void**)&y2_g, sizeof(double)* DATASIZE);
cudaMalloc((void**)&w1_g, sizeof(double)* NEURESIZE);
cudaMalloc((void**)&w2_g, sizeof(double)* NEURESIZE);
cudaMalloc((void**)&v_g, sizeof(double)* NEURESIZE);
cudaMalloc((void**)&yh_g, sizeof(double)* NEURESIZE);
cudaMalloc((void**)&cLoss_g, sizeof(double)); //cudaMemcpy 将产生的随机数复制到显卡内存中
//cudaMemcpyHostToDevice - 从内存复制到显卡内存
//cudaMemcpyDeviceToHost - 从显卡内存复制到内存
cudaMemcpy(w1_g,w1, sizeof(double)*NEURESIZE, cudaMemcpyHostToDevice);
cudaMemcpy(w2_g,w2, sizeof(double)*NEURESIZE, cudaMemcpyHostToDevice);
cudaMemcpy(v_g,v, sizeof(double)*NEURESIZE, cudaMemcpyHostToDevice);
cudaMemcpy(x1_g,x1, sizeof(double)*DATASIZE, cudaMemcpyHostToDevice);
cudaMemcpy(x2_g,x2, sizeof(double)*DATASIZE, cudaMemcpyHostToDevice);
cudaMemcpy(y_g,y, sizeof(double)*DATASIZE, cudaMemcpyHostToDevice);
cudaMemcpy(yh_g,yh, sizeof(double)*NEURESIZE, cudaMemcpyHostToDevice);
cudaMemcpy(cLoss_g,&cLoss, sizeof(double), cudaMemcpyHostToDevice); getM(DATASIZE,x1,m1);
getM(DATASIZE,x2,m2);
getM(DATASIZE,y,my);
normalize(DATASIZE,x1,m1);
normalize(DATASIZE,x2,m2);
normalize(DATASIZE,y,my); for(int j=;j<EPOCH;j++){
double tLoss = 0.0;
for(int i=;i<DATASIZE;i++){
hidenLayer<< < , NEURESIZE, >> >(x1_g[i],x2_g[i],w1_g,w2_g,yh_g);
cudaMemcpy(yh,yh_g, sizeof(double)*NEURESIZE, cudaMemcpyDeviceToHost);
cudaMemcpy(v,v_g, sizeof(double)*NEURESIZE, cudaMemcpyDeviceToHost);
y2[i] = outLayer(yh,v);
cLoss = y2[i] * (-y2[i]) * (y[i]-y2[i]);
cudaMemcpy(cLoss_g,&cLoss, sizeof(double), cudaMemcpyHostToDevice);
update<< < , NEURESIZE, >> >(x1_g,x2_g,yh_g,v_g,w1_g,w2_g,cLoss_g);
cudaMemcpy(&cLoss,cLoss_g, sizeof(double)*NEURESIZE, cudaMemcpyDeviceToHost);
cLoss = pow(cLoss,);
cLoss = cLoss*(my[]-my[]+);
tLoss += cLoss;
}
tLoss /= DATASIZE;
if(tLoss<minTrainLoss){
minTrainLoss = tLoss;
}
printf("EPOCH--%d, trainLoss--%0.4f\n",j,tLoss);
outf<<j<<"\t"<<tLoss<<endl; /*cudaMemcpy(w1,w1_g, sizeof(double)*NEURESIZE, cudaMemcpyDeviceToHost);
cudaMemcpy(w2,w2_g, sizeof(double)*NEURESIZE, cudaMemcpyDeviceToHost);
cudaMemcpy(v,v_g, sizeof(double)*NEURESIZE, cudaMemcpyDeviceToHost);
double avLoss = test(w1,w2,v,m1,m2,my);
printf("EPOCH--%d, avLoss--%0.4f\n",j,avLoss);
if(avLoss<minTestLoss){
minTestLoss = avLoss;
}*/
cout<<"------------------"<<endl;
}
printf("minTrainLoss--%0.4f\n",minTrainLoss);
//printf("minTestLoss--%0.4f\n",minTestLoss);
outf.close(); //Free
cudaFree(x1_g);
cudaFree(x2_g);
cudaFree(y_g);
cudaFree(w1_g);
cudaFree(w2_g);
cudaFree(v_g);
cudaFree(yh_g);
cudaFree(cLoss_g); long endtime = clock()-starttime;
float execution_time = (float)endtime / ( * );
cout << "total time cost: " << execution_time<<endl; return ;
}
c++和cuda混合编程 实现传统神经网络的更多相关文章
- mpi和cuda混合编程的正确编译
针对大数据的计算,很多程序通过搭建mpi集群进行加速,并取得了很好的效果.算法内部的加速,当前的并行化趋势是利用GPU显卡进行算法加速.针对并行性非常好的算法,GPU加速效果将远大于集群带来的加速效果 ...
- 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...
- Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)
原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了mat ...
- CUDA+OpenGL混合编程
CUDA+OpenGL混合编程示例: #include <stdio.h> #include <stdlib.h> #include "GL\glew.h" ...
- [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库
前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...
- Matlab与.NET基于类型安全的接口混合编程入门
原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...
- Matlab与.NET混合编程解决人脸识别问题
原文:[原创]Matlab与.NET混合编程解决人脸识别问题 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ht ...
- 通过混合编程分析的方法和机器学习预测Web应用程序的漏洞
通过混合编程分析的方法和机器学习预测Web应用程序的漏洞 由于时间和资源的限制,web软件工程师需要支持识别出有漏洞的代码.一个实用的方法用来预测漏洞代码可以提高他们安全审计的工作效率.在这篇文章中, ...
- Android程序中,内嵌ELF可执行文件-- Android开发C语言混合编程总结
前言 都知道的,Android基于Linux系统,然后覆盖了一层由Java虚拟机为核心的壳系统.跟一般常见的Linux+Java系统不同的,是其中有对硬件驱动进行支持,以避开GPL开源协议限制的HAL ...
随机推荐
- 雪花算法,生成分布式唯一ID
2.3 基于算法实现 [转载] 这里介绍下Twitter的Snowflake算法——snowflake,它把时间戳,工作机器id,序列号组合在一起,以保证在分布式系统中唯一性和自增性. snowfla ...
- linq 动态排序 order by
项目查询数据库使用的是linq 语法,可是后期需要用到不同字段的排序.各种纠结! 在网上找了各种资料 后面才找到两种方法 using System; using System.Collections. ...
- Django Redis配置
Django Redis配置 # Django默认不支持redis,需要第三方插件来支持 pipenv install django-redis pipenv install hiredis # 不是 ...
- Linux下系统调用的组成与实现
主要包括三个部分:(1)唯一的系统调用号(System Call Number):(2)系统调用表中相应的表项,即具体的函数地址:(3)对应的具体函数,即系统调用函数体. 以getpid()POSIX ...
- Vue路由传参的几种方式
原 Vue路由传参的几种方式 2018年07月28日 23:52:40 广积粮缓称王 阅读数 12613 前言:顾名思义,vue路由传参是指嵌套路由时父路由向子路由传递参数,否则操作无效.传参方式 ...
- dota2从窗口模式切换到独占全屏模式后黑屏解决办法
在dota2安装目录中查找video.txt,修改setting.defaultres与setting.defaultresheight两个参数与显示器的分辨率相同. 修改setting.fullsc ...
- ClickHouse学习笔记
1. 概述 ClickHouse是一个用于联机分析(OLAP:Online Analytical Processing)的列式数据库管理系统(DBMS:Database Management Syst ...
- 【转】CCS5.5从硬盘读入.dat数据格式的单张图像
首页 博客 学院 CSDN学院 下载 论坛 APP CSDN 问答 商城 活动 VIP会员 ...
- 用于并发系统建模和验证的着色Petri网及其工具软件的CPN Tools(笔记整理)
1.着色Petri网(CPNS)是一种建模和验证系统的语言,在这些熊中并发性,交互性和同步性扮演着主要的角色,着色Petri网是一种功能编程语言Standard ML结合起来的离散时间建模语言,Pet ...
- golang基础归纳
1. hello-world package main import "fmt" func main(){ fmt.Println("Hello world, Go Go ...