198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams/* 298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Copyright (C) 2012 The Android Open Source Project 398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * 498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * you may not use this file except in compliance with the License. 698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * You may obtain a copy of the License at 798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * 898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * 1098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Unless required by applicable law or agreed to in writing, software 1198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 1298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * See the License for the specific language governing permissions and 1498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * limitations under the License. 1598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams */ 1698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 1798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samspackage android.support.v8.renderscript; 1898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 1998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samsimport java.lang.reflect.Method; 20ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsimport java.util.ArrayList; 2198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 2298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams/** 23ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * ScriptGroup creates a groups of scripts which are executed 24ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * together based upon upon one execution call as if they were 25ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * all part of a single script. The scripts may be connected 26ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * internally or to an external allocation. For the internal 27ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * connections the intermediate results are not observable after 28ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * the execution of the script. 29ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * <p> 30ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * The external connections are grouped into inputs and outputs. 31ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * All outputs are produced by a script kernel and placed into a 32ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * user supplied allocation. Inputs are similar but supply the 33ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * input of a kernal. Inputs bounds to a script are set directly 34ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * upon the script. 35ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 3698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams **/ 37ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samspublic final class ScriptGroup extends BaseObj { 3898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams IO mOutputs[]; 3998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams IO mInputs[]; 4098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 4198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams static class IO { 42ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Script.KernelID mKID; 4398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams Allocation mAllocation; 4498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 45ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams IO(Script.KernelID s) { 46ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mKID = s; 4798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 4898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 4998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 50ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams static class ConnectLine { 51ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ConnectLine(Type t, Script.KernelID from, Script.KernelID to) { 52ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mFrom = from; 53ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mToK = to; 5498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams mAllocationType = t; 5598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 5698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 57ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ConnectLine(Type t, Script.KernelID from, Script.FieldID to) { 58ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mFrom = from; 59ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mToF = to; 60ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mAllocationType = t; 6198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 62ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 63ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Script.FieldID mToF; 64ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Script.KernelID mToK; 65ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Script.KernelID mFrom; 66ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Type mAllocationType; 6798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 6898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 6998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams static class Node { 7098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams Script mScript; 71ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ArrayList<Script.KernelID> mKernels = new ArrayList<Script.KernelID>(); 72ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ArrayList<ConnectLine> mInputs = new ArrayList<ConnectLine>(); 73ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ArrayList<ConnectLine> mOutputs = new ArrayList<ConnectLine>(); 7498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams boolean mSeen; 7598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 7698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams Node mNext; 7798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 7898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams Node(Script s) { 7998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams mScript = s; 8098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 8198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 8298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 8398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 8498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams ScriptGroup(int id, RenderScript rs) { 8598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams super(id, rs); 8698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 8798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 88ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 89ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Sets an input of the ScriptGroup. This specifies an 90ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Allocation to be used for the kernels which require a kernel 91ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * input and that input is provided external to the group. 92ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 93ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param s The ID of the kernel where the allocation should be 94ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * connected. 95ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param a The allocation to connect. 96ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 97ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams public void setInput(Script.KernelID s, Allocation a) { 9898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams for (int ct=0; ct < mInputs.length; ct++) { 99ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (mInputs[ct].mKID == s) { 10098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams mInputs[ct].mAllocation = a; 101ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mRS.nScriptGroupSetInput(getID(mRS), s.getID(mRS), mRS.safeID(a)); 10298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams return; 10398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 10498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 10598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams throw new RSIllegalArgumentException("Script not found"); 10698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 10798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 108ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 109ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Sets an output of the ScriptGroup. This specifies an 110ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Allocation to be used for the kernels which require a kernel 111ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * output and that output is provided external to the group. 112ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 113ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param s The ID of the kernel where the allocation should be 114ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * connected. 115ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param a The allocation to connect. 116ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 117ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams public void setOutput(Script.KernelID s, Allocation a) { 11898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams for (int ct=0; ct < mOutputs.length; ct++) { 119ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (mOutputs[ct].mKID == s) { 12098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams mOutputs[ct].mAllocation = a; 121ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mRS.nScriptGroupSetOutput(getID(mRS), s.getID(mRS), mRS.safeID(a)); 12298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams return; 12398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 12498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 12598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams throw new RSIllegalArgumentException("Script not found"); 12698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 12798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 128ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 129ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Execute the ScriptGroup. This will run all the kernels in 130ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * the script. The state of the connecting lines will not be 131ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * observable after this operation. 132ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 13398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams public void execute() { 134ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mRS.nScriptGroupExecute(getID(mRS)); 13598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 13698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 13798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 138ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 139ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Create a ScriptGroup. There are two steps to creating a 140ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * ScriptGoup. 141ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * <p> 142ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * First all the Kernels to be used by the group should be 143ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * added. Once this is done the kernels should be connected. 144ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Kernels cannot be added once a connection has been made. 145ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * <p> 146ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Second, add connections. There are two forms of connections. 147ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Kernel to Kernel and Kernel to Field. Kernel to Kernel is 148ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * higher performance and should be used where possible. The 149ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * line of connections cannot form a loop. If a loop is detected 150ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * an exception is thrown. 151ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * <p> 152ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Once all the connections are made a call to create will 153ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * return the ScriptGroup object. 154ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 155ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 156ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams public static final class Builder { 157ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams private RenderScript mRS; 158ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams private ArrayList<Node> mNodes = new ArrayList<Node>(); 159ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams private ArrayList<ConnectLine> mLines = new ArrayList<ConnectLine>(); 160ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams private int mKernelCount; 161ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 162ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 163ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Create a builder for generating a ScriptGroup. 164ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 165ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 166ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param rs The Renderscript context. 167ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 16898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams public Builder(RenderScript rs) { 16998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams mRS = rs; 17098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 17198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 17298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams private void validateRecurse(Node n, int depth) { 17398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams n.mSeen = true; 17498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 175ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams //android.util.Log.v("RSR", " validateRecurse outputCount " + n.mOutputs.size()); 176ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < n.mOutputs.size(); ct++) { 177ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams final ConnectLine cl = n.mOutputs.get(ct); 178ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (cl.mToK != null) { 179ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node tn = findNode(cl.mToK.mScript); 180ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (tn.mSeen) { 181ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSInvalidStateException("Loops in group not allowed."); 182ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 183ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams validateRecurse(tn, depth + 1); 184ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 185ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (cl.mToF != null) { 186ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node tn = findNode(cl.mToF.mScript); 187ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (tn.mSeen) { 18898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams throw new RSInvalidStateException("Loops in group not allowed."); 18998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 190ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams validateRecurse(tn, depth + 1); 19198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 19298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 19398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 19498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 19598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams private void validate() { 196ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams //android.util.Log.v("RSR", "validate"); 19798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 198ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < mNodes.size(); ct++) { 199ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct2=0; ct2 < mNodes.size(); ct2++) { 200ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mNodes.get(ct2).mSeen = false; 201ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 202ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node n = mNodes.get(ct); 203ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (n.mInputs.size() == 0) { 20498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams validateRecurse(n, 0); 20598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 20698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 20798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 20898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 209ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams private Node findNode(Script s) { 210ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < mNodes.size(); ct++) { 211ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (s == mNodes.get(ct).mScript) { 212ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return mNodes.get(ct); 21398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 21498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 21598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams return null; 21698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 21798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 218ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams private Node findNode(Script.KernelID k) { 219ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < mNodes.size(); ct++) { 220ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node n = mNodes.get(ct); 221ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct2=0; ct2 < n.mKernels.size(); ct2++) { 222ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (k == n.mKernels.get(ct2)) { 223ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return n; 22498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 22598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 22698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 227ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return null; 228ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 229ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 230ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 231ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Adds a Kernel to the group. 232ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 233ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 234ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param k The kernel to add. 235ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 236ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @return Builder Returns this. 237ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 238ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams public Builder addKernel(Script.KernelID k) { 239ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (mLines.size() != 0) { 240ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSInvalidStateException( 241ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams "Kernels may not be added once connections exist."); 242ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 243ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 244ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams //android.util.Log.v("RSR", "addKernel 1 k=" + k); 245ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (findNode(k) != null) { 246ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return this; 247ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 248ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams //android.util.Log.v("RSR", "addKernel 2 "); 249ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mKernelCount++; 250ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node n = findNode(k.mScript); 251ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (n == null) { 252ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams //android.util.Log.v("RSR", "addKernel 3 "); 253ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams n = new Node(k.mScript); 254ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mNodes.add(n); 255ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 256ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams n.mKernels.add(k); 257ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return this; 258ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 259ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 260ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 261ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Adds a connection to the group. 262ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 263ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 264ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param t The type of the connection. This is used to 265ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * determine the kernel launch sizes on the source side 266ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * of this connection. 267ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param from The source for the connection. 268ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param to The destination of the connection. 269ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 270ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @return Builder Returns this 271ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 272ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams public Builder addConnection(Type t, Script.KernelID from, Script.FieldID to) { 273ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to); 274ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 275ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node nf = findNode(from); 276ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (nf == null) { 277ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSInvalidStateException("From kernel not found."); 278ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 279ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 280ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node nt = findNode(to.mScript); 281ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (nt == null) { 282ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSInvalidStateException("To script not found."); 28398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 284ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 285ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ConnectLine cl = new ConnectLine(t, from, to); 286ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mLines.add(new ConnectLine(t, from, to)); 287ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 288ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams nf.mOutputs.add(cl); 289ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams nt.mInputs.add(cl); 29098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 29198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams validate(); 29298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams return this; 29398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 29498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 295ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 296ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Adds a connection to the group. 297ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 298ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 299ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param t The type of the connection. This is used to 300ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * determine the kernel launch sizes for both sides of 301ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * this connection. 302ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param from The source for the connection. 303ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @param to The destination of the connection. 304ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 305ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @return Builder Returns this 306ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 307ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams public Builder addConnection(Type t, Script.KernelID from, Script.KernelID to) { 308ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to); 309ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 310ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node nf = findNode(from); 311ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (nf == null) { 312ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSInvalidStateException("From kernel not found."); 313ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 314ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 315ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node nt = findNode(to); 316ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (nt == null) { 317ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSInvalidStateException("To script not found."); 318ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 319ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 320ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ConnectLine cl = new ConnectLine(t, from, to); 321ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams mLines.add(new ConnectLine(t, from, to)); 322ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 323ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams nf.mOutputs.add(cl); 324ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams nt.mInputs.add(cl); 325ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 326ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams validate(); 327ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return this; 328ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 329ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 330ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 331ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 332ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams /** 333ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Creates the Script group. 334ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 335ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 336ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * @return ScriptGroup The new ScriptGroup 337ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 33898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams public ScriptGroup create() { 339ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ArrayList<IO> inputs = new ArrayList<IO>(); 340ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ArrayList<IO> outputs = new ArrayList<IO>(); 341ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 342ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int[] kernels = new int[mKernelCount]; 343ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int idx = 0; 344ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < mNodes.size(); ct++) { 345ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams Node n = mNodes.get(ct); 346ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct2=0; ct2 < n.mKernels.size(); ct2++) { 347ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams final Script.KernelID kid = n.mKernels.get(ct2); 348ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams kernels[idx++] = kid.getID(mRS); 349ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 350ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams boolean hasInput = false; 351ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams boolean hasOutput = false; 352ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct3=0; ct3 < n.mInputs.size(); ct3++) { 353ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (n.mInputs.get(ct3).mToK == kid) { 354ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams hasInput = true; 355ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 356ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 357ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct3=0; ct3 < n.mOutputs.size(); ct3++) { 358ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (n.mOutputs.get(ct3).mFrom == kid) { 359ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams hasOutput = true; 360ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 361ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 362ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (!hasInput) { 363ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams inputs.add(new IO(kid)); 364ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 365ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (!hasOutput) { 366ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams outputs.add(new IO(kid)); 367ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 36898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 369ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 370ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 371ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (idx != mKernelCount) { 372ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSRuntimeException("Count mismatch, should not happen."); 373ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 374ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 375ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int[] src = new int[mLines.size()]; 376ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int[] dstk = new int[mLines.size()]; 377ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int[] dstf = new int[mLines.size()]; 378ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int[] types = new int[mLines.size()]; 379ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 380ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < mLines.size(); ct++) { 381ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ConnectLine cl = mLines.get(ct); 382ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams src[ct] = cl.mFrom.getID(mRS); 383ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (cl.mToK != null) { 384ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams dstk[ct] = cl.mToK.getID(mRS); 385ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 386ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (cl.mToF != null) { 387ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams dstf[ct] = cl.mToF.getID(mRS); 388ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 389ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams types[ct] = cl.mAllocationType.getID(mRS); 390ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 391ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 392ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types); 393ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if (id == 0) { 394ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams throw new RSRuntimeException("Object creation error, should not happen."); 395ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 396ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 397ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ScriptGroup sg = new ScriptGroup(id, mRS); 398ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams sg.mOutputs = new IO[outputs.size()]; 399ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < outputs.size(); ct++) { 400ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams sg.mOutputs[ct] = outputs.get(ct); 401ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 402ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 403ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams sg.mInputs = new IO[inputs.size()]; 404ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams for (int ct=0; ct < inputs.size(); ct++) { 405ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams sg.mInputs[ct] = inputs.get(ct); 406ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 40798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 40898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams return sg; 40998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 41098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 41198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams } 41298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 41398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 41498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams} 41598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 41698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams 417