@graphty/graph-format 0.0.0 → 0.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/LICENSE +21 -0
- package/README.md +216 -43
- package/dist/graph-format.d.ts +1 -0
- package/dist/graph-format.d.ts.map +1 -0
- package/dist/graph-format.js +15798 -0
- package/dist/graph-format.js.map +1 -0
- package/dist/src/builder/arena.d.ts +85 -0
- package/dist/src/builder/arena.d.ts.map +1 -0
- package/dist/src/builder/arena.js +154 -0
- package/dist/src/builder/arena.js.map +1 -0
- package/dist/src/builder/compact.d.ts +515 -0
- package/dist/src/builder/compact.d.ts.map +1 -0
- package/dist/src/builder/compact.js +1553 -0
- package/dist/src/builder/compact.js.map +1 -0
- package/dist/src/builder/counting-sort.d.ts +96 -0
- package/dist/src/builder/counting-sort.d.ts.map +1 -0
- package/dist/src/builder/counting-sort.js +430 -0
- package/dist/src/builder/counting-sort.js.map +1 -0
- package/dist/src/builder/freeze.d.ts +72 -0
- package/dist/src/builder/freeze.d.ts.map +1 -0
- package/dist/src/builder/freeze.js +548 -0
- package/dist/src/builder/freeze.js.map +1 -0
- package/dist/src/builder/graph-builder.d.ts +602 -0
- package/dist/src/builder/graph-builder.d.ts.map +1 -0
- package/dist/src/builder/graph-builder.js +1940 -0
- package/dist/src/builder/graph-builder.js.map +1 -0
- package/dist/src/builder/options.d.ts +16 -0
- package/dist/src/builder/options.d.ts.map +1 -0
- package/dist/src/builder/options.js +21 -0
- package/dist/src/builder/options.js.map +1 -0
- package/dist/src/columns/bitmap.d.ts +96 -0
- package/dist/src/columns/bitmap.d.ts.map +1 -0
- package/dist/src/columns/bitmap.js +184 -0
- package/dist/src/columns/bitmap.js.map +1 -0
- package/dist/src/columns/column.d.ts +220 -0
- package/dist/src/columns/column.d.ts.map +1 -0
- package/dist/src/columns/column.js +2109 -0
- package/dist/src/columns/column.js.map +1 -0
- package/dist/src/columns/dictionary.d.ts +60 -0
- package/dist/src/columns/dictionary.d.ts.map +1 -0
- package/dist/src/columns/dictionary.js +102 -0
- package/dist/src/columns/dictionary.js.map +1 -0
- package/dist/src/columns/growable.d.ts +198 -0
- package/dist/src/columns/growable.d.ts.map +1 -0
- package/dist/src/columns/growable.js +296 -0
- package/dist/src/columns/growable.js.map +1 -0
- package/dist/src/columns/infer.d.ts +121 -0
- package/dist/src/columns/infer.d.ts.map +1 -0
- package/dist/src/columns/infer.js +268 -0
- package/dist/src/columns/infer.js.map +1 -0
- package/dist/src/columns/remap.d.ts +143 -0
- package/dist/src/columns/remap.d.ts.map +1 -0
- package/dist/src/columns/remap.js +588 -0
- package/dist/src/columns/remap.js.map +1 -0
- package/dist/src/columns/table.d.ts +184 -0
- package/dist/src/columns/table.d.ts.map +1 -0
- package/dist/src/columns/table.js +485 -0
- package/dist/src/columns/table.js.map +1 -0
- package/dist/src/constants.d.ts +34 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +79 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/errors.d.ts +76 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +32 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/ids/edge-id-index.d.ts +77 -0
- package/dist/src/ids/edge-id-index.d.ts.map +1 -0
- package/dist/src/ids/edge-id-index.js +155 -0
- package/dist/src/ids/edge-id-index.js.map +1 -0
- package/dist/src/ids/node-id-map.d.ts +280 -0
- package/dist/src/ids/node-id-map.d.ts.map +1 -0
- package/dist/src/ids/node-id-map.js +1139 -0
- package/dist/src/ids/node-id-map.js.map +1 -0
- package/dist/src/ids/string-store.d.ts +219 -0
- package/dist/src/ids/string-store.d.ts.map +1 -0
- package/dist/src/ids/string-store.js +526 -0
- package/dist/src/ids/string-store.js.map +1 -0
- package/dist/src/index.d.ts +30 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +29 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/populate/from-csr.d.ts +61 -0
- package/dist/src/populate/from-csr.d.ts.map +1 -0
- package/dist/src/populate/from-csr.js +706 -0
- package/dist/src/populate/from-csr.js.map +1 -0
- package/dist/src/populate/from-edge-arrays.d.ts +51 -0
- package/dist/src/populate/from-edge-arrays.d.ts.map +1 -0
- package/dist/src/populate/from-edge-arrays.js +217 -0
- package/dist/src/populate/from-edge-arrays.js.map +1 -0
- package/dist/src/populate/from-records.d.ts +51 -0
- package/dist/src/populate/from-records.d.ts.map +1 -0
- package/dist/src/populate/from-records.js +447 -0
- package/dist/src/populate/from-records.js.map +1 -0
- package/dist/src/snapshot/derived.d.ts +211 -0
- package/dist/src/snapshot/derived.d.ts.map +1 -0
- package/dist/src/snapshot/derived.js +1254 -0
- package/dist/src/snapshot/derived.js.map +1 -0
- package/dist/src/snapshot/graph-meta.d.ts +23 -0
- package/dist/src/snapshot/graph-meta.d.ts.map +1 -0
- package/dist/src/snapshot/graph-meta.js +159 -0
- package/dist/src/snapshot/graph-meta.js.map +1 -0
- package/dist/src/snapshot/graph-snapshot.d.ts +509 -0
- package/dist/src/snapshot/graph-snapshot.d.ts.map +1 -0
- package/dist/src/snapshot/graph-snapshot.js +1247 -0
- package/dist/src/snapshot/graph-snapshot.js.map +1 -0
- package/dist/src/snapshot/hash.d.ts +90 -0
- package/dist/src/snapshot/hash.d.ts.map +1 -0
- package/dist/src/snapshot/hash.js +228 -0
- package/dist/src/snapshot/hash.js.map +1 -0
- package/dist/src/snapshot/queries.d.ts +74 -0
- package/dist/src/snapshot/queries.d.ts.map +1 -0
- package/dist/src/snapshot/queries.js +131 -0
- package/dist/src/snapshot/queries.js.map +1 -0
- package/dist/src/snapshot/validate.d.ts +192 -0
- package/dist/src/snapshot/validate.d.ts.map +1 -0
- package/dist/src/snapshot/validate.js +990 -0
- package/dist/src/snapshot/validate.js.map +1 -0
- package/dist/src/snapshot/views.d.ts +274 -0
- package/dist/src/snapshot/views.d.ts.map +1 -0
- package/dist/src/snapshot/views.js +856 -0
- package/dist/src/snapshot/views.js.map +1 -0
- package/dist/src/types/builder.d.ts +456 -0
- package/dist/src/types/builder.d.ts.map +1 -0
- package/dist/src/types/builder.js +11 -0
- package/dist/src/types/builder.js.map +1 -0
- package/dist/src/types/columns.d.ts +615 -0
- package/dist/src/types/columns.d.ts.map +1 -0
- package/dist/src/types/columns.js +14 -0
- package/dist/src/types/columns.js.map +1 -0
- package/dist/src/types/index.d.ts +14 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +11 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/internal.d.ts +172 -0
- package/dist/src/types/internal.d.ts.map +1 -0
- package/dist/src/types/internal.js +13 -0
- package/dist/src/types/internal.js.map +1 -0
- package/dist/src/types/snapshot.d.ts +801 -0
- package/dist/src/types/snapshot.d.ts.map +1 -0
- package/dist/src/types/snapshot.js +14 -0
- package/dist/src/types/snapshot.js.map +1 -0
- package/dist/src/types/wire.d.ts +196 -0
- package/dist/src/types/wire.d.ts.map +1 -0
- package/dist/src/types/wire.js +8 -0
- package/dist/src/types/wire.js.map +1 -0
- package/dist/src/util/mask.d.ts +55 -0
- package/dist/src/util/mask.d.ts.map +1 -0
- package/dist/src/util/mask.js +71 -0
- package/dist/src/util/mask.js.map +1 -0
- package/dist/src/util/options.d.ts +22 -0
- package/dist/src/util/options.d.ts.map +1 -0
- package/dist/src/util/options.js +49 -0
- package/dist/src/util/options.js.map +1 -0
- package/dist/src/util/shared-buffers.d.ts +42 -0
- package/dist/src/util/shared-buffers.d.ts.map +1 -0
- package/dist/src/util/shared-buffers.js +52 -0
- package/dist/src/util/shared-buffers.js.map +1 -0
- package/dist/src/util/typed-array.d.ts +205 -0
- package/dist/src/util/typed-array.d.ts.map +1 -0
- package/dist/src/util/typed-array.js +289 -0
- package/dist/src/util/typed-array.js.map +1 -0
- package/dist/src/wire/bytes.d.ts +69 -0
- package/dist/src/wire/bytes.d.ts.map +1 -0
- package/dist/src/wire/bytes.js +361 -0
- package/dist/src/wire/bytes.js.map +1 -0
- package/dist/src/wire/carried-views.d.ts +111 -0
- package/dist/src/wire/carried-views.d.ts.map +1 -0
- package/dist/src/wire/carried-views.js +286 -0
- package/dist/src/wire/carried-views.js.map +1 -0
- package/dist/src/wire/from-wire.d.ts +144 -0
- package/dist/src/wire/from-wire.d.ts.map +1 -0
- package/dist/src/wire/from-wire.js +1425 -0
- package/dist/src/wire/from-wire.js.map +1 -0
- package/dist/src/wire/to-wire.d.ts +171 -0
- package/dist/src/wire/to-wire.d.ts.map +1 -0
- package/dist/src/wire/to-wire.js +652 -0
- package/dist/src/wire/to-wire.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +72 -7
- package/src/builder/arena.ts +192 -0
- package/src/builder/compact.ts +1811 -0
- package/src/builder/counting-sort.ts +506 -0
- package/src/builder/freeze.ts +689 -0
- package/src/builder/graph-builder.ts +2264 -0
- package/src/builder/options.ts +29 -0
- package/src/columns/bitmap.ts +196 -0
- package/src/columns/column.ts +2574 -0
- package/src/columns/dictionary.ts +114 -0
- package/src/columns/growable.ts +350 -0
- package/src/columns/infer.ts +285 -0
- package/src/columns/remap.ts +663 -0
- package/src/columns/table.ts +568 -0
- package/src/constants.ts +89 -0
- package/src/errors.ts +115 -0
- package/src/ids/edge-id-index.ts +179 -0
- package/src/ids/node-id-map.ts +1340 -0
- package/src/ids/string-store.ts +589 -0
- package/src/index.ts +139 -0
- package/src/lib-resizable-array-buffer.d.ts +34 -0
- package/src/populate/from-csr.ts +802 -0
- package/src/populate/from-edge-arrays.ts +257 -0
- package/src/populate/from-records.ts +536 -0
- package/src/snapshot/derived.ts +1486 -0
- package/src/snapshot/graph-meta.ts +167 -0
- package/src/snapshot/graph-snapshot.ts +1503 -0
- package/src/snapshot/hash.ts +241 -0
- package/src/snapshot/queries.ts +136 -0
- package/src/snapshot/validate.ts +1108 -0
- package/src/snapshot/views.ts +943 -0
- package/src/types/builder.ts +480 -0
- package/src/types/columns.ts +727 -0
- package/src/types/index.ts +14 -0
- package/src/types/internal.ts +195 -0
- package/src/types/snapshot.ts +886 -0
- package/src/types/wire.ts +207 -0
- package/src/util/mask.ts +89 -0
- package/src/util/options.ts +57 -0
- package/src/util/shared-buffers.ts +56 -0
- package/src/util/typed-array.ts +371 -0
- package/src/wire/bytes.ts +440 -0
- package/src/wire/carried-views.ts +327 -0
- package/src/wire/from-wire.ts +1690 -0
- package/src/wire/to-wire.ts +755 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content checks of the views a wire manifest carries (`includeViews`, design sections 9.1 and 9.5),
|
|
3
|
+
* run at the "structure" level before a carried view is installed on the receiver. Every view is a
|
|
4
|
+
* pure function of the core (design section 7.2), so each check is exact: the index views are
|
|
5
|
+
* compared with what the core says arc by arc in O(n + m) without allocating a second copy, and the
|
|
6
|
+
* four f64 views are compared with the snapshot's own computation. A view that disagrees is
|
|
7
|
+
* E_INVALID_SNAPSHOT with `details.invariant` "I2" (a corrupt index array) or "I17" (a corrupt
|
|
8
|
+
* value array) and `details.view` naming it. At "none" nothing is checked (the manifest is trusted,
|
|
9
|
+
* design section 9.5); at "full" carried views are never installed.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { type GraphFormatError } from "../errors.js";
|
|
13
|
+
import { type GraphSnapshot } from "../snapshot/graph-snapshot.js";
|
|
14
|
+
import { invariantViolation } from "../snapshot/validate.js";
|
|
15
|
+
import { DEGREE_TIER_HIGH, DEGREE_TIER_MID, rowLengths } from "../snapshot/views.js";
|
|
16
|
+
import { type F32, type F64, type ReverseView, type U32 } from "../types/index.js";
|
|
17
|
+
|
|
18
|
+
/** The per-arc facts every index-view check reads, computed once per manifest. */
|
|
19
|
+
export class CoreFacts {
|
|
20
|
+
/** The row (source) of every arc. */
|
|
21
|
+
readonly arcRow: U32;
|
|
22
|
+
/** Loop arcs per node. */
|
|
23
|
+
readonly loops: U32;
|
|
24
|
+
/** In-arcs per node (directed only; the out-degree when undirected). */
|
|
25
|
+
readonly inDegree: U32;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Expand the core once.
|
|
29
|
+
* @param snapshot - the snapshot
|
|
30
|
+
*/
|
|
31
|
+
constructor(snapshot: GraphSnapshot) {
|
|
32
|
+
const { nodeCount, arcCount, rowPtr, colIdx, directed } = snapshot;
|
|
33
|
+
const arcRow = new Uint32Array(arcCount);
|
|
34
|
+
const loops = new Uint32Array(nodeCount);
|
|
35
|
+
const inDegree = directed ? new Uint32Array(nodeCount) : rowLengths(rowPtr, nodeCount);
|
|
36
|
+
for (let u = 0; u < nodeCount; u++) {
|
|
37
|
+
const end = rowPtr[u + 1];
|
|
38
|
+
for (let a = rowPtr[u]; a < end; a++) {
|
|
39
|
+
arcRow[a] = u;
|
|
40
|
+
const v = colIdx[a];
|
|
41
|
+
if (v === u) {
|
|
42
|
+
loops[u]++;
|
|
43
|
+
}
|
|
44
|
+
if (directed) {
|
|
45
|
+
inDegree[v]++;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
this.arcRow = arcRow;
|
|
50
|
+
this.loops = loops;
|
|
51
|
+
this.inDegree = inDegree;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The exclusive prefix sum of the in-degrees (the reverse rowPtr).
|
|
56
|
+
* @returns nodeCount + 1 offsets
|
|
57
|
+
*/
|
|
58
|
+
inDegreePrefix(): U32 {
|
|
59
|
+
const n = this.inDegree.length;
|
|
60
|
+
const out = new Uint32Array(n + 1);
|
|
61
|
+
for (let u = 0; u < n; u++) {
|
|
62
|
+
out[u + 1] = out[u] + this.inDegree[u];
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The error for a carried view that disagrees with the core.
|
|
70
|
+
* @param view - the view name
|
|
71
|
+
* @param member - the member array
|
|
72
|
+
* @param index - the offending index
|
|
73
|
+
* @param invariant - "I2" for an index array, "I17" for a value array
|
|
74
|
+
* @returns the error
|
|
75
|
+
*/
|
|
76
|
+
function viewError(view: string, member: string, index: number, invariant: "I2" | "I17"): GraphFormatError {
|
|
77
|
+
return invariantViolation(invariant, `carried view ${view}.${member} disagrees with the core at ${index}`, {
|
|
78
|
+
view,
|
|
79
|
+
member,
|
|
80
|
+
index,
|
|
81
|
+
reason: "view",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Compare two arrays element by element (NaN equal to NaN).
|
|
87
|
+
* @param view - the view name
|
|
88
|
+
* @param member - the member name
|
|
89
|
+
* @param found - the carried array
|
|
90
|
+
* @param expected - the truth
|
|
91
|
+
* @param invariant - the invariant to report
|
|
92
|
+
*/
|
|
93
|
+
function expectSame(
|
|
94
|
+
view: string,
|
|
95
|
+
member: string,
|
|
96
|
+
found: ArrayLike<number>,
|
|
97
|
+
expected: ArrayLike<number>,
|
|
98
|
+
invariant: "I2" | "I17",
|
|
99
|
+
): void {
|
|
100
|
+
for (let i = 0; i < expected.length; i++) {
|
|
101
|
+
if (!Object.is(found[i], expected[i]) && found[i] !== expected[i]) {
|
|
102
|
+
throw viewError(view, member, i, invariant);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check that an array is a permutation of 0..length-1.
|
|
109
|
+
* @param view - the view name
|
|
110
|
+
* @param member - the member name
|
|
111
|
+
* @param perm - the array
|
|
112
|
+
*/
|
|
113
|
+
function expectPermutation(view: string, member: string, perm: U32): void {
|
|
114
|
+
const seen = new Uint8Array(perm.length);
|
|
115
|
+
for (let i = 0; i < perm.length; i++) {
|
|
116
|
+
const p = perm[i];
|
|
117
|
+
if (p >= perm.length || seen[p] === 1) {
|
|
118
|
+
throw viewError(view, member, i, "I2");
|
|
119
|
+
}
|
|
120
|
+
seen[p] = 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* outDegree: the row lengths.
|
|
126
|
+
* @param snapshot - the snapshot
|
|
127
|
+
* @param data - the carried array
|
|
128
|
+
*/
|
|
129
|
+
export function checkOutDegree(snapshot: GraphSnapshot, data: U32): void {
|
|
130
|
+
expectSame("outDegree", "data", data, rowLengths(snapshot.rowPtr, snapshot.nodeCount), "I2");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* inDegree (directed): the in-arc counts.
|
|
135
|
+
* @param facts - the core facts
|
|
136
|
+
* @param data - the carried array
|
|
137
|
+
*/
|
|
138
|
+
export function checkInDegree(facts: CoreFacts, data: U32): void {
|
|
139
|
+
expectSame("inDegree", "data", data, facts.inDegree, "I2");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* degree: outDegree + inDegree (directed) or outDegree + loops (undirected), design section 3.4.
|
|
144
|
+
* @param snapshot - the snapshot
|
|
145
|
+
* @param facts - the core facts
|
|
146
|
+
* @param data - the carried array
|
|
147
|
+
*/
|
|
148
|
+
export function checkDegree(snapshot: GraphSnapshot, facts: CoreFacts, data: U32): void {
|
|
149
|
+
const out = rowLengths(snapshot.rowPtr, snapshot.nodeCount);
|
|
150
|
+
const add = snapshot.directed ? facts.inDegree : facts.loops;
|
|
151
|
+
for (let u = 0; u < out.length; u++) {
|
|
152
|
+
if (data[u] !== out[u] + add[u]) {
|
|
153
|
+
throw viewError("degree", "data", u, "I2");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* selfLoopsPerNode: the loop arcs per row.
|
|
160
|
+
* @param facts - the core facts
|
|
161
|
+
* @param data - the carried array
|
|
162
|
+
*/
|
|
163
|
+
export function checkSelfLoopsPerNode(facts: CoreFacts, data: U32): void {
|
|
164
|
+
expectSame("selfLoopsPerNode", "data", data, facts.loops, "I2");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* selfLoopArcs: ascending arcs, each a loop; with the length fixed to selfLoopCount that is exact.
|
|
169
|
+
* @param snapshot - the snapshot
|
|
170
|
+
* @param facts - the core facts
|
|
171
|
+
* @param data - the carried array
|
|
172
|
+
*/
|
|
173
|
+
export function checkSelfLoopArcs(snapshot: GraphSnapshot, facts: CoreFacts, data: U32): void {
|
|
174
|
+
const { colIdx, arcCount } = snapshot;
|
|
175
|
+
for (let i = 0; i < data.length; i++) {
|
|
176
|
+
const a = data[i];
|
|
177
|
+
if (a >= arcCount || colIdx[a] !== facts.arcRow[a] || (i > 0 && a <= data[i - 1])) {
|
|
178
|
+
throw viewError("selfLoopArcs", "data", i, "I2");
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* coo.src: the row of every arc.
|
|
185
|
+
* @param facts - the core facts
|
|
186
|
+
* @param src - the carried array
|
|
187
|
+
*/
|
|
188
|
+
export function checkCooSrc(facts: CoreFacts, src: U32): void {
|
|
189
|
+
expectSame("coo", "src", src, facts.arcRow, "I2");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* edgeList: `src[e]` is the row of `edgeToArc[e]`, `dst[e]` its target, `weights[e]` its weight.
|
|
194
|
+
* @param snapshot - the snapshot
|
|
195
|
+
* @param facts - the core facts
|
|
196
|
+
* @param src - the carried sources
|
|
197
|
+
* @param dst - the carried targets, or null when colIdx is aliased
|
|
198
|
+
* @param weights - the carried weights, or null when aliased or unweighted
|
|
199
|
+
*/
|
|
200
|
+
export function checkEdgeList(
|
|
201
|
+
snapshot: GraphSnapshot,
|
|
202
|
+
facts: CoreFacts,
|
|
203
|
+
src: U32,
|
|
204
|
+
dst: U32 | null,
|
|
205
|
+
weights: F32 | null,
|
|
206
|
+
): void {
|
|
207
|
+
const { edgeCount, edgeToArc, colIdx, arcCount } = snapshot;
|
|
208
|
+
const forward = snapshot.weights;
|
|
209
|
+
for (let e = 0; e < edgeCount; e++) {
|
|
210
|
+
const a = edgeToArc[e];
|
|
211
|
+
if (a >= arcCount || src[e] !== facts.arcRow[a]) {
|
|
212
|
+
throw viewError("edgeList", "src", e, "I2");
|
|
213
|
+
}
|
|
214
|
+
if (dst !== null && dst[e] !== colIdx[a]) {
|
|
215
|
+
throw viewError("edgeList", "dst", e, "I2");
|
|
216
|
+
}
|
|
217
|
+
if (weights !== null && forward !== null && !Object.is(weights[e], forward[a])) {
|
|
218
|
+
throw viewError("edgeList", "weights", e, "I17");
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* mate (undirected): an involution pairing the two arcs of every non-loop edge (invariant I7) and
|
|
225
|
+
* fixing every loop arc.
|
|
226
|
+
* @param snapshot - the snapshot
|
|
227
|
+
* @param facts - the core facts
|
|
228
|
+
* @param mate - the carried array
|
|
229
|
+
*/
|
|
230
|
+
export function checkMate(snapshot: GraphSnapshot, facts: CoreFacts, mate: U32): void {
|
|
231
|
+
const { arcCount, arcToEdge, colIdx } = snapshot;
|
|
232
|
+
for (let a = 0; a < arcCount; a++) {
|
|
233
|
+
const m = mate[a];
|
|
234
|
+
const loop = colIdx[a] === facts.arcRow[a];
|
|
235
|
+
if (m >= arcCount || mate[m] !== a || arcToEdge[m] !== arcToEdge[a] || (m === a) !== loop) {
|
|
236
|
+
throw viewError("mate", "data", a, "I2");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* degreeOrder / reverseDegreeOrder: a permutation ordered by non-increasing degree with ties in
|
|
243
|
+
* ascending node index, and the cuGraph tier offsets of design section 7.2.
|
|
244
|
+
* @param name - the view name
|
|
245
|
+
* @param degree - the degree of every node the order sorts by
|
|
246
|
+
* @param perm - the carried permutation
|
|
247
|
+
* @param segmentOffsets - the carried tier offsets
|
|
248
|
+
*/
|
|
249
|
+
export function checkDegreeOrder(
|
|
250
|
+
name: "degreeOrder" | "reverseDegreeOrder",
|
|
251
|
+
degree: U32,
|
|
252
|
+
perm: U32,
|
|
253
|
+
segmentOffsets: U32,
|
|
254
|
+
): void {
|
|
255
|
+
expectPermutation(name, "perm", perm);
|
|
256
|
+
let hi = 0;
|
|
257
|
+
let mid = 0;
|
|
258
|
+
let low = 0;
|
|
259
|
+
for (let i = 0; i < perm.length; i++) {
|
|
260
|
+
const d = degree[perm[i]];
|
|
261
|
+
if (i > 0) {
|
|
262
|
+
const previous = degree[perm[i - 1]];
|
|
263
|
+
if (d > previous || (d === previous && perm[i] < perm[i - 1])) {
|
|
264
|
+
throw viewError(name, "perm", i, "I2");
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (d >= DEGREE_TIER_HIGH) {
|
|
268
|
+
hi++;
|
|
269
|
+
} else if (d >= DEGREE_TIER_MID) {
|
|
270
|
+
mid++;
|
|
271
|
+
} else if (d >= 1) {
|
|
272
|
+
low++;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const expected = [0, hi, hi + mid, hi + mid + low, perm.length];
|
|
276
|
+
expectSame(name, "segmentOffsets", segmentOffsets, expected, "I2");
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* reverse (directed): the in-adjacency with rows sorted by source and ties by forward arc, `fwdArc`
|
|
281
|
+
* a permutation of the arcs, `colIdx` the sources, `weights` the forward weights gathered.
|
|
282
|
+
* @param snapshot - the snapshot
|
|
283
|
+
* @param facts - the core facts
|
|
284
|
+
* @param reverse - the carried view
|
|
285
|
+
*/
|
|
286
|
+
export function checkReverse(snapshot: GraphSnapshot, facts: CoreFacts, reverse: ReverseView): void {
|
|
287
|
+
const { nodeCount, arcCount, colIdx } = snapshot;
|
|
288
|
+
const forward = snapshot.weights;
|
|
289
|
+
const { rowPtr, fwdArc } = reverse;
|
|
290
|
+
const revIdx = reverse.colIdx;
|
|
291
|
+
const revWeights = reverse.weights;
|
|
292
|
+
if (rowPtr[0] !== 0 || rowPtr[nodeCount] !== arcCount) {
|
|
293
|
+
throw viewError("reverse", "rowPtr", 0, "I2");
|
|
294
|
+
}
|
|
295
|
+
expectSame("reverse", "rowPtr", rowPtr, facts.inDegreePrefix(), "I2");
|
|
296
|
+
expectPermutation("reverse", "fwdArc", fwdArc);
|
|
297
|
+
for (let v = 0; v < nodeCount; v++) {
|
|
298
|
+
const end = rowPtr[v + 1];
|
|
299
|
+
for (let k = rowPtr[v]; k < end; k++) {
|
|
300
|
+
const a = fwdArc[k];
|
|
301
|
+
const source = facts.arcRow[a];
|
|
302
|
+
if (colIdx[a] !== v || revIdx[k] !== source) {
|
|
303
|
+
throw viewError("reverse", "colIdx", k, "I2");
|
|
304
|
+
}
|
|
305
|
+
if (k > rowPtr[v]) {
|
|
306
|
+
const previous = fwdArc[k - 1];
|
|
307
|
+
const previousSource = facts.arcRow[previous];
|
|
308
|
+
if (source < previousSource || (source === previousSource && a <= previous)) {
|
|
309
|
+
throw viewError("reverse", "fwdArc", k, "I2");
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (revWeights !== null && forward !== null && !Object.is(revWeights[k], forward[a])) {
|
|
313
|
+
throw viewError("reverse", "weights", k, "I17");
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* An f64 view: compared with the snapshot's own computation.
|
|
321
|
+
* @param name - the view name
|
|
322
|
+
* @param found - the carried array
|
|
323
|
+
* @param expected - the computed truth
|
|
324
|
+
*/
|
|
325
|
+
export function checkF64View(name: string, found: F64, expected: F64): void {
|
|
326
|
+
expectSame(name, "data", found, expected, "I17");
|
|
327
|
+
}
|