From 1cd07f08840734238fb5f60ab0615916ca5c7547 Mon Sep 17 00:00:00 2001 From: Benjamin Weder Date: Fri, 29 Nov 2024 12:21:32 +0100 Subject: [PATCH] Quantum hardware selection (#164) * add flag * fix transformation * fix lint * fix for hwselect * add script to hwselection * fix issues * fix script --------- Co-authored-by: LaviniaStiliadou Co-authored-by: mbeisel --- .../extensions/pattern/util/PatternUtil.js | 5 ++- .../extensions/quantme/Constants.js | 1 + .../QuantMEPropertyEntries.js | 31 +++++++++++++ .../QuantMETaskProperties.js | 7 +++ .../replacement/QuantMETransformator.js | 43 ++++++++++++++++-- .../QuantMEHardwareSelectionHandler.js | 44 ++++++++++++++++++- .../quantme/resources/quantum4bpmn.json | 5 +++ node_modules/.package-lock.json | 6 +++ 8 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 node_modules/.package-lock.json diff --git a/components/bpmn-q/modeler-component/extensions/pattern/util/PatternUtil.js b/components/bpmn-q/modeler-component/extensions/pattern/util/PatternUtil.js index a3edd1d6..72c0e676 100644 --- a/components/bpmn-q/modeler-component/extensions/pattern/util/PatternUtil.js +++ b/components/bpmn-q/modeler-component/extensions/pattern/util/PatternUtil.js @@ -191,11 +191,12 @@ export function attachPatternsToSuitableConstruct( construct.y + construct.height, construct ); - console.log("added cutting"); + console.log("added hardware selection"); } if ( consts.BEHAVIORAL_PATTERNS.includes(patternType) && + patternType !== consts.QUANTUM_HARDWARE_SELECTION && type === "bpmn:SubProcess" ) { createPattern( @@ -334,6 +335,7 @@ export function removeAlgorithmAndAugmentationPatterns( modeling, elementRegistry ) { + console.log(patterns); for (let i = 0; i < patterns.length; i++) { let hostFlowElements = patterns[i].attachedToRef.flowElements; @@ -565,6 +567,7 @@ export function wrapExecutionTaskIntoSubprocess( subprocess, {} ); + modeling.connect(startEvent, copiedTask, { type: "bpmn:SequenceFlow", }); diff --git a/components/bpmn-q/modeler-component/extensions/quantme/Constants.js b/components/bpmn-q/modeler-component/extensions/quantme/Constants.js index b405edf0..7278e7cd 100644 --- a/components/bpmn-q/modeler-component/extensions/quantme/Constants.js +++ b/components/bpmn-q/modeler-component/extensions/quantme/Constants.js @@ -80,6 +80,7 @@ export const MAXIMUM_NUM_SUBCIRCUITS = "maxNumSubCircuits"; export const AUTOMATED_SELECTION = "automatedSelection"; export const ERROR_CORRECTION_METHOD = "errorCorrectionMethod"; export const WARM_STARTING_PATTERN = "warmStartingPattern"; +export const QRM_REPLACEMENT = "replacementSubprocess"; export const EXECUTION_RESULT = "executionResult"; export const EVALUATION_RESULT = "evaluationResult"; diff --git a/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMEPropertyEntries.js b/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMEPropertyEntries.js index 45ff7a71..d28bb93f 100644 --- a/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMEPropertyEntries.js +++ b/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMEPropertyEntries.js @@ -517,6 +517,7 @@ export function AutomatedSelectionEntry({ element }) { /> ); } + export function CalibrationMethodEntry({ element }) { const modeling = useService("modeling"); const translate = @@ -1736,3 +1737,33 @@ export function RequirementsEntry({ element }) { /> ); } + +export function QrmReplacementEntry({ element }) { + const modeling = useService("modeling"); + const translate = + useService("translate") || + function (str) { + return str; + }; + const debounce = useService("debounceInput"); + + const getValue = function () { + return element.businessObject.replacementSubprocess; + }; + + const setValue = function (newValue) { + return modeling.updateProperties(element, { + replacementSubprocess: newValue, + }); + }; + + return ( + + ); +} diff --git a/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMETaskProperties.js b/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMETaskProperties.js index b801c239..59cfab1c 100644 --- a/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMETaskProperties.js +++ b/components/bpmn-q/modeler-component/extensions/quantme/modeling/properties-provider/QuantMETaskProperties.js @@ -52,6 +52,7 @@ import { ErrorCorrectionMethodEntry, WarmStartingPatternEntry, RequirementsEntry, + QrmReplacementEntry, } from "./QuantMEPropertyEntries"; /** @@ -277,6 +278,12 @@ export function HardwareSelectionSubprocessProperties(element) { component: AutomatedSelectionEntry, isEdited: isTextFieldEntryEdited, }, + { + id: consts.QRM_REPLACEMENT, + element, + component: QrmReplacementEntry, + isEdited: isTextFieldEntryEdited, + }, ]; } diff --git a/components/bpmn-q/modeler-component/extensions/quantme/replacement/QuantMETransformator.js b/components/bpmn-q/modeler-component/extensions/quantme/replacement/QuantMETransformator.js index 3fc38cb5..ecb58b8a 100644 --- a/components/bpmn-q/modeler-component/extensions/quantme/replacement/QuantMETransformator.js +++ b/components/bpmn-q/modeler-component/extensions/quantme/replacement/QuantMETransformator.js @@ -57,8 +57,8 @@ export async function startQuantmeReplacementProcess( let moddle = modeler.get("moddle"); // get root element of the current diagram - const definitions = modeler.getDefinitions(); - const rootElement = getRootProcess(definitions); + let definitions = modeler.getDefinitions(); + let rootElement = getRootProcess(definitions); console.log(rootElement); if (typeof rootElement === "undefined") { @@ -71,13 +71,50 @@ export async function startQuantmeReplacementProcess( // get all QuantME modeling constructs from the process let replacementConstructs = getQuantMETasks(rootElement, elementRegistry); + console.log(replacementConstructs); + for (let replacementConstruct of replacementConstructs) { + if ( + replacementConstruct.task.$type === + constants.QUANTUM_HARDWARE_SELECTION_SUBPROCESS + ) { + console.log("Transforming QuantumHardwareSelectionSubprocess..."); + let replacementSuccess = await replaceHardwareSelectionSubprocess( + replacementConstruct.task, + replacementConstruct.parent, + modeler, + endpointConfig.nisqAnalyzerEndpoint, + endpointConfig.transformationFrameworkEndpoint, + endpointConfig.camundaEndpoint + ); + if (!replacementSuccess) { + console.log( + "Replacement of QuantME modeling construct with Id " + + replacementConstruct.task.id + + " failed. Aborting process!" + ); + return { + status: "failed", + cause: + "Replacement of QuantME modeling construct with Id " + + replacementConstruct.task.id + + " failed. Aborting process!", + }; + } + } + } + + definitions = modeler.getDefinitions(); + rootElement = getRootProcess(definitions); + layout(modeling, elementRegistry, rootElement); + updated_xml = await getXml(modeler); + replacementConstructs = getQuantMETasks(rootElement, elementRegistry); console.log( "Process contains " + replacementConstructs.length + " QuantME modeling constructs to replace..." ); if (!replacementConstructs || !replacementConstructs.length) { - return { status: "transformed", xml: xml }; + return { status: "transformed", xml: updated_xml }; } addQProvEndpoint(rootElement, elementRegistry, modeling, moddle); diff --git a/components/bpmn-q/modeler-component/extensions/quantme/replacement/hardware-selection/QuantMEHardwareSelectionHandler.js b/components/bpmn-q/modeler-component/extensions/quantme/replacement/hardware-selection/QuantMEHardwareSelectionHandler.js index ad992dbe..3d688a67 100644 --- a/components/bpmn-q/modeler-component/extensions/quantme/replacement/hardware-selection/QuantMEHardwareSelectionHandler.js +++ b/components/bpmn-q/modeler-component/extensions/quantme/replacement/hardware-selection/QuantMEHardwareSelectionHandler.js @@ -52,7 +52,8 @@ export async function replaceHardwareSelectionSubprocess( let moddle = modeler.get("moddle"); const automatedSelection = subprocess.automatedSelection; - const replacementSubprocess = subprocess.$attrs.replacementSubprocess; + console.log(elementRegistry.get(subprocess.id)); + const replacementSubprocess = subprocess.replacementSubprocess; // replace QuantumHardwareSelectionSubprocess with traditional subprocess let element = bpmnReplace.replaceElement(elementRegistry.get(subprocess.id), { @@ -66,6 +67,7 @@ export async function replaceHardwareSelectionSubprocess( providers: undefined, simulatorsAllowed: undefined, automatedSelection: undefined, + replacementSubprocess: undefined, }); console.log(element.businessObject.$attrs["quantme:replacementSubprocess"]); @@ -254,6 +256,46 @@ export async function replaceHardwareSelectionSubprocess( return true; } } else { + console.log(element); + // if the subprocess does not contain any children then the subprocess is invalid + if (element.children === undefined) { + return false; + } + // retrieve the first start event + let startEvent = element.children.filter( + (child) => child.type === "bpmn:StartEvent" + )[0]; + console.log(startEvent); + if (startEvent === undefined) { + return false; + } + + let scriptTask = modeling.createShape( + { type: "bpmn:ScriptTask" }, + { x: 50, y: 50 }, + element, + {} + ); + scriptTask.businessObject.name = "Select Quantum Device"; + scriptTask.businessObject.scriptFormat = "groovy"; + scriptTask.businessObject.script = `println "selectDevice";`; + scriptTask.businessObject.asyncBefore = true; + let flows = []; + startEvent.outgoing.forEach((flow) => { + flows.push(flow); + modeling.connect(scriptTask, elementRegistry.get(flow.target.id), { + type: "bpmn:SequenceFlow", + }); + }); + for (let i = 0; i < flows.length; i++) { + let flow = elementRegistry.get(flows[i].id); + modeling.removeConnection(flow); + } + modeling.connect(startEvent, scriptTask, { + type: "bpmn:SequenceFlow", + }); + console.log("finished tran"); + return true; } } diff --git a/components/bpmn-q/modeler-component/extensions/quantme/resources/quantum4bpmn.json b/components/bpmn-q/modeler-component/extensions/quantme/resources/quantum4bpmn.json index 8bebc64c..e7dd615a 100644 --- a/components/bpmn-q/modeler-component/extensions/quantme/resources/quantum4bpmn.json +++ b/components/bpmn-q/modeler-component/extensions/quantme/resources/quantum4bpmn.json @@ -41,6 +41,11 @@ "name": "automatedSelection", "isAttr": true, "type": "Boolean" + }, + { + "name": "replacementSubprocess", + "isAttr": true, + "type": "Boolean" } ] }, diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 00000000..f8fad29d --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "workflow-modeler", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}