-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathnbody.c
148 lines (127 loc) · 3.58 KB
/
nbody.c
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/////////////////////////////////////////////
// Test related params
#define PROFILING 1
#define SAMPLES 1
#define DEBUG 1
// Tolerance for comparing FP results
// due to different rounding in GPU ops.
#define FP_TOLERANCE 1e-3f
// Use case related params
#define DIM 3
#define PROBLEM_SIZE 10
#define DT 0.01f
#define ITERS 10
#define SOFTENING 1e-9f
/////////////////////////////////////////////
typedef struct
{
float x, y, z;
} Triple;
#pragma polca map CALCFORCE pos frc
void bodyForce(Triple *pos, Triple *frc, int n)
{
for (int i = 0; i < n; i++)
#pragma polca def CALCFORCE
#pragma polca input pos
#pragma polca output frc[i]
{
frc[i].x = 0.0f;
frc[i].y = 0.0f;
frc[i].z = 0.0f;
#pragma polca foldl ADDFORCE zip(frc[i], pos[i]) pos zip(frc[i], pos[i])
for (int j = 0; j < n; j++)
#pragma polca def ADDFORCE
#pragma polca input pos[j]
#pragma polca inout zip(frc[i], pos[i])
{
float dx = pos[j].x - pos[i].x;
float dy = pos[j].y - pos[i].y;
float dz = pos[j].z - pos[i].z;
float distSqr = dx*dx + dy*dy + dz*dz + SOFTENING;
float invDist = 1.0f / sqrtf(distSqr);
float invDist3 = invDist * invDist * invDist;
frc[i].x += dx * invDist3;
frc[i].y += dy * invDist3;
frc[i].z += dz * invDist3;
}
}
}
#pragma polca ZipWith UPDV frc vel vel
void velocities(Triple *frc, Triple *vel, float dt, int n)
{
for (int i = 0; i < n; i++)
#pragma polca def UPDV
#pragma polca input vel[i] frc[i]
#pragma polca output vel[i]
{
vel[i].x += dt*frc[i].x;
vel[i].y += dt*frc[i].y;
vel[i].z += dt*frc[i].z;
}
}
#pragma polca ZipWith UPDP pos vel pos
void integrate(Triple *pos, Triple *vel, float dt, int n)
{
for (int i = 0 ; i < n; i++)
#pragma polca def UPDP
#pragma polca input pos[i] vel[i]
#pragma polca output pos[i]
{
pos[i].x += vel[i].x*dt;
pos[i].y += vel[i].y*dt;
pos[i].z += vel[i].z*dt;
}
}
void loadData(Triple *ds, int n)
{
for(int i = 0; i<n; i++)
{
ds[i].x = ((float)(rand() % 1000))/10.0f;
ds[i].y = ((float)(rand() % 1000))/10.0f;
ds[i].z = ((float)(rand() % 1000))/10.0f;
}
}
void saveData(Triple *ds, int n)
{
for(int i = 0; i<n; i++)
{
printf("%f - %f - %f\n", ds[i].x, ds[i].y, ds[i].z);
}
}
int main(const int argc, const char** argv)
{
int nBodies;
const float dt = DT; // time step
const int nIters = ITERS; // simulation iterations
srand(0);
nBodies = PROBLEM_SIZE;
#pragma polca memAlloc (sizeof(Triple)) nBodies pStruct
Triple *pStruct = (Triple*)malloc(nBodies*sizeof(Triple));
#pragma polca memAlloc (sizeof(Triple)) nBodies vStruct
Triple *vStruct = (Triple*)malloc(nBodies*sizeof(Triple));
#pragma polca memAlloc (sizeof(Triple)) nBodies fStruct
Triple *fStruct = (Triple*)malloc(nBodies*sizeof(Triple));
loadData(pStruct, nBodies);
loadData(vStruct, nBodies);
#pragma polca itn MAINLOOP zip(pStruct, vStruct) nIters zip(pStruct, vStruct)
for (int iter = 0; iter < nIters; iter++)
#pragma polca def MAINLOOP
#pragma polca inout zip(pStruct, vStruct)
{
bodyForce(pStruct, fStruct, nBodies); // compute interbody forces
velocities(fStruct, vStruct, dt, nBodies); // update velocities
integrate(pStruct, vStruct, dt, nBodies); // integrate for dt
}
saveData(pStruct, nBodies);
saveData(vStruct, nBodies);
#pragma polca memFree pStruct
free(pStruct);
#pragma polca memFree vStruct
free(vStruct);
#pragma polca memFree fStruct
free(fStruct);
return 0;
}