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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 caltinay 3096
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 jfenwick 3259 #if HAVE_MPI
45 caltinay 3096 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 jfenwick 3259 #if HAVE_MPI
92 caltinay 3096 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 jfenwick 3259 #if HAVE_MPI
172 caltinay 3096 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 caltinay 3128 void publishData(EscriptDataset_ptr dataset)
203 caltinay 3096 {
204     #ifdef USE_VISIT
205     int visitState = 0, err = 0;
206    
207     if (connected) {
208 caltinay 3128 visitData->publishData(dataset);
209     visitData->setSimulationStatus(runFlag);
210 caltinay 3096 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 jfenwick 3259 #if HAVE_MPI
221 caltinay 3128 MPI_Bcast(&visitState, 1, MPI_INT, 0, dataset->getMPIComm());
222 caltinay 3096 #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 caltinay 3128 visitData->publishData(dataset);
238     visitData->setSimulationStatus(runFlag);
239 caltinay 3096 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