Skip to content
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

Tensor arithmetic #69

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
aecc2be
Add static methods to create zero vectors/matrices.
izrik Jan 6, 2023
b8afb4b
Add early support for variadic functions.
izrik Jan 6, 2023
b700f17
Add tests for addition (currently failing).
izrik Jan 6, 2023
3b8a464
Add a type for fixed and variadic functions on vectors.
izrik Jan 6, 2023
6a3de07
Make sure subsequent invocations return the same object.
izrik Jan 9, 2023
8c783b6
Add an intermediate interface to represent function types.
izrik Jan 14, 2023
da9625c
Use a property on functions to give the function type.
izrik Jan 14, 2023
48fda2d
Add explanation.
izrik Jan 14, 2023
4bf870b
Fix the case of nullary functions.
izrik Jan 14, 2023
9eeb099
More explanation.
izrik Jan 14, 2023
5b76ee2
todo
izrik Jan 14, 2023
b2e8b99
Define superset in terms of subset, so the logic doesn't have to be d…
izrik Jan 14, 2023
68144a9
readonly
izrik Jan 16, 2023
53db10b
Check the function call arguments based on the FunctionType instead o…
izrik Jan 16, 2023
1202163
Add test cases for the new variadic functions type. Clean up the test…
izrik Jan 16, 2023
052cba6
Test the FunctionType property.
izrik Jan 16, 2023
53e00db
Fix number of args.
izrik Jan 18, 2023
e0818c3
Fix exception type.
izrik Jan 18, 2023
5f586ec
Clean up and improve docs of function types.
izrik Jan 18, 2023
9d4e358
Exaplanation.
izrik Jan 18, 2023
7526281
Turn AdditionOperation into just a Function.
izrik Jan 18, 2023
ed308e7
Check the arguments for vectors and matrices.
izrik Feb 3, 2023
1e19672
Add vectors together.
izrik Feb 3, 2023
634680e
Add matrices together.
izrik Feb 3, 2023
397751a
Pass the environment while compiling, and use that to store the types…
izrik Feb 7, 2023
9dccc7f
Fix tests.
izrik Feb 7, 2023
5be7165
Fix explanation and examples.
izrik Dec 4, 2023
344c3fb
todo
izrik Dec 4, 2023
37acbb8
Actually load the file.
izrik Dec 4, 2023
0a37e10
Add important clarification for the unwary.
izrik Dec 4, 2023
e8f1c7b
todo
izrik Dec 4, 2023
470519d
Simplify matrix-of-literals to literal-of-matrix, so it actually adds…
izrik Dec 4, 2023
3f42163
Provide interfaces to eventually replace the intermediate function su…
izrik Dec 5, 2023
07f8efc
Make addition an operation again, using the interface.
izrik Dec 5, 2023
cf6f843
Extract static function.
izrik Dec 5, 2023
5802c55
Render addition expressions correctly.
izrik Dec 5, 2023
ab7ac52
Change multiplication to a plain function, with interface.
izrik Dec 5, 2023
feb512a
Use interfaces throughout.
izrik Dec 5, 2023
45c7c6b
Don't use the interfaces for argument checking.
izrik Dec 5, 2023
8b1e098
Teach MultiplicationOperation to accept vectors and matrices.
izrik Dec 6, 2023
055d297
Make specialized vector types completely equivalent to the generalize…
izrik Dec 6, 2023
0ff1c7c
Add some utility constructors.
izrik Dec 6, 2023
3d10fd7
Check the other way around.
izrik Dec 6, 2023
460fbff
todo
izrik Dec 6, 2023
b8111d2
Also check the number of arguments.
izrik Dec 6, 2023
c713a4b
Partially implement matrix and vector multiplication.
izrik Dec 6, 2023
14ef733
todo
izrik Dec 6, 2023
e42b6f9
Fix test name.
izrik Aug 20, 2024
2a84ece
Change the test to check for the custom function type.
izrik Aug 20, 2024
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
8 changes: 5 additions & 3 deletions Compiler/ILCompiler.Expressions.ComponentAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,17 @@ static Type[] GetTypeArrayOfInt(int length)
}

public IlExpression ConvertToIlExpression(ComponentAccess expr,
NascentMethod nm, VariableIdentityMap variables)
NascentMethod nm, SolusEnvironment env,
VariableIdentityMap variables)
{
var expr2 = ConvertToIlExpression(expr.Expr, nm, variables);
var expr2 = ConvertToIlExpression(expr.Expr, nm, env, variables);
var indexes2 = new IlExpression[expr.Indexes.Count];
int i;
for (i = 0; i < indexes2.Length; i++)
{
indexes2[i] = new ConvertI4IlExpression(
ConvertToIlExpression(expr.Indexes[i], nm, variables));
ConvertToIlExpression(expr.Indexes[i], nm, env,
variables));
}

