blob: 39e869b053783d14475689859b2cac3475b66e62 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015, 2020 Dortmund University of Applied Sciences and Arts and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dortmund University of Applied Sciences and Arts - initial API and implementation
*******************************************************************************/
package org.eclipse.app4mc.multicore.openmapping.algorithms.heuristic.lb;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.app4mc.multicore.openmapping.algorithms.AbstractMappingAlgorithm;
import org.eclipse.app4mc.multicore.openmapping.algorithms.helper.ListBuilder;
import org.eclipse.app4mc.multicore.openmapping.model.OMAllocation;
import org.eclipse.app4mc.multicore.openmapping.model.OMCore;
import org.eclipse.app4mc.multicore.openmapping.model.OMMapping;
import org.eclipse.app4mc.multicore.openmapping.model.OMTask;
import org.eclipse.app4mc.multicore.sharelibs.UniversalHandler;
public class LoadBalancingDFG extends AbstractMappingAlgorithm {
private List<OMTask> taskList = new ArrayList<>();
private List<OMCore> coreList = new ArrayList<>();
private Boolean parseConstraints() {
// Work in progress
return true;
}
@Override
public void calculateMapping() {
final long timeStart, timeStep1, timeStep2, timeStep3, timeStep4;
this.con.appendln("Performing heuristic DFG Mapping");
if (!initModels()) {
this.con.appendln("Error during Model initialization, exiting.");
return;
}
// Create lists of Cores and Tasks
// Get list of tasks and calculate their execution time
timeStart = java.lang.System.nanoTime();
this.con.appendln("Step 1: Building Task-List...");
if (null == (this.taskList = ListBuilder.getTaskList(getMergedModel().getSwModel()))) {
this.con.append("Error during Task generation, exiting.");
return;
}
timeStep1 = java.lang.System.nanoTime();
this.con.appendln(" Success! (" + (timeStep1 - timeStart) / 1000000 + "ms)");
// Get list of cores and calculate their performance
this.con.appendln("Step 2: Building Core-List...");
if (null == (this.coreList = ListBuilder.getCoreList(getMergedModel().getHwModel()))) {
this.con.appendln("Error during Core generation, exiting.");
return;
}
timeStep2 = java.lang.System.nanoTime();
this.con.appendln(" Success! (" + (timeStep2 - timeStep1) / 1000000 + "ms)");
this.con.appendln("Step 3: Determining Constraints and narrowing down the solution space... ");
// Any Constraints set?
if (!hasConstraints()) {
this.con.appendln(" There are no propertyConstraints set, skipping this step.");
timeStep3 = java.lang.System.nanoTime();
}
else {
if (!parseConstraints()) {
this.con.appendln("Error during constrain analysis, exiting.");
return;
}
timeStep3 = java.lang.System.nanoTime();
this.con.appendln(" Success! (" + (timeStep3 - timeStep2) / 1000000 + "ms)");
}
// Perform the actual Mapping
this.con.appendln("Step 4: Creating Mapping...");
if (!performMappingAlgorithm()) {
this.con.appendln("Error during performMappingAlgorithm, exiting.");
return;
}
timeStep4 = java.lang.System.nanoTime();
this.con.appendln("Success after " + (timeStep4 - timeStep3) / 1000000 + "ms.");
this.con.appendln("Leaving mapping algorithm.");
}
private boolean performMappingAlgorithm() {
final Map<OMCore, Long> coreLoad = new HashMap<>();
final OMMapping hMapping = new OMMapping();
// If just one core is available theres no need to run the algorithm
if (this.coreList.size() == 1) {
return mapToFirstCore();
}
// Sort tasks and cores according to their complexity/performance
UniversalHandler.getInstance().logCon("Sorting...");
Collections.sort(this.taskList, new SortTasks());
Collections.sort(this.coreList, new SortCores());
for (final OMTask task : this.taskList) {
OMCore targetCore = null;
long minLoad = 0;
for (final OMCore core : this.coreList) {
final long taskLoad = new OMAllocation(task, core).calculateProcessingTime();
final long resultLoad = coreLoad.getOrDefault(core, 0l) + taskLoad;
if (targetCore == null || resultLoad < minLoad) {
UniversalHandler.getInstance().logCon("+ Setting this core as Target!");
minLoad = resultLoad;
targetCore = core;
}
}
if (targetCore != null) {
coreLoad.put(targetCore, minLoad);
final OMAllocation allocation = new OMAllocation(task, targetCore);
hMapping.addAllocation(allocation);
}
}
updateModel(hMapping);
return true;
}
private class SortTasks implements Comparator<OMTask> {
@Override
public int compare(final OMTask o1, final OMTask o2) {
if (o1.getInstructionCount() == o2.getInstructionCount()) {
return 0;
}
if (o1.getInstructionCount() < o2.getInstructionCount()) {
return 1;
}
return -1;
}
}
private class SortCores implements Comparator<OMCore> {
@Override
public int compare(final OMCore o1, final OMCore o2) {
if (o1.getInstructionsPerSecond() == o2.getInstructionsPerSecond()) {
return 0;
}
if (o1.getInstructionsPerSecond() < o2.getInstructionsPerSecond()) {
return 1;
}
return -1;
}
}
}