Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8547d558 authored by Stephen Hines's avatar Stephen Hines Committed by Android (Google) Code Review
Browse files

Merge "Add math agreement test. float_distance and float_almost_agree added to header"

parents e09e9b70 325ca454
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ public class RSTestCore {
        unitTests.add(new UT_struct(this, mRes, mCtx));
        unitTests.add(new UT_math(this, mRes, mCtx));
        unitTests.add(new UT_math_conformance(this, mRes, mCtx));
        unitTests.add(new UT_math_agree(this, mRes, mCtx));
        unitTests.add(new UT_element(this, mRes, mCtx));
        unitTests.add(new UT_sampler(this, mRes, mCtx));
        unitTests.add(new UT_program_store(this, mRes, mCtx));
+57 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.rs.test;

import android.content.Context;
import android.content.res.Resources;
import android.renderscript.*;
import java.util.Random;

public class UT_math_agree extends UnitTest {
    private Resources mRes;

    protected UT_math_agree(RSTestCore rstc, Resources res, Context ctx) {
        super(rstc, "Math Agreement", ctx);
        mRes = res;
    }

    private void initializeValues(ScriptC_math_agree s) {
        Random rand = new Random();

        float x = rand.nextFloat();
        float y = rand.nextFloat();

        s.set_x(x);
        s.set_y(y);
        s.set_result_add(x + y);
        s.set_result_sub(x - y);
        s.set_result_mul(x * y);
        s.set_result_div(x / y);
    }

    public void run() {
        RenderScript pRS = RenderScript.create(mCtx);
        ScriptC_math_agree s = new ScriptC_math_agree(pRS, mRes,
                R.raw.math_agree);
        pRS.setMessageHandler(mRsMessage);
        initializeValues(s);
        s.invoke_math_agree_test();
        pRS.finish();
        waitForMessage();
        pRS.destroy();
    }
}
+54 −0
Original line number Diff line number Diff line
#include "shared.rsh"
//#pragma rs_fp_relaxed

float x = 0.0f;
float y = 0.0f;
float result_add = 0.0f;
float result_sub = 0.0f;
float result_mul = 0.0f;
float result_div = 0.0f;

#define TEST_OP(op, opName)                                             \
result = x op y;                                                        \
if (! float_almost_equal(result, result_##opName)) {                    \
    rsDebug(#opName " did not match!", 0);                              \
    rsDebug("x = ", x);                                                 \
    rsDebug("y = ", y);                                                 \
    rsDebug("Result = ", result);                                       \
    rsDebug("Expected = ", result_##opName);                            \
    rsDebug("Difference = ", result - result_##opName);                 \
    rsDebug("ULP Difference =", float_dist(result, result_##opName));   \
    failed = true;                                                      \
}

static bool test_math_agree() {
    bool failed = false;
    float result = 0.0;

    TEST_OP(+, add);
    TEST_OP(-, sub);
    TEST_OP(*, mul);
    TEST_OP(/, div);

    if (failed) {
        rsDebug("test_math_agree FAILED", 0);
    }
    else {
        rsDebug("test_math_agree PASSED", 0);
    }

    return failed;
}

void math_agree_test() {
    bool failed = false;
    failed |= test_math_agree();

    if (failed) {
        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
    }
    else {
        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
    }
}
+34 −0
Original line number Diff line number Diff line
@@ -74,6 +74,40 @@ static bool iszero(float f) {
    return isposzero(f) || isnegzero(f);
}

/* Absolute epsilon used for floats.  Value is similar to float.h. */
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.19e7f
#endif
/* Max ULPs while still being considered "equal".  Only used when this number
   of ULPs is of a greater size than FLT_EPSILON. */
#define FLT_MAX_ULP 1

/* Calculate the difference in ULPs between the two values.  (Return zero on
   perfect equality.) */
static int float_dist(float f1, float f2) {
    return *((int *)(&f1)) - *((int *)(&f2));
}

/* Check if two floats are essentially equal.  Will fail with some values
   due to design.  (Validate using FLT_EPSILON or similar if necessary.) */
static bool float_almost_equal(float f1, float f2) {
    int *i1 = (int*)(&f1);
    int *i2 = (int*)(&f2);

    // Check for sign equality
    if ( ((*i1 >> 31) == 0) != ((*i2 >> 31) == 0) ) {
        // Handle signed zeroes
        if (f1 == f2)
            return true;
        return false;
    }

    // Check with ULP distance
    if (float_dist(f1, f2) > FLT_MAX_ULP)
        return false;
    return true;
}

/* These constants must match those in UnitTest.java */
static const int RS_MSG_TEST_PASSED = 100;
static const int RS_MSG_TEST_FAILED = 101;