use of de.mirkosertic.bytecoder.core.BytecodeLinkerContext in project Bytecoder by mirkosertic.
the class NaiveProgramGeneratorTest method newProgramFrom.
private Program newProgramFrom(BytecodeProgram aProgram, BytecodeMethodSignature aSignature) {
BytecodeLinkerContext theContext = mock(BytecodeLinkerContext.class);
ProgramGenerator theGenerator = NaiveProgramGenerator.FACTORY.createFor(theContext);
BytecodeClass theClass = mock(BytecodeClass.class);
BytecodeMethod theMethod = mock(BytecodeMethod.class);
when(theMethod.getAccessFlags()).thenReturn(new BytecodeAccessFlags(0));
when(theMethod.getSignature()).thenReturn(aSignature);
BytecodeCodeAttributeInfo theCodeAttribute = mock(BytecodeCodeAttributeInfo.class);
when(theCodeAttribute.getProgramm()).thenReturn(aProgram);
when(theMethod.getCode(any())).thenReturn(theCodeAttribute);
return theGenerator.generateFrom(theClass, theMethod);
}
use of de.mirkosertic.bytecoder.core.BytecodeLinkerContext in project Bytecoder by mirkosertic.
the class CompilerTest method testSimpleKernel.
@Test
public void testSimpleKernel() {
OpenCLCompileBackend backend = new OpenCLCompileBackend();
CompileOptions compileOptions = new CompileOptions(new Slf4JLogger(), false, KnownOptimizer.ALL);
Kernel theKernel = createKernel();
Class theKernelClass = theKernel.getClass();
System.out.println(theKernelClass);
Method[] theMethods = theKernelClass.getDeclaredMethods();
if (theMethods.length != 1) {
throw new IllegalArgumentException("A kernel must have exactly one declared method!");
}
Method theMethod = theMethods[0];
BytecodeMethodSignature theSignature = backend.signatureFrom(theMethod);
BytecodeLoader theLoader = new BytecodeLoader(getClass().getClassLoader());
BytecodeLinkerContext theLinkerContext = new BytecodeLinkerContext(theLoader, compileOptions.getLogger());
OpenCLCompileResult theCompiledKernel = backend.generateCodeFor(compileOptions, theLinkerContext, theKernelClass, theMethod.getName(), theSignature);
System.out.println(theCompiledKernel.getData());
}
use of de.mirkosertic.bytecoder.core.BytecodeLinkerContext in project Bytecoder by mirkosertic.
the class CompilerTest method testKernelWithComplexType.
@Test
public void testKernelWithComplexType() {
OpenCLCompileBackend backend = new OpenCLCompileBackend();
CompileOptions compileOptions = new CompileOptions(new Slf4JLogger(), false, KnownOptimizer.ALL);
Float2[] theIn = new Float2[10];
Float2[] theOut = new Float2[10];
Kernel theKernel = new Kernel() {
public void processWorkItem() {
int theIndex = get_global_id(0);
Float2 a = theIn[theIndex];
Float2 b = theOut[theIndex];
b.s0 = a.s0;
b.s1 = a.s1;
}
};
Class theKernelClass = theKernel.getClass();
System.out.println(theKernelClass);
Method[] theMethods = theKernelClass.getDeclaredMethods();
if (theMethods.length != 1) {
throw new IllegalArgumentException("A kernel must have exactly one declared method!");
}
Method theMethod = theMethods[0];
BytecodeMethodSignature theSignature = backend.signatureFrom(theMethod);
BytecodeLoader theLoader = new BytecodeLoader(getClass().getClassLoader());
BytecodeLinkerContext theLinkerContext = new BytecodeLinkerContext(theLoader, compileOptions.getLogger());
OpenCLCompileResult theCompiedKernel = backend.generateCodeFor(compileOptions, theLinkerContext, theKernelClass, theMethod.getName(), theSignature);
System.out.println(theCompiedKernel.getData());
}
use of de.mirkosertic.bytecoder.core.BytecodeLinkerContext in project Bytecoder by mirkosertic.
the class OpenCLCompileBackend method generateCodeFor.
@Override
public OpenCLCompileResult generateCodeFor(CompileOptions aOptions, BytecodeLinkerContext aLinkerContext, Class aEntryPointClass, String aEntryPointMethodName, BytecodeMethodSignature aEntryPointSignatue) {
BytecodeLinkerContext theLinkerContext = new BytecodeLinkerContext(loader, aOptions.getLogger());
BytecodeLinkedClass theKernelClass = theLinkerContext.resolveClass(BytecodeObjectTypeRef.fromRuntimeClass(aEntryPointClass));
theKernelClass.resolveVirtualMethod(aEntryPointMethodName, aEntryPointSignatue);
BytecodeResolvedMethods theMethodMap = theKernelClass.resolvedMethods();
StringWriter theStrWriter = new StringWriter();
OpenCLInputOutputs theInputOutputs;
// First of all, we link the kernel method
BytecodeMethod theKernelMethod = theKernelClass.getBytecodeClass().methodByNameAndSignatureOrNull("processWorkItem", new BytecodeMethodSignature(BytecodePrimitiveTypeRef.VOID, new BytecodeTypeRef[0]));
ProgramGenerator theGenerator = programGeneratorFactory.createFor(aLinkerContext);
Program theSSAProgram = theGenerator.generateFrom(theKernelClass.getBytecodeClass(), theKernelMethod);
// Run optimizer
aOptions.getOptimizer().optimize(theSSAProgram.getControlFlowGraph(), aLinkerContext);
// Every member of the kernel class becomes a kernel function argument
try {
theInputOutputs = inputOutputsFor(theLinkerContext, theKernelClass, theSSAProgram);
} catch (Exception e) {
throw new RuntimeException(e);
}
// And then we ca pass it to the code generator to generate the kernel code
OpenCLWriter theSSAWriter = new OpenCLWriter(theKernelClass, aOptions, theSSAProgram, "", new PrintWriter(theStrWriter), aLinkerContext, theInputOutputs);
// We use the relooper here
Relooper theRelooper = new Relooper();
theMethodMap.stream().forEach(aMethodMapEntry -> {
BytecodeMethod theMethod = aMethodMapEntry.getValue();
if (theMethod.isConstructor()) {
return;
}
if (theMethod != theKernelMethod) {
Program theSSAProgram1 = theGenerator.generateFrom(aMethodMapEntry.getProvidingClass().getBytecodeClass(), theMethod);
// Run optimizer
aOptions.getOptimizer().optimize(theSSAProgram1.getControlFlowGraph(), aLinkerContext);
// Try to reloop it!
try {
Relooper.Block theReloopedBlock = theRelooper.reloop(theSSAProgram1.getControlFlowGraph());
theSSAWriter.printReloopedInline(theMethod, theSSAProgram1, theReloopedBlock);
} catch (Exception e) {
throw new IllegalStateException("Error relooping cfg", e);
}
}
});
// Finally, we write the kernel method
try {
Relooper.Block theReloopedBlock = theRelooper.reloop(theSSAProgram.getControlFlowGraph());
theSSAWriter.printReloopedKernel(theSSAProgram, theReloopedBlock);
} catch (Exception e) {
throw new IllegalStateException("Error relooping cfg", e);
}
return new OpenCLCompileResult(theInputOutputs, theStrWriter.toString());
}
use of de.mirkosertic.bytecoder.core.BytecodeLinkerContext in project Bytecoder by mirkosertic.
the class OpenCLContext method kernelFor.
private CachedKernel kernelFor(Kernel aKernel) {
Class theKernelClass = aKernel.getClass();
CachedKernel theCachedKernel = cachedKernels.get(theKernelClass);
if (theCachedKernel != null) {
return theCachedKernel;
}
OpenCLCompileResult theResult = ALREADY_COMPILED.get(theKernelClass);
if (theResult == null) {
Method theMethod;
try {
theMethod = aKernel.getClass().getDeclaredMethod("processWorkItem");
} catch (Exception e) {
throw new IllegalArgumentException("Error resolving kernel method", e);
}
BytecodeMethodSignature theSignature = backend.signatureFrom(theMethod);
BytecodeLoader theLoader = new BytecodeLoader(theKernelClass.getClassLoader());
BytecodeLinkerContext theLinkerContext = new BytecodeLinkerContext(theLoader, compileOptions.getLogger());
theResult = backend.generateCodeFor(compileOptions, theLinkerContext, aKernel.getClass(), theMethod.getName(), theSignature);
logger.debug("Generated Kernel code : {}", theResult.getData());
ALREADY_COMPILED.put(theKernelClass, theResult);
}
// Construct the program
cl_program theCLProgram = clCreateProgramWithSource(context, 1, new String[] { theResult.getData() }, null, null);
clBuildProgram(theCLProgram, 0, null, null, null, null);
cl_kernel theKernel = clCreateKernel(theCLProgram, "BytecoderKernel", null);
CachedKernel theCached = new CachedKernel(theResult.getInputOutputs(), theCLProgram, theKernel);
cachedKernels.put(theKernelClass, theCached);
return theCached;
}
Aggregations