Browse Source

More unit tests

master
Ashley Hauck 12 years ago
parent
commit
7c6cb2f93b
  1. 2
      CudaSharp/CudaSharp.cs
  2. 1
      CudaSharp/CudaSharp.csproj
  3. 2
      CudaSharp/Disasm.cs
  4. 137
      CudaSharp/Translator.cs
  5. 3
      CudaSharpTest/CudaSharpTest.csproj
  6. 110
      CudaSharpTest/UnitTests.cs

2
CudaSharp/CudaSharp.cs

@ -85,8 +85,6 @@ namespace CudaSharp
var module = Translator.Translate(Context.Global, methods);
kernelNames = methods.Select(m => m.Name.StripNameToValidPtx()).ToArray();
var ptx = PInvokeHelper.EmitInMemory(module, targetCpu);
//Console.WriteLine(Marshal.PtrToStringAnsi(PInvoke.LLVMPrintModuleToString(module)));
//Console.Write(Encoding.UTF8.GetString(ptx));
return ptx;
}

1
CudaSharp/CudaSharp.csproj

@ -21,6 +21,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\CudaSharp.XML</DocumentationFile>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>

2
CudaSharp/Disasm.cs

@ -69,7 +69,7 @@ namespace CudaSharp
parameter = stream.ReadInt16();
break;
case OperandType.ShortInlineBrTarget:
parameter = stream.ReadByte();
parameter = stream.ReadSByte();
break;
case OperandType.ShortInlineI:
parameter = stream.ReadSByte();

137
CudaSharp/Translator.cs

