1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.numerics.atomic;
39
40 import edu.rit.pj.IntegerForLoop;
41 import edu.rit.pj.ParallelRegion;
42 import edu.rit.pj.ParallelTeam;
43 import java.util.Arrays;
44 import java.util.logging.Level;
45 import java.util.logging.Logger;
46
47
48
49
50
51
52
53
54 public class MultiDoubleArray implements AtomicDoubleArray {
55
56 private static final Logger logger = Logger.getLogger(MultiDoubleArray.class.getName());
57
58 private final int threadCount;
59
60
61
62
63
64
65 private final double[][] array;
66
67 private int size;
68
69
70
71
72
73
74
75 public MultiDoubleArray(int threadCount, int arraySize) {
76 this.size = arraySize;
77 array = new double[threadCount][arraySize];
78 this.threadCount = threadCount;
79 }
80
81
82
83
84 @Override
85 public void add(int threadID, int index, double value) {
86 array[threadID][index] += value;
87 }
88
89
90
91
92 @Override
93 public void alloc(int arraySize) {
94 this.size = arraySize;
95 for (int i = 0; i < threadCount; i++) {
96 if (array[i].length < arraySize) {
97 array[i] = new double[arraySize];
98 }
99 }
100 }
101
102
103
104
105 @Override
106 public double get(int index) {
107 return array[0][index];
108 }
109
110
111
112
113
114
115
116 @Override
117 public void reduce(int lb, int ub) {
118 double[] mainArray = array[0];
119 for (int t = 1; t < threadCount; t++) {
120 double[] threadArray = array[t];
121 reduceFromThreads(mainArray, threadArray, lb, ub);
122 }
123 }
124
125
126
127
128
129
130
131
132
133 private void reduceFromThreads(double[] mainArray, double[] threadArray, int lb, int ub) {
134 for (int i = lb; i <= ub; i++) {
135 mainArray[i] += threadArray[i];
136 }
137 }
138
139
140
141
142 @Override
143 public void reduce(ParallelTeam parallelTeam, int lb, int ub) {
144 try {
145 parallelTeam.execute(new ParallelRegion() {
146 @Override
147 public void run() throws Exception {
148 execute(lb, ub, new IntegerForLoop() {
149 @Override
150 public void run(int first, int last) {
151 reduce(first, last);
152 }
153 });
154 }
155 });
156 } catch (Exception e) {
157 logger.log(Level.WARNING, "Exception reducing a MultiDoubleArray", e);
158 }
159 }
160
161
162
163
164 @Override
165 public void reset(int threadID, int lb, int ub) {
166 Arrays.fill(array[threadID], 0.0);
167 }
168
169
170
171
172 @Override
173 public void reset(ParallelTeam parallelTeam, int lb, int ub) {
174 try {
175 parallelTeam.execute(new ParallelRegion() {
176 @Override
177 public void run() throws Exception {
178 execute(0, threadCount - 1, new IntegerForLoop() {
179 @Override
180 public void run(int first, int last) {
181 for (int i = first; i <= last; i++) {
182 reset(i, lb, ub);
183 }
184 }
185 });
186 }
187 });
188 } catch (Exception e) {
189 logger.log(Level.WARNING, "Exception resetting a MultiDoubleArray", e);
190 }
191 }
192
193
194
195
196 @Override
197 public void scale(int threadID, int index, double value) {
198 array[threadID][index] *= value;
199 }
200
201
202
203
204 @Override
205 public void set(int threadID, int index, double value) {
206 array[threadID][index] = value;
207 }
208
209
210
211
212 @Override
213 public int size() {
214 return size;
215 }
216
217
218
219
220 @Override
221 public void sub(int threadID, int index, double value) {
222 array[threadID][index] -= value;
223 }
224 }