diff --git a/Directory.Build.props b/Directory.Build.props index 4a364777..aa14f82c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,13 @@ + + + false + + Lombiq Technologies Copyright © 2017, Lombiq Technologies Ltd. diff --git a/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj b/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj index 221916f9..060aea24 100644 --- a/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj +++ b/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/NuGetTest/Hast.NuGet.Console/Program.cs b/NuGetTest/Hast.NuGet.Console/Program.cs index 8d855ddd..f2448ecc 100644 --- a/NuGetTest/Hast.NuGet.Console/Program.cs +++ b/NuGetTest/Hast.NuGet.Console/Program.cs @@ -12,6 +12,16 @@ configuration.VhdlTransformerConfiguration().VhdlGenerationConfiguration = VhdlGenerationConfiguration.Debug; +// To cross-compile, first run without any arguments (this will throw an exception during execution), then copy the +// HardwareFramework directory to the remote device and pass the binary's path as the argument, e.g.: +// dotnet Hast.NuGet.Console.dll HardwareFramework/bin/*.azure.xclbin +var binaryPath = Environment.GetCommandLineArgs().FirstOrDefault(item => item.EndsWithOrdinalIgnoreCase(".xclbin")); +if (File.Exists(binaryPath)) +{ + configuration.SingleBinaryPath = binaryPath; + Console.WriteLine($"Using the existing binary file \"{binaryPath}\". Compilation will be skipped."); +} + hastlayer.ExecutedOnHardware += (_, e) => Console.WriteLine( StringHelper.ConcatenateConvertiblesInvariant( diff --git a/src/HardwareFrameworks/Vitis b/src/HardwareFrameworks/Vitis index 2d8bbf15..eaf7db0d 160000 --- a/src/HardwareFrameworks/Vitis +++ b/src/HardwareFrameworks/Vitis @@ -1 +1 @@ -Subproject commit 2d8bbf151adb5368dc13d8aa5618748237d2b74c +Subproject commit eaf7db0dea1e06690f1128a75ebe579b7266e163 diff --git a/src/Hastlayer/Hast.Common/Extensions/DictionaryExtensions.cs b/src/Hastlayer/Hast.Common/Extensions/DictionaryExtensions.cs index 3eedec12..108154e8 100644 --- a/src/Hastlayer/Hast.Common/Extensions/DictionaryExtensions.cs +++ b/src/Hastlayer/Hast.Common/Extensions/DictionaryExtensions.cs @@ -1,3 +1,5 @@ +using Newtonsoft.Json.Linq; + namespace System.Collections.Generic; public static class DictionaryExtensions @@ -5,7 +7,11 @@ public static class DictionaryExtensions public static T GetOrAddCustomConfiguration(this IDictionary customConfiguration, string key) where T : new() { - if (customConfiguration.TryGetValue(key, out var config)) return (T)config; + if (customConfiguration.TryGetValue(key, out var config)) + { + if (config is T typedConfig) return typedConfig; + if (config is JToken jToken) return jToken.ToObject(); + } var newInstance = new T(); customConfiguration[key] = newInstance; diff --git a/src/Hastlayer/Hast.Layer/Hast.Layer.csproj b/src/Hastlayer/Hast.Layer/Hast.Layer.csproj index 2e6a217b..1d49240d 100644 --- a/src/Hastlayer/Hast.Layer/Hast.Layer.csproj +++ b/src/Hastlayer/Hast.Layer/Hast.Layer.csproj @@ -13,7 +13,7 @@ true - + @@ -23,14 +23,13 @@ - + - diff --git a/src/Hastlayer/Hast.Vitis/Docs/Docker.md b/src/Hastlayer/Hast.Vitis/Docs/Docker.md index 41b4552a..27488d37 100644 --- a/src/Hastlayer/Hast.Vitis/Docs/Docker.md +++ b/src/Hastlayer/Hast.Vitis/Docs/Docker.md @@ -1,6 +1,6 @@ # Docker Setup -This way you can compile on your Windows machine, or any machine where you don't want to install XRT permanently. Note that you still need to download the complete Vitis XDK separately for licensing reasons and it takes about 125GB (and at least 50GB more temporarily) to set up the image. Of course you need [Docker installed](https://docs.docker.com/get-docker/) too. However there are no alternatives on Windows so please bear with it. Following these steps you will get a container with Vitis XDK and .NET Core 3.1 SDK installed. Please remember not to distribute the resulting image! +This way you can compile on your Windows machine, or any machine where you don't want to install XRT permanently. Note that you still need to download the complete Vitis XDK separately for licensing reasons and it takes about 125GB (and at least 50GB more temporarily) to set up the image. Of course you need [Docker installed](https://docs.docker.com/get-docker/) too. However there are no alternatives on Windows so please bear with it. Following these steps you will get a container with Vitis XDK and .NET SDK installed. Please remember not to distribute the resulting image! ## Installation Steps diff --git a/src/Hastlayer/Hast.Vitis/Docs/Nimbix.md b/src/Hastlayer/Hast.Vitis/Docs/Nimbix.md index c826e00b..b299767c 100644 --- a/src/Hastlayer/Hast.Vitis/Docs/Nimbix.md +++ b/src/Hastlayer/Hast.Vitis/Docs/Nimbix.md @@ -1,6 +1,8 @@ # Nimbix usage +> ⚠️ The instructions below are outdated, as the mentioned Alveo trial is no longer available. Some of the names have changed since Nimbix has been acquired by Atos, and they only seem to offer enterprise solutions now. The rest of the document is retained in case it may be a useful reference for anyone who wants to use their services with Hastlayer. + To run a Hastlayer applications on the [Nimbix HPC cloud](https://www.nimbix.net/), a compute instance must be launched, the dependencies installed and the host & device applications uploaded. You can find the necessary instructions here. @@ -10,7 +12,7 @@ Be sure to also check out the [general docs](../Readme.md). ## Administrative steps 1. Sign up for the [Nimbix Alveo Trial](https://www.nimbix.net/alveotrial). -2. [Log into the Nimbix platform](https://platform.jarvice.com/) after the registration is complete. [Here](https://support.nimbix.net/hc/en-us/articles/360035258971-Getting-Started-With-Alveo-Trial) is also some more getting started information (note that the costs indicator only updates when you shut down your job). +2. [Log into the Nimbix platform](https://cloud.nimbix.net/) after the registration is complete. [Here](https://support.nimbix.net/hc/en-us/articles/360035258971-Getting-Started-With-Alveo-Trial) is also some more getting started information (note that the costs indicator only updates when you shut down your job). 3. On the right sidebar click "Compute" and find "Xilinx Vitis Unified Software Platform 2020.1" in the search bar. At the time of writing this that option lets you pick U50, U200, and U280. 4. Activate "Desktop Mode with FPGA" and select the machine type with the appropriate board. Note that Nimbix might be overloaded and not every board you can select will actually be available, resulting in the job being queued forever. Check out the availability on the [Nimbix status page](https://status.jarvice.com/) first. 5. You should be sent to the Dashboard section with a thumbnail for the running instance. diff --git a/src/Hastlayer/Hast.Vitis/Interop/Xrt.cs b/src/Hastlayer/Hast.Vitis/Interop/Xrt.cs index 913ae0be..61b57f8c 100644 --- a/src/Hastlayer/Hast.Vitis/Interop/Xrt.cs +++ b/src/Hastlayer/Hast.Vitis/Interop/Xrt.cs @@ -12,7 +12,7 @@ namespace Hast.Vitis.Interop; /// Source: . /// /// Legacy layout is used since that's the one in the examples here. +/// href="https://github.com/Xilinx/Vitis_Accel_Examples/blob/2021.1/host/hbm_bandwidth/src/host.cpp">here. /// /// // LayoutKind can't be Auto because this struct is exposed to unmanaged code. diff --git a/src/Hastlayer/Hast.Vitis/Readme.md b/src/Hastlayer/Hast.Vitis/Readme.md index f3b44912..39af52cb 100644 --- a/src/Hastlayer/Hast.Vitis/Readme.md +++ b/src/Hastlayer/Hast.Vitis/Readme.md @@ -8,8 +8,6 @@ This project contains the communication service used to connect with Xilinx's [V Note that the SH scripts in this project should use LF line endings! You'll get errors such as `-bash: $'\r': command not found` otherwise. -For Nimbix-specific instructions see [the Nimbix docs](Docs/Nimbix.md). - ## Requirements * The system running the FPGA card must be 64-bit Linux (e.g. Ubuntu 18.04.2 LTS or CentOS 7.6). The installation instructions can be found here [in the platform documentation](https://www.xilinx.com/html_docs/xilinx2019_2/vitis_doc/vhc1571429852245.html). @@ -20,7 +18,8 @@ For Nimbix-specific instructions see [the Nimbix docs](Docs/Nimbix.md). Even after everything is installed, you have to make sure that the executing user's environment variables are correctly set by sourcing the setup scripts [as described in the documentation](https://docs.xilinx.com/r/en-US/ug1400-vitis-embedded/Setting-Up-the-Environment-to-Run-the-Vitis-Software-Platform). You can add these commands into the `~/.bashrc` file to avoid having to type them every time. If running from the cloud, like Nimbix, this is probably handled automatically. -For setup instructions on the Nimbix cloud see the [Nimbix-specific instructions](Docs/Nimbix.md). +- For Azure-specific instructions see [the Azure NP docs](Docs/AzureReadme.md). +- For Nimbix-specific instructions see [the Nimbix docs](Docs/Nimbix.md). ## Cross Compilation @@ -45,7 +44,7 @@ Aside from general Vitis accelerator card support, there are a couple specialize ## Other Remarks -If you ever get an error *\[XRT\] ERROR: some device is already programmed* due to a crashed or interrupted execution, you can reset the card using `xbutil reset` command. See more info about the Xilinx Board Utility [here](https://www.xilinx.com/html_docs/xilinx2019_1/sdaccel_doc/yrx1536963262111.html). +If you ever get an error *\[XRT\] ERROR: some device is already programmed* due to a crashed or interrupted execution, you can reset the card using `xbutil reset` command. See more info about the Xilinx Board Utility [here](https://xilinx.github.io/XRT/master/html/xbutil.html). If you just want to generate a simulation report, you can do that without the full build by configuring the `VitisBuildConfiguration.SynthesisOnly` custom configuration in the *appsettings.json* or by adding the following command line argument: diff --git a/src/Hastlayer/Hast.Vitis/Services/VitisHardwareImplementationComposerBuildProvider.cs b/src/Hastlayer/Hast.Vitis/Services/VitisHardwareImplementationComposerBuildProvider.cs index 3e0e915f..9b3b517b 100644 --- a/src/Hastlayer/Hast.Vitis/Services/VitisHardwareImplementationComposerBuildProvider.cs +++ b/src/Hastlayer/Hast.Vitis/Services/VitisHardwareImplementationComposerBuildProvider.cs @@ -85,7 +85,7 @@ public Task BuildAsync( // When cross-compiling, the build machine needs Vivado and XRT, but the FPGA machine only needs XRT. _logger.LogWarning( "XILINX_VITIS variable is not set. This is required to build using Vivado. For further instructions " + - "see https://www.xilinx.com/html_docs/xilinx2020_1/vitis_doc/settingupvitisenvironment.html."); + "see https://docs.xilinx.com/r/en-US/ug1393-vitis-application-acceleration/Building-and-Running-the-Application."); } GetXilinxDirectoryPathOrThrow(); @@ -364,7 +364,7 @@ private async Task BuildKernelAsync( var emConfigExecutable = await GetExecutablePathAsync("emconfigutil"); var emConfigArguments = new[] { "--platform", device, "--od", tmpDirectoryPath, }; await _buildLogger.ExecuteWithLoggingAsync(emConfigExecutable, emConfigArguments, rtlDirectoryPath); - File.Copy(Path.Combine(tmpDirectoryPath, "emconfig.json"), "emconfig.json"); + Copy(Path.Combine(tmpDirectoryPath, "emconfig.json"), "emconfig.json", overwrite: false); ProgressMajor("Emulation configuration (emconfig) setup is finished."); } } @@ -401,8 +401,8 @@ private void CopyBinaries( if (binaryDirectoryPath != null) EnsureDirectoryExists(binaryDirectoryPath); var builtFilePath = Path.Combine(GetTmpDirectoryPath(hashId), $"hastip.{target}.xclbin"); - File.Copy(builtFilePath, binaryPath); - File.Copy(builtFilePath + InfoFileExtension, binaryPath + InfoFileExtension); + Copy(builtFilePath, binaryPath, overwrite: true); + Copy(builtFilePath + InfoFileExtension, binaryPath + InfoFileExtension, overwrite: true); if (disableHbm) File.Create(binaryPath + NoHbmFlagExtension).Dispose(); ProgressMajor($"Files copied to binary folder ({builtFilePath})."); } @@ -427,7 +427,7 @@ private async Task CollectReportsAsync( var reportFiles = Directory.GetFiles(reportPath, "*.rpt"); foreach (var reportFile in reportFiles) { - File.Copy(reportFile, Path.Combine(reportSavePath, Path.GetFileName(reportFile))); + Copy(reportFile, Path.Combine(reportSavePath, Path.GetFileName(reportFile)), overwrite: true); } var reportFilePath = @@ -635,7 +635,7 @@ private static async Task ApplyTemplatesAsync( if (file.EndsWith(".template", StringComparison.OrdinalIgnoreCase)) continue; var targetFilePath = Path.Combine(targetDirectoryPath, "IP", Path.GetFileName(file)); - if (!File.Exists(targetFilePath)) File.Copy(file, targetFilePath); + Copy(file, targetFilePath, overwrite: false); } } @@ -686,4 +686,15 @@ private static string GetXilinxDirectoryPathOrThrow() return xilinxDirectoryPath; } + + private static void Copy(string from, string to, bool overwrite) + { + ArgumentNullException.ThrowIfNull(from); + ArgumentNullException.ThrowIfNull(to); + + if (overwrite || !File.Exists(to)) + { + File.Copy(from, to, overwrite: true); + } + } } diff --git a/src/Hastlayer/Hast.Vitis/ubuntu-install.sh b/src/Hastlayer/Hast.Vitis/ubuntu-install.sh index 113ef0ef..ce924773 100644 --- a/src/Hastlayer/Hast.Vitis/ubuntu-install.sh +++ b/src/Hastlayer/Hast.Vitis/ubuntu-install.sh @@ -13,8 +13,8 @@ yes | sudo apt-get --yes --force-yes install apt-transport-https sudo apt-get update # This installs the full SDK allowing you to build from source. If you only want to run the compiled application, you # can install just the runtime by swapping the comment on the two lines below. -yes | sudo apt-get --yes --force-yes install dotnet-sdk-3.1 -# yes | sudo apt-get --yes --force-yes install dotnet-runtime-3.1 +yes | sudo apt-get --yes --force-yes install dotnet-sdk-7.0.x86_64 +# yes | sudo apt-get --yes --force-yes install dotnet-runtime-7.0.x86_64 diff --git a/src/Hastlayer/Hast.Xilinx/Drivers/AzureAlveoU250Driver.cs b/src/Hastlayer/Hast.Xilinx/Drivers/AzureAlveoU250Driver.cs index 08530f75..69e4be56 100644 --- a/src/Hastlayer/Hast.Xilinx/Drivers/AzureAlveoU250Driver.cs +++ b/src/Hastlayer/Hast.Xilinx/Drivers/AzureAlveoU250Driver.cs @@ -1,4 +1,6 @@ +using Hast.Layer; using Hast.Synthesis.Services; +using System; namespace Hast.Xilinx.Drivers; @@ -10,7 +12,13 @@ public class AzureAlveoU250Driver : VitisDeviceDriverBase public override string PlatformName => "xilinx_u250_gen3x16_xdma_2_1_202010_1"; // Needs a very specific version. public override uint ClockFrequencyMhz => 300; + protected override string TimingReportFileName => nameof(AlveoU250Driver); + public AzureAlveoU250Driver(ITimingReportParser timingReportParser) - : base(timingReportParser) - { } + : base(timingReportParser) => + _deviceManifest = new Lazy(() => InitializeManifest(new AzureNpDeviceManifest + { + SupportsHbm = false, + RequiresDcpBinary = true, + })); } diff --git a/src/Hastlayer/Hast.Xilinx/Drivers/VitisDeviceDriverBase.cs b/src/Hastlayer/Hast.Xilinx/Drivers/VitisDeviceDriverBase.cs index 1510096d..e65a567b 100644 --- a/src/Hastlayer/Hast.Xilinx/Drivers/VitisDeviceDriverBase.cs +++ b/src/Hastlayer/Hast.Xilinx/Drivers/VitisDeviceDriverBase.cs @@ -15,17 +15,21 @@ public abstract class VitisDeviceDriverBase : DeviceDriverBase protected VitisDeviceDriverBase(ITimingReportParser timingReportParser) : base(timingReportParser) => - _deviceManifest = new Lazy(() => new VitisDeviceManifest - { - Name = DeviceName, - ClockFrequencyHz = ClockFrequencyMhz * Mhz, - SupportedCommunicationChannelNames = new[] { Constants.VitisCommunicationChannelName }, - // While there is much more DDR RAM on the device, the max object size in .NET is 2GB. So until we add - // paging to SimpleMemory the limit is 2GB, see: https://github.com/Lombiq/Hastlayer-SDK/issues/27 - AvailableMemoryBytes = 2 * GigaByte, - SupportedPlatforms = string.IsNullOrEmpty(PlatformName) ? Array.Empty() : new[] { PlatformName }, - }); + _deviceManifest = new Lazy(() => InitializeManifest(new VitisDeviceManifest())); public override void ConfigureMemory(MemoryConfiguration memory, IHardwareGenerationConfiguration hardwareGeneration) => MemoryConfigurationHelper.ConfigureMemoryForVitis(memory, hardwareGeneration); + + protected IDeviceManifest InitializeManifest(VitisDeviceManifest manifest) + { + manifest.Name = DeviceName; + manifest.ClockFrequencyHz = ClockFrequencyMhz * Mhz; + manifest.SupportedCommunicationChannelNames = new[] { Constants.VitisCommunicationChannelName }; + // While there is much more DDR RAM on the device, the max object size in .NET is 2GB. So until we add + // paging to SimpleMemory the limit is 2GB, see: https://github.com/Lombiq/Hastlayer-SDK/issues/27. + manifest.AvailableMemoryBytes = 2 * GigaByte; + manifest.SupportedPlatforms = string.IsNullOrEmpty(PlatformName) ? Array.Empty() : new[] { PlatformName }; + + return manifest; + } } diff --git a/src/Libraries/External/Lombiq.HelpfulLibraries b/src/Libraries/External/Lombiq.HelpfulLibraries index ee17f91f..57171a77 160000 --- a/src/Libraries/External/Lombiq.HelpfulLibraries +++ b/src/Libraries/External/Lombiq.HelpfulLibraries @@ -1 +1 @@ -Subproject commit ee17f91fa976a456dff55c1177074ceb93c7a054 +Subproject commit 57171a77a08b1a7ee055bc2167322188ccccde6d diff --git a/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj b/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj index 2455902f..3dd3be9d 100644 --- a/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj +++ b/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj @@ -12,11 +12,11 @@ - - + + - +