IR_VisItMainloop.scala 6.3 KB
Newer Older
1
2
3
4
5
6
7
8
package exastencils.visualization.ir.visit

import scala.collection.mutable.ListBuffer

import exastencils.base.ir.IR_ImplicitConversion._
import exastencils.base.ir._
import exastencils.config._
import exastencils.parallelization.api.mpi._
9
import exastencils.visualization.ir.visit.IR_VisItGlobals._
10

11
case class IR_VisItMainloop() extends IR_VisItFuturePlainFunction {
12
13
14
15
16
17
18
19
20

  import exastencils.visualization.ir.visit.IR_VisItUtil._

  override def generateFct() : IR_PlainFunction = {

    val fctBody = ListBuffer[IR_Statement]()
    val whileBody = ListBuffer[IR_Statement]()
    val consoleInputBody = ListBuffer[IR_Statement]()

21
22
23
    val blocking = IR_VariableAccess("blocking", IR_BooleanDatatype)
    val visitInput = IR_VariableAccess("visit_input", IR_IntegerDatatype)
    val command = IR_VariableAccess("command", IR_PointerDatatype(IR_CharDatatype))
24
25
26

    val registerCallbackFcts = ListBuffer[IR_Statement]()
    val procEngineCommandFct = if (Knowledge.mpi_enabled) {
Richard Angersbach's avatar
Richard Angersbach committed
27
      callExtFunction("ProcessVisItCommand")
28
    } else {
Richard Angersbach's avatar
Richard Angersbach committed
29
      callExtFunction("VisItProcessEngineCommand")
30
31
32
33
    }

    // callback functions to register
    if (Knowledge.mpi_enabled) {
Richard Angersbach's avatar
Richard Angersbach committed
34
35
      registerCallbackFcts += callExtFunction("VisItSetSlaveProcessCallback", IR_Native("slave_process_callback"))
      registerCallbackFcts += callExtFunction("VisItSetGetDomainList", IR_Native("SimGetDomainList"), nullptr)
36
    }
Richard Angersbach's avatar
Richard Angersbach committed
37
38
    registerCallbackFcts += callExtFunction("VisItSetGetMetaData", IR_Native("SimGetMetaData"), nullptr)
    registerCallbackFcts += callExtFunction("VisItSetGetMesh", IR_Native("SimGetMesh"), nullptr)
39
    if (Knowledge.dimensionality > 1) { // 1d variables are pictured as meshes
Richard Angersbach's avatar
Richard Angersbach committed
40
      registerCallbackFcts += callExtFunction("VisItSetGetVariable", IR_Native("SimGetVariable"), nullptr)
41
42
    }

Richard Angersbach's avatar
Richard Angersbach committed
43
    registerCallbackFcts += callExtFunction("VisItSetCommandCallback", IR_Native("ControlCommandCallback"), nullptr)
44
45
46

    // body of the while loop containing the switch statement
    whileBody += IR_IfCondition(
47
      simDone,
48
49
      IR_Break()
    )
50
    whileBody += IR_VariableDeclaration(blocking, IR_TernaryCondition(runMode, IR_BooleanConstant(false), IR_BooleanConstant(true)))
51
52
53
54
55
56
57
58

    val funcRef = if (Platform.targetCompiler == "MSVC") {
      IR_ExternalFunctionReference("_fileno")
    } else {
      IR_ExternalFunctionReference("fileno")
    }

    if (Knowledge.mpi_enabled) {
59
      whileBody += IR_VariableDeclaration(visitInput)
60
61
      whileBody += IR_IfCondition(
        MPI_IsRootProc.apply(),
Richard Angersbach's avatar
Richard Angersbach committed
62
        IR_Assignment(visitInput, callExtFunction("VisItDetectInput", blocking, IR_FunctionCall(funcRef, IR_Native("stdin"))))
63
      )
Richard Angersbach's avatar
Richard Angersbach committed
64
      whileBody += callExtFunction("MPI_Bcast", IR_AddressOf(visitInput), IR_IntegerConstant(1), IR_Native("MPI_INT"), IR_IntegerConstant(0), Knowledge.mpi_defaultCommunicator)
65
    } else {
Richard Angersbach's avatar
Richard Angersbach committed
66
      whileBody += IR_VariableDeclaration(visitInput, callExtFunction("VisItDetectInput", blocking, IR_FunctionCall(funcRef, IR_Native("stdin"))))
67
68
69
    }

    // body of the third case of the switch statement
70
71
    consoleInputBody += IR_VariableDeclaration(command, nullptr)
    consoleInputBody += IR_ArrayAllocation(command, IR_CharDatatype, IR_IntegerConstant(1000))
72
73
74
75
76

    if (Knowledge.mpi_enabled) {
      consoleInputBody += IR_IfCondition(
        MPI_IsRootProc.apply(),
        IR_IfCondition(
Richard Angersbach's avatar
Richard Angersbach committed
77
          callExtFunction("VisItReadConsole", IR_IntegerConstant(1000), command) Neq visitOkay,
78
79
80
          IR_Break()
        )
      )
Richard Angersbach's avatar
Richard Angersbach committed
81
      consoleInputBody += callExtFunction("MPI_Bcast", command, IR_IntegerConstant(1000), IR_Native("MPI_CHAR"), IR_IntegerConstant(0), Knowledge.mpi_defaultCommunicator)
82
83
    } else {
      consoleInputBody += IR_IfCondition(
Richard Angersbach's avatar
Richard Angersbach committed
84
        callExtFunction("VisItReadConsole", IR_IntegerConstant(1000), command) Neq visitOkay,
85
86
87
88
89
        IR_Break()
      )
    }

    // process console inputs
90
    consoleInputBody += IR_VisItCommandHandling(command)
91
92
    // scaling: only used for curvilinear meshes
    if (Knowledge.dimensionality == 1 || Knowledge.dimensionality == 2) {
Richard Angersbach's avatar
Richard Angersbach committed
93
      val strToReal = if (Knowledge.useDblPrecision) "std::stod" else "std::stof"
94
      consoleInputBody += IR_IfCondition(
Richard Angersbach's avatar
Richard Angersbach committed
95
        callExtFunction("strstr", command, IR_StringConstant("scale=")) Neq nullptr,
96
97
        IR_Native(
          s"""|try{
98
              |scale = $strToReal(command+6);
99
100
101
102
103
104
105
106
107
              |} catch (const std::invalid_argument&) {
              |
              |} catch (const std::out_of_range&) {
              |
              |}
          """.stripMargin
        )
      )
    }
108
    consoleInputBody += IR_ArrayFree(command)
109
110

    whileBody += IR_IfCondition(
111
      visitInput < IR_IntegerConstant(0), // error, stop calling VisItDetectInput
112
113
      IR_Return()
    )
114

115
    whileBody += IR_IfCondition(
116
      visitInput EqEq IR_IntegerConstant(0), // VisItDetectInput timed out
117
118
119
      ListBuffer[IR_Statement](
        IR_FunctionCall(IR_LeveledInternalFunctionReference("simulate_timestep", Knowledge.maxLevel, IR_UnitDatatype)),
        IR_IfCondition(
Richard Angersbach's avatar
Richard Angersbach committed
120
          callExtFunction("VisItIsConnected"),
121
          ListBuffer[IR_Statement](
Richard Angersbach's avatar
Richard Angersbach committed
122
            callExtFunction("VisItTimeStepChanged"),
123
            IR_IfCondition(
124
              updatePlots,
Richard Angersbach's avatar
Richard Angersbach committed
125
              callExtFunction("VisItUpdatePlots"))))))
126

127
    whileBody += IR_IfCondition(visitInput EqEq IR_IntegerConstant(1), // inbound connection is being made
128
      IR_IfCondition(
Richard Angersbach's avatar
Richard Angersbach committed
129
        callExtFunction("VisItAttemptToCompleteConnection"),
130
        registerCallbackFcts,
131
132
        IR_Native("std::cout << \"Visit connection failed. Error message: \" << VisItGetLastError() << std::endl")))

133
    whileBody += IR_IfCondition(
134
      visitInput EqEq IR_IntegerConstant(2), // viewer sent instructions
135
136
137
      IR_IfCondition(
        procEngineCommandFct Neq IR_BooleanConstant(true),
        ListBuffer[IR_Statement](
Richard Angersbach's avatar
Richard Angersbach committed
138
          callExtFunction("VisItDisconnect"),
139
          IR_Assignment(runMode, IR_BooleanConstant(true))))) // run after VisIt closes connection
140

141
    whileBody += IR_IfCondition(
142
      visitInput EqEq IR_IntegerConstant(3), // console input detected
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
      consoleInputBody
    )

    fctBody += IR_WhileLoop(
      IR_IntegerConstant(1),
      whileBody
    )

    IR_PlainFunction(
      name,
      IR_UnitDatatype,
      fctBody
    )

  }
  override def name : String = "visit_mainloop"
}