@sdeverywhere/cli 0.7.37 → 0.7.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/c/main.c +118 -23
- package/src/c/model.c +141 -53
- package/src/c/sde.h +5 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdeverywhere/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.39",
|
|
4
4
|
"description": "Contains the `sde` command line interface for the SDEverywhere tool suite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"sde": "src/main.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@sdeverywhere/build": "^0.3.
|
|
15
|
-
"@sdeverywhere/compile": "^0.7.
|
|
14
|
+
"@sdeverywhere/build": "^0.3.10",
|
|
15
|
+
"@sdeverywhere/compile": "^0.7.27",
|
|
16
16
|
"byline": "^5.0.0",
|
|
17
17
|
"ramda": "^0.27.0",
|
|
18
18
|
"shelljs": "^0.10.0",
|
package/src/c/main.c
CHANGED
|
@@ -1,8 +1,70 @@
|
|
|
1
1
|
#include "sde.h"
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Count the number of input pairs in the input string in the format
|
|
5
|
+
* "varIndex:value varIndex:value ..." (for example, "0:3.14 6:42").
|
|
6
|
+
*/
|
|
7
|
+
static size_t countInputs(const char* inputData) {
|
|
8
|
+
if (inputData == NULL || *inputData == '\0') {
|
|
9
|
+
return 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Make a copy since strtok modifies the string
|
|
13
|
+
char* inputsCopy = (char*)malloc(strlen(inputData) + 1);
|
|
14
|
+
strcpy(inputsCopy, inputData);
|
|
15
|
+
|
|
16
|
+
size_t count = 0;
|
|
17
|
+
char* token = strtok(inputsCopy, " ");
|
|
18
|
+
while (token) {
|
|
19
|
+
if (strchr(token, ':') != NULL) {
|
|
20
|
+
count++;
|
|
21
|
+
}
|
|
22
|
+
token = strtok(NULL, " ");
|
|
23
|
+
}
|
|
24
|
+
free(inputsCopy);
|
|
25
|
+
|
|
26
|
+
return count;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parse an input data string in the format "varIndex:value varIndex:value ..."
|
|
31
|
+
* (for example, "0:3.14 6:42") and populate the inputValues and inputIndices
|
|
32
|
+
* arrays for sparse input setting.
|
|
33
|
+
*
|
|
34
|
+
* @param inputData The input string to parse.
|
|
35
|
+
* @param inputValues The array to populate with input values.
|
|
36
|
+
* @param inputIndices The array to populate with input indices (first element is count).
|
|
37
|
+
*/
|
|
38
|
+
static void parseInputs(const char* inputData, double* inputValues, int32_t* inputIndices) {
|
|
39
|
+
if (inputData == NULL || *inputData == '\0') {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Make a copy since strtok modifies the string
|
|
44
|
+
char* inputsCopy = (char*)malloc(strlen(inputData) + 1);
|
|
45
|
+
strcpy(inputsCopy, inputData);
|
|
46
|
+
|
|
47
|
+
size_t i = 0;
|
|
48
|
+
char* token = strtok(inputsCopy, " ");
|
|
49
|
+
while (token) {
|
|
50
|
+
char* p = strchr(token, ':');
|
|
51
|
+
if (p) {
|
|
52
|
+
*p = '\0';
|
|
53
|
+
int modelVarIndex = atoi(token);
|
|
54
|
+
double value = atof(p + 1);
|
|
55
|
+
inputIndices[i + 1] = modelVarIndex;
|
|
56
|
+
inputValues[i] = value;
|
|
57
|
+
i++;
|
|
58
|
+
}
|
|
59
|
+
token = strtok(NULL, " ");
|
|
60
|
+
}
|
|
61
|
+
inputIndices[0] = (int32_t)i;
|
|
62
|
+
free(inputsCopy);
|
|
63
|
+
}
|
|
64
|
+
|
|
3
65
|
int main(int argc, char** argv) {
|
|
4
66
|
// TODO make the input buffer size dynamic
|
|
5
|
-
char
|
|
67
|
+
char inputString[500000];
|
|
6
68
|
// When true, output data without newlines or a header, suitable for embedding reference data.
|
|
7
69
|
bool raw_output = false;
|
|
8
70
|
// When true, suppress data output when using PR* macros.
|
|
@@ -10,11 +72,11 @@ int main(int argc, char** argv) {
|
|
|
10
72
|
// Try to read input from a file named in the argument.
|
|
11
73
|
if (argc > 1) {
|
|
12
74
|
FILE* instream = fopen(argv[1], "r");
|
|
13
|
-
if (instream && fgets(
|
|
75
|
+
if (instream && fgets(inputString, sizeof inputString, instream) != NULL) {
|
|
14
76
|
fclose(instream);
|
|
15
|
-
size_t len = strlen(
|
|
16
|
-
if (
|
|
17
|
-
|
|
77
|
+
size_t len = strlen(inputString);
|
|
78
|
+
if (inputString[len - 1] == '\n') {
|
|
79
|
+
inputString[len - 1] = '\0';
|
|
18
80
|
}
|
|
19
81
|
}
|
|
20
82
|
if (argc > 2) {
|
|
@@ -24,35 +86,68 @@ int main(int argc, char** argv) {
|
|
|
24
86
|
}
|
|
25
87
|
}
|
|
26
88
|
} else {
|
|
27
|
-
*
|
|
89
|
+
*inputString = '\0';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Parse input string and create sparse input arrays. Only allocate buffers if there
|
|
93
|
+
// are inputs to parse; otherwise pass NULL to runModelWithBuffers so that the model
|
|
94
|
+
// uses its default values from initConstants.
|
|
95
|
+
double* inputValues = NULL;
|
|
96
|
+
int32_t* inputIndices = NULL;
|
|
97
|
+
size_t inputCount = countInputs(inputString);
|
|
98
|
+
if (inputCount > 0) {
|
|
99
|
+
inputValues = (double*)malloc(inputCount * sizeof(double));
|
|
100
|
+
inputIndices = (int32_t*)malloc((inputCount + 1) * sizeof(int32_t));
|
|
101
|
+
parseInputs(inputString, inputValues, inputIndices);
|
|
28
102
|
}
|
|
29
|
-
|
|
30
|
-
|
|
103
|
+
|
|
104
|
+
// Calculate the number of save points for the output buffer
|
|
105
|
+
double initialTime = getInitialTime();
|
|
106
|
+
double finalTime = getFinalTime();
|
|
107
|
+
double saveper = getSaveper();
|
|
108
|
+
size_t numSavePoints = (size_t)(round((finalTime - initialTime) / saveper)) + 1;
|
|
109
|
+
|
|
110
|
+
// Allocate output buffer
|
|
111
|
+
double* outputBuffer = (double*)malloc(numOutputs * numSavePoints * sizeof(double));
|
|
112
|
+
|
|
113
|
+
// Run the model with the sparse input arrays and output buffer
|
|
114
|
+
runModelWithBuffers(inputValues, inputIndices, outputBuffer, NULL, NULL, NULL);
|
|
115
|
+
|
|
31
116
|
if (!suppress_data_output) {
|
|
32
117
|
if (raw_output) {
|
|
33
|
-
// Write raw output data directly
|
|
34
|
-
|
|
118
|
+
// Write raw output data directly (tab-separated, no newlines)
|
|
119
|
+
for (size_t t = 0; t < numSavePoints; t++) {
|
|
120
|
+
for (size_t v = 0; v < numOutputs; v++) {
|
|
121
|
+
// Output buffer is organized by variable (each variable has numSavePoints values)
|
|
122
|
+
double value = outputBuffer[v * numSavePoints + t];
|
|
123
|
+
printf("%g\t", value);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
35
126
|
} else {
|
|
36
127
|
// Write a header for output data.
|
|
37
128
|
printf("%s\n", getHeader());
|
|
38
129
|
// Write tab-delimited output data, one line per output time step.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
p++;
|
|
46
|
-
}
|
|
47
|
-
while (*p && *p != '\t') {
|
|
48
|
-
p++;
|
|
49
|
-
}
|
|
130
|
+
for (size_t t = 0; t < numSavePoints; t++) {
|
|
131
|
+
for (size_t v = 0; v < numOutputs; v++) {
|
|
132
|
+
// Output buffer is organized by variable (each variable has numSavePoints values)
|
|
133
|
+
double value = outputBuffer[v * numSavePoints + t];
|
|
134
|
+
if (v > 0) {
|
|
135
|
+
printf("\t");
|
|
50
136
|
}
|
|
51
|
-
|
|
52
|
-
printf("%s\n", line);
|
|
137
|
+
printf("%g", value);
|
|
53
138
|
}
|
|
139
|
+
printf("\n");
|
|
54
140
|
}
|
|
55
141
|
}
|
|
56
142
|
}
|
|
143
|
+
|
|
144
|
+
// Clean up
|
|
145
|
+
if (inputValues != NULL) {
|
|
146
|
+
free(inputValues);
|
|
147
|
+
}
|
|
148
|
+
if (inputIndices != NULL) {
|
|
149
|
+
free(inputIndices);
|
|
150
|
+
}
|
|
151
|
+
free(outputBuffer);
|
|
57
152
|
finish();
|
|
58
153
|
}
|
package/src/c/model.c
CHANGED
|
@@ -11,11 +11,7 @@ struct timespec startTime, finishTime;
|
|
|
11
11
|
// The special _time variable is not included in .mdl files.
|
|
12
12
|
double _time;
|
|
13
13
|
|
|
14
|
-
// Output data buffer used by `
|
|
15
|
-
char* outputData = NULL;
|
|
16
|
-
size_t outputIndex = 0;
|
|
17
|
-
|
|
18
|
-
// Output data buffer used by `runModelWithBuffers`
|
|
14
|
+
// Output data buffer and parameters used by `runModelWithBuffers`
|
|
19
15
|
double* outputBuffer = NULL;
|
|
20
16
|
int32_t* outputIndexBuffer = NULL;
|
|
21
17
|
size_t outputVarIndex = 0;
|
|
@@ -67,47 +63,157 @@ double getSaveper() {
|
|
|
67
63
|
return _saveper;
|
|
68
64
|
}
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Set constant overrides from the given buffers.
|
|
68
|
+
*
|
|
69
|
+
* The `constantIndices` buffer contains the variable indices and subscript indices
|
|
70
|
+
* for each constant to override. The format is:
|
|
71
|
+
* [count, varIndex1, subCount1, subIndex1_1, ..., varIndex2, subCount2, ...]
|
|
72
|
+
*
|
|
73
|
+
* The `constantValues` buffer contains the corresponding values for each constant.
|
|
74
|
+
*/
|
|
75
|
+
void setConstantOverridesFromBuffers(double* constantValues, int32_t* constantIndices) {
|
|
76
|
+
if (constantValues == NULL || constantIndices == NULL) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
size_t indexBufferOffset = 0;
|
|
81
|
+
size_t valueBufferOffset = 0;
|
|
82
|
+
size_t constantCount = (size_t)constantIndices[indexBufferOffset++];
|
|
83
|
+
|
|
84
|
+
for (size_t i = 0; i < constantCount; i++) {
|
|
85
|
+
size_t varIndex = (size_t)constantIndices[indexBufferOffset++];
|
|
86
|
+
size_t subCount = (size_t)constantIndices[indexBufferOffset++];
|
|
87
|
+
size_t* subIndices;
|
|
88
|
+
if (subCount > 0) {
|
|
89
|
+
subIndices = (size_t*)(constantIndices + indexBufferOffset);
|
|
90
|
+
indexBufferOffset += subCount;
|
|
91
|
+
} else {
|
|
92
|
+
subIndices = NULL;
|
|
93
|
+
}
|
|
94
|
+
double value = constantValues[valueBufferOffset++];
|
|
95
|
+
setConstant(varIndex, subIndices, value);
|
|
96
|
+
}
|
|
81
97
|
}
|
|
82
98
|
|
|
83
99
|
/**
|
|
84
100
|
* Run the model, reading inputs from the given `inputs` buffer, and writing outputs
|
|
85
101
|
* to the given `outputs` buffer.
|
|
86
102
|
*
|
|
87
|
-
* This
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* The `inputs` buffer is assumed to have one double value for each input variable;
|
|
91
|
-
* they must be in exactly the same order as the variables are listed in the spec file.
|
|
103
|
+
* This is a simplified version of `runModelWithBuffers` that passes NULL for
|
|
104
|
+
* all parameters other than `inputs` and `outputs`.
|
|
92
105
|
*
|
|
93
106
|
* After each step of the run, the `outputs` buffer will be updated with the output
|
|
94
|
-
* variables. The buffer needs to be at least as large as:
|
|
107
|
+
* variables. The `outputs` buffer needs to be at least as large as:
|
|
95
108
|
* `number of output variables` * `number of save points`
|
|
96
|
-
* where `number of save points` is typically one point for each year inclusive of
|
|
97
|
-
* the start and end times.
|
|
98
109
|
*
|
|
99
110
|
* The outputs will be stored in the same order as the outputs are defined in the
|
|
100
111
|
* spec file, with one "row" for each variable. For example, the first value in
|
|
101
|
-
* the buffer will be the output value at t0 for the first output variable,
|
|
102
|
-
* by the output value for that variable at t1, and so on. After the
|
|
103
|
-
* (where tN is the last time in the range), the second variable
|
|
104
|
-
* and so on.
|
|
112
|
+
* the buffer will be the output value at t0 for the first output variable,
|
|
113
|
+
* followed by the output value for that variable at t1, and so on. After the
|
|
114
|
+
* value for tN (where tN is the last time in the range), the second variable
|
|
115
|
+
* outputs will begin, and so on.
|
|
116
|
+
*
|
|
117
|
+
* @param inputs The buffer that contains the model input values. If NULL,
|
|
118
|
+
* no inputs will be set and the model will use the default values for all
|
|
119
|
+
* constants as defined in the generated model. If non-NULL, the buffer is
|
|
120
|
+
* assumed to have one double value for each input variable in exactly the
|
|
121
|
+
* same order that the variables are listed in the spec file.
|
|
122
|
+
* @param outputs The required buffer that will receive the model output
|
|
123
|
+
* values. See above for details on the expected format.
|
|
124
|
+
*/
|
|
125
|
+
void runModel(double* inputs, double* outputs) {
|
|
126
|
+
runModelWithBuffers(inputs, NULL, outputs, NULL, NULL, NULL);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Run the model, reading inputs from the given `inputs` buffer, and writing outputs
|
|
131
|
+
* to the given `outputs` buffer.
|
|
132
|
+
*
|
|
133
|
+
* INPUTS
|
|
134
|
+
* ------
|
|
135
|
+
*
|
|
136
|
+
* If `inputIndices` is NULL, the `inputs` buffer is assumed to have one double value
|
|
137
|
+
* for each input variable, in exactly the same order as the variables are listed in
|
|
138
|
+
* the spec file.
|
|
139
|
+
*
|
|
140
|
+
* If `inputIndices` is non-NULL, it specifies which inputs are being set:
|
|
141
|
+
* - inputIndices[0] is the count (C) of inputs being specified
|
|
142
|
+
* - inputIndices[1...C] are the indices of the inputs to set (where each index
|
|
143
|
+
* corresponds to the index of the input variable in the spec.json file)
|
|
144
|
+
* - inputs[0...C-1] are the corresponding values
|
|
145
|
+
*
|
|
146
|
+
* OUTPUTS
|
|
147
|
+
* -------
|
|
148
|
+
*
|
|
149
|
+
* After each step of the run, the `outputs` buffer will be updated with the output
|
|
150
|
+
* variables. The `outputs` buffer needs to be at least as large as:
|
|
151
|
+
* `number of output variables` * `number of save points`
|
|
152
|
+
*
|
|
153
|
+
* If `outputIndices` is NULL, outputs will be stored in the same order as the outputs
|
|
154
|
+
* are defined in the spec file, with one "row" for each variable. For example, the
|
|
155
|
+
* first value in the buffer will be the output value at t0 for the first output
|
|
156
|
+
* variable, followed by the output value for that variable at t1, and so on. After
|
|
157
|
+
* the value for tN (where tN is the last time in the range), the second variable
|
|
158
|
+
* outputs will begin, and so on.
|
|
159
|
+
*
|
|
160
|
+
* If `outputIndices` is non-NULL, it specifies which outputs are being stored:
|
|
161
|
+
* - outputIndices[0] is the count (C) of output variables being stored
|
|
162
|
+
* - outputIndices[1...] are the indices of the output variables to store, in
|
|
163
|
+
* the following format:
|
|
164
|
+
* [count, varIndex1, subCount1, subIndex1_1, ..., varIndex2, subCount2, ...]
|
|
165
|
+
* where `count` is the number of variables to store, `varIndexN` is the index
|
|
166
|
+
* of the variable to store (from the {model}.json listing file), `subCountN` is
|
|
167
|
+
* the number of subscripts for that variable, and `subIndexN_M` is the index of
|
|
168
|
+
* the subscript at the Mth position for that variable
|
|
169
|
+
* - outputs[0...C-1] are the corresponding values
|
|
170
|
+
*
|
|
171
|
+
* CONSTANT OVERRIDES
|
|
172
|
+
* ------------------
|
|
173
|
+
*
|
|
174
|
+
* If `constants` and `constantIndices` are non-NULL, the provided constant values will
|
|
175
|
+
* override the default values for those constants as defined in the generated model.
|
|
176
|
+
*
|
|
177
|
+
* The `constantIndices` buffer specifies which constants are being overridden. The
|
|
178
|
+
* format is the same as described above for `outputIndices`:
|
|
179
|
+
* - constantIndices[0] is the count (C) of constants being overridden
|
|
180
|
+
* - constantIndices[1...] are the indices of the constants to override, in the
|
|
181
|
+
* following format:
|
|
182
|
+
* [count, varIndex1, subCount1, subIndex1_1, ..., varIndex2, subCount2, ...]
|
|
183
|
+
* where `count` is the number of constants to override, `varIndexN` is the index
|
|
184
|
+
* of the variable to store (from the {model}.json listing file), `subCountN` is
|
|
185
|
+
* the number of subscripts for that variable, and `subIndexN_M` is the index of
|
|
186
|
+
* the subscript at the Mth position for that variable
|
|
187
|
+
* - constants[0...C-1] are the corresponding values
|
|
188
|
+
*
|
|
189
|
+
* @param inputs The buffer that contains the model input values. If NULL, no inputs
|
|
190
|
+
* will be set and the model will use the default values for all constants as defined
|
|
191
|
+
* in the generated model. If non-NULL, the buffer is assumed to have one double value
|
|
192
|
+
* for each input variable. The number of values provided depends on `inputIndices`;
|
|
193
|
+
* see above for details on the expected format of these two parameters.
|
|
194
|
+
* @param inputIndices The optional buffer that specifies which input values from the
|
|
195
|
+
* `inputs` buffer are being set. See above for details on the expected format.
|
|
196
|
+
* @param outputs The required buffer that will receive the model output values. See
|
|
197
|
+
* above for details on the expected format.
|
|
198
|
+
* @param outputIndices The optional buffer that specifies which output values will be
|
|
199
|
+
* stored in the `outputs` buffer. See above for details on the expected format.
|
|
200
|
+
* @param constants An optional buffer that contains the values of the constants to
|
|
201
|
+
* override. Pass NULL if not overriding any constants. Each value in the buffer
|
|
202
|
+
* corresponds to the value of the constant at the corresponding index.
|
|
203
|
+
* @param constantIndices An optional buffer that contains the indices of the constants
|
|
204
|
+
* to override. Pass NULL if not overriding any constants. See above for details on
|
|
205
|
+
* the expected format.
|
|
105
206
|
*/
|
|
106
|
-
void runModelWithBuffers(double* inputs, double* outputs, int32_t* outputIndices) {
|
|
207
|
+
void runModelWithBuffers(double* inputs, int32_t* inputIndices, double* outputs, int32_t* outputIndices, double* constants, int32_t* constantIndices) {
|
|
107
208
|
outputBuffer = outputs;
|
|
108
209
|
outputIndexBuffer = outputIndices;
|
|
109
210
|
initConstants();
|
|
110
|
-
|
|
211
|
+
if (constants != NULL && constantIndices != NULL) {
|
|
212
|
+
setConstantOverridesFromBuffers(constants, constantIndices);
|
|
213
|
+
}
|
|
214
|
+
if (inputs != NULL) {
|
|
215
|
+
setInputs(inputs, inputIndices);
|
|
216
|
+
}
|
|
111
217
|
initLevels();
|
|
112
218
|
run();
|
|
113
219
|
outputBuffer = NULL;
|
|
@@ -121,7 +227,6 @@ void run() {
|
|
|
121
227
|
|
|
122
228
|
// Restart fresh output for all steps in this run.
|
|
123
229
|
savePointIndex = 0;
|
|
124
|
-
outputIndex = 0;
|
|
125
230
|
|
|
126
231
|
// Initialize time with the required INITIAL TIME control variable.
|
|
127
232
|
_time = _initial_time;
|
|
@@ -171,25 +276,11 @@ void run() {
|
|
|
171
276
|
}
|
|
172
277
|
|
|
173
278
|
void outputVar(double value) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
outputVarIndex++;
|
|
180
|
-
} else {
|
|
181
|
-
// Allocate an output buffer for all output steps as a single block.
|
|
182
|
-
// Add one character for a null terminator.
|
|
183
|
-
if (outputData == NULL) {
|
|
184
|
-
int numOutputSteps = (int)(round((_final_time - _initial_time) / _saveper)) + 1;
|
|
185
|
-
size_t size = numOutputSteps * (OUTPUT_STRING_LEN * numOutputs) + 1;
|
|
186
|
-
// fprintf(stderr, "output data size = %zu\n", size);
|
|
187
|
-
outputData = (char*)malloc(size);
|
|
188
|
-
}
|
|
189
|
-
// Format the value as a string in the output data buffer.
|
|
190
|
-
int numChars = snprintf(outputData + outputIndex, OUTPUT_STRING_LEN + 1, "%g\t", value);
|
|
191
|
-
outputIndex += numChars;
|
|
192
|
-
}
|
|
279
|
+
// Write each value into the preallocated buffer; each variable has a "row" that
|
|
280
|
+
// contains `numSavePoints` values, one value for each save point
|
|
281
|
+
double* outputPtr = outputBuffer + (outputVarIndex * numSavePoints) + savePointIndex;
|
|
282
|
+
*outputPtr = value;
|
|
283
|
+
outputVarIndex++;
|
|
193
284
|
}
|
|
194
285
|
|
|
195
286
|
void finish() {
|
|
@@ -199,7 +290,4 @@ void finish() {
|
|
|
199
290
|
1000.0 * finishTime.tv_sec + 1e-6 * finishTime.tv_nsec - (1000.0 * startTime.tv_sec + 1e-6 * startTime.tv_nsec);
|
|
200
291
|
fprintf(stderr, "calculation runtime = %.0f ms\n", runtime);
|
|
201
292
|
#endif
|
|
202
|
-
if (outputData != NULL) {
|
|
203
|
-
free(outputData);
|
|
204
|
-
}
|
|
205
293
|
}
|
package/src/c/sde.h
CHANGED
|
@@ -41,6 +41,7 @@ EXTERN double _epsilon;
|
|
|
41
41
|
#define OUTPUT_STRING_LEN 14
|
|
42
42
|
|
|
43
43
|
// Internal variables
|
|
44
|
+
EXTERN const int numInputs;
|
|
44
45
|
EXTERN const int numOutputs;
|
|
45
46
|
|
|
46
47
|
// Standard simulation control parameters
|
|
@@ -54,8 +55,8 @@ EXTERN double _saveper;
|
|
|
54
55
|
double getInitialTime(void);
|
|
55
56
|
double getFinalTime(void);
|
|
56
57
|
double getSaveper(void);
|
|
57
|
-
|
|
58
|
-
void runModelWithBuffers(double* inputs, double* outputs, int32_t* outputIndices);
|
|
58
|
+
void runModel(double* inputs, double* outputs);
|
|
59
|
+
void runModelWithBuffers(double* inputs, int32_t* inputIndices, double* outputs, int32_t* outputIndices, double* constants, int32_t* constantIndices);
|
|
59
60
|
void run(void);
|
|
60
61
|
void startOutput(void);
|
|
61
62
|
void outputVar(double value);
|
|
@@ -64,8 +65,8 @@ void finish(void);
|
|
|
64
65
|
// Functions implemented by the generated model
|
|
65
66
|
void initConstants(void);
|
|
66
67
|
void initLevels(void);
|
|
67
|
-
void setInputs(
|
|
68
|
-
void
|
|
68
|
+
void setInputs(double* inputValues, int32_t* inputIndices);
|
|
69
|
+
void setConstant(size_t varIndex, size_t* subIndices, double value);
|
|
69
70
|
void setLookup(size_t varIndex, size_t* subIndices, double* points, size_t numPoints);
|
|
70
71
|
void evalAux(void);
|
|
71
72
|
void evalLevels(void);
|