@ -93,6 +93,7 @@ namespace CudaSharp
var efo = new EmitFuncObj(module, function, body, writer, null, new Stack<Value>(),
body == null ? null : new Value[body.LocalVariables.Count], new Value[llvmParameters.Length]);
PrintHeader(efo);
foreach (var opcode in opcodes)
{
if (EmitFunctions.ContainsKey(opcode.Opcode) == false)
@ -105,6 +106,17 @@ namespace CudaSharp
return function;
}
private static void PrintHeader(EmitFuncObj _)
{
for (var index = 0; index < _.Parameters.Length; index++)
{
_.Parameters[index] = _.Builder.StackAlloc(_.Function[index].Type);
_.Builder.Store(_.Function[index], _.Parameters[index]);
}
for (var index = 0; index < _.Locals.Length; index++)
_.Locals[index] = _.Builder.StackAlloc(ConvertType(_.Module, _.CilMethod.LocalVariables[index].LocalType));
}
private static void FindBranchTargets(IList<OpCodeInstruction> opCodes, Context context, Function function)
{
for (var i = 0; i < opCodes.Count; i++)
@ -294,28 +306,28 @@ namespace CudaSharp
{OpCodes.Cgt_Un, CgtUn},
{OpCodes.Clt, Clt},
{OpCodes.Clt_Un, CltUn},
{OpCodes.Ldloca, _ => LdVarA(_, _.Locals, Convert.ToInt32(_.Argument), false)},
{OpCodes.Ldloca_S, _ => LdVarA(_, _.Locals, Convert.ToInt32(_.Argument), false)},
{OpCodes.Ldloc, _ => LdVar(_, _.Locals, Convert.ToInt32(_.Argument), false)},
{OpCodes.Ldloc_S, _ => LdVar(_, _.Locals, Convert.ToInt32(_.Argument), false)},
{OpCodes.Ldloc_0, _ => LdVar(_, _.Locals, 0, false)},
{OpCodes.Ldloc_1, _ => LdVar(_, _.Locals, 1, false)},
{OpCodes.Ldloc_2, _ => LdVar(_, _.Locals, 2, false)},
{OpCodes.Ldloc_3, _ => LdVar(_, _.Locals, 3, false)},
{OpCodes.Ldloca, _ => LdVarA(_, _.Locals, Convert.ToInt32(_.Argument))},
{OpCodes.Ldloca_S, _ => LdVarA(_, _.Locals, Convert.ToInt32(_.Argument))},
{OpCodes.Ldloc, _ => LdVar(_, _.Locals, Convert.ToInt32(_.Argument))},
{OpCodes.Ldloc_S, _ => LdVar(_, _.Locals, Convert.ToInt32(_.Argument))},
{OpCodes.Ldloc_0, _ => LdVar(_, _.Locals, 0)},
{OpCodes.Ldloc_1, _ => LdVar(_, _.Locals, 1)},
{OpCodes.Ldloc_2, _ => LdVar(_, _.Locals, 2)},
{OpCodes.Ldloc_3, _ => LdVar(_, _.Locals, 3)},
{OpCodes.Stloc, _ => StVar(_, _.Locals, Convert.ToInt32(_.Argument))},
{OpCodes.Stloc_S, _ => StVar(_, _.Locals, Convert.ToInt32(_.Argument))},
{OpCodes.Stloc_0, _ => StVar(_, _.Locals, 0)},
{OpCodes.Stloc_1, _ => StVar(_, _.Locals, 1)},
{OpCodes.Stloc_2, _ => StVar(_, _.Locals, 2)},
{OpCodes.Stloc_3, _ => StVar(_, _.Locals, 3)},
{OpCodes.Ldarga, _ => LdVarA(_, _.Parameters, Convert.ToInt32(_.Argument), true)},
{OpCodes.Ldarga_S, _ => LdVarA(_, _.Parameters, Convert.ToInt32(_.Argument), true)},
{OpCodes.Ldarg, _ => LdVar(_, _.Parameters, Convert.ToInt32(_.Argument), true)},
{OpCodes.Ldarg_S, _ => LdVar(_, _.Parameters, Convert.ToInt32(_.Argument), true)},
{OpCodes.Ldarg_0, _ => LdVar(_, _.Parameters, 0, true)},
{OpCodes.Ldarg_1, _ => LdVar(_, _.Parameters, 1, true)},
{OpCodes.Ldarg_2, _ => LdVar(_, _.Parameters, 2, true)},
{OpCodes.Ldarg_3, _ => LdVar(_, _.Parameters, 3, true)},
{OpCodes.Ldarga, _ => LdVarA(_, _.Parameters, Convert.ToInt32(_.Argument))},
{OpCodes.Ldarga_S, _ => LdVarA(_, _.Parameters, Convert.ToInt32(_.Argument))},
{OpCodes.Ldarg, _ => LdVar(_, _.Parameters, Convert.ToInt32(_.Argument))},
{OpCodes.Ldarg_S, _ => LdVar(_, _.Parameters, Convert.ToInt32(_.Argument))},
{OpCodes.Ldarg_0, _ => LdVar(_, _.Parameters, 0)},
{OpCodes.Ldarg_1, _ => LdVar(_, _.Parameters, 1)},
{OpCodes.Ldarg_2, _ => LdVar(_, _.Parameters, 2)},
{OpCodes.Ldarg_3, _ => LdVar(_, _.Parameters, 3)},
{OpCodes.Starg, _ => StVar(_, _.Parameters, Convert.ToInt32(_.Argument))},
{OpCodes.Starg_S, _ => StVar(_, _.Parameters, Convert.ToInt32(_.Argument))},
{OpCodes.Br, Br},
@ -346,17 +358,26 @@ namespace CudaSharp
{OpCodes.Bgt_Un_S, _ => {CgtUn(_);BrCond(_, true);}},
{OpCodes.Tailcall, _ => {}},
{OpCodes.Call, Call},
{OpCodes.Ldfld, _ => _.Stack.Push(_.Builder.Load(ElementPointer(_, _.Stack.Pop(), FieldIndex((FieldInfo)_.Argument))))},
{OpCodes.Ldfld, Ldfld},
{OpCodes.Stfld, _ => {var value = _.Stack.Pop(); var ptr = _.Stack.Pop(); _.Builder.Store(value, ElementPointer(_, ptr, FieldIndex((FieldInfo)_.Argument)));}},
{OpCodes.Newobj, _ => { _.Stack.Push(_.Builder.StackAlloc(ConvertType(_.Module, ((ConstructorInfo)_.Argument).DeclaringType))); Call(_); }},
{OpCodes.Newobj, _ => { NewobjPreConstructor(_); Call(_); }},
{OpCodes.Initobj, _ => _.Builder.Store(ConvertType(_.Module, (System.Type)_.Argument).Zero, _.Stack.Pop())},
};
private static void Ldfld(EmitFuncObj _)
{
var obj = _.Stack.Pop();
if (obj.Type is PointerType)
_.Stack.Push(_.Builder.Load(ElementPointer(_, obj, FieldIndex((FieldInfo)_.Argument))));
else
_.Stack.Push(_.Builder.Extract(obj, FieldIndex((FieldInfo)_.Argument)));
}
private static Value ElementPointer(EmitFuncObj _, Value pointer, int index)
{
var zeroConstant = IntegerType.GetInt32(_.Context).Constant(0, false);
var indexConstant = IntegerType.GetInt32(_.Context).Constant((ulong)index, false);
return _.Builder.Element(pointer, new Value[] { zeroConstant, indexConstant });
return _.Builder.Element(pointer, new Value[] { zeroConstant, indexConstant }); // guarenteed to be pointer type
}
private static IEnumerable<FieldInfo> AllFields(System.Type type)
@ -369,60 +390,95 @@ namespace CudaSharp
return AllFields(field.DeclaringType).IndexOf(f => f == field);
}
private static void NewobjPreConstructor(EmitFuncObj _)
{
var stackalloca = _.Builder.StackAlloc(ConvertType(_.Module, ((ConstructorInfo)_.Argument).DeclaringType));
var altstack = new Stack<Value>();
var paramLength = ((MethodBase)_.Argument).GetParameters().Length;
for (var i = 0; i < paramLength; i++)
altstack.Push(_.Stack.Pop());
_.Stack.Push(stackalloca);
for (var i = 0; i < paramLength; i++)
_.Stack.Push(altstack.Pop());
}
private static void Call(EmitFuncObj _)
{
var method = (MethodBase)_.Argument;
var count = method.GetParameters().Length;
if (method is ConstructorInfo)
if (method is ConstructorInfo || method.IsStatic == false)
count++;
var args = Enumerable.Range(0, count).Select(x => _.Stack.Pop()).Reverse().ToArray();
var result = _.Builder.Call(EmitFunction(_.Module, method), args);
if (result.Type.StructuralEquals(Type.GetVoid(_.Context)) == false)
_.Stack.Push(result);
else if (method is ConstructorInfo)
_.Stack.Push(_.Builder.Load(args[0]));
}
private static void FlipTopTwoStack(EmitFuncObj _)
{
var top = _.Stack.Pop();
var bottom = _.Stack.Pop();
_.Stack.Push(top);
_.Stack.Push(bottom);
}
private static void Ceq(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.Equal, PopNoBool(_), PopNoBool(_)));
}
private static void Cgt(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.SignedGreater, _.Stack.Pop(), _.Stack.Pop()));
}
private static void CgtUn(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.UnsignedGreater, _.Stack.Pop(), _.Stack.Pop()));
}
private static void Cge(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.SignedGreaterEqual, _.Stack.Pop(), _.Stack.Pop()));
}
private static void CgeUn(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.UnsignedGreaterEqual, _.Stack.Pop(), _.Stack.Pop()));
}
private static void Clt(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.SignedLess, _.Stack.Pop(), _.Stack.Pop()));
}
private static void CltUn(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.UnsignedLess, _.Stack.Pop(), _.Stack.Pop()));
}
private static void Cle(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.SignedLessEqual, _.Stack.Pop(), _.Stack.Pop()));
}
private static void CleUn(EmitFuncObj _)
{
FlipTopTwoStack(_);
_.Stack.Push(_.Builder.Compare(IntegerComparison.UnsignedLessEqual, _.Stack.Pop(), _.Stack.Pop()));
}
@ -465,50 +521,19 @@ namespace CudaSharp
_.Builder = new InstructionBuilder(_.Context, cont);
}
private static void LdVar(EmitFuncObj _, Value[] values, int index, bool isParameter)
private static void LdVar(EmitFuncObj _, Value[] values, int index)
{
if (values[index] == null)
{
if (!isParameter)
throw new CudaSharpException("Uninitialized variable at index " + index);
var arg = _.Function[index];
values[index] = _.Builder.StackAlloc(_.Function[index].Type);
_.Builder.Store(arg, values[index]);
_.Stack.Push(arg);
}
else
{
var load = _.Builder.Load(values[index]);
_.Stack.Push(load);
}
_.Stack.Push(_.Builder.Load(values[index]));
}
private static void LdVarA(EmitFuncObj _, Value[] values, int index, bool isParameter)
private static void LdVarA(EmitFuncObj _, Value[] values, int index)
{
if (values[index] == null)
{
if (isParameter)
{
var arg = _.Function[index];
values[index] = _.Builder.StackAlloc(_.Function[index].Type);
_.Builder.Store(arg, values[index]);
}
else
values[index] = _.Builder.StackAlloc(ConvertType(_.Module, _.CilMethod.LocalVariables[index].LocalType));
_.Stack.Push(values[index]);
}
else
{
_.Stack.Push(values[index]);
}
_.Stack.Push(values[index]);
}
private static void StVar(EmitFuncObj _, Value[] values, int index)
{
var pop = _.Stack.Pop();
if (values[index] == null)
values[index] = _.Builder.StackAlloc(pop.Type);
_.Builder.Store(pop, values[index]);
_.Builder.Store(_.Stack.Pop(), values[index]);
}
private static void StElem(EmitFuncObj _)

