bones-compiler 1.1.0
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.
- data/CHANGELOG +117 -0
- data/LICENSE +9 -0
- data/README.rdoc +126 -0
- data/Rakefile +107 -0
- data/VERSION +1 -0
- data/bin/bones +20 -0
- data/examples/applications/ffos.c +552 -0
- data/examples/benchmarks/2mm.c +70 -0
- data/examples/benchmarks/3mm.c +81 -0
- data/examples/benchmarks/adi.c +81 -0
- data/examples/benchmarks/atax.c +65 -0
- data/examples/benchmarks/bicg.c +67 -0
- data/examples/benchmarks/cholesky.c +64 -0
- data/examples/benchmarks/common.h +168 -0
- data/examples/benchmarks/correlation.c +97 -0
- data/examples/benchmarks/covariance.c +77 -0
- data/examples/benchmarks/doitgen.c +63 -0
- data/examples/benchmarks/durbin.c +76 -0
- data/examples/benchmarks/dynprog.c +67 -0
- data/examples/benchmarks/fdtd-2d-apml.c +114 -0
- data/examples/benchmarks/fdtd-2d.c +74 -0
- data/examples/benchmarks/floyd-warshall.c +50 -0
- data/examples/benchmarks/gemm.c +69 -0
- data/examples/benchmarks/gemver.c +89 -0
- data/examples/benchmarks/gesummv.c +64 -0
- data/examples/benchmarks/gramschmidt.c +84 -0
- data/examples/benchmarks/jacobi-1d-imper.c +55 -0
- data/examples/benchmarks/jacobi-2d-imper.c +61 -0
- data/examples/benchmarks/lu.c +57 -0
- data/examples/benchmarks/ludcmp.c +91 -0
- data/examples/benchmarks/mvt.c +65 -0
- data/examples/benchmarks/overview.txt +38 -0
- data/examples/benchmarks/reg_detect.c +82 -0
- data/examples/benchmarks/saxpy.c +45 -0
- data/examples/benchmarks/seidel-2d.c +51 -0
- data/examples/benchmarks/symm.c +74 -0
- data/examples/benchmarks/syr2k.c +65 -0
- data/examples/benchmarks/syrk.c +62 -0
- data/examples/benchmarks/trisolv.c +57 -0
- data/examples/benchmarks/trmm.c +57 -0
- data/examples/chunk/example1.c +54 -0
- data/examples/chunk/example2.c +44 -0
- data/examples/chunk/example3.c +59 -0
- data/examples/chunk/example4.c +55 -0
- data/examples/chunk/example5.c +52 -0
- data/examples/element/example1.c +46 -0
- data/examples/element/example10.c +50 -0
- data/examples/element/example11.c +47 -0
- data/examples/element/example12.c +56 -0
- data/examples/element/example2.c +46 -0
- data/examples/element/example3.c +58 -0
- data/examples/element/example4.c +49 -0
- data/examples/element/example5.c +56 -0
- data/examples/element/example6.c +46 -0
- data/examples/element/example7.c +54 -0
- data/examples/element/example8.c +45 -0
- data/examples/element/example9.c +48 -0
- data/examples/neighbourhood/example1.c +54 -0
- data/examples/neighbourhood/example2.c +55 -0
- data/examples/neighbourhood/example3.c +82 -0
- data/examples/neighbourhood/example4.c +52 -0
- data/examples/shared/example1.c +45 -0
- data/examples/shared/example2.c +51 -0
- data/examples/shared/example3.c +55 -0
- data/examples/shared/example4.c +52 -0
- data/examples/shared/example5.c +48 -0
- data/lib/bones.rb +266 -0
- data/lib/bones/algorithm.rb +541 -0
- data/lib/bones/engine.rb +386 -0
- data/lib/bones/preprocessor.rb +161 -0
- data/lib/bones/species.rb +196 -0
- data/lib/bones/structure.rb +94 -0
- data/lib/bones/variable.rb +169 -0
- data/lib/bones/variablelist.rb +72 -0
- data/lib/castaddon.rb +27 -0
- data/lib/castaddon/index.rb +40 -0
- data/lib/castaddon/node.rb +753 -0
- data/lib/castaddon/type.rb +37 -0
- data/skeletons/CPU-C/common/epilogue.c +0 -0
- data/skeletons/CPU-C/common/globals.c +17 -0
- data/skeletons/CPU-C/common/globals_kernel.c +1 -0
- data/skeletons/CPU-C/common/header.c +0 -0
- data/skeletons/CPU-C/common/mem_copy_D2H.c +0 -0
- data/skeletons/CPU-C/common/mem_copy_H2D.c +0 -0
- data/skeletons/CPU-C/common/mem_epilogue.c +0 -0
- data/skeletons/CPU-C/common/mem_prologue.c +3 -0
- data/skeletons/CPU-C/common/prologue.c +0 -0
- data/skeletons/CPU-C/common/timer_1_start.c +0 -0
- data/skeletons/CPU-C/common/timer_1_stop.c +0 -0
- data/skeletons/CPU-C/common/timer_2_start.c +20 -0
- data/skeletons/CPU-C/common/timer_2_stop.c +8 -0
- data/skeletons/CPU-C/kernel/default.host.c +3 -0
- data/skeletons/CPU-C/kernel/default.kernel.c +15 -0
- data/skeletons/CPU-C/skeletons.txt +24 -0
- data/skeletons/CPU-OPENCL-AMD/common/epilogue.c +6 -0
- data/skeletons/CPU-OPENCL-AMD/common/globals.c +155 -0
- data/skeletons/CPU-OPENCL-AMD/common/globals_kernel.c +4 -0
- data/skeletons/CPU-OPENCL-AMD/common/header.c +0 -0
- data/skeletons/CPU-OPENCL-AMD/common/mem_copy_D2H.c +8 -0
- data/skeletons/CPU-OPENCL-AMD/common/mem_copy_H2D.c +4 -0
- data/skeletons/CPU-OPENCL-AMD/common/mem_epilogue.c +3 -0
- data/skeletons/CPU-OPENCL-AMD/common/mem_prologue.c +6 -0
- data/skeletons/CPU-OPENCL-AMD/common/prologue.c +24 -0
- data/skeletons/CPU-OPENCL-AMD/common/timer_1_start.c +5 -0
- data/skeletons/CPU-OPENCL-AMD/common/timer_1_stop.c +9 -0
- data/skeletons/CPU-OPENCL-AMD/common/timer_2_start.c +16 -0
- data/skeletons/CPU-OPENCL-AMD/common/timer_2_stop.c +11 -0
- data/skeletons/CPU-OPENCL-AMD/kernel/D-element-to-1-shared.host.c +67 -0
- data/skeletons/CPU-OPENCL-AMD/kernel/D-element-to-1-shared.kernel.cl +72 -0
- data/skeletons/CPU-OPENCL-AMD/kernel/default.host.c +14 -0
- data/skeletons/CPU-OPENCL-AMD/kernel/default.kernel.cl +13 -0
- data/skeletons/CPU-OPENCL-AMD/skeletons.txt +26 -0
- data/skeletons/CPU-OPENCL-INTEL/common/epilogue.c +3 -0
- data/skeletons/CPU-OPENCL-INTEL/common/globals.c +154 -0
- data/skeletons/CPU-OPENCL-INTEL/common/globals_kernel.c +4 -0
- data/skeletons/CPU-OPENCL-INTEL/common/header.c +31 -0
- data/skeletons/CPU-OPENCL-INTEL/common/mem_copy_D2H.c +5 -0
- data/skeletons/CPU-OPENCL-INTEL/common/mem_copy_H2D.c +3 -0
- data/skeletons/CPU-OPENCL-INTEL/common/mem_epilogue.c +3 -0
- data/skeletons/CPU-OPENCL-INTEL/common/mem_prologue.c +4 -0
- data/skeletons/CPU-OPENCL-INTEL/common/prologue.c +24 -0
- data/skeletons/CPU-OPENCL-INTEL/common/timer_1_start.c +5 -0
- data/skeletons/CPU-OPENCL-INTEL/common/timer_1_stop.c +9 -0
- data/skeletons/CPU-OPENCL-INTEL/common/timer_2_start.c +16 -0
- data/skeletons/CPU-OPENCL-INTEL/common/timer_2_stop.c +11 -0
- data/skeletons/CPU-OPENCL-INTEL/kernel/D-element-to-1-shared.host.c +67 -0
- data/skeletons/CPU-OPENCL-INTEL/kernel/D-element-to-1-shared.kernel.cl +72 -0
- data/skeletons/CPU-OPENCL-INTEL/kernel/default.host.c +14 -0
- data/skeletons/CPU-OPENCL-INTEL/kernel/default.kernel.cl +13 -0
- data/skeletons/CPU-OPENCL-INTEL/skeletons.txt +26 -0
- data/skeletons/CPU-OPENMP/common/epilogue.c +0 -0
- data/skeletons/CPU-OPENMP/common/globals.c +37 -0
- data/skeletons/CPU-OPENMP/common/globals_kernel.c +6 -0
- data/skeletons/CPU-OPENMP/common/header.c +0 -0
- data/skeletons/CPU-OPENMP/common/mem_copy_D2H.c +0 -0
- data/skeletons/CPU-OPENMP/common/mem_copy_H2D.c +0 -0
- data/skeletons/CPU-OPENMP/common/mem_epilogue.c +0 -0
- data/skeletons/CPU-OPENMP/common/mem_prologue.c +3 -0
- data/skeletons/CPU-OPENMP/common/prologue.c +0 -0
- data/skeletons/CPU-OPENMP/common/timer_1_start.c +12 -0
- data/skeletons/CPU-OPENMP/common/timer_1_stop.c +0 -0
- data/skeletons/CPU-OPENMP/common/timer_2_start.c +18 -0
- data/skeletons/CPU-OPENMP/common/timer_2_stop.c +8 -0
- data/skeletons/CPU-OPENMP/kernel/D-element-to-1-shared.host.c +27 -0
- data/skeletons/CPU-OPENMP/kernel/D-element-to-1-shared.kernel.c +46 -0
- data/skeletons/CPU-OPENMP/kernel/default.host.c +11 -0
- data/skeletons/CPU-OPENMP/kernel/default.kernel.c +18 -0
- data/skeletons/CPU-OPENMP/skeletons.txt +26 -0
- data/skeletons/GPU-CUDA/common/epilogue.c +0 -0
- data/skeletons/GPU-CUDA/common/globals.c +31 -0
- data/skeletons/GPU-CUDA/common/globals_kernel.c +4 -0
- data/skeletons/GPU-CUDA/common/header.c +0 -0
- data/skeletons/GPU-CUDA/common/mem_copy_D2H.c +3 -0
- data/skeletons/GPU-CUDA/common/mem_copy_H2D.c +3 -0
- data/skeletons/GPU-CUDA/common/mem_epilogue.c +3 -0
- data/skeletons/GPU-CUDA/common/mem_prologue.c +5 -0
- data/skeletons/GPU-CUDA/common/prologue.c +6 -0
- data/skeletons/GPU-CUDA/common/timer_1_start.c +6 -0
- data/skeletons/GPU-CUDA/common/timer_1_stop.c +10 -0
- data/skeletons/GPU-CUDA/common/timer_2_start.c +6 -0
- data/skeletons/GPU-CUDA/common/timer_2_stop.c +10 -0
- data/skeletons/GPU-CUDA/kernel/2xN-N-chunk-1-N-to-D-element.host.c +3 -0
- data/skeletons/GPU-CUDA/kernel/2xN-N-chunk-1-N-to-D-element.kernel.cu +105 -0
- data/skeletons/GPU-CUDA/kernel/D-element-to-1-shared.host.c +3 -0
- data/skeletons/GPU-CUDA/kernel/D-element-to-1-shared.kernel.cu +119 -0
- data/skeletons/GPU-CUDA/kernel/D-element-to-N-shared.host.c +3 -0
- data/skeletons/GPU-CUDA/kernel/D-element-to-N-shared.kernel.cu +166 -0
- data/skeletons/GPU-CUDA/kernel/N-N-chunk-1-N-to-D-element.host.c +3 -0
- data/skeletons/GPU-CUDA/kernel/N-N-chunk-1-N-to-D-element.kernel.cu +69 -0
- data/skeletons/GPU-CUDA/kernel/N-neighbourhood-N-to-N-element.host.c +3 -0
- data/skeletons/GPU-CUDA/kernel/N-neighbourhood-N-to-N-element.kernel.cu +42 -0
- data/skeletons/GPU-CUDA/kernel/default.host.c +3 -0
- data/skeletons/GPU-CUDA/kernel/default.kernel.cu +28 -0
- data/skeletons/GPU-CUDA/skeletons.txt +30 -0
- data/skeletons/GPU-OPENCL-AMD/common/epilogue.c +3 -0
- data/skeletons/GPU-OPENCL-AMD/common/globals.c +155 -0
- data/skeletons/GPU-OPENCL-AMD/common/globals_kernel.c +4 -0
- data/skeletons/GPU-OPENCL-AMD/common/header.c +0 -0
- data/skeletons/GPU-OPENCL-AMD/common/mem_copy_D2H.c +4 -0
- data/skeletons/GPU-OPENCL-AMD/common/mem_copy_H2D.c +4 -0
- data/skeletons/GPU-OPENCL-AMD/common/mem_epilogue.c +3 -0
- data/skeletons/GPU-OPENCL-AMD/common/mem_prologue.c +3 -0
- data/skeletons/GPU-OPENCL-AMD/common/prologue.c +24 -0
- data/skeletons/GPU-OPENCL-AMD/common/timer_1_start.c +5 -0
- data/skeletons/GPU-OPENCL-AMD/common/timer_1_stop.c +9 -0
- data/skeletons/GPU-OPENCL-AMD/common/timer_2_start.c +4 -0
- data/skeletons/GPU-OPENCL-AMD/common/timer_2_stop.c +11 -0
- data/skeletons/GPU-OPENCL-AMD/kernel/D-element-to-1-shared.host.c +67 -0
- data/skeletons/GPU-OPENCL-AMD/kernel/D-element-to-1-shared.kernel.cl +72 -0
- data/skeletons/GPU-OPENCL-AMD/kernel/default.host.c +14 -0
- data/skeletons/GPU-OPENCL-AMD/kernel/default.kernel.cl +13 -0
- data/skeletons/GPU-OPENCL-AMD/skeletons.txt +26 -0
- data/skeletons/verification/header.c +2 -0
- data/skeletons/verification/timer_start.c +4 -0
- data/skeletons/verification/timer_stop.c +6 -0
- data/skeletons/verification/verify_results.c +23 -0
- data/test/bones/test_algorithm.rb +40 -0
- data/test/bones/test_common.rb +54 -0
- data/test/bones/test_preprocessor.rb +46 -0
- data/test/bones/test_species.rb +21 -0
- data/test/bones/test_variable.rb +84 -0
- data/test/test_helper.rb +106 -0
- metadata +303 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
|
|
2
|
+
module Bones
|
|
3
|
+
# The species class contains 'algorithm classes', or 'species'.
|
|
4
|
+
# Individual species contain a number of input and output
|
|
5
|
+
# structures and possibly a prefix.
|
|
6
|
+
#
|
|
7
|
+
# Examples of species are found below:
|
|
8
|
+
#
|
|
9
|
+
# 0:9|element -> 0:0|shared
|
|
10
|
+
# 0:31,0:31|neighbourhood(-1:1,-1:1) -> 0:31,0:31|element
|
|
11
|
+
# unordered 0:99,0:9|chunk(0:0,0:9) -> 0:99|element
|
|
12
|
+
#
|
|
13
|
+
# == Naming conventions
|
|
14
|
+
# The species class uses several naming conventions within
|
|
15
|
+
# functions. They are as follows for the example species
|
|
16
|
+
# '0:31,0:15|neighbourhood(-1:1,-1:1) ^ 0:31,0:15|element -> 0:31,0:15|element':
|
|
17
|
+
#
|
|
18
|
+
# input:: '0:31,0:15|neighbourhood(-1:1,-1:1) ^ 0:31,0:15|element'
|
|
19
|
+
# output:: '0:31,0:15|element'
|
|
20
|
+
# structures:: \['0:31,0:15|neighbourhood(-1:1,-1:1)', '0:31,0:15|element', '0:31,0:15|element']
|
|
21
|
+
# structure:: '0:31,0:15|neighbourhood(-1:1,-1:1)' or '0:31,0:15|element' (twice)
|
|
22
|
+
# pattern:: 'neighbourhood' or 'element'
|
|
23
|
+
# ranges:: \['0:31', '0:15'] or ['-1:1', '-1:1']
|
|
24
|
+
# range:: '0:31' or '0:15' or '-1:1'
|
|
25
|
+
# from:: '0' or '-1'
|
|
26
|
+
# to:: '31' or '15' or '1'
|
|
27
|
+
# sum:: '32' or '16' or '3'
|
|
28
|
+
class Species < Common
|
|
29
|
+
attr_reader :name, :inputs, :outputs, :skeleton_name, :settings, :prefix
|
|
30
|
+
|
|
31
|
+
# Initializes the species with a prefix, inputs and out-
|
|
32
|
+
# puts. It additionally verifies the correctness of the
|
|
33
|
+
# provided raw data.
|
|
34
|
+
def initialize(prefix, input, output)
|
|
35
|
+
@prefix = prefix
|
|
36
|
+
@name = (input+' '+ARROW+' '+output)
|
|
37
|
+
@inputs = set_structures(input)
|
|
38
|
+
@outputs = set_structures(output)
|
|
39
|
+
@skeleton_name = nil
|
|
40
|
+
@settings = nil
|
|
41
|
+
self.verify_species
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# This method splits the raw data (a string) into seperate
|
|
45
|
+
# structures. The method returns an array of structures.
|
|
46
|
+
def set_structures(raw_data)
|
|
47
|
+
raw_data.split(WEDGE).map { |structure| Structure.new(structure) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Method to return an array of structures in a given di-
|
|
51
|
+
# rection.
|
|
52
|
+
def structures(direction)
|
|
53
|
+
(direction == INPUT) ? @inputs : @outputs
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Method to return an array of structures for both direc-
|
|
57
|
+
# tions.
|
|
58
|
+
def all_structures
|
|
59
|
+
@inputs + @outputs
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Method to return an ordered array of structures in a
|
|
63
|
+
# given direction. The order is specified by an argument
|
|
64
|
+
# which contains a list of pattern names.
|
|
65
|
+
def ordered(direction,order)
|
|
66
|
+
ordered = []
|
|
67
|
+
order.each do |pattern_name|
|
|
68
|
+
self.structures(direction).each do |structure|
|
|
69
|
+
ordered.push(structure) if structure.pattern == pattern_name
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Remove structures with a duplicate name (for matching only - and only if names are given)
|
|
74
|
+
if ordered.all? { |s| s.name != "" }
|
|
75
|
+
names = []
|
|
76
|
+
ordered.each do |structure|
|
|
77
|
+
ordered.delete(structure) if names.include?(structure.name)
|
|
78
|
+
names.push(structure.name)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
return ordered
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# This method maps an algorithm species to a skeleton.
|
|
85
|
+
# This is done based on a mapping file provided as part
|
|
86
|
+
# of the skeleton library. If multiple skeletons match
|
|
87
|
+
# the current species, the first found match is taken.
|
|
88
|
+
# This method does not return any values, but instead
|
|
89
|
+
# sets the class variables +skeleton_name+ and +settings+.
|
|
90
|
+
def set_skeleton(mapping_file)
|
|
91
|
+
matches = []
|
|
92
|
+
File.read(mapping_file).each_line do |line|
|
|
93
|
+
next if line =~ /^#/
|
|
94
|
+
data = line.split(/\s:/)
|
|
95
|
+
matches.push(data) if match_species?(data[0].split(ARROW))
|
|
96
|
+
end
|
|
97
|
+
puts MESSAGE+'Multiple matches in skeleton file, selecting the first listed' if matches.length > 1
|
|
98
|
+
if matches.length != 0
|
|
99
|
+
@skeleton_name = matches[0][1].delete(':').strip
|
|
100
|
+
@settings = matches[0][2].delete(':').strip
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# This method is called by the +set_skeleton+ method. It
|
|
105
|
+
# performs a match between the current species and the
|
|
106
|
+
# species found in the mapping file. The matching is based
|
|
107
|
+
# on a fixed order of patterns. The method returns either
|
|
108
|
+
# true or false.
|
|
109
|
+
def match_species?(file_data)
|
|
110
|
+
DIRECTIONS.each_with_index do |direction,num_direction|
|
|
111
|
+
file_structures = file_data[num_direction].split(WEDGE)
|
|
112
|
+
counter = 0
|
|
113
|
+
search_structures = ordered(direction,['chunk','neighbourhood','element','shared','void'])
|
|
114
|
+
search_structures.each do |search_structure|
|
|
115
|
+
if !match?(file_structures[counter],search_structure)
|
|
116
|
+
if (counter != 0) && (file_structures[counter-1] =~ /\+/) && match?(file_structures[counter-1],search_structure)
|
|
117
|
+
counter = counter - 1
|
|
118
|
+
else
|
|
119
|
+
return false
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
counter = counter + 1
|
|
123
|
+
end
|
|
124
|
+
return false if counter != file_structures.length
|
|
125
|
+
end
|
|
126
|
+
return true
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# This method implements the match between a species'
|
|
130
|
+
# structure and a structure found in the mapping file.
|
|
131
|
+
# It is called from the +match_species+ method. It first
|
|
132
|
+
# checks for a pattern match, followed by a match of the
|
|
133
|
+
# dimensions. The method returns either true or false.
|
|
134
|
+
# TODO: Complete the matching (N-dimensional).
|
|
135
|
+
def match?(file,search)
|
|
136
|
+
if (file =~ /#{search.pattern}/)
|
|
137
|
+
condition = true
|
|
138
|
+
|
|
139
|
+
# Check for parameters
|
|
140
|
+
if file.split('(').length == 2
|
|
141
|
+
parameters = file.split('(')[1].split(')')[0]
|
|
142
|
+
if (parameters == 'D') ||
|
|
143
|
+
((parameters == 'N') && (search.parameters.length == 1)) ||
|
|
144
|
+
((parameters == 'N,N') && (search.parameters.length == 2)) ||
|
|
145
|
+
((parameters == 'N,1') && (search.parameters.length == 2) && simplify(sum(search.parameters[1])) == '1') ||
|
|
146
|
+
((parameters == '1,N') && (search.parameters.length == 2) && simplify(sum(search.parameters[0])) == '1') ||
|
|
147
|
+
((parameters == simplify(search.parameters.map { |r| sum(r) }.join(','))))
|
|
148
|
+
condition = condition && true
|
|
149
|
+
else
|
|
150
|
+
condition = false
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Check for dimensions
|
|
155
|
+
dimensions = file.split(PIPE)[0].strip
|
|
156
|
+
if (dimensions == 'D') ||
|
|
157
|
+
((dimensions == 'N') && (search.dimensions.length == 1)) ||
|
|
158
|
+
((dimensions == 'N,N') && (search.dimensions.length == 2)) ||
|
|
159
|
+
((dimensions == simplify(search.dimensions.map { |r| sum(r) }.join(','))))
|
|
160
|
+
condition = condition && true
|
|
161
|
+
else
|
|
162
|
+
condition = false
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Return
|
|
166
|
+
return true if condition == true
|
|
167
|
+
end
|
|
168
|
+
return false
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Method to verify whether this species is shared-based
|
|
172
|
+
# or not. The method either returns true (if 'shared' is
|
|
173
|
+
# included in the input or output) or false (if not).
|
|
174
|
+
def shared?
|
|
175
|
+
(@name =~ /shared/)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# This method verifies if the species dimensions match
|
|
179
|
+
# with its parameters in terms of number of dimensions.
|
|
180
|
+
def verify_species
|
|
181
|
+
DIRECTIONS.each do |direction|
|
|
182
|
+
structures(direction).each do |structure|
|
|
183
|
+
if (structure.has_parameter?) && (structure.dimensions.length != structure.parameters.length)
|
|
184
|
+
puts WARNING+'Parameter dimension mismatch: '+structure.parameters.inspect+' versus '+structure.dimensions.inspect
|
|
185
|
+
end
|
|
186
|
+
structure.dimensions.each do |dimension|
|
|
187
|
+
puts WARNING+'Negative range given: '+dimension.inspect if (simplify(sum(dimension)).to_i < 1) && !(sum(dimension) =~ /[a-zA-Z]/)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
end
|
|
196
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
|
|
2
|
+
module Bones
|
|
3
|
+
# This class represents a single structure in a species.
|
|
4
|
+
# Such a structure is a single input or output 'structure'.
|
|
5
|
+
# Stuctures can be set as part of array variables. Examples
|
|
6
|
+
# of structures are given below:
|
|
7
|
+
# 0:9|element
|
|
8
|
+
# 0:0|shared
|
|
9
|
+
# 0:31,0:31|neighbourhood(-1:1,-1:1)
|
|
10
|
+
# 0:99,0:9|chunk(0:0,0:9)
|
|
11
|
+
#
|
|
12
|
+
class Structure < Common
|
|
13
|
+
attr_reader :dimensions, :pattern, :parameters
|
|
14
|
+
attr_accessor :name
|
|
15
|
+
|
|
16
|
+
# The structure is initialized by the full name given as
|
|
17
|
+
# a string. It is then analyzed and stored accordingly in
|
|
18
|
+
# a number of class variables.
|
|
19
|
+
def initialize(raw_data)
|
|
20
|
+
data = raw_data.split(PIPE)
|
|
21
|
+
pattern_data = data[1].split('(')
|
|
22
|
+
dimension_data = data[0].split('[')
|
|
23
|
+
@pattern = pattern_data[0].strip
|
|
24
|
+
@name = (dimension_data.length == 2) ? dimension_data[0].strip : ''
|
|
25
|
+
@dimensions = (dimension_data.length == 2) ? dimension_data[1].delete(']').split(DIM_SEP) : dimension_data[0].split(DIM_SEP)
|
|
26
|
+
@parameters = (pattern_data.length > 1) ? pattern_data[1].delete(')').split(DIM_SEP) : []
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# TODO: Implement the reverse function
|
|
30
|
+
def reverse?
|
|
31
|
+
true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Method to find out if the structure has a parameter.
|
|
35
|
+
# This is only the case if it is neighbourhood or chunk
|
|
36
|
+
# based.
|
|
37
|
+
def has_parameter?
|
|
38
|
+
return (@parameters != [])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Method to find out if the structure has a arrayname
|
|
42
|
+
# defined. This is optional for a structure.
|
|
43
|
+
def has_arrayname?
|
|
44
|
+
return (@name != '')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Method to get the start of a range given a dimension 'n'.
|
|
48
|
+
# The method returns the proper simplified result, taking
|
|
49
|
+
# chunk-sizes into account.
|
|
50
|
+
def from_at(n)
|
|
51
|
+
return simplify(from(@dimensions[n]))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Method to get the end of a range given a dimension 'n'.
|
|
55
|
+
# The method returns the proper simplified result, taking
|
|
56
|
+
# chunk-sizes into account.
|
|
57
|
+
def to_at(n)
|
|
58
|
+
return (chunk?) ? simplify('((('+to(@dimensions[n])+'+1)/('+to(@parameters[n])+'+1))-1)') : simplify(to(@dimensions[n]))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Method to verify if a structure is empty or not (e.g. if
|
|
62
|
+
# it is based on the 'void' pattern.
|
|
63
|
+
def empty?
|
|
64
|
+
return @pattern =~ /void/
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Method to check whether a structure is element-based.
|
|
68
|
+
def element?
|
|
69
|
+
return @pattern =~ /element/
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Method to check whether a structure is neighbourhood-based.
|
|
73
|
+
def neighbourhood?
|
|
74
|
+
return @pattern =~ /neighbourhood/
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Method to check whether a structure is chunk-based.
|
|
78
|
+
def chunk?
|
|
79
|
+
return @pattern =~ /chunk/
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Method to check whether a structure is shared-based.
|
|
83
|
+
def shared?
|
|
84
|
+
return @pattern =~ /shared/
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Method to check whether a structure is full-based.
|
|
88
|
+
def full?
|
|
89
|
+
return @pattern =~ /full/
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
|
|
2
|
+
module Bones
|
|
3
|
+
# This class represents individual variables. Variables have a
|
|
4
|
+
# name, a type, a direction and an id. They might also have an
|
|
5
|
+
# algorithmic species coupled if they represent an array. The
|
|
6
|
+
# variable type is in AST form and holds information which can
|
|
7
|
+
# be extracted through methods implemented for the Type class.
|
|
8
|
+
#
|
|
9
|
+
# The provided methods are able to obtain information from the
|
|
10
|
+
# variables, such as the number of dimensions and the definition.
|
|
11
|
+
# Other methods query variables for properties, such as whether
|
|
12
|
+
# a variable is an array or not. Several methods should only be
|
|
13
|
+
# executed if the variable is an array - this is not checked
|
|
14
|
+
# within the methods itself.
|
|
15
|
+
class Variable < Common
|
|
16
|
+
attr_reader :name, :type, :factors, :direction
|
|
17
|
+
attr_accessor :species, :size, :guess
|
|
18
|
+
|
|
19
|
+
# Method to initilize the variable class with a name, type
|
|
20
|
+
# and a direction.
|
|
21
|
+
def initialize(name,type,size,direction,id,shared)
|
|
22
|
+
@name = name
|
|
23
|
+
@type = type
|
|
24
|
+
@size = size
|
|
25
|
+
@direction = direction
|
|
26
|
+
@id = id
|
|
27
|
+
@shared = shared
|
|
28
|
+
@guess = false
|
|
29
|
+
@species = nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# This method returns the device name of the variable.
|
|
33
|
+
def device_name
|
|
34
|
+
DEVICE+@name
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# This method returns the 'golden' name of a variable.
|
|
38
|
+
# This is used to generate verification code.
|
|
39
|
+
def golden_name
|
|
40
|
+
GOLDEN + '_' + @name + '_' + @id
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Method to find out whether a variable is used as an in-
|
|
44
|
+
# put. If the current algorithm uses the 'shared' pattern,
|
|
45
|
+
# then the variable must be input only, otherwise it can
|
|
46
|
+
# be both input or inout to be considered input. The return
|
|
47
|
+
# value is boolean.
|
|
48
|
+
def input?
|
|
49
|
+
return (@shared) ? (@direction == INPUT) : (@direction == INPUT || @direction == INOUT)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Method to find out whether a variable is used as an out-
|
|
53
|
+
# put. The variable can be both output or inout to be con-
|
|
54
|
+
# sidered input. The return value is boolean.
|
|
55
|
+
def output?
|
|
56
|
+
return (@direction == OUTPUT || @direction == INOUT)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Method to obtain the type of a variable, omitting any
|
|
60
|
+
# information about arrays or pointers. Examples of out-
|
|
61
|
+
# puts are: +int+, +float+ or +char+. This functionality
|
|
62
|
+
# is implemented as a recursive search in the Type class,
|
|
63
|
+
# since the type is in AST form.
|
|
64
|
+
def type_name
|
|
65
|
+
@type.type_name.to_s
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Method to obtain the number of dimensions of a variable.
|
|
69
|
+
# This method returns a positive integer. The functionality
|
|
70
|
+
# is implemented as a recursive search in the Type class.
|
|
71
|
+
def dimensions
|
|
72
|
+
@type.dimensions
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Method to return the device version of a variable's
|
|
76
|
+
# definition. This includes the variable's type, zero or
|
|
77
|
+
# more stars and the variable's name, all returned as a
|
|
78
|
+
# single string.
|
|
79
|
+
def device_definition
|
|
80
|
+
type_name + device_pointer + ' ' + @name
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Method to obtain the full defintion of a variable. This
|
|
84
|
+
# includes the variable type, the variable name, and the
|
|
85
|
+
# dimensions and/or pointers. Example return values are:
|
|
86
|
+
# int example[10]
|
|
87
|
+
# char **variable
|
|
88
|
+
# unsigned int* example[N]
|
|
89
|
+
# float array[][]
|
|
90
|
+
def definition
|
|
91
|
+
definition_prefix + ' ' + @name + definition_suffix
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# This method returns a star ('*') if the variable is an
|
|
95
|
+
# array or an empty string if it is not. It will not be
|
|
96
|
+
# able to return more than a single star, as device varia-
|
|
97
|
+
# bles are assumed to be flattened.
|
|
98
|
+
def device_pointer
|
|
99
|
+
(@type.array_or_pointer?) ? '*' : ''
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Method to flatten an array into a one dimensional array.
|
|
103
|
+
# If an array has multiple dimensions, the method will
|
|
104
|
+
# return a '[0]' for each additional dimension. This method
|
|
105
|
+
# assumes that the variable is an array.
|
|
106
|
+
def flatten
|
|
107
|
+
''+'[0]'*(dimensions-1)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# This method returns the initialization code for a varia-
|
|
111
|
+
# ble, formatted as a string. This is used to generate the
|
|
112
|
+
# verification code.
|
|
113
|
+
def initialization
|
|
114
|
+
(dynamic?) ? " = (#{definition_prefix})malloc(#{@size.join('*')}*sizeof(#{type_name}));"+NL : ';'+NL
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# This method detects whether the variable is dynamically
|
|
118
|
+
# allocated or not. It returns either true or false.
|
|
119
|
+
def dynamic?
|
|
120
|
+
(definition_prefix.count('*') > 0)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Method to return an array of multiplication factors for
|
|
124
|
+
# multi-dimensional arrays that need to be flattened. For
|
|
125
|
+
# every dimension, one factor is generated.
|
|
126
|
+
def set_factors
|
|
127
|
+
raise_error("Species dimensions (#{@species.dimensions.length}) and array dimensions (#{@size.length}) mismatch for array '#{@name}'") if @species.dimensions.length != @size.length
|
|
128
|
+
sizes, @factors = [], []
|
|
129
|
+
@species.dimensions.each_with_index do |dimension,num_dimension|
|
|
130
|
+
(sizes.empty?) ? @factors.push('') : @factors.push('*'+sizes.join('*'))
|
|
131
|
+
sizes.push(simplify(@size[dimensions-num_dimension-1]))
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Method to return the full flattened address.
|
|
136
|
+
def flatindex
|
|
137
|
+
indices = []
|
|
138
|
+
@species.dimensions.each_with_index do |dimension,num_dimension|
|
|
139
|
+
index_reverse = !(@species.reverse?) ? num_dimension : @species.dimensions.length-num_dimension-1 # FIXME: REVERSED
|
|
140
|
+
if (from(dimension) != to(dimension))
|
|
141
|
+
data = "#{GLOBAL_ID}_#{index_reverse}"
|
|
142
|
+
else
|
|
143
|
+
data = from(dimension)
|
|
144
|
+
end
|
|
145
|
+
indices.push(data + @factors[index_reverse])
|
|
146
|
+
end
|
|
147
|
+
return indices.join(' + ')
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Start of the class's private methods.
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
# Method to obtain the prefix of a variable's definition,
|
|
154
|
+
# formatted as a string. The string contains the variable's
|
|
155
|
+
# type and zero or more stars ('*').
|
|
156
|
+
def definition_prefix
|
|
157
|
+
@type.to_s.partition('[')[0].strip
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Method to obtain the suffix of a variable's definition,
|
|
161
|
+
# formatted as a string. The string is either empty or
|
|
162
|
+
# contains one or more brackets (e.g. [N][M] or [10]).
|
|
163
|
+
def definition_suffix
|
|
164
|
+
@type.to_s.partition('[')[1]+@type.to_s.partition('[')[2]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|