欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

4.3 stability应用程序

程序员文章站 2022-06-22 09:52:35
...

4.2 flashlight基础上的改进

kernel.h

#pragma once
#ifndef KERNEL_H
#define KERNEL_H

struct uchar4;
struct int2;

void kernelLauncher(uchar4 *d_out, int w, int h, float p, int s);

#endif // !KERNEL_H

kernel.cu

#include "kernel.h"
#define TX 32//线程数
#define TY 32
#define LEN 5.f//空间比例因子
#define TIME_STEP 0.005f//时间步长
#define FINAL_TIME 10.f//时间间隔

__device__ float scale(int i, int w)//限定像素值的坐标范围[-LEN,LEN]
{
	return 2 * LEN*(((1.f*i) / w) - 0.5f);
}

__device__ float f(float x, float y, float param, float sys)//速度的变化率
{
	if (sys==1)//线性阻尼振荡器
	{
		return x - 2 * param*y;
	}
	if (sys == 2)//负有效刚度线性振荡器(接近于倒立摆位的情况)
	{
		return -x + param*(1 - x*x)*y;
	}
	else
		return -x - 2 * param*y;//范德堡尔振荡器,具有一个非线性阻尼项
}

//对一个给定的初始状态进行模拟,并且根据轨迹的位置在模拟区间结尾返回一个float2型的值
__device__ float2 euler(float x, float y, float dt, float tFinal, float param, float sys)
{
	float dx = 0.f, dy = 0.f;
	for (float t = 0; t < tFinal; t+=dt)
	{
		dx = dt*y;
		dy = dt*f(x, y, param, sys);
		x += dx;
		y += dy;
	}
	return make_float2(x, y);
}

__device__ unsigned char clip(int n)
{
	return n > 255 ? 255 : (n < 0 ? 0 : n);
}
__global__ void stabImageKernel(uchar4 *d_out, int w, int h, float p, int s)//阻尼参数p 振荡器类型s
{
	const int c = blockIdx.x*blockDim.x + threadIdx.x;
	const int r = blockIdx.x*blockDim.y + threadIdx.y;
	if ((c>=w)||(r>=h))
	{
		return;
	}
	const int i = c + r*w;
	const float x0 = scale(c, w);
	const float y0 = scale(r, h);
	const float dist_0 = sqrt(x0*x0 + y0*y0);
	const float2 pos = euler(x0, y0, TIME_STEP, FINAL_TIME, p, s);
	const float dist_f = sqrt(pos.x*pos.x+pos.y*pos.y);//基于距离比较分配阴影值
	const float dist_r = dist_f / dist_0;
	d_out[i].x = clip(dist_r * 255);//red逐渐远离平衡(即否决稳定的其他投票)
	d_out[i].y = ((c == w / 2));//green
	d_out[i].z = clip((1 / dist_r) * 255);//blue代表衰减到平衡(即稳定的投票)
	d_out[i].w = 255;

}
void kernelLauncher(uchar4 *d_out, int w, int h, float p, int s)
{
	const dim3 blockSize(TX, TY);
	const dim3 gridSize = dim3((w + TX - 1) / TX, (h + TY - 1) / TY);
	stabImageKernel << <gridSize, blockSize >> > (d_out, w, h, p, s);
}

interactions.h

#pragma once
#ifndef INTERACTIONS_H
#define INTERACTIONS_H
#define W 600//图像维度
#define H 600
#define DELTA 5//每按下箭头键参考点移动的距离(以像素为单位)
//#define  TITLE_STRING "flashlight:distance image display app"//标题栏中显示的文本
#define DELTA_P 0.1f
#define  TITLE_STRING "Stablility"

int sys = 0;
float param = 0.1f;
void keyboard(unsigned char key, int x, int y)
{
	if (key==27)
	{
		exit(0);
	}
	if (key=='0')
	{
		sys = 0;
	}
	if (key == '1')
		sys = 1;
	if (key == '2')
		sys = 2;
	glutPostRedisplay();
}

void handleSpecialKeypress(int key, int x, int y)
{
	if (key==GLUT_KEY_DOWN)
	{
		param -= DELTA_P;
	}
	if (key==GLUT_KEY_UP)
	{
		param += DELTA_P;//调节阻尼值
	}
	glutPostRedisplay();
}

void mouseMove(int x, int y) { return; }
void mouseDrag(int x, int y) { return; }

void printInstructions()
{
	printf("Stability visualizer\n");
	printf("Use number keys to select system:\n");
	printf("\t0: linear oscillator:positive stiffness\n");
	printf("\t1: linear oscillator:negative stiffness\n");
	printf("\t2: van der Pol oscillator:nonlinear damping\n");
	printf("up/down arrow keys adjust parameter value\n\n");
	printf("Choose the van der Pol (sys=2)\n");
	printf("Keep up arrow key depressed and watch the show.\n");
}
#endif

main.cpp中只对render()函数进行了改动,标题栏信息和内核启动调用

void render()//创造属于自己的CUDA/OPENGL互操作应用程序时,唯一需要改变的就是render函数
{
	uchar4 *d_out = 0;
	cudaGraphicsMapResources(1, &cuda_pbo_resource, 0);
	cudaGraphicsResourceGetMappedPointer((void**)&d_out, NULL, cuda_pbo_resource);
	kernelLauncher(d_out, W, H, param, sys);
	cudaGraphicsUnmapResources(1, &cuda_pbo_resource, 0);

	char title[64];
	sprintf(title, "Stability:param=%.1f,sys=%d", param, sys);
	glutSetWindowTitle(title);
}

运行结果:

4.3 stability应用程序

4.3 stability应用程序

相关标签: CUDA