I'm running math heavy code on GPU with ILGPU, I organized it in modular classes segregated by interfaces to implement different algorithms that are modular.
Now ILGPU allows only to run static methods on GPU kernels. So I need to take the IL out of those nested classes, and inline manually, ouputting a single static method that will be called as Kernel.
In example
public interface IFunction
{
public float DoSum(float[] input);
}
public class NormalSum
{
public float(float[] input)
{
float sum=0.0f;
for(int i=0;i<input.Lenght;i++)
sum+=input[i];
}
}
public interface IAlgorithm
{
public void DoAlgorithm(float[] input, float[] output);
}
public class MyAlgorithm
{
IFunction fun;
public MyAlgorithm(IFunction fun)
{
this.fun = fun;
}
public void DoAlgorithm(float[] input, float[] output)
{
for(int j=0;j<output.Length;j++)
{
output[j] = 2.0f* fun.DoSum(input);
}
}
}
There are no stored variables, the classes and interfaces are just wrappers over algorithms so I need a code and expect it to inline the methods to something like that without bothering to resolve eventual references to instance members, i look to "fun" just to extract the method implementation, then "fun" can be discarded.
var staticMethod = Inline(new MyAlgorithm(new NormalSum));
// generated IL
public static void GeneratedCode(float[] input, float[] output)
{
for(int j=0;j<output.Length;j++)
{
float sum=0.0f;
for(int i=0;i<input.Length;i++)
sum+=input[i];
float result = sum;
output[j] = 2.0f* result;
}
}
So far i just copied a single static method, but was not able to go "inside the implementation".
MethodInfo existingMethod = typeof(MyStaticClass).GetMethod("MethodToCopy", BindingFlags.Static | BindingFlags.Public);
AssemblyName assemblyName = new AssemblyName("DynamicAssembly");
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicClass", TypeAttributes.Public);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("DynamicMethod", MethodAttributes.Public | MethodAttributes.Static, existingMethod.ReturnType, new Type[] { });
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
// Copy IL code
foreach (var instruction in existingMethod.GetMethodBody().GetILAsByteArray())
{
ilGenerator.Emit(instruction);
}
Type type = typeBuilder.CreateType();
type.GetMethod("DynamicMethod").Invoke(null, null);
input.Lenghtandoutput.Lenghtdistracting.ouputless so, but still...give your code the same amount of care and attention that you want potential answers to give.