package cpustream;

import static com.maxeler.maxcompiler.v2.managers.standard.Manager.link;

import com.maxeler.maxcompiler.v2.kernelcompiler.Kernel;
import com.maxeler.maxcompiler.v2.managers.BuildConfig;
import com.maxeler.maxcompiler.v2.managers.engine_interfaces.CPUTypes;
import com.maxeler.maxcompiler.v2.managers.engine_interfaces.EngineInterface;
import com.maxeler.maxcompiler.v2.managers.engine_interfaces.InterfaceParam;
import com.maxeler.maxcompiler.v2.managers.standard.IOLink.IODestination;
import com.maxeler.maxcompiler.v2.managers.standard.Manager;

public class CpuStreamManager {

	private static final String s_kernelName = "CpuStreamKernel";

	public static void main(String[] args) {
		CpuStreamEngineParameters params = new CpuStreamEngineParameters(args);
		Manager manager = new Manager(params);
		Kernel kernel = new CpuStreamKernel(
				manager.makeKernelParameters(s_kernelName));
		manager.setKernel(kernel);
		manager.setIO(link("a", IODestination.CPU),
				link("b", IODestination.CPU), link("c", IODestination.CPU),
				link("d", IODestination.CPU));

		manager.createSLiCinterface(interfaceDefault());

		configBuild(manager, params);

		manager.build();
	}

	private static EngineInterface interfaceDefault() {
		EngineInterface engine_interface = new EngineInterface();
		CPUTypes type1 = CPUTypes.INT32;
		CPUTypes type2 = CPUTypes.FLOAT;
		int size1 = type1.sizeInBytes();
		int size2 = type2.sizeInBytes();

		InterfaceParam N = engine_interface.addParam("N", CPUTypes.INT);

		engine_interface.setTicks(s_kernelName, N);
		engine_interface.setStream("a", type1, N * size1);
		engine_interface.setStream("b", type1, N * size1);
		engine_interface.setStream("c", type1, N * size1);
		engine_interface.setStream("d", type2, N * size2);
		return engine_interface;
	}

	private static void configBuild(Manager manager,
			CpuStreamEngineParameters params) {
		manager.setEnableStreamStatusBlocks(false);
		BuildConfig buildConfig = manager.getBuildConfig();
		buildConfig.setMPPRCostTableSearchRange(params.getMPPRStartCT(),
				params.getMPPREndCT());
		buildConfig.setMPPRParallelism(params.getMPPRThreads());
		buildConfig.setMPPRRetryNearMissesThreshold(params
				.getMPPRRetryThreshold());
	}
}
