Skip to content

Commit 37af637

Browse files
authored
Avoid passing 64-bit ints through LibraryLink (#648)
## Changes * Closes #641. * We are currently passing 64-bit ints for disabled step specs, and an unsigned 32-bit for the seed initialization. WL LibraryLink does not support that on 32-bit platforms, so any calls to `libSetReplace` would fail. * This PR changes it to pass -1 and 31-bit ints instead, which should fix that issue. ## Comments * Someone with a 32-bit system needs to confirm there is nothing else here I'm missing.
1 parent 0162876 commit 37af637

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

Kernel/setSubstitutionSystem$cpp.m

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
Integer, (* event selection function *)
1414
{Integer, 1, "Constant"}, (* ordering function index, forward / reverse, function, forward / reverse, ... *)
1515
Integer, (* event deduplication *)
16-
Integer}, (* random seed *)
16+
(* random seed, passed as two numbers because LibraryLink does not support unsigned ints *)
17+
{Integer, 1, "Constant"}},
1718
"Void"];
1819

1920
importLibSetReplaceFunction[
@@ -102,7 +103,7 @@
102103
newLeft -> newRight
103104
];
104105

105-
$maxInt64 = 2^63 - 1;
106+
$unset = -1;
106107
$maxUInt32 = 2^32 - 1;
107108

108109
$terminationReasonCodes = <|
@@ -119,7 +120,7 @@
119120
(* GlobalSpacelike is syntactic sugar for "EventSelectionFunction" -> "MultiwaySpacelike", "MaxDestroyerEvents" -> 1 *)
120121

121122
maxDestroyerEvents[_, $globalSpacelike] = 1;
122-
maxDestroyerEvents[Automatic | _ ? MissingQ | Infinity, _] = $maxInt64;
123+
maxDestroyerEvents[Automatic | _ ? MissingQ | Infinity, _] = $unset;
123124
maxDestroyerEvents[n_, _] := n;
124125

125126
(* 0 -> All
@@ -171,15 +172,15 @@
171172
maxDestroyerEvents[stepSpec[$maxDestroyerEvents], eventSelectionFunction],
172173
Catenate[Replace[eventOrderingFunction, $orderingFunctionCodes, {2}]],
173174
Replace[eventDeduplication, $eventDeduplicationCodes],
174-
RandomInteger[{0, $maxUInt32}]
175+
IntegerDigits[RandomInteger[{0, $maxUInt32}], 2^16, 2]
175176
];
176177
TimeConstrained[
177178
CheckAbort[
178179
cpp$setReplace[
179180
setID,
180181
stepSpec /@ {
181182
$maxEvents, $maxGenerationsLocal, $maxFinalVertices, $maxFinalVertexDegree, $maxFinalExpressions} /.
182-
{Infinity | (_ ? MissingQ) -> $maxInt64}],
183+
{Infinity | (_ ? MissingQ) -> $unset}],
183184
If[!returnOnAbortQ, Abort[], terminationReason = $Aborted]],
184185
timeConstraint,
185186
If[!returnOnAbortQ, Return[$Aborted], terminationReason = $timeConstraint]];

libSetReplace/WolframLanguageAPI.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,21 @@ HypergraphMatcher::OrderingSpec getOrderingSpec(WolframLibraryData libData, MTen
105105
return result;
106106
}
107107

108+
// Seed is passed as two uint16_t because LibraryLink does not support unsigned ints, which becomes a problem on 32-bit
109+
// architectures
110+
uint32_t getSeed(WolframLibraryData libData, MTensor seedTensor) {
111+
mint tensorLength = libData->MTensor_getFlattenedLength(seedTensor);
112+
if (tensorLength != 2) throw LIBRARY_FUNCTION_ERROR;
113+
mint* tensorData = libData->MTensor_getIntegerData(seedTensor);
114+
uint32_t result = 0;
115+
for (mint i = 0; i < tensorLength; ++i) {
116+
result = (1 << 16) * result + static_cast<uint32_t>(getData(tensorData, tensorLength, i));
117+
}
118+
return result;
119+
}
120+
121+
constexpr int64_t wlStepLimitDisabled = -1;
122+
108123
HypergraphSubstitutionSystem::StepSpecification getStepSpec(WolframLibraryData libData, MTensor stepsTensor) {
109124
mint tensorLength = libData->MTensor_getFlattenedLength(stepsTensor);
110125
constexpr mint specLength = 5;
@@ -115,6 +130,9 @@ HypergraphSubstitutionSystem::StepSpecification getStepSpec(WolframLibraryData l
115130
std::vector<int64_t> stepSpecElements(specLength);
116131
for (mint k = 0; k < specLength; ++k) {
117132
stepSpecElements[k] = static_cast<int64_t>(getData(tensorData, specLength, k));
133+
if (stepSpecElements[k] == wlStepLimitDisabled) {
134+
stepSpecElements[k] = HypergraphSubstitutionSystem::stepLimitDisabled;
135+
}
118136
if (stepSpecElements[k] < 0) throw LIBRARY_FUNCTION_ERROR;
119137
}
120138

@@ -230,6 +248,9 @@ int hypergraphSubstitutionSystemInitialize(WolframLibraryData libData,
230248
SystemID thisSystemID;
231249
std::vector<Rule> rules;
232250
std::vector<AtomsVector> initialTokens;
251+
// WL passes wlStepLimitDisabled (-1) instead of HypergraphSubstitutionSystem::stepLimitDisabled (max int64) for
252+
// infinity because passing 64-bit ints is not supported on 32-bit systems in LibraryLink
253+
int64_t wlMaxDestroyerEvents;
233254
uint64_t maxDestroyerEvents;
234255
HypergraphMatcher::OrderingSpec orderingSpec;
235256
HypergraphMatcher::EventDeduplication eventDeduplication;
@@ -238,10 +259,12 @@ int hypergraphSubstitutionSystemInitialize(WolframLibraryData libData,
238259
thisSystemID = MArgument_getInteger(argv[0]);
239260
rules = getRules(libData, MArgument_getMTensor(argv[1]), MArgument_getMTensor(argv[2]));
240261
initialTokens = getHypergraph(libData, MArgument_getMTensor(argv[3]));
241-
maxDestroyerEvents = MArgument_getInteger(argv[4]);
262+
wlMaxDestroyerEvents = MArgument_getInteger(argv[4]);
263+
maxDestroyerEvents = wlMaxDestroyerEvents == wlStepLimitDisabled ? HypergraphSubstitutionSystem::stepLimitDisabled
264+
: wlMaxDestroyerEvents;
242265
orderingSpec = getOrderingSpec(libData, MArgument_getMTensor(argv[5]));
243266
eventDeduplication = static_cast<HypergraphMatcher::EventDeduplication>(MArgument_getInteger(argv[6]));
244-
randomSeed = static_cast<unsigned int>(MArgument_getInteger(argv[7]));
267+
randomSeed = getSeed(libData, MArgument_getMTensor(argv[7]));
245268
} catch (...) {
246269
return LIBRARY_FUNCTION_ERROR;
247270
}

0 commit comments

Comments
 (0)