3
CudaSharpTest/CudaSharpTest.csproj

@ -13,7 +13,7 @@
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@ -45,7 +45,6 @@
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UnitTests.cs" />
</ItemGroup>

110
CudaSharpTest/UnitTests.cs

@ -1,4 +1,6 @@
using System;
using System.Linq;
using CudaSharp;
using ManagedCuda;
using NUnit.Framework;
@ -7,7 +9,7 @@ namespace CudaSharpTest
class UnitTests
{
private CudaContext _context;
[SetUp]
public void Initialize()
{
@ -18,8 +20,10 @@ namespace CudaSharpTest
{
var methodInfo = method.Method;
string[] kernels;
var ptx = CudaSharp.CudaSharp.Translate(out kernels, methodInfo);
Console.WriteLine(kernels[0]);
string llvmIr, ptxIr;
var ptx = CudaSharp.CudaSharp.Translate(out kernels, out llvmIr, out ptxIr, "sm_20", methodInfo);
Console.WriteLine(llvmIr);
Console.WriteLine(ptxIr);
var kernel = _context.LoadKernelPTX(ptx, kernels[0]);
var maxThreads = kernel.MaxThreadsPerBlock;
if (parameters.Length <= maxThreads)
@ -63,5 +67,103 @@ namespace CudaSharpTest
{
Assert.AreEqual(4, RunKernel(p => p[0] = CallTest(p[0]), 2));
}
struct SingleValueStruct
{
public SingleValueStruct(int x)
{
X = x;
}
public int X;
}
private static SingleValueStruct StructByValTest(SingleValueStruct obj)
{
obj.X = obj.X + 2;
return obj;
}
[Test, Ignore]
public void StructByValue()
{
Assert.AreEqual(4, RunKernel(p => p[0] = StructByValTest(new SingleValueStruct(p[0])).X, 2));
}
private static void StructByRefTest(ref SingleValueStruct obj)
{
obj.X = obj.X + 2;
}
[Test]
public void StructByRef()
{
Assert.AreEqual(4, RunKernel(p =>
{
var obj = new SingleValueStruct(p[0]);
StructByRefTest(ref obj);
p[0] = obj.X;
}, 2));
}
[Test]
public void IfStatement()
{
Assert.AreEqual(4, RunKernel(p =>
{
if (p[0] == 2)
p[0] = 4;
}, 2));
}
[Test]
public void IfNotStatement()
{
Assert.AreEqual(4, RunKernel(p =>
{
if (p[0] != 1)
p[0] = 4;
}, 2));
}
[Test]
public void IfCltStatement()
{
Assert.AreEqual(4, RunKernel(p =>
{
if (p[0] < 4)
p[0] = 4;
}, 2));
}
[Test]
public void WhileStatement()
{
Assert.AreEqual(4, RunKernel(p =>
{
while (p[0] != 4)
p[0]++;
}, 2));
}
[Test]
public void ForStatement()
{
Assert.AreEqual(4, RunKernel(p =>
{
for (var i = 0; i < 2; i++)
p[0]++;
}, 2));
}
[Test]
public void ThreadIdxIntrinsics()
{
Assert.AreEqual(Enumerable.Range(0, 256).ToArray(), RunKernel(p =>
{
var tid = Gpu.BlockX() * Gpu.ThreadDimX() + Gpu.ThreadX();
p[tid] = tid;
}, new int[256]));
}
}
}
}
Loading…
Cancel
Save