-
Notifications
You must be signed in to change notification settings - Fork 563
Csi native #600
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
Csi native #600
Conversation
| { | ||
| public class NativeAssemblyLoadHelper : INativeAssemblyLoadHelper | ||
| { | ||
| private static readonly HashSet<DirectoryInfo> globalProbingPaths = new HashSet<DirectoryInfo>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several instances of NativeAssemblyLoadHelper created. The globalProbingPaths is the union of all of the located probing paths.
| } | ||
| } | ||
|
|
||
| private IEnumerable<string> ProbingFilenames(string name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the name passed in here is the value specified with the DllAttribute. by convention, the dll may have:
- A full path
- A relativepath
- lib prepended
- on windows .dll or .exe as a suffix.
- on linux .so as a suffix
- on macos .dynlib as a suffix
This function enumerates the possibilities.
| } | ||
| } | ||
|
|
||
| private IEnumerable<string> ProbingPaths(string probingPath, string name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function combines the probing root directory with the runtimes/rid/native to produce a list of dll's
| (libraryName, assembly, searchPath) => | ||
| { | ||
| var ptr = IntPtr.Zero; | ||
| if (_resolvers.TryGetValue( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use calling assembly path to limit probes to _probepaths.
| return ptr; | ||
| }); | ||
|
|
||
| IntPtr nativeLoader(string dll) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can't load it, just return a Zero intptr
| foreach (var pname in ProbingFilenames(name)) | ||
| { | ||
| var p = Path.Combine(path, pname); | ||
| if (File.Exists(p)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are probing for a file, don't return it if it isn't actually there.
NuGet.config
Outdated
| <add key="dotnet-try" value="https://dotnet.myget.org/F/dotnet-try/api/v3/index.json" /> | ||
| <add key="roslyn" value="https://dotnet.myget.org/F/roslyn/api/v3/index.json" /> | ||
| <add key="dotnet-corefxlab" value="https://dotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json" /> | ||
| <add key="dotnet-corefxlab" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/MachineLearning/nuget/v3/index.json" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to include this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file should not use azure package source
367b0ab to
7755032
Compare
| void Configure(string v); | ||
| void Handle(ResolvedNugetPackageReference reference); | ||
|
|
||
| void SetNativeDllProbingPaths(IReadOnlyList<DirectoryInfo> nativeDllProbingPaths); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(nit) NativeDll may not be the best name here since .dll is a Windows concept/extension.
How about NativeLibrary?
|
|
||
| // Computer valid dotnet-rids for this environment: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog | ||
| // Where rid is: win, win-x64, win-x86, osx-x64, linux-x64 etc ... | ||
| IEnumerable<string> ProbingRids() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we doing this ourselves? This is exactly what AssemblyDependencyResolver is meant to solve. It reads the .deps.json files and handles any RID fallbacks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have a .deps.json. We're doing a restore but not a build in order to avoid copying so many files out of the NuGet caches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should be generating a .deps.json file then. The logic being added here is super fragile and will not work in many cases.
For example, the proposed code won't handle the same scenario I just fixed in Azure Functions - Azure/azure-functions-host#5187. In that case, the native library is located at runtimes\{RID}\nativeassets\{TFM}. You won't be able to guess at this path, unless you are planning on knowing how to fall back through TFMs. The current RID support here is also problematic because it won't allow for things like alpine to work.
The more we try to hard-code what the current system does, the more we are going to get it wrong. We should be using as much of the current systems as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should be generating a .deps.json file then.
Do you mean by doing a build or do you have another approach in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You wouldn't need to do a full build to generate a .deps.json file. We have a few levels of places we can get at the current code.
- Call into the MSBuild Task directly.
- Invoke the MSBuild Target
Maybe @dsplaisted or @nguerrera have other ideas on how to generate a .deps.json file without doing a full build.
Another potential route would be to inspect NuGet's project.assets.json file and read all of the native asset paths from it. However, we would still need to know how to do RID fallback which the AssemblyDependencyResolver solves for us. But that is a solvable problem by reading the shared frameworks .deps.json file, which will give you the RID fallback graph for the current machine. (Assuming we are always running on a shared framework in dotnet-try.)
Also - another route is that if you just want to avoid "copying so many files out of the NuGet cache", you can set MSBuild properties to disable that. See dotnet/sdk@1936ebd.
The
CopyLocalLockFileAssembliesproperty can be set tofalseto revert to
the previous behavior fordotnet build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Eric that you should try to reuse as much of the existing build logic as possible. I would avoid calling the GenerateDepsFile task directly, as a lot of the logic of what flows into that happens in targets files. Running the GenerateDepsFile target is probably the right thing to do.
| NativeLibrary.SetDllImportResolver(args.LoadedAssembly, Resolve); | ||
| ptr = NativeLibrary.Load(dll); | ||
| Logger.Log.Info("NativeLibrary.Load({dll})", args.LoadedAssembly.Location); | ||
| Console.WriteLine($"NativeLibrary.Load({dll})"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to show up in the user's notebook output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. The Console.WriteLine needs to be removed.
| "#r \"nuget:Microsoft.ML,1.4.0-preview\"\n", | ||
| "#r \"nuget:Microsoft.ML.AutoML,0.16.0-preview\"\n", | ||
| "#r \"nuget:Microsoft.Data.DataFrame,0.1.1-e190920-1\"" | ||
| "#r \"nuget:Microsoft.Data.DataFrame,1.0.0-e190910-1\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately we messed up some versions on our myget feed. The 1.0.0- versions are older than the 0.1.1- versions. If you are looking at the feed, note the date it was published.
The good news is that we have renamed the package to Microsoft.Data.Analysis and so all the versioning issues went away.
I can send a separate update to fix this to the latest package name and version, and fixing any code that needs updating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KevinRansom, please revert the notebook changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonsequitur, I had already reverted them on my machine. Eric, updated the version, and have updated it to the newer version.
The tests were failing because there was no way to specify the custom feed, with the new location for the project file. I have added support for #r "nuget:restoresources=http://blah".
Unlike the F# repo, this needs to be specified before the #r nugets that rely on it. So … first I suppose.
I am going to spend some time seeing if I can wire up the F# #r nuget processor, wich would enable me to rip out some of the code.
@eerhardt --- the primary benefit of reading the assets.json file, will be that there is less guesswork about where to find the file is, and so it should perform better in the resolution stage. My main gripe, is there is no decent way to find the nuget root directory.
I will try to incorporate asset.json probing in the F# probing algorithm and thus the C# probing if I can successfully incorporate it. However, using #I to specified probing roots for assemblies, has always been a thing in F# and we will want to continue with that including native probing, it's a nice developer scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main gripe, is there is no decent way to find the nuget root directory.
I believe that is what the FallbackPackagePathResolver in NuGet is for. It will locate where a NuGet package is for a given context.
See https://github.com/dotnet/sdk/blob/51a0655dea6d6e4f56c235191aec6c2f9d62c07b/src/Tasks/Microsoft.NET.Build.Tasks/NuGetPackageResolver.cs#L17 for the usage in the .NET SDK.
However, doesn't the Interactive Kernel control where the nuget root directory is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per our discussions yesterday, I'd prefer to merge this PR and then revisit the approach, since there a number of different bugs being fixed here, not just the native dependency resolution.
Update @jonsequitur 's PR to probe for cross platform native .dlls
Other changes are Jon's.