-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkernel.c
152 lines (137 loc) · 4.05 KB
/
kernel.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
149
150
151
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
int count_larger(__global double* fit) {
const int gid = get_global_id(0);
const int grpid = get_group_id(0);
const int num_lcl = get_local_size(0);
const int lid = get_local_id(0);
barrier(CLK_GLOBAL_MEM_FENCE | CLK_LOCAL_MEM_FENCE);
int num_larger = 0;
for (int i = grpid * num_lcl; i < grpid * num_lcl + num_lcl; i++) {
if (fit[i] > fit[gid] || fit[gid] < 1) {
num_larger++;
}
}
return num_larger;
}
__kernel
void init(
__global int* _port,
__global float* thd_rnd,
__global float* fit,
const int num_sec,
const int num_thd,
const int rnd_off)
{
const int gid = get_global_id(0);
__global int* port = _port + gid * num_sec;
for (int i = 0; i < num_sec; i++)
port[i] = 10 * thd_rnd[(gid + rnd_off + i) % num_thd] - 5;
fit[gid] = 0;
}
__kernel
void get_fitness(
__constant float* alpha,
__constant float* bid,
__constant float* ask,
__constant float* prc,
__constant float* adv,
__global int* _port_s,
__global double* fit,
__global float* thd_rnd,
const int num_sec,
const int num_thd)
{
const int gid = get_global_id(0);
__global int* port = _port_s + gid * num_sec;
const double target_gmv = 200000;
const double max_nmv = 0.025 * target_gmv;
const double max_participation = .025;
double fit_ = 0;
float gmv = 0;
float nmv = 0;
float max_part = 0;
for (int i = 0; i < num_sec; i++) {
fit_ += alpha[i] * port[i] * adv[i] / fabs(ask[i]-bid[i]);
gmv += fabs(port[i]*prc[i]);
nmv += port[i]*prc[i];
max_part = max(max_part, fabs(port[i] * prc[i] / adv[i]));
}
fit_ *= gmv;
fit_ *= max_participation / max_part;
if (!(gmv < target_gmv) ||
!(fabs(nmv) < max_nmv) ||
!(max_part < max_participation) ||
!(fit_ > 0))
{
fit_ = -1.0;
for (int i = 0; i < num_sec; i++) {
port[i] /= 10;
}
}
fit[gid] = fit_;
}
__constant float mut_prob = .3;
__constant float recom_prob = .5;
__kernel
void mutate(
__global int* _port,
__global double* fit,
__global float* sec_rnd,
__global float* thd_rnd,
__local int* best,
const int num_sec,
const int num_thd,
const int num_keep,
const int rnd_off)
{
int gid = get_global_id(0);
int larger = count_larger(fit);
bool keep = larger == 0;
bool mutate = thd_rnd[(rnd_off + gid) % num_thd] < mut_prob;
bool recom = !mutate && thd_rnd[(rnd_off + gid) % num_thd] < recom_prob;
__global int* port = _port + gid * num_sec;
for (int i = 0; i < num_keep; i++) best[i] = -1;
if (mutate && !keep) {
double avg = 0;
for (int i = 0; i < num_sec; i++) {
port[i] = (int)(port[i] * (4 * sec_rnd[(i + rnd_off + gid) % num_sec] - 2) + 5*sec_rnd[(i + rnd_off*i + gid) % num_sec]);
port[i] *= sec_rnd[(i + rnd_off + gid) % num_sec] < .2 ? -1 : 1;
avg = (avg * i + abs(port[i])) / (i + 1);
}
}
if (!mutate && !keep) {
for (int i = 0; i < num_sec; i++) {
port[i] = (int)(5 * sec_rnd[(i + rnd_off + gid) % num_sec] - 2.5);
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (keep) {
best[larger] = gid;
}
if (recom && !keep) {
int recom_idx = best[convert_int(thd_rnd[(rnd_off + gid) % num_thd] * num_keep) % num_keep];
__global int* best_port = _port + recom_idx * num_sec;
if (recom_idx == -1) return;
for (int i = 0; i < num_sec; i++) {
port[i] = (port[i] + best_port[i]) / (2 * thd_rnd[(rnd_off + gid) % num_thd]);
}
}
}
__kernel
void get_max(
__global int* _port,
__global int* _out_port,
__global double* fit,
const int num_sec)
{
int gid = get_global_id(0);
int grpid = get_group_id(0);
bool best = count_larger(fit) == 0;
__global int* port = _port + gid * num_sec;
__global int* out_port = _out_port + grpid * num_sec;
if (best) {
for (int i = 0; i < num_sec; i++) {
out_port[i] = port[i];
}
}
}