1c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
2c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Copyright (C) 2015 The Android Open Source Project
3c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
4c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Licensed under the Apache License, Version 2.0 (the "License");
5c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * you may not use this file except in compliance with the License.
6c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * You may obtain a copy of the License at
7c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
8c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *      http://www.apache.org/licenses/LICENSE-2.0
9c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
10c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Unless required by applicable law or agreed to in writing, software
11c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * distributed under the License is distributed on an "AS IS" BASIS,
12c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * See the License for the specific language governing permissions and
14c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * limitations under the License.
15c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */
16c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
17c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <iomanip>
18c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <iostream>
19c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <cmath>
20c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <sstream>
21c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
22c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Generator.h"
23c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Specification.h"
24c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Utilities.h"
25c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
26c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletusing namespace std;
27c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
28c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Converts float2 to FLOAT_32 and 2, etc.
29c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void convertToRsType(const string& name, string* dataType, char* vectorSize) {
30c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string s = name;
31c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    int last = s.size() - 1;
32c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    char lastChar = s[last];
33c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (lastChar >= '1' && lastChar <= '4') {
34c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        s.erase(last);
35c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *vectorSize = lastChar;
36c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
37c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *vectorSize = '1';
38c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
39c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    dataType->clear();
40c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (int i = 0; i < NUM_TYPES; i++) {
41c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (s == TYPES[i].cType) {
42c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *dataType = TYPES[i].rsDataType;
43c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
44c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
45c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
46c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
47c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
48c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Returns true if any permutation of the function have tests to b
4912398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nistatic bool needTestFiles(const Function& function, unsigned int versionOfTestFiles) {
50c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto spec : function.getSpecifications()) {
51c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (spec->hasTests(versionOfTestFiles)) {
52c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            return true;
53c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
54c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
55c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return false;
56c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
57c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
58c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/* One instance of this class is generated for each permutation of a function for which
59c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * we are generating test code.  This instance will generate both the script and the Java
60c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * section of the test files for this permutation.  The class is mostly used to keep track
61c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * of the various names shared between script and Java files.
62c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * WARNING: Because the constructor keeps a reference to the FunctionPermutation, PermutationWriter
63c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * should not exceed the lifetime of FunctionPermutation.
64c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */
65c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletclass PermutationWriter {
66c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletprivate:
67c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    FunctionPermutation& mPermutation;
68c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
69c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string mRsKernelName;
70c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string mJavaArgumentsClassName;
71c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string mJavaArgumentsNClassName;
72c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string mJavaVerifierComputeMethodName;
73c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string mJavaVerifierVerifyMethodName;
74c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string mJavaCheckMethodName;
75c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string mJavaVerifyMethodName;
76c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
77c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Pointer to the files we are generating.  Handy to avoid always passing them in the calls.
78c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    GeneratedFile* mRs;
79c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    GeneratedFile* mJava;
80c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
81c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* Shortcuts to the return parameter and the first input parameter of the function
82c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * specification.
83c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const ParameterDefinition* mReturnParam;      // Can be nullptr.  NOT OWNED.
85c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const ParameterDefinition* mFirstInputParam;  // Can be nullptr.  NOT OWNED.
86c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
87c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* All the parameters plus the return param, if present.  Collecting them together
88c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * simplifies code generation.  NOT OWNED.
89c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    vector<const ParameterDefinition*> mAllInputsAndOutputs;
91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* We use a class to pass the arguments between the generated code and the CoreVerifier.  This
93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * method generates this class.  The set keeps track if we've generated this class already
94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * for this test file, as more than one permutation may use the same argument class.
95c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
96c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaArgumentClass(bool scalar, set<string>* javaGeneratedArgumentClasses) const;
97c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
98c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate the Check* method that invokes the script and calls the verifier.
99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaCheckMethod(bool generateCallToVerifier) const;
100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate code to define and randomly initialize the input allocation.
102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaInputAllocationDefinition(const ParameterDefinition& param) const;
103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* Generate code that instantiate an allocation of floats or integers and fills it with
105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * random data. This random data must be compatible with the specified type.  This is
106c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * used for the convert_* tests, as converting values that don't fit yield undefined results.
107c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaRandomCompatibleFloatAllocation(const string& dataType, const string& seed,
109c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                  char vectorSize,
110c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                  const NumericalType& compatibleType,
111c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                  const NumericalType& generatedType) const;
112c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaRandomCompatibleIntegerAllocation(const string& dataType, const string& seed,
113c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                    char vectorSize,
114c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                    const NumericalType& compatibleType,
115c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                    const NumericalType& generatedType) const;
116c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
117c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate code that defines an output allocation.
118c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaOutputAllocationDefinition(const ParameterDefinition& param) const;
119c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
120c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* Generate the code that verifies the results for RenderScript functions where each entry
121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * of a vector is evaluated independently.  If verifierValidates is true, CoreMathVerifier
122c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * does the actual validation instead of more commonly returning the range of acceptable values.
123c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
124c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaVerifyScalarMethod(bool verifierValidates) const;
125c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
126c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* Generate the code that verify the results for a RenderScript function where a vector
127c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * is a point in n-dimensional space.
128c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
129c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaVerifyVectorMethod() const;
130c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
13193abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    // Generate the line that creates the Target.
13293abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    void writeJavaCreateTarget() const;
13393abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar
134c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate the method header of the verify function.
135c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaVerifyMethodHeader() const;
136c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
137c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate codes that copies the content of an allocation to an array.
138c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaArrayInitialization(const ParameterDefinition& p) const;
139c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
140c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate code that tests one value returned from the script.
141c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaTestAndSetValid(const ParameterDefinition& p, const string& argsIndex,
142c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                  const string& actualIndex) const;
143c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaTestOneValue(const ParameterDefinition& p, const string& argsIndex,
144c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                               const string& actualIndex) const;
145c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // For test:vector cases, generate code that compares returned vector vs. expected value.
146c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaVectorComparison(const ParameterDefinition& p) const;
147c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
148c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Muliple functions that generates code to build the error message if an error is found.
149c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaAppendOutputToMessage(const ParameterDefinition& p, const string& argsIndex,
150c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                        const string& actualIndex, bool verifierValidates) const;
151c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaAppendInputToMessage(const ParameterDefinition& p, const string& actual) const;
152c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaAppendNewLineToMessage() const;
153c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaAppendVectorInputToMessage(const ParameterDefinition& p) const;
154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaAppendVectorOutputToMessage(const ParameterDefinition& p) const;
155c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate the set of instructions to call the script.
157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaCallToRs(bool relaxed, bool generateCallToVerifier) const;
158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write an allocation definition if not already emitted in the .rs file.
160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeRsAllocationDefinition(const ParameterDefinition& param,
161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                     set<string>* rsAllocationsGenerated) const;
162c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
163c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletpublic:
164c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* NOTE: We keep pointers to the permutation and the files.  This object should not
165c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * outlive the arguments.
166c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
167c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    PermutationWriter(FunctionPermutation& permutation, GeneratedFile* rsFile,
168c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                      GeneratedFile* javaFile);
169c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string getJavaCheckMethodName() const { return mJavaCheckMethodName; }
170c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
171c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the script test function for this permutation.
172c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeRsSection(set<string>* rsAllocationsGenerated) const;
173c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the section of the Java code that calls the script and validates the results
174c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    void writeJavaSection(set<string>* javaGeneratedArgumentClasses) const;
175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet};
176c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
177c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletPermutationWriter::PermutationWriter(FunctionPermutation& permutation, GeneratedFile* rsFile,
178c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                     GeneratedFile* javaFile)
179c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    : mPermutation(permutation),
180c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet      mRs(rsFile),
181c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet      mJava(javaFile),
182c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet      mReturnParam(nullptr),
183c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet      mFirstInputParam(nullptr) {
184c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mRsKernelName = "test" + capitalize(permutation.getName());
185c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
186c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJavaArgumentsClassName = "Arguments";
187c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJavaArgumentsNClassName = "Arguments";
188c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string trunk = capitalize(permutation.getNameTrunk());
189c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJavaCheckMethodName = "check" + trunk;
190c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJavaVerifyMethodName = "verifyResults" + trunk;
191c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
192c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : permutation.getParams()) {
193c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mAllInputsAndOutputs.push_back(p);
194c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (mFirstInputParam == nullptr && !p->isOutParameter) {
195c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mFirstInputParam = p;
196c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
197c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
198c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mReturnParam = permutation.getReturn();
199c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mReturnParam) {
200c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mAllInputsAndOutputs.push_back(mReturnParam);
201c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
202c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
203c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
204c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        const string capitalizedRsType = capitalize(p->rsType);
205c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        const string capitalizedBaseType = capitalize(p->rsBaseType);
206c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mRsKernelName += capitalizedRsType;
207c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJavaArgumentsClassName += capitalizedBaseType;
208c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJavaArgumentsNClassName += capitalizedBaseType;
209c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->mVectorSize != "1") {
210c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mJavaArgumentsNClassName += "N";
211c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
212c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJavaCheckMethodName += capitalizedRsType;
213c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJavaVerifyMethodName += capitalizedRsType;
214c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
215c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJavaVerifierComputeMethodName = "compute" + trunk;
216c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJavaVerifierVerifyMethodName = "verify" + trunk;
217c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
218c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
219c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaSection(set<string>* javaGeneratedArgumentClasses) const {
220c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // By default, we test the results using item by item comparison.
221c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string test = mPermutation.getTest();
222c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (test == "scalar" || test == "limited") {
223c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaArgumentClass(true, javaGeneratedArgumentClasses);
224c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaCheckMethod(true);
225c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaVerifyScalarMethod(false);
226c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else if (test == "custom") {
227c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaArgumentClass(true, javaGeneratedArgumentClasses);
228c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaCheckMethod(true);
229c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaVerifyScalarMethod(true);
230c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else if (test == "vector") {
231c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaArgumentClass(false, javaGeneratedArgumentClasses);
232c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaCheckMethod(true);
233c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaVerifyVectorMethod();
234c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else if (test == "noverify") {
235c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaCheckMethod(false);
236c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
237c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
238c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
239c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaArgumentClass(bool scalar,
240c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                               set<string>* javaGeneratedArgumentClasses) const {
241c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string name;
242c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (scalar) {
243c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        name = mJavaArgumentsClassName;
244c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
245c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        name = mJavaArgumentsNClassName;
246c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
247c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
248c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Make sure we have not generated the argument class already.
249c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!testAndSet(name, javaGeneratedArgumentClasses)) {
250c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "public class " << name;
251c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->startBlock();
252c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
253c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto p : mAllInputsAndOutputs) {
2543b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            bool isFieldArray = !scalar && p->mVectorSize != "1";
2553b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            bool isFloatyField = p->isOutParameter && p->isFloatType && mPermutation.getTest() != "custom";
2563b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar
257c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mJava->indent() << "public ";
2583b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            if (isFloatyField) {
259c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *mJava << "Target.Floaty";
260c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            } else {
261c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *mJava << p->javaBaseType;
262c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
2633b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            if (isFieldArray) {
264c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *mJava << "[]";
265c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
266c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << " " << p->variableName << ";\n";
2673b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar
2683b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            // For Float16 parameters, add an extra 'double' field in the class
2693b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            // to hold the Double value converted from the input.
2703b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            if (p->isFloat16Parameter() && !isFloatyField) {
2713b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                mJava->indent() << "public double";
2723b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                if (isFieldArray) {
2733b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                    *mJava << "[]";
2743b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                }
2753b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                *mJava << " " + p->variableName << "Double;\n";
2763b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            }
277c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
278c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->endBlock();
279c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << "\n";
280c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
281c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
282c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
283c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaCheckMethod(bool generateCallToVerifier) const {
284c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "private void " << mJavaCheckMethodName << "()";
285c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
286c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
287c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate the input allocations and initialization.
288c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
289c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!p->isOutParameter) {
290c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaInputAllocationDefinition(*p);
291c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
292c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
293c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate code to enforce ordering between two allocations if needed.
294c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
295c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!p->isOutParameter && !p->smallerParameter.empty()) {
296c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            string smallerAlloc = "in" + capitalize(p->smallerParameter);
297c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mJava->indent() << "enforceOrdering(" << smallerAlloc << ", " << p->javaAllocName
298c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                            << ");\n";
299c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
300c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
301c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
302c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Generate code to check the full and relaxed scripts.
303c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeJavaCallToRs(false, generateCallToVerifier);
304c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeJavaCallToRs(true, generateCallToVerifier);
305c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
306c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
307c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << "\n";
308c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
309c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
310c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaInputAllocationDefinition(const ParameterDefinition& param) const {
311c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string dataType;
312c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    char vectorSize;
313c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    convertToRsType(param.rsType, &dataType, &vectorSize);
314c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
315c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string seed = hashString(mJavaCheckMethodName + param.javaAllocName);
316c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "Allocation " << param.javaAllocName << " = ";
317c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (param.compatibleTypeIndex >= 0) {
318c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (TYPES[param.typeIndex].kind == FLOATING_POINT) {
319c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaRandomCompatibleFloatAllocation(dataType, seed, vectorSize,
320c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                     TYPES[param.compatibleTypeIndex],
321c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                     TYPES[param.typeIndex]);
322c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
323c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaRandomCompatibleIntegerAllocation(dataType, seed, vectorSize,
324c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                       TYPES[param.compatibleTypeIndex],
325c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                       TYPES[param.typeIndex]);
326c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
327c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else if (!param.minValue.empty()) {
328c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << "createRandomFloatAllocation(mRS, Element.DataType." << dataType << ", "
329c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet               << vectorSize << ", " << seed << ", " << param.minValue << ", " << param.maxValue
330c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet               << ")";
331c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
332c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        /* TODO Instead of passing always false, check whether we are doing a limited test.
333c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet         * Use instead: (mPermutation.getTest() == "limited" ? "false" : "true")
334c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet         */
335c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << "createRandomAllocation(mRS, Element.DataType." << dataType << ", " << vectorSize
336c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet               << ", " << seed << ", false)";
337c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
338c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << ";\n";
339c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
340c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
341c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaRandomCompatibleFloatAllocation(
342c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string& dataType, const string& seed, char vectorSize,
343c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const NumericalType& compatibleType, const NumericalType& generatedType) const {
344c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << "createRandomFloatAllocation"
345c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet           << "(mRS, Element.DataType." << dataType << ", " << vectorSize << ", " << seed << ", ";
346c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    double minValue = 0.0;
347c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    double maxValue = 0.0;
348c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    switch (compatibleType.kind) {
349c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case FLOATING_POINT: {
350c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            // We're generating floating point values.  We just worry about the exponent.
351c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            // Subtract 1 for the exponent sign.
352c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            int bits = min(compatibleType.exponentBits, generatedType.exponentBits) - 1;
353c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            maxValue = ldexp(0.95, (1 << bits) - 1);
354c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            minValue = -maxValue;
355c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
356c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
357c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case UNSIGNED_INTEGER:
358c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            maxValue = maxDoubleForInteger(compatibleType.significantBits,
359c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                           generatedType.significantBits);
360c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            minValue = 0.0;
361c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
362c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case SIGNED_INTEGER:
363c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            maxValue = maxDoubleForInteger(compatibleType.significantBits,
364c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                           generatedType.significantBits);
365c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            minValue = -maxValue - 1.0;
366c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
367c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
368c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << scientific << std::setprecision(19);
369c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << minValue << ", " << maxValue << ")";
370c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->unsetf(ios_base::floatfield);
371c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
372c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
373c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaRandomCompatibleIntegerAllocation(
374c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string& dataType, const string& seed, char vectorSize,
375c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const NumericalType& compatibleType, const NumericalType& generatedType) const {
376c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << "createRandomIntegerAllocation"
377c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet           << "(mRS, Element.DataType." << dataType << ", " << vectorSize << ", " << seed << ", ";
378c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
379c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (compatibleType.kind == FLOATING_POINT) {
380c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        // Currently, all floating points can take any number we generate.
381c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        bool isSigned = generatedType.kind == SIGNED_INTEGER;
382c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << (isSigned ? "true" : "false") << ", " << generatedType.significantBits;
383c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
384c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        bool isSigned =
385c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    compatibleType.kind == SIGNED_INTEGER && generatedType.kind == SIGNED_INTEGER;
386c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << (isSigned ? "true" : "false") << ", "
387c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet               << min(compatibleType.significantBits, generatedType.significantBits);
388c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
389c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << ")";
390c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
391c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
392c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaOutputAllocationDefinition(
393c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const ParameterDefinition& param) const {
394c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string dataType;
395c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    char vectorSize;
396c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    convertToRsType(param.rsType, &dataType, &vectorSize);
397c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "Allocation " << param.javaAllocName << " = Allocation.createSized(mRS, "
398c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    << "getElement(mRS, Element.DataType." << dataType << ", " << vectorSize
399c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    << "), INPUTSIZE);\n";
400c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
401c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
402c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaVerifyScalarMethod(bool verifierValidates) const {
403c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeJavaVerifyMethodHeader();
404c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
405c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
406c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string vectorSize = "1";
407c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
408c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaArrayInitialization(*p);
409c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->mVectorSize != "1" && p->mVectorSize != vectorSize) {
410c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (vectorSize == "1") {
411c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                vectorSize = p->mVectorSize;
412c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            } else {
413c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                cerr << "Error.  Had vector " << vectorSize << " and " << p->mVectorSize << "\n";
414c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
415c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
416c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
417c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
4180c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "StringBuilder message = new StringBuilder();\n";
4190c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "boolean errorFound = false;\n";
420c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "for (int i = 0; i < INPUTSIZE; i++)";
421c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
422c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
423c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "for (int j = 0; j < " << vectorSize << " ; j++)";
424c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
425c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
426c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "// Extract the inputs.\n";
427c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << mJavaArgumentsClassName << " args = new " << mJavaArgumentsClassName
428c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    << "();\n";
429c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
430c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!p->isOutParameter) {
431c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mJava->indent() << "args." << p->variableName << " = " << p->javaArrayName << "[i";
432c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (p->vectorWidth != "1") {
433c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *mJava << " * " << p->vectorWidth << " + j";
434c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
435c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << "];\n";
4363b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar
4373b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            // Convert the Float16 parameter to double and store it in the appropriate field in the
4383b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            // Arguments class.
4393b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            if (p->isFloat16Parameter()) {
4403b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                mJava->indent() << "args." << p->doubleVariableName
4413b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                                << " = Float16Utils.convertFloat16ToDouble(args."
4423b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                                << p->variableName << ");\n";
4433b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            }
444c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
445c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
446c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const bool hasFloat = mPermutation.hasFloatAnswers();
447c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (verifierValidates) {
448c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "// Extract the outputs.\n";
449c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto p : mAllInputsAndOutputs) {
450c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (p->isOutParameter) {
451c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                mJava->indent() << "args." << p->variableName << " = " << p->javaArrayName
45249736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet                                << "[i * " << p->vectorWidth << " + j];\n";
453f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar                if (p->isFloat16Parameter()) {
454f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar                    mJava->indent() << "args." << p->doubleVariableName
455f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar                                    << " = Float16Utils.convertFloat16ToDouble(args."
456f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar                                    << p->variableName << ");\n";
457f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar                }
458c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
459c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
460c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "// Ask the CoreMathVerifier to validate.\n";
461c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (hasFloat) {
46293abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar            writeJavaCreateTarget();
463c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
464c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "String errorMessage = CoreMathVerifier."
465c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                        << mJavaVerifierVerifyMethodName << "(args";
466c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (hasFloat) {
467c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << ", target";
468c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
469c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << ");\n";
470c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "boolean valid = errorMessage == null;\n";
471c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
472c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "// Figure out what the outputs should have been.\n";
473c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (hasFloat) {
47493abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar            writeJavaCreateTarget();
475c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
476c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "CoreMathVerifier." << mJavaVerifierComputeMethodName << "(args";
477c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (hasFloat) {
478c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << ", target";
479c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
480c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << ");\n";
481c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "// Validate the outputs.\n";
482c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "boolean valid = true;\n";
483c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto p : mAllInputsAndOutputs) {
484c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (p->isOutParameter) {
485c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                writeJavaTestAndSetValid(*p, "", "[i * " + p->vectorWidth + " + j]");
486c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
487c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
488c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
489c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
490c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "if (!valid)";
491c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
4920c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "if (!errorFound)";
4930c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->startBlock();
4940c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "errorFound = true;\n";
495c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
496c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
497c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->isOutParameter) {
498c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaAppendOutputToMessage(*p, "", "[i * " + p->vectorWidth + " + j]",
499c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                           verifierValidates);
500c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
501c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaAppendInputToMessage(*p, "args." + p->variableName);
502c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
503c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
504c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (verifierValidates) {
505c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "message.append(errorMessage);\n";
506c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
5070c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(\"Errors at\");\n";
5080c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->endBlock();
509c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
5100c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(\" [\");\n";
5110c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(Integer.toString(i));\n";
5120c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(\", \");\n";
5130c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(Integer.toString(j));\n";
5140c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(\"]\");\n";
515c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
516c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
517c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
518c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
5190c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet
5200c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "assertFalse(\"Incorrect output for " << mJavaCheckMethodName << "\" +\n";
5210c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indentPlus()
5220c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet                << "(relaxed ? \"_relaxed\" : \"\") + \":\\n\" + message.toString(), errorFound);\n";
5230c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet
524c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
525c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << "\n";
526c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
527c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
528c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaVerifyVectorMethod() const {
529c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeJavaVerifyMethodHeader();
530c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
531c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
532c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
533c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaArrayInitialization(*p);
534c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
5350c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "StringBuilder message = new StringBuilder();\n";
5360c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "boolean errorFound = false;\n";
537c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "for (int i = 0; i < INPUTSIZE; i++)";
538c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
539c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
540c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << mJavaArgumentsNClassName << " args = new " << mJavaArgumentsNClassName
541c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    << "();\n";
542c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
543c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "// Create the appropriate sized arrays in args\n";
544c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
545c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->mVectorSize != "1") {
546c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            string type = p->javaBaseType;
547c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (p->isOutParameter && p->isFloatType) {
548c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                type = "Target.Floaty";
549c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
550c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mJava->indent() << "args." << p->variableName << " = new " << type << "["
551c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                            << p->mVectorSize << "];\n";
5523b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            if (p->isFloat16Parameter() && !p->isOutParameter) {
5533b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                mJava->indent() << "args." << p->variableName << "Double = new double["
5543b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                                << p->mVectorSize << "];\n";
5553b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            }
556c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
557c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
558c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
559c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "// Fill args with the input values\n";
560c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
561c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!p->isOutParameter) {
562c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (p->mVectorSize == "1") {
56349736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet                mJava->indent() << "args." << p->variableName << " = " << p->javaArrayName << "[i]"
564c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                << ";\n";
565b7841c4b0caf8dfff41a60c5469c0589ed13b190Pirama Arumuga Nainar                // Convert the Float16 parameter to double and store it in the appropriate field in
566b7841c4b0caf8dfff41a60c5469c0589ed13b190Pirama Arumuga Nainar                // the Arguments class.
567b7841c4b0caf8dfff41a60c5469c0589ed13b190Pirama Arumuga Nainar                if (p->isFloat16Parameter()) {
568b7841c4b0caf8dfff41a60c5469c0589ed13b190Pirama Arumuga Nainar                    mJava->indent() << "args." << p->doubleVariableName << " = "
569b7841c4b0caf8dfff41a60c5469c0589ed13b190Pirama Arumuga Nainar                                    << "Float16Utils.convertFloat16ToDouble(args."
570b7841c4b0caf8dfff41a60c5469c0589ed13b190Pirama Arumuga Nainar                                    << p->variableName << ");\n";
571b7841c4b0caf8dfff41a60c5469c0589ed13b190Pirama Arumuga Nainar                }
572c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            } else {
573c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                mJava->indent() << "for (int j = 0; j < " << p->mVectorSize << " ; j++)";
574c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                mJava->startBlock();
57549736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet                mJava->indent() << "args." << p->variableName << "[j] = "
57649736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet                                << p->javaArrayName << "[i * " << p->vectorWidth << " + j]"
577c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                << ";\n";
5783b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar
5793b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                // Convert the Float16 parameter to double and store it in the appropriate field in
5803b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                // the Arguments class.
5813b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                if (p->isFloat16Parameter()) {
5823b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                    mJava->indent() << "args." << p->doubleVariableName << "[j] = "
5833b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                                    << "Float16Utils.convertFloat16ToDouble(args."
5843b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                                    << p->variableName << "[j]);\n";
5853b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                }
586c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                mJava->endBlock();
587c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
588c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
589c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
59093abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    writeJavaCreateTarget();
591c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "CoreMathVerifier." << mJavaVerifierComputeMethodName
592c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    << "(args, target);\n\n";
593c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
594c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "// Compare the expected outputs to the actual values returned by RS.\n";
595c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "boolean valid = true;\n";
596c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
597c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->isOutParameter) {
598c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaVectorComparison(*p);
599c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
600c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
601c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
602c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "if (!valid)";
603c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
6040c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "if (!errorFound)";
6050c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->startBlock();
6060c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "errorFound = true;\n";
607c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
608c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
609c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->isOutParameter) {
610c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaAppendVectorOutputToMessage(*p);
611c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
612c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaAppendVectorInputToMessage(*p);
613c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
614c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
6150c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(\"Errors at\");\n";
6160c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->endBlock();
617c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
6180c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(\" [\");\n";
6190c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(Integer.toString(i));\n";
6200c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "message.append(\"]\");\n";
621c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
622c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
623c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
6240c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet
6250c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indent() << "assertFalse(\"Incorrect output for " << mJavaCheckMethodName << "\" +\n";
6260c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    mJava->indentPlus()
6270c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet                << "(relaxed ? \"_relaxed\" : \"\") + \":\\n\" + message.toString(), errorFound);\n";
6280c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet
629c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
630c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << "\n";
631c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
632c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
63393abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar
63493abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainarvoid PermutationWriter::writeJavaCreateTarget() const {
63593abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    string name = mPermutation.getName();
63693abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar
63793abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    const char* functionType = "NORMAL";
63893abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    size_t end = name.find('_');
63993abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    if (end != string::npos) {
64093abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        if (name.compare(0, end, "native") == 0) {
64193abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar            functionType = "NATIVE";
64293abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        } else if (name.compare(0, end, "half") == 0) {
64393abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar            functionType = "HALF";
64493abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        } else if (name.compare(0, end, "fast") == 0) {
64593abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar            functionType = "FAST";
64693abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        }
64793abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    }
64893abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar
64993abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    string floatType = mReturnParam->specType;
65093abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    const char* precisionStr = "";
65193abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    if (floatType.compare("f16") == 0) {
65293abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        precisionStr = "HALF";
65393abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    } else if (floatType.compare("f32") == 0) {
65493abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        precisionStr = "FLOAT";
65593abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    } else if (floatType.compare("f64") == 0) {
65693abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        precisionStr = "DOUBLE";
65793abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    } else {
65893abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar        cerr << "Error. Unreachable.  Return type is not floating point\n";
65993abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    }
66093abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar
66193abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    mJava->indent() << "Target target = new Target(Target.FunctionType." <<
66293abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar                    functionType << ", Target.ReturnType." << precisionStr <<
66393abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar                    ", relaxed);\n";
66493abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar}
66593abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar
666c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaVerifyMethodHeader() const {
667c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "private void " << mJavaVerifyMethodName << "(";
668c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
669c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << "Allocation " << p->javaAllocName << ", ";
670c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
671c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << "boolean relaxed)";
672c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
673c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
674c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaArrayInitialization(const ParameterDefinition& p) const {
675c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << p.javaBaseType << "[] " << p.javaArrayName << " = new " << p.javaBaseType
676c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    << "[INPUTSIZE * " << p.vectorWidth << "];\n";
6770c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet
6780c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    /* For basic types, populate the array with values, to help understand failures.  We have had
6790c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet     * bugs where the output buffer was all 0.  We were not sure if there was a failed copy or
6800c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet     * the GPU driver was copying zeroes.
6810c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet     */
6820c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    if (p.typeIndex >= 0) {
6830c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet        mJava->indent() << "Arrays.fill(" << p.javaArrayName << ", (" << TYPES[p.typeIndex].javaType
6840c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet                        << ") 42);\n";
6850c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    }
6860c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet
687c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << p.javaAllocName << ".copyTo(" << p.javaArrayName << ");\n";
688c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
689c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
690c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaTestAndSetValid(const ParameterDefinition& p,
691c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                 const string& argsIndex,
692c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                 const string& actualIndex) const {
693c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeJavaTestOneValue(p, argsIndex, actualIndex);
694c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
695c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "valid = false;\n";
696c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
697c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
698c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
699c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaTestOneValue(const ParameterDefinition& p, const string& argsIndex,
700c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                              const string& actualIndex) const {
7013b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar    string actualOut;
7023b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar    if (p.isFloat16Parameter()) {
7033b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar        // For Float16 values, the output needs to be converted to Double.
7043b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar        actualOut = "Float16Utils.convertFloat16ToDouble(" + p.javaArrayName + actualIndex + ")";
7053b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar    } else {
7063b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar        actualOut = p.javaArrayName + actualIndex;
7073b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar    }
7083b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar
709c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "if (";
710c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (p.isFloatType) {
7113b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar        *mJava << "!args." << p.variableName << argsIndex << ".couldBe(" << actualOut;
712c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        const string s = mPermutation.getPrecisionLimit();
713c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!s.empty()) {
714c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << ", " << s;
715c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
716c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << ")";
717c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
718c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << "args." << p.variableName << argsIndex << " != " << p.javaArrayName
719c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet               << actualIndex;
720c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
721c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
722c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (p.undefinedIfOutIsNan && mReturnParam) {
723c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << " && !args." << mReturnParam->variableName << argsIndex << ".isNaN()";
724c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
725c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mJava << ")";
726c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
727c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
728c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaVectorComparison(const ParameterDefinition& p) const {
729c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (p.mVectorSize == "1") {
730c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaTestAndSetValid(p, "", "[i]");
731c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
732c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "for (int j = 0; j < " << p.mVectorSize << " ; j++)";
733c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->startBlock();
734c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaTestAndSetValid(p, "[j]", "[i * " + p.vectorWidth + " + j]");
735c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->endBlock();
736c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
737c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
738c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
739c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaAppendOutputToMessage(const ParameterDefinition& p,
740c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                       const string& argsIndex,
741c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                       const string& actualIndex,
742c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                       bool verifierValidates) const {
743c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (verifierValidates) {
74449736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet        mJava->indent() << "message.append(\"Output " << p.variableName << ": \");\n";
74549736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet        mJava->indent() << "appendVariableToMessage(message, args." << p.variableName << argsIndex
74649736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet                        << ");\n";
747c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaAppendNewLineToMessage();
748f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar        if (p.isFloat16Parameter()) {
749f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar            writeJavaAppendNewLineToMessage();
750f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar            mJava->indent() << "message.append(\"Output " << p.variableName
751f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar                            << " (in double): \");\n";
752f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar            mJava->indent() << "appendVariableToMessage(message, args." << p.doubleVariableName
753f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar                            << ");\n";
754f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar            writeJavaAppendNewLineToMessage();
755f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar        }
756c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
75749736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet        mJava->indent() << "message.append(\"Expected output " << p.variableName << ": \");\n";
75849736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet        mJava->indent() << "appendVariableToMessage(message, args." << p.variableName << argsIndex
75949736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet                        << ");\n";
760c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaAppendNewLineToMessage();
76149736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet
76249736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet        mJava->indent() << "message.append(\"Actual   output " << p.variableName << ": \");\n";
76349736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet        mJava->indent() << "appendVariableToMessage(message, " << p.javaArrayName << actualIndex
76449736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet                        << ");\n";
765c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
7663b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar        if (p.isFloat16Parameter()) {
7673b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            writeJavaAppendNewLineToMessage();
7683b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            mJava->indent() << "message.append(\"Actual   output " << p.variableName
7693b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                            << " (in double): \");\n";
7703b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar            mJava->indent() << "appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble("
7713b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar                            << p.javaArrayName << actualIndex << "));\n";
7723b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar        }
7733b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar
774c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaTestOneValue(p, argsIndex, actualIndex);
775c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->startBlock();
776c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "message.append(\" FAIL\");\n";
777c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->endBlock();
778c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaAppendNewLineToMessage();
779c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
780c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
781c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
782c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaAppendInputToMessage(const ParameterDefinition& p,
783c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                      const string& actual) const {
78449736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet    mJava->indent() << "message.append(\"Input " << p.variableName << ": \");\n";
78549736b322c6539016c1a563fe74881b405b350f0Jean-Luc Brouillet    mJava->indent() << "appendVariableToMessage(message, " << actual << ");\n";
786c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeJavaAppendNewLineToMessage();
787c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
788c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
789c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaAppendNewLineToMessage() const {
790c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "message.append(\"\\n\");\n";
791c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
792c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
793c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaAppendVectorInputToMessage(const ParameterDefinition& p) const {
794c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (p.mVectorSize == "1") {
795c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaAppendInputToMessage(p, p.javaArrayName + "[i]");
796c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
797c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "for (int j = 0; j < " << p.mVectorSize << " ; j++)";
798c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->startBlock();
799c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaAppendInputToMessage(p, p.javaArrayName + "[i * " + p.vectorWidth + " + j]");
800c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->endBlock();
801c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
802c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
803c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
804c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaAppendVectorOutputToMessage(const ParameterDefinition& p) const {
805c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (p.mVectorSize == "1") {
806c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaAppendOutputToMessage(p, "", "[i]", false);
807c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
808c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << "for (int j = 0; j < " << p.mVectorSize << " ; j++)";
809c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->startBlock();
810c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeJavaAppendOutputToMessage(p, "[j]", "[i * " + p.vectorWidth + " + j]", false);
811c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->endBlock();
812c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
813c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
814c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
815c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeJavaCallToRs(bool relaxed, bool generateCallToVerifier) const {
816c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string script = "script";
817c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (relaxed) {
818c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        script += "Relaxed";
819c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
820c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
821c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "try";
822c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->startBlock();
823c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
824c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mAllInputsAndOutputs) {
825c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->isOutParameter) {
826c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeJavaOutputAllocationDefinition(*p);
827c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
828c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
829c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
830c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mPermutation.getParams()) {
831c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p != mFirstInputParam) {
832c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mJava->indent() << script << ".set_" << p->rsAllocName << "(" << p->javaAllocName
833c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                            << ");\n";
834c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
835c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
836c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
837c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << script << ".forEach_" << mRsKernelName << "(";
838c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    bool needComma = false;
839c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mFirstInputParam) {
840c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << mFirstInputParam->javaAllocName;
841c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        needComma = true;
842c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
843c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mReturnParam) {
844c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (needComma) {
845c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << ", ";
846c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
847c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << mReturnParam->variableName << ");\n";
848c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
849c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
850c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (generateCallToVerifier) {
851c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mJava->indent() << mJavaVerifyMethodName << "(";
852c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto p : mAllInputsAndOutputs) {
853c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << p->variableName << ", ";
854c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
855c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
856c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (relaxed) {
857c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << "true";
858c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
859c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mJava << "false";
860c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
861c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mJava << ");\n";
862c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
863c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->decreaseIndent();
864c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "} catch (Exception e) {\n";
865c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->increaseIndent();
866c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->indent() << "throw new RSRuntimeException(\"RenderScript. Can't invoke forEach_"
867c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    << mRsKernelName << ": \" + e.toString());\n";
868c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mJava->endBlock();
869c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
870c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
871c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/* Write the section of the .rs file for this permutation.
872c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
873c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * We communicate the extra input and output parameters via global allocations.
874c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * For example, if we have a function that takes three arguments, two for input
875c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * and one for output:
876c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
877c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * start:
878c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * name: gamn
879c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * ret: float3
880c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * arg: float3 a
881c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * arg: int b
882c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * arg: float3 *c
883c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * end:
884c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
885c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * We'll produce:
886c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
887c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * rs_allocation gAllocInB;
888c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * rs_allocation gAllocOutC;
889c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
890c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * float3 __attribute__((kernel)) test_gamn_float3_int_float3(float3 inA, unsigned int x) {
891c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *    int inB;
892c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *    float3 outC;
893c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *    float2 out;
894c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *    inB = rsGetElementAt_int(gAllocInB, x);
895c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *    out = gamn(a, in_b, &outC);
896c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *    rsSetElementAt_float4(gAllocOutC, &outC, x);
897c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *    return out;
898c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * }
899c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
900c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * We avoid re-using x and y from the definition because these have reserved
901c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * meanings in a .rs file.
902c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */
903c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeRsSection(set<string>* rsAllocationsGenerated) const {
904c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the allocation declarations we'll need.
905c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mPermutation.getParams()) {
906c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        // Don't need allocation for one input and one return value.
907c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p != mFirstInputParam) {
908c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeRsAllocationDefinition(*p, rsAllocationsGenerated);
909c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
910c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
911c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mRs << "\n";
912c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
913c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the function header.
914c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mReturnParam) {
915c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mRs << mReturnParam->rsType;
916c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
917c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mRs << "void";
918c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
919c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mRs << " __attribute__((kernel)) " << mRsKernelName;
920c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mRs << "(";
921c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    bool needComma = false;
922c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mFirstInputParam) {
923c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mRs << mFirstInputParam->rsType << " " << mFirstInputParam->variableName;
924c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        needComma = true;
925c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
926c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mPermutation.getOutputCount() > 1 || mPermutation.getInputCount() > 1) {
927c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (needComma) {
928c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mRs << ", ";
929c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
930c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mRs << "unsigned int x";
931c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
932c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mRs << ")";
933c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mRs->startBlock();
934c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
935c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the local variable declarations and initializations.
936c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mPermutation.getParams()) {
937c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p == mFirstInputParam) {
938c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            continue;
939c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
940c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        mRs->indent() << p->rsType << " " << p->variableName;
941c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->isOutParameter) {
942c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mRs << " = 0;\n";
943c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
944c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mRs << " = rsGetElementAt_" << p->rsType << "(" << p->rsAllocName << ", x);\n";
945c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
946c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
947c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
948c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the function call.
949c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mReturnParam) {
950c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (mPermutation.getOutputCount() > 1) {
951c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mRs->indent() << mReturnParam->rsType << " " << mReturnParam->variableName << " = ";
952c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
953c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mRs->indent() << "return ";
954c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
955c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
956c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mRs << mPermutation.getName() << "(";
957c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    needComma = false;
958c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : mPermutation.getParams()) {
959c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (needComma) {
960c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mRs << ", ";
961c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
962c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->isOutParameter) {
963c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *mRs << "&";
964c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
965c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mRs << p->variableName;
966c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        needComma = true;
967c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
968c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *mRs << ");\n";
969c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
970c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (mPermutation.getOutputCount() > 1) {
971c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        // Write setting the extra out parameters into the allocations.
972c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto p : mPermutation.getParams()) {
973c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (p->isOutParameter) {
974c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                mRs->indent() << "rsSetElementAt_" << p->rsType << "(" << p->rsAllocName << ", ";
975c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                // Check if we need to use '&' for this type of argument.
976c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                char lastChar = p->variableName.back();
977c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                if (lastChar >= '0' && lastChar <= '9') {
978c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    *mRs << "&";
979c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                }
980c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *mRs << p->variableName << ", x);\n";
981c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
982c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
983c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (mReturnParam) {
984c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            mRs->indent() << "return " << mReturnParam->variableName << ";\n";
985c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
986c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
987c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    mRs->endBlock();
988c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
989c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
990c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid PermutationWriter::writeRsAllocationDefinition(const ParameterDefinition& param,
991c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                                    set<string>* rsAllocationsGenerated) const {
992c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!testAndSet(param.rsAllocName, rsAllocationsGenerated)) {
993c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *mRs << "rs_allocation " << param.rsAllocName << ";\n";
994c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
995c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
996c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
997c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Open the mJavaFile and writes the header.
99862e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouilletstatic bool startJavaFile(GeneratedFile* file, const Function& function, const string& directory,
99962e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet                          const string& testName, const string& relaxedTestName) {
1000c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string fileName = testName + ".java";
100162e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    if (!file->start(directory, fileName)) {
1002c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
1003c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1004c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->writeNotices();
1005c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1006c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "package android.renderscript.cts;\n\n";
1007c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1008c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "import android.renderscript.Allocation;\n";
1009c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "import android.renderscript.RSRuntimeException;\n";
101093abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    *file << "import android.renderscript.Element;\n";
101193abc2d8bd168191b9573017d3ac26f1bfc5fc49Pirama Arumuga Nainar    *file << "import android.renderscript.cts.Target;\n\n";
10120c905c882fb351eb754a630d18339c14392fdbcbJean-Luc Brouillet    *file << "import java.util.Arrays;\n\n";
1013c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1014c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "public class " << testName << " extends RSBaseCompute";
1015c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->startBlock();  // The corresponding endBlock() is in finishJavaFile()
1016c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "\n";
1017c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1018c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "private ScriptC_" << testName << " script;\n";
1019c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "private ScriptC_" << relaxedTestName << " scriptRelaxed;\n\n";
1020c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1021c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "@Override\n";
1022c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "protected void setUp() throws Exception";
1023c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->startBlock();
1024c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1025c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "super.setUp();\n";
1026c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "script = new ScriptC_" << testName << "(mRS);\n";
1027c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "scriptRelaxed = new ScriptC_" << relaxedTestName << "(mRS);\n";
1028c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1029c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->endBlock();
1030c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "\n";
1031c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return true;
1032c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
1033c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1034c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Write the test method that calls all the generated Check methods.
1035c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void finishJavaFile(GeneratedFile* file, const Function& function,
1036c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                           const vector<string>& javaCheckMethods) {
1037c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->indent() << "public void test" << function.getCapitalizedName() << "()";
1038c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->startBlock();
1039c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto m : javaCheckMethods) {
1040c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        file->indent() << m << "();\n";
1041c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1042c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->endBlock();
1043c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1044c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->endBlock();
1045c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
1046c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1047c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Open the script file and write its header.
104862e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouilletstatic bool startRsFile(GeneratedFile* file, const Function& function, const string& directory,
104962e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet                        const string& testName) {
1050c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string fileName = testName + ".rs";
105162e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    if (!file->start(directory, fileName)) {
1052c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
1053c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1054c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file->writeNotices();
1055c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1056c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "#pragma version(1)\n";
1057c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "#pragma rs java_package_name(android.renderscript.cts)\n\n";
1058c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return true;
1059c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
1060c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1061c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Write the entire *Relaxed.rs test file, as it only depends on the name.
106262e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouilletstatic bool writeRelaxedRsFile(const Function& function, const string& directory,
106362e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet                               const string& testName, const string& relaxedTestName) {
1064c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    string name = relaxedTestName + ".rs";
1065c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1066c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    GeneratedFile file;
106762e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    if (!file.start(directory, name)) {
1068c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
1069c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1070c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file.writeNotices();
1071c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1072c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#include \"" << testName << ".rs\"\n";
1073c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#pragma rs_fp_relaxed\n";
1074c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file.close();
1075c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return true;
1076c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
1077c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1078c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/* Write the .java and the two .rs test files.  versionOfTestFiles is used to restrict which API
1079c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * to test.
1080c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */
108162e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouilletstatic bool writeTestFilesForFunction(const Function& function, const string& directory,
108212398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni                                      unsigned int versionOfTestFiles) {
1083c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Avoid creating empty files if we're not testing this function.
1084c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!needTestFiles(function, versionOfTestFiles)) {
1085c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return true;
1086c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1087c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
108862e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    const string testName = "Test" + function.getCapitalizedName();
1089c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string relaxedTestName = testName + "Relaxed";
1090c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
109162e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    if (!writeRelaxedRsFile(function, directory, testName, relaxedTestName)) {
1092c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
1093c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1094c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1095c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    GeneratedFile rsFile;    // The Renderscript test file we're generating.
1096c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    GeneratedFile javaFile;  // The Jave test file we're generating.
109762e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    if (!startRsFile(&rsFile, function, directory, testName)) {
1098c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
1099c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
110162e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    if (!startJavaFile(&javaFile, function, directory, testName, relaxedTestName)) {
1102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
1103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* We keep track of the allocations generated in the .rs file and the argument classes defined
1106c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * in the Java file, as we share these between the functions created for each specification.
1107c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
1108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    set<string> rsAllocationsGenerated;
1109c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    set<string> javaGeneratedArgumentClasses;
1110c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Lines of Java code to invoke the check methods.
1111c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    vector<string> javaCheckMethods;
1112c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1113c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto spec : function.getSpecifications()) {
1114c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (spec->hasTests(versionOfTestFiles)) {
1115c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            for (auto permutation : spec->getPermutations()) {
1116c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                PermutationWriter w(*permutation, &rsFile, &javaFile);
1117c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                w.writeRsSection(&rsAllocationsGenerated);
1118c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                w.writeJavaSection(&javaGeneratedArgumentClasses);
1119c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1120c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                // Store the check method to be called.
1121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                javaCheckMethods.push_back(w.getJavaCheckMethodName());
1122c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
1123c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
1124c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1125c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1126c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    finishJavaFile(&javaFile, function, javaCheckMethods);
1127c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // There's no work to wrap-up in the .rs file.
1128c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1129c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsFile.close();
1130c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    javaFile.close();
1131c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return true;
1132c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
1133c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
113412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nibool generateTestFiles(const string& directory, unsigned int versionOfTestFiles) {
1135c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    bool success = true;
11367c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    for (auto f : systemSpecification.getFunctions()) {
11377c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        if (!writeTestFilesForFunction(*f.second, directory, versionOfTestFiles)) {
11387c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet            success = false;
1139c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
1140c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
1141c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return success;
1142c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
1143