@sdeverywhere/runtime 0.2.6 → 0.2.8
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/README.md +1 -1
- package/dist/index.cjs +445 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +212 -10
- package/dist/index.d.ts +212 -10
- package/dist/index.js +437 -22
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -206,6 +206,66 @@ function encodeVarIndices(varSpecs, indicesArray) {
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
+
function getEncodedConstantBufferLengths(constantDefs) {
|
|
210
|
+
var _a;
|
|
211
|
+
let constantIndicesLength = 1;
|
|
212
|
+
let constantsLength = 0;
|
|
213
|
+
for (const constantDef of constantDefs) {
|
|
214
|
+
const varSpec = constantDef.varRef.varSpec;
|
|
215
|
+
if (varSpec === void 0) {
|
|
216
|
+
throw new Error("Cannot compute constant buffer lengths until all constant var specs are defined");
|
|
217
|
+
}
|
|
218
|
+
constantIndicesLength += 2;
|
|
219
|
+
const subCount = ((_a = varSpec.subscriptIndices) == null ? void 0 : _a.length) || 0;
|
|
220
|
+
constantIndicesLength += subCount;
|
|
221
|
+
constantsLength += 1;
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
constantIndicesLength,
|
|
225
|
+
constantsLength
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function encodeConstants(constantDefs, constantIndicesArray, constantsArray) {
|
|
229
|
+
let ci = 0;
|
|
230
|
+
constantIndicesArray[ci++] = constantDefs.length;
|
|
231
|
+
let constantDataOffset = 0;
|
|
232
|
+
for (const constantDef of constantDefs) {
|
|
233
|
+
const varSpec = constantDef.varRef.varSpec;
|
|
234
|
+
constantIndicesArray[ci++] = varSpec.varIndex;
|
|
235
|
+
const subs = varSpec.subscriptIndices;
|
|
236
|
+
const subCount = (subs == null ? void 0 : subs.length) || 0;
|
|
237
|
+
constantIndicesArray[ci++] = subCount;
|
|
238
|
+
for (let i = 0; i < subCount; i++) {
|
|
239
|
+
constantIndicesArray[ci++] = subs[i];
|
|
240
|
+
}
|
|
241
|
+
constantsArray[constantDataOffset++] = constantDef.value;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function decodeConstants(constantIndicesArray, constantsArray) {
|
|
245
|
+
const constantDefs = [];
|
|
246
|
+
let ci = 0;
|
|
247
|
+
const constantCount = constantIndicesArray[ci++];
|
|
248
|
+
for (let i = 0; i < constantCount; i++) {
|
|
249
|
+
const varIndex = constantIndicesArray[ci++];
|
|
250
|
+
const subCount = constantIndicesArray[ci++];
|
|
251
|
+
const subscriptIndices = subCount > 0 ? Array(subCount) : void 0;
|
|
252
|
+
for (let subIndex = 0; subIndex < subCount; subIndex++) {
|
|
253
|
+
subscriptIndices[subIndex] = constantIndicesArray[ci++];
|
|
254
|
+
}
|
|
255
|
+
const varSpec = {
|
|
256
|
+
varIndex,
|
|
257
|
+
subscriptIndices
|
|
258
|
+
};
|
|
259
|
+
const value = constantsArray[i];
|
|
260
|
+
constantDefs.push({
|
|
261
|
+
varRef: {
|
|
262
|
+
varSpec
|
|
263
|
+
},
|
|
264
|
+
value
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return constantDefs;
|
|
268
|
+
}
|
|
209
269
|
function getEncodedLookupBufferLengths(lookupDefs) {
|
|
210
270
|
var _a, _b;
|
|
211
271
|
let lookupIndicesLength = 1;
|
|
@@ -287,6 +347,14 @@ function decodeLookups(lookupIndicesArray, lookupsArray) {
|
|
|
287
347
|
return lookupDefs;
|
|
288
348
|
}
|
|
289
349
|
|
|
350
|
+
// src/_shared/constant-def.ts
|
|
351
|
+
function createConstantDef(varRef, value) {
|
|
352
|
+
return {
|
|
353
|
+
varRef,
|
|
354
|
+
value
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
290
358
|
// src/_shared/lookup-def.ts
|
|
291
359
|
function createLookupDef(varRef, points) {
|
|
292
360
|
let flatPoints;
|
|
@@ -457,7 +525,7 @@ function resolveVarRef(listing, varRef, varKind) {
|
|
|
457
525
|
}
|
|
458
526
|
|
|
459
527
|
// src/runnable-model/buffered-run-model-params.ts
|
|
460
|
-
var headerLengthInElements =
|
|
528
|
+
var headerLengthInElements = 20;
|
|
461
529
|
var extrasLengthInElements = 1;
|
|
462
530
|
var Int32Section = class {
|
|
463
531
|
constructor() {
|
|
@@ -502,6 +570,10 @@ var BufferedRunModelParams = class {
|
|
|
502
570
|
this.outputs = new Float64Section();
|
|
503
571
|
/** The output indices section of the `encoded` buffer. */
|
|
504
572
|
this.outputIndices = new Int32Section();
|
|
573
|
+
/** The constant values section of the `encoded` buffer. */
|
|
574
|
+
this.constants = new Float64Section();
|
|
575
|
+
/** The constant indices section of the `encoded` buffer. */
|
|
576
|
+
this.constantIndices = new Int32Section();
|
|
505
577
|
/** The lookup data section of the `encoded` buffer. */
|
|
506
578
|
this.lookups = new Float64Section();
|
|
507
579
|
/** The lookup indices section of the `encoded` buffer. */
|
|
@@ -569,6 +641,13 @@ var BufferedRunModelParams = class {
|
|
|
569
641
|
}
|
|
570
642
|
}
|
|
571
643
|
// from RunModelParams interface
|
|
644
|
+
getConstants() {
|
|
645
|
+
if (this.constantIndices.lengthInElements === 0) {
|
|
646
|
+
return void 0;
|
|
647
|
+
}
|
|
648
|
+
return decodeConstants(this.constantIndices.view, this.constants.view);
|
|
649
|
+
}
|
|
650
|
+
// from RunModelParams interface
|
|
572
651
|
getLookups() {
|
|
573
652
|
if (this.lookupIndices.lengthInElements === 0) {
|
|
574
653
|
return void 0;
|
|
@@ -613,6 +692,19 @@ var BufferedRunModelParams = class {
|
|
|
613
692
|
} else {
|
|
614
693
|
outputIndicesLengthInElements = 0;
|
|
615
694
|
}
|
|
695
|
+
let constantsLengthInElements;
|
|
696
|
+
let constantIndicesLengthInElements;
|
|
697
|
+
if ((options == null ? void 0 : options.constants) !== void 0 && options.constants.length > 0) {
|
|
698
|
+
for (const constantDef of options.constants) {
|
|
699
|
+
resolveVarRef(this.listing, constantDef.varRef, "constant");
|
|
700
|
+
}
|
|
701
|
+
const encodedLengths = getEncodedConstantBufferLengths(options.constants);
|
|
702
|
+
constantsLengthInElements = encodedLengths.constantsLength;
|
|
703
|
+
constantIndicesLengthInElements = encodedLengths.constantIndicesLength;
|
|
704
|
+
} else {
|
|
705
|
+
constantsLengthInElements = 0;
|
|
706
|
+
constantIndicesLengthInElements = 0;
|
|
707
|
+
}
|
|
616
708
|
let lookupsLengthInElements;
|
|
617
709
|
let lookupIndicesLengthInElements;
|
|
618
710
|
if ((options == null ? void 0 : options.lookups) !== void 0 && options.lookups.length > 0) {
|
|
@@ -640,6 +732,8 @@ var BufferedRunModelParams = class {
|
|
|
640
732
|
const inputsOffsetInBytes = section("float64", inputsLengthInElements);
|
|
641
733
|
const outputsOffsetInBytes = section("float64", outputsLengthInElements);
|
|
642
734
|
const outputIndicesOffsetInBytes = section("int32", outputIndicesLengthInElements);
|
|
735
|
+
const constantsOffsetInBytes = section("float64", constantsLengthInElements);
|
|
736
|
+
const constantIndicesOffsetInBytes = section("int32", constantIndicesLengthInElements);
|
|
643
737
|
const lookupsOffsetInBytes = section("float64", lookupsLengthInElements);
|
|
644
738
|
const lookupIndicesOffsetInBytes = section("int32", lookupIndicesLengthInElements);
|
|
645
739
|
const requiredLengthInBytes = byteOffset;
|
|
@@ -658,6 +752,10 @@ var BufferedRunModelParams = class {
|
|
|
658
752
|
headerView[headerIndex++] = outputsLengthInElements;
|
|
659
753
|
headerView[headerIndex++] = outputIndicesOffsetInBytes;
|
|
660
754
|
headerView[headerIndex++] = outputIndicesLengthInElements;
|
|
755
|
+
headerView[headerIndex++] = constantsOffsetInBytes;
|
|
756
|
+
headerView[headerIndex++] = constantsLengthInElements;
|
|
757
|
+
headerView[headerIndex++] = constantIndicesOffsetInBytes;
|
|
758
|
+
headerView[headerIndex++] = constantIndicesLengthInElements;
|
|
661
759
|
headerView[headerIndex++] = lookupsOffsetInBytes;
|
|
662
760
|
headerView[headerIndex++] = lookupsLengthInElements;
|
|
663
761
|
headerView[headerIndex++] = lookupIndicesOffsetInBytes;
|
|
@@ -666,6 +764,8 @@ var BufferedRunModelParams = class {
|
|
|
666
764
|
this.extras.update(this.encoded, extrasOffsetInBytes, extrasLengthInElements);
|
|
667
765
|
this.outputs.update(this.encoded, outputsOffsetInBytes, outputsLengthInElements);
|
|
668
766
|
this.outputIndices.update(this.encoded, outputIndicesOffsetInBytes, outputIndicesLengthInElements);
|
|
767
|
+
this.constants.update(this.encoded, constantsOffsetInBytes, constantsLengthInElements);
|
|
768
|
+
this.constantIndices.update(this.encoded, constantIndicesOffsetInBytes, constantIndicesLengthInElements);
|
|
669
769
|
this.lookups.update(this.encoded, lookupsOffsetInBytes, lookupsLengthInElements);
|
|
670
770
|
this.lookupIndices.update(this.encoded, lookupIndicesOffsetInBytes, lookupIndicesLengthInElements);
|
|
671
771
|
const inputsView = this.inputs.view;
|
|
@@ -680,6 +780,9 @@ var BufferedRunModelParams = class {
|
|
|
680
780
|
if (this.outputIndices.view) {
|
|
681
781
|
encodeVarIndices(outputVarSpecs, this.outputIndices.view);
|
|
682
782
|
}
|
|
783
|
+
if (constantIndicesLengthInElements > 0) {
|
|
784
|
+
encodeConstants(options.constants, this.constantIndices.view, this.constants.view);
|
|
785
|
+
}
|
|
683
786
|
if (lookupIndicesLengthInElements > 0) {
|
|
684
787
|
encodeLookups(options.lookups, this.lookupIndices.view, this.lookups.view);
|
|
685
788
|
}
|
|
@@ -708,6 +811,10 @@ var BufferedRunModelParams = class {
|
|
|
708
811
|
const outputsLengthInElements = headerView[headerIndex++];
|
|
709
812
|
const outputIndicesOffsetInBytes = headerView[headerIndex++];
|
|
710
813
|
const outputIndicesLengthInElements = headerView[headerIndex++];
|
|
814
|
+
const constantsOffsetInBytes = headerView[headerIndex++];
|
|
815
|
+
const constantsLengthInElements = headerView[headerIndex++];
|
|
816
|
+
const constantIndicesOffsetInBytes = headerView[headerIndex++];
|
|
817
|
+
const constantIndicesLengthInElements = headerView[headerIndex++];
|
|
711
818
|
const lookupsOffsetInBytes = headerView[headerIndex++];
|
|
712
819
|
const lookupsLengthInElements = headerView[headerIndex++];
|
|
713
820
|
const lookupIndicesOffsetInBytes = headerView[headerIndex++];
|
|
@@ -716,9 +823,11 @@ var BufferedRunModelParams = class {
|
|
|
716
823
|
const inputsLengthInBytes = inputsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
|
|
717
824
|
const outputsLengthInBytes = outputsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
|
|
718
825
|
const outputIndicesLengthInBytes = outputIndicesLengthInElements * Int32Array.BYTES_PER_ELEMENT;
|
|
826
|
+
const constantsLengthInBytes = constantsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
|
|
827
|
+
const constantIndicesLengthInBytes = constantIndicesLengthInElements * Int32Array.BYTES_PER_ELEMENT;
|
|
719
828
|
const lookupsLengthInBytes = lookupsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
|
|
720
829
|
const lookupIndicesLengthInBytes = lookupIndicesLengthInElements * Int32Array.BYTES_PER_ELEMENT;
|
|
721
|
-
const requiredLengthInBytes = headerLengthInBytes + extrasLengthInBytes + inputsLengthInBytes + outputsLengthInBytes + outputIndicesLengthInBytes + lookupsLengthInBytes + lookupIndicesLengthInBytes;
|
|
830
|
+
const requiredLengthInBytes = headerLengthInBytes + extrasLengthInBytes + inputsLengthInBytes + outputsLengthInBytes + outputIndicesLengthInBytes + constantsLengthInBytes + constantIndicesLengthInBytes + lookupsLengthInBytes + lookupIndicesLengthInBytes;
|
|
722
831
|
if (buffer.byteLength < requiredLengthInBytes) {
|
|
723
832
|
throw new Error("Buffer must be long enough to contain sections declared in header");
|
|
724
833
|
}
|
|
@@ -726,6 +835,8 @@ var BufferedRunModelParams = class {
|
|
|
726
835
|
this.inputs.update(this.encoded, inputsOffsetInBytes, inputsLengthInElements);
|
|
727
836
|
this.outputs.update(this.encoded, outputsOffsetInBytes, outputsLengthInElements);
|
|
728
837
|
this.outputIndices.update(this.encoded, outputIndicesOffsetInBytes, outputIndicesLengthInElements);
|
|
838
|
+
this.constants.update(this.encoded, constantsOffsetInBytes, constantsLengthInElements);
|
|
839
|
+
this.constantIndices.update(this.encoded, constantIndicesOffsetInBytes, constantIndicesLengthInElements);
|
|
729
840
|
this.lookups.update(this.encoded, lookupsOffsetInBytes, lookupsLengthInElements);
|
|
730
841
|
this.lookupIndices.update(this.encoded, lookupIndicesOffsetInBytes, lookupIndicesLengthInElements);
|
|
731
842
|
}
|
|
@@ -802,6 +913,14 @@ var ReferencedRunModelParams = class {
|
|
|
802
913
|
}
|
|
803
914
|
}
|
|
804
915
|
// from RunModelParams interface
|
|
916
|
+
getConstants() {
|
|
917
|
+
if (this.constants !== void 0 && this.constants.length > 0) {
|
|
918
|
+
return this.constants;
|
|
919
|
+
} else {
|
|
920
|
+
return void 0;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
// from RunModelParams interface
|
|
805
924
|
getLookups() {
|
|
806
925
|
if (this.lookups !== void 0 && this.lookups.length > 0) {
|
|
807
926
|
return this.lookups;
|
|
@@ -831,7 +950,13 @@ var ReferencedRunModelParams = class {
|
|
|
831
950
|
this.inputs = inputs;
|
|
832
951
|
this.outputs = outputs;
|
|
833
952
|
this.outputsLengthInElements = outputs.varIds.length * outputs.seriesLength;
|
|
953
|
+
this.constants = options == null ? void 0 : options.constants;
|
|
834
954
|
this.lookups = options == null ? void 0 : options.lookups;
|
|
955
|
+
if (this.constants) {
|
|
956
|
+
for (const constantDef of this.constants) {
|
|
957
|
+
resolveVarRef(this.listing, constantDef.varRef, "constant");
|
|
958
|
+
}
|
|
959
|
+
}
|
|
835
960
|
if (this.lookups) {
|
|
836
961
|
for (const lookupDef of this.lookups) {
|
|
837
962
|
resolveVarRef(this.listing, lookupDef.varRef, "lookup");
|
|
@@ -1311,6 +1436,7 @@ var BaseRunnableModel = class {
|
|
|
1311
1436
|
const t0 = perfNow();
|
|
1312
1437
|
(_a = this.onRunModel) == null ? void 0 : _a.call(this, inputsArray, outputsArray, {
|
|
1313
1438
|
outputIndices: outputIndicesArray,
|
|
1439
|
+
constants: params.getConstants(),
|
|
1314
1440
|
lookups: params.getLookups()
|
|
1315
1441
|
});
|
|
1316
1442
|
const elapsed = perfElapsed(t0);
|
|
@@ -1352,13 +1478,14 @@ function initJsModel(model) {
|
|
|
1352
1478
|
inputs,
|
|
1353
1479
|
outputs,
|
|
1354
1480
|
options == null ? void 0 : options.outputIndices,
|
|
1481
|
+
options == null ? void 0 : options.constants,
|
|
1355
1482
|
options == null ? void 0 : options.lookups,
|
|
1356
1483
|
void 0
|
|
1357
1484
|
);
|
|
1358
1485
|
}
|
|
1359
1486
|
});
|
|
1360
1487
|
}
|
|
1361
|
-
function runJsModel(model, initialTime, finalTime, timeStep, saveFreq, numSavePoints, inputs, outputs, outputIndices, lookups, stopAfterTime) {
|
|
1488
|
+
function runJsModel(model, initialTime, finalTime, timeStep, saveFreq, numSavePoints, inputs, outputs, outputIndices, constants, lookups, stopAfterTime) {
|
|
1362
1489
|
let time = initialTime;
|
|
1363
1490
|
model.setTime(time);
|
|
1364
1491
|
const fnContext = {
|
|
@@ -1367,6 +1494,11 @@ function runJsModel(model, initialTime, finalTime, timeStep, saveFreq, numSavePo
|
|
|
1367
1494
|
};
|
|
1368
1495
|
model.getModelFunctions().setContext(fnContext);
|
|
1369
1496
|
model.initConstants();
|
|
1497
|
+
if (constants !== void 0) {
|
|
1498
|
+
for (const constantDef of constants) {
|
|
1499
|
+
model.setConstant(constantDef.varRef.varSpec, constantDef.value);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1370
1502
|
if (lookups !== void 0) {
|
|
1371
1503
|
for (const lookupDef of lookups) {
|
|
1372
1504
|
model.setLookup(lookupDef.varRef.varSpec, lookupDef.points);
|
|
@@ -1453,6 +1585,7 @@ var MockJsModel = class {
|
|
|
1453
1585
|
// from JsModel interface
|
|
1454
1586
|
this.kind = "js";
|
|
1455
1587
|
this.vars = /* @__PURE__ */ new Map();
|
|
1588
|
+
this.constants = /* @__PURE__ */ new Map();
|
|
1456
1589
|
this.lookups = /* @__PURE__ */ new Map();
|
|
1457
1590
|
this.outputVarIds = options.outputVarIds;
|
|
1458
1591
|
this.outputVarNames = options.outputVarIds;
|
|
@@ -1505,6 +1638,14 @@ var MockJsModel = class {
|
|
|
1505
1638
|
setInputs() {
|
|
1506
1639
|
}
|
|
1507
1640
|
// from JsModel interface
|
|
1641
|
+
setConstant(varSpec, value) {
|
|
1642
|
+
const varId = this.varIdForSpec(varSpec);
|
|
1643
|
+
if (varId === void 0) {
|
|
1644
|
+
throw new Error(`No constant variable found for spec ${varSpec}`);
|
|
1645
|
+
}
|
|
1646
|
+
this.constants.set(varId, value);
|
|
1647
|
+
}
|
|
1648
|
+
// from JsModel interface
|
|
1508
1649
|
setLookup(varSpec, points) {
|
|
1509
1650
|
const varId = this.varIdForSpec(varSpec);
|
|
1510
1651
|
if (varId === void 0) {
|
|
@@ -1529,6 +1670,7 @@ var MockJsModel = class {
|
|
|
1529
1670
|
}
|
|
1530
1671
|
// from JsModel interface
|
|
1531
1672
|
initConstants() {
|
|
1673
|
+
this.constants.clear();
|
|
1532
1674
|
}
|
|
1533
1675
|
// from JsModel interface
|
|
1534
1676
|
initLevels() {
|
|
@@ -1536,7 +1678,7 @@ var MockJsModel = class {
|
|
|
1536
1678
|
// from JsModel interface
|
|
1537
1679
|
evalAux() {
|
|
1538
1680
|
var _a;
|
|
1539
|
-
(_a = this.onEvalAux) == null ? void 0 : _a.call(this, this.vars, this.lookups);
|
|
1681
|
+
(_a = this.onEvalAux) == null ? void 0 : _a.call(this, this.vars, this.constants.size > 0 ? this.constants : void 0, this.lookups);
|
|
1540
1682
|
}
|
|
1541
1683
|
// from JsModel interface
|
|
1542
1684
|
evalLevels() {
|
|
@@ -1619,11 +1761,18 @@ var WasmModel = class {
|
|
|
1619
1761
|
this.outputVarIds = wasmModule.outputVarIds;
|
|
1620
1762
|
this.modelListing = wasmModule.modelListing;
|
|
1621
1763
|
this.wasmSetLookup = wasmModule.cwrap("setLookup", null, ["number", "number", "number", "number"]);
|
|
1622
|
-
this.wasmRunModel = wasmModule.cwrap("runModelWithBuffers", null, [
|
|
1764
|
+
this.wasmRunModel = wasmModule.cwrap("runModelWithBuffers", null, [
|
|
1765
|
+
"number",
|
|
1766
|
+
"number",
|
|
1767
|
+
"number",
|
|
1768
|
+
"number",
|
|
1769
|
+
"number",
|
|
1770
|
+
"number"
|
|
1771
|
+
]);
|
|
1623
1772
|
}
|
|
1624
1773
|
// from RunnableModel interface
|
|
1625
1774
|
runModel(params) {
|
|
1626
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1775
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
1627
1776
|
const lookups = params.getLookups();
|
|
1628
1777
|
if (lookups !== void 0) {
|
|
1629
1778
|
for (const lookupDef of lookups) {
|
|
@@ -1659,7 +1808,48 @@ var WasmModel = class {
|
|
|
1659
1808
|
this.wasmSetLookup(varIndex, subIndicesAddress, pointsAddress, numPoints);
|
|
1660
1809
|
}
|
|
1661
1810
|
}
|
|
1662
|
-
|
|
1811
|
+
let constantIndicesBuffer;
|
|
1812
|
+
let constantValuesBuffer;
|
|
1813
|
+
const constants = params.getConstants();
|
|
1814
|
+
if (constants !== void 0 && constants.length > 0) {
|
|
1815
|
+
let totalIndicesSize = 1;
|
|
1816
|
+
for (const constantDef of constants) {
|
|
1817
|
+
const numSubElements = ((_d = constantDef.varRef.varSpec.subscriptIndices) == null ? void 0 : _d.length) || 0;
|
|
1818
|
+
totalIndicesSize += 2 + numSubElements;
|
|
1819
|
+
}
|
|
1820
|
+
if (this.constantIndicesBuffer === void 0 || this.constantIndicesBuffer.numElements < totalIndicesSize) {
|
|
1821
|
+
(_e = this.constantIndicesBuffer) == null ? void 0 : _e.dispose();
|
|
1822
|
+
this.constantIndicesBuffer = createInt32WasmBuffer(this.wasmModule, totalIndicesSize);
|
|
1823
|
+
}
|
|
1824
|
+
const numConstants = constants.length;
|
|
1825
|
+
if (this.constantValuesBuffer === void 0 || this.constantValuesBuffer.numElements < numConstants) {
|
|
1826
|
+
(_f = this.constantValuesBuffer) == null ? void 0 : _f.dispose();
|
|
1827
|
+
this.constantValuesBuffer = createFloat64WasmBuffer(this.wasmModule, numConstants);
|
|
1828
|
+
}
|
|
1829
|
+
const indicesView = this.constantIndicesBuffer.getArrayView();
|
|
1830
|
+
const valuesView = this.constantValuesBuffer.getArrayView();
|
|
1831
|
+
let indicesOffset = 0;
|
|
1832
|
+
let valuesOffset = 0;
|
|
1833
|
+
indicesView[indicesOffset++] = numConstants;
|
|
1834
|
+
for (const constantDef of constants) {
|
|
1835
|
+
const varSpec = constantDef.varRef.varSpec;
|
|
1836
|
+
const numSubElements = ((_g = varSpec.subscriptIndices) == null ? void 0 : _g.length) || 0;
|
|
1837
|
+
indicesView[indicesOffset++] = varSpec.varIndex;
|
|
1838
|
+
indicesView[indicesOffset++] = numSubElements;
|
|
1839
|
+
if (numSubElements > 0) {
|
|
1840
|
+
for (let i = 0; i < numSubElements; i++) {
|
|
1841
|
+
indicesView[indicesOffset++] = varSpec.subscriptIndices[i];
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
valuesView[valuesOffset++] = constantDef.value;
|
|
1845
|
+
}
|
|
1846
|
+
constantIndicesBuffer = this.constantIndicesBuffer;
|
|
1847
|
+
constantValuesBuffer = this.constantValuesBuffer;
|
|
1848
|
+
} else {
|
|
1849
|
+
constantIndicesBuffer = void 0;
|
|
1850
|
+
constantValuesBuffer = void 0;
|
|
1851
|
+
}
|
|
1852
|
+
params.copyInputs((_h = this.inputsBuffer) == null ? void 0 : _h.getArrayView(), (numElements) => {
|
|
1663
1853
|
var _a2;
|
|
1664
1854
|
(_a2 = this.inputsBuffer) == null ? void 0 : _a2.dispose();
|
|
1665
1855
|
this.inputsBuffer = createFloat64WasmBuffer(this.wasmModule, numElements);
|
|
@@ -1667,7 +1857,7 @@ var WasmModel = class {
|
|
|
1667
1857
|
});
|
|
1668
1858
|
let outputIndicesBuffer;
|
|
1669
1859
|
if (params.getOutputIndicesLength() > 0) {
|
|
1670
|
-
params.copyOutputIndices((
|
|
1860
|
+
params.copyOutputIndices((_i = this.outputIndicesBuffer) == null ? void 0 : _i.getArrayView(), (numElements) => {
|
|
1671
1861
|
var _a2;
|
|
1672
1862
|
(_a2 = this.outputIndicesBuffer) == null ? void 0 : _a2.dispose();
|
|
1673
1863
|
this.outputIndicesBuffer = createInt32WasmBuffer(this.wasmModule, numElements);
|
|
@@ -1679,14 +1869,19 @@ var WasmModel = class {
|
|
|
1679
1869
|
}
|
|
1680
1870
|
const outputsLengthInElements = params.getOutputsLength();
|
|
1681
1871
|
if (this.outputsBuffer === void 0 || this.outputsBuffer.numElements < outputsLengthInElements) {
|
|
1682
|
-
(
|
|
1872
|
+
(_j = this.outputsBuffer) == null ? void 0 : _j.dispose();
|
|
1683
1873
|
this.outputsBuffer = createFloat64WasmBuffer(this.wasmModule, outputsLengthInElements);
|
|
1684
1874
|
}
|
|
1685
1875
|
const t0 = perfNow();
|
|
1686
1876
|
this.wasmRunModel(
|
|
1687
|
-
((
|
|
1877
|
+
((_k = this.inputsBuffer) == null ? void 0 : _k.getAddress()) || 0,
|
|
1878
|
+
// Always pass 0 (NULL) for input indices, since we assume that all input values are
|
|
1879
|
+
// provided and are in the same order as the input variables defined in the model spec
|
|
1880
|
+
0,
|
|
1688
1881
|
this.outputsBuffer.getAddress(),
|
|
1689
|
-
(outputIndicesBuffer == null ? void 0 : outputIndicesBuffer.getAddress()) || 0
|
|
1882
|
+
(outputIndicesBuffer == null ? void 0 : outputIndicesBuffer.getAddress()) || 0,
|
|
1883
|
+
(constantValuesBuffer == null ? void 0 : constantValuesBuffer.getAddress()) || 0,
|
|
1884
|
+
(constantIndicesBuffer == null ? void 0 : constantIndicesBuffer.getAddress()) || 0
|
|
1690
1885
|
);
|
|
1691
1886
|
const elapsed = perfElapsed(t0);
|
|
1692
1887
|
params.storeOutputs(this.outputsBuffer.getArrayView());
|
|
@@ -1694,13 +1889,17 @@ var WasmModel = class {
|
|
|
1694
1889
|
}
|
|
1695
1890
|
// from RunnableModel interface
|
|
1696
1891
|
terminate() {
|
|
1697
|
-
var _a, _b, _c;
|
|
1892
|
+
var _a, _b, _c, _d, _e;
|
|
1698
1893
|
(_a = this.inputsBuffer) == null ? void 0 : _a.dispose();
|
|
1699
1894
|
this.inputsBuffer = void 0;
|
|
1700
1895
|
(_b = this.outputsBuffer) == null ? void 0 : _b.dispose();
|
|
1701
1896
|
this.outputsBuffer = void 0;
|
|
1702
1897
|
(_c = this.outputIndicesBuffer) == null ? void 0 : _c.dispose();
|
|
1703
1898
|
this.outputIndicesBuffer = void 0;
|
|
1899
|
+
(_d = this.constantValuesBuffer) == null ? void 0 : _d.dispose();
|
|
1900
|
+
this.constantValuesBuffer = void 0;
|
|
1901
|
+
(_e = this.constantIndicesBuffer) == null ? void 0 : _e.dispose();
|
|
1902
|
+
this.constantIndicesBuffer = void 0;
|
|
1704
1903
|
}
|
|
1705
1904
|
};
|
|
1706
1905
|
function initWasmModel(wasmModule) {
|
|
@@ -1716,6 +1915,7 @@ var MockWasmModule = class {
|
|
|
1716
1915
|
this.mallocOffset = 8;
|
|
1717
1916
|
this.allocs = /* @__PURE__ */ new Map();
|
|
1718
1917
|
this.lookups = /* @__PURE__ */ new Map();
|
|
1918
|
+
this.constants = /* @__PURE__ */ new Map();
|
|
1719
1919
|
this.initialTime = options.initialTime;
|
|
1720
1920
|
this.finalTime = options.finalTime;
|
|
1721
1921
|
this.outputVarIds = options.outputVarIds;
|
|
@@ -1755,11 +1955,35 @@ var MockWasmModule = class {
|
|
|
1755
1955
|
this.lookups.set(varId, new JsModelLookup(numPoints, points));
|
|
1756
1956
|
};
|
|
1757
1957
|
case "runModelWithBuffers":
|
|
1758
|
-
return (inputsAddress, outputsAddress, outputIndicesAddress) => {
|
|
1958
|
+
return (inputsAddress, _inputIndicesAddress, outputsAddress, outputIndicesAddress, constantValuesAddress, constantIndicesAddress) => {
|
|
1759
1959
|
const inputs = this.getHeapView("float64", inputsAddress);
|
|
1760
1960
|
const outputs = this.getHeapView("float64", outputsAddress);
|
|
1761
1961
|
const outputIndices = this.getHeapView("int32", outputIndicesAddress);
|
|
1762
|
-
this.
|
|
1962
|
+
this.constants.clear();
|
|
1963
|
+
if (constantValuesAddress !== 0 && constantIndicesAddress !== 0) {
|
|
1964
|
+
const constantValues = this.getHeapView("float64", constantValuesAddress);
|
|
1965
|
+
const constantIndices = this.getHeapView("int32", constantIndicesAddress);
|
|
1966
|
+
const numConstants = constantIndices[0];
|
|
1967
|
+
let indicesOffset = 1;
|
|
1968
|
+
let valuesOffset = 0;
|
|
1969
|
+
for (let i = 0; i < numConstants; i++) {
|
|
1970
|
+
const varIndex = constantIndices[indicesOffset++];
|
|
1971
|
+
const subCount = constantIndices[indicesOffset++];
|
|
1972
|
+
indicesOffset += subCount;
|
|
1973
|
+
const varId = this.varIdForSpec({ varIndex });
|
|
1974
|
+
if (varId) {
|
|
1975
|
+
this.constants.set(varId, constantValues[valuesOffset++]);
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
this.onRunModel(
|
|
1980
|
+
inputs,
|
|
1981
|
+
outputs,
|
|
1982
|
+
this.constants.size > 0 ? this.constants : void 0,
|
|
1983
|
+
this.lookups,
|
|
1984
|
+
outputIndices
|
|
1985
|
+
);
|
|
1986
|
+
this.constants.clear();
|
|
1763
1987
|
};
|
|
1764
1988
|
default:
|
|
1765
1989
|
throw new Error(`Unhandled call to cwrap with function name '${fname}'`);
|
|
@@ -1837,7 +2061,7 @@ function createRunnerFromRunnableModel(model) {
|
|
|
1837
2061
|
}
|
|
1838
2062
|
return runModelSync(inputs, outputs, options);
|
|
1839
2063
|
},
|
|
1840
|
-
terminate: () => __async(
|
|
2064
|
+
terminate: () => __async(null, null, function* () {
|
|
1841
2065
|
if (!terminated) {
|
|
1842
2066
|
model.terminate();
|
|
1843
2067
|
terminated = true;
|
|
@@ -1862,7 +2086,7 @@ var ModelScheduler = class {
|
|
|
1862
2086
|
/** Whether a model run is in progress. */
|
|
1863
2087
|
this.runInProgress = false;
|
|
1864
2088
|
const afterSet = () => {
|
|
1865
|
-
this.
|
|
2089
|
+
this.runModelIfNeeded();
|
|
1866
2090
|
};
|
|
1867
2091
|
for (const userInput of userInputs) {
|
|
1868
2092
|
userInput.callbacks.onSet = afterSet;
|
|
@@ -1873,24 +2097,24 @@ var ModelScheduler = class {
|
|
|
1873
2097
|
}
|
|
1874
2098
|
}
|
|
1875
2099
|
/**
|
|
1876
|
-
* Schedule a
|
|
2100
|
+
* Schedule a model run (if not already pending). When the run is
|
|
1877
2101
|
* complete, save the outputs and call the `onOutputsChanged` callback.
|
|
1878
2102
|
*/
|
|
1879
|
-
|
|
2103
|
+
runModelIfNeeded() {
|
|
1880
2104
|
this.runNeeded = true;
|
|
1881
2105
|
if (this.runInProgress) {
|
|
1882
2106
|
return;
|
|
1883
2107
|
} else {
|
|
1884
2108
|
this.runInProgress = true;
|
|
1885
2109
|
setTimeout(() => {
|
|
1886
|
-
this.
|
|
2110
|
+
this.runModelNow();
|
|
1887
2111
|
}, 0);
|
|
1888
2112
|
}
|
|
1889
2113
|
}
|
|
1890
2114
|
/**
|
|
1891
|
-
* Run the
|
|
2115
|
+
* Run the model asynchronously using the current set of input values.
|
|
1892
2116
|
*/
|
|
1893
|
-
|
|
2117
|
+
runModelNow() {
|
|
1894
2118
|
return __async(this, null, function* () {
|
|
1895
2119
|
var _a;
|
|
1896
2120
|
for (let i = 0; i < this.userInputs.length; i++) {
|
|
@@ -1905,7 +2129,7 @@ var ModelScheduler = class {
|
|
|
1905
2129
|
if (this.runNeeded) {
|
|
1906
2130
|
this.runNeeded = false;
|
|
1907
2131
|
setTimeout(() => {
|
|
1908
|
-
this.
|
|
2132
|
+
this.runModelNow();
|
|
1909
2133
|
}, 0);
|
|
1910
2134
|
} else {
|
|
1911
2135
|
this.runNeeded = false;
|
|
@@ -1927,23 +2151,214 @@ function createSimpleInputValue(varId) {
|
|
|
1927
2151
|
};
|
|
1928
2152
|
return { varId, get, set, reset, callbacks: {} };
|
|
1929
2153
|
}
|
|
2154
|
+
|
|
2155
|
+
// src/model-scheduler/multi-context-model-scheduler.ts
|
|
2156
|
+
var MultiContextModelScheduler = class {
|
|
2157
|
+
/**
|
|
2158
|
+
* @param runner The model runner.
|
|
2159
|
+
* @param options Additional options for the scheduler.
|
|
2160
|
+
* @param options.initialOutputs An optional `Outputs` instance that will be reused
|
|
2161
|
+
* for the initial context. This is useful for saving memory when an `Outputs`
|
|
2162
|
+
* instance was already created for, e.g., a initial baseline/reference run.
|
|
2163
|
+
*/
|
|
2164
|
+
constructor(runner, options) {
|
|
2165
|
+
this.runner = runner;
|
|
2166
|
+
/** The contexts that hold distinct sets of inputs and outputs. */
|
|
2167
|
+
this.contexts = [];
|
|
2168
|
+
/** Whether a model run has been scheduled. */
|
|
2169
|
+
this.runNeeded = false;
|
|
2170
|
+
/** Whether a model run is in progress. */
|
|
2171
|
+
this.runInProgress = false;
|
|
2172
|
+
this.initialOutputs = options == null ? void 0 : options.initialOutputs;
|
|
2173
|
+
}
|
|
2174
|
+
/**
|
|
2175
|
+
* Return true if the scheduler has started any model runs.
|
|
2176
|
+
*/
|
|
2177
|
+
isStarted() {
|
|
2178
|
+
return this.initialOutputs === void 0;
|
|
2179
|
+
}
|
|
2180
|
+
/**
|
|
2181
|
+
* Add a new context that holds a distinct set of model inputs and outputs.
|
|
2182
|
+
* These inputs and outputs are kept separate from those in other contexts,
|
|
2183
|
+
* which allows an application to use the same underlying model to run with
|
|
2184
|
+
* multiple I/O contexts.
|
|
2185
|
+
*
|
|
2186
|
+
* Note that the contexts created before the first scheduled model run
|
|
2187
|
+
* will inherit the data from `initialOutputs` passed to the constructor,
|
|
2188
|
+
* but contexts created after that will initially have output values set
|
|
2189
|
+
* to zero.
|
|
2190
|
+
*
|
|
2191
|
+
* @param inputs The input values, in the same order as in the spec file passed to `sde`.
|
|
2192
|
+
* @param options Additional options for the context.
|
|
2193
|
+
* @param options.externalData Additional data that is external to the model outputs.
|
|
2194
|
+
* For example, this can contain data that was captured from an initial reference
|
|
2195
|
+
* run, or other static data that is displayed in graphs alongside the model
|
|
2196
|
+
* output data in graphs.
|
|
2197
|
+
*/
|
|
2198
|
+
addContext(inputs, options) {
|
|
2199
|
+
let outputs;
|
|
2200
|
+
if (this.initialOutputs !== void 0) {
|
|
2201
|
+
if (this.contexts.length === 0) {
|
|
2202
|
+
outputs = this.initialOutputs;
|
|
2203
|
+
} else {
|
|
2204
|
+
outputs = this.runner.createOutputs();
|
|
2205
|
+
for (const varId of outputs.varIds) {
|
|
2206
|
+
const series0 = this.initialOutputs.getSeriesForVar(varId);
|
|
2207
|
+
const series1 = outputs.getSeriesForVar(varId);
|
|
2208
|
+
for (let i = 0; i < series0.points.length; i++) {
|
|
2209
|
+
series1.points[i].y = series0.points[i].y;
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
} else {
|
|
2214
|
+
outputs = this.runner.createOutputs();
|
|
2215
|
+
}
|
|
2216
|
+
const context = new ModelContextImpl(inputs, outputs, options == null ? void 0 : options.externalData);
|
|
2217
|
+
const afterSet = () => {
|
|
2218
|
+
context.runNeeded = true;
|
|
2219
|
+
this.runModelIfNeeded();
|
|
2220
|
+
};
|
|
2221
|
+
for (const input of inputs) {
|
|
2222
|
+
input.callbacks.onSet = afterSet;
|
|
2223
|
+
}
|
|
2224
|
+
this.contexts.push(context);
|
|
2225
|
+
return context;
|
|
2226
|
+
}
|
|
2227
|
+
/**
|
|
2228
|
+
* Remove the given context from the set of contexts managed by the scheduler.
|
|
2229
|
+
*
|
|
2230
|
+
* @param context The context to remove.
|
|
2231
|
+
*/
|
|
2232
|
+
removeContext(context) {
|
|
2233
|
+
const index = this.contexts.findIndex((c) => c === context);
|
|
2234
|
+
if (index >= 0) {
|
|
2235
|
+
this.contexts.splice(index, 1);
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
/**
|
|
2239
|
+
* Schedule a model run (if not already pending). When the run is
|
|
2240
|
+
* complete, save the outputs and call the `onOutputsChanged` callback.
|
|
2241
|
+
*/
|
|
2242
|
+
runModelIfNeeded() {
|
|
2243
|
+
this.runNeeded = true;
|
|
2244
|
+
if (this.runInProgress) {
|
|
2245
|
+
return;
|
|
2246
|
+
} else {
|
|
2247
|
+
this.runInProgress = true;
|
|
2248
|
+
setTimeout(() => {
|
|
2249
|
+
this.runModelNow();
|
|
2250
|
+
}, 0);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* Run the model asynchronously for all relevant contexts.
|
|
2255
|
+
*/
|
|
2256
|
+
runModelNow() {
|
|
2257
|
+
return __async(this, null, function* () {
|
|
2258
|
+
this.initialOutputs = void 0;
|
|
2259
|
+
for (const context of this.contexts) {
|
|
2260
|
+
if (context.runNeeded) {
|
|
2261
|
+
context.runNeeded = false;
|
|
2262
|
+
yield this.runModelNowForContext(context);
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
if (this.runNeeded) {
|
|
2266
|
+
this.runNeeded = false;
|
|
2267
|
+
setTimeout(() => {
|
|
2268
|
+
this.runModelNow();
|
|
2269
|
+
}, 0);
|
|
2270
|
+
} else {
|
|
2271
|
+
this.runNeeded = false;
|
|
2272
|
+
this.runInProgress = false;
|
|
2273
|
+
}
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
/**
|
|
2277
|
+
* Run the model asynchronously using the current set of input values in the given context.
|
|
2278
|
+
*
|
|
2279
|
+
* @param context The context to use for the model run.
|
|
2280
|
+
*/
|
|
2281
|
+
runModelNowForContext(context) {
|
|
2282
|
+
return __async(this, null, function* () {
|
|
2283
|
+
var _a;
|
|
2284
|
+
if (this.currentInputs === void 0) {
|
|
2285
|
+
this.currentInputs = Array(context.inputsArray.length);
|
|
2286
|
+
}
|
|
2287
|
+
for (let i = 0; i < context.inputsArray.length; i++) {
|
|
2288
|
+
this.currentInputs[i] = context.inputsArray[i].get();
|
|
2289
|
+
}
|
|
2290
|
+
try {
|
|
2291
|
+
yield this.runner.runModel(this.currentInputs, context.outputs);
|
|
2292
|
+
(_a = context.onOutputsChanged) == null ? void 0 : _a.call(context);
|
|
2293
|
+
} catch (e) {
|
|
2294
|
+
console.error("ERROR: The scheduler encountered an error when running the model:", e);
|
|
2295
|
+
}
|
|
2296
|
+
});
|
|
2297
|
+
}
|
|
2298
|
+
};
|
|
2299
|
+
var ModelContextImpl = class {
|
|
2300
|
+
/**
|
|
2301
|
+
* @hidden This is intended for use by `MultiContextModelScheduler` only.
|
|
2302
|
+
*
|
|
2303
|
+
* @param inputs The input values, in the same order as in the spec file passed to `sde`.
|
|
2304
|
+
* @param outputs The structure into which the model outputs will be stored.
|
|
2305
|
+
* @param externalData Additional data that is external to the model outputs. For example, this can contain
|
|
2306
|
+
* data that was captured from an initial reference run, or other static data that is displayed in graphs
|
|
2307
|
+
* alongside the model output data in graphs.
|
|
2308
|
+
*/
|
|
2309
|
+
constructor(inputs, outputs, externalData) {
|
|
2310
|
+
this.externalData = externalData;
|
|
2311
|
+
/**
|
|
2312
|
+
* Whether a model run is needed for this context.
|
|
2313
|
+
* @hidden This is intended for use by `MultiContextModelScheduler` only.
|
|
2314
|
+
*/
|
|
2315
|
+
this.runNeeded = false;
|
|
2316
|
+
this.inputsArray = Array.from(inputs);
|
|
2317
|
+
this.outputs = outputs;
|
|
2318
|
+
}
|
|
2319
|
+
/**
|
|
2320
|
+
* Return the series data for the given model output variable or external
|
|
2321
|
+
* dataset.
|
|
2322
|
+
*
|
|
2323
|
+
* @param varId The ID of the output variable associated with the data.
|
|
2324
|
+
* @param sourceName The external data source name (e.g. "Ref"), or
|
|
2325
|
+
* undefined to use the latest model output data from this context.
|
|
2326
|
+
*/
|
|
2327
|
+
getSeriesForVar(varId, sourceName) {
|
|
2328
|
+
if (sourceName === void 0) {
|
|
2329
|
+
return this.outputs.getSeriesForVar(varId);
|
|
2330
|
+
} else {
|
|
2331
|
+
const dataForSource = this.externalData.get(sourceName);
|
|
2332
|
+
if (dataForSource !== void 0) {
|
|
2333
|
+
return dataForSource.get(varId);
|
|
2334
|
+
} else {
|
|
2335
|
+
return void 0;
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
};
|
|
1930
2340
|
export {
|
|
1931
2341
|
BufferedRunModelParams,
|
|
1932
2342
|
MockJsModel,
|
|
1933
2343
|
MockWasmModule,
|
|
1934
2344
|
ModelListing,
|
|
1935
2345
|
ModelScheduler,
|
|
2346
|
+
MultiContextModelScheduler,
|
|
1936
2347
|
Outputs,
|
|
1937
2348
|
ReferencedRunModelParams,
|
|
1938
2349
|
Series,
|
|
2350
|
+
createConstantDef,
|
|
1939
2351
|
createInputValue,
|
|
1940
2352
|
createLookupDef,
|
|
1941
2353
|
createRunnableModel,
|
|
1942
2354
|
createSynchronousModelRunner,
|
|
2355
|
+
decodeConstants,
|
|
1943
2356
|
decodeLookups,
|
|
2357
|
+
encodeConstants,
|
|
1944
2358
|
encodeLookups,
|
|
1945
2359
|
encodeVarIndices,
|
|
1946
2360
|
execJsModel,
|
|
2361
|
+
getEncodedConstantBufferLengths,
|
|
1947
2362
|
getEncodedLookupBufferLengths,
|
|
1948
2363
|
getEncodedVarIndicesLength,
|
|
1949
2364
|
getJsModelFunctions,
|