I'm not sure whether the title is detail/correct or not but i can't figure out how to describe it in the title so I will try my best to describe it here
I've been trying to use callable in Java for concurrency, but the outcome is not correct, seem like the thread has been over lapping each other while running...below is the call function for that
@Override
public String call() {
String result = "yay";
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOutMiliseconds * 1000;
while (System.currentTimeMillis() < endTime) {
int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
System.out.println(" current - " + Arrays.toString(currentMapping) + " - " + ID);
result = Arrays.toString(currentMapping);
}
return result;
}
generateTpuMappingWithRange()
function is just generate another random integer array with the first index from startRange -> stopRange
(i.e. startRange = 0, stopRange = 2, then [0, 2, 1,] -> [1, 2, 1] or [2,2,1])
constructor
public MarkovTest(int ID, int startRange, int stopRange) {
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
Here is main
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable<String> Array = new MarkovTest(1, 0, 1);
Callable<String> Array2 = new MarkovTest(2, 2, 3);
Callable<String> Array3 = new MarkovTest(3, 4, 5);
List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);
List<Future<String>> future = executor.invokeAll(taskList);
for(Future<String> result : future)
{
System.out.println(result.get());
}
}
the number in the last is the ID
variable is to check whether it's printing out the correct one or not...however here is the problem, in the console, this happen...
current - [0, 3, 5, 0, 5, 4, 3, 2, 1, 4, 6, 1, 3, 6] - 1
current - [1, 3, 5, 0, 5, 4, 3, 2, 1, 4, 6, 1, 3, 6] - 3
current - [0, 3, 5, 0, 5, 4, 2, 2, 0, 4, 6, 1, 3, 6] - 1
current - [0, 3, 5, 0, 5, 4, 3, 2, 0, 4, 6, 1, 3, 6] - 2
1st line is correct, ID 1 should print array with first index in range 0 to 1. But ID 3 and 2 should not have the 0 or 1 in the first index...this doesn't happen all the time but will appear here and there among thousand of console output
Any idea why is this happening? I'm really stressed because of this...T__T
Edit: Added generateTpuMappingWithRange
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
final Logger log = Logger.getLogger(MarkovTest.class);
int maximumNoOfCoreIndex = 6;
int minimumNoOfCoreIndex = 0;
int firstIndex = 0;
int[] result = iap;
log.debug("OLD MAPPING = " + Arrays.toString(result));
// generate random
Random randomNum = new Random();
// generate number from 0 -> 13 (because last number will always be 6)
int randomIndex = randomNum.nextInt(iap.length - 1);
// last one will always be 6 so dont need to include that
int minusOrPlus = 0;
minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
PuType thisTaskPuType = domains.get(thisTask);
int[] newIndexValueRange = this.intervals.get(thisTaskPuType);
minimumNoOfCoreIndex = newIndexValueRange[0];
maximumNoOfCoreIndex = newIndexValueRange[1];
int newIndexValue = result[randomIndex] + minusOrPlus;
// Split 0-1, 2-3, 4-5 for 3 markov chain.
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
// if the new index value generated from line above surpass our maximum no of
// core, then it will return to number 0
// This may resolve to infinite loop if THE SAME randomIndex appear again and
// again and again and again, which hopefully wont be a thing for this
// implementation
result[randomIndex] = newIndexValue;
log.debug("NEW MAPPING = " + Arrays.toString(result));
log.debug(" location =" + randomIndex + " value =" + newIndexValue);
return result;
}
Here is the full Version of the code just in case.
init()
method is basically generate 2 HashMap, mainly used to determine the maxmimum and minimum value for each index.
public class MarkovTest implements Callable<String> {
static ExecutorService executor = Executors.newFixedThreadPool(3);
int startRange;
int stopRange;
long timeOutMiliseconds = 1000;
long maxIteration;
Amalthea model;
int[] ia;
int ID;
private final int nbCPUs;
private final int nbPUs;
private final HashMap<Task, PuType> domains = new HashMap<Task, PuType>();
private final HashMap<PuType, int[]> intervals = new HashMap<PuType, int[]>();
public MarkovTest(int[] ia, Amalthea model, int ID, int startRange, int stopRange) {
this.model = model;
this.ia = ia;
this.nbCPUs = CommonUtils.getNumberofCPUs(model);
// this.nbGPUs = CommonUtils.getNumberofGPUs(this.model);
this.nbPUs = CommonUtils.getNumberofPUs(model);
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
org.apache.log4j.BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.INFO);
long startTime = System.currentTimeMillis();
int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));
Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);
List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);
List<Future<String>> future = executor.invokeAll(taskList);
for(Future<String> result : future)
{
System.out.println(result.get());
}
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println(" elapsed Time = " + elapsedTime);
System.out.println("Done");
}
@Override
public String call() {
String result = "yay";
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOutMiliseconds * 1000;
while (System.currentTimeMillis() < endTime) {
int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
System.out.println(" current - " + Arrays.toString(currentMapping) + " - " + ID);
result = Arrays.toString(currentMapping);
}
return result;
}
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
final Logger log = Logger.getLogger(MarkovTest.class);
int maximumNoOfCoreIndex = 6;
int minimumNoOfCoreIndex = 0;
int firstIndex = 0;
int[] result = iap;
log.debug("OLD MAPPING = " + Arrays.toString(result));
// generate random
Random randomNum = new Random();
// generate number from 0 -> 13 (because last number will always be 6)
int randomIndex = randomNum.nextInt(iap.length - 1);
// last one will always be 6 so dont need to include that
int minusOrPlus = 0;
minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
PuType thisTaskPuType = domains.get(thisTask);
int[] newIndexValueRange = this.intervals.get(thisTaskPuType);
minimumNoOfCoreIndex = newIndexValueRange[0];
maximumNoOfCoreIndex = newIndexValueRange[1];
int newIndexValue = result[randomIndex] + minusOrPlus;
// Split 0-4, 5-10, 11-13 for 3 markov chain.
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
// if the new index value generated from line above surpass our maximum no of
// core, then it will return to number 0
// This may resolve to infinite loop if THE SAME randomIndex appear again and
// again and again and again, which hopefully wont be a thing for this
// implementation
result[randomIndex] = newIndexValue;
log.debug("NEW MAPPING = " + Arrays.toString(result));
log.debug(" location =" + randomIndex + " value =" + newIndexValue);
return result;
}
private void init() {
final Logger log = Logger.getLogger(CallableForMarkov.class);
for (final Task t : this.model.getSwModel().getTasks()) {
boolean cpu = false;
boolean gpu = false;
boolean defaultVal = false;
for (final CallGraphItem geb : t.getCallGraph().getItems()) {
if (geb instanceof Group) {
final Group cs = (Group) geb;
for (final CallGraphItem csi : cs.getItems()) {
if (csi instanceof RunnableCall) {
final RunnableCall trc = (RunnableCall) csi;
for (final CallGraphItem ri : trc.getRunnable().getRunnableItems()) {
if (ri instanceof Ticks) {
final Ticks ticks = (Ticks) ri;
if (null != ticks.getDefault() && ticks.getDefault().getAverage() > 0) {
defaultVal = true;
}
for (final Entry<ProcessingUnitDefinition, IDiscreteValueDeviation> e : ticks
.getExtended().entrySet()) {
if (!gpu && e.getKey().getPuType().equals(PuType.GPU)) {
gpu = true;
} else if (!cpu && e.getKey().getPuType().equals(PuType.CPU)) {
cpu = true;
}
}
}
}
// TODO check if there are runnables with different tick vals
}
}
}
}
if (cpu && !gpu) {
/* task can be mapped only to CPUs */
log.debug(t.getName() + " can be mapped to 0 --" + (this.nbCPUs - 1));
this.domains.put(t, PuType.CPU);
if (!this.intervals.containsKey(PuType.CPU)) {
this.intervals.put(PuType.CPU, new int[] { 0, this.nbCPUs - 1 });
}
} else if (gpu && !cpu) {
/* task can be mapped only to GPUs */
log.debug(t.getName() + " can be mapped to " + this.nbCPUs + "--" + (this.nbPUs - 1));
this.domains.put(t, PuType.GPU);
if (!this.intervals.containsKey(PuType.GPU)) {
this.intervals.put(PuType.GPU, new int[] { this.nbCPUs, this.nbPUs - 1 });
}
} else if (defaultVal || (gpu && cpu)) {
/* task can be mapped anywhere */
log.debug(t.getName() + " can be mapped to 0 --" + (this.nbPUs - 1));
this.domains.put(t, PuType._UNDEFINED_);
if (!this.intervals.containsKey(PuType._UNDEFINED_)) {
this.intervals.put(PuType._UNDEFINED_, new int[] { 0, this.nbPUs - 1 });
}
} else {
/* Task can be mapped nowhere */
log.fatal(t.getName() + " can be mapped nowhere");
}
}
}
}