cpsat-js 1.0.0 → 1.2.0
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 +118 -4
- package/build/{cpsat.mjs → portable/cpsat.mjs} +1 -1
- package/build/{cpsat.wasm → portable/cpsat.wasm} +0 -0
- package/build/threaded/cpsat.mjs +2 -0
- package/build/threaded/cpsat.wasm +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.portable.d.ts +2 -0
- package/dist/index.portable.d.ts.map +1 -0
- package/dist/index.portable.js +17 -0
- package/dist/index.portable.js.map +1 -0
- package/dist/index.threaded.d.ts +2 -0
- package/dist/index.threaded.d.ts.map +1 -0
- package/dist/index.threaded.js +17 -0
- package/dist/index.threaded.js.map +1 -0
- package/dist/model/cp-model.d.ts +23 -0
- package/dist/model/cp-model.d.ts.map +1 -1
- package/dist/model/cp-model.js +37 -1
- package/dist/model/cp-model.js.map +1 -1
- package/dist/solver/cp-solver.d.ts +67 -0
- package/dist/solver/cp-solver.d.ts.map +1 -1
- package/dist/solver/cp-solver.js +72 -15
- package/dist/solver/cp-solver.js.map +1 -1
- package/package.json +21 -10
package/dist/solver/cp-solver.js
CHANGED
|
@@ -2,6 +2,26 @@ import { create, toBinary, fromBinary } from '@bufbuild/protobuf';
|
|
|
2
2
|
import { CpModelProtoSchema, CpSolverResponseSchema, CpSolverStatus, } from '../generated/cp_model_pb.js';
|
|
3
3
|
import { SatParametersSchema, } from '../generated/sat_parameters_pb.js';
|
|
4
4
|
export { CpSolverStatus };
|
|
5
|
+
let glueLoader;
|
|
6
|
+
let glueIsThreaded = false;
|
|
7
|
+
/** @internal — called by the package entry point (index.threaded / index.portable). */
|
|
8
|
+
export function setGlueLoader(loader, threaded) {
|
|
9
|
+
glueLoader = loader;
|
|
10
|
+
glueIsThreaded = threaded;
|
|
11
|
+
}
|
|
12
|
+
/** Build the caller-facing view of a response. Shared by results and incumbents. */
|
|
13
|
+
function readResponse(response) {
|
|
14
|
+
return {
|
|
15
|
+
status: response.status,
|
|
16
|
+
objectiveValue: response.objectiveValue,
|
|
17
|
+
bestObjectiveBound: response.bestObjectiveBound,
|
|
18
|
+
wallTime: response.wallTime,
|
|
19
|
+
value(variable) {
|
|
20
|
+
return Number(response.solution[variable.index]);
|
|
21
|
+
},
|
|
22
|
+
response,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
5
25
|
/**
|
|
6
26
|
* Loads the WASM module and solves CP-SAT models.
|
|
7
27
|
*
|
|
@@ -15,8 +35,12 @@ export class CpSolver {
|
|
|
15
35
|
this.module = module;
|
|
16
36
|
}
|
|
17
37
|
static async create(options) {
|
|
18
|
-
|
|
19
|
-
|
|
38
|
+
if (!glueLoader) {
|
|
39
|
+
throw new Error("No WASM build was registered. Import the package entry point ('cpsat-js', " +
|
|
40
|
+
"'cpsat-js/threaded' or 'cpsat-js/portable') rather than a deep internal path.");
|
|
41
|
+
}
|
|
42
|
+
// The glue — and therefore the 6MB WASM — is only loaded here, on first create().
|
|
43
|
+
const createModule = await glueLoader(options?.locateFile);
|
|
20
44
|
const module = await createModule();
|
|
21
45
|
return new CpSolver(module);
|
|
22
46
|
}
|
|
@@ -24,14 +48,21 @@ export class CpSolver {
|
|
|
24
48
|
const modelProto = model.toProto();
|
|
25
49
|
const modelBytes = toBinary(CpModelProtoSchema, modelProto);
|
|
26
50
|
const satParams = create(SatParametersSchema, {});
|
|
27
|
-
//
|
|
28
|
-
|
|
51
|
+
// CP-SAT's speed comes from its parallel subsolver portfolio, which only engages
|
|
52
|
+
// at >= 6 workers; 2 and 4 are measurably SLOWER than 1. The threaded WASM is
|
|
53
|
+
// built with a pre-spawned pthread pool, so 8 is both safe and the right default.
|
|
54
|
+
satParams.numWorkers = 8;
|
|
29
55
|
if (params?.maxTimeInSeconds !== undefined) {
|
|
30
56
|
satParams.maxTimeInSeconds = params.maxTimeInSeconds;
|
|
31
57
|
}
|
|
32
58
|
if (params?.numWorkers !== undefined) {
|
|
33
59
|
satParams.numWorkers = params.numWorkers;
|
|
34
60
|
}
|
|
61
|
+
// The portable build has no threads. Clamp to 1 rather than to some lower count:
|
|
62
|
+
// anything in 2..5 selects a degraded portfolio and is slower than a single worker.
|
|
63
|
+
if (!glueIsThreaded) {
|
|
64
|
+
satParams.numWorkers = 1;
|
|
65
|
+
}
|
|
35
66
|
const paramsBytes = toBinary(SatParametersSchema, satParams);
|
|
36
67
|
// Allocate WASM heap memory for model
|
|
37
68
|
const modelPtr = this.module._malloc(modelBytes.length);
|
|
@@ -39,13 +70,34 @@ export class CpSolver {
|
|
|
39
70
|
// Allocate WASM heap memory for params
|
|
40
71
|
const paramsPtr = this.module._malloc(paramsBytes.length);
|
|
41
72
|
this.module.HEAPU8.set(paramsBytes, paramsPtr);
|
|
73
|
+
const onSolution = params?.onSolution;
|
|
74
|
+
if (onSolution) {
|
|
75
|
+
this.module.__cpsatOnSolution = (bytes) => {
|
|
76
|
+
onSolution({ ...readResponse(fromBinary(CpSolverResponseSchema, bytes)), live: true });
|
|
77
|
+
};
|
|
78
|
+
}
|
|
42
79
|
let resultLen;
|
|
43
80
|
try {
|
|
44
|
-
resultLen = this.module._solve(modelPtr, modelBytes.length, paramsPtr, paramsBytes.length);
|
|
81
|
+
resultLen = this.module._solve(modelPtr, modelBytes.length, paramsPtr, paramsBytes.length, onSolution ? 1 : 0);
|
|
45
82
|
}
|
|
46
83
|
finally {
|
|
47
84
|
this.module._free(modelPtr);
|
|
48
85
|
this.module._free(paramsPtr);
|
|
86
|
+
delete this.module.__cpsatOnSolution;
|
|
87
|
+
}
|
|
88
|
+
// Incumbents the observer could only record, because it ran on a thread that
|
|
89
|
+
// cannot enter JS. Drained unconditionally: a live solve recorded nothing, so the
|
|
90
|
+
// count is zero and this does nothing. That way the 1-vs-many rule lives in one
|
|
91
|
+
// place — the C++ observer — and is never restated here to drift out of step.
|
|
92
|
+
if (onSolution) {
|
|
93
|
+
const recorded = this.module._solution_count();
|
|
94
|
+
for (let i = 0; i < recorded; i++) {
|
|
95
|
+
const ptr = this.module._solution_ptr(i);
|
|
96
|
+
const len = this.module._solution_len(i);
|
|
97
|
+
// Re-read HEAPU8 each time: growing the heap replaces the buffer.
|
|
98
|
+
const bytes = this.module.HEAPU8.slice(ptr, ptr + len);
|
|
99
|
+
onSolution({ ...readResponse(fromBinary(CpSolverResponseSchema, bytes)), live: false });
|
|
100
|
+
}
|
|
49
101
|
}
|
|
50
102
|
// Read result from WASM memory
|
|
51
103
|
const resultPtr = this.module._get_result_ptr();
|
|
@@ -66,15 +118,20 @@ export class CpSolver {
|
|
|
66
118
|
};
|
|
67
119
|
}
|
|
68
120
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Shared plumbing for the per-variant glue loaders. Each caller passes its own
|
|
123
|
+
* statically-analysable import, so only that variant's WASM is ever emitted.
|
|
124
|
+
*/
|
|
125
|
+
export function makeGlueLoader(importGlue, wasmUrl) {
|
|
126
|
+
return async (locateFile) => {
|
|
127
|
+
const glue = await importGlue();
|
|
128
|
+
const factory = glue.default;
|
|
129
|
+
if (typeof factory !== 'function') {
|
|
130
|
+
throw new Error('cpsat glue did not export a factory function');
|
|
131
|
+
}
|
|
132
|
+
const url = wasmUrl();
|
|
133
|
+
const resolvedLocate = locateFile ?? ((path) => (path.endsWith('.wasm') ? url : path));
|
|
134
|
+
return (options) => factory({ ...options, locateFile: resolvedLocate });
|
|
135
|
+
};
|
|
79
136
|
}
|
|
80
137
|
//# sourceMappingURL=cp-solver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cp-solver.js","sourceRoot":"","sources":["../../src/solver/cp-solver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,GAEf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAI3C,OAAO,EAAE,cAAc,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"cp-solver.js","sourceRoot":"","sources":["../../src/solver/cp-solver.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cpsat-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "WebAssembly port of Google OR-Tools CP-SAT constraint programming solver",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
6
|
+
"main": "dist/index.portable.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"browser": "./dist/index.portable.js",
|
|
12
|
+
"node": "./dist/index.threaded.js",
|
|
13
|
+
"default": "./dist/index.portable.js"
|
|
12
14
|
},
|
|
13
|
-
"./
|
|
15
|
+
"./threaded": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.threaded.js"
|
|
18
|
+
},
|
|
19
|
+
"./portable": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.portable.js"
|
|
22
|
+
}
|
|
14
23
|
},
|
|
15
24
|
"files": [
|
|
16
25
|
"dist/",
|
|
17
|
-
"build/cpsat.mjs",
|
|
18
|
-
"build/cpsat.wasm"
|
|
26
|
+
"build/threaded/cpsat.mjs",
|
|
27
|
+
"build/threaded/cpsat.wasm",
|
|
28
|
+
"build/portable/cpsat.mjs",
|
|
29
|
+
"build/portable/cpsat.wasm"
|
|
19
30
|
],
|
|
20
31
|
"scripts": {
|
|
21
32
|
"build:wasm": "./build.sh",
|
|
@@ -39,11 +50,11 @@
|
|
|
39
50
|
"license": "Apache-2.0",
|
|
40
51
|
"repository": {
|
|
41
52
|
"type": "git",
|
|
42
|
-
"url": "git+
|
|
53
|
+
"url": "git+https://github.com/owen-lacey/cpsat-js.git"
|
|
43
54
|
},
|
|
44
|
-
"homepage": "https://github.com/owen-lacey/
|
|
55
|
+
"homepage": "https://github.com/owen-lacey/cpsat-js#readme",
|
|
45
56
|
"bugs": {
|
|
46
|
-
"url": "https://github.com/owen-lacey/
|
|
57
|
+
"url": "https://github.com/owen-lacey/cpsat-js/issues"
|
|
47
58
|
},
|
|
48
59
|
"dependencies": {
|
|
49
60
|
"@bufbuild/protobuf": "^2.3.0"
|