Contention class uploaded

Change-Id: I6d1ada2c3e2e3956ca68d77bed5bd1a9543fd92e
Signed-off-by: The Bao Bui <ZeroVNB@Gmail.com>
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/Contention.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/Contention.java
new file mode 100644
index 0000000..c68bf5d
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/Contention.java
@@ -0,0 +1,644 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     FH Dortmund - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.app4mc.gsoc_rta;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.app4mc.gsoc_rta.CommonUtils;
+import org.eclipse.app4mc.amalthea.model.Amalthea;
+import org.eclipse.app4mc.amalthea.model.CallSequenceItem;
+import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
+import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
+import org.eclipse.app4mc.amalthea.model.Label;
+import org.eclipse.app4mc.amalthea.model.LabelAccess;
+import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
+import org.eclipse.app4mc.amalthea.model.Process;
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
+import org.eclipse.app4mc.amalthea.model.PuType;
+import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.SetEvent;
+import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.TaskRunnableCall;
+import org.eclipse.app4mc.amalthea.model.Time;
+import org.eclipse.app4mc.amalthea.model.TimeUnit;
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
+import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
+import org.eclipse.emf.common.util.EList;
+
+public class Contention {
+	/*
+	 * this class will give the worst case latency for each task when memory
+	 * contention happen.
+	 */
+
+	private final int[] ia;
+	private final Amalthea model;
+	private final int[] flagArray;
+	private final HashMap<Task, List<Label>[]> gpuLabels = new HashMap<Task, List<Label>[]>();
+
+	public Contention(final int[] iap, final Amalthea modelp) {
+		this.ia = iap;
+		this.model = modelp;
+		this.flagArray = new int[iap.length];
+	}
+
+	/**
+	 * Checking whether ProcessingUnit is GPU or CPU
+	 * @param pu
+	 * @return true for CPU and false for GPU
+	 */
+
+	public static boolean identifyPUType(final ProcessingUnit pu) {
+		/* true=CPU; false=GPU; */
+		boolean result = false;
+
+		if (pu.getDefinition().getPuType().equals(PuType.CPU)) {
+			result = true;
+		}
+
+		else {
+			result = false;
+		}
+		return result;
+	}
+
+	/**
+	 * 	Initiallize hashmap contain GPU tasks' labels hashmap <task, List<label>> (readList = hashmap.get(task)[0];)
+	 * and create flagarray that have the same length with our integerArray, then loop through all the PRE_POST tasks ( via looking for InterProcessStimulus) and check whether the triggered task (GPU task) are located on GPU or not, if it is, then I will give the value of that task in flagArray equal 1. It will look like this
+
+		ia = { 5, 1, 5, 0, 1, 0, 2, 1, 2, 1, 6, 3, 4, 6 } - our mapping array
+		fa = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,} - the flag array
+	 *
+	 * @param tpumapping (or ia)
+	 */
+	private void setUpFlagArrayAndHashMap(final int[] iap) {
+		final EList<Task> modelTask = this.model.getSwModel().getTasks();
+		/* get gpu task list via checking task with InterProcessStimulus*/
+
+		final List<Task> gpuTask = modelTask.stream().filter(a -> a.getStimuli().get(0) instanceof InterProcessStimulus).collect(Collectors.toList());
+		/* get shotting task start*/
+		for (final Task t : gpuTask) {
+			/* shotting task => t.getName */
+			final List<SetEvent> shottingTaskEvent = SoftwareUtil.collectSetEvents(t, null);
+			final Process shottingTask = shottingTaskEvent.get(0).getProcess();
+			final int shotIndex = this.model.getSwModel().getTasks().indexOf(shottingTask);
+			final int gpuIndex = this.model.getSwModel().getTasks().indexOf(t);
+			if (iap[gpuIndex] != 6) {
+				/* If GPU is at GPU task then no flag */
+				this.flagArray[shotIndex] = 1;
+			}
+			/* create HashMap for GPU task that mapped to CPU start here*/
+			final List<Label> readLabelList = new ArrayList<Label>();
+			final List<Label> writeLabelList = new ArrayList<Label>();
+			final List<CallSequenceItem> callList = SoftwareUtil.collectCalls(shottingTask);
+			final CallSequenceItem ipt = callList.stream().filter(a -> a instanceof InterProcessTrigger).iterator().next();
+			/*
+			 * get the position of InterProcessTrigger within task taking
+			 * readLabel and write labels from pre and post processing (
+			 * preprocessing happen before trigger and post_processing happen
+			 * after the trigger )
+			 */
+			final int indexforTrigger = callList.indexOf(ipt);
+			for (int i = 0; i < callList.size(); i++) {
+				Runnable thisRunnable = null;
+				/* Pre-processing Runnable */
+				if ((i < indexforTrigger) && (callList.get(i) instanceof TaskRunnableCall)) {
+					thisRunnable = ((TaskRunnableCall) callList.get(i)).getRunnable();
+					final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
+					for (final LabelAccess la : thisLAList) {
+						if (la.getAccess().equals(LabelAccessEnum.READ)) {
+							readLabelList.add(la.getData());
+						}
+					}
+				}
+				/* Post-processing Runnable */
+				else if ((i > indexforTrigger) && (callList.get(i) instanceof TaskRunnableCall)) {
+					thisRunnable = ((TaskRunnableCall) callList.get(i)).getRunnable();
+					final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
+					for (final LabelAccess la : thisLAList) {
+						if (la.getAccess().equals(LabelAccessEnum.WRITE)) {
+							writeLabelList.add(la.getData());
+						}
+					}
+				}
+			}
+
+			final List<Label>[] aryofLabelList = new ArrayList[2];
+			aryofLabelList[0] = readLabelList;
+			aryofLabelList[1] = writeLabelList;
+			this.gpuLabels.put(t, aryofLabelList);
+			// HashMap created with <Task, ArrayofLabelList>
+		}
+
+	}
+
+	/** Calculating contention for CPU task only
+	 *
+	 * @param task
+	 * @return time
+	 */
+
+	public Time contentionForTask(final Task task) {
+		/* Initialize hashmap */
+		setUpFlagArrayAndHashMap(this.ia);
+
+		final Time time = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+		/**
+		 * Constant and variable init, change those constant for different model number
+		 *
+		 * The arrayList below are used to find number of core interfering and also for easier debugging
+		 * b1 = current task's name
+		 * b2 = intefering task's name
+		 * c1 = current task's core
+		 * c2 = intefering task's core
+		 * c3 = core definition's name (to check is task PU to apply the appropiate calculation)
+		 * d2 = c2 but reduced duplication
+		 */
+		final ArrayList<String> b1 = new ArrayList<>();
+		final ArrayList<String> b2 = new ArrayList<>();
+		final ArrayList<String> c1 = new ArrayList<>();
+		final ArrayList<String> c2 = new ArrayList<>();
+		final ArrayList<String> c3 = new ArrayList<>();
+		ArrayList<String> d2 = new ArrayList<>();
+
+		/* name of GPU core, use for identification task's core while calculating */
+		final String GPU = "GPU";
+		/* name of CPU core, use for identification task's core while calculating
+		 * can't use the identifyPU type above to distinguished because we have 2 different CPU in this model*/
+		final String A57CPU = "A57";
+		final String DenverCPU = "Denver";
+
+		/* time taken to read or write a cacheLine (64B)*/
+		final double A57_Baseline = 20.0;
+		final double Denver_Baseline = 8.0;
+		final double GPU_Baseline = 3.0;
+		/*increase in latency operated by a single interfering core.
+		 *  Do note: it does  not matter if the interfering core is Denver or A57
+		 *  : this number only depends on the observed CPU core (CPUtype)*/
+
+
+		final double A57_KConstant = 20.0;
+		final double Denver_KConstant = 2.0;
+
+		/* sensibility to GPU CE activity.*/
+		final double A57_sGPU = 100.0;
+		final double Denver_sGPU = 20.0;
+
+		/*bGPU = boolean, 1: if GPU is operating the copy engine, 0 other wise
+		 * We are assuming WCET so this will always be 1 in this implementation*/
+		final double bGPU = 1.0;
+
+		/*Computation to get NUMBER OF CORE intefering start*/
+
+		final List<ProcessingUnit> pul = CommonUtils.getPUs(this.model);
+		for (final Task t : this.model.getSwModel().getTasks()) {
+			if (t.equals(task)) {
+
+				/* Checking if task is flagged or not, because
+				 * if GPU task is on CPU => PREPOST will not be considered */
+
+				final int currentTaskIndex = this.model.getSwModel().getTasks().indexOf(task);
+				if (this.flagArray[currentTaskIndex] == 1) {
+					return time;
+				}
+
+				for (final Label l : CommonUtils.getAccessedLabelSet(t)) {
+
+					final Set<Runnable> wL = SoftwareUtil.getWriterSetOfLabel(l, null);
+					for (final Runnable r : wL) {
+						final List<Process> lT = SoftwareUtil.getProcesses(r, null);
+						for (final Process lTT : lT) {
+							/* get related task through checking which runnable are accessing the same label
+							 * put the task that contain those runnable into b2 and the core of that task in c2
+							 */
+							for (int taskIndex = 0; taskIndex < this.ia.length; taskIndex++) {
+								final ProcessingUnit pup = pul.get(this.ia[taskIndex]);
+								final String taskName = this.model.getSwModel().getTasks().get(taskIndex).getName();
+								final String coreName = pup.getName();
+								if (t.getName().equals(taskName)) {
+									b1.add(taskName);
+									c1.add(coreName);
+									c3.add(pup.getDefinition().getName());
+								}
+								final int b2Index = this.model.getSwModel().getTasks().indexOf(lTT);
+								/*only put that task in our array if task isn't flagged (check for
+								 * unnecessary PRE_POST task, we assume those task are gone when
+								 * corresponded GPU task is mapped to CPU)*/
+								if (lTT.getName().equals(taskName) && (this.flagArray[b2Index] == 0)) {
+									b2.add(taskName);
+									c2.add(coreName);
+								}
+							}
+						}
+					}
+
+
+					final Set<Runnable> rL = SoftwareUtil.getReadersSetOfLabel(l, null);
+					for (final Runnable r : rL) {
+						final List<Process> lT1 = SoftwareUtil.getProcesses(r, null);
+						for (final Process lTT1 : lT1) {
+							/* get related task through checking which runnable are accessing the same label
+							 * put the task that contain those runnable into b2 and the core of that task in c2
+							 */
+							for (int taskIndex = 0; taskIndex < this.ia.length; taskIndex++) {
+								final ProcessingUnit pup = pul.get(this.ia[taskIndex]);
+
+								final String taskName = this.model.getSwModel().getTasks().get(taskIndex).getName();
+								final String coreName = pup.getName();
+								if (t.getName().equals(taskName)) {
+									b1.add(taskName);
+									c1.add(coreName);
+									c3.add(pup.getDefinition().getName());
+
+								}
+								/*only put that task in our array if task isn't flagged (check for
+								 * unnecessary PRE_POST task, we assume those task are gone when
+								 * corresponded GPU task is mapped to CPU)*/
+
+								final int b2Index1 = this.model.getSwModel().getTasks().indexOf(lTT1);
+
+								if (lTT1.getName().equals(taskName) && (this.flagArray[b2Index1] == 0)) {
+									b2.add(taskName);
+									c2.add(coreName);
+								}
+							}
+						}
+					}
+
+				}
+
+				/* Remove all the duplicates inside c2.*/
+				d2 = (ArrayList<String>) c2.stream().distinct().collect(Collectors.toList());
+
+				/* Hashmap of <Core, Integer>
+				 * Assign value for other task as 1, GPU task and observed task as 0
+				 * total of value in integer will be equal to number of core intefering
+				 * Output of hashMap look like this {Core3=1, Core4=1, Core0=0, GP10B=0}*/
+
+				final HashMap<Object, Integer> coreHashMap = new HashMap<Object, Integer>();
+				for (final ProcessingUnit pu : pul) {
+					final String puName = pu.getName();
+					for (final String cName : d2) {
+						if (cName.equals(puName)) {
+							if (identifyPUType(pu)) {
+								coreHashMap.put(puName, 1);
+								if (puName.equals(c1.get(0))) {
+									coreHashMap.put(puName, 0);
+								}
+							}
+
+							else {
+								coreHashMap.put(puName, 0);
+							}
+						}
+					}
+				}
+
+				/*calculate total number of core via summing up all value in hashmap*/
+				int NoOfCore = 0;
+				for (final int val : coreHashMap.values()) {
+					NoOfCore += val;
+				}
+				/*Memory contention calculation for CPU
+				 * 	Lat = baseline + K*C + sGPU*bGPU
+				 * Lat = time necessary to read/write 64B ( nanosecond )
+				 * 64B I repeat. Scale the Lat accordingly to the memory footprint size
+				 * NoOfCore = C in the formula above.
+				 */
+				double Lat = 0.0;
+
+				if (!c3.isEmpty()) {
+					if (c3.get(0).contains(A57CPU)) {
+						Lat = A57_Baseline + (A57_KConstant * NoOfCore) + (A57_sGPU * bGPU);
+					}
+					if (c3.get(0).contains(DenverCPU)) {
+						Lat = Denver_Baseline + (Denver_KConstant * NoOfCore) + (Denver_sGPU * bGPU);
+					}
+
+					/*Memory contention calculation for GPU
+					 * 	Lat = GPU_Baseline + 0.5*C
+					 * Lat = time necessary to transfer 64B with copy engine ( nanosecond )
+					 * 64B I repeat. Scale the Lat accordingly to the memory footprint size
+					 * NoOfCore = C in the formula above. */
+
+					if (c3.get(0).contains(GPU)) {
+						Lat = GPU_Baseline + 0.5 * NoOfCore;
+					}
+				}
+
+				/* Latency for 64B calculation end here*/
+
+				long sumCycle = 0;
+
+
+				/*get data size of task start here */
+				final EList<Task> modelTask = this.model.getSwModel().getTasks();
+				final List<Task> gpuTask = modelTask.stream().filter(a -> a.getStimuli().get(0) instanceof InterProcessStimulus).collect(Collectors.toList());
+
+				/*if task is mapped to GPU, use the label within hashmap */
+				if (gpuTask.contains(task)) {
+					final List<SetEvent> shottingTaskEvent = SoftwareUtil.collectSetEvents(task, null);
+					final Process shottingTask = shottingTaskEvent.get(0).getProcess();
+					/*checking whether shotting task (triggering task) is flagged or not
+					 * if it is flagged, then the current GPU task is on CPU, hence using label in hashmap
+					 * if it is not, then the current GPU task is on GPU, therefore no need to look further more*/
+					final int shotIndex = this.model.getSwModel().getTasks().indexOf(shottingTask);
+
+					if (this.flagArray[shotIndex] == 1) {
+						final List<Label> readList = this.gpuLabels.get(task)[0];
+						final List<Label> writeList = this.gpuLabels.get(task)[1];
+						for (final Label l : readList) {
+
+							sumCycle += (long) Math.ceil(l.getSize().getNumberBytes() / 64.0);
+
+						}
+
+						for (final Label l : writeList) {
+							sumCycle += (long) Math.ceil(l.getSize().getNumberBytes() / 64.0);
+						}
+					}
+
+				}
+
+				/*normal calculation of total label within task for contention calculation
+				 * this is what we use most of the time*/
+				else {
+					for (final Runnable r : SoftwareUtil.getRunnableList(t, null)) {
+						for (final Label rl : SoftwareUtil.getReadLabelSet(r, null)) {
+							sumCycle += (long) Math.ceil(rl.getSize().getNumberBytes() / 64.0);
+						}
+
+						for (final Label wl : SoftwareUtil.getWriteLabelSet(r, null)) {
+							sumCycle += (long) Math.ceil(wl.getSize().getNumberBytes() / 64.0);
+						}
+					}
+
+				}
+
+
+				/* No core = no interference => No contention*/
+				if (NoOfCore == 0) {
+					Lat = 0;
+				}
+
+				/* task's contention in picosecond */
+				//
+				double taskLat = 0.0;
+				taskLat = Lat * sumCycle;
+
+				time.setValue(BigInteger.valueOf((long) taskLat * 1000l));
+				/*Clear out the Array for next task, print console before this if want to check */
+				b1.clear();
+				b2.clear();
+				c1.clear();
+				c2.clear();
+				d2.clear();
+				c3.clear();
+			}
+
+		}
+		return time;
+	}
+	// contentionForTask function end here
+
+
+	/**
+	 * Contention for GPU CopyEngine only, when copyengine perform copyIn
+	 * and copyOut. Mostly same with contention for CPU task,
+	 * except we only considering written label when copyOut
+	 * (since no need to copy back read label)
+	 * @param task
+	 * @return time
+	 */
+
+	public Time contentionForGPUCE(final Task task) {
+		setUpFlagArrayAndHashMap(this.ia);
+		final Time contentionTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+		/**
+		 * Constant and variable init, change those constant for different model number
+		 *
+		 * The arrayList below are used to find number of core interfering and also for easier debugging
+		 * b1 = current task's name
+		 * b2 = intefering task's name
+		 * c1 = current task's core
+		 * c2 = intefering task's core
+		 * c3 = core definition's name (to check is task PU to apply the appropiate calculation)
+		 * d2 = c2 but reduced duplication
+		 */
+
+		final ArrayList<String> b1 = new ArrayList<>();
+		final ArrayList<String> b2 = new ArrayList<>();
+		final ArrayList<String> c1 = new ArrayList<>();
+		final ArrayList<String> c2 = new ArrayList<>();
+		final ArrayList<String> c3 = new ArrayList<>();
+		ArrayList<String> d2 = new ArrayList<>();
+
+		/* name of GPU core, use for identification task's core while calculating */
+		final String GPU = "GPU";
+		/* name of CPU core, use for identification task's core while calculating
+		 * can't use the identifyPU type above to distinguished because we have 2 different CPU in this model*/
+		final String A57CPU = "A57";
+		final String DenverCPU = "Denver";
+
+		/* time taken to read or write a cacheLine (64B)*/
+		final double A57_Baseline = 20.0;
+		final double Denver_Baseline = 8.0;
+		final double GPU_Baseline = 3.0;
+		/*increase in latency operated by a single interfering core.
+		 *  Do note: it does  not matter if the interfering core is Denver or A57
+		 *  : this number only depends on the observed CPU core (CPUtype)*/
+
+		final double A57_KConstant = 20.0;
+		final double Denver_KConstant = 2.0;
+
+		/* sensibility to GPU CE activity.*/
+		final double A57_sGPU = 100.0;
+		final double Denver_sGPU = 20.0;
+
+		/*bGPU = boolean, 1: if GPU is operating the copy engine, 0 other wise
+		 * We are assuming WCET so this will always be 1 in this implementation*/
+		final double bGPU = 1.0;
+
+		/*Computation to get NUMBER OF CORE intefering start*/
+		final List<ProcessingUnit> pul = CommonUtils.getPUs(this.model);
+		final EList<Task> modelTask = this.model.getSwModel().getTasks();
+		// get gpu task start
+		final List<Task> gpuTask = modelTask.stream().filter(a -> a.getStimuli().get(0) instanceof InterProcessStimulus).collect(Collectors.toList());
+		// get gpu task finished
+		for (final Task t : gpuTask) {
+			if (t.equals(task)) {
+				for (final Label l : CommonUtils.getAccessedLabelSet(t)) {
+
+					final Set<Runnable> wL = SoftwareUtil.getWriterSetOfLabel(l, null);
+					for (final Runnable r : wL) {
+						final List<Process> lT = SoftwareUtil.getProcesses(r, null);
+						for (final Process lTT : lT) {
+
+							for (int taskIndex = 0; taskIndex < this.ia.length; taskIndex++) {
+								final ProcessingUnit pup = pul.get(this.ia[taskIndex]);
+								final String taskName = this.model.getSwModel().getTasks().get(taskIndex).getName();
+								final String coreName = pup.getName();
+								/* get related task through checking which runnable are accessing the same label
+								 * put the task that contain those runnable into b2 and the core of that task in c2
+								 */
+
+								if (t.getName().equals(taskName)) {
+									b1.add(taskName);
+									c1.add(coreName);
+									c3.add(pup.getDefinition().getName());
+								}
+								/*only put that task in our array if task isn't flagged (check for
+								 * unnecessary PRE_POST task, we assume those task are gone when
+								 * corresponded GPU task is mapped to CPU)*/
+
+								final int b2Index = this.model.getSwModel().getTasks().indexOf(lTT);
+								if (lTT.getName().equals(taskName) && (this.flagArray[b2Index] == 0)) {
+									b2.add(taskName);
+									c2.add(coreName);
+								}
+							}
+						}
+					}
+					final Set<Runnable> rL = SoftwareUtil.getReadersSetOfLabel(l, null);
+					for (final Runnable r : rL) {
+						final List<Process> lT1 = SoftwareUtil.getProcesses(r, null);
+						for (final Process lTT1 : lT1) {
+							for (int taskIndex = 0; taskIndex < this.ia.length; taskIndex++) {
+								final ProcessingUnit pup = pul.get(this.ia[taskIndex]);
+								final String taskName = this.model.getSwModel().getTasks().get(taskIndex).getName();
+								final String coreName = pup.getName();
+								/* get related task through checking which runnable are accessing the same label
+								 * put the task that contain those runnable into b2 and the core of that task in c2
+								 */
+								if (t.getName().equals(taskName)) {
+									b1.add(taskName);
+									c1.add(coreName);
+									c3.add(pup.getDefinition().getName());
+
+								}
+
+								/*only put that task in our array if task isn't flagged (check for
+								 * unnecessary PRE_POST task, we assume those task are gone when
+								 * corresponded GPU task is mapped to CPU)*/
+								final int b2Index1 = this.model.getSwModel().getTasks().indexOf(lTT1);
+								if (lTT1.getName().equals(taskName) && (this.flagArray[b2Index1] == 0)) {
+									b2.add(taskName);
+									c2.add(coreName);
+								}
+							}
+						}
+					}
+
+				}
+				// Remove all the duplicates inside c2.
+				d2 = (ArrayList<String>) c2.stream().distinct().collect(Collectors.toList());
+
+				/* Hashmap of <Core, Integer>
+				 * Assign value for other task as 1, GPU task and observed task as 0
+				 * total of value in integer will be equal to number of core intefering
+				 * Output of hashMap look like this {Core3=1, Core4=1, Core0=0, GP10B=0}*/
+				final HashMap<Object, Integer> coreHashMap = new HashMap<Object, Integer>();
+				for (final ProcessingUnit pu : pul) {
+					final String puName = pu.getName();
+					for (final String cName : d2) {
+						if (cName.equals(puName)) {
+							if (identifyPUType(pu)) {
+								coreHashMap.put(puName, 1);
+								if (puName.equals(c1.get(0))) {
+									coreHashMap.put(puName, 0);
+								}
+							}
+							else {
+								coreHashMap.put(puName, 0);
+							}
+						}
+					}
+				}
+				int NoOfCore = 0;
+				for (final int val : coreHashMap.values()) {
+					NoOfCore += val;
+				}
+				/*Memory contention calculation for CPU
+				 * 	Lat = baseline + K*C + sGPU*bGPU
+				 * Lat = time necessary to read/write 64B ( nanosecond )
+				 * 64B I repeat. Scale the Lat accordingly to the memory footprint size
+				 * NoOfCore = C in the formula above.
+				 */
+				double Lat = 0.0;
+				if (!c3.isEmpty()) {
+					if (c3.get(0).contains(A57CPU)) {
+						Lat = A57_Baseline + (A57_KConstant * NoOfCore) + (A57_sGPU * bGPU);
+					}
+					if (c3.get(0).contains(DenverCPU)) {
+						Lat = Denver_Baseline + (Denver_KConstant * NoOfCore) + (Denver_sGPU * bGPU);
+					}
+					/*Memory contention calculation for GPU
+					 * 	Lat = GPU_Baseline + 0.5*C
+					 * Lat = time necessary to transfer 64B with copy engine ( nanosecond )
+					 * 64B I repeat. Scale the Lat accordingly to the memory footprint size
+					 * NoOfCore = C in the formula above. */
+
+					if (c3.get(0).contains(GPU)) {
+						Lat = GPU_Baseline + 0.5 * NoOfCore;
+					}
+				}
+				/* Latency for 64B calculation end here*/
+				long sumCycle = 0;
+				/* Full read and write labels for CE when copyIN */
+				final Set<Label> fullList = SoftwareUtil.getAccessedLabelSet(t, null);
+				for (final Label l : fullList) {
+					final long fullSize = l.getSize().getNumberBytes();
+					final long cycle = (long) Math.ceil(fullSize / 64.0);
+					sumCycle += cycle;
+				}
+
+
+				/* Written labels only for CE when CopyOut*/
+				final Set<Label> writeList = SoftwareUtil.getWriteLabelSet(t, null);
+				for (final Label l : writeList) {
+					final long fullSize = l.getSize().getNumberBytes();
+					final long cycle = (long) Math.ceil(fullSize / 64.0);
+					sumCycle += cycle;
+				}
+
+
+				// No core = no interference => No contention
+				if (NoOfCore == 0) {
+					Lat = 0;
+				}
+				double taskLat = 0.0;
+				taskLat = Lat * sumCycle;
+
+				contentionTime.setValue(BigInteger.valueOf((long) taskLat * 1000l));
+
+				/*Clear out the Array for next task, print console before this if want to check */
+				b1.clear();
+				b2.clear();
+				c1.clear();
+				c2.clear();
+				d2.clear();
+				c3.clear();
+			}
+
+		}
+		// continue
+
+		return contentionTime;
+	}
+}