PyHierarchicalTsetlinMachineCUDA 0.2.3__tar.gz → 0.2.6__tar.gz
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.
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PKG-INFO +1 -1
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/kernels.py +114 -34
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/tm.py +37 -15
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/PKG-INFO +1 -1
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/SOURCES.txt +1 -5
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/requires.txt +1 -0
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/README.md +5 -5
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/setup.py +2 -1
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/LICENSE +0 -0
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/__init__.py +0 -0
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/tools.py +0 -0
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/utils.py +0 -0
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/dependency_links.txt +0 -0
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/top_level.txt +0 -0
- {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/setup.cfg +0 -0
|
@@ -159,44 +159,52 @@ code_update = """
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// Evaluate example
|
|
162
|
-
__global__ void evaluate_leaves(unsigned int *global_ta_state, int *component_weights,
|
|
162
|
+
__global__ void evaluate_leaves(unsigned int *global_ta_state, int *component_weights, int *global_component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_type, int *X, int example)
|
|
163
163
|
{
|
|
164
164
|
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
165
165
|
int stride = blockDim.x * gridDim.x;
|
|
166
166
|
|
|
167
|
-
int *Xi = &X[(long long)example*LITERAL_CHUNKS];
|
|
167
|
+
int *Xi = &X[(unsigned long long)example*LITERAL_CHUNKS];
|
|
168
168
|
|
|
169
169
|
// Evaluate each clause component (leaf) in separate threads
|
|
170
170
|
for (int clause_component = index; clause_component < CLAUSES*COMPONENTS; clause_component += stride) {
|
|
171
|
+
int clause = clause_component / COMPONENTS;
|
|
171
172
|
int component = clause_component % COMPONENTS;
|
|
172
173
|
|
|
173
|
-
// Get state of current clause component
|
|
174
|
-
unsigned int *ta_state = &global_ta_state[clause_component*TA_CHUNKS_PER_LEAF*STATE_BITS];
|
|
175
|
-
|
|
176
174
|
int component_remainder = component;
|
|
175
|
+
int feature_chunk_base = 0;
|
|
177
176
|
int ta_chunk_base = 0;
|
|
178
|
-
int
|
|
177
|
+
int size_feature_chunk_base = 1;
|
|
178
|
+
int size_ta_chunk_base = 1;
|
|
179
179
|
for (int d = 0; d < depth-1; ++d) {
|
|
180
180
|
int depth_d_node_index = component_remainder % hierarchy_structure_factors[d];
|
|
181
181
|
component_remainder = component_remainder / hierarchy_structure_factors[d];
|
|
182
182
|
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
if (hierarchy_structure_type[d] != 1) {
|
|
184
|
+
feature_chunk_base += size_feature_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
|
|
185
|
+
size_feature_chunk_base *= hierarchy_structure_factors[d];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (hierarchy_structure_type[d] != 2) {
|
|
189
|
+
ta_chunk_base += size_ta_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
|
|
190
|
+
size_ta_chunk_base *= hierarchy_structure_factors[d];
|
|
186
191
|
}
|
|
187
192
|
}
|
|
188
193
|
|
|
194
|
+
// Get state of current ta team component
|
|
195
|
+
unsigned int *ta_state = &global_ta_state[clause*COMPONENTS*TA_CHUNKS_PER_LEAF*STATE_BITS + ta_chunk_base*STATE_BITS];
|
|
196
|
+
|
|
189
197
|
// Evaluate clause component
|
|
190
198
|
int component_output = 1;
|
|
191
199
|
for (int ta_chunk = 0; ta_chunk < TA_CHUNKS_PER_LEAF-1; ++ta_chunk) {
|
|
192
200
|
// Compare the TA state of the component (leaf) against the corresponding part of the feature vector
|
|
193
|
-
if ((ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1] & Xi[
|
|
201
|
+
if ((ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1] & Xi[feature_chunk_base + ta_chunk]) != ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1]) {
|
|
194
202
|
component_output = 0;
|
|
195
203
|
break;
|
|
196
204
|
}
|
|
197
205
|
}
|
|
198
206
|
|
|
199
|
-
if ((ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & Xi[
|
|
207
|
+
if ((ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & Xi[feature_chunk_base + TA_CHUNKS_PER_LEAF-1] & FILTER_HIERARCHICAL) != (ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & FILTER_HIERARCHICAL)) {
|
|
200
208
|
component_output = 0;
|
|
201
209
|
}
|
|
202
210
|
|
|
@@ -204,7 +212,7 @@ code_update = """
|
|
|
204
212
|
}
|
|
205
213
|
}
|
|
206
214
|
|
|
207
|
-
__global__ void evaluate_or_groups(
|
|
215
|
+
__global__ void evaluate_or_groups(int *child_input, int *or_group_node_output, int number_of_or_group_nodes, int number_of_or_group_addends)
|
|
208
216
|
{
|
|
209
217
|
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
210
218
|
int stride = blockDim.x * gridDim.x;
|
|
@@ -212,24 +220,30 @@ code_update = """
|
|
|
212
220
|
// Add up the votes of each OR node child
|
|
213
221
|
for (int or_group_node = index; or_group_node < CLAUSES*number_of_or_group_nodes; or_group_node += stride) {
|
|
214
222
|
// Add OR addends
|
|
215
|
-
|
|
223
|
+
int or_group_vote_sum = 0;
|
|
224
|
+
int max_vote_sum = 0;
|
|
225
|
+
|
|
216
226
|
for (int or_addend = 0; or_addend < number_of_or_group_addends; ++or_addend) {
|
|
217
227
|
// Aggregate votes from each child node through addition
|
|
218
228
|
|
|
219
|
-
|
|
229
|
+
if (child_input[or_group_node*number_of_or_group_addends + or_addend] > max_vote_sum) {
|
|
230
|
+
max_vote_sum = child_input[or_group_node*number_of_or_group_addends + or_addend];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
int previous_or_group_vote_sum = or_group_vote_sum;
|
|
220
234
|
or_group_vote_sum += child_input[or_group_node*number_of_or_group_addends + or_addend];
|
|
221
235
|
if (or_group_vote_sum < 0) {
|
|
222
|
-
printf("OR* OVERFLOW %
|
|
236
|
+
printf("OR* OVERFLOW %d -> %d\\n", previous_or_group_vote_sum, or_group_vote_sum);
|
|
223
237
|
or_group_vote_sum = previous_or_group_vote_sum;
|
|
224
238
|
}
|
|
225
239
|
}
|
|
226
240
|
|
|
227
|
-
//
|
|
228
|
-
or_group_node_output[or_group_node] =
|
|
241
|
+
// or_group_node_output[or_group_node] = or_group_vote_sum;
|
|
242
|
+
or_group_node_output[or_group_node] = max_vote_sum;
|
|
229
243
|
}
|
|
230
244
|
}
|
|
231
245
|
|
|
232
|
-
__global__ void evaluate_and_groups(
|
|
246
|
+
__global__ void evaluate_and_groups(int *child_input, int *and_group_node_output, int number_of_and_group_nodes, int number_of_and_group_factors)
|
|
233
247
|
{
|
|
234
248
|
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
235
249
|
int stride = blockDim.x * gridDim.x;
|
|
@@ -237,15 +251,15 @@ code_update = """
|
|
|
237
251
|
// Multiply the votes from the children of each AND node
|
|
238
252
|
for (int and_group_node = index; and_group_node < CLAUSES*number_of_and_group_nodes; and_group_node += stride) {
|
|
239
253
|
// Multiply and factors
|
|
240
|
-
|
|
254
|
+
int and_group_vote_product = 1;
|
|
241
255
|
for (int and_factor = 0; and_factor < number_of_and_group_factors; ++and_factor) {
|
|
242
256
|
// Aggregate votes from each child node through multiplication
|
|
243
257
|
|
|
244
|
-
|
|
258
|
+
int previous_and_group_vote_product = and_group_vote_product;
|
|
245
259
|
and_group_vote_product *= child_input[and_group_node*number_of_and_group_factors + and_factor];
|
|
246
260
|
|
|
247
261
|
if (and_group_vote_product < 0) {
|
|
248
|
-
printf("AND OVERFLOW %
|
|
262
|
+
printf("AND OVERFLOW %d -> %d\\n", previous_and_group_vote_product, and_group_vote_product);
|
|
249
263
|
and_group_vote_product = previous_and_group_vote_product;
|
|
250
264
|
}
|
|
251
265
|
}
|
|
@@ -255,7 +269,7 @@ code_update = """
|
|
|
255
269
|
}
|
|
256
270
|
}
|
|
257
271
|
|
|
258
|
-
__global__ void propagate_and_group_false_truth_values(
|
|
272
|
+
__global__ void propagate_and_group_false_truth_values(int *child_input, int *group_node_output, int number_of_group_nodes, int number_of_group_node_children)
|
|
259
273
|
{
|
|
260
274
|
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
261
275
|
int stride = blockDim.x * gridDim.x;
|
|
@@ -272,7 +286,59 @@ code_update = """
|
|
|
272
286
|
}
|
|
273
287
|
}
|
|
274
288
|
|
|
275
|
-
__global__ void
|
|
289
|
+
__global__ void propagate_or_group_false_truth_values(curandState *state, int *child_input, int *group_node_output, int number_of_group_nodes, int number_of_group_node_children)
|
|
290
|
+
{
|
|
291
|
+
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
292
|
+
int stride = blockDim.x * gridDim.x;
|
|
293
|
+
|
|
294
|
+
int non_zero_children[361];
|
|
295
|
+
|
|
296
|
+
/* Copy state to local memory for efficiency */
|
|
297
|
+
curandState localState = state[index];
|
|
298
|
+
|
|
299
|
+
// If a group node is false, all children are made false.
|
|
300
|
+
for (int group_node = index; group_node < CLAUSES*number_of_group_nodes; group_node += stride) {
|
|
301
|
+
int number_of_non_zero_children = 0;
|
|
302
|
+
|
|
303
|
+
if (group_node_output[group_node] == -1) {
|
|
304
|
+
for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
|
|
305
|
+
child_input[group_node*number_of_group_node_children + or_addend] = -1;
|
|
306
|
+
}
|
|
307
|
+
} else if (group_node_output[group_node] == 0) {
|
|
308
|
+
for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
|
|
309
|
+
if (child_input[group_node*number_of_group_node_children + or_addend] > 0) {
|
|
310
|
+
child_input[group_node*number_of_group_node_children + or_addend] = 0;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
|
|
315
|
+
if (child_input[group_node*number_of_group_node_children + or_addend] > 0) {
|
|
316
|
+
non_zero_children[number_of_non_zero_children] = or_addend;
|
|
317
|
+
number_of_non_zero_children++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (group_node_output[group_node] != -1) {
|
|
323
|
+
int selected_child;
|
|
324
|
+
if (number_of_non_zero_children > 0) {
|
|
325
|
+
selected_child = non_zero_children[curand(&localState) % number_of_non_zero_children];
|
|
326
|
+
} else {
|
|
327
|
+
selected_child = curand(&localState) % number_of_group_node_children;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
|
|
331
|
+
if (selected_child != or_addend) {
|
|
332
|
+
child_input[group_node*number_of_group_node_children + or_addend] = -1;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
state[index] = localState;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
__global__ void evaluate_or_alternatives(int *child_input, int *or_alternatives_node_output, int number_of_or_alternatives_nodes, int number_of_or_alternatives)
|
|
276
342
|
{
|
|
277
343
|
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
278
344
|
int stride = blockDim.x * gridDim.x;
|
|
@@ -280,16 +346,16 @@ code_update = """
|
|
|
280
346
|
// Add up the votes from the children of each OR node
|
|
281
347
|
for (int or_alternatives_node = index; or_alternatives_node < CLAUSES*number_of_or_alternatives_nodes; or_alternatives_node += stride) {
|
|
282
348
|
// Sum up votes from each or alternative
|
|
283
|
-
|
|
349
|
+
int or_alternatives_vote_sum = 0;
|
|
284
350
|
for (int or_alternative = 0; or_alternative < number_of_or_alternatives; ++or_alternative) {
|
|
285
351
|
// Aggregate same input or alternatives through summation
|
|
286
352
|
|
|
287
353
|
|
|
288
|
-
|
|
354
|
+
int previous_or_alternatives_vote_sum = or_alternatives_vote_sum;
|
|
289
355
|
or_alternatives_vote_sum += child_input[or_alternatives_node * number_of_or_alternatives + or_alternative];
|
|
290
356
|
|
|
291
357
|
if (or_alternatives_vote_sum < 0) {
|
|
292
|
-
printf("OR OVERFLOW %
|
|
358
|
+
printf("OR OVERFLOW %d -> %d\\n", previous_or_alternatives_vote_sum, or_alternatives_vote_sum);
|
|
293
359
|
or_alternatives_vote_sum = previous_or_alternatives_vote_sum;
|
|
294
360
|
}
|
|
295
361
|
}
|
|
@@ -299,7 +365,7 @@ code_update = """
|
|
|
299
365
|
}
|
|
300
366
|
}
|
|
301
367
|
|
|
302
|
-
__global__ void evaluate_final(int number_of_outputs,
|
|
368
|
+
__global__ void evaluate_final(int number_of_outputs, int *child_input, int *clause_weights, int *class_sum)
|
|
303
369
|
{
|
|
304
370
|
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
305
371
|
int stride = blockDim.x * gridDim.x;
|
|
@@ -316,7 +382,7 @@ code_update = """
|
|
|
316
382
|
}
|
|
317
383
|
|
|
318
384
|
// Update state of Tsetlin Automata team
|
|
319
|
-
__global__ void update_hierarchy(curandState *state, int number_of_outputs, unsigned int *global_ta_state, int *clause_weights,
|
|
385
|
+
__global__ void update_hierarchy(curandState *state, int number_of_outputs, unsigned int *global_ta_state, int *clause_weights, int *component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_type, int *class_sum, int *X, int *y, int example)
|
|
320
386
|
{
|
|
321
387
|
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
|
322
388
|
int stride = blockDim.x * gridDim.x;
|
|
@@ -328,25 +394,39 @@ code_update = """
|
|
|
328
394
|
|
|
329
395
|
// Calculate clause output first
|
|
330
396
|
for (int clause_component = index; clause_component < CLAUSES*COMPONENTS; clause_component += stride) {
|
|
397
|
+
if (component_output[clause_component] == -1) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
|
|
331
401
|
int clause = clause_component / COMPONENTS;
|
|
332
402
|
int component = clause_component % COMPONENTS;
|
|
333
403
|
|
|
334
404
|
// Get state of current clause component
|
|
335
|
-
|
|
405
|
+
// This one must be updated for reuse of TAs within OR group
|
|
336
406
|
|
|
337
407
|
int component_remainder = component;
|
|
408
|
+
int feature_chunk_base = 0;
|
|
338
409
|
int ta_chunk_base = 0;
|
|
339
|
-
int
|
|
410
|
+
int size_feature_chunk_base = 1;
|
|
411
|
+
int size_ta_chunk_base = 1;
|
|
340
412
|
for (int d = 0; d < depth-1; ++d) {
|
|
341
413
|
int depth_d_node_index = component_remainder % hierarchy_structure_factors[d];
|
|
342
414
|
component_remainder = component_remainder / hierarchy_structure_factors[d];
|
|
343
415
|
|
|
344
|
-
if (
|
|
345
|
-
|
|
346
|
-
|
|
416
|
+
if (hierarchy_structure_type[d] != 1) {
|
|
417
|
+
feature_chunk_base += size_feature_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
|
|
418
|
+
size_feature_chunk_base *= hierarchy_structure_factors[d];
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (hierarchy_structure_type[d] != 2) {
|
|
422
|
+
ta_chunk_base += size_ta_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
|
|
423
|
+
size_ta_chunk_base *= hierarchy_structure_factors[d];
|
|
347
424
|
}
|
|
348
425
|
}
|
|
349
426
|
|
|
427
|
+
// Get state of current ta team component
|
|
428
|
+
unsigned int *ta_state = &global_ta_state[clause*COMPONENTS*TA_CHUNKS_PER_LEAF*STATE_BITS + ta_chunk_base*STATE_BITS];
|
|
429
|
+
|
|
350
430
|
for (unsigned long long class_id = 0; class_id < number_of_outputs; ++class_id) {
|
|
351
431
|
int local_class_sum = class_sum[class_id];
|
|
352
432
|
if (local_class_sum > THRESHOLD) {
|
|
@@ -355,7 +435,7 @@ code_update = """
|
|
|
355
435
|
local_class_sum = -THRESHOLD;
|
|
356
436
|
}
|
|
357
437
|
|
|
358
|
-
update_component_hierarchy(&localState, number_of_outputs, &clause_weights[class_id*CLAUSES + clause], ta_state, component_output[clause_component], &Xi[
|
|
438
|
+
update_component_hierarchy(&localState, number_of_outputs, &clause_weights[class_id*CLAUSES + clause], ta_state, component_output[clause_component], &Xi[feature_chunk_base], y[example*number_of_outputs + class_id], local_class_sum);
|
|
359
439
|
}
|
|
360
440
|
}
|
|
361
441
|
|
|
@@ -28,6 +28,7 @@ import pycuda.driver as cuda
|
|
|
28
28
|
import pycuda.autoinit
|
|
29
29
|
from pycuda.compiler import SourceModule
|
|
30
30
|
from pycuda import gpuarray
|
|
31
|
+
import sys
|
|
31
32
|
|
|
32
33
|
from time import time
|
|
33
34
|
|
|
@@ -64,11 +65,13 @@ class CommonTsetlinMachine():
|
|
|
64
65
|
|
|
65
66
|
# Represents hierarchy structure for transfer to GPU
|
|
66
67
|
self.hierarchy_structure_factors = [0] * (self.depth - 1)
|
|
67
|
-
self.
|
|
68
|
+
self.hierarchy_structure_type = [0] * (self.depth - 1)
|
|
68
69
|
for d in range(1, self.depth):
|
|
69
70
|
self.hierarchy_structure_factors[d-1] = self.hierarchy_structure[d][1]
|
|
70
71
|
if self.hierarchy_structure[d][0] == OR_ALTERNATIVES:
|
|
71
|
-
self.
|
|
72
|
+
self.hierarchy_structure_type[d-1] = 1
|
|
73
|
+
elif self.hierarchy_structure[d][0] == OR_GROUP:
|
|
74
|
+
self.hierarchy_structure_type[d-1] = 2
|
|
72
75
|
|
|
73
76
|
# Calculates total number of features spanned by the hierarchy
|
|
74
77
|
self.number_of_features_hierarchy = 1
|
|
@@ -147,6 +150,9 @@ class CommonTsetlinMachine():
|
|
|
147
150
|
self.propagate_and_group_false_truth_values = mod_update.get_function("propagate_and_group_false_truth_values")
|
|
148
151
|
self.propagate_and_group_false_truth_values.prepare("PPii")
|
|
149
152
|
|
|
153
|
+
self.propagate_or_group_false_truth_values = mod_update.get_function("propagate_or_group_false_truth_values")
|
|
154
|
+
self.propagate_or_group_false_truth_values.prepare("PPPii")
|
|
155
|
+
|
|
150
156
|
self.evaluate_or_groups = mod_update.get_function("evaluate_or_groups")
|
|
151
157
|
self.evaluate_or_groups.prepare("PPii")
|
|
152
158
|
|
|
@@ -189,8 +195,8 @@ class CommonTsetlinMachine():
|
|
|
189
195
|
cuda.memcpy_htod(self.hierarchy_structure_factors_gpu, np.array(self.hierarchy_structure_factors, dtype=np.int32))
|
|
190
196
|
|
|
191
197
|
# GPU memory for storing hierarchy structure
|
|
192
|
-
self.
|
|
193
|
-
cuda.memcpy_htod(self.
|
|
198
|
+
self.hierarchy_structure_type_gpu = cuda.mem_alloc((self.depth-1)*4)
|
|
199
|
+
cuda.memcpy_htod(self.hierarchy_structure_type_gpu, np.array(self.hierarchy_structure_type, dtype=np.int32))
|
|
194
200
|
|
|
195
201
|
# GPU memory for storing Tsetlin Automata states
|
|
196
202
|
self.ta_state_hierarchy_gpu = cuda.mem_alloc(self.number_of_clauses*self.hierarchy_size[0]*self.number_of_state_bits*4)
|
|
@@ -266,7 +272,7 @@ class CommonTsetlinMachine():
|
|
|
266
272
|
self.hierarchy_votes[0],
|
|
267
273
|
self.depth,
|
|
268
274
|
self.hierarchy_structure_factors_gpu,
|
|
269
|
-
self.
|
|
275
|
+
self.hierarchy_structure_type_gpu,
|
|
270
276
|
encoded_X_hierarchy,
|
|
271
277
|
np.int32(e)
|
|
272
278
|
)
|
|
@@ -320,6 +326,10 @@ class CommonTsetlinMachine():
|
|
|
320
326
|
cuda.Context.synchronize()
|
|
321
327
|
|
|
322
328
|
def _fit(self, X, encoded_Y, epochs=100, incremental=False):
|
|
329
|
+
if self.number_of_features_hierarchy != X.shape[1]:
|
|
330
|
+
print("The number of features spanned by hierarchy does not align with the input data.")
|
|
331
|
+
sys.exit(-1)
|
|
332
|
+
|
|
323
333
|
number_of_examples = X.shape[0]
|
|
324
334
|
|
|
325
335
|
if self.first:
|
|
@@ -347,15 +357,27 @@ class CommonTsetlinMachine():
|
|
|
347
357
|
# Propagates the root value and any intermittent node values back to the leaves.
|
|
348
358
|
# The purpose is to determine which leaves only has True nodes on the path from leaf to root.
|
|
349
359
|
for d in range(self.depth-1, 0, -1):
|
|
350
|
-
self.
|
|
351
|
-
self.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
360
|
+
if self.hierarchy_structure[d][0] != OR_GROUP:
|
|
361
|
+
self.propagate_and_group_false_truth_values.prepared_call(
|
|
362
|
+
self.grid,
|
|
363
|
+
self.block,
|
|
364
|
+
self.hierarchy_votes[d-1],
|
|
365
|
+
self.hierarchy_votes[d],
|
|
366
|
+
self.hierarchy_size[d + 1],
|
|
367
|
+
self.hierarchy_structure[d][1]
|
|
368
|
+
)
|
|
369
|
+
cuda.Context.synchronize()
|
|
370
|
+
else:
|
|
371
|
+
self.propagate_or_group_false_truth_values.prepared_call(
|
|
372
|
+
self.grid,
|
|
373
|
+
self.block,
|
|
374
|
+
self.cuda_rng.state,
|
|
375
|
+
self.hierarchy_votes[d-1],
|
|
376
|
+
self.hierarchy_votes[d],
|
|
377
|
+
self.hierarchy_size[d + 1],
|
|
378
|
+
self.hierarchy_structure[d][1]
|
|
379
|
+
)
|
|
380
|
+
cuda.Context.synchronize()
|
|
359
381
|
|
|
360
382
|
# Updates the clause components (leaves) based on the propagated truth values
|
|
361
383
|
self.update_hierarchy.prepared_call(
|
|
@@ -368,7 +390,7 @@ class CommonTsetlinMachine():
|
|
|
368
390
|
self.hierarchy_votes[0],
|
|
369
391
|
self.depth,
|
|
370
392
|
self.hierarchy_structure_factors_gpu,
|
|
371
|
-
self.
|
|
393
|
+
self.hierarchy_structure_type_gpu,
|
|
372
394
|
self.class_sum_gpu,
|
|
373
395
|
encoded_X_hierarchy_training_gpu,
|
|
374
396
|
Y_gpu,
|
|
@@ -10,8 +10,4 @@ PyHierarchicalTsetlinMachineCUDA.egg-info/PKG-INFO
|
|
|
10
10
|
PyHierarchicalTsetlinMachineCUDA.egg-info/SOURCES.txt
|
|
11
11
|
PyHierarchicalTsetlinMachineCUDA.egg-info/dependency_links.txt
|
|
12
12
|
PyHierarchicalTsetlinMachineCUDA.egg-info/requires.txt
|
|
13
|
-
PyHierarchicalTsetlinMachineCUDA.egg-info/top_level.txt
|
|
14
|
-
pyhierarchicaltsetlinmachinecuda.egg-info/PKG-INFO
|
|
15
|
-
pyhierarchicaltsetlinmachinecuda.egg-info/SOURCES.txt
|
|
16
|
-
pyhierarchicaltsetlinmachinecuda.egg-info/dependency_links.txt
|
|
17
|
-
pyhierarchicaltsetlinmachinecuda.egg-info/top_level.txt
|
|
13
|
+
PyHierarchicalTsetlinMachineCUDA.egg-info/top_level.txt
|
|
@@ -149,11 +149,11 @@ python3 ./examples/HexDemo.py
|
|
|
149
149
|
|
|
150
150
|
Accuracy over 1000 epochs:
|
|
151
151
|
|
|
152
|
-
#1 Training Accuracy: 97.
|
|
153
|
-
#2 Training Accuracy: 99.
|
|
154
|
-
#3 Training Accuracy: 99.
|
|
155
|
-
#4 Training Accuracy: 99.
|
|
156
|
-
#5 Training Accuracy: 99.
|
|
152
|
+
#1 Training Accuracy: 97.98% Testing Accuracy: 97.46% Training Time: 37.02s Testing Time: 5.74s
|
|
153
|
+
#2 Training Accuracy: 99.19% Testing Accuracy: 98.70% Training Time: 34.44s Testing Time: 5.76s
|
|
154
|
+
#3 Training Accuracy: 99.49% Testing Accuracy: 98.92% Training Time: 33.60s Testing Time: 5.75s
|
|
155
|
+
#4 Training Accuracy: 99.65% Testing Accuracy: 99.05% Training Time: 33.15s Testing Time: 5.78s
|
|
156
|
+
#5 Training Accuracy: 99.73% Testing Accuracy: 99.10% Training Time: 32.86s Testing Time: 5.76s
|
|
157
157
|
...
|
|
158
158
|
#446 Training Accuracy: 100.00% Testing Accuracy: 99.45% Training Time: 32.09s Testing Time: 6.09s
|
|
159
159
|
#447 Training Accuracy: 100.00% Testing Accuracy: 99.46% Training Time: 32.08s Testing Time: 6.09s
|
|
@@ -2,7 +2,7 @@ from setuptools import *
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='PyHierarchicalTsetlinMachineCUDA',
|
|
5
|
-
version='0.2.
|
|
5
|
+
version='0.2.6',
|
|
6
6
|
author='Ole-Christoffer Granmo',
|
|
7
7
|
author_email='ole.granmo@uia.no',
|
|
8
8
|
url='https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/',
|
|
@@ -16,6 +16,7 @@ setup(
|
|
|
16
16
|
'pycuda',
|
|
17
17
|
'scipy',
|
|
18
18
|
'scikit-learn',
|
|
19
|
+
'scikit-image',
|
|
19
20
|
'networkx',
|
|
20
21
|
],
|
|
21
22
|
extras_require={
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|