machinelearning: Unable to load DLL 'CpuMathNative'

System information

  • OS version/distro: Windows 10 x64 (1809 17763.503) and x86 (1809 17763.503)
  • .NET Version (eg., dotnet --info):
.NET Core SDK (reflecting any global.json):
 Version:   2.1.700-preview-009597
 Commit:    96b18bcb5c
Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17763
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.1.700-preview-009597\

Host (useful for support):
  Version: 2.1.9
  Commit:  dcedc87d22

.NET Core SDKs installed:
  2.1.601 [C:\Program Files\dotnet\sdk]
  2.1.602 [C:\Program Files\dotnet\sdk]
  2.1.700-preview-009597 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

Issue

  • What did you do?: Created a new .net standard project, added ML.NET from nuget and added the project to my existing solution (.net Framework 4.7.2). Both are set to Any CPU, as I read that ML.NET also supports x86. The DLL Microsoft.ML.CpuMath.dll is present in the release folder.
  • What happened?: When creating the model I get the exception as shown below in “logs”
  • What did you expect?: Creating the model as expected.

Source code / logs

05/21/2019 16:15:32: Runtime terminating: True
05/22/2019 11:58:37: System.InvalidOperationException: Shuffle input cursor reader failed with an exception ---> System.InvalidOperationException: Splitter/consolidator worker encountered exception while consuming source data ---> System.DllNotFoundException: Unable to load DLL 'CpuMathNative': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at Microsoft.ML.Internal.CpuMath.Thunk.SumSqU(Single* ps, Int32 c)
   at Microsoft.ML.Transforms.LpNormNormalizingTransformer.Mapper.<>c__DisplayClass6_0.<MakeGetter>b__5(VBuffer`1& dst)
   at Microsoft.ML.Data.ColumnConcatenatingTransformer.Mapper.BoundColumn.<>c__DisplayClass18_0`1.<MakeGetter>b__0(VBuffer`1& dst)
   at Microsoft.ML.Data.ColumnConcatenatingTransformer.Mapper.BoundColumn.<>c__DisplayClass18_0`1.<MakeGetter>b__0(VBuffer`1& dst)
   at Microsoft.ML.Data.DataViewUtils.Splitter.InPipe.Impl`1.Fill()
   at Microsoft.ML.Data.DataViewUtils.Splitter.<>c__DisplayClass5_1.<ConsolidateCore>b__2()
   --- End of inner exception stack trace ---
   at Microsoft.ML.Data.DataViewUtils.Splitter.Batch.SetAll(OutPipe[] pipes)
   at Microsoft.ML.Data.DataViewUtils.Splitter.Cursor.MoveNextCore()
   at Microsoft.ML.Data.RootCursorBase.MoveNext()
   at Microsoft.ML.Transforms.RowShufflingTransformer.Cursor.<LoopProducerWorker>d__31.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.ML.Transforms.RowShufflingTransformer.Cursor.MoveNextCore()
   at Microsoft.ML.Data.RootCursorBase.MoveNext()
   at Microsoft.ML.Trainers.TrainingCursorBase.MoveNext()
   at Microsoft.ML.Trainers.SdcaTrainerBase`3.TrainCore(IChannel ch, RoleMappedData data, LinearModelParameters predictor, Int32 weightSetCount)
   at Microsoft.ML.Trainers.StochasticTrainerBase`2.TrainModelCore(TrainContext context)
   at Microsoft.ML.Trainers.TrainerEstimatorBase`2.TrainTransformer(IDataView trainSet, IDataView validationSet, IPredictor initPredictor)
   at Microsoft.ML.Data.EstimatorChain`1.Fit(IDataView input)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (10 by maintainers)

Most upvoted comments

@pjmelvin - can you try with the latest pre-release version of ML.NET? https://www.nuget.org/packages/Microsoft.ML/1.5.0-preview. If that doesn’t fix your issue, please open a new issue to track it with full repro steps - https://github.com/dotnet/machinelearning/issues/new

The assembly that is causing an issue is the CpuMathNative.dll assembly - not to be confused with the Microsoft.ML.CpuMath.dll. The Microsoft.ML.CpuMath.dll assembly is a C# assembly that calls into the C++ CpuMathNative.dll assembly.

There is no such thing as “any CPU” for C/C++ - you need to compile it for a specific processor architecture. We compile CpuMathNative.dll for 2 architectures on Windows: x86 and x64. Both versions have the same name: CpuMathNative.dll, that way we can just P/Invoke from C# into the native dll directly.

This works great on .NET Core, because .NET Core has the concept of a “portable” application - meaning it can run either x86 or x64, Windows or Linux or macOS. The way native assemblies work on .NET Core, is they all get put into a runtimes\<RID> folder, where <RID> represents the OS and architecture of the application. So we have a runtimes\win-x64\CpuMathNative.dll and a runtimes\win-x86\CpuMathNative.dll. They both get deployed with a .NET Core portable application and the correct one is picked automatically at runtime based on what the app is running as.

However, on .NET Framework this doesn’t work. The .NET Framework doesn’t have the same capability to pick a native asset based on the current process. So instead, if you have native dependencies (like ML.NET does) you need to build a .NET Framework application for the specific architecture you expect it to run on. If you need it to run on both 32-bit and 64-bit, then you will need to build 2 versions of it - one with the x86 native binaries and one with the x64 native binaries.

There are ways to pick the native assets yourself on .NET Framework, but I would consider them to be advanced scenarios. If you are curious, one example is how DiaSymReader works with its native assets:

https://github.com/dotnet/symreader/blob/e763379c9add41f613687d7993e7425719d69844/src/Microsoft.DiaSymReader/SymUnmanagedFactory.cs#L165-L186

The idea here would be to deploy both the win-x86\CpuMathNative.dll and win-x64\CpuMathNative.dll assemblies in your app (the files are named the same, so you would need to put them in different folders), and then control yourself which one gets loaded based on which architecture the process was.

Like I said, I’d consider that an advanced approach, and I would recommend building your .NET Framework Exe project as x86 or x64 specifically.

I am having the same issue. Changing to x86 or x64 does not correct the problem.