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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3259 - (show annotations)
Mon Oct 11 01:48:14 2010 UTC (8 years, 8 months ago) by jfenwick
File size: 8364 byte(s)
Merging dudley and scons updates from branches

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

  ViewVC Help
Powered by ViewVC 1.1.26