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.
Files changed (15) hide show
  1. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PKG-INFO +1 -1
  2. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/kernels.py +114 -34
  3. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/tm.py +37 -15
  4. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/PKG-INFO +1 -1
  5. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/SOURCES.txt +1 -5
  6. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/requires.txt +1 -0
  7. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/README.md +5 -5
  8. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/setup.py +2 -1
  9. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/LICENSE +0 -0
  10. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/__init__.py +0 -0
  11. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/tools.py +0 -0
  12. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA/utils.py +0 -0
  13. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/dependency_links.txt +0 -0
  14. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/PyHierarchicalTsetlinMachineCUDA.egg-info/top_level.txt +0 -0
  15. {PyHierarchicalTsetlinMachineCUDA-0.2.3 → PyHierarchicalTsetlinMachineCUDA-0.2.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyHierarchicalTsetlinMachineCUDA
3
- Version: 0.2.3
3
+ Version: 0.2.6
4
4
  Summary: Hierarchical Tsetlin Machine Architecture.
5
5
  Home-page: https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/
6
6
  Author: Ole-Christoffer Granmo
@@ -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, long long int *global_component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_alternatives, int *X, int example)
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 size = 1;
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 (hierarchy_structure_alternatives[d] == 0) {
184
- ta_chunk_base += size * depth_d_node_index * TA_CHUNKS_PER_LEAF;
185
- size *= hierarchy_structure_factors[d];
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[ta_chunk_base + ta_chunk]) != ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1]) {
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[ta_chunk_base + TA_CHUNKS_PER_LEAF-1] & FILTER_HIERARCHICAL) != (ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & FILTER_HIERARCHICAL)) {
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(long long int *child_input, long long int *or_group_node_output, int number_of_or_group_nodes, int number_of_or_group_addends)
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
- long long int or_group_vote_sum = 0;
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
- long long int previous_or_group_vote_sum = or_group_vote_sum;
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 %lld -> %lld\\n", previous_or_group_vote_sum, or_group_vote_sum);
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
- // Store or group vote sum as node output
228
- or_group_node_output[or_group_node] = or_group_vote_sum;
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(long long int *child_input, long long int *and_group_node_output, int number_of_and_group_nodes, int number_of_and_group_factors)
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
- long long int and_group_vote_product = 1;
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
- long long int previous_and_group_vote_product = and_group_vote_product;
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 %lld -> %lld\\n", previous_and_group_vote_product, and_group_vote_product);
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(long long int *child_input, long long int *group_node_output, int number_of_group_nodes, int number_of_group_node_children)
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 evaluate_or_alternatives(long long int *child_input, long long int *or_alternatives_node_output, int number_of_or_alternatives_nodes, int number_of_or_alternatives)
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
- long long int or_alternatives_vote_sum = 0;
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
- long long int previous_or_alternatives_vote_sum = or_alternatives_vote_sum;
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 %lld -> %lld\\n", previous_or_alternatives_vote_sum, or_alternatives_vote_sum);
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, long long int *child_input, int *clause_weights, int *class_sum)
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, long long int *component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_alternatives, int *class_sum, int *X, int *y, int example)
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
- unsigned int *ta_state = &global_ta_state[clause_component*TA_CHUNKS_PER_LEAF*STATE_BITS];
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 size = 1;
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 (hierarchy_structure_alternatives[d] == 0) {
345
- ta_chunk_base += size * depth_d_node_index * TA_CHUNKS_PER_LEAF;
346
- size *= hierarchy_structure_factors[d];
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[ta_chunk_base], y[example*number_of_outputs + class_id], local_class_sum);
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.hierarchy_structure_alternatives = [0] * (self.depth - 1)
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.hierarchy_structure_alternatives[d-1] = 1
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.hierarchy_structure_alternatives_gpu = cuda.mem_alloc((self.depth-1)*4)
193
- cuda.memcpy_htod(self.hierarchy_structure_alternatives_gpu, np.array(self.hierarchy_structure_alternatives, dtype=np.int32))
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.hierarchy_structure_alternatives_gpu,
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.propagate_and_group_false_truth_values.prepared_call(
351
- self.grid,
352
- self.block,
353
- self.hierarchy_votes[d-1],
354
- self.hierarchy_votes[d],
355
- self.hierarchy_size[d + 1],
356
- self.hierarchy_structure[d][1]
357
- )
358
- cuda.Context.synchronize()
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.hierarchy_structure_alternatives_gpu,
393
+ self.hierarchy_structure_type_gpu,
372
394
  self.class_sum_gpu,
373
395
  encoded_X_hierarchy_training_gpu,
374
396
  Y_gpu,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyHierarchicalTsetlinMachineCUDA
3
- Version: 0.2.3
3
+ Version: 0.2.6
4
4
  Summary: Hierarchical Tsetlin Machine Architecture.
5
5
  Home-page: https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/
6
6
  Author: Ole-Christoffer Granmo
@@ -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.71% Testing Accuracy: 97.26% Training Time: 36.00s Testing Time: 5.65s
153
- #2 Training Accuracy: 99.11% Testing Accuracy: 98.61% Training Time: 33.65s Testing Time: 5.65s
154
- #3 Training Accuracy: 99.53% Testing Accuracy: 98.92% Training Time: 33.00s Testing Time: 5.65s
155
- #4 Training Accuracy: 99.74% Testing Accuracy: 99.18% Training Time: 32.66s Testing Time: 5.67s
156
- #5 Training Accuracy: 99.84% Testing Accuracy: 99.35% Training Time: 32.40s Testing Time: 5.67s
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.3',
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={