iqsharp
iqsharp copied to clipboard
Passing BigInt fails for very large integers
Describe the bug
If a function defined to accept a BigInt type is passed a large enough value from Python, the program crashes with the error JSON integer <the value> is too large to parse.
To Reproduce
The following code in Main.qs:
namespace TestBigInt {
operation OperationTakingBigInt (x: BigInt) : Int {
return 0;
}
}
and in test.py
import qsharp
from TestBigInt import OperationTakingBigInt
OperationTakingBigInt.estimate_resources(x=2**2048)
Running python test.py causes the crash. Note that the program runs OK with smaller arguments (say, x=2**1024).
System information
qsharpversion 0.12.2010.504
Hi @GregDMeyer! 👋 Thanks for reporting this.
Indeed this appears to be a problem. IQ# uses Newtonsoft.Json to parse JSON-serialized arguments from Python, and that library appears to have a hard-coded upper limit of 380 digits for an integer. This gives an upper limit of approximately 2**1262. See the source here:
https://github.com/JamesNK/Newtonsoft.Json/blob/666d9760719e5ec5b2a50046f7dbd6a1267c01c6/Src/Newtonsoft.Json/JsonTextReader.cs#L2184-L2189
Do you have any particular scenario where you need to pass integers this large, or is this just something you happened to run into while trying things out?
For future reference, below is the kernel-side stack where the JSON parsing failure occurs.
Newtonsoft.Json.dll!Newtonsoft.Json.Linq.JObject.Parse(string json) Unknown
> Microsoft.Quantum.IQSharp.Core.dll!Microsoft.Quantum.IQSharp.JsonConverters.JsonToDict(string json) Line 51 C#
Microsoft.Quantum.IQSharp.Jupyter.dll!Microsoft.Quantum.IQSharp.Jupyter.AbstractMagic.JsonToDict(string input) Line 73 C#
Microsoft.Quantum.IQSharp.Jupyter.dll!Microsoft.Quantum.IQSharp.Jupyter.AbstractMagic.ParseInputParameters(string input, string firstParameterInferredName) Line 115 C#
Microsoft.Quantum.IQSharp.Kernel.dll!Microsoft.Quantum.IQSharp.Kernel.EstimateMagic.RunAsync(string input, Microsoft.Jupyter.Core.IChannel channel) Line 108 C#
Microsoft.Quantum.IQSharp.Kernel.dll!Microsoft.Quantum.IQSharp.Kernel.EstimateMagic.Run(string input, Microsoft.Jupyter.Core.IChannel channel) Line 98 C#
Microsoft.Quantum.IQSharp.Jupyter.dll!Microsoft.Quantum.IQSharp.Jupyter.AbstractMagic.RunCancellable(string input, Microsoft.Jupyter.Core.IChannel channel, System.Threading.CancellationToken cancellationToken) Line 163 C#
Microsoft.Quantum.IQSharp.Jupyter.dll!Microsoft.Quantum.IQSharp.Jupyter.AbstractMagic.SafeExecute.AnonymousMethod__1() Line 49 C#
And the exception:
Exception thrown: 'Newtonsoft.Json.JsonReaderException' in Newtonsoft.Json.dll
JSON integer 32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638215525166389437335543602135433229604645318478604952148193555853611059596230656 is too large to parse. Path 'x', line 1, position 623.
Thanks for the response! Makes sense re: the source of the problem.
I have been studying quantum integer multiplication, and I was running this code via Python, doing resource estimation and Toffoli simulation. For now, I have worked around the problem by just chunking the large integers into an array of 1024 bit BigInts to pass them to Q#, then reconstituting the original integer on the other side. So no urgent need for a fix now, but of course it would be nice to be able to do it cleanly :)