1423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams/*
2423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * Copyright (C) 2012 The Android Open Source Project
3423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *
4423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * you may not use this file except in compliance with the License.
6423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * You may obtain a copy of the License at
7423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *
8423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *
10423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * Unless required by applicable law or agreed to in writing, software
11423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * See the License for the specific language governing permissions and
14423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * limitations under the License.
15423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams */
16423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
17423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Samspackage android.renderscript;
18423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
1908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Samsimport java.util.ArrayList;
20423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
21423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams/**
22c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * ScriptGroup creates a group of kernels that are executed
23c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * together with one execution call as if they were a single kernel.
24c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * The kernels may be connected internally or to an external allocation.
25c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * The intermediate results for internal connections are not observable
26c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * after the execution of the script.
2708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams * <p>
28c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * External connections are grouped into inputs and outputs.
2908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams * All outputs are produced by a script kernel and placed into a
30c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * user-supplied allocation. Inputs provide the input of a kernel.
31c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * Inputs bound to script globals are set directly upon the script.
322a603897c6fdeba553051eedb911ec3b0b794530Tim Murray * <p>
332a603897c6fdeba553051eedb911ec3b0b794530Tim Murray * A ScriptGroup must contain at least one kernel. A ScriptGroup
342a603897c6fdeba553051eedb911ec3b0b794530Tim Murray * must contain only a single directed acyclic graph (DAG) of
352a603897c6fdeba553051eedb911ec3b0b794530Tim Murray * script kernels and connections. Attempting to create a
362a603897c6fdeba553051eedb911ec3b0b794530Tim Murray * ScriptGroup with multiple DAGs or attempting to create
372a603897c6fdeba553051eedb911ec3b0b794530Tim Murray * a cycle within a ScriptGroup will throw an exception.
38c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * <p>
39c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * Currently, all kernels in a ScriptGroup must be from separate
40c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * Script objects. Attempting to use multiple kernels from the same
41c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * Script object will result in an {@link android.renderscript.RSInvalidStateException}.
4208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams *
43423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams **/
4408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Samspublic final class ScriptGroup extends BaseObj {
45423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    IO mOutputs[];
46423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    IO mInputs[];
47423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
48423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    static class IO {
4908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        Script.KernelID mKID;
50423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Allocation mAllocation;
51423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
5208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        IO(Script.KernelID s) {
5308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mKID = s;
54423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
55423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
56423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
5708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    static class ConnectLine {
5808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        ConnectLine(Type t, Script.KernelID from, Script.KernelID to) {
5908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mFrom = from;
6008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mToK = to;
61423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mAllocationType = t;
62423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
63423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
6408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        ConnectLine(Type t, Script.KernelID from, Script.FieldID to) {
6508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mFrom = from;
6608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mToF = to;
6708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mAllocationType = t;
68423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
6908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
7008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        Script.FieldID mToF;
7108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        Script.KernelID mToK;
7208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        Script.KernelID mFrom;
7308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        Type mAllocationType;
74423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
75423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
76423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    static class Node {
77423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Script mScript;
7808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        ArrayList<Script.KernelID> mKernels = new ArrayList<Script.KernelID>();
7908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        ArrayList<ConnectLine> mInputs = new ArrayList<ConnectLine>();
8008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        ArrayList<ConnectLine> mOutputs = new ArrayList<ConnectLine>();
812a603897c6fdeba553051eedb911ec3b0b794530Tim Murray        int dagNumber;
82423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
83423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node mNext;
84423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
85423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node(Script s) {
86423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mScript = s;
87423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
88423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
89423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
90423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
91460a04971c494fec39ffcb38e873bb8fdd82d113Tim Murray    ScriptGroup(long id, RenderScript rs) {
92423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        super(id, rs);
93423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
94423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
9508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    /**
9608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * Sets an input of the ScriptGroup. This specifies an
97c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Allocation to be used for kernels that require an input
98c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Allocation provided from outside of the ScriptGroup.
9908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     *
10008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * @param s The ID of the kernel where the allocation should be
10108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     *          connected.
10208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * @param a The allocation to connect.
10308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     */
10408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    public void setInput(Script.KernelID s, Allocation a) {
105423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        for (int ct=0; ct < mInputs.length; ct++) {
10608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (mInputs[ct].mKID == s) {
107423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mInputs[ct].mAllocation = a;
10808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                mRS.nScriptGroupSetInput(getID(mRS), s.getID(mRS), mRS.safeID(a));
109423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                return;
110423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
111423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
112423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        throw new RSIllegalArgumentException("Script not found");
113423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
114423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
11508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    /**
11608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * Sets an output of the ScriptGroup. This specifies an
117c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Allocation to be used for the kernels that require an output
118c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Allocation visible after the ScriptGroup is executed.
11908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     *
12008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * @param s The ID of the kernel where the allocation should be
12108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     *          connected.
12208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * @param a The allocation to connect.
12308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     */
12408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    public void setOutput(Script.KernelID s, Allocation a) {
125423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        for (int ct=0; ct < mOutputs.length; ct++) {
12608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (mOutputs[ct].mKID == s) {
127423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mOutputs[ct].mAllocation = a;
12808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                mRS.nScriptGroupSetOutput(getID(mRS), s.getID(mRS), mRS.safeID(a));
129423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                return;
130423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
131423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
132423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        throw new RSIllegalArgumentException("Script not found");
133423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
134423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
13508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    /**
13608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * Execute the ScriptGroup.  This will run all the kernels in
137c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * the ScriptGroup.  No internal connection results will be visible
138c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * after execution of the ScriptGroup.
13908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     */
140423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    public void execute() {
14108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        mRS.nScriptGroupExecute(getID(mRS));
142423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
143423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
144423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
14508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    /**
146c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Helper class to build a ScriptGroup. A ScriptGroup is
147c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * created in two steps.
148c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * <p>
149c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * First, all kernels to be used by the ScriptGroup should be added.
15008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * <p>
151c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Second, add connections between kernels. There are two types
152c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * of connections: kernel to kernel and kernel to field.
153c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Kernel to kernel allows a kernel's output to be passed to
154c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * another kernel as input. Kernel to field allows the output of
155c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * one kernel to be bound as a script global. Kernel to kernel is
156c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * higher performance and should be used where possible.
15708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * <p>
158c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * A ScriptGroup must contain a single directed acyclic graph (DAG); it
159c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * cannot contain cycles. Currently, all kernels used in a ScriptGroup
160c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * must come from different Script objects. Additionally, all kernels
161c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * in a ScriptGroup must have at least one input, output, or internal
162c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * connection.
16308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * <p>
164c11e25c4e653124def1fb18e203b894f42106cbeTim Murray     * Once all connections are made, a call to {@link #create} will
16508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     * return the ScriptGroup object.
16608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     *
16708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams     */
16808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams    public static final class Builder {
16908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        private RenderScript mRS;
17008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        private ArrayList<Node> mNodes = new ArrayList<Node>();
17108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        private ArrayList<ConnectLine> mLines = new ArrayList<ConnectLine>();
17208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        private int mKernelCount;
17308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
17408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        /**
175c11e25c4e653124def1fb18e203b894f42106cbeTim Murray         * Create a Builder for generating a ScriptGroup.
17608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
17708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
178c11e25c4e653124def1fb18e203b894f42106cbeTim Murray         * @param rs The RenderScript context.
17908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         */
180423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        public Builder(RenderScript rs) {
181423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mRS = rs;
182423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
183423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
184091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray        // do a DFS from original node, looking for original node
185091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray        // any cycle that could be created must contain original node
186091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray        private void validateCycle(Node target, Node original) {
187091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray            for (int ct = 0; ct < target.mOutputs.size(); ct++) {
188091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray                final ConnectLine cl = target.mOutputs.get(ct);
18908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                if (cl.mToK != null) {
19008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    Node tn = findNode(cl.mToK.mScript);
191091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray                    if (tn.equals(original)) {
192423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        throw new RSInvalidStateException("Loops in group not allowed.");
193423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
194091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray                    validateCycle(tn, original);
19508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                }
19608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                if (cl.mToF != null) {
19708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    Node tn = findNode(cl.mToF.mScript);
198091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray                    if (tn.equals(original)) {
19908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        throw new RSInvalidStateException("Loops in group not allowed.");
20008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    }
201091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray                    validateCycle(tn, original);
2022a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                }
2032a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            }
2042a603897c6fdeba553051eedb911ec3b0b794530Tim Murray        }
2052a603897c6fdeba553051eedb911ec3b0b794530Tim Murray
2062a603897c6fdeba553051eedb911ec3b0b794530Tim Murray        private void mergeDAGs(int valueUsed, int valueKilled) {
2072a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            for (int ct=0; ct < mNodes.size(); ct++) {
2082a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                if (mNodes.get(ct).dagNumber == valueKilled)
2092a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    mNodes.get(ct).dagNumber = valueUsed;
2102a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            }
2112a603897c6fdeba553051eedb911ec3b0b794530Tim Murray        }
2122a603897c6fdeba553051eedb911ec3b0b794530Tim Murray
2132a603897c6fdeba553051eedb911ec3b0b794530Tim Murray        private void validateDAGRecurse(Node n, int dagNumber) {
2142a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            // combine DAGs if this node has been seen already
2152a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            if (n.dagNumber != 0 && n.dagNumber != dagNumber) {
2162a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                mergeDAGs(n.dagNumber, dagNumber);
2172a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                return;
2182a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            }
2192a603897c6fdeba553051eedb911ec3b0b794530Tim Murray
2202a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            n.dagNumber = dagNumber;
2212a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            for (int ct=0; ct < n.mOutputs.size(); ct++) {
2222a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                final ConnectLine cl = n.mOutputs.get(ct);
2232a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                if (cl.mToK != null) {
2242a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    Node tn = findNode(cl.mToK.mScript);
2252a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    validateDAGRecurse(tn, dagNumber);
2262a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                }
2272a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                if (cl.mToF != null) {
2282a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    Node tn = findNode(cl.mToF.mScript);
2292a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    validateDAGRecurse(tn, dagNumber);
2302a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                }
2312a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            }
2322a603897c6fdeba553051eedb911ec3b0b794530Tim Murray        }
2332a603897c6fdeba553051eedb911ec3b0b794530Tim Murray
2342a603897c6fdeba553051eedb911ec3b0b794530Tim Murray        private void validateDAG() {
2352a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            for (int ct=0; ct < mNodes.size(); ct++) {
2362a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                Node n = mNodes.get(ct);
2372a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                if (n.mInputs.size() == 0) {
2382a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    if (n.mOutputs.size() == 0 && mNodes.size() > 1) {
2392a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                        throw new RSInvalidStateException("Groups cannot contain unconnected scripts");
2402a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    }
2412a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    validateDAGRecurse(n, ct+1);
2422a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                }
2432a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            }
2442a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            int dagNumber = mNodes.get(0).dagNumber;
2452a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            for (int ct=0; ct < mNodes.size(); ct++) {
2462a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                if (mNodes.get(ct).dagNumber != dagNumber) {
2472a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                    throw new RSInvalidStateException("Multiple DAGs in group not allowed.");
248423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
249423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
250423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
251423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
25208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        private Node findNode(Script s) {
25308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            for (int ct=0; ct < mNodes.size(); ct++) {
25408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                if (s == mNodes.get(ct).mScript) {
25508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    return mNodes.get(ct);
256423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
257423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
258423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            return null;
259423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
260423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
26108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        private Node findNode(Script.KernelID k) {
26208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            for (int ct=0; ct < mNodes.size(); ct++) {
26308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                Node n = mNodes.get(ct);
26408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
26508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    if (k == n.mKernels.get(ct2)) {
26608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        return n;
267423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
268423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
269423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
27008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            return null;
27108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        }
27208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
27308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        /**
27408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * Adds a Kernel to the group.
27508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
27608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
27708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @param k The kernel to add.
27808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
27908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @return Builder Returns this.
28008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         */
28108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        public Builder addKernel(Script.KernelID k) {
28208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (mLines.size() != 0) {
28308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                throw new RSInvalidStateException(
28408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    "Kernels may not be added once connections exist.");
28508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
28608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
28708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            //android.util.Log.v("RSR", "addKernel 1 k=" + k);
28808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (findNode(k) != null) {
28908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                return this;
29008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
29108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            //android.util.Log.v("RSR", "addKernel 2 ");
29208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mKernelCount++;
29308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            Node n = findNode(k.mScript);
29408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (n == null) {
29508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                //android.util.Log.v("RSR", "addKernel 3 ");
29608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                n = new Node(k.mScript);
29708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                mNodes.add(n);
29808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
29908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            n.mKernels.add(k);
30008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            return this;
30108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        }
30208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
30308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        /**
30408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * Adds a connection to the group.
30508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
30608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
30708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @param t The type of the connection. This is used to
30808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *          determine the kernel launch sizes on the source side
30908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *          of this connection.
31008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @param from The source for the connection.
31108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @param to The destination of the connection.
31208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
31308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @return Builder Returns this
31408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         */
31508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        public Builder addConnection(Type t, Script.KernelID from, Script.FieldID to) {
31608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
31708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
31808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            Node nf = findNode(from);
31908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (nf == null) {
320091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray                throw new RSInvalidStateException("From script not found.");
32108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
32208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
32308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            Node nt = findNode(to.mScript);
32408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (nt == null) {
32508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                throw new RSInvalidStateException("To script not found.");
32608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
32708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
32808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            ConnectLine cl = new ConnectLine(t, from, to);
32908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mLines.add(new ConnectLine(t, from, to));
33008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
33108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            nf.mOutputs.add(cl);
33208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            nt.mInputs.add(cl);
33308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
334091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray            validateCycle(nf, nf);
33508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            return this;
33608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        }
33708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
33808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        /**
33908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * Adds a connection to the group.
34008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
34108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
34208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @param t The type of the connection. This is used to
34308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *          determine the kernel launch sizes for both sides of
34408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *          this connection.
34508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @param from The source for the connection.
34608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @param to The destination of the connection.
34708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
34808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @return Builder Returns this
34908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         */
35008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        public Builder addConnection(Type t, Script.KernelID from, Script.KernelID to) {
35108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
35208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
35308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            Node nf = findNode(from);
35408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (nf == null) {
355091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray                throw new RSInvalidStateException("From script not found.");
35608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
35708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
35808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            Node nt = findNode(to);
35908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (nt == null) {
36008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                throw new RSInvalidStateException("To script not found.");
361423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
36208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
36308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            ConnectLine cl = new ConnectLine(t, from, to);
36408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            mLines.add(new ConnectLine(t, from, to));
36508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
36608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            nf.mOutputs.add(cl);
36708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            nt.mInputs.add(cl);
368423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
369091f7ccf9a97aed94383370666b592a57a1b9400Tim Murray            validateCycle(nf, nf);
370423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            return this;
371423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
372423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
37308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
37408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
37508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams        /**
37608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * Creates the Script group.
37708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
37808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         *
37908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         * @return ScriptGroup The new ScriptGroup
38008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams         */
381423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        public ScriptGroup create() {
3822a603897c6fdeba553051eedb911ec3b0b794530Tim Murray
3832a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            if (mNodes.size() == 0) {
3842a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                throw new RSInvalidStateException("Empty script groups are not allowed");
3852a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            }
3862a603897c6fdeba553051eedb911ec3b0b794530Tim Murray
3872a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            // reset DAG numbers in case we're building a second group
3882a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            for (int ct=0; ct < mNodes.size(); ct++) {
3892a603897c6fdeba553051eedb911ec3b0b794530Tim Murray                mNodes.get(ct).dagNumber = 0;
3902a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            }
3912a603897c6fdeba553051eedb911ec3b0b794530Tim Murray            validateDAG();
3922a603897c6fdeba553051eedb911ec3b0b794530Tim Murray
39308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            ArrayList<IO> inputs = new ArrayList<IO>();
39408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            ArrayList<IO> outputs = new ArrayList<IO>();
39508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
3969807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat            long[] kernels = new long[mKernelCount];
39708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            int idx = 0;
39808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            for (int ct=0; ct < mNodes.size(); ct++) {
39908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                Node n = mNodes.get(ct);
40008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
40108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    final Script.KernelID kid = n.mKernels.get(ct2);
4029807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat                    kernels[idx++] = kid.getID(mRS);
40308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
40408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    boolean hasInput = false;
40508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    boolean hasOutput = false;
40608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    for (int ct3=0; ct3 < n.mInputs.size(); ct3++) {
40708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        if (n.mInputs.get(ct3).mToK == kid) {
40808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                            hasInput = true;
40908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        }
41008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    }
41108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    for (int ct3=0; ct3 < n.mOutputs.size(); ct3++) {
41208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        if (n.mOutputs.get(ct3).mFrom == kid) {
41308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                            hasOutput = true;
41408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        }
41508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    }
41608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    if (!hasInput) {
41708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        inputs.add(new IO(kid));
41808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    }
41908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    if (!hasOutput) {
42008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                        outputs.add(new IO(kid));
42108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                    }
422423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
42308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                }
42408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
42508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (idx != mKernelCount) {
42608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                throw new RSRuntimeException("Count mismatch, should not happen.");
42708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
42808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
4299807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat            long[] src = new long[mLines.size()];
4309807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat            long[] dstk = new long[mLines.size()];
4319807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat            long[] dstf = new long[mLines.size()];
4329807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat            long[] types = new long[mLines.size()];
43308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
43408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            for (int ct=0; ct < mLines.size(); ct++) {
43508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                ConnectLine cl = mLines.get(ct);
4369807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat                src[ct] = cl.mFrom.getID(mRS);
43708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                if (cl.mToK != null) {
4389807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat                    dstk[ct] = cl.mToK.getID(mRS);
43908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                }
44008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                if (cl.mToF != null) {
4419807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat                    dstf[ct] = cl.mToF.getID(mRS);
44208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                }
4439807155b11a25fb6068edc9b1cd82928ac2f05deAshok Bhat                types[ct] = cl.mAllocationType.getID(mRS);
44408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
44508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
446460a04971c494fec39ffcb38e873bb8fdd82d113Tim Murray            long id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types);
44708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            if (id == 0) {
44808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                throw new RSRuntimeException("Object creation error, should not happen.");
44908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
45008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
45108a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            ScriptGroup sg = new ScriptGroup(id, mRS);
45208a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            sg.mOutputs = new IO[outputs.size()];
45308a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            for (int ct=0; ct < outputs.size(); ct++) {
45408a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                sg.mOutputs[ct] = outputs.get(ct);
45508a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
45608a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams
45708a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            sg.mInputs = new IO[inputs.size()];
45808a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            for (int ct=0; ct < inputs.size(); ct++) {
45908a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams                sg.mInputs[ct] = inputs.get(ct);
46008a81583c18a849e442ceeb8d7baeca743fb3be8Jason Sams            }
461423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
462423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            return sg;
463423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
464423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
465423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
466423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
467423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
468423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams}
469423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
470423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
471