1 // ******************************************************************************
2 //
3 // Title: Force Field X.
4 // Description: Force Field X - Software for Molecular Biophysics.
5 // Copyright: Copyright (c) Michael J. Schnieders 2001-2025.
6 //
7 // This file is part of Force Field X.
8 //
9 // Force Field X is free software; you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License version 3 as published by
11 // the Free Software Foundation.
12 //
13 // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 // details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20 // Place, Suite 330, Boston, MA 02111-1307 USA
21 //
22 // Linking this library statically or dynamically with other modules is making a
23 // combined work based on this library. Thus, the terms and conditions of the
24 // GNU General Public License cover the whole combination.
25 //
26 // As a special exception, the copyright holders of this library give you
27 // permission to link this library with independent modules to produce an
28 // executable, regardless of the license terms of these independent modules, and
29 // to copy and distribute the resulting executable under terms of your choice,
30 // provided that you also meet, for each linked independent module, the terms
31 // and conditions of the license of that module. An independent module is a
32 // module which is not derived from or based on this library. If you modify this
33 // library, you may extend this exception to your version of the library, but
34 // you are not obligated to do so. If you do not wish to do so, delete this
35 // exception statement from your version.
36 //
37 // ******************************************************************************
38 package ffx.potential.bonded;
39
40 import org.jogamp.java3d.BranchGroup;
41
42 import javax.swing.tree.TreeNode;
43 import java.io.Serial;
44 import java.util.Enumeration;
45 import java.util.List;
46 import java.util.Objects;
47 import java.util.logging.Logger;
48
49 /**
50 * The ROLSP class is used for Proof-Of-Concept Parallel Recusive Over Length Scales (ROLS) Methods
51 * (currently only on shared memory systems). Simply inserting a ParallelMSM node into the
52 * Hierarchy causes a seperate thread of execution to be created for all operations on nodes below
53 * the ROLSP node. This is very preliminary code, but a useful concept for parallelizing ROLS in
54 * ffe.lang.
55 *
56 * @author Michael J. Schnieders
57 * @since 1.0
58 */
59 public class ROLSP extends MSNode implements ROLS, Runnable {
60
61 @Serial
62 private static final long serialVersionUID = 1L;
63
64 private static final Logger logger = Logger.getLogger(ROLSP.class.getName());
65 /** Constant <code>GO_PARALLEL=false</code> */
66 public static boolean GO_PARALLEL;
67 /** Constant <code>parallelNotDone=0</code> */
68 public static int parallelNotDone = 0;
69
70 static {
71 try {
72 GO_PARALLEL = Boolean.parseBoolean(System.getProperty("ffx.lang.parallel", "false"));
73 } catch (Exception e) {
74 GO_PARALLEL = false;
75 }
76 }
77
78 private PARALLELMETHOD parallelMethod = PARALLELMETHOD.NONE;
79 private long startTime = 0;
80 private long threadTime = 0;
81 private RendererCache.ViewModel viewModel = null;
82 private List<BranchGroup> newShapes = null;
83
84 /** Constructor for ROLSP. */
85 public ROLSP() {
86 super("Parallel Node");
87 }
88
89 /**
90 * {@inheritDoc}
91 *
92 * <p>Overidden equals method.
93 */
94 @Override
95 public boolean equals(Object o) {
96 return this == o;
97 }
98
99 /** {@inheritDoc} */
100 @Override
101 public int hashCode() {
102 MSNode child = (MSNode) getChildAt(0);
103 if (child == null) {
104 return Objects.hash("none");
105 }
106 return Objects.hash(child.hashCode());
107 }
108
109 /** {@inheritDoc} */
110 @Override
111 public void run() {
112 switch (parallelMethod) {
113 case SETVIEW:
114 setView(viewModel, newShapes);
115 break;
116 default:
117 return;
118 }
119 threadTime = System.currentTimeMillis() - startTime;
120 logger.info("Start Time: " + startTime + " Total Time: " + threadTime);
121 parallelNotDone--;
122 }
123
124 /** {@inheritDoc} */
125 @Override
126 public void setView(RendererCache.ViewModel viewModel, List<BranchGroup> newShapes) {
127 // Set Up the Parallel setView Method
128 if (parallelMethod == PARALLELMETHOD.NONE) {
129 startTime = System.currentTimeMillis();
130 this.viewModel = viewModel;
131 this.newShapes = newShapes;
132 parallelMethod = PARALLELMETHOD.SETVIEW;
133 Thread thread = new Thread(this);
134 thread.setName(getParent().toString() + ": Parallel setView MSM");
135 thread.setPriority(Thread.MAX_PRIORITY);
136 parallelNotDone++;
137 thread.start();
138 } else if (parallelMethod == PARALLELMETHOD.SETVIEW) {
139 // setView has been called from within the 'run' method of the
140 // "setView" thread
141 for (Enumeration<TreeNode> e = children(); e.hasMoreElements(); ) {
142 MSNode node = (MSNode) e.nextElement();
143 node.setView(viewModel, newShapes);
144 }
145 parallelMethod = PARALLELMETHOD.NONE;
146 } else {
147 logger.info(" Parallel setView method called by: " + parallelMethod);
148 }
149 }
150
151 /** {@inheritDoc} */
152 @Override
153 public String toString() {
154 if (threadTime != 0) {
155 return "Parallel Node " + threadTime + " (msec)";
156 }
157 return "Parallel Node";
158 }
159
160 public enum PARALLELMETHOD {
161 SETVIEW,
162 NONE
163 }
164 }