/[escript]/trunk/weipa/src/VisItControl.cpp
ViewVC logotype

Contents of /trunk/weipa/src/VisItControl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6651 - (show annotations)
Wed Feb 7 02:12:08 2018 UTC (18 months, 2 weeks ago) by jfenwick
File size: 9008 byte(s)
Make everyone sad by touching all the files

Copyright dates update

1
2 /*****************************************************************************
3 *
4 * Copyright (c) 2003-2018 by The University of Queensland
5 * http://www.uq.edu.au
6 *
7 * Primary Business: Queensland, Australia
8 * Licensed under the Apache License, version 2.0
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 * Development 2012-2013 by School of Earth Sciences
13 * Development from 2014 by Centre for Geoscience Computing (GeoComp)
14 *
15 *****************************************************************************/
16
17 #include <weipa/VisItControl.h>
18 #include <weipa/EscriptDataset.h>
19
20 #ifdef USE_VISIT
21 #include <weipa/VisItData.h>
22
23 #include <VisItControlInterface_V2.h>
24
25 #include <cstring>
26 #include <iostream>
27
28 #define VISIT_COMMAND_PROCESS 0
29 #define VISIT_COMMAND_SUCCESS 1
30 #define VISIT_COMMAND_FAILURE 2
31 #endif
32
33 namespace weipa {
34
35 namespace VisItControl {
36
37 bool initialized = false;
38
39 #ifdef USE_VISIT
40
41 weipa::VisItData_ptr visitData(new VisItData());
42 int mpiRank = 0;
43 int mpiSize = 1;
44 bool runFlag = true;
45 bool connected = false;
46
47 // Helper function for processVisItCommand()
48 static void broadcastSlaveCommand(int* command)
49 {
50 #if WEIPA_HAVE_MPI
51 MPI_Bcast(command, 1, MPI_INT, 0, MPI_COMM_WORLD);
52 #endif
53 }
54
55 // Processes commands from the VisIt viewer on all processors
56 static int processVisItCommand()
57 {
58 if (mpiRank == 0) {
59 int success = VisItProcessEngineCommand();
60 int command;
61
62 if (success) {
63 command = VISIT_COMMAND_SUCCESS;
64 broadcastSlaveCommand(&command);
65 return 1;
66 } else {
67 command = VISIT_COMMAND_FAILURE;
68 broadcastSlaveCommand(&command);
69 return 0;
70 }
71 } else {
72 // Note: Only through the SlaveProcessCallback() function
73 // can rank 0 send VISIT_COMMAND_PROCESS to non-zero ranks
74 while (1) {
75 int command=VISIT_COMMAND_SUCCESS;
76 broadcastSlaveCommand(&command);
77 switch (command) {
78 case VISIT_COMMAND_PROCESS:
79 VisItProcessEngineCommand();
80 break;
81 case VISIT_COMMAND_SUCCESS:
82 return 1;
83 case VISIT_COMMAND_FAILURE:
84 return 0;
85 }
86 }
87 }
88 }
89
90 // Callback involved in command communication
91 static void slaveProcessCallback()
92 {
93 int command = VISIT_COMMAND_PROCESS;
94 broadcastSlaveCommand(&command);
95 }
96
97 #if WEIPA_HAVE_MPI
98 static int broadcastIntCallback(int* value, int sender)
99 {
100 return MPI_Bcast(value, 1, MPI_INT, sender, MPI_COMM_WORLD);
101 }
102
103 static int broadcastStringCallback(char* str, int len, int sender)
104 {
105 return MPI_Bcast(str, len, MPI_CHAR, sender, MPI_COMM_WORLD);
106 }
107 #endif
108
109 // Processes a control command
110 static void controlCommandCallback(const char* cmd, const char* sdata,
111 void* cb_data)
112 {
113 #ifdef _DEBUG
114 std::cout << "Control Command: " << cmd << std::endl;
115 #endif
116
117 if (strstr(cmd, "pause")) {
118 runFlag = !runFlag;
119 } else if (strstr(cmd, "update_plots")) {
120 VisItUpdatePlots();
121 }
122 }
123
124 // Callback that returns metadata for this dataset
125 visit_handle VisItGetMetaData(void* cbdata)
126 {
127 #ifdef _DEBUG
128 std::cout << "VisItGetMetaData()" << std::endl;
129 #endif
130 return visitData->getSimMetaData();
131 }
132
133 // Callback that returns the domain list for this dataset
134 visit_handle VisItGetDomainList(const char* name, void* cbdata)
135 {
136 #ifdef _DEBUG
137 std::cout << "VisItGetDomainList(" << name << ")" << std::endl;
138 #endif
139 return visitData->getDomainList();
140 }
141
142 // Callback that returns mesh data
143 visit_handle VisItGetMesh(int domain, const char* name, void* cbdata)
144 {
145 #ifdef _DEBUG
146 std::cout << "VisItGetMesh(" << domain << ", '" << name << "')" << std::endl;
147 #endif
148 if (mpiRank != domain) {
149 #ifdef _DEBUG
150 std::cout << "I don't have data for domain " << domain << std::endl;
151 #endif
152 return VISIT_INVALID_HANDLE;
153 }
154 return visitData->getMesh(name);
155 }
156
157 // Callback that returns variable data
158 visit_handle VisItGetVariable(int domain, const char* name, void* cbdata)
159 {
160 #ifdef _DEBUG
161 std::cout << "VisItGetVariable(" << domain << ", '" << name << "')" << std::endl;
162 #endif
163 if (mpiRank != domain) {
164 #ifdef _DEBUG
165 std::cout << "I don't have data for domain " << domain << std::endl;
166 #endif
167 return VISIT_INVALID_HANDLE;
168 }
169 return visitData->getVariable(name);
170 }
171
172 #endif // USE_VISIT
173
174 /**************************************************************************************************/
175
176 // Initializes libsim and the communication to VisIt
177 bool initialize(const std::string& simFile, const std::string& comment)
178 {
179 #ifdef USE_VISIT
180 if (connected) {
181 VisItDisconnect();
182 connected = false;
183 std::cout << "VisIt client disconnected." << std::endl;
184 }
185
186 if (!initialized) {
187 //VisItOpenTraceFile("/tmp/simV2trace.txt");
188 if (!VisItSetupEnvironment()) {
189 std::cerr << "Error setting up VisIt environment" << std::endl;
190 return false;
191 }
192
193 #if WEIPA_HAVE_MPI
194 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
195 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
196
197 // Install callback functions for global communication
198 VisItSetBroadcastIntFunction(broadcastIntCallback);
199 VisItSetBroadcastStringFunction(broadcastStringCallback);
200
201 // Tell libsim whether the simulation is parallel
202 VisItSetParallel(mpiSize > 1);
203 VisItSetParallelRank(mpiRank);
204 #endif
205 std::vector<std::string> cmdNames;
206 cmdNames.push_back("pause");
207 cmdNames.push_back("update_plots");
208 visitData->setCommandNames(cmdNames);
209 initialized = true;
210 }
211
212 if (mpiRank == 0) {
213 std::string filename(simFile);
214 if (filename.rfind(".sim2") != filename.length()-5) {
215 filename += ".sim2";
216 }
217 VisItInitializeSocketAndDumpSimFile("escript", comment.c_str(),
218 NULL, NULL, NULL, filename.c_str());
219 }
220 #endif // USE_VISIT
221 return initialized;
222 }
223
224 // Main entry point that checks for client input and publishes new data
225 bool publishData(EscriptDataset_ptr dataset)
226 {
227 if (!initialized || dataset->getConvertedDomain().size()==0) {
228 return false;
229 }
230
231 #ifdef USE_VISIT
232 int visitState = 0, err = 0;
233
234 if (connected) {
235 visitData->publishData(dataset);
236 visitData->setSimulationStatus(runFlag);
237 VisItTimeStepChanged();
238 }
239
240 do {
241 // Get input from VisIt or timeout so the simulation can continue
242 if (mpiRank == 0) {
243 int blocking = (connected && !runFlag) ? 1 : 0;
244 visitState = VisItDetectInput(blocking, -1);
245 }
246
247 #if WEIPA_HAVE_MPI
248 MPI_Bcast(&visitState, 1, MPI_INT, 0, dataset->getMPIComm());
249 #endif
250
251 // visitState values:
252 // 0: there was no input from VisIt so nothing to do
253 // 1: VisIt is trying to connect
254 // 2: VisIt sent a command which should be processed
255 // < 0: an unrecoverable error occurred
256 if (visitState < 0) {
257 std::cerr << "VisItControl: Can't recover from error! State="
258 << visitState << std::endl; fflush(stderr);
259 err = 1;
260 } else if (visitState == 1) {
261 if (VisItAttemptToCompleteConnection() == VISIT_OKAY) {
262 std::cout << "VisIt client connected." << std::endl;
263 // publish latest data
264 visitData->publishData(dataset);
265 visitData->setSimulationStatus(runFlag);
266 void* cbdata = NULL;
267 VisItSetCommandCallback(controlCommandCallback, cbdata);
268 VisItSetSlaveProcessCallback(slaveProcessCallback);
269
270 VisItSetGetMetaData(VisItGetMetaData, cbdata);
271 VisItSetGetMesh(VisItGetMesh, cbdata);
272 VisItSetGetVariable(VisItGetVariable, cbdata);
273 VisItSetGetDomainList(VisItGetDomainList, cbdata);
274 VisItTimeStepChanged();
275 connected = true;
276 } else {
277 char *errorString = VisItGetLastError();
278 if (mpiRank == 0) {
279 if (strlen(errorString) > 0) {
280 std::cerr << errorString << std::endl;
281 } else {
282 std::cerr << "VisIt failed to connect successfully."
283 << std::endl;
284 }
285 }
286 free(errorString);
287 }
288 } else if (visitState == 2) {
289 if (!processVisItCommand()) {
290 VisItDisconnect();
291 connected = false;
292 std::cout << "VisIt client disconnected." << std::endl;
293 }
294 }
295 } while (visitState != 0);
296
297 return err==0;
298 #else // USE_VISIT
299
300 return false;
301 #endif
302 }
303
304 } // namespace VisItControl
305
306 } // namespace weipa
307

  ViewVC Help
Powered by ViewVC 1.1.26