Skip to content

Commit

Permalink
Merge pull request #118 from Lombiq/issue/HAST-327
Browse files Browse the repository at this point in the history
HAST-327: Update Lombiq.Analyzers to latest
  • Loading branch information
Piedone authored Oct 19, 2023
2 parents dbee349 + 96f3db9 commit 0ae2477
Show file tree
Hide file tree
Showing 132 changed files with 501 additions and 439 deletions.
19 changes: 19 additions & 0 deletions .globalconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
is_global = true

# Code analysis rules for Hastlayer, extending Lombiq.Analyzers.globalconfig.

# Microsoft.CodeAnalysis.NetAnalyzers rules

# CA1062: Validate arguments of public methods. We disabled it, because it makes the code bloated and doesn't support
# `ArgumentNullException.ThrowIfNull()` either.
dotnet_diagnostic.CA1062.severity = none

# CA1848: Use the LoggerMessage delegates. While this might slightly improve performance, it deters logging by turning
# it into a huge chore by breaking up the code flow and creating an unreasonable amount of boilerplate.
dotnet_diagnostic.CA1848.severity = none

# CA2007 : Consider calling ConfigureAwait on the awaited task. This warning is relevant to desktop apps that have a GUI
# thread. While Hastlayer can be used in GUI applications, itself does not operate a user interface so this warning is
# not relevant internally. A consumer of the library may call ConfigureAwait on one of the asynchronous public API
# methods if needed.
dotnet_diagnostic.CA2007.severity = none
1 change: 1 addition & 0 deletions Hastlayer.SDK.sln
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
NuGet.config = NuGet.config
NuGetIcon.png = NuGetIcon.png
Readme.md = Readme.md
.globalconfig = .globalconfig
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hast.Samples.Demo", "src\Samples\Hast.Samples.Demo\Hast.Samples.Demo.csproj", "{CBAC105A-E50F-4202-A647-CFD674E6C0F8}"
Expand Down
4 changes: 2 additions & 2 deletions NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Hast.Algorithms" Version="2.1.1" />
<PackageReference Include="Hast.Layer" Version="2.1.1" />
<PackageReference Include="Hast.Algorithms" Version="2.1.2-alpha.0.hast-327" />
<PackageReference Include="Hast.Layer" Version="2.1.2-alpha.0.hast-327" />
<PackageReference Include="Hast.Vitis.HardwareFramework" Version="1.2.0" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion NuGetTest/Hast.NuGet.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// 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"));
var binaryPath = Environment.GetCommandLineArgs().Find(item => item.EndsWithOrdinalIgnoreCase(".xclbin"));
if (File.Exists(binaryPath))
{
configuration.SingleBinaryPath = binaryPath;
Expand Down
27 changes: 13 additions & 14 deletions src/Hastlayer/Hast.Algorithms/Fix64.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;

Expand Down Expand Up @@ -41,7 +42,7 @@ namespace Hast.Algorithms;
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/// </para>
/// </remarks>
public struct Fix64 : IEquatable<Fix64>, IComparable<Fix64>
public readonly struct Fix64 : IEquatable<Fix64>, IComparable<Fix64>
{
private const long MaxRawValue = long.MaxValue;
private const long MinRawValue = long.MinValue;
Expand Down Expand Up @@ -79,17 +80,17 @@ public struct Fix64 : IEquatable<Fix64>, IComparable<Fix64>

#region Instance methods

public override int GetHashCode() => RawValue.GetHashCode();
public override readonly int GetHashCode() => RawValue.GetHashCode();

public override bool Equals(object obj) => obj is Fix64 fix64 && fix64.RawValue == RawValue;
public override readonly bool Equals(object obj) => obj is Fix64 fix64 && fix64.RawValue == RawValue;

public bool Equals(Fix64 other) => RawValue == other.RawValue;
public readonly bool Equals(Fix64 other) => RawValue == other.RawValue;

public int CompareTo(Fix64 other) => RawValue.CompareTo(other.RawValue);
public readonly int CompareTo(Fix64 other) => RawValue.CompareTo(other.RawValue);

public override string ToString() => ((decimal)this).ToString(CultureInfo.InvariantCulture);
public override readonly string ToString() => ((decimal)this).ToString(CultureInfo.InvariantCulture);

public int[] ToIntegers()
public readonly int[] ToIntegers()
{
var low = (int)(RawValue & uint.MaxValue);
int high = (int)(RawValue >> 32);
Expand All @@ -104,13 +105,11 @@ public int[] ToIntegers()
/// Returns a number indicating the sign of a Fix64 number. Returns 1 if the value is positive, 0 if is 0, and -1 if
/// it is negative.
/// </summary>
public static int Sign(Fix64 value) =>
value.RawValue switch
{
{ } when value.RawValue < 0 => -1,
{ } when value.RawValue > 0 => 1,
_ => 0,
};
[SuppressMessage(
"Major Code Smell",
"S3358:Ternary operators should not be nested",
Justification = "The generated code is simpler this way.")]
public static int Sign(Fix64 value) => value.RawValue == 0 ? 0 : (value.RawValue > 0 ? 1 : -1);

/// <summary>
/// Returns the absolute value of a Fix64 number. Note: Abs(Fix64.MinValue) == Fix64.MaxValue.
Expand Down
88 changes: 42 additions & 46 deletions src/Hastlayer/Hast.Catapult/CatapultLibrary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using InputHeaderSizes = Hast.Catapult.Constants.InputHeaderSizes;
using OutputHeaderSizes = Hast.Catapult.Constants.OutputHeaderSizes;
using InputHeaderSizes = Hast.Catapult.Constants.Catapult.InputHeaderSizes;
using OutputHeaderSizes = Hast.Catapult.Constants.Catapult.OutputHeaderSizes;

namespace Hast.Catapult;

Expand All @@ -31,7 +31,7 @@ public sealed class CatapultLibrary : IDisposable
/// <summary>
/// Gets the name of the instance (Catapult:N where N is the PCIe endpoint number).
/// </summary>
public string InstanceName => FormattableString.Invariant($"{Constants.ChannelName}:{PcieEndpointNumber}");
public string InstanceName => StringHelper.CreateInvariant($"{Constants.Catapult.ChannelName}:{PcieEndpointNumber}");

/// <summary>
/// Contains the latest tasks to be awaited when starting a new task.
Expand Down Expand Up @@ -96,15 +96,15 @@ public bool PcieEnabled
get
{
VerifyResult(NativeLibrary.ReadShellRegister(_handle, 0, out uint pcie));
return (pcie & Constants.RegisterMaskPcieEnabled) != 0;
return (pcie & Constants.Catapult.RegisterMaskPcieEnabled) != 0;
}
private set
{
VerifyResult(NativeLibrary.ReadShellRegister(_handle, 0, out uint pcie));

// Set control_register[6]
if (value) pcie |= Constants.RegisterMaskPcieEnabled;
else pcie &= ~Constants.RegisterMaskPcieEnabled;
if (value) pcie |= Constants.Catapult.RegisterMaskPcieEnabled;
else pcie &= ~Constants.Catapult.RegisterMaskPcieEnabled;

VerifyResult(NativeLibrary.WriteShellRegister(_handle, 0, pcie));
}
Expand All @@ -129,10 +129,10 @@ private set
/// parameter and a string as its second. Note that the strings all end with newline character.
/// </param>
public CatapultLibrary(
string libraryPath = Constants.DefaultLibraryPath,
string libraryPath = Constants.Catapult.DefaultLibraryPath,
string versionDefinitionsFile = null,
string versionManifestFile = null,
int endpointNumber = Constants.PcieHipNumber,
int endpointNumber = Constants.Catapult.PcieHipNumber,
CatapultLogFunction logFunction = null)
{
LogFunction = logFunction;
Expand All @@ -153,7 +153,7 @@ public CatapultLibrary(
VerifyResult(createStatus);

// Configure hardware settings & enable hardware.
SetSoftRegister(Constants.ConfigDram.Channel0, 0);
SetSoftRegister(Constants.Catapult.ConfigDram.Channel0, 0);
PcieEnabled = true;

// Query device info.
Expand All @@ -165,9 +165,9 @@ public CatapultLibrary(
BufferSize = (int)count;

// Load in configuration from the soft registers
var allowedSlots = (int)GetSoftRegister(Constants.SoftRegisters.AllowedSlots);
var allowedSlots = (int)GetSoftRegister(Constants.Catapult.SoftRegisters.AllowedSlots);
if (allowedSlots > 0 && allowedSlots < BufferCount) BufferCount = allowedSlots;
var bufferPayloadSize = (int)GetSoftRegister(Constants.SoftRegisters.BufferPayloadSize);
var bufferPayloadSize = (int)GetSoftRegister(Constants.Catapult.SoftRegisters.BufferPayloadSize);
if (bufferPayloadSize > 0 && bufferPayloadSize < BufferPayloadSize) BufferPayloadSize = bufferPayloadSize;

// Set up the task tracker.
Expand All @@ -178,15 +178,11 @@ public CatapultLibrary(
public static CatapultLibrary Create(
IDictionary<string, object> config,
ILogger<CatapultLibrary> logger,
int endpointNumber = Constants.PcieHipNumber)
int endpointNumber = Constants.Catapult.PcieHipNumber)
{
var libraryPath = config.ContainsKey(Constants.ConfigKeys.LibraryPath) ?
config[Constants.ConfigKeys.LibraryPath] ?? Constants.DefaultLibraryPath :
Constants.DefaultLibraryPath;
var versionDefinitionsFile = config.ContainsKey(Constants.ConfigKeys.VersionDefinitionsFile) ?
config[Constants.ConfigKeys.VersionDefinitionsFile] : null;
var versionManifestFile = config.ContainsKey(Constants.ConfigKeys.VersionManifestFile) ?
config[Constants.ConfigKeys.VersionManifestFile] : null;
var libraryPath = config.GetMaybe(Constants.Catapult.DefaultLibraryPath) ?? Constants.Catapult.DefaultLibraryPath;
var versionDefinitionsFile = config.GetMaybe(Constants.Catapult.ConfigKeys.VersionDefinitionsFile);
var versionManifestFile = config.GetMaybe(Constants.Catapult.ConfigKeys.VersionManifestFile);

return new CatapultLibrary(
(string)libraryPath,
Expand All @@ -195,28 +191,28 @@ public static CatapultLibrary Create(
endpointNumber: endpointNumber,
logFunction: (flagValue, text) =>
{
var flag = (Constants.Log)flagValue;
var flag = (Constants.Catapult.Log)flagValue;
// This function proxies special log entries so they can't be static.
#pragma warning disable CA2254 // Template should be a static expression
switch (flag)
{
case Constants.Log.None:
case Constants.Catapult.Log.None:
return;
case Constants.Log.Info:
case Constants.Catapult.Log.Info:
logger.LogInformation(text);
break;
case Constants.Log.Debug:
case Constants.Log.Verbose:
case Constants.Catapult.Log.Debug:
case Constants.Catapult.Log.Verbose:
logger.LogDebug(text);
break;
case Constants.Log.Error:
case Constants.Catapult.Log.Error:
logger.LogError(text);
break;
case Constants.Log.Fatal:
case Constants.Catapult.Log.Fatal:
logger.LogCritical(text);
break;
case Constants.Log.Warn:
case Constants.Catapult.Log.Warn:
logger.LogWarning(text);
break;
default:
Expand All @@ -240,12 +236,12 @@ public void Dispose()
// close the PICe connection via `PcieEnabled = false;` right after that anyway.
}

LogLine(Constants.Log.Info, "Closing down the FPGA...");
LogLine(Constants.Catapult.Log.Info, "Closing down the FPGA...");
PcieEnabled = false;
NativeLibrary.CloseHandle(Handle);

NativeLibrary.Dispose();
LogLine(Constants.Log.Info, "Closed down the FPGA...");
LogLine(Constants.Catapult.Log.Info, "Closed down the FPGA...");

_isDisposed = true;
}
Expand All @@ -265,9 +261,9 @@ public void WaitClean()
/// </summary>
/// <param name="status">The return value from the library function.</param>
/// <exception cref="CatapultFunctionResultException">Thrown when the status isn't SUCCESS.</exception>
public void VerifyResult(Constants.Status status)
public void VerifyResult(Constants.Catapult.Status status)
{
if (status == Constants.Status.Success) return;
if (status == Constants.Catapult.Status.Success) return;

var errorMessage = new StringBuilder(512);
NativeLibrary.GetLastError();
Expand Down Expand Up @@ -352,7 +348,7 @@ private async Task<Memory<byte>> AssignJobAsync(
var jobResult = await job;
if (TesterOutput == null) return jobResult;

var message = FormattableString.Invariant(
var message = StringHelper.CreateInvariant(
$"Job Finished{Environment.NewLine}************{Environment.NewLine}Slot: {currentSlot}{Environment.NewLine}");
if (!ignoreResponse)
{
Expand All @@ -377,7 +373,7 @@ private async Task<Memory<byte>> AssignMultiSliceJobAsync(
int totalDataSize,
int currentSliceCount)
{
await TesterWriteLineAsync(FormattableString.Invariant($"Slices: {currentSliceCount}"));
await TesterWriteLineAsync(StringHelper.CreateInvariant($"Slices: {currentSliceCount}"));
bool slotOverflow = currentSliceCount > BufferCount;

// If the data exceeds buffer size limit, then cut it into maximal slices.
Expand Down Expand Up @@ -440,13 +436,13 @@ private async Task<Memory<byte>> AssignMultiSliceJobAsync(
/// <returns>The resulting output from the FPGA.</returns>
private async Task<Memory<byte>> RunJobAsync(int bufferIndex, Memory<byte> inputData, bool ignoreResponse)
{
LogLineInvariant(Constants.Log.Info, $"Job on slot #{bufferIndex} starting...");
LogLineInvariant(Constants.Catapult.Log.Info, $"Job on slot #{bufferIndex} starting...");
Debug.Assert(
bufferIndex < BufferCount,
FormattableString.Invariant($"The buffer index is out of range. (current: {bufferIndex}, max: {BufferCount})"));
StringHelper.CreateInvariant($"The buffer index is out of range. (current: {bufferIndex}, max: {BufferCount})"));
Debug.Assert(
inputData.Length <= BufferSize,
FormattableString.Invariant($"The input data doesn't fit in the buffer. (current: {inputData.Length}, max: {BufferSize})"));
StringHelper.CreateInvariant($"The input data doesn't fit in the buffer. (current: {inputData.Length}, max: {BufferSize})"));
var slot = (uint)bufferIndex;

// Makes sure the buffer is ready to be written.
Expand All @@ -463,16 +459,16 @@ private async Task<Memory<byte>> RunJobAsync(int bufferIndex, Memory<byte> input

// If the input message isn't 64B aligned, pad it with zeros.
var payloadBytes = inputData.Length - InputHeaderSizes.Total;
if (payloadBytes % Constants.BufferChunkBytes != 0)
if (payloadBytes % Constants.Catapult.BufferChunkBytes != 0)
{
int paddedPayloadSize = Constants.BufferChunkBytes * ((payloadBytes / Constants.BufferChunkBytes) + 1);
int paddedPayloadSize = Constants.Catapult.BufferChunkBytes * ((payloadBytes / Constants.Catapult.BufferChunkBytes) + 1);
if (paddedPayloadSize <= BufferPayloadSize)
{
LogLine(
Constants.Log.Warn,
Constants.Catapult.Log.Warn,
StringHelper.Concatenate(
$"Incoming payload ({payloadBytes}B) must be aligned to {Constants.BufferChunkBytes}B! ",
$"Padding for {Constants.BufferChunkBytes - paddedPayloadSize}B..."));
$"Incoming payload ({payloadBytes}B) must be aligned to {Constants.Catapult.BufferChunkBytes}B! ",
$"Padding for {Constants.Catapult.BufferChunkBytes - paddedPayloadSize}B..."));
var padded = new byte[paddedPayloadSize + InputHeaderSizes.Total];
inputData.CopyTo(padded);
inputData = padded;
Expand All @@ -482,7 +478,7 @@ private async Task<Memory<byte>> RunJobAsync(int bufferIndex, Memory<byte> input
VerifyResult(NativeLibrary.GetInputBufferPointer(_handle, slot, out var inputBuffer));

LogLineInvariant(
Constants.Log.Debug,
Constants.Catapult.Log.Debug,
$"Buffer #{slot} @ {inputBuffer.ToInt64()} input start: {Marshal.PtrToStructure<byte>(inputBuffer)}");

// Upload data into input buffer.
Expand Down Expand Up @@ -526,13 +522,13 @@ private async Task<Memory<byte>> ReceiveJobResultsAsync(uint slot)
}

LogLineInvariant(
Constants.Log.Debug,
Constants.Catapult.Log.Debug,
$"Buffer #{slot} @ {outputBuffer.ToInt64()} output start: {Marshal.PtrToStructure<byte>(outputBuffer)}");

// Signal that we are done.
NativeLibrary.DiscardOutputBuffer(_handle, slot);

LogFunction?.Invoke((uint)Constants.Log.Info, $"Job on slot #{slot} finished!{Environment.NewLine}");
LogFunction?.Invoke((uint)Constants.Catapult.Log.Info, $"Job on slot #{slot} finished!{Environment.NewLine}");
return resultMemory;
}

Expand All @@ -544,10 +540,10 @@ private Task TesterWriteLineAsync(string format, params object[] objects)
return TesterOutput.WriteLineAsync(format);
}

private void LogLine(Constants.Log level, string text) =>
private void LogLine(Constants.Catapult.Log level, string text) =>
LogFunction?.Invoke((uint)level, text + Environment.NewLine);

private void LogLineInvariant(Constants.Log level, FormattableString text) =>
private void LogLineInvariant(Constants.Catapult.Log level, FormattableString text) =>
LogFunction?.Invoke((uint)level, text.ToString(CultureInfo.InvariantCulture) + Environment.NewLine);

public override string ToString() => InstanceName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using System;
using System.Diagnostics.CodeAnalysis;

namespace Hast.Catapult;
namespace Hast.Catapult.Constants;

public static class Constants
[SuppressMessage(
"Naming",
"CA1724: Type names should not match namespaces",
Justification = "This class contains the Catapult-specific constants so this is an appropriate name.")]
public static class Catapult
{
public const string Catapult = nameof(Catapult);
public const string ChannelName = Catapult;
public const string DeviceName = nameof(Catapult);
public const string ChannelName = DeviceName;

public const string DefaultLibraryPath = "FpgaCoreLib";

Expand Down
2 changes: 1 addition & 1 deletion src/Hastlayer/Hast.Catapult/Drivers/CatapultDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Hast.Catapult.Drivers;

public class CatapultDriver : IDeviceDriver
{
public const string DeviceName = Constants.Catapult;
public const string DeviceName = Constants.Catapult.DeviceName;

private readonly ITimingReportParser _timingReportParser;
private readonly object _timingReportParserLock = new();
Expand Down
Loading

0 comments on commit 0ae2477

Please sign in to comment.