// TODO: check expr.ResultType against the number of indexes
Expand Down
5 changes: 3 additions & 2 deletions Compiler/ILCompiler.Expressions.FunctionCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
FunctionCall expr, NascentMethod nm,
VariableIdentityMap variables)
SolusEnvironment env, VariableIdentityMap variables)
{
if (expr.Function is Literal literal &&
literal.Value is Function f)
return ConvertToIlExpression(f, nm, variables, expr.Arguments);
return ConvertToIlExpression(f, nm, env, variables,
expr.Arguments);

// TODO:
throw new NotImplementedException(
Expand Down
2 changes: 1 addition & 1 deletion Compiler/ILCompiler.Expressions.Literal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
Literal expr, NascentMethod nm,
VariableIdentityMap variables)
SolusEnvironment env, VariableIdentityMap variables)
{
// TODO: work out how to use `variables` in place of null `env`

Expand Down
6 changes: 4 additions & 2 deletions Compiler/ILCompiler.Expressions.MatrixExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace MetaphysicsIndustries.Solus.Compiler
public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(MatrixExpression expr,
NascentMethod nm, VariableIdentityMap variables)
NascentMethod nm, SolusEnvironment env,
VariableIdentityMap variables)
{
var arrayType = typeof(float[,]);
var ctor = arrayType.GetConstructor(
Expand All @@ -51,7 +52,8 @@ public IlExpression ConvertToIlExpression(MatrixExpression expr,
dup,
new LoadConstantIlExpression(r),
new LoadConstantIlExpression(c),
ConvertToIlExpression(expr[r, c], nm, variables)));
ConvertToIlExpression(expr[r, c], nm, env,
variables)));
return new IlExpressionSequence(seq);
}
}
Expand Down
2 changes: 1 addition & 1 deletion Compiler/ILCompiler.Expressions.VariableAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
VariableAccess expr, NascentMethod nm,
VariableIdentityMap variables)
SolusEnvironment env, VariableIdentityMap variables)
{
var vi = variables[expr.VariableName];
if (vi.Source == VariableSource.Param)
Expand Down
6 changes: 4 additions & 2 deletions Compiler/ILCompiler.Expressions.VectorExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace MetaphysicsIndustries.Solus.Compiler
public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(VectorExpression expr,
NascentMethod nm, VariableIdentityMap variables)
NascentMethod nm, SolusEnvironment env,
VariableIdentityMap variables)
{
var seq = new List<IlExpression>();
var newarr = new NewArrIlExpression(
Expand All @@ -42,7 +43,8 @@ public IlExpression ConvertToIlExpression(VectorExpression expr,
new StoreElemIlExpression(
array_: new DupIlExpression(newarr),
index: new LoadConstantIlExpression(i),
value: ConvertToIlExpression(expr[i], nm, variables)));
value: ConvertToIlExpression(expr[i], nm, env,
variables)));

return new IlExpressionSequence(seq);
}
Expand Down
25 changes: 14 additions & 11 deletions Compiler/ILCompiler.Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,37 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
Expression expr, NascentMethod nm,
VariableIdentityMap variables)
SolusEnvironment env, VariableIdentityMap variables)
{
if (expr is FunctionCall call)
return ConvertToIlExpression(call, nm, variables);
return ConvertToIlExpression(call, nm, env, variables);
if (expr is Literal lit)
return ConvertToIlExpression(lit, nm, variables);
return ConvertToIlExpression(lit, nm, env, variables);
if (expr is VariableAccess va)
return ConvertToIlExpression(va, nm, variables);
return ConvertToIlExpression(va, nm, env, variables);
if (expr is ComponentAccess ca)
return ConvertToIlExpression(ca, nm, variables);
return ConvertToIlExpression(ca, nm, env, variables);
if (expr is VectorExpression ve)
return ConvertToIlExpression(ve, nm, variables);
return ConvertToIlExpression(ve, nm, env, variables);
if (expr is MatrixExpression me)
return ConvertToIlExpression(me, nm, variables);
return ConvertToIlExpression(me, nm, env, variables);
if (expr is IntervalExpression ie)
return ConvertToIlExpression(ie, nm, variables);
return ConvertToIlExpression(ie, nm, env, variables);
throw new ArgumentException(
$"Unsupported expression type: \"{expr}\"", nameof(expr));
}

