integration 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|