Skip to content

Commit

Permalink
Improve QBroker and Gateways
Browse files Browse the repository at this point in the history
  • Loading branch information
hoaiocom committed Jul 20, 2023
1 parent 8908492 commit 0b80ee8
Show file tree
Hide file tree
Showing 10 changed files with 300 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public static void main(String[] args) throws Exception {
EdgeGateway edgeGateway = new EdgeGateway("EdgeGateway", ceBroker, qeBroker);

// Step 6: Create 4 QTasks
qTaskList = createQTaskList(QEDatacenter, qeBroker);
qTaskList = createQTaskList(qeBroker);

// Step 7: Submit all tasks to brokers
edgeGateway.submitQTasks(qTaskList);
Expand All @@ -85,11 +85,25 @@ public static void main(String[] args) throws Exception {
iQuantum.stopSimulation();

// Step 10: Print the results when simulation is over
// Step 8: Print the results when simulation is over
Log.printLine("SIMULATION RESULTS");
Log.printLine("==========================================================");
List<QTask> qcTaskResults = qcBroker.getQTaskReceivedList();
QTaskExporter.printQTaskList(qcTaskResults);
QTaskExporter.extractQTaskListToCSV(qcTaskResults, exampleName);
Log.printLine("iQuantum Hybrid Example finished!");
Log.printLine("CLOUD Layer ================================");
if(qcTaskResults.size() == 0) {
Log.printLine("No QTask received");
} else {
QTaskExporter.printQTaskList(qcTaskResults);
QTaskExporter.extractQTaskListToCSV(qcTaskResults, exampleName+"-cloud");
}
List<QTask> qeTaskResults = qeBroker.getQTaskReceivedList();
Log.printLine("EDGE Layer ================================");
if(qeTaskResults.size() == 0) {
Log.printLine("No QTask received");
} else {
QTaskExporter.printQTaskList(qeTaskResults);
QTaskExporter.extractQTaskListToCSV(qeTaskResults, exampleName+"-edge");
}
Log.printLine(exampleName +" finished!");
}

/**
Expand Down Expand Up @@ -123,34 +137,21 @@ private static CEdgeBroker createEBroker() {
* QUANTUM PART
*/

private static List<QTask> createQTaskList(QDatacenter qDatacenter, QBroker qBroker) {
private static List<QTask> createQTaskList(QBroker qBroker) {
List<QTask> QTaskList = new ArrayList<>();
String folderPath = "dataset/iquantum/MQT-Set1-298-10-27-IBMQ27-Opt3-Extra.csv";
// String folderPath = "dataset/iquantum/MQT-Set1-298-10-27-IBMQ27-Opt3-Extra.csv";
String folderPath = "dataset/iquantum/MQT-Set2-7-127-AllOpt-IBMMapped-Extra.csv";
Path datasetPath = Paths.get(System.getProperty("user.dir"), folderPath);
QTaskImporter QTaskImporter = new QTaskImporter();
try {
List<QTask> QTasks = QTaskImporter.importQTasksFromCsv(datasetPath.toString());
List<QNode> qNodeList = (List<QNode>) qDatacenter.getCharacteristics().getQNodeList();
Random random = new Random();
for (QTask qtask : QTasks) {
switch(qtask.getPreferredBackend()) {
case "ibm_27q":
qtask.setQNodeId(11);
break;
case "ibm_127q":
qtask.setQNodeId(21);
break;
default:
qtask.setQNodeId(qNodeList.get(random.nextInt(qNodeList.size())).getId());
break;
}
qtask.setBrokerId(qBroker.getId());
QTaskList.add(qtask);
}
} catch (IOException e) {
System.err.println("Error reading CSV file: " + e.getMessage());
}

return QTaskList;
}

Expand Down
85 changes: 59 additions & 26 deletions modules/iquantum/src/main/java/org/iquantum/brokers/QBroker.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import org.iquantum.datacenters.QDatacenterCharacteristics;
import org.iquantum.backends.quantum.QNode;
import org.iquantum.policies.qtasks.QNodeSelectionLottery;
import org.iquantum.tasks.QTask;
import org.iquantum.utils.Log;
import org.iquantum.core.*;
Expand All @@ -24,7 +25,7 @@
public class QBroker extends SimEntity {

/** The list of QNodes submitted to be managed by the broker.. */
protected QNodeList qNodeList;
protected List<? extends QNode> qNodeList;

/** The list of QTask submitted to the broker. */
protected List<? extends QTask> qtaskList;
Expand All @@ -38,6 +39,8 @@ public class QBroker extends SimEntity {
/** The number of submitted QTasks. */
protected int numQTaskSubmitted;

protected int numQTaskFailed;

/** The id list of available quantum datacenters. */
protected List<Integer> qDatacenterIdList;

Expand All @@ -50,6 +53,7 @@ public class QBroker extends SimEntity {
public QBroker(String name) throws Exception {
super(name);
numQTaskSubmitted = 0;
numQTaskFailed = 0;

setQNodeList(new ArrayList<QNode>());
setQTaskList(new ArrayList<QTask>());
Expand All @@ -71,12 +75,12 @@ public void bindCloudletToQNode(int qtaskId, int qNodeId) {

/////// GETTERS AND SETTERS ///////

protected void setQNodeList(QNodeList qNodeList) {
protected <T extends QNode> void setQNodeList(List<T> qNodeList) {
this.qNodeList = qNodeList;
}

public QNodeList getQNodeList() {
return qNodeList;
public <T extends QNode> List<T> getQNodeList() {
return (List<T>) qNodeList;
}

protected <T extends QTask> void setQTaskList(List<T> qtaskList) {
Expand Down Expand Up @@ -194,49 +198,78 @@ protected void setDatacenterIdsList(List<Integer> datacenterIdsList) {
private void processQTaskSubmit(SimEvent ev) {
int[] data = (int[]) ev.getData();
int qDatacenter = data[0];
int qNodeId = 0;
List<QTask> submittedQTasks = new ArrayList<QTask>();
List<QTask> failedQTasks = new ArrayList<QTask>();
Log.printConcatLine(iQuantum.clock(), ": ", getName(), " : Started scheduling all QTasks to QDatacenter #", qDatacenter);

QNodeList qNodeList = getQDatacenterCharacteristicsList().get(qDatacenter).getQNodeList();
List<? extends QNode> qNodeList = getQDatacenterCharacteristicsList().get(qDatacenter).getQNodeList();
setQNodeList(qNodeList);

for (QTask QTask : getQTaskList()) {
QNode qNode;
if (QTask.getQNodeId() == -1) {
// Submit qtask to a the first available QNode
// TODO: Implement a better (default) scheduling algorithm
qNode = getQNodeList().get(qNodeId);
QNodeSelectionLottery qnodeselection = new QNodeSelectionLottery(0.5, 0.5);
QNode qNode = null;
for (QTask qTask : getQTaskList()) {
if (qTask.getQNodeId() == -1) {
// APPLY SIMPLE LOTTERY BACKEND SELECTION STRATEGY
List<? extends QNode> preQNodes;
preQNodes = preScheduleQTask((List<QNode>) qNodeList, qTask);
if(!preQNodes.isEmpty()) {
qNode = qnodeselection.selectQNode(preQNodes);
qTask.setQNodeId(qNode.getId());
}
} else {
// Submit qtask to a specific QNode
qNode = QNodeList.getById(getQNodeList(), QTask.getQNodeId());
qNode = QNodeList.getById(getQNodeList(), qTask.getQNodeId());
if (qNode == null) {
if(!Log.isDisabled()) {
Log.printConcatLine(iQuantum.clock(), ": ", getName(), ": Postponing execution of QTask ", QTask.getQTaskId(),
Log.printConcatLine(iQuantum.clock(), ": ", getName(), ": Postponing execution of QTask ", qTask.getQTaskId(),
": QNode is not available");
}
continue;
}
}
// TODO: Check the constraints
/** QNode must have enough resources to execute the QTask
* number of qubits of QNode >= number of qubits of QTask
*/
if (!Log.isDisabled()) {
Log.printConcatLine(iQuantum.clock(), ": ", getName(), ": Checking if QNode #", qNode.getId(), " has enough qubits/gates to execute QTask",
QTask.getQTaskId());
}
if(verifyConstraints(qNode, QTask, submittedQTasks)) {
if (qNode!=null) {
if (!Log.isDisabled()) {
Log.printConcatLine(iQuantum.clock(), ": ", getName(), ": Sending QTask ",
QTask.getQTaskId(), " to QNode #", qNode.getId());
Log.printConcatLine(iQuantum.clock(), ": ", getName(), ": Checking if QNode #", qNode.getId(), " has enough qubits/gates to execute QTask",
qTask.getQTaskId());
}
if(verifyConstraints(qNode, qTask, submittedQTasks)) {
if (!Log.isDisabled()) {
Log.printConcatLine(iQuantum.clock(), ": ", getName(), ": Sending QTask ",
qTask.getQTaskId(), " to QNode #", qNode.getId());
}
sendNow(qNode.getQDatacenter().getId(), iQuantumTags.QTASK_SUBMIT, qTask);
numQTaskSubmitted++;
submittedQTasks.add(qTask);
}
sendNow(qNode.getQDatacenter().getId(), iQuantumTags.QTASK_SUBMIT, QTask);
numQTaskSubmitted++;
submittedQTasks.add(QTask);
} else
{
if(!Log.isDisabled()) {
Log.printConcatLine(iQuantum.clock(), ": ", getName(), ": Postponing execution of QTask ", qTask.getQTaskId(),
": No sufficient QNode available.");
}
failedQTasks.add(qTask);
numQTaskFailed++;
// If this task is submitted to Edge Layer, it can be offloaded to Cloud Layer
}
}
getQTaskList().removeAll(submittedQTasks);
getQTaskList().removeAll(failedQTasks);
}

private List<? extends QNode> preScheduleQTask(List<QNode> qNodeList, QTask qTask) {
List<QNode> preScheduledQNodeList = new ArrayList<>();
for (QNode qNode : qNodeList) {
if (qNode.getNumQubits() >= qTask.getNumQubits()
& isSubset(qTask.getGateSet(), qNode.getGateSets())) {
if(qNode.getQTaskScheduler().qtaskMapping(qTask, qNode)!=null)
{
preScheduledQNodeList.add(qNode);
}
}
}
return preScheduledQNodeList;
}

private boolean verifyConstraints(QNode qNode, QTask QTask, List<QTask> submittedQTasks){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import org.iquantum.core.SimEvent;
import org.iquantum.core.iQuantum;
import org.iquantum.core.iQuantumTags;
import org.iquantum.datacenters.QCloudDatacenter;
import org.iquantum.datacenters.QDatacenterCharacteristics;
import org.iquantum.datacenters.QEdgeDatacenter;
import org.iquantum.gateways.CloudGateway;
import org.iquantum.utils.Log;

import java.util.ArrayList;
Expand All @@ -16,6 +16,7 @@
* Quantum Edge Broker
*/
public class QEdgeBroker extends QBroker{

public QEdgeBroker(String name) throws Exception {
super(name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package org.iquantum.datacenters;

import org.iquantum.lists.QNodeList;
import org.iquantum.tasks.QTask;
import org.iquantum.backends.quantum.QNode;
import org.iquantum.utils.Log;
Expand Down Expand Up @@ -217,12 +218,10 @@ protected void processQTaskSubmit(SimEvent ev, boolean ack) {


// Get the QNode
//QNode qNode = getCharacteristics().getQNodeList().get(qNodeId);
QNode qNode = getCharacteristics().getQNodeList()
QNode qNode = QNodeList.getById(getCharacteristics().getQNodeList(), qNodeId);
// Temporary ignore the transfer time (will be considered in the future)
double transferTime = 0.0;

assert qNode != null;
QTaskScheduler scheduler = qNode.getQTaskScheduler();
double estimatedCompletionTime = scheduler.qtaskSubmit(QTask, transferTime);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
package org.iquantum.datacenters;
import org.iquantum.core.iQuantum;
import org.iquantum.backends.quantum.QNode;
import org.iquantum.lists.QNodeList;

import java.util.List;

Expand All @@ -17,13 +16,13 @@ public class QDatacenterCharacteristics{
private int id;

/** The hosts owned by the datacenter. */
private QNodeList qNodeList;
private List<? extends QNode> qNodeList;

/** The time zone, defined as the difference from GMT. */
private double timeZone;

private double costPerSecond;
public QDatacenterCharacteristics(QNodeList qNodeList, double timeZone, double costPerSecond) {
public QDatacenterCharacteristics(List<? extends QNode> qNodeList, double timeZone, double costPerSecond) {
setId(-1);
setQNodeList(qNodeList);
setTimeZone(0.0);
Expand Down Expand Up @@ -52,11 +51,11 @@ public void setId(int id) {
this.id = id;
}

public QNodeList getQNodeList() {
public List<? extends QNode> getQNodeList() {
return qNodeList;
}

public void setQNodeList(QNodeList qNodeList) {
public void setQNodeList(List<? extends QNode> qNodeList) {
this.qNodeList = qNodeList;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import org.iquantum.brokers.CCloudBroker;
import org.iquantum.brokers.QCloudBroker;
import org.iquantum.core.SimEntity;
import org.iquantum.core.SimEvent;
import org.iquantum.core.iQuantum;
import org.iquantum.core.iQuantumTags;
Expand All @@ -13,7 +12,7 @@
import java.util.ArrayList;
import java.util.List;

public class CloudGateway extends SimEntity {
public class CloudGateway extends Gateway {
/** The name of the cloud gateway. */
protected String name;
/** List of all CTask submitted to the cloud gateway. */
Expand Down Expand Up @@ -55,6 +54,14 @@ public void submitTasks(List<? extends CTask> cTaskList, List<? extends QTask> q
getQTaskList().addAll(qTaskList);
}

public void submitQTasks(List<? extends QTask> qTaskList) {
getQTaskList().addAll(qTaskList);
}

public void submitCTasks(List<? extends CTask> cTaskList) {
getCTaskList().addAll(cTaskList);
}


@Override
public void startEntity() {
Expand All @@ -73,7 +80,8 @@ public void processEvent(SimEvent ev) {
}
}

private void processTaskDispatch(SimEvent ev) {
@Override
protected void processTaskDispatch(SimEvent ev) {
Log.printConcatLine(iQuantum.clock(), ": ", getName(), " : Dispatching ",getCTaskList().size()," CTasks and ",getQTaskList().size()," QTasks from Cloud Gateway to Brokers for processing");
cBroker.submitCloudletList(getCTaskList());
qBroker.submitQTaskList(getQTaskList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/**
* Edge Gateway
*/
public class EdgeGateway extends SimEntity {
public class EdgeGateway extends Gateway {
protected String name;
/** List of all CTask submitted to the cloud gateway. */
protected List<? extends CTask> cTaskList;
Expand Down Expand Up @@ -83,7 +83,8 @@ public void processEvent(SimEvent ev) {
}
}

private void processTaskDispatch(SimEvent ev) {
@Override
protected void processTaskDispatch(SimEvent ev) {
Log.printConcatLine(iQuantum.clock(), ": ", getName(), " : Dispatching ",getCTaskList().size()," CTasks and ",getQTaskList().size()," QTasks from Edge Gateway to Brokers for processing");
cBroker.submitCloudletList(getCTaskList());
qBroker.submitQTaskList(getQTaskList());
Expand Down
Loading

0 comments on commit 0b80ee8

Please sign in to comment.