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.potential.commands;
39
40 import ffx.numerics.Potential;
41 import ffx.potential.ForceFieldEnergy;
42 import ffx.potential.cli.PotentialCommand;
43 import ffx.potential.cli.TimerOptions;
44 import ffx.utilities.FFXBinding;
45 import picocli.CommandLine.Command;
46 import picocli.CommandLine.Mixin;
47 import picocli.CommandLine.Parameters;
48
49 import java.util.ArrayList;
50 import java.util.Collections;
51 import java.util.List;
52
53 import static java.lang.String.format;
54 import static org.apache.commons.math3.util.FastMath.sqrt;
55
56
57
58
59
60
61
62 @Command(name = "Timer", description = " Time energy evaluations.")
63 public class Timer extends PotentialCommand {
64
65
66 @Mixin
67 private TimerOptions timer = new TimerOptions();
68
69
70 @Parameters(arity = "1", paramLabel = "file",
71 description = "The atomic coordinate file in PDB or XYZ format.")
72 private String filename = null;
73
74 private ForceFieldEnergy energy = null;
75
76 public Timer() { super(); }
77 public Timer(FFXBinding binding) { super(binding); }
78 public Timer(String[] args) { super(args); }
79
80 @Override
81 public Timer run() {
82
83 if (!init()) {
84 return this;
85 }
86
87
88 if (timer.getThreads() > 0) {
89 System.setProperty("pj.nt", Integer.toString(timer.getThreads()));
90 }
91
92
93 activeAssembly = getActiveAssembly(filename);
94 if (activeAssembly == null) {
95 logger.info(helpString());
96 return this;
97 }
98
99
100 filename = activeAssembly.getFile().getAbsolutePath();
101
102 if (timer.getNoGradient()) {
103 logger.info("\n Timing energy for " + filename);
104 } else {
105 logger.info("\n Timing energy and gradient for " + filename);
106 }
107
108 int nEvals = timer.getIterations();
109
110 energy = activeAssembly.getPotentialEnergy();
111
112 long minTime = Long.MAX_VALUE;
113 double sumTime2 = 0.0;
114 int halfnEvals = (nEvals % 2 == 1) ? (nEvals / 2) : (nEvals / 2) - 1;
115 for (int i = 0; i < nEvals; i++) {
116 long time = -System.nanoTime();
117 double e = energy.energy(!timer.getNoGradient(), timer.getVerbose());
118 time += System.nanoTime();
119 if (!timer.getVerbose()) {
120 logger.info(format(" %4d Energy %16.8f in %6.3f (sec)", i, e, time * 1.0E-9));
121 }
122 minTime = Math.min(time, minTime);
123 if (i >= (nEvals / 2)) {
124 double time2 = time * 1.0E-9;
125 sumTime2 += (time2 * time2);
126 }
127 }
128
129 ++halfnEvals;
130 double rmsTime = sqrt(sumTime2 / halfnEvals);
131 logger.info(format("\n Minimum time: %6.3f (sec)", minTime * 1.0E-9));
132 logger.info(format(" RMS time (latter half): %6.3f (sec)", rmsTime));
133
134 return this;
135 }
136
137 @Override
138 public List<Potential> getPotentials() {
139 if (energy == null) {
140 return Collections.emptyList();
141 } else {
142 List<Potential> list = new ArrayList<>(1);
143 list.add(energy);
144 return list;
145 }
146 }
147 }