"plugins/rpmd/platforms/hip/tests/TestHipRpmd.cpp" did not exist on "2a53088236129e8a85e7d63965d8cce56212ba25"
knlforce.br 2.79 KB
Newer Older
Mark Friedrichs's avatar
Mark Friedrichs committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

/****************************************************************
* This file is part of the gpu acceleration library for gromacs.
* Author: V. Vishal
* Copyright (C) Pande Group, Stanford, 2006
*****************************************************************/

/* 
 * 3rd attempt at writing a force kernel that uses neighborlists.
 * Keeping things very simple this time - no unrolling at all.
 *
 * Starting with simple Coul-LJ
 * */

//Constant dielectric, LJ (normal forces)
kernel float4 nl_scalar_force_CDLJ( float4 qq, float epsfac, float4 sig, float4 eps, float4 r2 ) {
	float4 invr, invrsig2, invrsig6;
	float4 f;

	invr = rsqrt( r2 ); // 1 or 2 flops?
	invrsig2 = invr * sig; //1 flop
	invrsig2 = invrsig2 * invrsig2; //1 flop
	invrsig6 = invrsig2 * invrsig2 * invrsig2; //2flops
	f = eps * ( 12.0f*invrsig6 - 6.0f ) * invrsig6; //4flops
	f += epsfac*qq*invr; //2 flops
	f *= invr*invr; //2 flops 
	return f; //Total ? flops
}

kernel float4 nl_get_r2( float3 d1, float3 d2, float3 d3, float3 d4 ) {
	float4 r2;
	r2 = float4( dot(d1, d1), dot( d2, d2 ), dot( d3, d3 ), dot( d4, d4 ) ); //5*4 flops
	return r2;
}

kernel void knbforce_nl(
		float AtomStrWidth,  //Width of atom position stream
		float epsfac,
		iter float2 wpos<>,  //pixel position of output (i-atom)
		float4 posq[][],     //coordinates and charges
		float3 inforce<>,
		float4 nlist0<>,     //nbor indices
		float4 sig0<>,        //LJ sigmas
		float4 eps0<>,        //LJ epsilons
		//We'll add more nlists here to reduce number of kernel calls
		out float3 force<>   //output forces
		)
{
	float2 jind;
	float4 ind_tmp1, ind_tmp2;
	float4 qj;
	float3 jpos1, jpos2, jpos3, jpos4;
	float4 r2, fs, qq;
	float3 d1, d2, d3, d4;
	float3 ipos;
	float qi;
	
	//Since neighbors will not be adjacent in memory
	//We may want to stagger compute and etch, but 
	//with fxc, we don't have control over scheduling anyway.
	//Will try hand scheduling the ps3 code later

	//etch i parameters
	ipos = posq[ wpos ].xyz;
	qi   = posq[ wpos ].w;

	//etch j parameters
	
	ind_tmp1 = floor( nlist0 / AtomStrWidth );
	ind_tmp2 = nlist0 - ind_tmp1 * AtomStrWidth;

	force = inforce;
	
	//1st set of 4 neighbors
	jind.y = ind_tmp1.x;
	jind.x = ind_tmp2.x;
	jpos1  = posq[ jind ].xyz;
	qj.x   = posq[ jind ].w;
	
	jind.y = ind_tmp1.y;
	jind.x = ind_tmp2.y;
	jpos2  = posq[ jind ].xyz;
	qj.y   = posq[ jind ].w;
	
	jind.y = ind_tmp1.z;
	jind.x = ind_tmp2.z;
	jpos3  = posq[ jind ].xyz;
	qj.z   = posq[ jind ].w;

	
	jind.y = ind_tmp1.w;
	jind.x = ind_tmp2.w;
	jpos4  = posq[ jind ].xyz;
	qj.w   = posq[ jind ].w;


	d1 = ipos - jpos1;
	d2 = ipos - jpos2;
	d3 = ipos - jpos3;
	d4 = ipos - jpos4;
	
	r2 = nl_get_r2( d1, d2, d3, d4 );

	qq = qi * qj;

	fs = nl_scalar_force_CDLJ( qq, epsfac, sig0, eps0, r2 );
	
	force += fs.x * d1;
	force += fs.y * d2;
	force += fs.z * d3;
	force += fs.w * d4;	
}