Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExecutionEngineException in Unity3d IL2CPP iOS #152

Open
mjokipii opened this issue May 18, 2019 · 8 comments
Open

ExecutionEngineException in Unity3d IL2CPP iOS #152

mjokipii opened this issue May 18, 2019 · 8 comments

Comments

@mjokipii
Copy link

Running code using Infer.NET fails with an ExecutionEngineException on iOS when built with IL2CPP from Unity3d. Some of the instantiations of generic types used internally don't exist during compile time which causes the corresponding iOS AOT code to be missing at runtime.

Details:
Unity 2018.3
Microsoft.ML.Probabilistic.dll
Microsoft.ML.Probabilistic.Compiler.dll

ExecutionEngineException: Attempting to call method 'Microsoft.ML.Probabilistic.Models.ModelBuilder::SearchExpression<System.Boolean>' for which no ahead of time (AOT) code was generated.
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Utilities.Util.Invoke (System.Reflection.MethodBase method, System.Object target, System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.ModelBuilder.Build (Microsoft.ML.Probabilistic.Models.InferenceEngine engine, System.Boolean inferOnlySpecifiedVars, System.Collections.Generic.IEnumerable`1[T] vars) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.InferenceEngine.BuildAndCompile (System.Boolean inferOnlySpecifiedVars, System.Collections.Generic.IEnumerable`1[T] vars) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.InferenceEngine.GetCompiledInferenceAlgorithm (System.Boolean inferOnlySpecifiedVars, Microsoft.ML.Probabilistic.Models.IVariable var) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.InferenceEngine.Infer (Microsoft.ML.Probabilistic.Models.IVariable var) [0x00000] in <00000000000000000000000000000000>:0 
  at Main.TwoCoins () [0x00000] in <00000000000000000000000000000000>:0 
  at Main.Start () [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Utilities.Util.Invoke (System.Reflection.MethodBase method, System.Object target, System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.ModelBuilder.Build (Microsoft.ML.Probabilistic.Models.InferenceEngine engine, System.Boolean inferOnlySpecifiedVars, System.Collections.Generic.IEnumerable`1[T] vars) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.InferenceEngine.BuildAndCompile (System.Boolean inferOnlySpecifiedVars, System.Collections.Generic.IEnumerable`1[T] vars) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.InferenceEngine.GetCompiledInferenceAlgorithm (System.Boolean inferOnlySpecifiedVars, Microsoft.ML.Probabilistic.Models.IVariable var) [0x00000] in <00000000000000000000000000000000>:0 
  at Microsoft.ML.Probabilistic.Models.InferenceEngine.Infer (Microsoft.ML.Probabilistic.Models.IVariable var) [0x00000] in <00000000000000000000000000000000>:0 
  at Main.TwoCoins () [0x00000] in <00000000000000000000000000000000>:0 
  at Main.Start () [0x00000] in <00000000000000000000000000000000>:0 
 
(Filename: currently not available on il2cpp Line: -1)```
@a-vishar
Copy link
Contributor

a-vishar commented May 18, 2019 via email

@mjokipii
Copy link
Author

This error occurs only when ran on a device that executes only AOT code like the IL2CPP compiled Xcode build on any iOS device. The library performs correctly in the editor that executes managed code. I have a small Unity3d repro. Where should i deliver the project?

@a-vishar
Copy link
Contributor

a-vishar commented May 18, 2019 via email

@mjokipii
Copy link
Author

Yes, this is due to a known limitation of the IL2CPP compiler used in Unity3d and concerns only generic types with value type parameter. Please see:

https://stackoverflow.com/questions/56183606/invoke-generic-method-via-reflection-in-c-sharp-il2cpp-on-ios/56185978#56185978

Unfortunately that includes just about every use of Infer.Net.

I'll post the repro in a minute.

@mjokipii
Copy link
Author

InferAheadOfTimeException.zip

  1. Unzip the InferAheadOfTimeException.zip archive
  2. Open the contained folder in Unity3d
  3. In Unity editor, open the Assets/Scenes/Main scene
  4. Open the build settings from File/Build Settings
  5. Select Platform iOS and click Switch Platform
  6. Press Play button in editor
  7. Observe correct output from Scripts/Main.cs in Console
  8. Press Play button again to exit playmode in editor
  9. Click Build button in the Build Settings window and choose the target location
  10. After the build is finished, open the resulting Unity-iPhone.xcodeproj in Xcode
  11. Build and run on an iOS device
  12. Observe the reported error appear in the debug panel

Reproduced on iOS 12.1.4 and iOS 10.2.1 using Unity3d 2018.3.10f1 and Xcode 10.2.1.

@mjokipii
Copy link
Author

Hi there, any chance for a fix or a workaround to allow Infer.NET on Unity iOS?

@msdmkats
Copy link
Contributor

Hi!
I see, the error happens during the compilation of the Infer.Net model. Do you actually need to run the compilation on the iOS device or, maybe, inference would be enough? In the latter case you could compile the model into C# code on your development machine, and then only put that code and Infer.Net runtime into the iOS code. This way all the necessary generic instantiations would probably (I don't have an iOS device anywhere nearby to check) exist at compile time.

See User guide on precompiling models

@mjokipii
Copy link
Author

That sounds promising. After a quick look to the instructions, if ican can update the model parameters and data without recompiling, i think inference is all i need in the iOS side. I will look into this and see if i can make this work. Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants