Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "ext/satsumagraph"]
path = ext/satsumagraph
url = https://github.com/allisterb/satsumagraph.git
28 changes: 28 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,31 @@ When writing complex features or significant refactors, use an ExecPlan (as desc
## Local models

The ONNX model at `models\multilingual-e5-small\model.onnx` is already downloaded from Hugging Face and is git-ignored. Use it for the `lonnx run` e5 example instead of fetching the URL.

## Repo map (high-signal)
- `Lokad.Onnx.slnx`: root solution (XML format); targets net10.0 across projects; includes vendored `ext\NLog`.
- `src\Lokad.Onnx.Base`: shared infra (logging, profiling, hardware config, utilities).
- `src\Lokad.Onnx.Tensors`: core tensor types + ops (managed port of ONNX Runtime tensors); unsafe + SIMD options.
- `src\Lokad.Onnx.Backend`: ONNX graph execution (Model/Node/ComputationalGraph/CPUExecutionProvider).
- `src\Lokad.Onnx.Data`: text + image IO helpers (tokenizers, ImageSharp).
- `src\Lokad.Onnx.CLI`: `lonnx` CLI (verbs: `info`, `run`, `benchmark`); output in `src\Lokad.Onnx.CLI\bin\Release\net10.0\`.
- `src\Lokad.Onnx.Interop`: .NET assembly used by Python interop (`src\interop`).
- `src\interop`: Python bridge + helpers; used by `tests\python` (requires pythonnet + transformers + onnx).
- `src\Lokad.Onnx.Package`: NuGet pack that compiles Base/Tensors/Backend + satsumagraph into single `Lokad.Onnx` package.
- `tests\Lokad.Onnx.Backend.Tests`: xUnit backend tests + MNIST assets.
- `tests\Lokad.Onnx.Tensors.Tests`: xUnit tensor tests.
- `tests\python`: pytest suite comparing .NET vs NumPy/transformers.
- `ext\NLog`: vendored logging source; solution includes project reference.
- `ext\satsumagraph`: git submodule used for graph algorithms (Backend/Package references it).

## Build / run / test (repo conventions)
- Build all: `build.cmd` (restore + CLI build + interop publish). Uses `--tl:off`.
- Pack NuGet: `pack.cmd` (builds `src\Lokad.Onnx.Package`).
- CLI wrapper: `lonnx.cmd` calls Release `Lokad.Onnx.CLI.exe`.
- Run tests: `dotnet test --tl:off --nologo -v minimal --no-build` from repo root.
- Python tests: build interop first (`build.cmd`), then `pip install -r src\interop\requirements.txt`, run `pytest` from repo root.

## CLI quick notes
- `lonnx info <model.onnx>`: model metadata; supports `--ops`, `--init`, `--op-filter`.
- `lonnx run <model.onnx> <inputs...>`: supports image/text inputs, `--softmax`, `--print-input`, profiling, SIMD toggles.
- `lonnx benchmark <id>`: `matmul2d`, `matmul`, `indexing`, `me5s-load`, `me5s-run` with BenchmarkDotNet flags.
20 changes: 20 additions & 0 deletions Lokad.Onnx.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Solution>
<Folder Name="/ext/" />
<Folder Name="/ext/NLog/" />
<Folder Name="/ext/NLog/src/">
<Project Path="ext/NLog/src/NLog/NLog.csproj" />
</Folder>
<Folder Name="/src/">
<Project Path="src/Lokad.Onnx.Backend/Lokad.Onnx.Backend.csproj" />
<Project Path="src/Lokad.Onnx.Base/Lokad.Onnx.Base.csproj" />
<Project Path="src/Lokad.Onnx.CLI/Lokad.Onnx.CLI.csproj" />
<Project Path="src/Lokad.Onnx.Data/Lokad.Onnx.Data.csproj" />
<Project Path="src/Lokad.Onnx.Interop/Lokad.Onnx.Interop.csproj" />
<Project Path="src/Lokad.Onnx.Package/Lokad.Onnx.Package.csproj" />
<Project Path="src/Lokad.Onnx.Tensors/Lokad.Onnx.Tensors.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/Lokad.Onnx.Backend.Tests/Lokad.Onnx.Backend.Tests.csproj" />
<Project Path="tests/Lokad.Onnx.Tensors.Tests/Lokad.Onnx.Tensors.Tests.csproj" />
</Folder>
</Solution>
4 changes: 2 additions & 2 deletions build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ set ERROR_CODE=0

echo Building Lokad Onnx projects..

dotnet restore --tl:off -v minimal src\Lokad.Onnx.sln
dotnet restore --tl:off -v minimal Lokad.Onnx.slnx
if not %ERRORLEVEL%==0 (
echo Error restoring NuGet packages for Lokad.Onnx.sln.
echo Error restoring NuGet packages for Lokad.Onnx.slnx.
set ERROR_CODE=1
goto End
)
Expand Down
1 change: 0 additions & 1 deletion ext/satsumagraph
Submodule satsumagraph deleted from 890f50
4 changes: 2 additions & 2 deletions lonnx.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set ERROR_CODE=0
REM From Alec Mev https://superuser.com/questions/35698/how-to-supress-terminate-batch-job-y-n-confirmation/715798#715798
IF [%JUSTTERMINATE%] == [OKAY] (
SET JUSTTERMINATE=
src\Lokad.Onnx.CLI\bin\Release\net6.0\Lokad.Onnx.CLI.exe %*
src\Lokad.Onnx.CLI\bin\Release\net10.0\Lokad.Onnx.CLI.exe %*
) ELSE (
SET JUSTTERMINATE=OKAY
CALL %0 %* <NUL
Expand All @@ -15,4 +15,4 @@ IF [%JUSTTERMINATE%] == [OKAY] (
:end
@endlocal
popd
exit /B %ERROR_CODE%
exit /B %ERROR_CODE%
4 changes: 2 additions & 2 deletions pack.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ set ERROR_CODE=0

echo Building Lokad Onnx package..

dotnet restore src\Lokad.Onnx.sln
dotnet restore Lokad.Onnx.slnx
if not %ERRORLEVEL%==0 (
echo Error restoring NuGet packages for Lokad.Onnx.sln.
echo Error restoring NuGet packages for Lokad.Onnx.slnx.
set ERROR_CODE=1
goto End
)
Expand Down
14 changes: 0 additions & 14 deletions src/Lokad.Onnx.Backend/ComputationalGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
using System.Diagnostics;
using System.Linq;

using Satsuma;

public class ComputationalGraph : Runtime
{
#region Fields
Expand All @@ -24,8 +22,6 @@ public class ComputationalGraph : Runtime

public List<Node> Nodes { get; set; } = new List<Node>();

public WeightedDirectedGraph WeightedDirectedGraph { get; } = new WeightedDirectedGraph();

public Dictionary<string, int> Opset = new Dictionary<string, int>();

public Dictionary<string, object> Metadata = new Dictionary<string, object>();
Expand Down Expand Up @@ -349,13 +345,3 @@ public void Reset(bool gc = false)
}
#endregion
}

public class WeightedDirectedGraph : AbstractGraph
{
public Satsuma.Node AddNode(string id)
{
var _id = id.GetHashCode();
this.AddNode(_id);
return new Satsuma.Node(_id);
}
}
6 changes: 3 additions & 3 deletions src/Lokad.Onnx.Backend/Lokad.Onnx.Backend.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>10.0</LangVersion>
</PropertyGroup>
Expand All @@ -13,9 +13,9 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\ext\satsumagraph\Satsuma.csproj" />
<ProjectReference Include="..\Lokad.Onnx.Base\Lokad.Onnx.Base.csproj" />
<ProjectReference Include="..\Lokad.Onnx.Tensors\Lokad.Onnx.Tensors.csproj" />
</ItemGroup>

</Project>

1 change: 0 additions & 1 deletion src/Lokad.Onnx.Backend/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public partial struct Node
public long ID;
public string Name;
public Dictionary<string, object>? Attributes;
public Satsuma.Node WeightedGraphNode;
public OpType Op;
public string[] Inputs;
public string[] Outputs;
Expand Down
13 changes: 0 additions & 13 deletions src/Lokad.Onnx.Backend/NodeUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public static Node ToNode(this NodeProto np, ComputationalGraph graph)
{
Name = np.Name,
ID = np.Name.GetHashCode(),
WeightedGraphNode = new Satsuma.Node(np.Name.GetHashCode()),
Attributes = np.Attribute.ToDictionary(k => k.Name, v => v.Value()),
Op = (OpType) Enum.Parse(typeof(OpType), np.OpType),
Inputs = np.Input.ToArray(),
Expand All @@ -41,18 +40,6 @@ public static Node ToNode(this NodeProto np, ComputationalGraph graph)
graph.IntermediateOutputs.Add(o, null);
}
}
graph.WeightedDirectedGraph.AddNode(node.Name);
foreach (var n in graph.Nodes)
{
foreach (var i in node.Inputs)
{
if (n.Outputs.Contains(i))
{
graph.WeightedDirectedGraph.AddArc(n.WeightedGraphNode, node.WeightedGraphNode, Satsuma.Directedness.Directed, label: i);
Runtime.Debug("Node {dest} has predecessor {src}.", node.Name, n.Name);
}
}
}
return node;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Lokad.Onnx.Base/HardwareConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public static class HardwareConfig
{
public static bool UseSimd { get; set; } = true;

public static bool UseIntrinsics { get; set; } = false;
public static bool UseIntrinsics { get; set; } = HardwareIntrinsics.IsX86FmaSupported;

public static void EnableIntrinsics()
{
Expand Down
5 changes: 3 additions & 2 deletions src/Lokad.Onnx.Base/Lokad.Onnx.Base.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -14,3 +14,4 @@
</ItemGroup>

</Project>

5 changes: 3 additions & 2 deletions src/Lokad.Onnx.CLI/Lokad.Onnx.CLI.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand Down Expand Up @@ -31,3 +31,4 @@
</ItemGroup>

</Project>

8 changes: 6 additions & 2 deletions src/Lokad.Onnx.CLI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ static void Run(RunOptions ro)
if (ro.DisableSimd)
{
HardwareConfig.UseSimd = false;
HardwareConfig.UseIntrinsics = false;
Info("CPU SIMD features disabled.");
}
else
Expand All @@ -206,9 +207,12 @@ static void Run(RunOptions ro)
}
}

if (ro.EnableIntrinsics && System.Numerics.Vector.IsHardwareAccelerated)
if (!ro.DisableSimd && System.Numerics.Vector.IsHardwareAccelerated)
{
HardwareConfig.UseIntrinsics = (ro.EnableIntrinsics || HardwareConfig.UseIntrinsics);
}
if (HardwareConfig.UseIntrinsics)
{
HardwareConfig.UseIntrinsics = true;
Info("CPU SIMD available intrinsics: {s}.", HardwareIntrinsics.GetFullInfo());
}
else
Expand Down
9 changes: 5 additions & 4 deletions src/Lokad.Onnx.Data/Lokad.Onnx.Data.csproj
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net80</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>11.0</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FastBertTokenizer" Version="0.4.67" />
<PackageReference Include="Lokad.Tokenizers" Version="0.1.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Lokad.Tokenizers" Version="0.1.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
</ItemGroup>

<ItemGroup>
Expand All @@ -18,3 +18,4 @@
</ItemGroup>

</Project>

5 changes: 3 additions & 2 deletions src/Lokad.Onnx.Interop/Lokad.Onnx.Interop.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -21,3 +21,4 @@
</ItemGroup>

</Project>

6 changes: 3 additions & 3 deletions src/Lokad.Onnx.Package/Lokad.Onnx.Package.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
<LangVersion>preview</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>annotations</Nullable>
Expand All @@ -23,7 +23,6 @@
<Compile Include="..\Lokad.Onnx.Base\**\*.cs" />
<Compile Include="..\Lokad.Onnx.Tensors\**\*.cs" />
<Compile Include="..\Lokad.Onnx.Backend\**\*.cs" />
<Compile Include="..\..\ext\satsumagraph\src\**\*.cs" />
<Compile Remove="**\obj\**" />
</ItemGroup>

Expand All @@ -47,3 +46,4 @@
</ItemGroup>

</Project>

5 changes: 3 additions & 2 deletions src/Lokad.Onnx.Tensors/Lokad.Onnx.Tensors.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
<LangVersion>preview</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>warnings</Nullable>
Expand All @@ -17,3 +17,4 @@
</ItemGroup>

</Project>

25 changes: 18 additions & 7 deletions src/Lokad.Onnx.Tensors/TensorOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@ public static Tensor<int> MatMul2D(Tensor<int> x, Tensor<int> y)
var n = x.Dimensions[1];
var k = y.Dimensions[1];

var _x = x.ToDenseTensor();
var _y = y.ToDenseTensor();
var dx = x as DenseTensor<int>;
var dy = y as DenseTensor<int>;
var _x = dx is not null && !dx.IsReversedStride ? dx : x.ToDenseTensor();
var _y = dy is not null && !dy.IsReversedStride ? dy : y.ToDenseTensor();
var output = DenseTensor<int>.OfShape(new int[] { x.Dimensions[0], y.Dimensions[1] });

var xh = _x.Buffer.Pin();
Expand Down Expand Up @@ -363,9 +365,16 @@ public static Tensor<float> MatMul2D(Tensor<float> x, Tensor<float> y)
var n = x.Dimensions[1];
var k = y.Dimensions[1];

StartOpStage(OpStage.Copy);
var _x = x.ToDenseTensor();
var _y = y.ToDenseTensor();
var dx = x as DenseTensor<float>;
var dy = y as DenseTensor<float>;
var needsCopyX = dx is null || dx.IsReversedStride;
var needsCopyY = dy is null || dy.IsReversedStride;
if (needsCopyX || needsCopyY)
{
StartOpStage(OpStage.Copy);
}
var _x = needsCopyX ? x.ToDenseTensor() : dx!;
var _y = needsCopyY ? y.ToDenseTensor() : dy!;
var output = DenseTensor<float>.OfShape(new int[] { x.Dimensions[0], y.Dimensions[1] });

StartOpStage(OpStage.Math);
Expand Down Expand Up @@ -416,8 +425,10 @@ public static Tensor<double> MatMul2D(Tensor<double> x, Tensor<double> y)
var k = y.Dimensions[1];


var _x = x.ToDenseTensor();
var _y = y.ToDenseTensor();
var dx = x as DenseTensor<double>;
var dy = y as DenseTensor<double>;
var _x = dx is not null && !dx.IsReversedStride ? dx : x.ToDenseTensor();
var _y = dy is not null && !dy.IsReversedStride ? dy : y.ToDenseTensor();
var output = DenseTensor<double>.OfShape(new int[] { x.Dimensions[0], y.Dimensions[1] });

var xh = _x.Buffer.Pin();
Expand Down
Loading