integration 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +6 -5
- data/README.md +67 -53
- data/Rakefile +5 -25
- data/integration.gemspec +4 -5
- data/lib/integration.rb +233 -58
- data/lib/integration/version.rb +3 -0
- data/lib/opencl/Makefile +29 -0
- data/lib/opencl/integration_host.c +151 -0
- data/lib/opencl/opencl_minimization.rb +251 -0
- data/lib/opencl/unidimensional_kernel.cl +47 -0
- metadata +7 -7
- data/.autotest +0 -23
- data/.rspec +0 -2
- data/Gemfile.lock +0 -38
- data/Manifest.txt +0 -9
- data/lib/symbolic.rb +0 -55
data/lib/opencl/Makefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
all: cl.so
|
2
|
+
|
3
|
+
CC=gcc
|
4
|
+
CL_HEADERS_PATH=
|
5
|
+
LIBOPENCL_PATH=
|
6
|
+
|
7
|
+
|
8
|
+
UNAME := $(shell uname)
|
9
|
+
ifeq ($(UNAME), Linux)
|
10
|
+
# do something Linux-y
|
11
|
+
OPENCL_LIBRARY_CALL=-lOpenCL
|
12
|
+
endif
|
13
|
+
ifeq ($(UNAME), Solaris)
|
14
|
+
# do something Solaris-y
|
15
|
+
OPENCL_LIBRARY_CALL=-framework OpenCL
|
16
|
+
endif
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
cl.so: integration_host.o
|
21
|
+
$(CC) -shared -o cl.so integration_host.o -I $(CL_HEADERS_PATH) -L $(LIBOPENCL_PATH) $(OPENCL_LIBRARY_CALL)
|
22
|
+
|
23
|
+
|
24
|
+
integration_host.o: integration_host.c
|
25
|
+
$(CC) -fpic -c integration_host.c
|
26
|
+
|
27
|
+
clean:
|
28
|
+
rm cl.so integration_host.o
|
29
|
+
|
@@ -0,0 +1,151 @@
|
|
1
|
+
// This file contains the host code of the openCL supported integration
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <limits.h> //For PATH_MAX
|
7
|
+
|
8
|
+
// import OpenCL headers assuming OS is a linux version or MAC
|
9
|
+
#ifdef __APPLE__
|
10
|
+
#include<OpenCL/opencl.h>
|
11
|
+
#else
|
12
|
+
#include<CL/cl.h>
|
13
|
+
#endif
|
14
|
+
|
15
|
+
#define MAX_SOURCE_SIZE (0x100000) // maximum size allowed for the kernel text
|
16
|
+
|
17
|
+
// these are the available integration methods
|
18
|
+
enum methods{
|
19
|
+
rectangle,
|
20
|
+
trapezoid,
|
21
|
+
simpson,
|
22
|
+
adaptive_quadrature,
|
23
|
+
gauss,
|
24
|
+
romberg,
|
25
|
+
monte_carlo
|
26
|
+
};
|
27
|
+
|
28
|
+
double opencl_integration(double lower, double upper, int n, char* f,
|
29
|
+
enum methods method, char* path_to_kerne) {
|
30
|
+
|
31
|
+
char* source_str;
|
32
|
+
size_t source_size;
|
33
|
+
int i = 0;
|
34
|
+
double dx = (upper - lower) / n;
|
35
|
+
double *results = (double*) malloc(n * sizeof(double));
|
36
|
+
|
37
|
+
// read the corresponding kernel
|
38
|
+
FILE* fp;
|
39
|
+
sprintf(path_to_kerne, "%s%s", path_to_kerne, "/unidimensional_kernel.cl");
|
40
|
+
fp = fopen(path_to_kerne, "r");
|
41
|
+
|
42
|
+
// if the kernel file doesn't exist, stop the execution
|
43
|
+
if(fp == 0) {
|
44
|
+
printf("kernel file not found\n");
|
45
|
+
exit(0);
|
46
|
+
}
|
47
|
+
|
48
|
+
char *temp_source;
|
49
|
+
// allocate memory for kenel code
|
50
|
+
temp_source = (char*) malloc(sizeof(char) * MAX_SOURCE_SIZE);
|
51
|
+
source_str = (char*) malloc(sizeof(char) * MAX_SOURCE_SIZE);
|
52
|
+
|
53
|
+
temp_source[0] = '\0'; // make temp_source a null string
|
54
|
+
char line[100];
|
55
|
+
// read the text of the kernel into temp_source
|
56
|
+
while(!feof(fp)) {
|
57
|
+
if (fgets(line, 100, fp)) {
|
58
|
+
sprintf(temp_source, "%s%s",temp_source, line);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
// create the complete kernel code appending,
|
63
|
+
// f() - integrating function
|
64
|
+
sprintf(source_str, "double f(double x){return (%s);}\n%s", f, temp_source);
|
65
|
+
|
66
|
+
// printf("\nfunction----------------------------\n%s\n--------------------------\n", source_str);
|
67
|
+
source_size = strlen(source_str);
|
68
|
+
fclose(fp);
|
69
|
+
free(temp_source);
|
70
|
+
|
71
|
+
cl_platform_id platform_id = NULL;
|
72
|
+
cl_device_id device_id = NULL;
|
73
|
+
cl_uint ret_num_devices;
|
74
|
+
cl_uint ret_num_platforms;
|
75
|
+
cl_int ret;
|
76
|
+
ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
|
77
|
+
// CL_DEVICE_TYPE_CPU is being used currently as the testing value
|
78
|
+
ret = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_CPU, 1, &device_id, &ret_num_devices);
|
79
|
+
|
80
|
+
// create kernel
|
81
|
+
cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret);
|
82
|
+
// create command queue
|
83
|
+
cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
|
84
|
+
|
85
|
+
// create memory buffers to share memory with kernel program
|
86
|
+
cl_mem lower_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(double) , NULL, &ret);
|
87
|
+
cl_mem dx_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(double) , NULL, &ret);
|
88
|
+
cl_mem n_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int) , NULL, &ret);
|
89
|
+
cl_mem method_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int) , NULL, &ret);
|
90
|
+
cl_mem result_obj = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(double) * n , NULL, &ret);
|
91
|
+
//cl_mem epsilon_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(double) , NULL, &ret);
|
92
|
+
//cl_mem golden_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(double) , NULL, &ret);
|
93
|
+
|
94
|
+
// writes the input values into the allocated memory buffers
|
95
|
+
ret = clEnqueueWriteBuffer(command_queue, lower_obj, CL_TRUE, 0, sizeof(double) , &lower , 0, NULL, NULL);
|
96
|
+
ret = clEnqueueWriteBuffer(command_queue, dx_obj , CL_TRUE, 0, sizeof(double) , &dx , 0, NULL, NULL);
|
97
|
+
ret = clEnqueueWriteBuffer(command_queue, n_obj , CL_TRUE, 0, sizeof(int) , &n , 0, NULL, NULL);
|
98
|
+
ret = clEnqueueWriteBuffer(command_queue, method_obj, CL_TRUE, 0, sizeof(int) , &method, 0, NULL, NULL);
|
99
|
+
//ret = clEnqueueWriteBuffer(command_queue, epsilon_obj , CL_TRUE, 0, sizeof(double) , &epsilon , 0, NULL, NULL);
|
100
|
+
//ret = clEnqueueWriteBuffer(command_queue, golden_obj , CL_TRUE, 0, sizeof(double) , &golden , 0, NULL, NULL);
|
101
|
+
|
102
|
+
// create kernel program
|
103
|
+
cl_program program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);
|
104
|
+
// build the kernel program. Still the code isn't being executed
|
105
|
+
// memory buffers haven't involved. Any error at this stage MAY be a syntax error of kernel code
|
106
|
+
ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
|
107
|
+
// this gives error message only if the kernel code includes any syntax error
|
108
|
+
if(ret == CL_BUILD_PROGRAM_FAILURE) printf("\nerror while building kernel: %d\n", ret);
|
109
|
+
// create the kernel calling the kernel function 'minimize'
|
110
|
+
cl_kernel kernel = clCreateKernel(program, "integrate", &ret);
|
111
|
+
|
112
|
+
// set arguments of kernel function
|
113
|
+
ret = clSetKernelArg(kernel, 0 , sizeof(cl_mem) , (void *)&lower_obj);
|
114
|
+
ret = clSetKernelArg(kernel, 1 , sizeof(cl_mem) , (void *)&dx_obj);
|
115
|
+
ret = clSetKernelArg(kernel, 2 , sizeof(cl_mem) , (void *)&n_obj);
|
116
|
+
ret = clSetKernelArg(kernel, 3 , sizeof(cl_mem) , (void *)&method_obj);
|
117
|
+
ret = clSetKernelArg(kernel, 4 , sizeof(cl_mem) * n, (void *)&result_obj);
|
118
|
+
//ret = clSetKernelArg(kernel, 9 , sizeof(cl_mem) , (void *)&epsilon_obj);
|
119
|
+
//ret = clSetKernelArg(kernel, 10, sizeof(cl_mem) , (void *)&golden_obj);
|
120
|
+
|
121
|
+
size_t global_item_size = n;
|
122
|
+
// enqueue the jobs and let them to be solved by kernel program
|
123
|
+
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size, NULL, 0, NULL, NULL);
|
124
|
+
|
125
|
+
// retrieve results from the shared memory buffers
|
126
|
+
ret = clEnqueueReadBuffer(command_queue, result_obj, CL_TRUE, 0, sizeof(double) * n, results, 0, NULL, NULL);
|
127
|
+
|
128
|
+
// clear the allocated memory
|
129
|
+
ret = clFlush(command_queue);
|
130
|
+
ret = clFinish(command_queue);
|
131
|
+
ret = clReleaseKernel(kernel);
|
132
|
+
ret = clReleaseProgram(program);
|
133
|
+
|
134
|
+
ret = clReleaseMemObject(lower_obj);
|
135
|
+
ret = clReleaseMemObject(dx_obj);
|
136
|
+
ret = clReleaseMemObject(n_obj);
|
137
|
+
ret = clReleaseMemObject(method_obj);
|
138
|
+
//ret = clReleaseMemObject(epsilon_obj);
|
139
|
+
//ret = clReleaseMemObject(golden_obj);
|
140
|
+
|
141
|
+
ret = clReleaseCommandQueue(command_queue);
|
142
|
+
ret = clReleaseContext(context);
|
143
|
+
free(source_str);
|
144
|
+
|
145
|
+
double final_result = 0;
|
146
|
+
for(i = 0; i < n; ++i) {
|
147
|
+
final_result += results[i];
|
148
|
+
}
|
149
|
+
|
150
|
+
return final_result;
|
151
|
+
}
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module OpenCLMinimization extend FFI::Library
|
4
|
+
|
5
|
+
MAX_ITERATIONS_DEFAULT = 100000
|
6
|
+
EPSILON_DEFAULT = 0.00001
|
7
|
+
GOLDEN_DEFAULT = 0.3819660
|
8
|
+
SQRT_EPSILON_DEFAULT = 0.00001
|
9
|
+
PATH_TO_KERNEL = File.expand_path(File.dirname(__FILE__))
|
10
|
+
|
11
|
+
ffi_lib "#{File.expand_path(File.dirname(__FILE__))}/cl.so"
|
12
|
+
|
13
|
+
# attack with the opencl_minimize of min_host.c
|
14
|
+
attach_function 'opencl_minimize', [:int, :pointer, :pointer, :pointer, :int, :string, :string,
|
15
|
+
:string, :pointer, :pointer, :int, :int, :float, :float, :float, :string], :void
|
16
|
+
|
17
|
+
# Classic GodlSectionMinimizer minimization method.
|
18
|
+
# Basic minimization algorithm. Slow, but robust.
|
19
|
+
# See Unidimensional for methods.
|
20
|
+
# == Usage
|
21
|
+
# n = 3
|
22
|
+
# start_point = [1, 3, 5]
|
23
|
+
# expected_point = [1.5, 3.5, 5.5]
|
24
|
+
# end_point = [3, 5, 7]
|
25
|
+
# f = "pow((x-2)*(x-4)*(x-6), 2)+1"
|
26
|
+
# min = OpenCLMinimization::GodlSectionMinimizer.new(n, start_point, expected_point, end_point, f)
|
27
|
+
# min.minimize
|
28
|
+
# min.x_minimum
|
29
|
+
# min.f_minimum
|
30
|
+
#
|
31
|
+
class GodlSectionMinimizer
|
32
|
+
attr_reader :x_minimum
|
33
|
+
attr_reader :f_minimum
|
34
|
+
|
35
|
+
attr_writer :max_iterations
|
36
|
+
attr_writer :epsilon
|
37
|
+
attr_writer :golden
|
38
|
+
|
39
|
+
# == Parameters:
|
40
|
+
# * <tt>n</tt>: Number of Jobs
|
41
|
+
# * <tt>start_point</tt>: Lower possible value
|
42
|
+
# * <tt>expected_point</tt>: Initial point
|
43
|
+
# * <tt>end_point</tt>: Higher possible value
|
44
|
+
# * <tt>f</tt>: Original function string
|
45
|
+
#
|
46
|
+
def initialize(n, start_point, expected_point, end_point, f)
|
47
|
+
@n = n
|
48
|
+
@start_point = start_point
|
49
|
+
@expected_point = expected_point
|
50
|
+
@end_point = end_point
|
51
|
+
@f = f
|
52
|
+
@max_iterations = MAX_ITERATIONS_DEFAULT
|
53
|
+
@epsilon = EPSILON_DEFAULT
|
54
|
+
@golden = GOLDEN_DEFAULT
|
55
|
+
@sqrt_epsilon = SQRT_EPSILON_DEFAULT
|
56
|
+
end
|
57
|
+
|
58
|
+
def minimize
|
59
|
+
# create Buffers for inputs and outputs
|
60
|
+
start_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
61
|
+
expected_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
62
|
+
end_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
63
|
+
x_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
64
|
+
f_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
65
|
+
|
66
|
+
# set inputs
|
67
|
+
start_buffer.write_array_of_float(@start_point)
|
68
|
+
expected_buffer.write_array_of_float(@expected_point)
|
69
|
+
end_buffer.write_array_of_float(@end_point)
|
70
|
+
|
71
|
+
# call minimizer
|
72
|
+
OpenCLMinimization::opencl_minimize(@n, start_buffer, expected_buffer, end_buffer, 0, @f, "", "", x_buffer,
|
73
|
+
f_buffer, 0, @max_iterations, @epsilon, @golden, @sqrt_epsilon, PATH_TO_KERNEL)
|
74
|
+
|
75
|
+
@x_minimum = Array.new(@n)
|
76
|
+
@f_minimum = Array.new(@n)
|
77
|
+
# read results
|
78
|
+
@x_minimum = x_buffer.read_array_of_float(@n)
|
79
|
+
@f_minimum = f_buffer.read_array_of_float(@n)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Classic Newton-Raphson minimization method.
|
84
|
+
# Requires first and second derivative
|
85
|
+
# == Usage
|
86
|
+
# n = 3
|
87
|
+
# expected_point = [1, 100, 1000]
|
88
|
+
# f = "(x-3)*(x-3)+5"
|
89
|
+
# fd = "2*(x-3)"
|
90
|
+
# fdd = "2"
|
91
|
+
# min = OpenCLMinimization::NewtonRampsonMinimizer.new(n, expected_point, f, fd, fdd)
|
92
|
+
# min.minimize
|
93
|
+
# min.x_minimum
|
94
|
+
# min.f_minimum
|
95
|
+
#
|
96
|
+
class NewtonRampsonMinimizer
|
97
|
+
attr_reader :x_minimum
|
98
|
+
attr_reader :f_minimum
|
99
|
+
|
100
|
+
attr_writer :max_iterations
|
101
|
+
attr_writer :epsilon
|
102
|
+
attr_writer :golden
|
103
|
+
|
104
|
+
# == Parameters:
|
105
|
+
# * <tt>n</tt>: Number of Jobs
|
106
|
+
# * <tt>expected_point</tt>: Initial point
|
107
|
+
# * <tt>f</tt>: Original function
|
108
|
+
# * <tt>fd</tt>: First derivative function string
|
109
|
+
# * <tt>fdd</tt>: Second derivative function string
|
110
|
+
#
|
111
|
+
def initialize(n, expected_point, f, fd, fdd)
|
112
|
+
@n = n
|
113
|
+
@expected_point = expected_point
|
114
|
+
@f = f
|
115
|
+
@fd = fd
|
116
|
+
@fdd = fdd
|
117
|
+
@max_iterations = MAX_ITERATIONS_DEFAULT
|
118
|
+
@epsilon = EPSILON_DEFAULT
|
119
|
+
@golden = GOLDEN_DEFAULT
|
120
|
+
@sqrt_epsilon = SQRT_EPSILON_DEFAULT
|
121
|
+
end
|
122
|
+
|
123
|
+
def minimize
|
124
|
+
# create Buffers for inputs and outputs
|
125
|
+
expected_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
126
|
+
x_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
127
|
+
f_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
128
|
+
|
129
|
+
# set inputs
|
130
|
+
expected_buffer.write_array_of_float(@expected_point)
|
131
|
+
|
132
|
+
# call minimizer
|
133
|
+
OpenCLMinimization::opencl_minimize(@n, nil, expected_buffer, nil, 1, @f, @fd, @fdd, x_buffer, f_buffer, 0,
|
134
|
+
@max_iterations, @epsilon, @golden, @sqrt_epsilon, PATH_TO_KERNEL)
|
135
|
+
|
136
|
+
@x_minimum = Array.new(@n)
|
137
|
+
@f_minimum = Array.new(@n)
|
138
|
+
# read results
|
139
|
+
@x_minimum = x_buffer.read_array_of_float(@n)
|
140
|
+
@f_minimum = f_buffer.read_array_of_float(@n)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# = Bisection Minimizer.
|
145
|
+
# Basic minimization algorithm. Slow, but robust.
|
146
|
+
# See Unidimensional for methods.
|
147
|
+
# == Usage.
|
148
|
+
# n = 3
|
149
|
+
# start_point = [1, 3, 5]
|
150
|
+
# expected_point = [1.5, 3.5, 5.5]
|
151
|
+
# end_point = [3, 5, 7]
|
152
|
+
# f = "pow((x-2)*(x-4)*(x-6), 2)+1"
|
153
|
+
# min = OpenCLMinimization::BisectionMinimizer.new(n, start_point, expected_point, end_point, f)
|
154
|
+
# min.minimize
|
155
|
+
# min.x_minimum
|
156
|
+
# min.f_minimum
|
157
|
+
#
|
158
|
+
class BisectionMinimizer < GodlSectionMinimizer
|
159
|
+
|
160
|
+
def minimize
|
161
|
+
# create Buffers for inputs and outputs
|
162
|
+
start_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
163
|
+
expected_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
164
|
+
end_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
165
|
+
x_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
166
|
+
f_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
167
|
+
|
168
|
+
# set inputs
|
169
|
+
start_buffer.write_array_of_float(@start_point)
|
170
|
+
expected_buffer.write_array_of_float(@expected_point)
|
171
|
+
end_buffer.write_array_of_float(@end_point)
|
172
|
+
|
173
|
+
# call minimizer
|
174
|
+
OpenCLMinimization::opencl_minimize(@n, start_buffer, expected_buffer, end_buffer, 2, @f, "", "", x_buffer,
|
175
|
+
f_buffer, 0, @max_iterations, @epsilon, @golden, @sqrt_epsilon, PATH_TO_KERNEL)
|
176
|
+
|
177
|
+
@x_minimum = Array.new(@n)
|
178
|
+
@f_minimum = Array.new(@n)
|
179
|
+
# read results
|
180
|
+
@x_minimum = x_buffer.read_array_of_float(@n)
|
181
|
+
@f_minimum = f_buffer.read_array_of_float(@n)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Direct port of Brent algorithm found on GSL.
|
186
|
+
# See Unidimensional for methods.
|
187
|
+
# == Usage
|
188
|
+
# n = 3
|
189
|
+
# start_point = [1, 3, 5]
|
190
|
+
# expected_point = [1.5, 3.5, 5.5]
|
191
|
+
# end_point = [3, 5, 7]
|
192
|
+
# f = "pow((x-2)*(x-4)*(x-6), 2)+1"
|
193
|
+
# min = OpenCLMinimization::BisectionMinimizer.new(n, start_point, expected_point, end_point, f)
|
194
|
+
# min.minimize
|
195
|
+
# min.x_minimum
|
196
|
+
# min.f_minimum
|
197
|
+
#
|
198
|
+
class BrentMinimizer
|
199
|
+
attr_reader :x_minimum
|
200
|
+
attr_reader :f_minimum
|
201
|
+
|
202
|
+
attr_writer :max_iterations
|
203
|
+
attr_writer :epsilon
|
204
|
+
attr_writer :golden
|
205
|
+
attr_writer :sqrt_epsilon
|
206
|
+
|
207
|
+
# == Parameters:
|
208
|
+
# * <tt>n</tt>: Number of Jobs
|
209
|
+
# * <tt>start_point</tt>: Lower possible value
|
210
|
+
# * <tt>expected_point</tt>: Initial point
|
211
|
+
# * <tt>end_point</tt>: Higher possible value
|
212
|
+
# * <tt>f</tt>: Original function string
|
213
|
+
#
|
214
|
+
def initialize(n, start_point, expected_point, end_point, f)
|
215
|
+
@n = n
|
216
|
+
@start_point = start_point
|
217
|
+
@expected_point = expected_point
|
218
|
+
@end_point = end_point
|
219
|
+
@f = f
|
220
|
+
@max_iterations = MAX_ITERATIONS_DEFAULT
|
221
|
+
@epsilon = EPSILON_DEFAULT
|
222
|
+
@golden = GOLDEN_DEFAULT
|
223
|
+
@sqrt_epsilon = SQRT_EPSILON_DEFAULT
|
224
|
+
end
|
225
|
+
|
226
|
+
def minimize
|
227
|
+
# create Buffers for inputs and outputs
|
228
|
+
start_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
229
|
+
expected_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
230
|
+
end_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
231
|
+
x_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
232
|
+
f_buffer = FFI::Buffer.alloc_inout(:pointer, @n)
|
233
|
+
|
234
|
+
# set inputs
|
235
|
+
start_buffer.write_array_of_float(@start_point)
|
236
|
+
expected_buffer.write_array_of_float(@expected_point)
|
237
|
+
end_buffer.write_array_of_float(@end_point)
|
238
|
+
|
239
|
+
# call minimizer
|
240
|
+
OpenCLMinimization::opencl_minimize(@n, start_buffer, expected_buffer, end_buffer, 3, @f, "", "", x_buffer,
|
241
|
+
f_buffer, 0, @max_iterations, @epsilon, @golden, @sqrt_epsilon, PATH_TO_KERNEL)
|
242
|
+
|
243
|
+
@x_minimum = Array.new(@n)
|
244
|
+
@f_minimum = Array.new(@n)
|
245
|
+
# read results
|
246
|
+
@x_minimum = x_buffer.read_array_of_float(@n)
|
247
|
+
@f_minimum = f_buffer.read_array_of_float(@n)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
// This is the kenel code for unidimensional integration methods.
|
2
|
+
// This is loaded into memory at runtime and a functions will be appended at run time,
|
3
|
+
// double f(double x) - integrating function
|
4
|
+
|
5
|
+
|
6
|
+
double rectangle(int i, double a, double dx);
|
7
|
+
double trapezoid(int i, double a, double dx);
|
8
|
+
double simpson(int i, double a, double dx);
|
9
|
+
double romberg(int i, double a, double dx);
|
10
|
+
|
11
|
+
__kernel void integrate(__global const double *a, __global const double *dx, __global const double *n,
|
12
|
+
__global int *method, __global double *results) {
|
13
|
+
|
14
|
+
// Get the index of the current element to be processed
|
15
|
+
int i = get_global_id(0);
|
16
|
+
|
17
|
+
// Do the operation
|
18
|
+
if(i <= n) {
|
19
|
+
int m = *method;
|
20
|
+
switch(m) {
|
21
|
+
case 0: results[i] = rectangle(i, *a, *dx);
|
22
|
+
break;
|
23
|
+
case 1: results[i] = trapezoid(i, *a, *dx);
|
24
|
+
break;
|
25
|
+
case 2: results[i] = simpson(i, *a, *dx);
|
26
|
+
break;
|
27
|
+
case 3: results[i] = romberg(i, *a, *dx);
|
28
|
+
break;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
double rectangle(int i, double a, double dx) {
|
34
|
+
double midpoint = a + (i + 0.5) * dx;
|
35
|
+
return dx * f(midpoint);
|
36
|
+
}
|
37
|
+
|
38
|
+
double trapezoid(int i, double a, double dx) {
|
39
|
+
double lower = a + i * dx;
|
40
|
+
return (0.5 * dx * (f(lower) + f(lower + dx)));
|
41
|
+
}
|
42
|
+
|
43
|
+
double simpson(int i, double a, double dx) {
|
44
|
+
double lower = a + i * dx;
|
45
|
+
return (dx / 6) * (f(lower) + 4 * f(lower + 0.5 * dx) + f(lower + dx));
|
46
|
+
}
|
47
|
+
|