// TODO: copy-paste IlCompiler.Expressions.*.cs here

public IlExpression ConvertToIlExpression(IntervalExpression expr,
NascentMethod nm, VariableIdentityMap variables)
NascentMethod nm, SolusEnvironment env,
VariableIdentityMap variables)
{
var lower = ConvertToIlExpression(expr.LowerBound, nm, variables);
var lower = ConvertToIlExpression(expr.LowerBound, nm, env,
variables);
var isLowerOpen = new LoadConstantIlExpression(expr.OpenLowerBound);
var upper = ConvertToIlExpression(expr.UpperBound, nm, variables);
var upper = ConvertToIlExpression(expr.UpperBound, nm, env,
variables);
var isUpperOpen = new LoadConstantIlExpression(expr.OpenUpperBound);
// TODO: IsIntegerInterval ?
var stuple = typeof(STuple<float, bool, float, bool>);
Expand Down
4 changes: 2 additions & 2 deletions Compiler/ILCompiler.Functions.AbsoluteValueFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
AbsoluteValueFunction func, NascentMethod nm,
VariableIdentityMap variables,
SolusEnvironment env, VariableIdentityMap variables,
List<Expression> arguments)
{
return new CallIlExpression(
new Func<double, double>(Math.Abs),
ConvertToIlExpression(arguments[0], nm, variables));
ConvertToIlExpression(arguments[0], nm, env, variables));
}
}
}
152 changes: 134 additions & 18 deletions Compiler/ILCompiler.Functions.AdditionOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,159 @@

using System.Collections.Generic;
using MetaphysicsIndustries.Solus.Compiler.IlExpressions;
using MetaphysicsIndustries.Solus.Exceptions;
using MetaphysicsIndustries.Solus.Expressions;
using MetaphysicsIndustries.Solus.Functions;
using MetaphysicsIndustries.Solus.Sets;
using MetaphysicsIndustries.Solus.Values;

