/******************************************************************************* * Copyright (c) 2014 Imperial College London * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Raul Castro Fernandez - initial API and implementation ******************************************************************************/ package uk.ac.imperial.lsds.java2sdg.bricks.SDG; import java.util.LinkedList; import java.util.List; import uk.ac.imperial.lsds.java2sdg.bricks.SDGAnnotation; import uk.ac.imperial.lsds.java2sdg.bricks.TaskElement; import uk.ac.imperial.lsds.java2sdg.bricks.TaskElementNature; import uk.ac.imperial.lsds.java2sdg.bricks.TaskElement.TaskElementBuilder; public class PartialSDGBuilder { public static List<OperatorBlock> buildPartialSDG(List<TaskElementBuilder> sequentialTEList, int workflowId){ // Connections per local TE LinkedList<OperatorBlock> partialSDG = new LinkedList<OperatorBlock>(); int id = 0; int stateIdPtr = -1; for(TaskElementBuilder teb : sequentialTEList){ TaskElement te = teb.build(); OperatorBlock ob = null; if(te.getOpType().getNature().equals(TaskElementNature.Nature.STATEFUL_OPERATOR)){ int stateId = teb.getOpType().getStateElementId(); ob = OperatorBlock.makeStatefulOperator(id, workflowId, stateId); // If it's stateful there might be loops if(stateId > stateIdPtr){ stateIdPtr = stateId; // update pointer to most downstream state } else{ //loop. connect to whoever is required for(OperatorBlock looping : partialSDG){ // If op is stateful AND its state is the same if(looping.getTE().getOpType().getNature().equals(TaskElementNature.Nature.STATEFUL_OPERATOR) && looping.getStateId() == stateId){ // we get the sendType required by our upstream SendType demandedSendType = SendType.getSendType(looping.getTE().getAnn(), looping.getTE().getOpType()); demandedSendType.setBranchingIdentifier(workflowId); te.setSendType(demandedSendType); ob.addDownstream(looping.getId(), workflowId, StreamType.ONE_AT_A_TIME); looping.addUpstream(id, workflowId); } } } } else if(te.getOpType().getNature().equals(TaskElementNature.Nature.STATELESS_OPERATOR)){ int stateRef = te.getOpType().getStateElementId(); ob = OperatorBlock.makeStatelessOperator(id, workflowId, stateRef); } ob.addTE(te, id, workflowId); // Perform connections with previous OB if(!partialSDG.isEmpty()){ // Create a stream to connect upstream to me. For now, only annotations decide on this StreamType st = null; SDGAnnotation ann = te.getAnn(); if(ann != null){ if(ann.equals(SDGAnnotation.COLLECTION)){ st = StreamType.SYNC_BARRIER; } else{ st = StreamType.ONE_AT_A_TIME; } } // Detect the type of send I need SendType demandedSendType = SendType.getSendType(ob.getTE().getAnn(), ob.getTE().getOpType()); demandedSendType.setBranchingIdentifier(workflowId); partialSDG.getLast().getTE().setSendType(demandedSendType); // connect upstream to me partialSDG.getLast().addDownstream(ob.getId(), workflowId, st); // connect myself to upstream ob.addUpstream(partialSDG.getLast().getId(), workflowId); } // Finally I add myself to the graph partialSDG.add(ob); id++; } // Finishing by completing the SendInfo for those ops that will send to sink for(OperatorBlock op : partialSDG){ if(op.getTE().getSendType() == null){ //SendType demandedSendType = SendType.getSendType(op.getTE().getAnn(), op.getTE().getOpType()); // to fill ops connecting to sinks if(op.getDownstreamOperator().size() == 0){ SendType st = SendType.SEND; st.setBranchingIdentifier(workflowId); op.getTE().setSendType(SendType.SEND); } } } return partialSDG; } }