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 nThreads, int size) {
76 this.size = size;
77 array = new double[nThreads][size];
78 threadCount = nThreads;
79 }
80
81
82 @Override
83 public void add(int threadID, int index, double value) {
84 array[threadID][index] += value;
85 }
86
87
88 @Override
89 public void alloc(int size) {
90 this.size = size;
91 for (int i = 0; i < threadCount; i++) {
92 if (array[i].length < size) {
93 array[i] = new double[size];
94 }
95 }
96 }
97
98
99
100
101 @Override
102 public double get(int index) {
103 return array[0][index];
104 }
105
106
107
108
109
110
111 @Override
112 public void reduce(int lb, int ub) {
113 double[] gx = array[0];
114 for (int t = 1; t < threadCount; t++) {
115 double[] gxt = array[t];
116 for (int i = lb; i <= ub; i++) {
117 gx[i] += gxt[i];
118 }
119 }
120 }
121
122
123
124
125
126
127 @Override
128 public void reduce(ParallelTeam parallelTeam, int lb, int ub) {
129 try {
130 parallelTeam.execute(
131 new ParallelRegion() {
132 @Override
133 public void run() throws Exception {
134 execute(
135 lb,
136 ub,
137 new IntegerForLoop() {
138 @Override
139 public void run(int first, int last) {
140 reduce(first, last);
141 }
142 });
143 }
144 });
145 } catch (Exception e) {
146 logger.log(Level.WARNING, " Exception reducing an MultiDoubleArray", e);
147 }
148 }
149
150
151
152
153 @Override
154 public void reset(int threadID, int lb, int ub) {
155
156 Arrays.fill(array[threadID], 0.0);
157
158 }
159
160
161
162
163 @Override
164 public void reset(ParallelTeam parallelTeam, int lb, int ub) {
165 try {
166 parallelTeam.execute(
167 new ParallelRegion() {
168 @Override
169 public void run() throws Exception {
170 execute(
171 0,
172 threadCount - 1,
173 new IntegerForLoop() {
174 @Override
175 public void run(int first, int last) {
176 for (int i = first; i <= last; i++) {
177 reset(i, lb, ub);
178 }
179 }
180 });
181 }
182 });
183 } catch (Exception e) {
184 logger.log(Level.WARNING, " Exception resetting an MultiDoubleArray", e);
185 }
186 }
187
188
189 @Override
190 public void scale(int threadID, int index, double value) {
191 array[threadID][index] *= value;
192 }
193
194
195 @Override
196 public void set(int threadID, int index, double value) {
197 array[threadID][index] = value;
198 }
199
200
201 @Override
202 public int size() {
203 return size;
204 }
205
206
207 @Override
208 public void sub(int threadID, int index, double value) {
209 array[threadID][index] -= value;
210 }
211 }