namespace MetaphysicsIndustries.Solus.Compiler
{
public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
AdditionOperation func, NascentMethod nm,
VariableIdentityMap variables,
SolusEnvironment env, VariableIdentityMap variables,
List<Expression> arguments)
{
IlExpression expr = new RawInstructions();

bool first = true;
foreach (var arg in arguments)
var argType = arguments[0].GetResultType(env);
if (argType.IsSubsetOf(Reals.Value)){
bool first = true;
foreach (var arg in arguments)
{
if (!first &&
arg is FunctionCall call &&
call.Function is Literal literal &&
literal.Value is Function f &&
f == NegationOperation.Value)
{
expr = new SubIlExpression(expr,
ConvertToIlExpression(call.Arguments[0], nm,
env, variables));
}
else
{
if (first)
expr = ConvertToIlExpression(arg, nm, env,
variables);
else
expr = new AddIlExpression(expr,
ConvertToIlExpression(arg, nm, env,
variables));
first = false;
}
}
}
else if (argType is Vectors vt)
{
if (!first &&
arg is FunctionCall call &&
call.Function is Literal literal &&
literal.Value is Function f &&
f == NegationOperation.Value)
int n = vt.Dimension;
var seq = new List<IlExpression>();
var destLocal = nm.CreateLocal(typeof(float[]), "vectorSum");
var stloc = new StoreLocalIlExpression(
destLocal,
ConvertToIlExpression(
new Literal(Vector.Zero(n)), nm, env, variables));
seq.Add(stloc);
var addendLocal =
nm.CreateLocal(typeof(float[]), "vectorAddend");
foreach (var arg in arguments)
{
expr = new SubIlExpression(expr,
ConvertToIlExpression(call.Arguments[0], nm,
variables));
seq.Add(
new StoreLocalIlExpression(
addendLocal,
ConvertToIlExpression(arg, nm, env, variables)));
// TODO: logic to choose between a loop (e.g.
// WhileLoopConstruct) and a hard-coded sequence of
// instructions, or something in between, like a
// partially unrolled loop, or even a duff's device.
int i;
for (i = 0; i < n; i++)
seq.Add(new StoreElemIlExpression(
new LoadLocalIlExpression(destLocal),
new LoadConstantIlExpression(i),
new AddIlExpression(
new LoadElemIlExpression(
new LoadLocalIlExpression(destLocal),
new LoadConstantIlExpression(i)),
new LoadElemIlExpression(
new LoadLocalIlExpression(addendLocal),
new LoadConstantIlExpression(i)))));
}
else

seq.Add(new LoadLocalIlExpression(destLocal));

return new IlExpressionSequence(seq);
}
else if (argType is Matrices mt)
{
int nr = mt.RowCount;
int nc = mt.ColumnCount;
var seq = new List<IlExpression>();
var destLocal = nm.CreateLocal(typeof(float[]), "sum");
var stloc = new StoreLocalIlExpression(
destLocal,
ConvertToIlExpression(
new Literal(Matrix.Zero(nr, nc)),
nm, env, variables));
seq.Add(stloc);
var addendLocal =
nm.CreateLocal(typeof(float[]), "addend");
foreach (var arg in arguments)
{
if (first)
expr = ConvertToIlExpression(arg, nm, variables);
else
expr = new AddIlExpression(expr,
ConvertToIlExpression(arg, nm, variables));
first = false;
seq.Add(
new StoreLocalIlExpression(
addendLocal,
ConvertToIlExpression(arg, nm, env, variables)));
// TODO: logic to choose between loops (e.g.
// WhileLoopConstruct) and a hard-coded sequence of
// instructions, or something in between, like
// partially unrolled loops, or even duff's device.
var arrayType = typeof(float[,]);
var ctor = arrayType.GetConstructor(
new[] { typeof(int), typeof(int) });
var getMethod = arrayType.GetMethod("Get",
new[] { typeof(int), typeof(int) });
var setMethod = arrayType.GetMethod("Set",
new[] { typeof(int), typeof(int), typeof(float) });
var destIl = new LoadLocalIlExpression(destLocal);
var addendIl = new LoadLocalIlExpression(addendLocal);
int r, c;
for (r = 0; r < nr; r++)
{
var ril = new LoadConstantIlExpression(r);
for (c = 0; c < nc; c++)
{
var cil = new LoadConstantIlExpression(c);
seq.Add(
new CallIlExpression(
setMethod,
destIl,
ril,
cil,
new AddIlExpression(
new CallIlExpression(
getMethod,
destIl,
ril,
cil),
new CallIlExpression(
getMethod,
addendIl,
ril,
cil))));
}
}
}

seq.Add(new LoadLocalIlExpression(destLocal));

return new IlExpressionSequence(seq);
}
else
throw new TypeException("argument at index 0",
$"Unsupported type for addition: {argType.DisplayName}");

return expr;
}
Expand Down
4 changes: 2 additions & 2 deletions Compiler/ILCompiler.Functions.ArccosecantFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
ArccosecantFunction func, NascentMethod nm,
VariableIdentityMap variables,
SolusEnvironment env, VariableIdentityMap variables,
List<Expression> arguments)
{
var expr = new CallIlExpression(
typeof(Math).GetMethod(
"Asin", new [] { typeof(float) }),
new DivIlExpression(
new LoadConstantIlExpression(1f),
ConvertToIlExpression(arguments[0], nm, variables)));
ConvertToIlExpression(arguments[0], nm, env, variables)));
return expr;
}
}
Expand Down
4 changes: 2 additions & 2 deletions Compiler/ILCompiler.Functions.ArccosineFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
ArccosineFunction func, NascentMethod nm,
VariableIdentityMap variables,
SolusEnvironment env, VariableIdentityMap variables,
List<Expression> arguments)
{
var excType = typeof(OperandException);
Expand All @@ -45,7 +45,7 @@ public IlExpression ConvertToIlExpression(
var expr = new CallIlExpression(
new Func<double, double>(Math.Acos));
var seq = new List<IlExpression>();
var arg = ConvertToIlExpression(arguments[0], nm, variables);
var arg = ConvertToIlExpression(arguments[0], nm, env, variables);
seq.Add(arg);
seq.Add(
new CompareLessThanIlExpression(
Expand Down
4 changes: 2 additions & 2 deletions Compiler/ILCompiler.Functions.ArccotangentFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ public partial class ILCompiler
{
public IlExpression ConvertToIlExpression(
ArccotangentFunction func, NascentMethod nm,
VariableIdentityMap variables,
SolusEnvironment env, VariableIdentityMap variables,
List<Expression> arguments)
{
var expr = new CallIlExpression(
new Func<double, double, double>(Math.Atan2),
new LoadConstantIlExpression(1f),
ConvertToIlExpression(arguments[0], nm, variables));
ConvertToIlExpression(arguments[0], nm, env, variables));
return expr;
}
}
Expand Down
Loading
Loading